#include <wininet.h>
#include <string.h>
/**
* Retrieves the contents of a file from a remote HTTP server. In
* other words: gets the contents of a webpage. The function is
* synchronous, meaning it will not return until it has retrieved
* the contents of the web page, or it has failed. Expect a time
* delay.
*
* \param zurl A null terminated string of the URL of the web page.
* \param zsize A pointer to an integer that will be set to the size
* (in bytes) of the string returned. If the function
* fails the integer will not be changed. This parameter
* can be NULL.
*
* \return A null-terminated string containing the contents of the
* web page. If the function fails, NULL is returned. Don't
* forget to free the string when you're done with it.
**/
char* openURL(const char* zurl, int* zsize)
{
// This will hold the web page's contents
char* content = NULL;
int content_size = 0;
// Create the buffers that will hold each part of the url
int zurl_len = strlen(zurl) + 1;
char* hostName = (char*)malloc(zurl_len);
char* urlPath = (char*)malloc(zurl_len);
char* extraInfo = (char*)malloc(zurl_len);
// Create a URL_COMPONENTS structure and zero its members
URL_COMPONENTS url;
memset(&url, 0, sizeof(URL_COMPONENTS));
// Tell it how big it is
url.dwStructSize = sizeof(URL_COMPONENTS);
// Place our buffers in the structures
url.lpszHostName = hostName;
url.dwHostNameLength = zurl_len;
url.lpszUrlPath = urlPath;
url.dwUrlPathLength = zurl_len;
url.lpszExtraInfo = extraInfo;
url.dwExtraInfoLength = zurl_len;
// Now break the url apart
if (!InternetCrackUrl(zurl, 0, ICU_DECODE, &url)) goto failURL;
// Append the extraInfo varaible to urlPath because they should always be together
if (url.dwExtraInfoLength != 0)
{
urlPath = (char*)realloc(urlPath, strlen(urlPath) + strlen(extraInfo));
strcat(urlPath, extraInfo);
}
// Enable INET for our application. Use default proxy settings.
HINTERNET hInet = InternetOpen("openURL", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInet == NULL) goto failInet;
// Prepare our connection to the server
HINTERNET hServer = InternetConnect(hInet, hostName, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (hServer == NULL) goto failServer;
// Create our request
HINTERNET hRequest = HttpOpenRequest(hServer, NULL, urlPath, NULL, NULL, NULL, 0, 0);
if (hRequest == NULL) goto failRequest;
// Send out our request
if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0)) goto failRequest;
// Loop until we get all of the webpage contents from the server
DWORD available;
while (InternetQueryDataAvailable(hRequest, &available, 0, 0))
{
// Create a buffer to hold the information from the server
char* buffer = (char*)malloc(available + 1);
// Read the information we've been sent into our buffer
DWORD bytesRead;
if (!InternetReadFile(hRequest, buffer, available, &bytesRead))
{
free(buffer);
goto failRequest;
}
// If were done getting information, break
if (bytesRead == 0) break;
// If this is the first piece of content we've gotten
if (content == NULL)
{
// Copy the contents of the buffer into the newly allocated content
content = (char*)malloc(bytesRead);
content_size = bytesRead;
memcpy(content, buffer, bytesRead);
}
else
{
// Reallocate content
content = (char*)realloc(content, content_size + bytesRead);
// Join the new content with the old
memcpy(content + content_size, buffer, bytesRead);
// Update content_size
content_size += bytesRead;
}
}
// Ensure content is null terminated
content = (char*)realloc(content, ++content_size);
content[content_size - 1] = '\0';
// Set the size
if (zsize != NULL) (*zsize) = content_size;
// Clean up
InternetCloseHandle(hRequest);
InternetCloseHandle(hServer);
InternetCloseHandle(hInet);
free(extraInfo);
free(urlPath);
free(hostName);
return content;
// Clean up when failure occurs
failRequest: InternetCloseHandle(hRequest);
failServer: InternetCloseHandle(hServer);
failInet: InternetCloseHandle(hInet);
failURL:
free(extraInfo);
free(urlPath);
free(hostName);
free(content);
return NULL;
}
Note: This code will compile as C code and as C++ code.
No replies to this topic
#1
Posted 27 January 2010 - 07:08 PM
I made this the other day and thought others might like to use it since I wasn't able to find an easy alternative online. The function uses Window's INET to retrieve the contents of a webpage. Only HTTP is supported, though if you have a serious need for FTP it's not too hard to implement using INET. Function is pretty easy to use, here's the code.
|
|
|
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users


Sign In
Create Account


Back to top









