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 { |
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); |