Skip to content

sbrki/nhttp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nhttp

Nano HTTP library writen in ANSI C (C89).

nhttp is a HTTP library that supports a solid subset of HTTP/1.0 (RFC 1945), and even some HTTP/1.1 features (RFC 2616) such as byte ranges.

It's focus is on having a clean and modern API, good readbility, solid performance & low memory footprint, and is intended for use in constrained computing environments.

Example

#include "nhttp.h"

/* route: /name/{name} */
int path_param_handler(const struct nhttp_ctx *ctx) {
  char buf[1024] = {0};
  sprintf(buf, "Hey %s, how are you?", nhttp_get_path_param(ctx, "name"));
  return nhttp_send_string(ctx, buf, 200);
}

int html_handler(const struct nhttp_ctx *ctx) {
  char *html =
      "<html>"
      "  <head>"
      "    <title>nhttp server</title>"
      "  </head>"
      "  <body>"
      "    <h1>nhttp server</h1>"
      "    <img src='/blob' style='image-rendering:pixelated; width: 20%;'/>"
      "    <p>how is it going</p>"
      "    <audio controls>"
      "      <source src='/song.mp3' type='audio/mpeg'>"
      "    Your browser does not support the audio element."
      "    </audio>"
      "  </body>"
      "</html>";
  return nhttp_send_html(ctx, html, 200);
}

int blob_handler(const struct nhttp_ctx *ctx) {

  unsigned char data[152] = {
      137, 80,  78,  71,  13,  10,  26,  10,  0,   0,   0,   13,  73,  72,
      68,  82,  0,   0,   0,   15,  0,   0,   0,   7,   8,   6,   0,   0,
      0,   215, 133, 23,  39,  0,   0,   0,   1,   115, 82,  71,  66,  0,
      174, 206, 28,  233, 0,   0,   0,   82,  73,  68,  65,  84,  24,  149,
      99,  96,  64,  3,   25,  25,  25,  255, 177, 241, 209, 197, 25,  24,
      24,  24,  152, 208, 5,   240, 105, 68,  55,  128, 241, 126, 161, 218,
      127, 6,   6,   6,   6,   197, 254, 91,  140, 232, 10,  102, 204, 152,
      193, 152, 145, 145, 241, 31,  157, 70,  177, 89,  177, 255, 22,  220,
      16,  152, 38,  124, 46,  130, 201, 227, 117, 54,  33,  239, 80,  164,
      145, 44,  155, 97,  0,   0,   152, 73,  43,  139, 166, 119, 206, 31,
      0,   0,   0,   0,   73,  69,  78,  68,  174, 66,  96,  130,
  };

  return nhttp_send_blob(ctx, data, 152, "image/png", 200);
}

int custom_err_handler(const struct nhttp_ctx *ctx) {
  return nhttp_send_string(ctx, "My custom error code!", 600);
}

int file_handler(const struct nhttp_ctx *ctx) {
  nhttp_set_response_header(ctx, "Content-Type", "audio/mpeg");
  return nhttp_send_file(ctx, "./song.mp3");
}

int temporary_redirect_handler(const struct nhttp_ctx *ctx) {
  return nhttp_redirect(ctx, "/blob", 0);
}

int permanent_redirect_handler(const struct nhttp_ctx *ctx) {
  return nhttp_redirect(ctx, "/blob", 1);
}

/* example route: /query-param?foo=something&bar=else */
int query_param_handler(const struct nhttp_ctx *ctx) {
  char buf[4096] = {0};
  sprintf(buf, "foo = <%s>, bar = <%s>", nhttp_get_query_param(ctx, "foo"),
          nhttp_get_query_param(ctx, "bar"));
  return nhttp_send_string(ctx, buf, 200);
}

/* route: /post/{name} */
int post_handler(const struct nhttp_ctx *ctx) {
  char buf[4096] = {0};
  sprintf(buf, "hello %s", nhttp_get_path_param(ctx, "name"));
  return nhttp_send_string(ctx, buf, 200);
}

int main(void) {
  struct nhttp_server *s = nhttp_server_create();
  nhttp_on_get(s, "/name/{name}/", path_param_handler);
  nhttp_on_get(s, "/html", html_handler);
  nhttp_on_get(s, "/blob", blob_handler);
  nhttp_on_get(s, "/song.mp3", file_handler);
  nhttp_on_get(s, "/600", custom_err_handler);
  nhttp_on_get(s, "/temporary-redirect", temporary_redirect_handler);
  nhttp_on_get(s, "/permanent-redirect", permanent_redirect_handler);
  nhttp_on_get(s, "/query-param", query_param_handler);
  nhttp_on_post(s, "/post/{name}", post_handler);

  nhttp_server_run(s, 8080);
}

Status

This is alpha quality software! Expect bugs, breaking interface changes, and other issues. Even though a solid proportion of nhttp is covered by tests, it is not production-ready software. Due to its stripped-down nature performance on modern machines is solid and nhttp can handle about 18k req/s. Currently the server uses <1KiB of memory (RSS) while idle.

Limitations

nhttp is single threaded (for now). Currently it has the benefit of keeping the code simple enough. For multicore use multiple application processes should be run.

Routing capabilities are also somewhat limited, see nhttp_router.h for more information.

Installation

Dependencies

None.

If you want to run the tests, you will need:

  • cmocka for unit tests (which don't cover all functionality)
  • python3 and requests library for E2E tests. (TODO:sbrki)

Usage

Security

Little thought was given into attack prevention aside from most basic attacks such as buffer overflows, and it may be voulnerable even against those. No effort was given into preventing even basic application level attacks (e.g.: slow lorris). Usage behing a robust and secure reverse proxy (such as Nginx) is a must.

About

Nano HTTP server library in ANSI C.

Resources

License

Stars

Watchers

Forks

Packages

No packages published