[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[Libevent-users] Introducing libevscgi, a new libevent-based SCGI server
(Sorry if this is a double-post; I mistakenly sent it to the old
monkey.org address the first time.)
Recently I've been porting the evhttp server from libevent to the SCGI
(Simple Common Gateway Interface) protocol. I got it to respond to test
requests correctly for the first time yesterday, so I've uploaded it to
Gitorious: https://gitorious.org/libevscgi
The API is mostly the same as evhttp. The biggest difference is that it
only implements the server side of the protocol. Another difference is
that it only supports Unix domain sockets (though I'll probably add
support for TCP sockets later). Also, it uses a few parts of evhttp
itself, such as the URI-manipulation functions, the functions for
manipulating the TAILQ header-lists, and the response-code symbolic names.
Here is a simple example, taken from the evhttp example
https://gist.github.com/793194 with a few minor changes, that demonstrates
how to handle SCGI requests in your program:
#include <event.h>
#include <event2/http.h> /* Currently only used for response status code constants. */
#include <evscgi/evscgi.h>
void process_request(struct evscgi_request *req, void *arg)
{
struct evbuffer *buf = evbuffer_new();
if (buf == NULL) return;
evbuffer_add_printf(buf, "Hello world.\n");
evscgi_send_reply(req, HTTP_OK, "OK", buf);
evbuffer_free(buf);
}
int main(int argc, char **argv)
{
struct event_base *base = NULL;
struct evscgi *scgi = NULL;
base = event_base_new();
if (base == NULL) return -1;
scgi = evscgi_new(base);
if (scgi == NULL) return -1;
if (evscgi_bind_unix_socket(scgi, "./scgi_socket") != 0) return -1;
evscgi_set_gencb(scgi, process_request, NULL);
event_base_dispatch(base);
}
I don't necessarily mean to keep the API as close as possible to evhttp,
however. In particular, I'm thinking of making it possible for an
application to receive a request body as a series of chunks (to avoid
keeping the whole thing in memory at once), or similarly to receive the
headers in a one-at-a-time manner. I didn't know about libevhtp when I
started this project, but I might change libevscgi's API to be more like
it.
Also, it seems like it would be good to have a protocol-independent API
for web applications, similar to Python's WSGI, but using a purely
event-driven design. [1] This could be made as a pair of interface
classes, one of which represents a request handler (with a method that's
called once for each request, and/or several methods for receiving the
request a piece at a time) and is implemented by the application, and the
other of which represents a server (with methods for registering the
application's request handlers with the server instance) and is
implemented by wrapper libraries for the different server backends (such
as libevhtp, evhttp, libevscgi, and possibly others). (Maybe there should
also be another pair of interface classes, one of which represents an
active connection and is implemented by the library, the other of which
represents an in-progress request and is implemented by the application.)
I'm thinking of developing an API like this using either C++ or Vala.
[1] WSGI is not really designed for use in a single-threaded event-driven
environment. It provides the request body to the handler as an "input
stream" object which the handler blocking-reads from; also, the handler
itself provides the response body to the middleware either by returning
all of it at once or else "yield"-ing it a piece at a time, in response to
one or more pull-requests from the middleware. This design basically
forces the middleware to have one process/thread per request, or else
handle the requests in a purely serial manner.
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users in the body.