Alister
Alister

Reputation: 53

Delphi7 Indy HTTPServer not getting form parameters

I have an Indy 10 IdHTTPServer in a Windows application which serves a virtual HTML form with two text boxes and a submit button. When the button is pressed in the browser I am not seeing any form params returned to the server. Note that this is a bit of proof of concept code which will be used to make a windows service respond to button presses in a web form.

The HTML form is like this:

 <form action="http://<addressofsite>/" method="post">
  First name:<br>
  <input type="text" name="firstname" value="Mickey"><br>
  Last name:<br>
  <input type="text" name="lastname" value="Mouse"><br><br>
  <input type="submit" value="Submit">
</form> 

in the Delphi code I have this:

procedure TForm1.HTTPServer1CommandGet(AThread: TIdPeerThread;
 ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin

...  

 if ARequestInfo.Command = 'POST' then
    begin
      {******* POSTS ***************}
      Memo1.Text := ARequestInfo.RawHTTPCommand;
    end;
end;

I have tried various bits of the ARequestInfo structure but whatever I try all I see when the button is pressed in the browser is:

POST / HTTP 1.1

No params appear to be passed.

I'm obviously doing something wrong, so please can someone point out my idiocy.

Update:

As pointed out by The Arioch below, I should have checked that the browser is actually sending the data - so using Chrome developer tools I examined the headers, the results of which are:

Response Headers

  Connection:close
  Content-Type:text/html
  Server:Indy/10.0.52

Request Headers

  Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image  /webp,*/*;q=0.8
  Accept-Encoding:gzip, deflate, br
  Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
  Authorization:Basic YWRtaW46cGFzcw==
  Cache-Control:max-age=0
  Connection:keep-alive
  Content-Length:31
  Content-Type:application/x-www-form-urlencoded
  Host:127.0.0.1:8091
  Origin:http://127.0.0.1:8091
  Referer:http://127.0.0.1:8091/main
  Upgrade-Insecure-Requests:1
  User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36      (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36

Form Data

  firstname:Mickey
  lastname:Mouse

So the browser is definitely sending the form data.

Upvotes: 1

Views: 1783

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 596823

The raw encoded form data is stored in the ARequestInfo.FormParams and ARequestInfo.UnparsedParams properties.

If TIdHTTPServer.ParseParams is true (which it is by default), the decoded form data is stored in the ARequestInfo.Params property, eg:

procedure TForm1.HTTPServer1CommandGet(AThread: TIdPeerThread;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  FirstName, LastName: string;
begin
  ...  
  if (ARequestInfo.CommandType = hcPOST) and
     IsHeaderMediaType(ARequestInfo.ContentType, 'application/x-www-form-urlencoded') then
  begin
    FirstName := ARequestInfo.Params.Values['firstname'];
    LastName := ARequestInfo.Params.Values['lastname'];
    ...
  end;
end;

Note that TIdHTTPServer is a multi-threaded component. The various events, including OnCommandGet, are fired in the context of worker threads. So, if you need to touch UI controls, like your TMemo, you must synchronize with the main UI thread, eg:

procedure TForm1.HTTPServer1CommandGet(AThread: TIdPeerThread;
 ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  ...  
  if (ARequestInfo.CommandType = hcPOST) and
     HeaderIsMediaType(ARequestInfo.ContentType, 'application/x-www-form-urlencoded') then
  begin
    TThread.Synchronize(nil,
      procedure
      begin
        Memo1.Text := ARequestInfo.Params.Text;
      end
    );
    ...
  end;
end;

Also, 10.0.52 is an outdated version of Indy. The current version (at the time of this writing) is 10.6.2.5384.

Upvotes: 2

Related Questions