Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2011-12

TFPHTTPClient Post works with jetty, fails with tomcat

10 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Mattias Gaertner

Hi,

For some reason TFPHTTPClient.Post hangs when accessing a "solr" server over "tomcat". It works with "solr" over "jetty". "curl" works fine with both, so I guess the tomcat server works normally.

Here is the code:

    client:=TFPHTTPClient.Create(nil);
    client.RequestHeaders.Add('Content-Type: text/xml');
    client.RequestBody:=ms; // a TMemoStream with some xml to post
    client.Post(URL);

It hangs here:

procedure TFPCustomHTTPClient.ReadResponse
...
  else if L<0 then
    // No content-length, so we read till no more data available.
    Repeat
      R:=Transfer(ReadBufLen);
    until (R=0);

Is there a remedy?

Mattias

Unknown author
to Mattias Gaertner
Mattias Gaertner wrote 25 lines
Hi, For some reason TFPHTTPClient.Post hangs when accessing a "solr" server over "tomcat". It works with "solr" over "jetty". "curl" works fine with both, so I guess the tomcat server works normally. Here is the code: client:=TFPHTTPClient.Create(nil); client.RequestHeaders.Add('Content-Type: text/xml'); client.RequestBody:=ms; // a TMemoStream with some xml to post client.Post(URL); It hangs here: procedure TFPCustomHTTPClient.ReadResponse ... else if L<0 then // No content-length, so we read till no more data available. Repeat R:=Transfer(ReadBufLen); until (R=0); Is there a remedy?

Can you check what happens with strace?

It means that the server didn't send a 'content-length' header, which is strange in itself.

Michael.

Mattias Gaertner
to Unknown author
Show quoted text 34 lines
On Mon, 19 Dec 2011, Mattias Gaertner wrote: > Hi, > > For some reason TFPHTTPClient.Post hangs when accessing a "solr" > server over "tomcat". It works with "solr" over "jetty". > "curl" works fine with both, so I guess the tomcat server works > normally. > > Here is the code: > > client:=TFPHTTPClient.Create(nil); > client.RequestHeaders.Add('Content-Type: text/xml'); > client.RequestBody:=ms; // a TMemoStream with some xml to post > client.Post(URL); > > It hangs here: > > procedure TFPCustomHTTPClient.ReadResponse > ... > else if L<0 then > // No content-length, so we read till no more data available. > Repeat > R:=Transfer(ReadBufLen); > until (R=0); > > Is there a remedy? Can you check what happens with strace? It means that the server didn't send a 'content-length' header, which is strange in itself.

Yes, it does not send the Content-Length.
The comment is right.
If I skip the repeat loop, it works, but I don't get the response. The response is a small xml snippet.

Mattias

Unknown author
to Mattias Gaertner
Mattias Gaertner wrote 42 lines
On Mon, 19 Dec 2011 09:27:16 +0100 (CET) wrote: > > > On Mon, 19 Dec 2011, Mattias Gaertner wrote: > >> Hi, >> >> For some reason TFPHTTPClient.Post hangs when accessing a "solr" >> server over "tomcat". It works with "solr" over "jetty". >> "curl" works fine with both, so I guess the tomcat server works >> normally. >> >> Here is the code: >> >> client:=TFPHTTPClient.Create(nil); >> client.RequestHeaders.Add('Content-Type: text/xml'); >> client.RequestBody:=ms; // a TMemoStream with some xml to post >> client.Post(URL); >> >> It hangs here: >> >> procedure TFPCustomHTTPClient.ReadResponse >> ... >> else if L<0 then >> // No content-length, so we read till no more data available. >> Repeat >> R:=Transfer(ReadBufLen); >> until (R=0); >> >> Is there a remedy? > > Can you check what happens with strace? > > It means that the server didn't send a 'content-length' header, which is > strange in itself. Yes, it does not send the Content-Length. The comment is right. If I skip the repeat loop, it works, but I don't get the response. The response is a small xml snippet.

What does 'strace' say ?

Michael.

Mattias Gaertner
to Unknown author
[...] What does 'strace' say ?

Same happens on fpc wiki:

Here is the strace:

