Sending Data to a Server

< BACK  NEXT >
[oR]

So far, all the HTTP calls covered in this chapter have been used to obtain data from an Internet server. Obviously, if you intend to use HTTP to access, for example, enterprise databases, you will need to send data back to the server. This can be done by doing the following:

  • Appending data onto the URL. This technique is used when small amounts of data are to be sent. Special characters, such as spaces, need to be encoded to ensure that the URL only contains legal characters.

  • Using the "POST" HTTP verb. You can send large amounts of data, including whole files.

The first technique is the easier to use, but the second is more flexible.

Sending Data with the URL

Data is appended onto a URL following a "?" character. The data must follow the standard rules regarding legal characters. For example, spaces must be sent as "%20". This requires the data to be encoded by the client application and decoded by the server. You can only append limited amounts of data to a URL since the overall length of the URL is limited, and the limit varies from Internet server to Internet server.

The function InternetCanonicalizeUrl can be used to encode data. This function, through the Flags parameter, allows control over how the encoding takes place. The function will fail if the buffer is not large enough to contain the encoded characters. Because of the nature of the encoding, the returned string can be significantly longer than the string passed for encoding.

Table 8.12. InternetCanonicalizeUrl Encodes data
InternetCanonicalizeUrl
LPCTSTR lpszUrl Pointer to the string to encode.
LPTSTR lpszBuffer Pointer to a buffer to receive the encoded data.
LPDWORD lpdwBufferLength On entry, the length of the buffer pointed to by lpszBuffer.
DWORD dwFlags Flags refining how the encoding takes place. 0 indicates default encoding. For example, ICU_ENCODE_SPACES_ONLY requests that only spaces are encoded to %20.
BOOL Return Value TRUE indicates success, FALSE failure. GetLastError returns ERROR_INSUFFICIENT_BUFFER if the buffer is not sufficiently large.

Listing 8.5 shows a code fragment that prompts the user for a URL and data to append onto the URL. The HTTP connection is opened using InternetOpen. Next, InternetCanonicalizeUrl is called to encode the data, and this data is appended onto the URL. Finally, InternetOpenUrl is called to request the data back from the server. The data can be read using the code shown in Listing 8.1 using InternetReadFile.

Listing 8.5 Sending data with the URL
 if(!GetTextResponse(_T("Enter URL to Display: "),     szURL, MAX_PATH))   return; if(!GetTextResponse(_T("Data To Send: "),     szData, MAX_PATH))   return; hHttpOpen = InternetOpen(_T("Example Agent"),     INTERNET_OPEN_TYPE_DIRECT,     NULL, // no proxy     NULL, // no bypass addresses     0);  // no flags dwBuffLen = MAX_PATH; if(!InternetCanonicalizeUrl(szData,     szDataCan, &dwBuffLen, 0)) {   cout   _T("Could not encode request %d")          GetLastError();   return; } wcscpy(szURLRequest, szURL); wcscat(szURLRequest, szDataCan); cout   _T("URL Request: ")   szURLRequest   endl; hHttpRequest = InternetOpenUrl(hHttpOpen,     szURLRequest, NULL, 0, 0, 0); 

The nature of the URL depends on how the server application is written. The following example shows a URL with data being sent to a Microsoft Visual Basic WebClass application that is called through an Active Server Page (ASP):

  http://MyServer/WinCETest/WinCETest.ASP?WCI=Bounce&WCE=Test %20Data 

In this case, the server is called "MyServer," the path is "WinCETest,", and the resource to be opened is WinCETest.ASP. The data follows the "?". In the case of Visual Basic web classes, the data following WCE= is an entry point into the Visual Basic DLL, and the data following WCE= is passed to the Visual Basic code. Notice how the data "Test Data" has been encoded into "Test%20Data."

If you do not have a suitable site to test against, you can enter the following for the URL:

 http://www.softwarepaths.com/WinCEProgramming/WinCETest.ASP?WCI=Bounce&WCE= 

You can enter anything you like for the data, and the ASP page will send back the data to you as the resource.

Posting Data to the Server

So far, all the HTTP requests sent from the Windows CE device have used the HTTP "GET" verb. This verb simply requests that the given resource is returned to the client. The "POST" verb can be used to send information to the server, and this data can be read by a server application. You can send any type of data (both text and binary), and there is no effective limit to the amount of data that can be sent.

Using "POST" is much the same as using "GET", except that you should do the following:

  • Specify the "POST" verb in HttpOpenRequest.

  • Specify the data to be sent in HttpSendRequest. Note this should be ANSI in the case of text data.

  • Add a Content-Type header to specify the type of data being sent to the server (required when sending data to an ASP or Microsoft Webclass application under IIS).

Listing 8.6 shows code used to send a "POST" HTTP request in the HttpOpenRequest and the sending of data using HttpSendRequest.

Listing 8.6 Using the "POST" verb
 LPCTSTR lpHeader =  _T("Content-Type: application/x-www-form-urlencoded\r\n"); LPCTSTR lpData =  _T("The data to be sent to the Internet Server");     hHttpRequest = HttpOpenRequest(hHttpSession,         _T("POST"),    // verb         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(!HttpAddRequestHeaders(hHttpRequest,         lpHeader,         wcslen(lpHeader),         HTTP_ADDREQ_FLAG_REPLACE |           HTTP_ADDREQ_FLAG_ADD))     {       cout    _T("Could not add HTTP header ")               GetLastError();       goto cleanUp;     }     // convert the data to ANSI     char szAnsi[1024];     wcstombs(szAnsi, lpData, wcslen(lpData));     szAnsi[wcslen(lpData)] = '\0';     if(!HttpSendRequest(hHttpRequest,       NULL, 0,             // no extra headers       (LPVOID)szAnsi,      // data to be sent       strlen(szAnsi)))     // length of data     {       cout   _T("Could not send request ")              GetLastError();       goto cleanUp;     } 

The "Content-Type" header pointed to by lpHeader must be added to the request using HttpAddRequestHeaders before HttpSendRequest is called. Note that this header string should be Unicode. Once this is done, HttpSendRequest is called. The last two parameters of the call specify the pointer to the data (szAnsi) and its length to be sent to the server. Note that this data should be sent as ANSI unless the server application is specifically written to accept Unicode. The usual code can be used to read a response from the server following the call to HttpSendRequest.

Table 8.13. HttpAddRequestHeaders Adds headers to a request
HttpAddRequestHeaders
HINTERNET hHttpRequest Request handle to add headers to.
LPCTSTR lpszHeaders Pointer to the header strings.
DWORD dwHeadersLength Length of the header strings.
DWORD dwModifiers How to add or change the headers: HTTP_ADDREQ_FLAG_ADD adds the header if it does not exist, and HTTP_ADDREQ_FLAG_REPLACE replaces the header if it does exist.
BOOL Return Value TRUE on success, otherwise FALSE.

You can use the following URL if you do not have an Internet site to test against. This Microsoft Visual Basic WebClass application will send back the posted data converted to upper case.

 http://www.softwarepaths.com/WinCEProgramming/WinCETest.ASP? WCI=PostData&WCE= 

< 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