4 #include <stdlib.h> |
4 #include <stdlib.h> |
5 #include <stdio.h> |
5 #include <stdio.h> |
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 |
10 |
10 #include <event.h> |
11 #include <event.h> |
11 #include <evhttp.h> |
12 #include <evhttp.h> |
12 |
13 |
13 #include "render.h" |
14 #include "render.h" |
14 #include "render_remote.h" |
15 #include "render_remote.h" |
15 #include "common.h" |
16 #include "common.h" |
16 |
17 |
|
18 #define CHUNK_SIZE 4096 |
|
19 #define OVERFLOW_BUFFER 4096 |
|
20 |
17 // what render node to use |
21 // what render node to use |
18 static struct sockaddr_storage render_node; |
22 static struct sockaddr_storage render_node; |
19 |
23 |
20 // info on a render request |
24 // info on a render request |
21 struct render_request { |
25 struct render_request { |
22 struct evhttp_request *http_request; |
26 struct evhttp_request *http_request; |
23 |
27 |
24 int headers_sent; |
28 int headers_sent; |
|
29 |
|
30 struct remote_render_ctx *remote_ctx; |
|
31 |
|
32 size_t bytes_sent; |
25 }; |
33 }; |
26 |
34 |
|
35 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 |
|
40 free(ctx); |
|
41 } |
|
42 |
27 void _render_sent (void *arg) { |
43 void _render_sent (void *arg) { |
28 struct render_request *ctx = arg; |
44 struct render_request *ctx = arg; |
|
45 |
|
46 // set chunk size |
|
47 render_remote_set_chunk_size(ctx->remote_ctx, CHUNK_SIZE, OVERFLOW_BUFFER); |
29 |
48 |
30 // send headers |
49 // send headers |
31 evhttp_add_header(ctx->http_request->output_headers, "Content-Type", "image/png"); |
50 evhttp_add_header(ctx->http_request->output_headers, "Content-Type", "image/png"); |
32 evhttp_send_reply_start(ctx->http_request, HTTP_OK, "OK"); |
51 evhttp_send_reply_start(ctx->http_request, HTTP_OK, "OK"); |
33 |
52 |
37 } |
56 } |
38 |
57 |
39 void _render_data (struct evbuffer *buf, void *arg) { |
58 void _render_data (struct evbuffer *buf, void *arg) { |
40 struct render_request *ctx = arg; |
59 struct render_request *ctx = arg; |
41 |
60 |
|
61 size_t buf_size = EVBUFFER_LENGTH(buf); |
|
62 |
42 // send chunk |
63 // send chunk |
43 evhttp_send_reply_chunk(ctx->http_request, buf); |
64 evhttp_send_reply_chunk(ctx->http_request, buf); |
44 |
65 |
45 printf("render [%p]: sent chunk\n", ctx); |
66 printf("render [%p]: enqueued chunk: %zu/%zu bytes\n", ctx, buf_size, ctx->bytes_sent); |
|
67 |
|
68 ctx->bytes_sent += buf_size; |
46 } |
69 } |
47 |
70 |
48 void _render_done (void *arg) { |
71 void _render_done (void *arg) { |
49 struct render_request *ctx = arg; |
72 struct render_request *ctx = arg; |
50 |
73 |
51 // send end |
74 // send end |
52 evhttp_send_reply_end(ctx->http_request); |
75 evhttp_send_reply_end(ctx->http_request); |
53 |
76 |
54 printf("render [%p]: done\n", ctx); |
77 printf("render [%p]: done: %zu bytes\n", ctx, ctx->bytes_sent); |
55 |
78 |
56 // clean up |
79 _render_cleanup(ctx); |
57 free(ctx); |
|
58 } |
80 } |
59 |
81 |
60 void _render_fail (void *arg) { |
82 void _render_fail (void *arg) { |
61 struct render_request *ctx = arg; |
83 struct render_request *ctx = arg; |
62 |
84 |
67 evhttp_send_error(ctx->http_request, 500, "Internal Server Error"); |
89 evhttp_send_error(ctx->http_request, 500, "Internal Server Error"); |
68 } |
90 } |
69 |
91 |
70 printf("render [%p]: failed\n", ctx); |
92 printf("render [%p]: failed\n", ctx); |
71 |
93 |
72 // clean up |
94 _render_cleanup(ctx); |
73 free(ctx); |
95 } |
|
96 |
|
97 void _render_http_lost (struct evhttp_connection *connection, void *arg) { |
|
98 struct render_request *ctx = arg; |
|
99 |
|
100 printf("render [%p]: lost http connection\n", ctx); |
|
101 |
|
102 // cancel |
|
103 render_remote_cancel(ctx->remote_ctx); |
|
104 |
|
105 _render_cleanup(ctx); |
74 } |
106 } |
75 |
107 |
76 void _http_render_execute (struct evhttp_request *request, u_int32_t img_w, u_int32_t img_h) { |
108 void _http_render_execute (struct evhttp_request *request, u_int32_t img_w, u_int32_t img_h) { |
77 // render request context |
109 // render request context |
78 struct render_request *req_ctx = calloc(1, sizeof(struct render_request)); |
110 struct render_request *req_ctx = calloc(1, sizeof(struct render_request)); |
79 |
111 |
80 req_ctx->http_request = request; |
112 req_ctx->http_request = request; |
81 req_ctx->headers_sent = 0; |
113 req_ctx->headers_sent = 0; |
|
114 req_ctx->bytes_sent = 0; |
82 |
115 |
83 // render context |
116 // render context |
84 render_t rend_ctx; |
117 render_t rend_ctx; |
85 render_init(&rend_ctx, RENDER_PNG); |
118 render_init(&rend_ctx, RENDER_PNG); |
86 render_set_size(&rend_ctx, img_w, img_h); |
119 render_set_size(&rend_ctx, img_w, img_h); |
87 render_region_full(&rend_ctx); |
120 render_region_full(&rend_ctx); |
88 |
121 |
89 // initiate the remote render operation |
122 // initiate the remote render operation |
90 if (render_remote(&rend_ctx, &render_node, |
123 if ((req_ctx->remote_ctx = render_remote(&rend_ctx, &render_node, |
91 &_render_sent, |
124 &_render_sent, |
92 &_render_data, |
125 &_render_data, |
93 &_render_done, |
126 &_render_done, |
94 &_render_fail, |
127 &_render_fail, |
95 req_ctx |
128 req_ctx |
96 )) { |
129 )) == NULL) { |
97 free(req_ctx); |
130 free(req_ctx); |
98 fprintf(stderr, "ERR: render_remote\n"); |
131 fprintf(stderr, "ERR: render_remote\n"); |
99 return; |
132 return; |
100 } |
133 } |
|
134 |
|
135 // set close cb |
|
136 evhttp_connection_set_closecb(request->evcon, &_render_http_lost, req_ctx); |
101 |
137 |
102 printf("render [%p]: started\n", req_ctx); |
138 printf("render [%p]: started\n", req_ctx); |
103 } |
139 } |
104 |
140 |
105 /* |
141 /* |
129 |
165 |
130 // clean up the qargs (badly named functions :< ) |
166 // clean up the qargs (badly named functions :< ) |
131 evhttp_clear_headers(&qargs); |
167 evhttp_clear_headers(&qargs); |
132 |
168 |
133 // request log |
169 // request log |
134 printf("REQ: [%s:%d] uri=%s, img_w=%d, img_h=%d\n", peer_address, peer_port, uri, img_w, img_h); |
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); |
135 |
171 |
136 // do it |
172 // do it |
137 _http_render_execute(request, img_w, img_h); |
173 _http_render_execute(request, img_w, img_h); |
138 } |
174 } |
139 |
175 |
|
176 struct event ev_sigint; |
|
177 |
|
178 void sigint_handler (int signal, short event, void *arg) { |
|
179 printf("SIGINT: shutting down\n"); |
|
180 |
|
181 if (event_loopexit(NULL)) |
|
182 err_exit("event_loopexit"); |
|
183 } |
|
184 |
|
185 void signals_init () { |
|
186 signal_set(&ev_sigint, SIGINT, &sigint_handler, NULL); |
|
187 signal_add(&ev_sigint, NULL); |
|
188 } |
|
189 |
|
190 void signals_deinit () { |
|
191 signal_del(&ev_sigint); |
|
192 } |
|
193 |
140 int main (void) { |
194 int main (void) { |
141 // libevent/http init |
195 // libevent init |
142 struct event_base *ev_base = event_init(); |
196 struct event_base *ev_base = event_init(); |
143 |
197 |
144 if (!ev_base) |
198 if (!ev_base) |
145 die("event_init"); |
199 die("event_init"); |
146 |
200 |
|
201 // handle signals |
|
202 signals_init(); |
|
203 |
|
204 // evhttp init |
147 struct evhttp *http_server = evhttp_new(ev_base); |
205 struct evhttp *http_server = evhttp_new(ev_base); |
148 |
206 |
149 if (!http_server) |
207 if (!http_server) |
150 die("evhttp_new"); |
208 die("evhttp_new"); |
151 |
209 |
167 printf("RUN 0.0.0.0:8117\n"); |
225 printf("RUN 0.0.0.0:8117\n"); |
168 |
226 |
169 // run the libevent mainloop |
227 // run the libevent mainloop |
170 if (event_dispatch()) |
228 if (event_dispatch()) |
171 die("event_dispatch"); |
229 die("event_dispatch"); |
|
230 |
|
231 printf("SHUTDOWN\n"); |
172 |
232 |
173 // clean up |
233 // clean up |
|
234 signals_deinit(); |
174 evhttp_free(http_server); |
235 evhttp_free(http_server); |
|
236 event_base_free(ev_base); |
175 |
237 |
176 // successfull exit |
238 // successfull exit |
177 return 0; |
239 return 0; |
178 } |
240 } |