All Classes Namespaces Functions Variables Groups Pages
HttpServer Module

# HttpServer Introduction

The HttpServer module provides a multi-threaded HTTP server to Qore programs.

The HttpServer implemented here was initially designed primarily for serving RPC-style requests, however it has been extended to support REST-style services, and additionally it can also be used to serve files or other content with an appropriate handler.

It has not been audited for security.

To use this module, use `"%requires HttpServer"` in your code. See examples/httpserver.q for an example program using this module

All the public symbols in the module are defined in the HttpServer namespace

The main classes are:

- AbstractAuthenticator: can be implemented to provide authentication and authorization info to the server
- AbstractHttpRequestHandler: this class must be subclassed to provide the real work of the HttpServer handling connections
- AbstractUrlHandler: this class serves as a base class for handler classes that serve requests anchored at a particular URL
- AbstractHttpSocketHandler: this class must be subclassed to implement a dedicated socket handler for protcol changes (for an example, see the WebSocketHandler module)
- HttpServer: this class implements the main interface to the HTTP server provided by this module

See also:

- RestHandler: a module providing a handler framework for this module for implementing server-side REST services
- WebSocketHandler: a module providing a handler framework for this module for implementing server-side WebSocket services
- WebUtil: a module providing higher-level HTTP services using this module as a base as well as providing support for dynamic template-based HTML rendering (ie rendering qhtml files which are a mix of HTML and Qore code)
- JsonRpcHandler: provides infrastructure for implementing JSON-RPC server-side services using the HttpServer module
- YamlRpcHandler: provides infrastructure for implementing YAML-RPC server-side services using the HttpServer module
- XmlRpcHandler: provides infrastructure for implementing XML-RPC server-side services using the HttpServer module
- SoapHandler: provides infrastructure for implementing SOAP server-side services using the HttpServer module

Example:
  #!/usr/bin/env qore
  %requires HttpServer
  %requires Mime
  class MyHandler inherits AbstractHttpRequestHandler {
  hash handleRequest(hash $cx, hash $hdr, *data $body) {
  # NOTE: change "%y" to "%N" to get a more readable multi-line output format for container values
  log("request received on %s from %s: context: %y hdr: %y body size: %d byte%s", $cx."peer-info".desc, $cx."socket-info".desc, $cx, $hdr, $body.size(), $body.size() == 1 ? "" : "s");
  return (
  "code": 200,
  "body": sprintf("<title>Test Page</title><body><h1>Qore HTTP server v%s</h1><p>%y on %s PID %s TID %d connection %d</p><p>Qore %s</p></body>", HttpServer::Version, now_us(), gethostname(), getpid(), gettid(), $cx.id, Qore::VersionString),
  "close": True,
  );
  }
  }
  sub log(string $str) {
  printf("%y: %s\n", now_us(), vsprintf($str, $argv));
  }
  const MyHttpPort = 19001;
  # create our handler object
  my MyHandler $myHandler();
  # create the http server object
  my HttpServer $hs(\log(), \log());
  # add our handler to the server
  $hs.setHandler("my-handler", "/", MimeTypeHtml, $myHandler);
  # set our handler as the default handler
  $hs.setDefaultHandler("my-handler", $myHandler);
  # start a listener
  my hash $lh = $hs.addListener(MyHttpPort);
  # output a log message
  log("started listener on %s", $lh.desc);

# HttpServer Module Release Notes

## HttpServer 0.3.7

- fixed a bug in parsing arguments in parse_uri_query()
- updated parse_uri_query() to accept both `"&"` and `";"` as argument separators
- added support for the `PUT` and `DELETE` methods and for optional message bodies independent of the HTTP method
- fixed handler matching to use a score for each handler and to check dynamic handlers also for a match if the fixed handlers don't provide a perfect match
- fixed response handling to not overwrite the `Connection` header if present from the handler
- fixed response handling to only return error reponses with codes >= 400
- implemented the AbstractHttpSocketHandler handler class to support dedicated socket connections when switching protocols in handlers
- do not add HTML to the msg body from explicit error responses from handlers
- improved HTTP server log messages
- added "family" argument to HttpServer::add*Listener*() methods
- turned of `TCP_NODELAY` by default and use socket shutdown when closing sockets instead
- set the listen backlog queue size to 100 by default (previously was hardcoded internally in Qore to 5)
- use the new ThreadPool class introduced in Qore 0.8.8 to pre-allocate threads to reduce latency for new socket connections
- improved handler matching algorithm
- implemented many performance improvements
- implemented support for simple string path matching when finding a handler for a request
- added static HttpServer::AbstractHttpRequestHandler::redirect() to help in generating 301 Moved Permanently messages

## HttpServer 0.3.6

- fixed a race condition in tracking active requests in dynamic HTTP handlers and removing dynamic HTTP handlers

## HttpServer 0.3.5

- fixed bugs in regexes in the HttpServer::addListeners() and HttpServer::addListenersWithHandler() methods
- updated module example code in summary
- added `"listener-id"` to request context hash

## HttpServer 0.3.4

- added public parse_uri_query() function

## HttpServer 0.3.3

- updated to a user module
- added support for custom redirects from user handlers
- use the Mime module for mime definitions

## HttpServer 0.3.2

- added support for listeners with specific handler lists
- added the ability to manage dynamic content handlers
- implemented content-encoding handling flags in AbstractHttpRequestHandler
- implemented support for `"identity"` encoding (if anyone ever sends it)

## HttpServer 0.3.1

- added IPv6 support in qore 0.8.2

## HttpServer 0.3.0

- added the ability to start and stop listeners on demand

## HttpServer 0.2.9

- updates for new SSL and timeout behavior with with Socket class with qore 0.8.1+
- set socket encoding to UTF-8 by default
- add `"charset=utf-8"` to `Content-Type` header if not already present
- add `"text/html"` to `Content-Type` header if no content-type is given by the handler
- fixed setting X.509 certificate and private key for HTTPS listeners
- require qore >= 0.8.1 for new Socket features

## HttpServer 0.2.8

- converted to hard typing for use with require-types
- require qore >= 0.8.0 for new Socket features

## HttpServer 0.2.7

- set `TCP_NODELAY` on all sockets to ensure that clients get all data before closing the socket, especially in case of errors
- require qore >= 0.7.4 for new Socket features

## HttpServer 0.2.6

- minor fixes for SOAP support
- improved handler matching

## HttpServer 0.2.5

- minor fixes for SOAP support

## HttpServer 0.2.4

- improved `Content-Type` handling
- improved URL/path support

## HttpServer 0.2.3

- bzip2 `Content-Encoding` support

## HttpServer 0.2.2

- basic authentication

## HttpServer 0.2.1

- implementing logic to handle `"deflate"` and `"gzip"` content-encoding
- chunked content-encoding supported for POSTs
- Date: header always sent as per HTTP 1.1 spec

## HttpServer 0.2.0

- modular/multiple listener support added
- https support added