Sample C Handler for nxweb

03.11.2014

nxweb has easy to use API for writing web handlers in C language.

Directory layout

current working directory/
  |- nxweb_config.json
  |- sample_handler.c
  |- sample_handler.so

sample_handler.c

#include "nxweb/nxweb.h"

static nxweb_result sample_on_request(nxweb_http_server_connection* conn, 
                    nxweb_http_request* req, nxweb_http_response* resp) {
  nxweb_set_response_content_type(resp, "text/html");

  nxweb_response_append_str(resp, "<p>Hello, nxweb!</p>");

  return NXWEB_OK; // always return NXWEB_OK
}

NXWEB_DEFINE_HANDLER(my_sample, .on_request=sample_on_request,
 .flags=NXWEB_HANDLE_ANY|NXWEB_PARSE_PARAMETERS|NXWEB_PARSE_COOKIES);

Compile

nxwebc sample_handler.c -o sample_handler.so

Note that nxwebc script has been added to nxweb on November 10th, 2014. In case you have older nxweb you can run the equivalent:

gcc -shared -fPIC sample_handler.c -o sample_handler.so `pkg-config --cflags nxweb` 

This will create sample_handler.so module that can be dynamically loaded by nxweb using the following configuration file.

nxweb_config.json

{
  "load": [
    {"so": "./sample_handler.so"} // must contain slash
  ],
  "routing": [
    {"prefix":"/sample", "handler":"my_sample"}
  ]
}

This will make our handler accessible via /sample URL prefix.

Launch nxweb

Make sure your current working directory is where nxweb_config.json file is located.

nxweb

Now you should be able to access your handler via http://localhost:8055/sample URL. Error log will go to stderr.

API Notes

NXWEB_DEFINE_HANDLER(<name>, ...) macro defines entry point(s) and other parameters of your handler.

flags bitmask instructs nxweb on how to use the handler:

  • NXWEB_INPROCESS – execute handler in network thread (must be fast and non-blocking)
  • NXWEB_INWORKER – execute handler in worker thread (for lengthy or blocking operations)
  • NXWEB_PARSE_PARAMETERS – parse query string and (url-encoded) post data before calling this handler
  • NXWEB_PRESERVE_URI – modifier for NXWEB_PARSE_PARAMETERS; preserves req->uri string while parsing (allocate copy)
  • NXWEB_PARSE_COOKIES – parse cookie header before calling this handler
  • NXWEB_HANDLE_GET – handler for GET method
  • NXWEB_HANDLE_POST – handler for POST method; implies NXWEB_ACCEPT_CONTENT
  • NXWEB_HANDLE_OTHER – handler for methods other than GET/POST
  • NXWEB_HANDLE_ANY – handler for any method
  • NXWEB_ACCEPT_CONTENT – handler accepts request body

Inside your handler HTTP request information can be extracted from req parameter. You can also use the following functions to get information about request and prepare the response:

const char* nxweb_get_request_header(nxweb_http_request *req, const char* name);

// make sure you set NXWEB_PARSE_PARAMETERS flag for this to work:
const char* nxweb_get_request_parameter(nxweb_http_request *req, const char* name);

// make sure you set NXWEB_PARSE_COOKIES flag for this to work:
const char* nxweb_get_request_cookie(nxweb_http_request *req, const char* name);

void nxweb_set_response_status(nxweb_http_response* resp, int code, const char* message);
void nxweb_set_response_content_type(nxweb_http_response* resp, const char* content_type);
void nxweb_set_response_charset(nxweb_http_response* resp, const char* charset);
void nxweb_add_response_header_safe(nxweb_http_response* resp, const char* name, const char* value);

void nxweb_send_redirect(nxweb_http_response* resp, int code, const char* location, int secure);
void nxweb_send_redirect2(nxweb_http_response *resp, int code, const char* location, const char* location_path_info, int secure);
void nxweb_send_http_error(nxweb_http_response* resp, int code, const char* message);

nxweb_response_append_*() as well as nxweb_response_printf() functions build dynamic response content by writing data into memory buffer that is automatically freed after response has been sent to client.

Blocking operations

nxweb networking is asynchronous and event driven. Make sure you specify NXWEB_INWORKER flag in case your handler is using some sort of blocking operation, eg. connecting to database. This flag will cause your on_request function to be executed on a separate thread without stopping nxweb serving other requests.

Comments