Leaked source code of windows server 2003
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

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