summaryrefslogtreecommitdiff
path: root/ot_http.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_http.c')
-rw-r--r--ot_http.c73
1 files changed, 18 insertions, 55 deletions
diff --git a/ot_http.c b/ot_http.c
index fc27eb8..331a457 100644
--- a/ot_http.c
+++ b/ot_http.c
@@ -15,7 +15,7 @@
15#include <unistd.h> 15#include <unistd.h>
16 16
17/* Libowfat */ 17/* Libowfat */
18#include "iob.h" 18#include "io.h"
19 19
20/* Opentracker */ 20/* Opentracker */
21#include "ot_accesslist.h" 21#include "ot_accesslist.h"
@@ -26,17 +26,11 @@
26#include "ot_mutex.h" 26#include "ot_mutex.h"
27#include "ot_scan.h" 27#include "ot_scan.h"
28#include "ot_stats.h" 28#include "ot_stats.h"
29#include "ot_timeout.h"
29#include "scan_urlencoded_query.h" 30#include "scan_urlencoded_query.h"
30#include "trackerlogic.h" 31#include "trackerlogic.h"
31 32
32#ifdef WANT_NO_AUTO_FREE
33#define OT_IOB_INIT(B) (bzero(B, sizeof(io_batch)), 0)
34#else
35#define OT_IOB_INIT(B) iob_init_autofree(B, 0)
36#endif
37
38#define OT_MAXMULTISCRAPE_COUNT 64 33#define OT_MAXMULTISCRAPE_COUNT 64
39#define OT_BATCH_LIMIT (1024 * 1024 * 16)
40extern const char *g_redirecturl; 34extern const char *g_redirecturl;
41 35
42const char *g_stats_path; 36const char *g_stats_path;
@@ -79,7 +73,6 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) {
79 73
80 if (written_size < ws->reply_size) { 74 if (written_size < ws->reply_size) {
81 char *outbuf; 75 char *outbuf;
82 tai6464 t;
83 76
84 if (!(outbuf = malloc(ws->reply_size - written_size))) { 77 if (!(outbuf = malloc(ws->reply_size - written_size))) {
85 buf_reset(&cookie->request); 78 buf_reset(&cookie->request);
@@ -90,25 +83,21 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) {
90 83
91 memcpy(outbuf, ws->reply + written_size, ws->reply_size - written_size); 84 memcpy(outbuf, ws->reply + written_size, ws->reply_size - written_size);
92 if (!cookie->batch) { 85 if (!cookie->batch) {
93 cookie->batch = malloc(sizeof(io_batch)); 86 cookie->batch = calloc(1, sizeof(ot_batch));
94 if (!cookie->batch || OT_IOB_INIT(cookie->batch) == -1) { 87 if (!cookie->batch) {
95 free(cookie->batch);
96 free(outbuf); 88 free(outbuf);
97 buf_reset(&cookie->request); 89 buf_reset(&cookie->request);
98 free(cookie); 90 free(cookie);
99 io_close(sock); 91 io_close(sock);
100 return; 92 return;
101 } 93 }
102
103 cookie->batches = 1;
104 } 94 }
105 95
106 iob_addbuf_free(cookie->batch, outbuf, ws->reply_size - written_size); 96 batch_add(cookie->batch, outbuf, ws->reply_size - written_size);
107 97
108 /* writeable short data sockets just have a tcp timeout */ 98 /* writeable short data sockets just have a tcp timeout */
109 if (!ws->keep_alive) { 99 if (!ws->keep_alive) {
110 taia_uint(&t, 0); 100 timeout_never(sock);
111 io_timeout(sock, t);
112 io_dontwantread(sock); 101 io_dontwantread(sock);
113 } 102 }
114 io_wantwrite(sock); 103 io_wantwrite(sock);
@@ -146,11 +135,9 @@ ssize_t http_issue_error(const int64_t sock, struct ot_workstruct *ws, int code)
146 135
147ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t iovec_entries, struct iovec *iovector, int is_partial) { 136ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t iovec_entries, struct iovec *iovector, int is_partial) {
148 struct http_data *cookie = io_getcookie(sock); 137 struct http_data *cookie = io_getcookie(sock);
149 io_batch *current;
150 char *header; 138 char *header;
151 const char *encoding = ""; 139 const char *encoding = "";
152 size_t i, header_size, size = iovec_length(&iovec_entries, (const struct iovec **)&iovector); 140 size_t header_size, size = iovec_length(&iovec_entries, (const struct iovec **)&iovector);
153 tai6464 t;
154 141
155 /* No cookie? Bad socket. Leave. */ 142 /* No cookie? Bad socket. Leave. */
156 if (!cookie) { 143 if (!cookie) {
@@ -199,46 +186,28 @@ ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t
199 } 186 }
200 187
201 if (!cookie->batch) { 188 if (!cookie->batch) {
202 cookie->batch = malloc(sizeof(io_batch)); 189 cookie->batch = calloc(1, sizeof(ot_batch));
203 if (!cookie->batch || OT_IOB_INIT(cookie->batch) == -1) { 190 if (!cookie->batch) {
204 free(cookie->batch);
205 free(header); 191 free(header);
206 iovec_free(&iovec_entries, &iovector); 192 iovec_free(&iovec_entries, &iovector);
207 HTTPERROR_500; 193 HTTPERROR_500;
208 } 194 }
209 cookie->batches = 1;
210 } 195 }
211 current = cookie->batch + cookie->batches - 1;
212 iob_addbuf_free(current, header, header_size);
213 196
214 /* Split huge iovectors into separate io_batches */ 197 batch_add(cookie->batch, header, header_size);
215 for (i = 0; i < (size_t)iovec_entries; ++i) { 198 batch_add_vector(cookie->batch, iovector, iovec_entries);
216 /* If the current batch's limit is reached, try to reallocate a new batch to work on */
217 if (current->bytesleft > OT_BATCH_LIMIT) {
218 io_batch *new_batch = realloc(cookie->batch, (cookie->batches + 1) * sizeof(io_batch));
219 if (new_batch) {
220 cookie->batch = new_batch;
221 if (OT_IOB_INIT(current) != -1)
222 current = cookie->batch + cookie->batches++;
223 }
224 }
225 iob_addbuf_free(current, iovector[i].iov_base, iovector[i].iov_len);
226 }
227 free(iovector); 199 free(iovector);
200
228 if (cookie->flag & STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER) 201 if (cookie->flag & STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER)
229 iob_addbuf(current, "\r\n", 2); 202 batch_add_copy(cookie->batch, "\r\n", 2);
230 } 203 }
231 204
232 if ((cookie->flag & STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER) && cookie->batch && !is_partial) { 205 if ((cookie->flag & STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER) && cookie->batch && !is_partial) {
233 current = cookie->batch + cookie->batches - 1; 206 batch_add_copy(cookie->batch, "0\r\n\r\n", 5);
234 iob_addbuf(current, "0\r\n\r\n", 5);
235 cookie->flag &= ~STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER; 207 cookie->flag &= ~STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER;
236 } 208 }
237 209
238 /* writeable sockets timeout after 10 minutes */ 210 timeout_in(sock, OT_CLIENT_TIMEOUT_SEND);
239 taia_now(&t);
240 taia_addsec(&t, &t, OT_CLIENT_TIMEOUT_SEND);
241 io_timeout(sock, t);
242 io_wantwrite(sock); 211 io_wantwrite(sock);
243 return 0; 212 return 0;
244} 213}
@@ -317,7 +286,6 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c
317 } 286 }
318 287
319 if (mode == TASK_STATS_TPB) { 288 if (mode == TASK_STATS_TPB) {
320 tai6464 t;
321#ifdef WANT_COMPRESSION_GZIP 289#ifdef WANT_COMPRESSION_GZIP
322 ws->request[ws->request_size - 1] = 0; 290 ws->request[ws->request_size - 1] = 0;
323#ifndef WANT_COMPRESSION_GZIP_ALWAYS 291#ifndef WANT_COMPRESSION_GZIP_ALWAYS
@@ -333,8 +301,7 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c
333 cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED; 301 cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED;
334 302
335 /* Clients waiting for us should not easily timeout */ 303 /* Clients waiting for us should not easily timeout */
336 taia_uint(&t, 0); 304 timeout_never(sock);
337 io_timeout(sock, t);
338 fullscrape_deliver(sock, format); 305 fullscrape_deliver(sock, format);
339 io_dontwantread(sock); 306 io_dontwantread(sock);
340 return ws->reply_size = -2; 307 return ws->reply_size = -2;
@@ -343,13 +310,11 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c
343 310
344 /* default format for now */ 311 /* default format for now */
345 if ((mode & TASK_CLASS_MASK) == TASK_STATS) { 312 if ((mode & TASK_CLASS_MASK) == TASK_STATS) {
346 tai6464 t;
347 313
348 cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; 314 cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK;
349 315
350 /* Complex stats also include expensive memory debugging tools */ 316 /* Complex stats also include expensive memory debugging tools */
351 taia_uint(&t, 0); 317 timeout_never(sock);
352 io_timeout(sock, t);
353 stats_deliver(sock, mode); 318 stats_deliver(sock, mode);
354 return ws->reply_size = -2; 319 return ws->reply_size = -2;
355 } 320 }
@@ -371,7 +336,6 @@ typedef struct {
371static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct *ws) { 336static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct *ws) {
372 struct http_data *cookie = io_getcookie(sock); 337 struct http_data *cookie = io_getcookie(sock);
373 int format = 0; 338 int format = 0;
374 tai6464 t;
375 339
376#ifdef WANT_MODEST_FULLSCRAPES 340#ifdef WANT_MODEST_FULLSCRAPES
377 { 341 {
@@ -430,8 +394,7 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct *
430 /* Pass this task to the worker thread */ 394 /* Pass this task to the worker thread */
431 cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED; 395 cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED;
432 /* Clients waiting for us should not easily timeout */ 396 /* Clients waiting for us should not easily timeout */
433 taia_uint(&t, 0); 397 timeout_never(sock);
434 io_timeout(sock, t);
435 fullscrape_deliver(sock, format); 398 fullscrape_deliver(sock, format);
436 io_dontwantread(sock); 399 io_dontwantread(sock);
437 return ws->reply_size = -2; 400 return ws->reply_size = -2;