More Complex HTTP Requests Using a Session

< BACK  NEXT >
[oR]

The simple HTTP request described in previous sections allows resources to be downloaded. However, you will need more control when sending data to the server or making more complex requests. For example, you may want to specify usernames and passwords. This section describes how to open a request, to send headers, and to send data to the server.

The following calls are required in order to make HTTP requests:

  1. InternetOpen to initialize the Windows CE Internet functions and return a handle to access other Internet functions

  2. InternetConnect to make a connection to the Internet server and return a connection, or session, handle

  3. HttpOpenRequest to specify the URL (Universal Resource Locator) of the resource to be acquired (for example, the HTML page) and return a request handle

  4. HttpSendRequest to send the request specified in HttpOpenRequest to the server

  5. InternetReadFile repeatedly until all the data has been read from the server

  6. InternetCloseHandle on each handle returned from steps 1-3

Certain steps in the above list can be repeated. For example, if you want to request multiple HTML files from the same server, you can repeat steps 3 and 4 as required. You need only call step 1 once when the application starts, and step 6 for the handle returned from InternetOpen when the application terminates (Figure 8.2).

Figure 8.2. Function-calling sequence for Internet and HTTP functions
graphics/08fig02.gif

Cracking the URL InternetCrackUrl

Each resource on the Internet or on an intranet has a unique name called a Universal Resource Locator, or URL. The URL contains information such as the following:

  1. The protocol used to access the URL (such as HTTP).

  2. The server the resource is located on, either as a named server (for example, www.microsoft.com) or an IP address (192.168.0.2).

  3. The resource name's location on the server. This is typically a folder or directory specification including the name of the file.

  4. The port number used on the server for the protocol being specified. Most protocols usually have a default port number (HTTP is 80), but this may be different on some servers.

A fully qualified URL, including a port number and fully qualified resource name, looks like "http://www.microsoft.com:80/windowsce/default.asp," which can be shortened using defaults to http://www.microsoft.com/windowsce/, since 80 is the default port number and default.asp is the default resource name for this site.

When you receive a URL from the user, you need to be able to parse out the server name and resource name, and this can become quite complex. Fortunately, Windows CE provides the InternetCrackUrl function for doing this (Table 8.5).

Table 8.5. InternetCrackURL Breaks a URL into components
InternetCrackURL
LPCTSTR lpszUrl Pointer to the URL to be parsed
DWORD dwUrlLength Length of the URL, or zero if NULL-terminated
DWORD dwFlags Set to 0 to parse URL without encoding or decoding characters
LPURL_COMPONENTS lpUrlComponents URL_COMPONENTS structure into which the parsed URL elements are returned
BOOL Return Value TRUE for success, FALSE for failure

The trick to using this function successfully is the initialization of the URL_COMPONENTS structure. This structure contains pointers to the various possible elements of the URL. These pointers must either be initialized to NULL if the element is not to be returned, or point at a string buffer if it is to be returned. In the following code fragment a URL_COMPONENT structure is initialized to return the server name and the path to the resource. Further, the dwStructSize member must be initialized to the size of the structure.

 URL_COMPONENTS crackedURL; TCHAR szServer[1024]; TCHAR szPath[1024]; memset(&crackedURL, 0, sizeof(crackedURL)); crackedURL.dwStructSize = sizeof(crackedURL); crackedURL.lpszHostName = szServer; crackedURL.dwHostNameLength = 1024; crackedURL.lpszUrlPath = szPath; crackedURL.dwUrlPathLength = 1024; InternetCrackUrl(szURL, 0, 0, &crackedURL); 

