Recent

Author Topic: passing variable onto httpserver (fpWeb)  (Read 550 times)

krolikbest

  • Full Member
  • ***
  • Posts: 139
passing variable onto httpserver (fpWeb)
« on: September 24, 2020, 09:11:33 am »
Hi,

soon I'd like to write httpserver side (fpWeb) as a part of a little bigger project. Server should acts as a http server application (not cgi) and have question: how to pass a variables to httpserver from external application? So far I've not started this part of project yet so my reflections are only theoretical.
Lets say I have such code in DataModuleRequest of httpserver:
Code: Pascal  [Select][+][-]
  1.  AResponse.Content := 'Some text' + someVar;
  2.  
and somewhere else different program (so-called 'client') sends via http protocol some data. This data should be passed onto http server as a someVar (obviously the same type). So reading and displaying vars in DataModuleRequest of httpserver should now look like something below , or am I wrong?
Code: Pascal  [Select][+][-]
  1.   someVar := ARequest.ContentFields.Values['data'];
  2.   AResponse.Content := 'Hello, ' + LName + '!';
  3.  
Or maybe in the fpWeb there is ready to use element to read and display incoming datas?

Regards,

egsuh

  • Sr. Member
  • ****
  • Posts: 471
Re: passing variable onto httpserver (fpWeb)
« Reply #1 on: September 24, 2020, 09:43:29 am »
I haven't done HTTPServer, only CGI. So judging based on my experience, your theory seems generally right. Just except that if your client sends request in GET method, then they will be stored in ARequest.QueryFields instead of ARequest.ContentFields.  ContentFields contains data when the request's method is POST.

You can send both QueryFields and ContentFields in POST method, but only QueryFields in GET method.

Your client may be web browser, or Windows application (if your OS is Windows. I don't know about Linix) --- I access webserver using Ararat Synapse.

krolikbest

  • Full Member
  • ***
  • Posts: 139
Re: passing variable onto httpserver (fpWeb)
« Reply #2 on: September 25, 2020, 08:39:10 pm »
So started writing httpserver as a standalone application. Server should receive datas from tcp client and it is external application with Synapse TvsVisualTCP. As a result of function HttpPostURL of this client I get response from httpserver. And it looks like:
Code: Pascal  [Select][+][-]
  1. <!doctype html>
  2. <html>
  3.   <head>
  4.     <title>Example</title>
  5.   </head>
  6.   <body>
  7.     aaaa
  8.   </body>
  9. </html>
  10.  
On the httpserver side there is:
Code: Pascal  [Select][+][-]
  1.  somevar := ARequest.ContentFields.Values['txt'];
  2.  if tekst<>'()' then
  3.     begin
  4.      with AResponse.Contents do begin
  5.         Clear;
  6.         BeginUpdate;
  7.         Add('<!doctype html>');
  8.         Add('<html>');
  9.         Add('  <head>');
  10.         Add('    <title>Example</title>');
  11.         Add('  </head>');
  12.         Add('  <body>');
  13.         Add(someVar);
  14.         Add('  </body>');
  15.         Add('</html>');
  16.         EndUpdate;
  17.      end;                
  18.  
So it seems to be OK. On the httpserver side I can see incoming this somevar='aaaa'. That is ok. Question is however how to display above page in the browser? For example after refreshing I get notnig but blank page. It looks like refreshing does something and this disrupts incoming datas from tcp client so wrong way. but how do it right?

Regards,

dogriz

  • Full Member
  • ***
  • Posts: 117
    • Tech blog - Delphi, Lazarus, Firebird, Windows, Linux, Android...
Re: passing variable onto httpserver (fpWeb)
« Reply #3 on: September 28, 2020, 08:22:11 am »
I use curl (a very versatile console tool), for your test like this:
Code: [Select]
curl -X POST -F 'myVar=HELLO' http://WebServerIP:port/optional_path
and in your web server procedure do something like this:
Code: Pascal  [Select][+][-]
  1. if ARequest.ContentFields.Values['myVar'] = 'HELLO' then
  2.   begin
  3.     AResponse.Code := 200;
  4.     AResponse.ContentType := 'text/plain';
  5.     AResponse.Content := 'OK';
  6.     AResponse.ContentLength := Length(AResponse.Content);
  7.     AResponse.SendContent;
  8.   end;
FPC 3.0.4
Lazarus 2.0.6
Debian x86_64, arm

krolikbest

  • Full Member
  • ***
  • Posts: 139
Re: passing variable onto httpserver (fpWeb)
« Reply #4 on: September 28, 2020, 11:16:18 am »
Thanks, this afternoon i'm going to struggle again with this.  :)

krolikbest

  • Full Member
  • ***
  • Posts: 139
Re: passing variable onto httpserver (fpWeb)
« Reply #5 on: September 28, 2020, 08:48:02 pm »
Unfortunatelly it's not as simply as I thought. It's given the code
Code: Pascal  [Select][+][-]
  1. procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;
  2.   AResponse: TResponse; var Handled: Boolean);
  3.  
  4. var
  5.     someVar : string;
  6.  
  7. begin
  8.  
  9.   someVar := ARequest.ContentFields.Values['txt'];
  10.   writeln(someVar);
  11.  
  12.   if someVar<>'' then
  13.     begin
  14.         AResponse.Code:=200;
  15.         AResponse.ContentType := 'text/plain';
  16.         AResponse.Content:='YES';
  17.         AResponse.ContentLength:=Length(AResponse.Content);
  18.         AResponse.SendContent;
  19.     end
  20.        else
  21.     begin
  22.         AResponse.Code:=200;
  23.         AResponse.ContentType := 'text/plain';
  24.         AResponse.Content:='NO';
  25.         AResponse.ContentLength:=Length(AResponse.Content);
  26.         aresponse.SendContent;
  27.     end;
  28.  Handled := True;
  29.  
  30. end;
  31.  