sendto(3, "GET /index.php?title=Special:Exp"..., 135, 0, NULL, 0) = 135 recvfrom(3, "HTTP/1.1 200 OK\r\nDate: Tue, 07 F"..., 4096, 0, NULL, NULL) = 2880 recvfrom(3, " and create spreadsheets, text d"..., 4096, 0, NULL, NULL) = 1440 recvfrom(3, "interface to various hardware de"..., 4096, 0, NULL, NULL) = 2880 recvfrom(3, "lements and links to the referen"..., 4096, 0, NULL, NULL) = 1440 recvfrom(3, "eploying Your Application]] - Ho"..., 4096, 0, NULL, NULL) = 2880 recvfrom(3, "zarus GUI\n*[[Roadmap]] - An idea"..., 4096, 0, NULL, NULL) = 1440 recvfrom(3, " A few notes for programmers on "..., 4096, 0, NULL, NULL) = 1440 recvfrom(3, "s Component]] for more component"..., 4096, 0, NULL, NULL) = 1440 recvfrom(3, "blogspot.com/ Porting to Lazarus"..., 4096, 0, NULL, NULL) = 2061 recvfrom(3, "17\r\n </page>\n</mediawiki>\n\r\n0\r\n"..., 4096, 0, NULL, NULL) = 34 recvfrom(3,

After some time it continues:

"", 4096, 0, NULL, NULL) = 0
close(3) = 0
munmap(0x7f1daa4d1000, 262144) = 0
munmap(0x7f1daa52d000, 32768) = 0
munmap(0x7f1daa51d000, 32768) = 0
munmap(0x7f1daa4c9000, 32768) = 0
munmap(0x7f1daa4b9000, 32768) = 0
munmap(0x7f1daa4b1000, 32768) = 0
munmap(0x7f1daa4c1000, 32768) = 0
exit_group(0) = ?

Mattias

Mattias Gaertner
to Mattias Gaertner
Show quoted text 7 lines
On Mon, 19 Dec 2011 10:39:09 +0100 (CET) wrote: >[...] > What does 'strace' say ? Same happens on fpc wiki:
uses Classes, SysUtils, fphttpclient;
...
var
  Response: TStringStream;
  client: TFPHTTPClient;
  URL: String;
begin
  Response:=nil;
  client:=nil;
  try
    client:=TFPHTTPClient.Create(nil);
    Response:=TStringStream.Create('');
    URL:='http://wiki.freepascal.org/index.php?title=Special:Export&pages=Lazarus_Documentation'&curonly=1&action=submit';
    writeln('URL=',URL);
    client.Get(URL,Response);
    //writeln(Response.DataString);
  finally
    client.Free;
    Response.Free;
  end;
end;
Show quoted text 27 lines
Here is the strace: sendto(3, "GET /index.php?title=Special:Exp"..., 135, 0, NULL, 0) = 135 recvfrom(3, "HTTP/1.1 200 OK\r\nDate: Tue, 07 F"..., 4096, 0, NULL, NULL) = 2880 recvfrom(3, " and create spreadsheets, text d"..., 4096, 0, NULL, NULL) = 1440 recvfrom(3, "interface to various hardware de"..., 4096, 0, NULL, NULL) = 2880 recvfrom(3, "lements and links to the referen"..., 4096, 0, NULL, NULL) = 1440 recvfrom(3, "eploying Your Application]] - Ho"..., 4096, 0, NULL, NULL) = 2880 recvfrom(3, "zarus GUI\n*[[Roadmap]] - An idea"..., 4096, 0, NULL, NULL) = 1440 recvfrom(3, " A few notes for programmers on "..., 4096, 0, NULL, NULL) = 1440 recvfrom(3, "s Component]] for more component"..., 4096, 0, NULL, NULL) = 1440 recvfrom(3, "blogspot.com/ Porting to Lazarus"..., 4096, 0, NULL, NULL) = 2061 recvfrom(3, "17\r\n </page>\n</mediawiki>\n\r\n0\r\n"..., 4096, 0, NULL, NULL) = 34 recvfrom(3, After some time it continues: "", 4096, 0, NULL, NULL) = 0 close(3) = 0 munmap(0x7f1daa4d1000, 262144) = 0 munmap(0x7f1daa52d000, 32768) = 0 munmap(0x7f1daa51d000, 32768) = 0 munmap(0x7f1daa4c9000, 32768) = 0 munmap(0x7f1daa4b9000, 32768) = 0 munmap(0x7f1daa4b1000, 32768) = 0 munmap(0x7f1daa4c1000, 32768) = 0 exit_group(0) = ?

