06-25-2020, 06:44 PM
(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:
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:
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:
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;