Const int recv_buffer_len = 1024;
//////////////////////////////////////// //////////////////////////////
// Construction/destruction
//////////////////////////////////////// //////////////////////////////
Dlrequest: dlrequest ()
{
}
Dlrequest ::~ Dlrequest ()
{
}
//************************************** **************************************** *************************
// Gethostaddress:
// Resolve using DNS or similar (wins, etc) the IP
// Address for a domain name such as www.wdj.com.
//************************************** **************************************** *************************
DWORD dlrequest: gethostaddress (lpcstr host)
{
Struct hostent * Phe;
Char * P;
PHE = gethostbyname (host );
If (PHE = NULL)
Return 0;
P = * phe-> h_addr_list;
Return * (DWORD *) P );
}
//************************************** **************************************** *************************
// Sendstring:
// Send a string (NULL terminated) over the specified socket.
//************************************** **************************************** *************************
Void dlrequest: sendstring (socket sock, lpcstr Str)
{
Send (sock, STR, strlen (STR), 0 );
}
//************************************** **************************************** *************************
// Validhostchar:
// Return true if the specified character is valid
// For a host name, I. e. A-Z or 0-9 or -.:
//************************************** **************************************** *************************
Bool dlrequest: validhostchar (char ch)
{
Return (isalpha (CH) | isdigit (CH)
| CH = '-' | CH = '.' | CH = ':');
}
Void dlrequest: parseurl (STD: String URL, lpstr protocol, int lprotocol, lpstr host, int lhost, lpstr request, int lrequest, int * port)
{
Char * Work, * PTR, * ptr2;
* Protocol = * Host = * request = 0;
* Port = 80;
Work = _ strdup (URL. c_str ());
_ Strupr_s (work, strlen (work) + 1 );
PTR = strchr (work, ':'); // find protocol if any
If (PTR! = NULL)
{
* (PTR ++) = 0;
Lstrcpyn (protocol, work, lprotocol );
}
Else
{
Lstrcpyn (protocol, "HTTP", lprotocol );
PTR = work;
}
If (* PTR = '/') & (* (PTR + 1) = '/') // skip past opening/'s
PTR + = 2;
Ptr2 = PTR; // find host
While (validhostchar (* ptr2) & * ptr2)
Ptr2 ++;
* Ptr2 = 0;
Lstrcpyn (host, PTR, lhost );
Lstrcpyn (request, URL. c_str () + (ptr2-work), lrequest); // find the request
PTR = strchr (host, ':'); // find the port number, if any
If (PTR! = NULL)
{
* PTR = 0;
* Port = atoi (PTR + 1 );
}
Free (work );
}
Int dlrequest: requesthttpdl (STD: String URL)
{
Wsadata;
Char Protocol [20];
Char host [256];
Int L, port, chars, err;
Char request [256] = {0 };
Parseurl (URL, protocol, sizeof (Protocol), host, sizeof (host), // parse the URL
Request, sizeof (request), & Port );
If (strcmp (protocol, "HTTP "))
Return 1;
Err = wsastartup (0x0101, & wsadata); // init Winsock
If (Err! = 0)
Return 1;
Socket sock = socket (af_inet, sock_stream, 0 );
If (sock = invalid_socket)
{
Return 1;
}
Sockaddr_in sin;
Sin. sin_family = af_inet; // connect to Web sever
Sin. sin_port = htons (unsigned short) Port );
Sin. sin_addr.s_addr = gethostaddress (host );
If (connect (sock, (lpsockaddr) & sin, sizeof (sockaddr_in )))
{
Return 1;
}
If (! * Request)
Lstrcpyn (request, "/", sizeof (request ));
// Format the Request Header
STD: String strheadsend ("get ");
Strheadsend + = request;
Strheadsend + = "HTTP/1.0 \ r \ n ";
Strheadsend + = "accept: */* \ r \ n ";
Strheadsend + = "Accept-language: En-US \ r \ n ";
Strheadsend + = "Host :";
Strheadsend + = host;
Strheadsend + = "\ r \ n ";
// Send the request header
Sendstring (sock, strheadsend. c_str ());
// Membuffer headersbuffer, messagebuffer;
//
// Membuffercreate (& headersbuffer );
Chars = 0;
Bool done;
Done = false;
Char buffer [recv_buffer_len] = {0 };
Int nposition = 0;
While (! Done)
{
L = Recv (sock, buffer + nposition, 1, 0 );
If (L <0)
Done = true;
Switch (* (buffer + nposition ))
{
Case '\ R ':
Break;
Case '\ N ':
If (chars = 0)
Done = true;
Chars = 0;
Break;
Default:
Chars ++;
Break;
}
Nposition ++;
}
// Obtain the status code
/// 200 OK
Client request successful
/// 400 bad request
The client has a syntax error and cannot be understood by the server.
/// 401 unauthorized
Unauthorized request
/// 403 Forbidden
The server received the request but refused to provide the service.
// 404 not found
The requested resource does not exist. An incorrect URL may be entered.
// 500 an unexpected error occurred on the internal server error Server
// 503 server unavailable
The server cannot process client requests currently, and may return to normal after a period of time
Char szhttpver [32] = {0 };
Int nstatuscode = 0;
Sscanf (buffer, "% S % d", szhttpver, & nstatuscode );
If (200! = Nstatuscode)
{
If (403 = nstatuscode | 503 = nstatuscode)
{
}
Else
{
Return 1; // failed
}
}
// Obtain the object Length
Int nfilelength = 0;
Char * pfindcl = strstr (buffer, "Content-Length :");
If (pfindcl! = NULL)
{
Char sztemp [32] = {0 };
Sscanf (pfindcl, "% S % d", sztemp, & nfilelength );
}
// Obtain the path
Char szdirectory [max_path] = {0 };
Getcurrentdirectory (max_path, szdirectory );
STD: String strfilename = szdirectory;
Strfilename + = request;
STD: Replace (strfilename. Begin (), strfilename. End (),'\\','/');
// Obtain the original file name
STD: String strorigfilename = strfilename;
// Int findpos = strfilename. find_last_of ("/");
// If (findpos! = String: NPOs)
//{
// Strorigfilename = strfilename. substr (findpos + 1 );
//}
Strfilename + = ". tmp ";
// Change the file name to a temporary file name and restore it after the download is complete.
File * pfile = NULL;
Fopen_s (& pfile, strfilename. c_str (), "WB ");
// Open a file and write it. If the file exists, clear it.
If (! Pfile)
{
Return 1;
}
Int nrecvedsize = 0;
// Number of received messages
Int NPOs = 0;
// Offset
While (true)
{
Int nrecv = Recv (sock, buffer + NPOs, recv_buffer_len-NPOs, 0 );
If (nrecv> 0)
{
Nrecvedsize + = nrecv;
NPOs + = nrecv;
If (NPOs> = recv_buffer_len & nrecvedsize <nfilelength) // The buff is full, but the file is not accepted.
{
// Write the content to the file
Fwrite (buffer, recv_buffer_len, 1, pfile );
NPOs = 0;
}
Else if (nrecvedsize> = nfilelength) // the file has been received
{
// After receiving the file, save the content
Fwrite (buffer, NPOs, 1, pfile );
Fclose (pfile );
// Modify the file name
Rename (strfilename. c_str (), strorigfilename. c_str ());
Break;
}
}
Else if (0 = nrecv)
{
// Disable socket
Break;
}
Else
{
Int nerrcode = wsagetlasterror ();
Break;
}
}
Closesocket (sock );
Return 0;
}