In this code fragment, the string szURL contains the full URL (for example, http://www.microsoft.com/windowsce/default.asp. On return lpszHostName would contain www.microsoft.com and lpszURLPath would contain "/windowsce/default.asp".

Connecting to a Server InternetConnect

The function InternetConnect (Table 8.6) is used to make a connection to a specified server, and is passed access information (for example, the user-name and password to connect with) and the port number and protocol to use. Once a connection has been made, multiple requests can be made to retrieve resources.

Table 8.6. InternetConnect Connects to a server
InternetConnect
HINTERNET hInternet Handle returned from InternetOpen
LPCTSTR lpszServerName Server name, e.g. "www.microsoft.com"
INTERNET_PORT nServerPort Port number, e.g. INTERNET_DEFAULT_HTTP_PORT for HTTP
LPCTSTR lpszUserName Pointer to the user name used to validate access to the server, or NULL for anonymous login
LPCTSTR lpszPassword Pointer to the password, or NULL for anonymous login
DWORD dwService Service or protocol to use, e.g. INTERNET_SERVICE_HTTP
DWORD dwFlags Flags specifying options, or 0 for no options
DWORD dwContext Context value used in callback functions
HANDLE Return Value Session handle, or NULL if function call fails

Most servers on the Internet do not require valid usernames and passwords they use anonymous login. In this situation, the call to InternetConnect is straightforward. In the following code fragment, a connection is made to the server name returned from cracking a fully qualified URL using the HTTP protocol.

 HINTERNET hHttpSession = NULL; hHttpSession = InternetConnect(hHttpOpen,   crackedURL.lpszHostName,    // server name   INTERNET_DEFAULT_HTTP_PORT,   NULL     // username   NULL,    // password   INTERNET_SERVICE_HTTP,   0,   // no flags   0); // no context 

There are a number of issues to consider when connecting to a secure Internet site, and these are covered later in the chapter.

Obtaining a Request Handle HttpOpenRequest

All the functions used so far are generic Internet functions they are used for HTTP, FTP, and any other supported protocols. The function HttpOpenRequest (Table 8.7) is, as its name implies, specific to the HTTP protocol and is used to open a handle through which a request to download a resource (such as a file or image) is made.

Simple requests generally use the GET verb. Small amounts of information can be sent to the server in the URL. The POST verb is used for sending larger amounts of data (such as files) to the server. These topics are covered later in this chapter.

Table 8.7. HttpOpenRequest Opens a request handle
HttpOpenRequest
HINTERNET hHttpSession Handle returned from InternetConnect.
LPCTSTR lpszVerb HTTP verb, usually either "GET" or "POST". NULL specifies "GET".
LPCTSTR lpszObjectName Resource path and name obtained from Internet-CrackUrl.
LPCTSTR lpszVersion HTTP version to use, or NULL for the default "HTTP/1.0".
LPCTSTR lpszReferrer URL of the document from which a hypertext jump was made to this resource. NULL for no referrer.
LPCTSTR *lplpszAcceptTypes Types of documents that the client can accept. NULL implies only "text/*" documents.
DWORD dwFlags Options for connection semantics, etc. 0 for no options. Most Windows NT options are not supported in Windows CE.
DWORD dwContext Context value used in callback functions.
HANDLE Return Value Request handle, or NULL on failure.

The next code fragment shows how to make a simple request to an HTTP server using the resource path obtained through calling InternetCrackUrl.

 hHttpRequest = HttpOpenRequest(hHttpSession,   NULL,    // verb is 'GET'   crackedURL.lpszUrlPath,   NULL,    // default version   NULL,    // no referrer   NULL,    // only accept text/* files   0,    // no flags   0);   // no context for call backs 

Making the Request HttpSendRequest

After opening a request using HttpOpenRequest, the function HttpSendRequest (Table 8.8) is called to send the request off to the server:

 HttpSendRequest(hHttpRequest,   NULL, 0,          // no headers   0, 0));        // no optional data 

Additional HTTP headers can be specified when the request is sent by calling HttpSendRequest. Alternatively, additional headers can be added using the function HttpAddRequestHeaders before the request is sent. This is illustrated later in the chapter.

Table 8.8. HttpSendRequest Sends a request to the server
HttpSendRequest
HINTERNET hRequest Request handle obtained from HttpOpenRequest
LPCTSTR lpszHeaders Additional headers, or NULL for none
DWORD dwHeadersLength Length of additional headers, or 0 for none
LPVOID lpOptional Optional data, or NULL for none
DWORD dwOptionalLength Length of optional data, or 0 for none
BOOL Return Value TRUE on success, otherwise FALSE

Listing 8.2 shows the entire code used to prompt the user for a URL and display the HTML code returned from the server.

Listing 8.2 Making an HTTP request using a session
 #define CHUNKSIZE 500 void Listing8_2() {   TCHAR szURL[MAX_PATH + 1];   HINTERNET hHttpOpen = NULL;   HINTERNET hHttpSession = NULL;   HINTERNET hHttpRequest = NULL;   char charBuffer[CHUNKSIZE + 1];   TCHAR szBuffer[CHUNKSIZE + 1];   DWORD dwRead;   URL_COMPONENTS crackedURL;   TCHAR szServer[1024];   TCHAR szPath[1024];   if(!GetTextResponse(_T("Enter URL to Display: "),         szURL, MAX_PATH))      return;     hHttpOpen = InternetOpen(        _T("Example Agent"),        INTERNET_OPEN_TYPE_DIRECT,        NULL, // no proxy        NULL, // no bypass addresses        0); // no flags   if(hHttpOpen == NULL)   {     cout   _T("Could not open internet session ")            GetLastError();     goto cleanUp;   }   // Crack the URL to get the server name   memset(&crackedURL, 0, sizeof(crackedURL));   crackedURL.dwStructSize = sizeof(crackedURL);   crackedURL.lpszHostName = szServer;   crackedURL.dwHostNameLength = 1024;   crackedURL.lpszUrlPath = szPath;   crackedURL.dwUrlPathLength = 1024;   if(!InternetCrackUrl(szURL, 0, 0, &crackedURL))   {      cout   _T("Cannot crack URL")   GetLastError();      goto cleanUp;   }   hHttpSession = InternetConnect(hHttpOpen,      crackedURL.lpszHostName, // server name      INTERNET_DEFAULT_HTTP_PORT,      NULL,           // username      NULL,           // password      INTERNET_SERVICE_HTTP,      0, // no flags      0); // no context   if(hHttpSession == NULL)   {     cout   _T("Could not open Internet connection")            GetLastError();     goto cleanUp;   }   hHttpRequest = HttpOpenRequest(hHttpSession,        NULL,           // verb is 'GET'        crackedURL.lpszUrlPath,        NULL,           // default version        NULL,           // no referrer        NULL,           // only accept text/* files        0,      // no flags        0);     // no context for call backs   if(hHttpRequest == NULL)   {     cout   _T("Could not get HTTP request ")            GetLastError();     goto cleanUp;   }   if(!HttpSendRequest(hHttpRequest,      NULL, 0,            // no headers      0, 0))     // no optional data   {     cout   _T("Could not read data ")            GetLastError();     goto cleanUp;   }   do   {      // read from Internet HTTP server      if(!InternetReadFile(hHttpRequest, charBuffer,            CHUNKSIZE, &dwRead))      {        cout   _T("Could not send request")              GetLastError();        goto cleanUp;      }      // convert to Unicode and display      charBuffer[dwRead] = '\0';      mbstowcs(szBuffer, charBuffer, dwRead);      szBuffer[dwRead] = '\0';      cout   szBuffer;   } while(dwRead > 0); cleanUp:   if(hHttpRequest != NULL)      InternetCloseHandle(hHttpRequest);   if(hHttpSession != NULL)      InternetCloseHandle(hHttpSession);   if(hHttpOpen != NULL)      InternetCloseHandle(hHttpOpen); } 

< BACK  NEXT >


Windows CE 3. 0 Application Programming
Windows CE 3.0: Application Programming (Prentice Hall Series on Microsoft Technologies)
ISBN: 0130255920
EAN: 2147483647
Year: 2002
Pages: 181

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net