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.

330 lines
6.6 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_INTERNET_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. if(!InternetCreateUrl(&sUrlComp, ICU_ESCAPE_AUTHORITY, pBuff, &dwSav)){
  113. dwError = GetLastError();
  114. goto Cleanup;
  115. }
  116. for(i=0;i<2;++i) {
  117. *lplpUrlName = (LPSTR)ALLOCATE_MEMORY(LPTR, dwSav);
  118. if (*lplpUrlName) {
  119. if(!InternetCanonicalizeUrl(pBuff, *lplpUrlName, &dwSav, ICU_ENCODE_SPACES_ONLY)){
  120. FREE_MEMORY(*lplpUrlName);
  121. // general paranoia
  122. *lplpUrlName = NULL;
  123. dwError = GetLastError();
  124. if ((i == 1) || (dwError != ERROR_INSUFFICIENT_BUFFER)) {
  125. goto Cleanup;
  126. }
  127. }
  128. else {
  129. dwError = ERROR_SUCCESS;
  130. *lpdwUrlLen = dwSav;
  131. break;
  132. }
  133. }
  134. else {
  135. SetLastError(dwError = ERROR_NOT_ENOUGH_MEMORY);
  136. goto Cleanup;
  137. }
  138. }
  139. Cleanup:
  140. if (pBuff) {
  141. FREE_MEMORY(pBuff);
  142. }
  143. if (dwError != ERROR_SUCCESS) {
  144. INET_ASSERT(!*lplpUrlName);
  145. *lpdwUrlLen = 0;
  146. }
  147. return (dwError);
  148. }
  149. DWORD
  150. pHttpBuildUrl(
  151. IN INTERNET_SCHEME SchemeType,
  152. IN LPSTR lpszTargetName,
  153. IN LPSTR lpszObjectName,
  154. IN DWORD dwPort,
  155. IN LPSTR lpszUrl,
  156. IN OUT LPDWORD lpdwBuffSize
  157. )
  158. /*++
  159. Routine Description:
  160. This routine builds an HTTP URL in the buffer passed. If the size is not
  161. enough it returns ERROR_INSUFFICIENT_BUFFER.
  162. Arguments:
  163. SchemeType - type of scheme - http, gopher, etc.
  164. lpszTargetName - host name
  165. lpszObjectName - URL-path
  166. dwPort - port number (if not default)
  167. lpszUrl - place to write URL
  168. lpdwBuffSize - IN: size of lpszUrl buffer
  169. OUT: size of URL written to lpszUrl
  170. Return Value:
  171. DWORD
  172. --*/
  173. {
  174. DWORD dwBuffLen;
  175. DWORD error;
  176. error = pHttpGetUrlLen(SchemeType,
  177. lpszTargetName,
  178. lpszObjectName,
  179. dwPort,
  180. &dwBuffLen
  181. );
  182. if (error != ERROR_SUCCESS) {
  183. return error;
  184. }
  185. if (dwBuffLen > *lpdwBuffSize) {
  186. return (ERROR_INSUFFICIENT_BUFFER);
  187. }
  188. LPSTR schemeName;
  189. DWORD schemeLength;
  190. schemeName = MapUrlScheme(SchemeType, &schemeLength);
  191. if (schemeName == NULL) {
  192. //
  193. // should never happen
  194. //
  195. INET_ASSERT(FALSE);
  196. return ERROR_INTERNET_UNRECOGNIZED_SCHEME;
  197. }
  198. LPSTR p = lpszUrl;
  199. int len;
  200. int urlLength;
  201. memcpy((LPVOID)p, (LPVOID)schemeName, schemeLength);
  202. p += schemeLength;
  203. urlLength = schemeLength;
  204. memcpy((LPVOID)p, (LPVOID)"://", sizeof("://") - 1);
  205. p += sizeof("://") - 1;
  206. urlLength += sizeof("://") - 1;
  207. len = lstrlen(lpszTargetName);
  208. memcpy((LPVOID)p, (LPVOID)lpszTargetName, len);
  209. p += len;
  210. urlLength += len;
  211. if (dwPort && (dwPort != INTERNET_DEFAULT_HTTP_PORT)) {
  212. CHAR TcpipPortString[32];
  213. //itoa(dwPort, TcpipPortString, 10);
  214. wsprintf(TcpipPortString, "%d", dwPort);
  215. INET_ASSERT(TcpipPortString[0] != '\0');
  216. *p++ = ':';
  217. len = lstrlen(TcpipPortString);
  218. memcpy((LPVOID)p, (LPVOID)TcpipPortString, len);
  219. p += len;
  220. urlLength += len + 1;
  221. }
  222. len = lstrlen(lpszObjectName);
  223. memcpy((LPVOID)p, (LPVOID)lpszObjectName, len);
  224. urlLength += len;
  225. *lpdwBuffSize = urlLength;
  226. return ERROR_SUCCESS;
  227. }