Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Capturing HTML POST with Delphi? (Indy)
#2
(Copying my answer to your same question on StackOverflow):

First off, let me start by just saying this:

- if ARequestInfo.Command = 'POST' then should be changed to either

  if TextIsSame(ARequestInfo.Command, 'POST') then

  or better

  if ARequestInfo.CommandType = hcPOST then

- OnCommand... event handlers are fired in the context of a worker thread, so any access to your UI MUST be synchronized with the main UI thread.

Now then, the HTML you have shown will post the webform values to an HTTP server using the "application/x-www-webform-urlencoded" media type.  In the TIdHTTPServer.OnCommandGet event, the ARequestInfo.PostStream property is not used with that media type and will be nil.  The posted webform values will instead be available in their original unparsed format in the ARequestInfo.FormParams and ARequestInfo.UnparsedParams properties, and in a parsed format in the ARequestInfo.Params property if the TIdHTTPServer.ParseParams property is True (which it is by default).

Try this instead:

Code:
procedure TForm1.serviceCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  testValue: string;
begin
  if ARequestInfo.URI <> '/test.php' then
  begin
    AResponseInfo.ResponseNo := 404;
    Exit;
  end;
  if ARequestInfo.CommandType <> hcPOST then
  begin
    AResponseInfo.ResponseNo := 405;
    Exit;
  end;
  testValue := ARequestInfo.Params.Values['test'];
  TThread.Queue(nil,
    procedure
    begin
      LOG.Lines.Add('test: ' + testValue);
    end
  );
  AResponseInfo.ResponseNo := 200;
end;

That being said, "form-data" in your test tool refers to the "multipart/form-data" media type.  In HTML, if you want to post your webform using that media type, you have to explicitly state that in the enctype parameter of the <form> element, eg:

Code:
<form method="post" action="http://localhost:99/test.php" enctype="multipart/form-data">
    <input type="hidden" name="test" value="04545">
    <input type="submit" value="send"/>
</form>

In which case, TIdHTTPServer does not currently support parsing "multipart/form-data" posts, so ARequestInfo.PostStream will not be nil, providing the raw bytes of the webform so you can parse the data manually as needed.

You can differentiate the media type used for posting the webform by looking at the ARequestInfo.ContentType property, eg:

Code:
procedure TForm1.serviceCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  testValue: string;
  data: string;
begin
  if ARequestInfo.URI <> '/test.php' then
  begin
    AResponseInfo.ResponseNo := 404;
    Exit;
  end;
  if ARequestInfo.CommandType <> hcPOST then
  begin
    AResponseInfo.ResponseNo := 405;
    Exit;
  end;
  if IsHeaderMediaType(ARequestInfo.ContentType, 'application/x-www-form-urlencoded') then
  begin
    testValue := ARequestInfo.Params.Values['test'];
    TThread.Queue(nil,
      procedure
      begin
        LOG.Lines.Add('test: ' + testValue);
      end
    );
    AResponseInfo.ResponseNo := 200;
  end
  else if IsHeaderMediaType(ARequestInfo.ContentType, 'multipart/form-data') then
  begin
    data := ReadStringFromStream(ARequestInfo.PostStream);
    TThread.Queue(nil,
      procedure
      begin
        LOG.Lines.Add('form-data: ' + data);
      end
    );
    AResponseInfo.ResponseNo := 200;
  end else
  begin
    AResponseInfo.ResponseNo := 415;
  end;
end;

Reply


Messages In This Thread
RE: Capturing HTML POST with Delphi? (Indy) - by rlebeau - 06-25-2020, 06:44 PM

Forum Jump:


Users browsing this thread: 1 Guest(s)