diff --git a/README.md b/README.md index 3fee8cd..0b46d55 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,156 @@ # cHTTP -This is an HTTP library for C, featuring an HTTP(S) server, HTTP(S) client, and much more! +cHTTP is an HTTP client and server library distributed as a single file with support for HTTPS, virtual hosts, fully non-blocking operations. + +## Quick Start + +### Your first request + +The simplest way to perform a GET request looks like this: + +```c +#include "chttp.h" + +int main(void) +{ + CHTTP_Response *response; + + int ret = chttp_get(CHTTP_STR("http://coz.is/"), NULL, 0, &response); + if (ret == CHTTP_OK) { + printf("Received %d bytes\n", response->body.len); + chttp_free_response(response); + } else { + printf("Request failure: %s\n", chttp_strerror(ret)); + } + return 0; +} +``` + +(Note the `http:` schema. If you want HTTPS, you'll have to enable it explicitly! Refer to the HTTPS section.) + +Copy this code to `first_request.c` near `chttp.c` and compile it by running: + +```sh +# Linux +gcc chttp.c first_request.c -o first_request + +# Windows (mingw) +gcc chttp.c first_request.c -o first_request.exe -lws2_32 +``` + +Then, run the program + +```sh +# Linux +./first_request + +# Windows +.\first_request.exe +``` + +Done! + +### Your first server + +The setup for a basic server looks like this: + +```c +#include "chttp.h" + +int main(void) +{ + int ret; + + CHTTP_Server server; + ret = chttp_server_init(&server); + if (ret < 0) { + fprintf(stderr, "Couldn't initialize server (%s)\n", chttp_strerror(ret)); + return -1; + } + + chttp_server_set_reuse_addr(&server, true); + chttp_server_set_trace_bytes(&server, true); + + ret = chttp_server_listen_tcp(&server, CHTTP_STR("127.0.0.1"), 8080); + if (ret < 0) { + fprintf(stderr, "Couldn't start listening (%s)\n", chttp_strerror(ret)); + return -1; + } + + for (;;) { + + CHTTP_Request *request; + CHTTP_ResponseBuilder builder; + chttp_server_wait_request(&server, &request, &builder); + + chttp_response_builder_status(builder, 200); + chttp_response_builder_body(builder, CHTTP_STR("Hello, world!")); + chttp_response_builder_send(builder); + } + + chttp_server_free(&server); + return 0; +} +``` + +Copy this code to a `first_server.c` file and compile it by running + +```sh +# Linux +gcc chttp.c first_server.c -o first_server + +# Windows (mingw) +gcc chttp.c first_server.c -o first_server.exe -lws2_32 +``` + +Then, run the program + +```sh +# Linux +./first_server + +# Windows +.\first_server.exe +``` + +While the program is running, open a browser and visit `http://127.0.0.1:8080/`. You should see the text "Hello, world!" sent by the server and a log of the HTTP requests and responses processed by the server in the console. + +## HTTPS + +HTTPS is supported via OpenSSL, which is easily available on Linux and less so on Windows. + +First, install the OpenSSL development libraries: + +```sh +# Ubuntu/Debian Linux +sudo apt install libssl-dev gcc +``` + +Then, enable HTTPS by compiling your program with the following flags: + +```sh +# Linux +gcc chttp.c main.c -lssl -lcrypto -DHTTPS_ENABLED + +# Windows +gcc chttp.c main.c -lws2_32 -lssl -lcrypto -DHTTPS_ENABLED +``` + +## Development Status + +The major limitation of cHTTP is HTTPS on Windows. For that to work correctly it will be necessary to port the OpenSSL code to SChannel. + +Other limitations: +* HTTP client doesn't follow redirections (responses with code 3xx) +* Support for HTTP client cookies is limited +* HTTP server adherence to the spec can be improved ## Contributing Contributions are welcome! The following are some notes on how to work with the codebase. Don't worry if you get something wrong. I will remind you. -The source code in the `src/` directory is intended to be be amalgamated into a single file before compilation. The amalgamation is not only intended as a distribution method, but also as easy-access documentation, and therefore need to be readable. For this reasons: -1. You never need need to include other cHTTP source files -2. All inclusions of third-party headers are to be placed inside `src/includes.h` -3. All files must start with a single empty line, unless they start with an overview comment of the file, in which case they must have no empty lines at the beginning of the file. -4. All files must end with a single empty line. +The source code in the src/ directory is intended to be be amalgamated into a single file before compilation. The amalgamation is not only intended as a distribution method, but also as easy-access documentation, and therefore need to be readable. For this reasons: + +* You never need need to include other cHTTP source files +* All inclusions of third-party headers are to be placed inside src/includes.h +* All files must start with a single empty line, unless they start with an overview comment of the file, in which case they must have no empty lines at the beginning of the file. +* All files must end with a single empty line. \ No newline at end of file