试试下面的代码。它展示了如何Content-Length
从响应头中获取并读取内容本身。
请注意,HTTP 协议远没有那么容易,但是如果您要与自己的服务器或您知道其工作原理的服务器进行通信,您可能会以此为灵感。并且不要忘记OpenSSL
在使用此代码时包含二进制文件(0.9.8 版肯定与 Synapse 兼容)。
uses
blcksock, ssl_openssl;
function HTTPGetText(const Host: string): AnsiString;
var
ContentLength: Integer;
HTTPHeader: AnsiString;
TCPSocket: TTCPBlockSocket;
begin
Result := '';
TCPSocket := TTCPBlockSocket.Create;
try
// initialize TTCPBlockSocket
TCPSocket.ConvertLineEnd := True;
TCPSocket.SizeRecvBuffer := c64k;
TCPSocket.SizeSendBuffer := c64k;
// connect to the host, port 443 is default for HTTP over SSL
TCPSocket.Connect(Host, '443');
// check for socket errors
if TCPSocket.LastError <> 0 then
Exit;
// server name identification
TCPSocket.SSL.SNIHost := Host;
// initialize and connect over OpenSSL
TCPSocket.SSLDoConnect;
// server name identification
TCPSocket.SSL.SNIHost := '';
// check for socket errors
if TCPSocket.LastError <> 0 then
Exit;
// build the HTTP request header
HTTPHeader :=
'GET / HTTP/1.0' + CRLF +
'Host: ' + Host + ':443' + CRLF +
'Keep-Alive: 300' + CRLF +
'Connection: keep-alive' + CRLF +
'User-Agent: Mozilla/4.0' + CRLF + CRLF;
// send the HTTP request
TCPSocket.SendString(HTTPHeader);
// check for socket errors
if TCPSocket.LastError <> 0 then
Exit;
// read the response status, here some servers might give you the content
// note, that we are waiting in a loop until the timeout or another error
// occurs; if we get some terminated line, we break the loop and continue
// to check if that line is the HTTP status code
repeat
HTTPHeader := TCPSocket.RecvString(5000);
if HTTPHeader <> '' then
Break;
until
TCPSocket.LastError <> 0;
// if the line we've received is the status code, like 'HTTP/1.1 200 OK'
// we will set the default value for content length to be read
if Pos('HTTP/', HTTPHeader) = 1 then
begin
ContentLength := -1;
// read the response header lines and if we find the 'Content-Length' we
// will store it for further content reading; note, that again, we are
// waiting in a loop until the timeout or another error occurs; if the
// empty string is received, it means we've read the whole response header
repeat
HTTPHeader := TCPSocket.RecvString(5000);
if Pos('Content-Length:', HTTPHeader) = 1 then
ContentLength := StrToIntDef(Trim(Copy(HTTPHeader, 16, MaxInt)), -1);
if HTTPHeader = '' then
Break;
until
TCPSocket.LastError <> 0;
// and now let's get the content, we know it's size, so we just call the
// mentioned RecvBufferStr function
if ContentLength <> -1 then
Result := TCPSocket.RecvBufferStr(ContentLength, 5000);
end;
TCPSocket.CloseSocket;
finally
TCPSocket.Free;
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Memo1.Text := HTTPGetText('www.meebo.com');
end;