HTTP SERVER API
Прилагаю ниже код, который не хочет биндить порт по ssl протоколу.
Не понятно почему. Если запускаю HTTP Configuration Utility и устанавливаю те же параметры, то все OK.
Кто-нибудь может подсказать в чем дело?
Заранее спасибо.
Код:
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#pragma comment(lib, "wsock32.lib")
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
#include <winsock2.h>
#include <windows.h>
#include <string>
#include <vector>
#include <winerror.h>
using namespace std;
#include <http.h>
#include <stdio.h>
#pragma comment(lib, "httpapi.lib")
#define MAX_SERVER_SESSION 20
#define INITIALIZE_HTTP_RESPONSE( resp, status, reason )
do
{
RtlZeroMemory( (resp), sizeof(*(resp)) );
(resp)->StatusCode = (status);
(resp)->pReason = (reason);
(resp)->ReasonLength = (USHORT) strlen(reason);
} while (FALSE)
#define ADD_KNOWN_HEADER(Response, HeaderId, RawValue)
do
{
(Response).Headers.KnownHeaders[(HeaderId)].pRawValue =
(RawValue);
(Response).Headers.KnownHeaders[(HeaderId)].RawValueLength =
(USHORT) strlen(RawValue);
} while(FALSE)
#define ALLOC_MEM(cb) HeapAlloc(GetProcessHeap(), 0, (cb))
#define FREE_MEM(ptr) HeapFree(GetProcessHeap(), 0, (ptr))
//
// Prototypes.
//
DWORD DoReceiveRequests(HANDLE hReqQueue);
DWORD
SendHttpResponse(
IN HANDLE hReqQueue,
IN PHTTP_REQUEST pRequest,
IN USHORT StatusCode,
IN PSTR pReason,
IN PSTR pEntity
);
int __cdecl wmain(
int argc,
wchar_t * argv[]
)
{
ULONG retCode;
HANDLE hReqQueue = NULL;
int UrlAdded = 0;
HTTPAPI_VERSION HttpApiVersion = HTTPAPI_VERSION_1;
retCode = HttpInitialize(
HttpApiVersion,
HTTP_INITIALIZE_SERVER | HTTP_INITIALIZE_CONFIG, // Flags
NULL // Reserved
);
if (retCode != NO_ERROR)
{
wprintf(L"HttpInitialize failed with %lu n", retCode);
return retCode;
}
SOCKADDR_IN sa;
static const GUID APPID = { 0x82d41f1f, 0x7251, 0x47c7, { 0xaa, 0x5, 0xf8, 0xe2, 0xe, 0xd4, 0xa1, 0xd6 } };
{
BYTE hash[] = {0xa0, 0xf9, 0x68, 0x3f, 0x7b, 0x38, 0x6f, 0xb7, 0x11, 0x7e, 0x5b, 0xef, 0xec, 0xd2, 0xb2, 0xe4, 0xca, 0x2a, 0x47, 0xf0};
HTTP_SERVICE_CONFIG_SSL_SET scssl;
memset(&sa,0,sizeof(sa));
sa.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
sa.sin_family = AF_INET;
sa.sin_port = 4040;
scssl.KeyDesc.pIpPort = (SOCKADDR*)&sa;
scssl.ParamDesc.AppId = APPID;
scssl.ParamDesc.DefaultCertCheckMode = 0;
scssl.ParamDesc.DefaultFlags = 0;//HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT;
scssl.ParamDesc.DefaultRevocationFreshnessTime = 0;
scssl.ParamDesc.DefaultRevocationUrlRetrievalTimeout = 0;
scssl.ParamDesc.pSslCertStoreName = L"MY";
scssl.ParamDesc.pDefaultSslCtlIdentifier = NULL;
scssl.ParamDesc.pDefaultSslCtlStoreName = NULL;
scssl.ParamDesc.pSslHash =(void*)hash;
scssl.ParamDesc.SslHashLength = sizeof(hash);
retCode = HttpSetServiceConfiguration(NULL,HttpServiceConfigSSLCertInfo,&scssl,sizeof(scssl),NULL);
printf("RetCode = %drn",retCode);
if(retCode!=NO_ERROR)
{
if (retCode == ERROR_ALREADY_EXISTS)
{
retCode = HttpDeleteServiceConfiguration(0,HttpServiceConfigSSLCertInfo,&scssl,sizeof(HTTP_SERVICE_CONFIG_SSL_SET),NULL);
wprintf(L"Delete HttpSetServiceConfiguration = %lu n", retCode);
if (NOERROR == retCode)
{
retCode = HttpSetServiceConfiguration(0,HttpServiceConfigSSLCertInfo,&scssl,sizeof(HTTP_SERVICE_CONFIG_SSL_SET),NULL);
wprintf(L"Setup HttpSetServiceConfiguration = %lu n", retCode);
}else
{
printf("%drn",retCode);
return retCode;
}
}else
{
printf("%drn",retCode);
return retCode;
}
}
}
retCode = HttpCreateHttpHandle(
&hReqQueue, // Req Queue
0 // Reserved
);
if (retCode != NO_ERROR)
{
wprintf(L"HttpCreateHttpHandle failed with %lu n", retCode);
goto CleanUp;
}
wchar_t* temp=NULL;
temp = (wchar_t*)malloc(sizeof(wchar_t)*(256));
if (!temp) return -1;
swprintf(temp, L"%S","https://127.0.0.1:4040/test");
{
retCode = HttpAddUrl(hReqQueue,temp,0);
if (retCode != NO_ERROR)
{
{
wprintf(L"HttpAddUrl failed with %lu n", retCode);
goto CleanUp;
}
}
else
{
UrlAdded ++;
wprintf(L"listening for requests on the following url%d: %wsn",UrlAdded, temp);
}
}
DoReceiveRequests(hReqQueue);
CleanUp:
{
HttpRemoveUrl(hReqQueue, temp);
}
if(hReqQueue)
{
CloseHandle(hReqQueue);
}
HttpTerminate(HTTP_INITIALIZE_SERVER, NULL);
return retCode;
}
DWORD DoReceiveRequests(
IN HANDLE hReqQueue
)
{
ULONG result;
HTTP_REQUEST_ID requestId;
DWORD bytesRead;
PHTTP_REQUEST pRequest;
PCHAR pRequestBuffer;
ULONG RequestBufferLength;
RequestBufferLength = sizeof(HTTP_REQUEST) + 2048*2;
pRequestBuffer = (PCHAR) ALLOC_MEM( RequestBufferLength );
if (pRequestBuffer == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
pRequest = (PHTTP_REQUEST)pRequestBuffer;
HTTP_SET_NULL_ID( &requestId );
for(;;)
{
RtlZeroMemory(pRequest, RequestBufferLength);
result = HttpReceiveHttpRequest(
hReqQueue, // Req Queue
requestId, // Req ID
HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY, // Flags
pRequest, // HTTP request buffer
RequestBufferLength,// req buffer length
&bytesRead, // bytes received
NULL // LPOVERLAPPED
);
if(NO_ERROR == result)
{
// Worked!
bool CheckAuth = false;
if (pRequest->Verb == HttpVerbGET || pRequest->Verb == HttpVerbPOST)
{
//начинаем парсировать буфер
if (pRequest->pEntityChunks && pRequest->pEntityChunks[0].FromMemory.pBuffer)
{
result = SendHttpResponse(hReqQueue, pRequest,200,"OK",NULL);
}else
result = SendHttpResponse(hReqQueue, pRequest,400,"BAD REQUEST",NULL);
}
else
{
wprintf(L"Got a unknown request for %ws n",pRequest->CookedUrl.pFullUrl);
result = SendHttpResponse(hReqQueue, pRequest,503,"Not Implemented",NULL);
}
if(result != NO_ERROR)
{
break;
}
HTTP_SET_NULL_ID( &requestId );
}
else if(result == ERROR_MORE_DATA)
{
requestId = pRequest->RequestId;
RequestBufferLength = bytesRead;
FREE_MEM( pRequestBuffer );
pRequestBuffer = (PCHAR) ALLOC_MEM( RequestBufferLength );
if (pRequestBuffer == NULL)
{
result = ERROR_NOT_ENOUGH_MEMORY;
break;
}
pRequest = (PHTTP_REQUEST)pRequestBuffer;
}
else if(ERROR_CONNECTION_INVALID == result &&
!HTTP_IS_NULL_ID(&requestId))
{
HTTP_SET_NULL_ID( &requestId );
}
else
{
break;
}
}
if(pRequestBuffer)
{
FREE_MEM( pRequestBuffer );
}
return result;
}
DWORD SendHttpResponse(
IN HANDLE hReqQueue,
IN PHTTP_REQUEST pRequest,
IN USHORT StatusCode,
IN PSTR pReason,
IN PSTR pEntityString
)
{
HTTP_RESPONSE response;
HTTP_DATA_CHUNK dataChunk;
DWORD result;
DWORD bytesSent;
INITIALIZE_HTTP_RESPONSE(&response, StatusCode, pReason);
ADD_KNOWN_HEADER(response, HttpHeaderContentType, "text/html");
if(pEntityString)
{
dataChunk.DataChunkType = HttpDataChunkFromMemory;
dataChunk.FromMemory.pBuffer = pEntityString;
dataChunk.FromMemory.BufferLength = (ULONG) strlen(pEntityString);
response.EntityChunkCount = 1;
response.pEntityChunks = &dataChunk;
}
result = HttpSendHttpResponse(
hReqQueue, // ReqQueueHandle
pRequest->RequestId, // Request ID
0, // Flags
&response, // HTTP response
NULL, // pReserved1
&bytesSent, // bytes sent (OPTIONAL)
NULL, // pReserved2 (must be NULL)
0, // Reserved3 (must be 0)
NULL, // LPOVERLAPPED(OPTIONAL)
NULL // pReserved4 (must be NULL)
);
if(result != NO_ERROR)
{
wprintf(L"HttpSendHttpResponse failed with %lu n", result);
}
return result;
}
#define UNICODE
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#pragma comment(lib, "wsock32.lib")
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
#include <winsock2.h>
#include <windows.h>
#include <string>
#include <vector>
#include <winerror.h>
using namespace std;
#include <http.h>
#include <stdio.h>
#pragma comment(lib, "httpapi.lib")
#define MAX_SERVER_SESSION 20
#define INITIALIZE_HTTP_RESPONSE( resp, status, reason )
do
{
RtlZeroMemory( (resp), sizeof(*(resp)) );
(resp)->StatusCode = (status);
(resp)->pReason = (reason);
(resp)->ReasonLength = (USHORT) strlen(reason);
} while (FALSE)
#define ADD_KNOWN_HEADER(Response, HeaderId, RawValue)
do
{
(Response).Headers.KnownHeaders[(HeaderId)].pRawValue =
(RawValue);
(Response).Headers.KnownHeaders[(HeaderId)].RawValueLength =
(USHORT) strlen(RawValue);
} while(FALSE)
#define ALLOC_MEM(cb) HeapAlloc(GetProcessHeap(), 0, (cb))
#define FREE_MEM(ptr) HeapFree(GetProcessHeap(), 0, (ptr))
//
// Prototypes.
//
DWORD DoReceiveRequests(HANDLE hReqQueue);
DWORD
SendHttpResponse(
IN HANDLE hReqQueue,
IN PHTTP_REQUEST pRequest,
IN USHORT StatusCode,
IN PSTR pReason,
IN PSTR pEntity
);
int __cdecl wmain(
int argc,
wchar_t * argv[]
)
{
ULONG retCode;
HANDLE hReqQueue = NULL;
int UrlAdded = 0;
HTTPAPI_VERSION HttpApiVersion = HTTPAPI_VERSION_1;
retCode = HttpInitialize(
HttpApiVersion,
HTTP_INITIALIZE_SERVER | HTTP_INITIALIZE_CONFIG, // Flags
NULL // Reserved
);
if (retCode != NO_ERROR)
{
wprintf(L"HttpInitialize failed with %lu n", retCode);
return retCode;
}
SOCKADDR_IN sa;
static const GUID APPID = { 0x82d41f1f, 0x7251, 0x47c7, { 0xaa, 0x5, 0xf8, 0xe2, 0xe, 0xd4, 0xa1, 0xd6 } };
{
BYTE hash[] = {0xa0, 0xf9, 0x68, 0x3f, 0x7b, 0x38, 0x6f, 0xb7, 0x11, 0x7e, 0x5b, 0xef, 0xec, 0xd2, 0xb2, 0xe4, 0xca, 0x2a, 0x47, 0xf0};
HTTP_SERVICE_CONFIG_SSL_SET scssl;
memset(&sa,0,sizeof(sa));
sa.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
sa.sin_family = AF_INET;
sa.sin_port = 4040;
scssl.KeyDesc.pIpPort = (SOCKADDR*)&sa;
scssl.ParamDesc.AppId = APPID;
scssl.ParamDesc.DefaultCertCheckMode = 0;
scssl.ParamDesc.DefaultFlags = 0;//HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT;
scssl.ParamDesc.DefaultRevocationFreshnessTime = 0;
scssl.ParamDesc.DefaultRevocationUrlRetrievalTimeout = 0;
scssl.ParamDesc.pSslCertStoreName = L"MY";
scssl.ParamDesc.pDefaultSslCtlIdentifier = NULL;
scssl.ParamDesc.pDefaultSslCtlStoreName = NULL;
scssl.ParamDesc.pSslHash =(void*)hash;
scssl.ParamDesc.SslHashLength = sizeof(hash);
retCode = HttpSetServiceConfiguration(NULL,HttpServiceConfigSSLCertInfo,&scssl,sizeof(scssl),NULL);
printf("RetCode = %drn",retCode);
if(retCode!=NO_ERROR)
{
if (retCode == ERROR_ALREADY_EXISTS)
{
retCode = HttpDeleteServiceConfiguration(0,HttpServiceConfigSSLCertInfo,&scssl,sizeof(HTTP_SERVICE_CONFIG_SSL_SET),NULL);
wprintf(L"Delete HttpSetServiceConfiguration = %lu n", retCode);
if (NOERROR == retCode)
{
retCode = HttpSetServiceConfiguration(0,HttpServiceConfigSSLCertInfo,&scssl,sizeof(HTTP_SERVICE_CONFIG_SSL_SET),NULL);
wprintf(L"Setup HttpSetServiceConfiguration = %lu n", retCode);
}else
{
printf("%drn",retCode);
return retCode;
}
}else
{
printf("%drn",retCode);
return retCode;
}
}
}
retCode = HttpCreateHttpHandle(
&hReqQueue, // Req Queue
0 // Reserved
);
if (retCode != NO_ERROR)
{
wprintf(L"HttpCreateHttpHandle failed with %lu n", retCode);
goto CleanUp;
}
wchar_t* temp=NULL;
temp = (wchar_t*)malloc(sizeof(wchar_t)*(256));
if (!temp) return -1;
swprintf(temp, L"%S","https://127.0.0.1:4040/test");
{
retCode = HttpAddUrl(hReqQueue,temp,0);
if (retCode != NO_ERROR)
{
{
wprintf(L"HttpAddUrl failed with %lu n", retCode);
goto CleanUp;
}
}
else
{
UrlAdded ++;
wprintf(L"listening for requests on the following url%d: %wsn",UrlAdded, temp);
}
}
DoReceiveRequests(hReqQueue);
CleanUp:
{
HttpRemoveUrl(hReqQueue, temp);
}
if(hReqQueue)
{
CloseHandle(hReqQueue);
}
HttpTerminate(HTTP_INITIALIZE_SERVER, NULL);
return retCode;
}
DWORD DoReceiveRequests(
IN HANDLE hReqQueue
)
{
ULONG result;
HTTP_REQUEST_ID requestId;
DWORD bytesRead;
PHTTP_REQUEST pRequest;
PCHAR pRequestBuffer;
ULONG RequestBufferLength;
RequestBufferLength = sizeof(HTTP_REQUEST) + 2048*2;
pRequestBuffer = (PCHAR) ALLOC_MEM( RequestBufferLength );
if (pRequestBuffer == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
pRequest = (PHTTP_REQUEST)pRequestBuffer;
HTTP_SET_NULL_ID( &requestId );
for(;;)
{
RtlZeroMemory(pRequest, RequestBufferLength);
result = HttpReceiveHttpRequest(
hReqQueue, // Req Queue
requestId, // Req ID
HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY, // Flags
pRequest, // HTTP request buffer
RequestBufferLength,// req buffer length
&bytesRead, // bytes received
NULL // LPOVERLAPPED
);
if(NO_ERROR == result)
{
// Worked!
bool CheckAuth = false;
if (pRequest->Verb == HttpVerbGET || pRequest->Verb == HttpVerbPOST)
{
//начинаем парсировать буфер
if (pRequest->pEntityChunks && pRequest->pEntityChunks[0].FromMemory.pBuffer)
{
result = SendHttpResponse(hReqQueue, pRequest,200,"OK",NULL);
}else
result = SendHttpResponse(hReqQueue, pRequest,400,"BAD REQUEST",NULL);
}
else
{
wprintf(L"Got a unknown request for %ws n",pRequest->CookedUrl.pFullUrl);
result = SendHttpResponse(hReqQueue, pRequest,503,"Not Implemented",NULL);
}
if(result != NO_ERROR)
{
break;
}
HTTP_SET_NULL_ID( &requestId );
}
else if(result == ERROR_MORE_DATA)
{
requestId = pRequest->RequestId;
RequestBufferLength = bytesRead;
FREE_MEM( pRequestBuffer );
pRequestBuffer = (PCHAR) ALLOC_MEM( RequestBufferLength );
if (pRequestBuffer == NULL)
{
result = ERROR_NOT_ENOUGH_MEMORY;
break;
}
pRequest = (PHTTP_REQUEST)pRequestBuffer;
}
else if(ERROR_CONNECTION_INVALID == result &&
!HTTP_IS_NULL_ID(&requestId))
{
HTTP_SET_NULL_ID( &requestId );
}
else
{
break;
}
}
if(pRequestBuffer)
{
FREE_MEM( pRequestBuffer );
}
return result;
}
DWORD SendHttpResponse(
IN HANDLE hReqQueue,
IN PHTTP_REQUEST pRequest,
IN USHORT StatusCode,
IN PSTR pReason,
IN PSTR pEntityString
)
{
HTTP_RESPONSE response;
HTTP_DATA_CHUNK dataChunk;
DWORD result;
DWORD bytesSent;
INITIALIZE_HTTP_RESPONSE(&response, StatusCode, pReason);
ADD_KNOWN_HEADER(response, HttpHeaderContentType, "text/html");
if(pEntityString)
{
dataChunk.DataChunkType = HttpDataChunkFromMemory;
dataChunk.FromMemory.pBuffer = pEntityString;
dataChunk.FromMemory.BufferLength = (ULONG) strlen(pEntityString);
response.EntityChunkCount = 1;
response.pEntityChunks = &dataChunk;
}
result = HttpSendHttpResponse(
hReqQueue, // ReqQueueHandle
pRequest->RequestId, // Request ID
0, // Flags
&response, // HTTP response
NULL, // pReserved1
&bytesSent, // bytes sent (OPTIONAL)
NULL, // pReserved2 (must be NULL)
0, // Reserved3 (must be 0)
NULL, // LPOVERLAPPED(OPTIONAL)
NULL // pReserved4 (must be NULL)
);
if(result != NO_ERROR)
{
wprintf(L"HttpSendHttpResponse failed with %lu n", result);
}
return result;
}