357 lines
7.3 KiB
C++
357 lines
7.3 KiB
C++
/*++
|
||
|
||
Copyright (c) 1994 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
request.cxx
|
||
|
||
Abstract:
|
||
|
||
Contains HTTP utility functions
|
||
|
||
Contents:
|
||
pHttpGetUrlLen
|
||
pHttpGetUrlString
|
||
pHttpBuildUrl
|
||
|
||
Author:
|
||
|
||
Keith Moore (keithmo) 16-Nov-1994
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include <wininetp.h>
|
||
#include "httpp.h"
|
||
|
||
//
|
||
// functions
|
||
//
|
||
|
||
|
||
DWORD
|
||
pHttpGetUrlLen(
|
||
IN INTERNET_SCHEME SchemeType,
|
||
IN LPSTR lpszTargetName,
|
||
IN LPSTR lpszObjectName,
|
||
IN DWORD dwPort,
|
||
OUT LPDWORD lpdwUrlLen
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine finds the length of an HTTP URL from targethostname
|
||
port and the object and returns the length
|
||
|
||
Arguments:
|
||
|
||
SchemeType - type of scheme for URL
|
||
|
||
lpszTargetName - host name
|
||
|
||
lpszObjectName - URL-path
|
||
|
||
dwPort - port (if not default)
|
||
|
||
lpdwUrlLen - returned URL length
|
||
|
||
Return Value:
|
||
|
||
DWORD
|
||
|
||
--*/
|
||
|
||
{
|
||
LPSTR schemeName;
|
||
DWORD schemeLength;
|
||
|
||
schemeName = MapUrlScheme(SchemeType, &schemeLength);
|
||
if (schemeName == NULL) {
|
||
return ERROR_WINHTTP_UNRECOGNIZED_SCHEME;
|
||
}
|
||
|
||
int portLen;
|
||
|
||
*lpdwUrlLen = 0;
|
||
|
||
if (dwPort) {
|
||
|
||
CHAR TcpipPortString[32];
|
||
|
||
//itoa(dwPort, TcpipPortString, 10);
|
||
wsprintf(TcpipPortString, "%d", dwPort);
|
||
|
||
portLen = lstrlen(TcpipPortString);
|
||
} else {
|
||
portLen = 0;
|
||
}
|
||
|
||
*lpdwUrlLen = schemeLength
|
||
+ sizeof("://")
|
||
+ portLen
|
||
+ lstrlen(lpszTargetName)
|
||
+ lstrlen(lpszObjectName)
|
||
;
|
||
|
||
return ERROR_SUCCESS;
|
||
}
|
||
|
||
DWORD
|
||
pHttpGetUrlString(
|
||
IN INTERNET_SCHEME SchemeType,
|
||
IN LPSTR lpszTargetName,
|
||
IN LPSTR lpszCWD,
|
||
IN LPSTR lpszObjectName,
|
||
IN LPSTR lpszExtension,
|
||
IN DWORD dwPort,
|
||
OUT LPSTR * lplpUrlName,
|
||
OUT LPDWORD lpdwUrlLen
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine returns a LocaAlloc'ed buffer containing an HTTP URL constructed
|
||
from the TargetHost, the ObjectName and the port. The caller is responsible
|
||
for freeing the memory.
|
||
|
||
Arguments:
|
||
|
||
SchemeType -
|
||
lpszTargetName -
|
||
lpszCWD -
|
||
lpszObjectName -
|
||
lpszExtension -
|
||
dwPort -
|
||
lplpUrlName -
|
||
lpdwUrlLen -
|
||
|
||
Return Value:
|
||
|
||
DWORD
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD dwError, dwSav, i;
|
||
URL_COMPONENTS sUrlComp;
|
||
char *pBuff = (char *) ALLOCATE_FIXED_MEMORY(INTERNET_MAX_URL_LENGTH);
|
||
|
||
if (pBuff == NULL)
|
||
{
|
||
dwError = ERROR_NOT_ENOUGH_MEMORY;
|
||
goto Cleanup;
|
||
}
|
||
|
||
INET_ASSERT(lpszCWD == NULL);
|
||
|
||
*lplpUrlName = NULL;
|
||
|
||
memset(&sUrlComp, 0, sizeof(URL_COMPONENTS));
|
||
|
||
sUrlComp.dwStructSize = sizeof(URL_COMPONENTS);
|
||
sUrlComp.nScheme = SchemeType;
|
||
sUrlComp.lpszHostName = lpszTargetName;
|
||
sUrlComp.lpszUrlPath = lpszObjectName;
|
||
sUrlComp.nPort = (INTERNET_PORT)dwPort;
|
||
|
||
dwSav = INTERNET_MAX_URL_LENGTH;
|
||
|
||
for (i=0; i<2; i++)
|
||
{
|
||
if(!WinHttpCreateUrlA(&sUrlComp, 0, pBuff, &dwSav))
|
||
{
|
||
dwError = GetLastError();
|
||
|
||
if ((dwError == ERROR_INSUFFICIENT_BUFFER)
|
||
&& (i==0))
|
||
{
|
||
LPSTR pTemp = (LPSTR)REALLOCATE_MEMORY(pBuff, dwSav, LMEM_MOVEABLE);
|
||
if (pTemp)
|
||
{
|
||
pBuff = pTemp;
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
dwError = ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
}
|
||
goto Cleanup;
|
||
}
|
||
else
|
||
{
|
||
dwError = ERROR_SUCCESS;
|
||
break;
|
||
}
|
||
}
|
||
// BUGBUG, this is because WinHttpCreateUrl is not returning
|
||
// the correct size
|
||
|
||
dwSav = strlen(pBuff)+5;
|
||
|
||
for(i=0;i<2;++i) {
|
||
|
||
*lplpUrlName = (LPSTR)ALLOCATE_MEMORY(LPTR, dwSav);
|
||
|
||
if (*lplpUrlName) {
|
||
|
||
if(!InternetCanonicalizeUrl(pBuff, *lplpUrlName, &dwSav, ICU_ENCODE_SPACES_ONLY)){
|
||
|
||
FREE_MEMORY(*lplpUrlName);
|
||
|
||
// general paranoia
|
||
*lplpUrlName = NULL;
|
||
|
||
dwError = GetLastError();
|
||
|
||
if ((i == 1) || (dwError != ERROR_INSUFFICIENT_BUFFER)) {
|
||
goto Cleanup;
|
||
}
|
||
}
|
||
else {
|
||
|
||
dwError = ERROR_SUCCESS;
|
||
*lpdwUrlLen = dwSav;
|
||
break;
|
||
|
||
}
|
||
}
|
||
else {
|
||
SetLastError(dwError = ERROR_NOT_ENOUGH_MEMORY);
|
||
goto Cleanup;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
Cleanup:
|
||
if (pBuff)
|
||
FREE_MEMORY(pBuff);
|
||
if (dwError != ERROR_SUCCESS) {
|
||
|
||
INET_ASSERT(!*lplpUrlName);
|
||
|
||
*lpdwUrlLen = 0;
|
||
}
|
||
|
||
return (dwError);
|
||
}
|
||
|
||
DWORD
|
||
pHttpBuildUrl(
|
||
IN INTERNET_SCHEME SchemeType,
|
||
IN LPSTR lpszTargetName,
|
||
IN LPSTR lpszObjectName,
|
||
IN DWORD dwPort,
|
||
IN LPSTR lpszUrl,
|
||
IN OUT LPDWORD lpdwBuffSize
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine builds an HTTP URL in the buffer passed. If the size is not
|
||
enough it returns ERROR_INSUFFICIENT_BUFFER.
|
||
|
||
Arguments:
|
||
|
||
SchemeType - type of scheme - http, gopher, etc.
|
||
|
||
lpszTargetName - host name
|
||
|
||
lpszObjectName - URL-path
|
||
|
||
dwPort - port number (if not default)
|
||
|
||
lpszUrl - place to write URL
|
||
|
||
lpdwBuffSize - IN: size of lpszUrl buffer
|
||
OUT: size of URL written to lpszUrl
|
||
|
||
Return Value:
|
||
|
||
DWORD
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD dwBuffLen;
|
||
DWORD error;
|
||
|
||
error = pHttpGetUrlLen(SchemeType,
|
||
lpszTargetName,
|
||
lpszObjectName,
|
||
dwPort,
|
||
&dwBuffLen
|
||
);
|
||
if (error != ERROR_SUCCESS) {
|
||
return error;
|
||
}
|
||
if (dwBuffLen > *lpdwBuffSize) {
|
||
return (ERROR_INSUFFICIENT_BUFFER);
|
||
}
|
||
|
||
LPSTR schemeName;
|
||
DWORD schemeLength;
|
||
|
||
schemeName = MapUrlScheme(SchemeType, &schemeLength);
|
||
if (schemeName == NULL) {
|
||
|
||
//
|
||
// should never happen
|
||
//
|
||
|
||
INET_ASSERT(FALSE);
|
||
|
||
return ERROR_WINHTTP_UNRECOGNIZED_SCHEME;
|
||
}
|
||
|
||
LPSTR p = lpszUrl;
|
||
int len;
|
||
int urlLength;
|
||
|
||
memcpy((LPVOID)p, (LPVOID)schemeName, schemeLength);
|
||
p += schemeLength;
|
||
urlLength = schemeLength;
|
||
|
||
memcpy((LPVOID)p, (LPVOID)"://", sizeof("://") - 1);
|
||
p += sizeof("://") - 1;
|
||
urlLength += sizeof("://") - 1;
|
||
|
||
len = lstrlen(lpszTargetName);
|
||
memcpy((LPVOID)p, (LPVOID)lpszTargetName, len);
|
||
p += len;
|
||
urlLength += len;
|
||
|
||
if (dwPort && (dwPort != INTERNET_DEFAULT_HTTP_PORT)) {
|
||
|
||
CHAR TcpipPortString[32];
|
||
|
||
//itoa(dwPort, TcpipPortString, 10);
|
||
wsprintf(TcpipPortString, "%d", dwPort);
|
||
|
||
INET_ASSERT(TcpipPortString[0] != '\0');
|
||
|
||
*p++ = ':';
|
||
len = lstrlen(TcpipPortString);
|
||
memcpy((LPVOID)p, (LPVOID)TcpipPortString, len);
|
||
p += len;
|
||
urlLength += len + 1;
|
||
}
|
||
|
||
len = lstrlen(lpszObjectName);
|
||
memcpy((LPVOID)p, (LPVOID)lpszObjectName, len);
|
||
urlLength += len;
|
||
|
||
*lpdwBuffSize = urlLength;
|
||
|
||
return ERROR_SUCCESS;
|
||
}
|