Mattias

Rainer Stratmann
to Mattias Gaertner: For some reason TFPHTTPClient.Post hangs when accessing a "solr" server over "tomcat". It…
Mattias Gaertner wrote 23 lines
Hi, For some reason TFPHTTPClient.Post hangs when accessing a "solr" server over "tomcat". It works with "solr" over "jetty". "curl" works fine with both, so I guess the tomcat server works normally. Here is the code: client:=TFPHTTPClient.Create(nil); client.RequestHeaders.Add('Content-Type: text/xml'); client.RequestBody:=ms; // a TMemoStream with some xml to post client.Post(URL); It hangs here: procedure TFPCustomHTTPClient.ReadResponse ... else if L<0 then // No content-length, so we read till no more data available. Repeat R:=Transfer(ReadBufLen); until (R=0);

If you have no content-length then mostly in the header ist a field 'Transfer-Encoding: chunked'. Then the content is send in snippets. It is exactly defined how long to read until there is no more content.

http://en.wikipedia.org/wiki/Chunked_transfer_encoding

Mattias Gaertner
to Rainer Stratmann
Show quoted text 30 lines
Am Monday 19 December 2011 01:22:18 schrieb Mattias Gaertner: > Hi, > > For some reason TFPHTTPClient.Post hangs when accessing a "solr" > server over "tomcat". It works with "solr" over "jetty". > "curl" works fine with both, so I guess the tomcat server works > normally. > > Here is the code: > > client:=TFPHTTPClient.Create(nil); > client.RequestHeaders.Add('Content-Type: text/xml'); > client.RequestBody:=ms; // a TMemoStream with some xml to post > client.Post(URL); > > It hangs here: > > procedure TFPCustomHTTPClient.ReadResponse > ... > else if L<0 then > // No content-length, so we read till no more data available. > Repeat > R:=Transfer(ReadBufLen); > until (R=0); If you have no content-length then mostly in the header ist a field 'Transfer-Encoding: chunked'. Then the content is send in snippets. It is exactly defined how long to read until there is no more content. http://en.wikipedia.org/wiki/Chunked_transfer_encoding

Thanks for the hint. I implemented chunked reading and now it works fast without timeouts. :)

Mattias

trick.

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 36 lines
On Tue, 7 Feb 2012 10:33:04 +0100 Rainer Stratmann wrote: > Am Monday 19 December 2011 01:22:18 schrieb Mattias Gaertner: >> Hi, >> >> For some reason TFPHTTPClient.Post hangs when accessing a "solr" >> server over "tomcat". It works with "solr" over "jetty". >> "curl" works fine with both, so I guess the tomcat server works >> normally. >> >> Here is the code: >> >> client:=TFPHTTPClient.Create(nil); >> client.RequestHeaders.Add('Content-Type: text/xml'); >> client.RequestBody:=ms; // a TMemoStream with some xml to post >> client.Post(URL); >> >> It hangs here: >> >> procedure TFPCustomHTTPClient.ReadResponse >> ... >> else if L<0 then >> // No content-length, so we read till no more data available. >> Repeat >> R:=Transfer(ReadBufLen); >> until (R=0); > > If you have no content-length then mostly in the header ist a > field 'Transfer-Encoding: chunked'. Then the content is send in snippets. It > is exactly defined how long to read until there is no more content. > > http://en.wikipedia.org/wiki/Chunked_transfer_encoding Thanks for the hint. I implemented chunked reading and now it works fast without timeouts. :)

Did you implement this in TFPCustomHTTPClient itself ? If so, please provide a patch.

Michael.

Mattias Gaertner
to Michael Van Canneyt
Show quoted text 18 lines
On Thu, 9 Feb 2012, Mattias Gaertner wrote: > On Tue, 7 Feb 2012 10:33:04 +0100 > Rainer Stratmann wrote: > [...] >> If you have no content-length then mostly in the header ist a >> field 'Transfer-Encoding: chunked'. Then the content is send in snippets. It >> is exactly defined how long to read until there is no more content. >> >> http://en.wikipedia.org/wiki/Chunked_transfer_encoding > > Thanks for the hint. I implemented chunked reading and now it works > fast without timeouts. :) Did you implement this in TFPCustomHTTPClient itself ?

Yes, it seems the right place.

If so, please provide a patch.

I will do after some more tests.

Mattias