Skip to content

Instantly share code, notes, and snippets.

@imba-tjd
Created May 20, 2024 14:12
Show Gist options
  • Save imba-tjd/523b377a0d36d40ae5109826e9eb9a0f to your computer and use it in GitHub Desktop.
Save imba-tjd/523b377a0d36d40ae5109826e9eb9a0f to your computer and use it in GitHub Desktop.
// gcc server.c -O2 -lhttpapi -o server
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <http.h>
#include <windows.h>
#include <signal.h>
HANDLE hReqQueue = NULL;
HTTP_SERVER_SESSION_ID serverSessionId;
HTTP_URL_GROUP_ID urlGroupId;
void cleanup(int) {
HttpCloseRequestQueue(hReqQueue);
HttpCloseUrlGroup(urlGroupId);
HttpCloseServerSession(serverSessionId);
HttpTerminate(HTTP_INITIALIZE_SERVER, NULL);
printf("Server terminated\n");
}
int main() {
ULONG ret;
HTTP_BINDING_INFO bindingInfo;
HTTP_TIMEOUT_LIMIT_INFO timeoutLimitInfo;
HTTP_REQUEST_ID requestId;
HTTP_RESPONSE response;
DWORD bytesRead, bytesSent;
HTTP_REQUEST *request = NULL;
ULONG requestBufferLength = sizeof(HTTP_REQUEST) + 1024;
char requestBuffer[sizeof(HTTP_REQUEST) + 1024];
// Initialize HTTP Server API
ret = HttpInitialize((HTTPAPI_VERSION)HTTPAPI_VERSION_2, HTTP_INITIALIZE_SERVER, NULL);
if (ret != NO_ERROR) {
printf("HttpInitialize failed with %lu\n", ret);
return ret;
}
// Create HTTP Server Session
ret = HttpCreateServerSession((HTTPAPI_VERSION)HTTPAPI_VERSION_2, &serverSessionId, 0);
if (ret != NO_ERROR) {
printf("HttpCreateServerSession failed with %lu\n", ret);
return ret;
}
// Create URL Group
ret = HttpCreateUrlGroup(serverSessionId, &urlGroupId, 0);
if (ret != NO_ERROR) {
printf("HttpCreateUrlGroup failed with %lu\n", ret);
return ret;
}
// Create Request Queue
ret = HttpCreateRequestQueue((HTTPAPI_VERSION)HTTPAPI_VERSION_2, NULL, NULL, 0, &hReqQueue);
if (ret != NO_ERROR) {
printf("HttpCreateRequestQueue failed with %lu\n", ret);
return ret;
}
// Bind URL Group to Request Queue
bindingInfo.Flags.Present = 1;
bindingInfo.RequestQueueHandle = hReqQueue;
ret = HttpSetUrlGroupProperty(urlGroupId, HttpServerBindingProperty, &bindingInfo, sizeof(bindingInfo));
if (ret != NO_ERROR) {
printf("HttpSetUrlGroupProperty failed with %lu\n", ret);
return ret;
}
// Set URL
ret = HttpAddUrlToUrlGroup(urlGroupId, L"http://localhost:8080/", 0, 0);
if (ret != NO_ERROR) {
printf("HttpAddUrlToUrlGroup failed with %lu\n", ret);
return ret;
}
signal(SIGINT, cleanup);
// Main loop to handle requests
while (1) {
// Initialize request structure
ZeroMemory(&requestBuffer, requestBufferLength);
request = (HTTP_REQUEST*) requestBuffer;
requestId = 0;
// Receive a request
ret = HttpReceiveHttpRequest(hReqQueue, requestId, 0, request, requestBufferLength, &bytesRead, NULL);
if (ret == NO_ERROR) {
// Initialize the response
ZeroMemory(&response, sizeof(response));
response.StatusCode = 200;
response.pReason = "OK";
response.ReasonLength = (USHORT)strlen(response.pReason);
response.Headers.KnownHeaders[HttpHeaderContentType].pRawValue = "text/plain";
response.Headers.KnownHeaders[HttpHeaderContentType].RawValueLength = (USHORT)strlen(response.Headers.KnownHeaders[HttpHeaderContentType].pRawValue);
// Response body
const char* responseBody = "Hello, World!";
HTTP_DATA_CHUNK dataChunk;
dataChunk.DataChunkType = HttpDataChunkFromMemory;
dataChunk.FromMemory.pBuffer = (PVOID)responseBody;
dataChunk.FromMemory.BufferLength = (ULONG)strlen(responseBody);
response.EntityChunkCount = 1;
response.pEntityChunks = &dataChunk;
// Send the response
ret = HttpSendHttpResponse(hReqQueue, request->RequestId, 0, &response, NULL, &bytesSent, NULL, 0, NULL, NULL);
if (ret != NO_ERROR) {
printf("HttpSendHttpResponse failed with %lu\n", ret);
}
} else {
printf("HttpReceiveHttpRequest failed with %lu\n", ret);
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment