你的
CGI
模块生成原始
HTTP response
它应该按原样由IW内容处理程序传输。响应消息包括:
-
-
HTTP标题行
-
分隔页眉和正文的空行
-
正文(案例中的实际图像数据)
THTTPReply
似乎无法控制原始的HTTP响应。它提供了专门的接口来分别处理状态、标题和正文。这就是为什么您需要预处理从CGI返回的流,并通过空行将头与正文分开。然后你可以通过
蒂普雷
. 也许你也只想白名单一些标题,而忽略其余的。
在您使用的代码片段中
ReadStringFromStream
这是毫无意义的,因为无论如何都要丢弃返回的值。它移动的位置
Stream
aReply.SendStream(Stream)
从一开始就发送整个流内容。
另一点是你用
IndyTextEncoding_OSDefault
作为最后一个参数
,这可能是错误的,因为
HTTP header is encoded in ASCII
IndyTextEncoding_ASCII
.
请改为使用以下代码:
function TContentImaqge.Execute(aRequest: THttpRequest; aReply: THttpReply;
const aPathname: string; aSession: TIWApplication;
aParams: TStrings): Boolean;
var
CGIOutput, ContentStream: TMemoryStream;
LocalDoc, Line: string;
CharPos: Integer;
begin
Result := True;
CGIOutput := TMemoryStream.Create;
try
LocalDoc := TIWAppInfo.GetAppPath + 'wwwroot\cgi-bin\newweb\dgate.exe';
RunCGIOutput(LocalDoc, CGIOutput, TIWAppInfo.GetAppPath + 'wwwroot\cgi-bin\newweb\');
if ReadLnFromStream(CGIOutput, Line, -1, IndyTextEncoding_ASCII) then
begin
{ process status line }
CharPos := Pos(' ', Line);
if CharPos > 0 then
begin
aReply.Code := StrToInt(Copy(Line, CharPos + 1, 3));
CharPos := Pos(' ', Line, CharPos);
if CharPos > 0 then
aReply.CodeText := Copy(Line, CharPos + 1);
end;
{ process headers (copy headers as they are) }
while ReadLnFromStream(CGIOutput, Line, -1, IndyTextEncoding_ASCII) and (Line <> '') do
aReply.Headers.Add(Line);
{ at this point CGIOutput.Position is at the beginning of body, so let's just copy
the content to a separate memory stream }
ContentStream := TMemoryStream.Create;
try
ContentStream.CopyFrom(CGIOutput, CGIOutput.Size - CGIOutput.Position);
except
ContentStream.Free;
raise;
end;
aReply.SendStream(ContentStream);
end
else
begin
aReply.Code := 500;
aReply.CodeText := RSHTTPInternalServerError;
aReply.WriteString('CGI module returned malformed response.');
end;
finally
CGIOutput.Free;
end;
end;
另外,请注意,您所附的CGI输出不包含状态行,直接以标题开头(内容类型:…)。如果这是从CGI得到的,那么您应该更新代码来处理这样的情况。