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.

360 lines
7.4 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. request.cxx
  5. Abstract:
  6. Contains HTTP utility functions
  7. Contents:
  8. pHttpGetUrlLen
  9. pHttpGetUrlString
  10. pHttpBuildUrl
  11. Author:
  12. Keith Moore (keithmo) 16-Nov-1994
  13. Revision History:
  14. --*/
  15. #include <wininetp.h>
  16. #include "httpp.h"
  17. //
  18. // functions
  19. //
  20. DWORD
  21. pHttpGetUrlLen(
  22. IN INTERNET_SCHEME SchemeType,
  23. IN LPSTR lpszTargetName,
  24. IN LPSTR lpszObjectName,
  25. IN DWORD dwPort,
  26. OUT LPDWORD lpdwUrlLen
  27. )
  28. /*++
  29. Routine Description:
  30. This routine finds the length of an HTTP URL from targethostname
  31. port and the object and returns the length
  32. Arguments:
  33. SchemeType - type of scheme for URL
  34. lpszTargetName - host name
  35. lpszObjectName - URL-path
  36. dwPort - port (if not default)
  37. lpdwUrlLen - returned URL length
  38. Return Value:
  39. DWORD
  40. --*/
  41. {
  42. LPSTR schemeName;
  43. DWORD schemeLength;
  44. schemeName = MapUrlScheme(SchemeType, &schemeLength);
  45. if (schemeName == NULL) {
  46. return ERROR_WINHTTP_UNRECOGNIZED_SCHEME;
  47. }
  48. int portLen;
  49. *lpdwUrlLen = 0;
  50. if (dwPort) {
  51. CHAR TcpipPortString[32];
  52. //itoa(dwPort, TcpipPortString, 10);
  53. wsprintf(TcpipPortString, "%d", dwPort);
  54. portLen = lstrlen(TcpipPortString);
  55. } else {
  56. portLen = 0;
  57. }
  58. *lpdwUrlLen = schemeLength
  59. + sizeof("://")
  60. + portLen
  61. + lstrlen(lpszTargetName)
  62. + lstrlen(lpszObjectName)
  63. ;
  64. return ERROR_SUCCESS;
  65. }
  66. DWORD
  67. pHttpGetUrlString(
  68. IN INTERNET_SCHEME SchemeType,
  69. IN LPSTR lpszTargetName,
  70. IN LPSTR lpszCWD,
  71. IN LPSTR lpszObjectName,
  72. IN LPSTR lpszExtension,
  73. IN DWORD dwPort,
  74. OUT LPSTR * lplpUrlName,
  75. OUT LPDWORD lpdwUrlLen
  76. )
  77. /*++
  78. Routine Description:
  79. This routine returns a LocaAlloc'ed buffer containing an HTTP URL constructed
  80. from the TargetHost, the ObjectName and the port. The caller is responsible
  81. for freeing the memory.
  82. Arguments:
  83. SchemeType -
  84. lpszTargetName -
  85. lpszCWD -
  86. lpszObjectName -
  87. lpszExtension -
  88. dwPort -
  89. lplpUrlName -
  90. lpdwUrlLen -
  91. Return Value:
  92. DWORD
  93. --*/
  94. {
  95. DWORD dwError= ERROR_SUCCESS, dwSav, i;
  96. URL_COMPONENTSA sUrlComp;
  97. char *pBuff = (char *) ALLOCATE_FIXED_MEMORY(INTERNET_MAX_URL_LENGTH);
  98. UNREFERENCED_PARAMETER(lpszExtension);
  99. UNREFERENCED_PARAMETER(lpszCWD);
  100. if (pBuff == NULL)
  101. {
  102. dwError = ERROR_NOT_ENOUGH_MEMORY;
  103. goto Cleanup;
  104. }
  105. INET_ASSERT(lpszCWD == NULL);
  106. *lplpUrlName = NULL;
  107. memset(&sUrlComp, 0, sizeof(sUrlComp));
  108. sUrlComp.dwStructSize = sizeof(sUrlComp);
  109. sUrlComp.nScheme = SchemeType;
  110. sUrlComp.lpszHostName = lpszTargetName;
  111. sUrlComp.lpszUrlPath = lpszObjectName;
  112. sUrlComp.nPort = (INTERNET_PORT)dwPort;
  113. dwSav = INTERNET_MAX_URL_LENGTH;
  114. for (i=0; i<2; i++)
  115. {
  116. if(!WinHttpCreateUrlA(&sUrlComp, 0, pBuff, &dwSav))
  117. {
  118. dwError = GetLastError();
  119. if ((dwError == ERROR_INSUFFICIENT_BUFFER)
  120. && (i==0))
  121. {
  122. //do not use reallocate here not to initiate unnecessary memory copy
  123. FREE_MEMORY(pBuff);
  124. pBuff = (char*)ALLOCATE_FIXED_MEMORY(dwSav);
  125. if (pBuff)
  126. {
  127. continue;
  128. }
  129. else
  130. {
  131. dwError = ERROR_NOT_ENOUGH_MEMORY;
  132. }
  133. }
  134. goto Cleanup;
  135. }
  136. else
  137. {
  138. dwError = ERROR_SUCCESS;
  139. break;
  140. }
  141. }
  142. // BUGBUG, this is because WinHttpCreateUrl is not returning
  143. // the correct size
  144. dwSav = strlen(pBuff)+5;
  145. for(i=0;i<2;++i) {
  146. *lplpUrlName = (LPSTR)ALLOCATE_ZERO_MEMORY(dwSav);
  147. if (*lplpUrlName) {
  148. if(!InternetCanonicalizeUrl(pBuff, *lplpUrlName, &dwSav, ICU_ENCODE_SPACES_ONLY)){
  149. FREE_MEMORY(*lplpUrlName);
  150. // general paranoia
  151. *lplpUrlName = NULL;
  152. dwError = GetLastError();
  153. if ((i == 1) || (dwError != ERROR_INSUFFICIENT_BUFFER)) {
  154. goto Cleanup;
  155. }
  156. }
  157. else {
  158. dwError = ERROR_SUCCESS;
  159. *lpdwUrlLen = dwSav;
  160. break;
  161. }
  162. }
  163. else {
  164. SetLastError(dwError = ERROR_NOT_ENOUGH_MEMORY);
  165. goto Cleanup;
  166. }
  167. }
  168. Cleanup:
  169. if (pBuff)
  170. FREE_MEMORY(pBuff);
  171. if (dwError != ERROR_SUCCESS) {
  172. INET_ASSERT(!*lplpUrlName);
  173. *lpdwUrlLen = 0;
  174. }
  175. return (dwError);
  176. }
  177. DWORD
  178. pHttpBuildUrl(
  179. IN INTERNET_SCHEME SchemeType,
  180. IN LPSTR lpszTargetName,
  181. IN LPSTR lpszObjectName,
  182. IN DWORD dwPort,
  183. IN LPSTR lpszUrl,
  184. IN OUT LPDWORD lpdwBuffSize
  185. )
  186. /*++
  187. Routine Description:
  188. This routine builds an HTTP URL in the buffer passed. If the size is not
  189. enough it returns ERROR_INSUFFICIENT_BUFFER.
  190. Arguments:
  191. SchemeType - type of scheme - http, gopher, etc.
  192. lpszTargetName - host name
  193. lpszObjectName - URL-path
  194. dwPort - port number (if not default)
  195. lpszUrl - place to write URL
  196. lpdwBuffSize - IN: size of lpszUrl buffer
  197. OUT: size of URL written to lpszUrl
  198. Return Value:
  199. DWORD
  200. --*/
  201. {
  202. DWORD dwBuffLen;
  203. DWORD error;
  204. error = pHttpGetUrlLen(SchemeType,
  205. lpszTargetName,
  206. lpszObjectName,
  207. dwPort,
  208. &dwBuffLen
  209. );
  210. if (error != ERROR_SUCCESS) {
  211. return error;
  212. }
  213. if (dwBuffLen > *lpdwBuffSize) {
  214. return (ERROR_INSUFFICIENT_BUFFER);
  215. }
  216. LPSTR schemeName;
  217. DWORD schemeLength;
  218. schemeName = MapUrlScheme(SchemeType, &schemeLength);
  219. if (schemeName == NULL) {
  220. //
  221. // should never happen
  222. //
  223. INET_ASSERT(FALSE);
  224. return ERROR_WINHTTP_UNRECOGNIZED_SCHEME;
  225. }
  226. LPSTR p = lpszUrl;
  227. int len;
  228. int urlLength;
  229. memcpy((LPVOID)p, (LPVOID)schemeName, schemeLength);
  230. p += schemeLength;
  231. urlLength = schemeLength;
  232. memcpy((LPVOID)p, (LPVOID)"://", sizeof("://") - 1);
  233. p += sizeof("://") - 1;
  234. urlLength += sizeof("://") - 1;
  235. len = lstrlen(lpszTargetName);
  236. memcpy((LPVOID)p, (LPVOID)lpszTargetName, len);
  237. p += len;
  238. urlLength += len;
  239. if (dwPort && (dwPort != INTERNET_DEFAULT_HTTP_PORT)) {
  240. CHAR TcpipPortString[32];
  241. //itoa(dwPort, TcpipPortString, 10);
  242. wsprintf(TcpipPortString, "%d", dwPort);
  243. INET_ASSERT(TcpipPortString[0] != '\0');
  244. *p++ = ':';
  245. len = lstrlen(TcpipPortString);
  246. memcpy((LPVOID)p, (LPVOID)TcpipPortString, len);
  247. p += len;
  248. urlLength += len + 1;
  249. }
  250. len = lstrlen(lpszObjectName);
  251. memcpy((LPVOID)p, (LPVOID)lpszObjectName, len);
  252. urlLength += len;
  253. *lpdwBuffSize = urlLength;
  254. return ERROR_SUCCESS;
  255. }