|
1 | | -Example Programs |
2 | | -================ |
3 | | - |
4 | | -hello_world.cpp - a very simple example of using libhttpserver to |
5 | | - create a Rest server capable of receiving and processing |
6 | | - HTTP requests. The server will be listening on port |
7 | | - 8080. |
8 | | - |
9 | | - |
10 | | -service.cpp - an example using more of the libhttpserver API. |
11 | | - This creates a Rest server capable of running with |
12 | | - HTTP or HTTPS (provided that libhttpserver and |
13 | | - libmicrohttpd have been compiled with SSL support. |
14 | | - |
15 | | - The server can be configured via command line |
16 | | - arguments: |
| 1 | +libhttpserver Examples |
| 2 | +====================== |
17 | 3 |
|
18 | | - -p <port> - port number to listen on (default 8080) |
19 | | - -s - enable HTTPS |
20 | | - -k - server key filename (default "key.pem") |
21 | | - -c - server certificate filename (default "cert.pem") |
| 4 | +Every example is a standalone program built from a single `.cpp`. To |
| 5 | +build the suite locally: |
| 6 | + |
| 7 | + ./bootstrap && mkdir build && cd build && ../configure && make |
| 8 | + |
| 9 | +Each binary lands in `build/examples/`. To verify that an example also |
| 10 | +compiles against an *installed* libhttpserver (the consumer view), run |
| 11 | +`scripts/verify-installed-examples.sh` after `make install`. To enforce |
| 12 | +the structural invariants on `hello_world.cpp` and `shared_state.cpp` |
| 13 | +(LOC budget, lambda-only form, mutex usage), run |
| 14 | +`scripts/check-examples.sh`. |
| 15 | + |
| 16 | +Start here |
| 17 | +---------- |
| 18 | + |
| 19 | +* `hello_world.cpp` — ten lines, no subclassing, no raw pointers. The |
| 20 | + canonical "hello world" demo and the PRD §3.4 acceptance fixture for |
| 21 | + the v2.0 lambda idiom. |
| 22 | +* `shared_state.cpp` — the canonical example of when the class form is |
| 23 | + the right shape: an `http_resource` subclass that shares a `std::mutex`- |
| 24 | + guarded counter between `render_get` and `render_post`. |
| 25 | + |
| 26 | +HTTP basics |
| 27 | +----------- |
| 28 | + |
| 29 | +* `setting_headers.cpp` — attach response headers fluently with |
| 30 | + `with_header`. |
| 31 | +* `hello_with_get_arg.cpp` — read a query-string parameter from |
| 32 | + `http_request::get_arg`. |
| 33 | +* `args_processing.cpp` — iterate every form/query argument. |
| 34 | +* `custom_error.cpp` — install custom `not_found_handler` and |
| 35 | + `method_not_allowed_handler` and let `set_allowing` restrict methods |
| 36 | + on a resource. |
| 37 | +* `allowing_disallowing_methods.cpp` — narrow a resource to a single |
| 38 | + HTTP method via the allow mask. |
| 39 | +* `url_registration.cpp` — exact paths, prefix matches, regex paths, |
| 40 | + and parametric segments (with optional per-segment regex). |
| 41 | +* `handlers.cpp` — register distinct lambdas for GET and POST on the |
| 42 | + same path; the dispatcher composes them. |
| 43 | + |
| 44 | +Response shapes |
| 45 | +--------------- |
| 46 | + |
| 47 | +* `minimal_file_response.cpp` — stream a file from disk. |
| 48 | +* `binary_buffer_response.cpp` — return a binary buffer (e.g. a PNG). |
| 49 | +* `iovec_response_example.cpp` — gather a response body from multiple |
| 50 | + borrowed buffers without copying. |
| 51 | +* `pipe_response_example.cpp` — stream from a pipe filled by a |
| 52 | + background thread. |
| 53 | +* `empty_response_example.cpp` — bodyless responses for DELETE / HEAD. |
| 54 | +* `minimal_deferred.cpp` — deferred response: the body is produced |
| 55 | + asynchronously by a callback. |
| 56 | +* `deferred_with_accumulator.cpp` — deferred response that mutates |
| 57 | + shared state across calls. |
| 58 | + |
| 59 | +TLS and authentication |
| 60 | +---------------------- |
| 61 | + |
| 62 | +* `minimal_https.cpp` — enable TLS with PEM key/cert files. |
| 63 | +* `minimal_https_psk.cpp` — TLS with pre-shared keys. |
| 64 | +* `basic_authentication.cpp` — per-request HTTP Basic auth inside the |
| 65 | + handler. |
| 66 | +* `centralized_authentication.cpp` — server-wide `auth_handler` and |
| 67 | + `auth_skip_paths`. |
| 68 | +* `digest_authentication.cpp` — per-request HTTP Digest auth via |
| 69 | + `http_request::check_digest_auth`. |
| 70 | +* `client_cert_auth.cpp` — mutual TLS with X.509 client certificates. |
| 71 | + Ships as a documentation artifact; not wired into `noinst_PROGRAMS`. |
| 72 | + |
| 73 | +Operations |
| 74 | +---------- |
| 75 | + |
| 76 | +* `daemon_info.cpp` — introspect the running daemon (bound port, |
| 77 | + listen FD, active connections). |
| 78 | +* `external_event_loop.cpp` — drive `EXTERNAL_SELECT` from the |
| 79 | + application's loop via `run_wait`. |
| 80 | +* `custom_access_log.cpp` — server-wide access-log callback. |
| 81 | +* `minimal_ip_ban.cpp` — `block_ip` / `unblock_ip` under the default |
| 82 | + ACCEPT policy. |
| 83 | +* `turbo_mode.cpp` — turbo, suppressed Date header, fastopen queue, |
| 84 | + listen backlog. |
| 85 | +* `service.cpp` — the kitchen-sink reference example: CLI args, |
| 86 | + optional TLS, all `render_*` overrides. |
| 87 | + |
| 88 | +Benchmarks |
| 89 | +---------- |
| 90 | + |
| 91 | +* `benchmark_select.cpp`, `benchmark_threads.cpp`, |
| 92 | + `benchmark_nodelay.cpp` — micro-benchmarks. See `test/v1_baseline/` for |
| 93 | + v1.x reference numbers. |
| 94 | + |
| 95 | +WebSockets |
| 96 | +---------- |
| 97 | + |
| 98 | +* `websocket_echo.cpp` — `websocket_handler` subclass registered via |
| 99 | + `register_ws_resource` with `std::make_unique`. |
| 100 | + |
| 101 | +File upload |
| 102 | +----------- |
| 103 | + |
| 104 | +* `file_upload.cpp`, `file_upload_with_callback.cpp` — multipart |
| 105 | + upload, GET serves the HTML form and POST processes the parts. |
22 | 106 |
|
23 | 107 | Creating Certificates |
24 | 108 | ===================== |
| 109 | + |
25 | 110 | Self-signed certificates can be created using OpenSSL using the |
26 | 111 | following steps: |
27 | 112 |
|
28 | | - $ openssl genrsa -des3 -passout pass:x -out server.pass.key 2048 |
29 | | - $ openssl rsa -passin pass:x -in server.pass.key -out server.key |
30 | | - $ openssl req -new -key server.key -out server.csr |
31 | | - $ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt |
| 113 | + $ openssl genrsa -des3 -passout pass:x -out server.pass.key 2048 |
| 114 | + $ openssl rsa -passin pass:x -in server.pass.key -out server.key |
| 115 | + $ openssl req -new -key server.key -out server.csr |
| 116 | + $ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt |
32 | 117 |
|
33 | 118 | On the last step when prompted for a challenge password it can be left |
34 | 119 | empty. |
35 | 120 |
|
36 | 121 | Thanks to https://devcenter.heroku.com/articles/ssl-certificate-self |
37 | 122 | for these instructions. |
38 | | - |
39 | | -Keystore configuration |
40 | | -====================== |
41 | | -If using a local client such as RestClient |
42 | | -(https://github.com/wiztools/rest-client) for testing the Rest server |
43 | | -then a keystore needs to be established. These commands should be |
44 | | -bundled with your Java installation. |
45 | | - |
46 | | -$ keytool -noprompt -import -keystore /path/to/restclient.store -alias |
47 | | -restclient -file /path/to/server.crt |
48 | | - |
49 | | -The keys in the store can be listed as follows: |
50 | | - |
51 | | -$ keytool -list -v -keystore /path/to/restclient.store |
52 | | - |
53 | | -The client can then be configured to use this keystore. Thanks to |
54 | | -http://rubensgomes.blogspot.com/2012/01/how-to-set-up-restclient-for-ssl.html |
55 | | -for instructions on configuring RestClient. |
56 | | - |
57 | | - |
58 | | - |
|
0 commit comments