web_main.c
changeset 4 49edbdf9ebe7
parent 3 675be0a45157
child 6 4252c27f2b72
equal deleted inserted replaced
3:675be0a45157 4:49edbdf9ebe7
     6 #include <string.h>
     6 #include <string.h>
     7 #include <netinet/ip.h>
     7 #include <netinet/ip.h>
     8 #include <arpa/inet.h>
     8 #include <arpa/inet.h>
     9 #include <signal.h>
     9 #include <signal.h>
    10 
    10 
    11 #include <event.h>
    11 #include <event2/event.h>
    12 #include <evhttp.h>
    12 #include <event2/event_compat.h>
       
    13 #include <event2/http.h>
       
    14 #include <event2/event_struct.h>
    13 
    15 
    14 #include "render.h"
    16 #include "render.h"
    15 #include "render_remote.h"
    17 #include "render_remote.h"
    16 #include "common.h"
    18 #include "common.h"
    17 
    19 
    18 #define CHUNK_SIZE 4096
    20 #define CHUNK_SIZE 4096
    19 #define OVERFLOW_BUFFER 4096
    21 #define OVERFLOW_BUFFER 4096
    20 
    22 
       
    23 
       
    24 // what event_base we're using
       
    25 static struct event_base *ev_base;
       
    26 
    21 // what render node to use
    27 // what render node to use
    22 static struct sockaddr_storage render_node;
    28 static struct sockaddr_storage render_node;
    23 
    29 
    24 // info on a render request
    30 // info on a render request
    25 struct render_request {
    31 struct render_request {
    31 
    37 
    32     size_t bytes_sent;
    38     size_t bytes_sent;
    33 };
    39 };
    34 
    40 
    35 void _render_cleanup (struct render_request *ctx) {
    41 void _render_cleanup (struct render_request *ctx) {
    36      // not interested anymore
       
    37     evhttp_connection_set_closecb(ctx->http_request->evcon, NULL, NULL);
       
    38 
       
    39     // clean up
    42     // clean up
    40     free(ctx);
    43     free(ctx);
    41 }
    44 }
    42 
    45 
    43 void _render_sent (void *arg) {
    46 void _render_sent (void *arg) {
    45 
    48 
    46     // set chunk size
    49     // set chunk size
    47     render_remote_set_chunk_size(ctx->remote_ctx, CHUNK_SIZE, OVERFLOW_BUFFER);
    50     render_remote_set_chunk_size(ctx->remote_ctx, CHUNK_SIZE, OVERFLOW_BUFFER);
    48 
    51 
    49     // send headers
    52     // send headers
    50     evhttp_add_header(ctx->http_request->output_headers, "Content-Type", "image/png");
    53     evhttp_add_header(evhttp_request_get_output_headers(ctx->http_request), "Content-Type", "image/png");
    51     evhttp_send_reply_start(ctx->http_request, HTTP_OK, "OK");
    54     evhttp_send_reply_start(ctx->http_request, HTTP_OK, "OK");
    52 
    55 
    53     ctx->headers_sent = 1;
    56     ctx->headers_sent = 1;
    54 
    57 
    55     printf("render [%p]: sent headers\n", ctx);
    58     printf("render [%p]: sent headers\n", ctx);
    92     printf("render [%p]: failed\n", ctx);
    95     printf("render [%p]: failed\n", ctx);
    93 
    96 
    94     _render_cleanup(ctx);
    97     _render_cleanup(ctx);
    95 }
    98 }
    96 
    99 
    97 void _render_http_lost (struct evhttp_connection *connection, void *arg) {
   100 void _render_http_lost (struct evhttp_request *req, void *arg) {
    98     struct render_request *ctx = arg;
   101     struct render_request *ctx = arg;
    99 
   102 
   100     printf("render [%p]: lost http connection\n", ctx);
   103     printf("render [%p]: lost http connection\n", ctx);
   101 
   104 
   102     // cancel
   105     // cancel
   131         fprintf(stderr, "ERR: render_remote\n");
   134         fprintf(stderr, "ERR: render_remote\n");
   132         return;
   135         return;
   133     }
   136     }
   134 
   137 
   135     // set close cb
   138     // set close cb
   136     evhttp_connection_set_closecb(request->evcon, &_render_http_lost, req_ctx);
   139     evhttp_set_reply_abortcb(request, &_render_http_lost, req_ctx);
   137     
   140     
   138     printf("render [%p]: started\n", req_ctx);
   141     printf("render [%p]: started\n", req_ctx);
   139 }
   142 }
   140 
   143 
   141 /*
   144 /*
   142  * HTTP request handler
   145  * HTTP request handler
   143  */
   146  */
   144 void http_render (struct evhttp_request *request, void *arg) {
   147 void http_render (struct evhttp_request *request, void *arg) {
   145     // gather some info about the request
   148     // gather some info about the request
   146     const char *uri = evhttp_request_uri(request);
   149     const char *uri = evhttp_request_get_uri(request);
   147     char *peer_address;
   150     char *peer_address;
   148     u_short peer_port;
   151     u_short peer_port;
   149 
   152 
   150     evhttp_connection_get_peer(request->evcon, &peer_address, &peer_port);
   153     evhttp_request_get_peer(request, &peer_address, &peer_port);
   151     
   154     
   152     // request arguments
   155     // request arguments
   153     u_int32_t img_w = 256, img_h = 256;
   156     u_int32_t img_w = 256, img_h = 256;
   154     struct evkeyval *qarg;
   157     struct evkeyval *qarg;
   155     struct evkeyvalq qargs;
   158     struct evkeyvalq qargs;
       
   159 
       
   160 /*
       
   161     enum query_arg_type {
       
   162         QARG_END,
       
   163         QARG_INT,
       
   164     };
       
   165 
       
   166     struct query_arg {
       
   167         const char          *qa_key;
       
   168         enum query_arg_type  qa_type;
       
   169         void                *qa_addr;
       
   170     } arg_def[] = {
       
   171         { "w",      QARG_INT,   &img_w  },
       
   172         { "h",      QARG_INT,   &img_h  },
       
   173         { NULL,     QARG_END,   NULL    }
       
   174     };
       
   175 */
   156 
   176 
   157     evhttp_parse_query(uri, &qargs);
   177     evhttp_parse_query(uri, &qargs);
   158 
   178 
   159     TAILQ_FOREACH(qarg, &qargs, next) {
   179     TAILQ_FOREACH(qarg, &qargs, next) {
   160         if (strcmp(qarg->key, "w") == 0)
   180         if (strcmp(qarg->key, "w") == 0)
   165 
   185 
   166     // clean up the qargs (badly named functions :< )
   186     // clean up the qargs (badly named functions :< )
   167     evhttp_clear_headers(&qargs);
   187     evhttp_clear_headers(&qargs);
   168 
   188 
   169     // request log
   189     // request log
   170     printf("REQ: [%s:%d] method=%d, uri=%s, img_w=%d, img_h=%d\n", peer_address, peer_port, request->type, uri, img_w, img_h);
   190     printf("REQ: [%s:%d] method=%d, uri=%s, img_w=%d, img_h=%d\n", peer_address, peer_port, evhttp_request_get_type(request), uri, img_w, img_h);
   171     
   191     
   172     // do it
   192     // do it
   173     _http_render_execute(request, img_w, img_h);
   193     _http_render_execute(request, img_w, img_h);
   174 }
   194 }
   175 
   195 
   176 struct event ev_sigint;
   196 struct event ev_sigint;
   177 
   197 
   178 void sigint_handler (int signal, short event, void *arg) {
   198 void sigint_handler (int signal, short event, void *arg) {
   179     printf("SIGINT: shutting down\n");
   199     printf("SIGINT: shutting down\n");
   180     
   200     
   181     if (event_loopexit(NULL))
   201     if (event_base_loopexit(ev_base, NULL))
   182         err_exit("event_loopexit");
   202         err_exit("event_loopexit");
   183 }
   203 }
   184 
   204 
   185 void signals_init () {
   205 void signals_init () {
   186     signal_set(&ev_sigint, SIGINT, &sigint_handler, NULL);
   206     signal_set(&ev_sigint, SIGINT, &sigint_handler, NULL);
   191     signal_del(&ev_sigint);
   211     signal_del(&ev_sigint);
   192 }
   212 }
   193 
   213 
   194 int main (void) {
   214 int main (void) {
   195     // libevent init
   215     // libevent init
   196     struct event_base *ev_base = event_init();
   216     ev_base = event_init();
   197 
   217 
   198     if (!ev_base)
   218     if (!ev_base)
   199         die("event_init");
   219         die("event_init");
   200     
   220     
   201     // handle signals
   221     // handle signals
   223 
   243 
   224     // we shall now run
   244     // we shall now run
   225     printf("RUN 0.0.0.0:8117\n");
   245     printf("RUN 0.0.0.0:8117\n");
   226     
   246     
   227     // run the libevent mainloop
   247     // run the libevent mainloop
   228     if (event_dispatch())
   248     if (event_base_dispatch(ev_base))
   229         die("event_dispatch");
   249         die("event_dispatch");
   230 
   250 
   231     printf("SHUTDOWN\n");
   251     printf("SHUTDOWN\n");
   232     
   252     
   233     // clean up
   253     // clean up