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;
...
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.