2011/06/20

HTTP server over libevent - sample code (2)

加入一些parse的function,可以得到request的method、URI、header、body、path

#include 
#include 
#include 
#include 
#include 

#define SVR_IP                         "127.0.0.1"
#define SVR_PORT                       8080

void dump_cb (struct evhttp_request *req, void *arg) {
    const char        *uri;
    struct evkeyvalq  *headers;
    struct evkeyval   *header;
    struct evbuffer   *evbuf;
    struct evhttp_uri *ev_uri;
    
    /* Get method */
    switch (evhttp_request_get_command(req)) {
        case EVHTTP_REQ_GET: 
            printf("Request method=[GET]\n");
            break;
        case EVHTTP_REQ_POST:
            printf("Request method=[POST]\n");
            break;
        default:
            printf("Request method=[others]\n");
            break;
    }
    
    /* Get path */
    uri = evhttp_request_get_uri(req);
    printf("Request uri=[%s]\n",  uri);
    
    /* Get header */
    printf("Headers:\n");
    headers = evhttp_request_get_input_headers(req);
    for (header = headers->tqh_first; header;
        header = header->next.tqe_next) {
        printf("  %s: %s\n", header->key, header->value);
    }
        
    /* Get body */
    evbuf = evhttp_request_get_input_buffer(req);
    printf("Body:\n");
    while (evbuffer_get_length(evbuf)) {
        int  size;
        char buf[128];
        
        memset(buf, 0, sizeof(buf));
        size = evbuffer_remove(evbuf, buf, sizeof(buf) - 1);
        printf("  %s\n", buf);
    }
    
    /* */
    ev_uri = evhttp_uri_parse(uri);
    if (ev_uri) {
        const char *path;
        char       *decoded_path;
        
        path = evhttp_uri_get_path(ev_uri);
        decoded_path = evhttp_uridecode(path, 0, NULL);
        printf("Request path=[%s]\n", decoded_path);
        
        /* Free resource */
        free(decoded_path);
        evhttp_uri_free(ev_uri);
    }
    
    /* Response */
    evhttp_send_reply(req, HTTP_OK, "OK", NULL);
}

int main (int argc, char **argv) {
    struct event_base *evbase;
    struct evhttp     *evhttp;

    /* Init event base */
    if ((evbase = event_base_new()) == NULL) {
        printf("event_base_new() failed\n");
        return -1;
    }

    /* Init evhttp */
    if ((evhttp = evhttp_new(evbase)) == NULL) {
        printf("evhttp_new() failed\n");
        return -1;
    }

    /* Set server IP, port */
    if (evhttp_bind_socket(evhttp, SVR_IP, SVR_PORT) == -1) {
        printf("evhttp_bind_socket() failed\n");
        return -1;
    } else {
        printf("Listening on [%s:%d]\n", SVR_IP, SVR_PORT);
    }
    
    /* Set timeout */
    evhttp_set_timeout(evhttp, 10);
    
    /* Set a callback for default path */
    evhttp_set_gencb(evhttp, dump_cb, NULL);

    /* Enter event loop */
    event_base_dispatch(evbase);

    /* Free resource */
    evhttp_free(evhttp);
    event_base_free(evbase);
    
    return 0;
}



Compile and run
$ gcc -g -Wall -o httpd httpd.c -levent -I/opt/libevent-2.0.12-stable/include/ -L/opt/libevent-2.0.12-stable/lib/
$ LD_LIBRARY_PATH=/opt/libevent-2.0.12-stable/lib ./httpd
Listening on [127.0.0.1:8080]

Request method=[GET]
Request uri=[/test.php?name=kevin&sex=male]
Headers:
  User-Agent: Wget/1.11.4 Red Hat modified
  Accept: */*
  Host: 127.0.0.1:8080
  Connection: Keep-Alive
Body:
Request path=[/test.php]

Request method=[POST]
Request uri=[/test.php]
Headers:
  User-Agent: Wget/1.11.4 Red Hat modified
  Accept: */*
  Host: 127.0.0.1:8080
  Connection: Keep-Alive
  Content-Type: application/x-www-form-urlencoded
  Content-Length: 19
Body:
  name=sylar&sex=male
Request path=[/test.php]


try to send a request to server...
# Get
$wget -q -O - 'http://127.0.0.1:8080/test.php?name=sylar&sex=male'

# Post
$wget -q -O - --post-data='name=sylar&sex=male' http://127.0.0.1:8080/test.php


沒有留言:

張貼留言