First in the browser I see 'NO', after refreshing a page in the browser still I see 'NO' but in command window of httpserver I see incoming someVar (lets say someVar='aaaa', so since the whole process runs in ModuleRequest I thought that if someVar<>'' then page browser automatically would refresh and will display 'YES'. But didn't. Maybe I shouldn't expect this code to refresh a page in browser? So how to do it?
Win7, Lazarus 2.0.10 64bit

dogriz

  • Full Member
  • ***
  • Posts: 117
    • Tech blog - Delphi, Lazarus, Firebird, Windows, Linux, Android...
Re: passing variable onto httpserver (fpWeb)
« Reply #6 on: September 29, 2020, 08:13:57 am »
I tested your code and it works. You probaby overlooked something... Here's complete program with examples:
Code: Pascal  [Select][+][-]
  1. program wsSimplePostResponse;
  2. {$mode objfpc}{$H+}
  3. uses
  4.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  5.   cthreads,
  6.   {$ENDIF}{$ENDIF}
  7.   sysutils, fphttpapp, HTTPDefs, httproute;
  8.  
  9. procedure Test(aReq: TRequest; aRes: TResponse);
  10. var
  11.   someVar: String;
  12. begin
  13.   someVar := aReq.ContentFields.Values['txt'];
  14.   WriteLn(someVar);
  15.  
  16.   if someVar <> '' then
  17.     begin
  18.       aRes.Code:=200;
  19.       aRes.ContentType := 'text/plain';
  20.       aRes.Content := 'YES';
  21.       aRes.ContentLength := Length(aRes.Content);
  22.       aRes.SendContent;
  23.     end
  24.   else
  25.     begin
  26.       aRes.Code:=200;
  27.       aRes.ContentType := 'text/plain';
  28.       aRes.Content := 'NO';
  29.       aRes.ContentLength := Length(aRes.Content);
  30.       aRes.SendContent;
  31.     end;
  32. end;
  33.  
  34. begin
  35.   Application.Port := 8080;
  36.   HTTPRouter.RegisterRoute('/test', rmPost, @Test, True);
  37.   Application.Initialize;
  38.   Application.Run;
  39. end.
Code: [Select]
curl -X POST -F 'txt=' http://localhost:8080
NO
curl -X POST -F 'txt=123' http://localhost:8080
YES
FPC 3.0.4
Lazarus 2.0.6
Debian x86_64, arm

krolikbest

  • Full Member
  • ***
  • Posts: 139
Re: passing variable onto httpserver (fpWeb)
« Reply #7 on: September 29, 2020, 10:12:36 am »
Hi,
 do you mean that it is automatically refreshed a page in browser? Perhaps I can't do this because of using httpPostUrl from httpsend (Synapse) in my extrenal program which is communicating with httpserver (fpWeb). Using httpPostUrl returns a response from httpserver, so on the side of httpServer in DataModuleRequest is proceeded request from httpPostUrl(Synapse) and send response to this external program instead of a browser.. have to check it.

Regards,

 

TinyPortal © 2005-2018