//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1997 - 1999 // // File: httptran.cpp // //-------------------------------------------------------------------------- #include "global.hxx" #include #include #include #include #include #include #define REALLOCSIZE 4096 DWORD CHttpTran::Open(const TCHAR * tszURL, DWORD fOpenT) { TCHAR tszDomanName[_MAX_PATH]; TCHAR tszPort[12]; TCHAR * ptch; TCHAR * ptchT; DWORD err; INTERNET_PORT dwPort = INTERNET_OPEN_TYPE_PRECONFIG; // did we get a flag? if( (fOpenT & (GTREAD | GTWRITE)) == 0 ) return(ERROR_INVALID_PARAMETER); // is it a readonly flag, then do gets fOpen = fOpenT; assert(tszURL != NULL); // we must have http:// assert(_tcslen(tszURL) > 7); assert(_tcsnicmp(tszURL, TEXT("http://"), 7) == 0); // copy the Doman Name ptch = (TCHAR *) &tszURL[7]; ptchT = tszDomanName; while(*ptch != _T('/') && *ptch != _T(':') && *ptch != 0) *ptchT++ = *ptch++; *ptchT = 0; // parse out the port number tszPort[0] = 0; if(*ptch == _T(':')) { ptchT = tszPort; while(*ptch != _T('/') && *ptch != 0) *ptchT++ = *ptch++; *ptchT = 0; } // Note, we don't support port numbers if(tszPort[0] != 0) { assert(tszPort[0] == ':'); dwPort = (INTERNET_PORT)atoi(&tszPort[1]); } // save away what to look up. tszPartURL = (TCHAR *) malloc(_tcslen(ptch) + 1); if(NULL == tszPartURL) return ERROR_OUTOFMEMORY; _tcscpy(tszPartURL, ptch); // INTERNET_OPEN_TYPE_DIRECT, if( (hIOpen = InternetOpen( TEXT("Transport"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0)) == NULL || (hIConnect = InternetConnect(hIOpen, tszDomanName, dwPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0)) == NULL ) { err = GetLastError(); return(err); } // If this is a GET, do a dummy send if( fOpen == GTREAD && ((hIHttp = HttpOpenRequest(hIConnect, TEXT("GET"), tszPartURL, HTTP_VERSION, NULL, NULL, INTERNET_FLAG_DONT_CACHE, 0)) == NULL || HttpSendRequest(hIHttp, TEXT("Accept: */*\r\n"), (DWORD) -1, NULL, 0) == FALSE) ) { err = GetLastError(); return(err); } return(ERROR_SUCCESS); } DWORD CHttpTran::Send(DWORD dwEncodeType, DWORD cbSendBuff, const BYTE * pbSendBuff) { TCHAR tszBuff[1024]; DWORD err; TCHAR * tszContentType; if( pbRecBuf != NULL || (fOpen & GTWRITE) != GTWRITE) return(ERROR_INVALID_PARAMETER); switch( dwEncodeType ) { case ASN_ENCODING: tszContentType = TEXT("application/x-octet-stream-asn"); break; case TLV_ENCODING: tszContentType = TEXT("application/x-octet-stream-tlv"); break; case IDL_ENCODING: tszContentType = TEXT("application/x-octet-stream-idl"); break; case OCTET_ENCODING: tszContentType = TEXT("application/octet-stream"); break; default: tszContentType = TEXT("text/*"); break; } // say how long the buffer is _stprintf(tszBuff, TEXT("Content-Type: %s\r\nContent-Length: %d\r\nAccept: %s\r\n"), tszContentType, cbSendBuff,tszContentType); if( (hIHttp = HttpOpenRequest(hIConnect, TEXT("POST"), tszPartURL, HTTP_VERSION, NULL, NULL, INTERNET_FLAG_DONT_CACHE, 0)) == NULL ) { return(GetLastError()); } // send of the request, this will wait for a response if( HttpSendRequest(hIHttp, tszBuff, (DWORD) -1, (LPVOID) pbSendBuff, cbSendBuff) == FALSE ) { err = GetLastError(); // close out the handle assert(hIHttp != NULL); InternetCloseHandle(hIHttp); hIHttp = NULL; return(err); } return(ERROR_SUCCESS); } DWORD CHttpTran::Receive(DWORD * pdwEncodeType, DWORD * pcbReceiveBuff, BYTE ** ppbReceiveBuff) { TCHAR tszBuff[1024]; DWORD cbBuff, cbBuffRead, cbBuffT; DWORD err; assert(pcbReceiveBuff != NULL && ppbReceiveBuff != NULL); *ppbReceiveBuff = NULL; *pcbReceiveBuff = 0; if( pbRecBuf != NULL || (fOpen & GTREAD) != GTREAD || hIHttp == NULL) return(ERROR_INVALID_PARAMETER); // get the content type if( pdwEncodeType != NULL) { cbBuff = sizeof(tszBuff); if(HttpQueryInfo( hIHttp, HTTP_QUERY_CONTENT_TYPE, tszBuff, &cbBuff, NULL) == FALSE) return(GetLastError()); assert(cbBuff > 0); // for now assert we have a content type of TLV_ENCODING if(!_tcscmp(TEXT("application/x-octet-stream-asn"), tszBuff)) *pdwEncodeType = ASN_ENCODING; else if(!_tcscmp(TEXT("application/x-octet-stream-idl"), tszBuff)) *pdwEncodeType = IDL_ENCODING; else if(!_tcscmp(TEXT("application/x-octet-stream-tlv"), tszBuff)) *pdwEncodeType = TLV_ENCODING; else if(!_tcscmp(TEXT("application/octet-stream"), tszBuff)) *pdwEncodeType = OCTET_ENCODING; else *pdwEncodeType = ASCII_ENCODING; } // allocate a buffer cbBuff = REALLOCSIZE; if( (pbRecBuf = (PBYTE) malloc(cbBuff)) == NULL ) return(ERROR_NOT_ENOUGH_MEMORY); // read the data cbBuffRead = 0; cbBuffT = 1; while(cbBuffT != 0) { cbBuffT = 0; if((cbBuff - cbBuffRead) == 0) { cbBuff += REALLOCSIZE; pbRecBuf = (PBYTE) realloc(pbRecBuf, cbBuff); if( pbRecBuf == NULL ) { free(pbRecBuf); InternetCloseHandle(hIHttp); return(ERROR_NOT_ENOUGH_MEMORY); } } if(InternetReadFile(hIHttp, &pbRecBuf[cbBuffRead], (cbBuff - cbBuffRead), &cbBuffT) == FALSE ) { err = GetLastError(); free(pbRecBuf); InternetCloseHandle(hIHttp); return(err); } cbBuffRead += cbBuffT; } // pass back the info *ppbReceiveBuff = pbRecBuf; *pcbReceiveBuff = cbBuffRead; return(ERROR_SUCCESS); } DWORD CHttpTran::Free(BYTE * pb) { assert(pb == pbRecBuf); free(pbRecBuf); pbRecBuf = NULL; return(ERROR_SUCCESS); } DWORD CHttpTran::Close(void) { // free any buffers if(pbRecBuf != NULL) { free(pbRecBuf); pbRecBuf = NULL; } if(tszPartURL != NULL) { free(tszPartURL); tszPartURL = NULL; } if(hIHttp != NULL) { InternetCloseHandle(hIHttp); hIHttp = NULL; } if(hIConnect != NULL) { InternetCloseHandle(hIConnect); hIConnect = NULL; } if(hIOpen != NULL) { InternetCloseHandle(hIOpen); hIOpen = NULL; } return(ERROR_SUCCESS); }