Как отправить запрос DELETE с помощью Indy 9?

Я пытаюсь отправить запрос HTTP DELETE, используя Indy 9.

Попытка ( вот так):

type
  TIdHTTPAccess = class(TIdHTTP)
  end;

TIdHTTPAccess(IdHttp).DoRequest(hmDelete, deleteURL, nil, nil);

Это не работает, потому что hmDelete пропустил в TIdHTTPProtocol.BuildAndSendRequest.

Есть ли шанс отправить HTTP-запрос DELETE с помощью Indy 9?

Delpphi 7, Indy 9.00.10, часть подразделения IdHTTP;

procedure TIdHTTPProtocol.BuildAndSendRequest(AURI: TIdURI);
...
  case Request.Method of
    hmHead: FHTTP.WriteLn('HEAD ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    hmGet: FHTTP.WriteLn('GET ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    hmPost: FHTTP.WriteLn('POST ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    // HTTP 1.1 only
    hmOptions: FHTTP.WriteLn('OPTIONS ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    hmTrace: FHTTP.WriteLn('TRACE ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    hmPut: FHTTP.WriteLn('PUT ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    hmConnect: FHTTP.WriteLn('CONNECT ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
  end;
...

1 ответ

Решение

Призвание TIdHTTP.DoRequest() напрямую это правильный способ отправить DELETE запрос в Indy 9. Использование класса доступа является одним из вариантов для этого. Другим вариантом будет получение нового компонента из TIdHTTP добавить свой собственный Delete() метод, который вызывает DoRequest() (так же, как TIdHTTP делает в Indy 10):

type
  TMyHTTP = class(TIdHTTP)
  public
    procedure Delete(AURL: string; AResponseContent: TStream); overload;
    function Delete(AURL: string): string; overload;
  end;

procedure TMyHTTP.Delete(AURL: string; AResponseContent: TStream);
begin
  DoRequest(hmDelete, AURL, nil, AResponseContent);
end;

function TMyHTTP.Delete(AURL: string): string;
var
  Stream: TMemoryStream;
begin
  Stream := TMemoryStream.Create;
  try
    Delete(AURL, Stream);
    SetLength(Result, Stream.Size);
    Move(PChar(Stream.Memory)^, PChar(Result)^, Stream.Size);
  finally
    Stream.Free;
  end;
end;

Тем не менее, как говорится, вы используете устаревшую версию Indy 9. Последняя версия 9.0.50, и его BuildAndSendRequest() код отличается от того, что вы показали:

const
  ProtocolVersionString: array[TIdHTTPProtocolVersion] of string = ('1.0', '1.1'); {do not localize}
  MethodString: array[TIdHTTPMethod] of String = ('HEAD', 'GET', 'POST', 'OPTIONS', 'TRACE', 'PUT', 'DELETE', 'CONNECT'); {do not localize}

...

procedure TIdHTTPProtocol.BuildAndSendRequest(AURI: TIdURI);
var
  ...
begin
  ...
  FHTTP.WriteLn(MethodString[Request.Method] + ' ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
  ...
end;

Самая проблема, с которой у вас возникли проблемы, была решена в последней редакции Indy 9 IdHTTP.pas файл (в редакции SVN 35 от 24 декабря 2007 г.):

Обновлен TIdHTTPProtocol.BuildAndSendRequest() для использования строкового массива имен методов вместо использования оператора case, в котором изначально отсутствовала запись для hmDelete.

Вам необходимо обновить до последней версии Indy 9 (если не до Indy 10).

Если это не вариант, вам придется отредактировать текущую копию IdHTTP.pas добавить недостающее hmDelete случай, а затем перекомпилировать Indy.

Другие вопросы по тегам