Files
cHTTP/examples/server/000_http_server.c
T

99 lines
3.3 KiB
C

#include <stdio.h>
#include <stdbool.h>
#include <chttp.h>
// This example shows how to set up a basic HTTP server
int main(void)
{
http_global_init();
// Choose the interface to listen on and the port.
// Currently, servers can only bind to IPv4 addresses.
HTTP_String addr = HTTP_STR("127.0.0.1");
uint16_t port = 8080;
bool all_interfaces = false;
// If you want to bind to all interfaces, you can
// set the address to an empty string.
if (all_interfaces)
addr = HTTP_STR("");
// Instanciate the HTTP server object
HTTP_Server *server = http_server_init(addr, port);
if (server == NULL)
return -1;
// Now we loop forever. Every iteration will serve
// a single HTTP request
for (;;) {
HTTP_Request *req;
HTTP_ResponseHandle res;
// Block until a request is available
int ret = http_server_wait(server, &req, &res);
// The wait functions returns 0 on success and -1
// on error. By "error" I mean an unrecoverable
// condition. There is no other option than kill
// the process.
if (ret < 0)
return -1;
// The request information is accessible from
// the [req] variable. Most fields in the request
// struct are reference to the original request
// string. They use type HTTP_String and are not
// null-terminated. This means you'll have to make
// sure to express the length when interacting with
// libc:
HTTP_String path = req->url.path;
printf("requested path [%.*s]\n", HTTP_UNPACK(path));
// To find a specific header value, you can either
// iterate over the [req->headers] array or use
// a helper function. Note that this compares header
// names case-insensitively.
int idx = http_find_header(req->headers, req->num_headers, HTTP_STR("Some-Header-Name"));
if (idx == -1) {
// Header wasn't found
} else {
// Found
HTTP_String value = req->headers[idx].value;
printf("Header has value [%.*s]\n", HTTP_UNPACK(value));
}
// To create a response, you will need to specify
// status code, headers, and content in the proper
// order.
// First the status code
http_response_status(res, 200);
// Then zero or more headers
http_response_header(res, HTTP_STR("Content-Type: text/plain"));
// Then you can write zero or more chunks of the response body
http_response_body(res, HTTP_STR("Hello"));
http_response_body(res, HTTP_STR(", world!"));
// Then, mark the request as complete (Very important or the server will hang!)
http_response_done(res);
// Note that none of the http_response_* functions return errors.
// This is by design to simplify user endpoint code. If at any point
// something goes wrong, the server will send a code 4xx or 5xx to
// the client or abort the TCP connection entirely.
}
// This program will loop forever, but if you write
// your server in a way to exit gracefully, this is
// you the server object is freed:
http_server_free(server);
http_global_free();
// Have fun. Bye!
return 0;
}