You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
312 lines
9.0 KiB
312 lines
9.0 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1997 - 1999
|
|
//
|
|
// File: httptran.cpp
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
#include "global.hxx"
|
|
|
|
#include <windows.h>
|
|
#include <tchar.h>
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <memory.h>
|
|
|
|
|
|
#define REALLOCSIZE 4096
|
|
|
|
DWORD CHttpTran::Open(const TCHAR * tszURL, DWORD fOpenT) {
|
|
|
|
TCHAR tszDomanNameDef[_MAX_PATH];
|
|
TCHAR tszPort[12];
|
|
TCHAR * tszDomanName;
|
|
TCHAR * ptch;
|
|
TCHAR * ptchT;
|
|
DWORD err;
|
|
DWORD dwLen;
|
|
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);
|
|
|
|
// make sure we can't overflow tszDomanName
|
|
dwLen = _tcslen((TCHAR *)&tszURL[7]);
|
|
if (dwLen < _MAX_PATH) {
|
|
// it will fit, so use our pre-allocated buffer
|
|
tszDomanName = tszDomanNameDef;
|
|
} else {
|
|
// it might not fit, so reallocate a new buffer.
|
|
tszDomanName = (TCHAR *)malloc(sizeof(TCHAR) * (dwLen + 1));
|
|
if (NULL == tszDomanName)
|
|
return ERROR_OUTOFMEMORY;
|
|
}
|
|
|
|
// 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 - tszPort) < 11 )
|
|
*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) * sizeof(TCHAR));
|
|
if(NULL == tszPartURL) {
|
|
if (tszDomanName != tszDomanNameDef)
|
|
free(tszDomanName);
|
|
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();
|
|
if (tszDomanName != tszDomanNameDef)
|
|
free(tszDomanName);
|
|
return(err);
|
|
}
|
|
|
|
// we don't need tszDomanName anymore, so free it if it was allocated
|
|
if (tszDomanName != tszDomanNameDef)
|
|
free(tszDomanName);
|
|
|
|
// 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;
|
|
VOID *pvTemp;
|
|
|
|
|
|
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;
|
|
pvTemp = realloc(pbRecBuf, cbBuff);
|
|
if( pvTemp == NULL ) {
|
|
free(pbRecBuf);
|
|
pbRecBuf = NULL;
|
|
InternetCloseHandle(hIHttp);
|
|
return(ERROR_NOT_ENOUGH_MEMORY);
|
|
} else {
|
|
pbRecBuf = (PBYTE) pvTemp;
|
|
}
|
|
}
|
|
|
|
if(InternetReadFile(hIHttp, &pbRecBuf[cbBuffRead], (cbBuff - cbBuffRead), &cbBuffT) == FALSE ) {
|
|
err = GetLastError();
|
|
free(pbRecBuf);
|
|
pbRecBuf = NULL;
|
|
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);
|
|
}
|