Well, dear friends, seems there is a bug in TFPCustomHTTPClient.SendRequest procedure.
It adds "Host" header without any check for existing one.
Look at line 30: header "Host" is added without any check.
Later (line 38) it adds all headers, defined by programmer.
I'm also upset with "Cookies" header (line 48), which is added empty in my case (I've cleared them with Client.Cookies.Clear).
Resulting string S (with 2 "Hosts" headers, empty "Cookies" header and two CRLF at the end) causes exception when calling FSocket.WriteBuffer procedure.
procedure TFPCustomHTTPClient.SendRequest(const AMethod: String; URI: TURI);
Var
PH,UN,PW,S,L : String;
I : Integer;
AddContentLength : Boolean;
begin
S:=Uppercase(AMethod)+' '+GetServerURL(URI)+' '+'HTTP/'+FHTTPVersion+CRLF;
UN:=URI.Username;
PW:=URI.Password;
if (UserName<>'') then
begin
UN:=UserName;
PW:=Password;
end;
If (UN<>'') then
begin
S:=S+'Authorization: Basic ' + EncodeStringBase64(UN+':'+PW)+CRLF;
I:=IndexOfHeader('Authorization');
If I<>-1 then
RequestHeaders.Delete(i);
end;
if Assigned(FProxy) and (FProxy.Host<>'') then
begin
PH:=FProxy.GetProxyHeaders;
if (PH<>'') then
S:=S+PH+CRLF;
end;
S:=S+'Host: '+URI.Host;
If (URI.Port<>0) then
S:=S+':'+IntToStr(URI.Port);
S:=S+CRLF;
AddContentLength:=Assigned(RequestBody) and (IndexOfHeader('Content-Length')=-1);
If AddContentLength then
AddHeader('Content-Length',IntToStr(RequestBody.Size));
CheckConnectionCloseHeader;
For I:=0 to FRequestHeaders.Count-1 do
begin
l:=FRequestHeaders[i];
If AllowHeader(L) then
S:=S+L+CRLF;
end;
If AddContentLength then
FRequestHeaders.Delete(FRequestHeaders.IndexOfName('Content-Length'));
if Assigned(FCookies) then
begin
L:='Cookie: ';
For I:=0 to FCookies.Count-1 do
begin
If (I>0) then
L:=L+'; ';
L:=L+FCookies[i];
end;
if AllowHeader(L) then
S:=S+L+CRLF;
end;
FreeAndNil(FSentCookies);
FSentCookies:=FCookies;
FCookies:=Nil;
S:=S+CRLF;
if not Terminated then
FSocket.WriteBuffer(S[1],Length(S));
If Assigned(FRequestBody) and not Terminated then
FSocket.CopyFrom(FRequestBody,FRequestBody.Size);
end;
So workaround for "Host" is: never add "Host" header manually!
How to completely clear "Cookies", I don't know.
In older examples I can see method Client.Clear, which is not available in current version (Lazarus 2.0.10, FPC 3.2.0).
I expect this was the way to clear the body and headers completely.