之前的员工显然不知道 Indy's 的存在TIdHTTP
组件,或者印地的ReadStream()
方法实际上是如何工作的,或者说 HTTP 通常是如何工作的。您应该重写要使用的函数TIdHTTP
并让它为您处理所有细节,例如:
function TMyConnector.GET(aRawHeader: String): String;
begin
FHTTP.ProtocolVersion := ...; // pv1_0 or pv1_1
// Indy has a TIdCookieManager component that can be attached to
// the TIdHTTP.CookieManager property, which handles parsing,
// tracking, and sending back cookies for you for each HTTP
// request, so this should be re-written to utilize that
// functionality...
//
FHTTP.Request.CustomHeaders.Values['Cookie'] := 'UserHPos=IOGLO00003000090000C000BS; '+
'LOSID=qsBiy/wEDCq6tOXFzGbOlTD1lmo5AXdFnCkbzzPn6+qCeheYVyTcumRrjsqh+Hds4Fr2gZDazfDzGN1RA+nnHuQQeBy78ZUgctrZyyy9MnGl2qI/ulkV6EPxAfmmLg/lopRq99f5gAcG/dgtytAJjS+aD5DqtHGrAqjiqgtkwuA=; '+
'LoginHPos=IOGLO00003000090000C000BS; '+
'UIHPos=IOGLO00003000020000500003; '+
'LOSG=61939308-7C83-47ED-B909-2D2D10AD7026; '+
'fControllingBusiness=IOGLO000030000900001000050000200001';
FHTTP.Request.Connection := 'Close';
if ResponseStream = nil then
ResponseStream := TMemoryStream.Create
else
ResponseStream.Size := 0;
try
try
FHTTP.Get('http://' + FHost + '/' + aRawHeader, ResponseStream);
finally
FRawResponse := FHTTP.Response.RawHeaders.Text;
Result := FRawResponse;
end;
except
on E: EIdHTTPProtocolException do
begin
// HTTP error response. You can grab the error content if you need it...
WriteStringToStream(ResponseStream, E.ErrorMessage);
end;
on E: Exception do
begin
// some other error, handle as needed...
end;
end;
end;
如果重写使用TIdHTTP
不可能,那么你必须更新原来的代码才能真正实现基本的HTTP解析。仅仅调用是不够的ReadStream()
, 你必须知道WHEN调用它,并且WHAT传递给它的参数。尝试更多类似这样的事情:
function TMyConnector.GET(aRawHeader: String): String;
var
Headers: TIdHeaderList;
Size: integer;
function InternalReadLn: String;
begin
Result := FSock.IOHandler.ReadLn;
if FSock.IOHandler.ReadLnTimedout then begin
raise EIdReadTimeout.Create('');
end;
end;
function ChunkSize: integer;
var
j: Integer;
s: string;
begin
s := InternalReadLn;
j := Pos(';', s); {do not localize}
if j > 0 then begin
s := Copy(s, 1, j - 1);
end;
Result := StrToInt('$' + Trim(s), 0);
end;
begin
if Not Connected then Connected := True;
if Connected then
begin
FRawRequest := 'GET /'+ aRawHeader + ' HTTP/'+HTTPVerText+#13#10+
'Host: '+FHost+#13#10+
'Cookie: UserHPos=IOGLO00003000090000C000BS; '+
'LOSID=qsBiy/wEDCq6tOXFzGbOlTD1lmo5AXdFnCkbzzPn6+qCeheYVyTcumRrjsqh+Hds4Fr2gZDazfDzGN1RA+nnHuQQeBy78ZUgctrZyyy9MnGl2qI/ulkV6EPxAfmmLg/lopRq99f5gAcG/dgtytAJjS+aD5DqtHGrAqjiqgtkwuA=; '+
'LoginHPos=IOGLO00003000090000C000BS; '+
'UIHPos=IOGLO00003000020000500003; '+
'LOSG=61939308-7C83-47ED-B909-2D2D10AD7026; '+
'fControllingBusiness=IOGLO000030000900001000050000200001'+#13#10+
'Connection: Close'+#13#10+
#13#10;
FSock.IOHandler.Write(FRawRequest);
FRawResponse := FSock.IOHandler.ReadLn(#13#10#13#10,nil);
Result := FRawResponse;
if ResponseStream = nil then ResponseStream := TMemoryStream.Create
else ResponseStream.Size := 0;
Headers := TIdHeaderList.Create(QuoteHTTP);
try
Headers.Text := FRawResponse;
if Pos('chunked', LowerCase(Headers.Values['Transfer-Encoding']) > 0 then
begin
Size := ChunkSize;
while Size <> 0 do begin
FSock.IOHandler.ReadStream(ResponseStream, Size);
InternalReadLn;
Size := ChunkSize;
end;
repeat until InternalReadLn = '';
end
else if Headers.IndexOfName('Content-Length') <> -1 then
begin
FSock.IOHandler.ReadStream(ResponseStream, StrToInt64(Headers.Values['Content-Length']), False);
end
else
FSock.IOHandler.ReadStream(ResponseStream, -1, True);
finally
Headers.Free;
end;
if Connected and (Not KeepAlive) then Connected := False;
end;
end;