Welcome to NESTA!


What is NESTA ?

NESTA is simple and high performance Application Server.
NESTA has basic HTTP server and C library for Web application.

The meaning of 'NESTA' is NEST Applications.

Why use NESTA ?

Because NESTA is written by C language, much processing in few computer resources.
NESTA supports three kinds of OS's of Linux, Mac OS X and Windows.

Features

  • The session cluster which does not depend on a load balancer session management
  • Implemented a simple text template engine
  • Implemented a simple key-value data store (Hash and B+Tree)
  • RDB's connection pooling
  • E-mail transmit a message for SMTP

Benchmarks

It is the result that performed the request of a tiny file by ApacheBench.
The file size of index.html is 54 bytes.

$ ab -c 10 -n 10000 http://localhost/index.html

OS Server Time
[sec]
Requests
[#/sec]
Transfer
[Kbytes/sec]
Result
RedHat 7.1 NESTA 2.338109 4276.96 1010.65 RedHat 7.1(NESTA)
  Apache2 4.782566 2090.93 743.12 RedHat 7.1(Apache2)
CentOS 5.3 NESTA 1.815787 5507.25 1301.36 CentOS 5.3(NESTA)
  Apache2 2.446743 4087.07 1213.04 CentOS 5.3(Apache2)
  lighttpd 1.526228 6552.10 1842.45 CentOS 5.3(lighttpd)
Mac OS X NESTA 1.171 8541.91 2018.69 Mac OS X(NESTA)
  Apache2 1.545 6472.09 2155.26 Mac OS X(Apache2)
Windows Vista NESTA 3.260 3067.11 724.84 Windows Vista(NESTA)
  Apache2 5.148 1942.50 643.07 Windows Vista(Apache2)

How to make

Make the application in NESTA as a shared library.
Linux is so library, Mac OS X is loadable library, Windows is DLL.

The application makes three following functions.

    (1) If necessary, make the initialization function.
    (2) The main function that processes the request.
    (3) If necessary, make the finalization function.

Define an application it in config file of NESTA.
The URL is as follows, http://NESTA-SERVER/samples/hello

nesta.conf
http.appzone = samples
samples.init_api = init_hello, nxsamples.so
samples.api = samples/hello, helloworld, nxsamples.so
samples.term_api = term_hello, nxsamples.so

hello.c
#include "expapi.h"
#include "nestalib.h"

/* HTML body message */
static char* hello_world_body =
    "<html>\n"
    "<body>\n"
    "<p>Hello, World!</p>\n"
    "</body>\n"
    "</html>";

/*
 * It is a function called during the initialization of the NESTA server.
 * This function is called in a state of the single thread.
 * Can initialize the application.
 * It is called before the listening of the HTTP port is started.
 *
 * PARAMETERS
 * u_param(IN): pointer of user paraneter structure
 *
 * RETURN
 *  When success is zero, error is not zero.
 */
EXPAPI int init_hello(struct user_param_t* u_param)
{
    printf("called Hello World, initial fuction.\n");
    return 0;
}

/*
 * It is the function that it is working to be finished,
 * and is called of the NESTA server.
 * This function is called in a state of the single thread.
 * Can finalize the application.
 * It is called at a point in time when the listening
 * of the HTTP port was finished.
 *
 * There is not guaranteed that this function is invited
 * to depending on the stop method of the application.
 *
 * PARAMETERS
 * u_param(IN): pointer of user paraneter structure
 *
 * RETURN
 *  When success is zero, error is not zero.
 */
EXPAPI int term_hello(struct user_param_t* u_param)
{
    printf("called Hello World, terminate fuction.\n");
    return 0;
}

/*
 * It is a function to process the request from a client.
 * This function transmits response data.
 *
 * This function is called in multi-threads,
 * it is necessary for the operation for static variable
 * to synchronize with mutex.
 *
 * PARAMETERS
 * req(IN): pointer of request structure
 * resp(IN): pointer of response structure
 * u_param(IN): pointer of user paraneter structure
 *
 * RETURN
 *  HTTP status number
 */
EXPAPI int helloworld(struct request_t* req,
                      struct response_t* resp,
                      struct user_param_t* u_param)
{
    struct http_header_t* hdr;    /* HTTP header */
    int len;                      /* contents size */

    /* initialize HTTP header */
    hdr = alloc_http_header();
    if (hdr == NULL) {
        err_log(req->addr, "helloworld(): no memory.");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    init_http_header(hdr);

    /* add 'Content-type' header */
    set_content_type(hdr, "text/html", NULL);

    /* add 'Content-length' header */
    len = strlen(hello_world_body);
    set_content_length(hdr, len);

    /* transmit an HTTP header to a client */
    if (resp_send_header(resp, hdr) < 0) {
        err_log(req->addr, "helloworld(): send header error");
        free_http_header(hdr);
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    free_http_header(hdr);

    /* transmit an HTTP body to a client */
    if (resp_send_body(resp, hello_world_body, len) < 0) {
        err_log(req->addr, "helloworld(): send error");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    return HTTP_OK;
}