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.

356 lines
7.3 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, dwSav, i;
  96. URL_COMPONENTS sUrlComp;
  97. char *pBuff = (char *) ALLOCATE_FIXED_MEMORY(INTERNET_MAX_URL_LENGTH);
  98. if (pBuff == NULL)
  99. {
  100. dwError = ERROR_NOT_ENOUGH_MEMORY;
  101. goto Cleanup;
  102. }
  103. INET_ASSERT(lpszCWD == NULL);
  104. *lplpUrlName = NULL;
  105. memset(&sUrlComp, 0, sizeof(URL_COMPONENTS));
  106. sUrlComp.dwStructSize = sizeof(URL_COMPONENTS);
  107. sUrlComp.nScheme = SchemeType;
  108. sUrlComp.lpszHostName = lpszTargetName;
  109. sUrlComp.lpszUrlPath = lpszObjectName;
  110. sUrlComp.nPort = (INTERNET_PORT)dwPort;
  111. dwSav = INTERNET_MAX_URL_LENGTH;
  112. for (i=0; i<2; i++)
  113. {
  114. if(!WinHttpCreateUrlA(&sUrlComp, 0, pBuff, &dwSav))
  115. {
  116. dwError = GetLastError();
  117. if ((dwError == ERROR_INSUFFICIENT_BUFFER)
  118. && (i==0))
  119. {
  120. LPSTR pTemp = (LPSTR)REALLOCATE_MEMORY(pBuff, dwSav, LMEM_MOVEABLE);
  121. if (pTemp)
  122. {
  123. pBuff = pTemp;
  124. continue;
  125. }
  126. else
  127. {
  128. dwError = ERROR_NOT_ENOUGH_MEMORY;
  129. }
  130. }
  131. goto Cleanup;
  132. }
  133. else
  134. {
  135. dwError = ERROR_SUCCESS;
  136. break;
  137. }
  138. }
  139. // BUGBUG, this is because WinHttpCreateUrl is not returning
  140. // the correct size
  141. dwSav = strlen(pBuff)+5;
  142. for(i=0;i<2;++i) {
  143. *lplpUrlName = (LPSTR)ALLOCATE_MEMORY(LPTR, dwSav);
  144. if (*lplpUrlName) {
  145. if(!InternetCanonicalizeUrl(pBuff, *lplpUrlName, &dwSav, ICU_ENCODE_SPACES_ONLY)){
  146. FREE_MEMORY(*lplpUrlName);
  147. // general paranoia
  148. *lplpUrlName = NULL;
  149. dwError = GetLastError();
  150. if ((i == 1) || (dwError != ERROR_INSUFFICIENT_BUFFER)) {
  151. goto Cleanup;
  152. }
  153. }
  154. else {
  155. dwError = ERROR_SUCCESS;
  156. *lpdwUrlLen = dwSav;
  157. break;
  158. }
  159. }
  160. else {
  161. SetLastError(dwError = ERROR_NOT_ENOUGH_MEMORY);
  162. goto Cleanup;
  163. }
  164. }
  165. Cleanup:
  166. if (pBuff)
  167. FREE_MEMORY(pBuff);
  168. if (dwError != ERROR_SUCCESS) {
  169. INET_ASSERT(!*lplpUrlName);
  170. *lpdwUrlLen = 0;
  171. }
  172. return (dwError);
  173. }
  174. DWORD
  175. pHttpBuildUrl(
  176. IN INTERNET_SCHEME SchemeType,
  177. IN LPSTR lpszTargetName,
  178. IN LPSTR lpszObjectName,
  179. IN DWORD dwPort,
  180. IN LPSTR lpszUrl,
  181. IN OUT LPDWORD lpdwBuffSize
  182. )
  183. /*++
  184. Routine Description:
  185. This routine builds an HTTP URL in the buffer passed. If the size is not
  186. enough it returns ERROR_INSUFFICIENT_BUFFER.
  187. Arguments:
  188. SchemeType - type of scheme - http, gopher, etc.
  189. lpszTargetName - host name
  190. lpszObjectName - URL-path
  191. dwPort - port number (if not default)
  192. lpszUrl - place to write URL
  193. lpdwBuffSize - IN: size of lpszUrl buffer
  194. OUT: size of URL written to lpszUrl
  195. Return Value:
  196. DWORD
  197. --*/
  198. {
  199. DWORD dwBuffLen;
  200. DWORD error;
  201. error = pHttpGetUrlLen(SchemeType,
  202. lpszTargetName,
  203. lpszObjectName,
  204. dwPort,
  205. &dwBuffLen
  206. );
  207. if (error != ERROR_SUCCESS) {
  208. return error;
  209. }
  210. if (dwBuffLen > *lpdwBuffSize) {
  211. return (ERROR_INSUFFICIENT_BUFFER);
  212. }
  213. LPSTR schemeName;
  214. DWORD schemeLength;
  215. schemeName = MapUrlScheme(SchemeType, &schemeLength);
  216. if (schemeName == NULL) {
  217. //
  218. // should never happen
  219. //
  220. INET_ASSERT(FALSE);
  221. return ERROR_WINHTTP_UNRECOGNIZED_SCHEME;
  222. }
  223. LPSTR p = lpszUrl;
  224. int len;
  225. int urlLength;
  226. memcpy((LPVOID)p, (LPVOID)schemeName, schemeLength);
  227. p += schemeLength;
  228. urlLength = schemeLength;
  229. memcpy((LPVOID)p, (LPVOID)"://", sizeof("://") - 1);
  230. p += sizeof("://") - 1;
  231. urlLength += sizeof("://") - 1;
  232. len = lstrlen(lpszTargetName);
  233. memcpy((LPVOID)p, (LPVOID)lpszTargetName, len);
  234. p += len;
  235. urlLength += len;
  236. if (dwPort && (dwPort != INTERNET_DEFAULT_HTTP_PORT)) {
  237. CHAR TcpipPortString[32];
  238. //itoa(dwPort, TcpipPortString, 10);
  239. wsprintf(TcpipPortString, "%d", dwPort);
  240. INET_ASSERT(TcpipPortString[0] != '\0');
  241. *p++ = ':';
  242. len = lstrlen(TcpipPortString);
  243. memcpy((LPVOID)p, (LPVOID)TcpipPortString, len);
  244. p += len;
  245. urlLength += len + 1;
  246. }
  247. len = lstrlen(lpszObjectName);
  248. memcpy((LPVOID)p, (LPVOID)lpszObjectName, len);
  249. urlLength += len;
  250. *lpdwBuffSize = urlLength;
  251. return ERROR_SUCCESS;
  252. }