0

I am trying to send HTTP DELETE request using Indy 9.

Attempt (like that):

type
  TIdHTTPAccess = class(TIdHTTP)
  end;

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

This doesn't work, because hmDelete skipped in TIdHTTPProtocol.BuildAndSendRequest.

Is there any chance, to send HTTP DELETE request using Indy 9?

Delpphi 7, Indy 9.00.10, part of unit 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;
...
Community
  • 1
  • 1
  • What you have shown will work just fine in Indy 9 (are you using the latest version of Indy 9?). `hmDelete` is **not** skipped in `BuildAndSendRequest()`. Where did you ever get that idea from? Just make sure that `TIdHTTP.ProtocolVersion` is set to `pv1_1` (which it is by default), otherwise `TIdHTTP` will raise a "This request method is supported in HTTP 1.1" exception. – Remy Lebeau Mar 13 '17 at 20:54
  • I added part of unit IdHTTP in the Question. I can't see `FHTTP.WriteLn('DELETE '...` in the code. Indy 9.00.10. `TIdHTTP.ProtocolVersion = pv1_1`. – Oleg Adibekov Mar 13 '17 at 21:18
  • I understand that upgrade will correct the situation. But my idea: the developer works with the Indy version delivered with delphi. If I correctly have understood you, then in this case it is impossible. Thanks, @Remylebeau. – Oleg Adibekov Mar 13 '17 at 21:46
  • It is not impossible, you would just have to tweak and recompile your existing copy of Indy. But many Indy users rarely use the Indy version that ships with Delphi, because it is frequently outdated shortly after release. Most Indy users keep up with Indy updates. – Remy Lebeau Mar 13 '17 at 21:53

1 Answers1

3

Calling TIdHTTP.DoRequest() directly is the correct way to send a DELETE request in Indy 9. Using an accessor class is one option to do that. Another option would be to derive a new component from TIdHTTP to add your own Delete() method that calls DoRequest() (much like TIdHTTP does in 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;

However, that being said, you are using an outdated version of Indy 9. The last version is 9.0.50, and its BuildAndSendRequest() code is different than what you showed:

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;

The very issue you are having trouble with was addressed in the last revision made to Indy 9's IdHTTP.pas file (in SVN revision 35 on Dec 24 2007):

Updated TIdHTTPProtocol.BuildAndSendRequest() to use a string array of method names instead of using a 'case of' statement, which was originally missing an entry for 'hmDelete'.

You need to upgrade to an up-to-date version of Indy 9 (if not to Indy 10).

If that is not an option, then you will have to edit your current copy of IdHTTP.pas to add the missing hmDelete case, and then recompile Indy.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770