LHTTPServer response problem
lazarus / 38-Networking and Web Programming
----------------------------------------------------------------------
Dibo · 2011-04-11 18:30
Hi,
Only LHTTPServer component from LNet package have status
"experimental" so I have question. There is demo for TCP server and it
works fine but I don't know how to use HTTP server. I know how to
handle connections because this is similar like in TCP but what next?
How to return HTML document? Example: client send request for some
subpage (www.somepage.com/page1, www.somepage.com/page2 etc) and my
server should return XML (depending on URL). TLHTTPServerSocket have 3
public methods (SetupEncoding, StartMemoryResponse, StartResponse) but
params are not clear for me and each method call raise AV. Can I
somehow prepare response template or must I do this manually by
calling ASocket.SendMessage('HTTP/1.1 STATUS OK.....')?
Regards
----------------------------------------------------------------------
Almindor · 2011-04-11 19:13
I didn't make the HTTP part and I don't remember much from the server
side, but there's a working webserver (even with PHP/fastCGI
connection!) inside lnet/examples/console/lhttp (fphttpd).
It's a basic console program of course, but it has already it's own
config file (fphttpd.ini IIRC located in ~/.fphttpd after 1st start).
Hope this helps with some experimentation, AFAIK we got it up and
running and even serving PHP requests. (so there's a file access bound
to be coded in there).
----------------------------------------------------------------------
Dibo · 2011-04-11 20:18
Hmm it seems that I must send it by my self. Maybe it's better. I have
full control of data which I send. Synapse server do this same things:
Code: Pascal [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i procedure
TForm1.LHTTPServerComponent1Accept(aSocket: TLSocket);var
OutputDataString: String;begin Memo1.Append('accept: ' +
aSocket.ClassName); OutputDataString := '' + #13#10
+ '
test test
' + #13#10; s.SendMessage(
'HTTP/1.0 200 '+#13#10+ 'Content-type: Text/Html'+#13#10+
'Content-length: '+inttostr(Length(OutputDataString))+#13#10+
'Connection: close'+#13#10+#13#10+ OutputDataString ); end;
But I think I found a bug in HTTP client. I spent a lot of time to
figure it out. I use lNet on client side too. I thought that problem
is on server side until I check this same on synapse http server.
Internet browser (chromium) retrieve data from my both servers so this
is client bug. So, look at example above. If after "HTTP/1.0 200" is
no space then client disconnect without error (only disconnect event
is fired). I sniffed this request using wireshark and client get
server response but can't parse it. I think in this loop:
Code: Pascal [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i procedure
TLHTTPClientSocket.ParseStatusLine(pLineEnd: pchar);var lPos:
pchar;begin lPos := FBufferPos; repeat if lPos >= pLineEnd then
begin Cancel(ceMalformedStatusLine); exit; end; if
lPos^ = ' ' then break; Inc(lPos); until false;
........... ... should be "OR #13#10" in line "if lPos^ = ' '". I
don't know how it depends on HTTP standards but internet browser can
parse status without space.
----------------------------------------------------------------------
Almindor · 2011-04-11 20:53
It seems this is not a proper status line conforming to specs:
Code: [Select] #13 and #10 are line terminators
'No CR or LF is allowed except in the final CRLF sequence.
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
* fpk is now known as fpk^off
so AFAICS, it is bad server implementation
does not conform to specification
----------------------------------------------------------------------
Dibo · 2011-04-16 19:23
Ok.
I have another problem. I can handle response, headers etc but how to
read client data? In TCP server demo only OnReceive event is assigned
but in LHTTPServer this event is never fired. Client send me content
length in headers and content (XML string) but I don't know how to
read it. If I force read data by calling GetMessage it return me that
there is no message. FRequestInfo and FRequestInfo objects have only
basic info (like method, query, params, headers) but no content :/
Regards