Source code of Windows XP (NT5)
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.

282 lines
7.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: httptran.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "global.hxx"
  11. #include <windows.h>
  12. #include <tchar.h>
  13. #include <assert.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <memory.h>
  17. #define REALLOCSIZE 4096
  18. DWORD CHttpTran::Open(const TCHAR * tszURL, DWORD fOpenT) {
  19. TCHAR tszDomanName[_MAX_PATH];
  20. TCHAR tszPort[12];
  21. TCHAR * ptch;
  22. TCHAR * ptchT;
  23. DWORD err;
  24. INTERNET_PORT dwPort = INTERNET_OPEN_TYPE_PRECONFIG;
  25. // did we get a flag?
  26. if( (fOpenT & (GTREAD | GTWRITE)) == 0 )
  27. return(ERROR_INVALID_PARAMETER);
  28. // is it a readonly flag, then do gets
  29. fOpen = fOpenT;
  30. assert(tszURL != NULL);
  31. // we must have http://
  32. assert(_tcslen(tszURL) > 7);
  33. assert(_tcsnicmp(tszURL, TEXT("http://"), 7) == 0);
  34. // copy the Doman Name
  35. ptch = (TCHAR *) &tszURL[7];
  36. ptchT = tszDomanName;
  37. while(*ptch != _T('/') && *ptch != _T(':') && *ptch != 0)
  38. *ptchT++ = *ptch++;
  39. *ptchT = 0;
  40. // parse out the port number
  41. tszPort[0] = 0;
  42. if(*ptch == _T(':')) {
  43. ptchT = tszPort;
  44. while(*ptch != _T('/') && *ptch != 0)
  45. *ptchT++ = *ptch++;
  46. *ptchT = 0;
  47. }
  48. // Note, we don't support port numbers
  49. if(tszPort[0] != 0) {
  50. assert(tszPort[0] == ':');
  51. dwPort = (INTERNET_PORT)atoi(&tszPort[1]);
  52. }
  53. // save away what to look up.
  54. tszPartURL = (TCHAR *) malloc(_tcslen(ptch) + 1);
  55. if(NULL == tszPartURL)
  56. return ERROR_OUTOFMEMORY;
  57. _tcscpy(tszPartURL, ptch);
  58. // INTERNET_OPEN_TYPE_DIRECT,
  59. if( (hIOpen = InternetOpen( TEXT("Transport"),
  60. INTERNET_OPEN_TYPE_PRECONFIG,
  61. NULL,
  62. NULL,
  63. 0)) == NULL ||
  64. (hIConnect = InternetConnect(hIOpen,
  65. tszDomanName,
  66. dwPort,
  67. NULL,
  68. NULL,
  69. INTERNET_SERVICE_HTTP,
  70. 0,
  71. 0)) == NULL ) {
  72. err = GetLastError();
  73. return(err);
  74. }
  75. // If this is a GET, do a dummy send
  76. if( fOpen == GTREAD &&
  77. ((hIHttp = HttpOpenRequest(hIConnect,
  78. TEXT("GET"),
  79. tszPartURL,
  80. HTTP_VERSION,
  81. NULL,
  82. NULL,
  83. INTERNET_FLAG_DONT_CACHE,
  84. 0)) == NULL ||
  85. HttpSendRequest(hIHttp, TEXT("Accept: */*\r\n"), (DWORD) -1, NULL, 0) == FALSE) ) {
  86. err = GetLastError();
  87. return(err);
  88. }
  89. return(ERROR_SUCCESS);
  90. }
  91. DWORD CHttpTran::Send(DWORD dwEncodeType, DWORD cbSendBuff, const BYTE * pbSendBuff) {
  92. TCHAR tszBuff[1024];
  93. DWORD err;
  94. TCHAR * tszContentType;
  95. if( pbRecBuf != NULL || (fOpen & GTWRITE) != GTWRITE)
  96. return(ERROR_INVALID_PARAMETER);
  97. switch( dwEncodeType ) {
  98. case ASN_ENCODING:
  99. tszContentType = TEXT("application/x-octet-stream-asn");
  100. break;
  101. case TLV_ENCODING:
  102. tszContentType = TEXT("application/x-octet-stream-tlv");
  103. break;
  104. case IDL_ENCODING:
  105. tszContentType = TEXT("application/x-octet-stream-idl");
  106. break;
  107. case OCTET_ENCODING:
  108. tszContentType = TEXT("application/octet-stream");
  109. break;
  110. default:
  111. tszContentType = TEXT("text/*");
  112. break;
  113. }
  114. // say how long the buffer is
  115. _stprintf(tszBuff, TEXT("Content-Type: %s\r\nContent-Length: %d\r\nAccept: %s\r\n"), tszContentType, cbSendBuff,tszContentType);
  116. if( (hIHttp = HttpOpenRequest(hIConnect,
  117. TEXT("POST"),
  118. tszPartURL,
  119. HTTP_VERSION,
  120. NULL,
  121. NULL,
  122. INTERNET_FLAG_DONT_CACHE,
  123. 0)) == NULL ) {
  124. return(GetLastError());
  125. }
  126. // send of the request, this will wait for a response
  127. if( HttpSendRequest(hIHttp, tszBuff, (DWORD) -1, (LPVOID) pbSendBuff, cbSendBuff) == FALSE ) {
  128. err = GetLastError();
  129. // close out the handle
  130. assert(hIHttp != NULL);
  131. InternetCloseHandle(hIHttp);
  132. hIHttp = NULL;
  133. return(err);
  134. }
  135. return(ERROR_SUCCESS);
  136. }
  137. DWORD CHttpTran::Receive(DWORD * pdwEncodeType, DWORD * pcbReceiveBuff, BYTE ** ppbReceiveBuff) {
  138. TCHAR tszBuff[1024];
  139. DWORD cbBuff, cbBuffRead, cbBuffT;
  140. DWORD err;
  141. assert(pcbReceiveBuff != NULL && ppbReceiveBuff != NULL);
  142. *ppbReceiveBuff = NULL;
  143. *pcbReceiveBuff = 0;
  144. if( pbRecBuf != NULL || (fOpen & GTREAD) != GTREAD || hIHttp == NULL)
  145. return(ERROR_INVALID_PARAMETER);
  146. // get the content type
  147. if( pdwEncodeType != NULL) {
  148. cbBuff = sizeof(tszBuff);
  149. if(HttpQueryInfo( hIHttp,
  150. HTTP_QUERY_CONTENT_TYPE,
  151. tszBuff,
  152. &cbBuff,
  153. NULL) == FALSE)
  154. return(GetLastError());
  155. assert(cbBuff > 0);
  156. // for now assert we have a content type of TLV_ENCODING
  157. if(!_tcscmp(TEXT("application/x-octet-stream-asn"), tszBuff))
  158. *pdwEncodeType = ASN_ENCODING;
  159. else if(!_tcscmp(TEXT("application/x-octet-stream-idl"), tszBuff))
  160. *pdwEncodeType = IDL_ENCODING;
  161. else if(!_tcscmp(TEXT("application/x-octet-stream-tlv"), tszBuff))
  162. *pdwEncodeType = TLV_ENCODING;
  163. else if(!_tcscmp(TEXT("application/octet-stream"), tszBuff))
  164. *pdwEncodeType = OCTET_ENCODING;
  165. else
  166. *pdwEncodeType = ASCII_ENCODING;
  167. }
  168. // allocate a buffer
  169. cbBuff = REALLOCSIZE;
  170. if( (pbRecBuf = (PBYTE) malloc(cbBuff)) == NULL )
  171. return(ERROR_NOT_ENOUGH_MEMORY);
  172. // read the data
  173. cbBuffRead = 0;
  174. cbBuffT = 1;
  175. while(cbBuffT != 0) {
  176. cbBuffT = 0;
  177. if((cbBuff - cbBuffRead) == 0) {
  178. cbBuff += REALLOCSIZE;
  179. pbRecBuf = (PBYTE) realloc(pbRecBuf, cbBuff);
  180. if( pbRecBuf == NULL ) {
  181. free(pbRecBuf);
  182. InternetCloseHandle(hIHttp);
  183. return(ERROR_NOT_ENOUGH_MEMORY);
  184. }
  185. }
  186. if(InternetReadFile(hIHttp, &pbRecBuf[cbBuffRead], (cbBuff - cbBuffRead), &cbBuffT) == FALSE ) {
  187. err = GetLastError();
  188. free(pbRecBuf);
  189. InternetCloseHandle(hIHttp);
  190. return(err);
  191. }
  192. cbBuffRead += cbBuffT;
  193. }
  194. // pass back the info
  195. *ppbReceiveBuff = pbRecBuf;
  196. *pcbReceiveBuff = cbBuffRead;
  197. return(ERROR_SUCCESS);
  198. }
  199. DWORD CHttpTran::Free(BYTE * pb) {
  200. assert(pb == pbRecBuf);
  201. free(pbRecBuf);
  202. pbRecBuf = NULL;
  203. return(ERROR_SUCCESS);
  204. }
  205. DWORD CHttpTran::Close(void) {
  206. // free any buffers
  207. if(pbRecBuf != NULL) {
  208. free(pbRecBuf);
  209. pbRecBuf = NULL;
  210. }
  211. if(tszPartURL != NULL) {
  212. free(tszPartURL);
  213. tszPartURL = NULL;
  214. }
  215. if(hIHttp != NULL) {
  216. InternetCloseHandle(hIHttp);
  217. hIHttp = NULL;
  218. }
  219. if(hIConnect != NULL) {
  220. InternetCloseHandle(hIConnect);
  221. hIConnect = NULL;
  222. }
  223. if(hIOpen != NULL) {
  224. InternetCloseHandle(hIOpen);
  225. hIOpen = NULL;
  226. }
  227. return(ERROR_SUCCESS);
  228. }