2008年3月29日土曜日

HTTP Server API

以前からWindows OSにはIISが含まれていたけど、Windows XP SP2、Windows Server 2003以降にはOS側にWebサーバ機能が組み込まれていて、IISもこれを使う設計らしい。
試しにこのHTTP Server APIを使ってみた。

HTTPAPI_VERSION version = HTTPAPI_VERSION_1;
HttpInitialize( version, HTTP_INITIALIZE_SERVER, NULL );

HANDLE handle;
HttpCreateHttpHandle( &handle, NULL );

HttpAddUrl( handle, L"http://+:80/", NULL );

while( !stop ){
HTTP_REQUEST_ID requestId;
HTTP_SET_NULL_ID( &requestId );
char buffer[ 4096 ] = {};
PHTTP_REQUEST request = reinterpret_cast<PHTTP_REQUEST>( buffer );
ULONG size;
HttpReceiveHttpRequest( handle, requestId, 0, request, sizeof buffer, &size, NULL );

HTTP_RESPONSE response;
memset( &response, 0, sizeof response ); // デフォルトコンストラクタ用意してください(;;)
HTTP_DATA_CHUNK chunk;
HANDLE file = INVALID_HANDLE_VALUE;
if( request->Verb != HttpVerbGET )
response.StatusCode = 503;
else{
// URLパスの先頭の'/'をスキップ
file = CreateFileW( &request->CookedUrl.pAbsPath[1], FILE_READ_DATA, 0, NULL, OPEN_EXISTING, 0, NULL );
if( file == INVALID_HANDLE_VALUE )
response.StatusCode = 404;
else{
chunk.DataChunkType = HttpDataChunkFromFileHandle;
chunk.FromFileHandle.ByteRange.StartingOffset.QuadPart = 0;
chunk.FromFileHandle.ByteRange.Length.QuadPart = HTTP_BYTE_RANGE_TO_EOF;
chunk.FromFileHandle.FileHandle = file;
response.StatusCode = 200;
response.EntityChunkCount = 1;
response.pEntityChunks = &chunk;
}
}
HttpSendHttpResponse( handle, request->RequestId, 0, &response, NULL, &size, NULL, 0, NULL, NULL );
if( file != INVALID_HANDLE_VALUE )
CloseHandle( file );
}
HttpRemoveUrl( handle, L"http://+:80/" );
CloseHandle( handle );
HttpTerminate( HTTP_INITIALIZE_SERVER, NULL );
サンプルなのでエラー処理は省いてます。機能的には、カレントディレクトリのファイルを返します。
stop = trueとしてもすぐには終了しません。HttpReceiveHttpRequest()でブロックされているので、次のリクエストを処理したところでループを抜けます。

0 件のコメント: