static const String CRLF = "/r/n";
int GetResponse(const String data, const String SContent)
{
int Result = -1;
TStrings *List = new TStringList;
List->Text = data.LowerCase();
for(int i = 0; i < List->Count; ++i)
{
int start = List->Strings.Pos(SContent);
if(start)
{
String s = List->Strings.SubString(SContent.Length() + 1, MaxInt);
int j = LastDelimiter(" ", s);
while (j)
{
s = s.SubString(1, j - 1);
j = LastDelimiter(" ", s);
}
Result = s.ToInt();
break;
}
}
delete List;
return Result;
}
int GetHTTPServer(const String data)
{
static const String SContent = "http/1.1 ";
return GetResponse(data, SContent);
}
int GetContentSize(const String data)
{
static const String SContent = "content-length: ";
return GetResponse(data, SContent);
}
bool WaitForData(int s, int Timeout)
{
TFDSet FDSet;
TTimeVal TimeVal;
TimeVal.tv_sec = Timeout;
TimeVal.tv_usec = 0;
FD_ZERO(&FDSet);
FD_SET(s, &FDSet);
return(select(0, &FDSet, NULL, NULL, &TimeVal) > 0);
}
String ReceiveLine(int s)
{
char C;
int RetLen;
String Result = "";
while(1)
{
RetLen = recv(s, &C, 1, 0);
if(0 == RetLen || SOCKET_ERROR == RetLen) throw ESocketError("Socket read error");
Result += C;
if(Result.Pos(CRLF) > 0) break;
}
return Result;
}
String SendCommand(int s, String Command)
{
String Data = "", Result = "";
send(s, Command.c_str(), Command.Length(), 0);
while(WaitForData(s, 5))
{
Data = ReceiveLine(s);
if(CRLF == Data)
break;
else
Result += Data;
}
return Result;
}
static const String SUserAgent =
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)";
static const String SRequestFileHead =
"HEAD %s HTTP/1.1" + CRLF +
"Pragma: no-cache" + CRLF +
"Cache-Control: no-cache" + CRLF +
SUserAgent + CRLF +
"Host: %s" + CRLF + CRLF;
static const String SRequestFileContent =
"GET %s HTTP/1.1" + CRLF +
"Accept: */*" + CRLF +
SUserAgent + CRLF +
"RANGE: bytes=%d-" + CRLF +
"Host: %s" + CRLF + CRLF;
void ExtractHTTPHost(const String AURL, String &AHost, String &AFileName)
{
static const String HTTPHEAD = "http://";
int Index, HTTPLen = HTTPHEAD.Length();
AHost = AURL;
Index = AURL.Pos(HTTPHEAD);
if(Index)
AHost = AHost.SubString(Index + HTTPLen, MaxInt);
Index = AHost.Pos("/");
while(Index)
{
AHost = AHost.SubString(1, Index - 1);
Index = AHost.Pos("/");
}
Index = AURL.Pos(AHost) + AHost.Length();
AFileName = AURL.SubString(Index, MaxInt);
}
in_addr LookupName(const String HostName)
{
in_addr Result;
hostent *p = gethostbyname(HostName.c_str());
memset(&Result, 0, sizeof(Result));
if (p)
Move(p->h_addr_list[0], &Result, p->h_length);
return Result;
}
int GetHttpHead(String URLFile)
{
int Result = SOCKET_ERROR;
WSAData data;
if (WSAStartup(MAKEWORD(2, 2), &data) != 0)
return Result;
try
{
int s = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
if (INVALID_SOCKET == s)
throw ESocketError("create socket error");
try
{
AnsiString Host, FileName;
ExtractHTTPHost(URLFile, Host, FileName);
//如果只是个主机,那访问“/”
if (FileName == "") FileName = "/";
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr = LookupName(Host);
addr.sin_port = htons(80);
int ret = connect(s, (sockaddr*)&addr, sizeof(addr));
if (SOCKET_ERROR == ret)
throw Exception("can't not connect");
String Command = Format(SRequestFileHead, ARRAYOFCONST((FileName, Host)));
String Data = SendCommand(s, Command);
Result = GetContentSize(Data);
}
__finally
{
closesocket(s);
}
}
__finally
{
WSACleanup();
}
return Result;
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Caption = GetHttpHead("www.delphibbs.com");
}