summaryrefslogtreecommitdiff
path: root/ot_http.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_http.c')
-rw-r--r--ot_http.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/ot_http.c b/ot_http.c
index e8ba3da..bb6ff24 100644
--- a/ot_http.c
+++ b/ot_http.c
@@ -39,9 +39,25 @@ ssize_t g_stats_path_len;
39 39
40enum { SUCCESS_HTTP_HEADER_LENGTH = 80, SUCCESS_HTTP_SIZE_OFF = 17 }; 40enum { SUCCESS_HTTP_HEADER_LENGTH = 80, SUCCESS_HTTP_SIZE_OFF = 17 };
41 41
42/* Give up a connection: the one place that knows everything hanging off it. 42int http_adopt(const int64_t sock, struct http_data *cookie) {
43 The slot is released before anything is freed, so that a late event or the 43 struct http_data *heap = malloc(sizeof(*heap));
44 expiry sweep finds a closed descriptor rather than a freed cookie. */ 44
45 if (!heap)
46 return -1;
47
48 *heap = *cookie;
49 heap->flag &= ~STRUCT_HTTP_FLAG_ONSTACK;
50 fdstate_set_cookie((int)sock, heap);
51
52 if (event_add((int)sock, heap->interest, fdstate_generation((int)sock)) == -1) {
53 fdstate_set_cookie((int)sock, cookie);
54 free(heap);
55 return -1;
56 }
57 return 0;
58}
59
60/* Give up a connection: the one place that knows everything hanging off it. */
45void http_close(const int64_t sock) { 61void http_close(const int64_t sock) {
46 struct http_data *cookie = fdstate_cookie(sock); 62 struct http_data *cookie = fdstate_cookie(sock);
47 63
@@ -54,7 +70,8 @@ void http_close(const int64_t sock) {
54 buf_reset(&cookie->request); 70 buf_reset(&cookie->request);
55 if (cookie->flag & (STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER)) 71 if (cookie->flag & (STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER))
56 mutex_workqueue_canceltask(sock); 72 mutex_workqueue_canceltask(sock);
57 free(cookie); 73 if (!(cookie->flag & STRUCT_HTTP_FLAG_ONSTACK))
74 free(cookie);
58 } 75 }
59 76
60 event_close((int)sock); 77 event_close((int)sock);
@@ -118,11 +135,9 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) {
118 batch_add(cookie->batch, outbuf, ws->reply_size - written_size); 135 batch_add(cookie->batch, outbuf, ws->reply_size - written_size);
119 136
120 /* writeable short data sockets just have a tcp timeout */ 137 /* writeable short data sockets just have a tcp timeout */
121 if (!ws->keep_alive) { 138 if (!ws->keep_alive)
122 fdstate_set_expiry(sock, 0); 139 fdstate_set_expiry(sock, 0);
123 http_interest_drop(sock, cookie, EVENT_IN); 140 http_interest_set(sock, cookie, EVENT_OUT);
124 }
125 http_interest_add(sock, cookie, EVENT_OUT);
126 } 141 }
127} 142}
128 143
@@ -135,21 +150,20 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) {
135#define HTTPERROR_403_IP return http_issue_error(sock, ws, CODE_HTTPERROR_403_IP) 150#define HTTPERROR_403_IP return http_issue_error(sock, ws, CODE_HTTPERROR_403_IP)
136#define HTTPERROR_404 return http_issue_error(sock, ws, CODE_HTTPERROR_404) 151#define HTTPERROR_404 return http_issue_error(sock, ws, CODE_HTTPERROR_404)
137#define HTTPERROR_500 return http_issue_error(sock, ws, CODE_HTTPERROR_500) 152#define HTTPERROR_500 return http_issue_error(sock, ws, CODE_HTTPERROR_500)
138static void http_interest(const int64_t sock, struct http_data *cookie, int what) { 153/* A connection is either being read or being written, never both, so what it
154 waits for is set outright rather than added to and taken away again. The
155 event layer only hears about it when the answer changes. */
156void http_interest_set(const int64_t sock, struct http_data *cookie, int what) {
139 if (cookie->interest == what) 157 if (cookie->interest == what)
140 return; 158 return;
141 cookie->interest = what; 159 cookie->interest = what;
160 /* Still on a stack, so not in the event loop yet: whoever adopts this
161 connection registers whatever it asked for last */
162 if (cookie->flag & STRUCT_HTTP_FLAG_ONSTACK)
163 return;
142 event_modify((int)sock, what, fdstate_generation((int)sock)); 164 event_modify((int)sock, what, fdstate_generation((int)sock));
143} 165}
144 166
145void http_interest_add(const int64_t sock, struct http_data *cookie, int what) {
146 http_interest(sock, cookie, cookie->interest | what);
147}
148
149void http_interest_drop(const int64_t sock, struct http_data *cookie, int what) {
150 http_interest(sock, cookie, cookie->interest & ~what);
151}
152
153ssize_t http_issue_error(const int64_t sock, struct ot_workstruct *ws, int code) { 167ssize_t http_issue_error(const int64_t sock, struct ot_workstruct *ws, int code) {
154 const char *error_code[] = {"302 Found", "400 Invalid Request", "400 Invalid Request", "400 Invalid Request", "402 Payment Required", 168 const char *error_code[] = {"302 Found", "400 Invalid Request", "400 Invalid Request", "400 Invalid Request", "402 Payment Required",
155 "403 Not Modest", "403 Access Denied", "404 Not Found", "500 Internal Server Error"}; 169 "403 Not Modest", "403 Access Denied", "404 Not Found", "500 Internal Server Error"};
@@ -194,7 +208,7 @@ ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t
194 208
195 /* If we came here, wait for the answer is over */ 209 /* If we came here, wait for the answer is over */
196 if (cookie->flag & STRUCT_HTTP_FLAG_WAITINGFORTASK) { 210 if (cookie->flag & STRUCT_HTTP_FLAG_WAITINGFORTASK) {
197 http_interest_drop(sock, cookie, EVENT_IN); 211 http_interest_set(sock, cookie, 0);
198 cookie->flag &= ~STRUCT_HTTP_FLAG_WAITINGFORTASK; 212 cookie->flag &= ~STRUCT_HTTP_FLAG_WAITINGFORTASK;
199 } 213 }
200 214
@@ -245,7 +259,7 @@ ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t
245 } 259 }
246 260
247 fdstate_set_expiry(sock, time_future_seconds(OT_CLIENT_TIMEOUT_SEND)); 261 fdstate_set_expiry(sock, time_future_seconds(OT_CLIENT_TIMEOUT_SEND));
248 http_interest_add(sock, cookie, EVENT_OUT); 262 http_interest_set(sock, cookie, EVENT_OUT);
249 return 0; 263 return 0;
250} 264}
251 265
@@ -340,7 +354,7 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c
340 /* Clients waiting for us should not easily timeout */ 354 /* Clients waiting for us should not easily timeout */
341 fdstate_set_expiry(sock, 0); 355 fdstate_set_expiry(sock, 0);
342 fullscrape_deliver(sock, format); 356 fullscrape_deliver(sock, format);
343 http_interest_drop(sock, cookie, EVENT_IN); 357 http_interest_set(sock, cookie, 0);
344 return ws->reply_size = -2; 358 return ws->reply_size = -2;
345 } 359 }
346#endif 360#endif
@@ -435,7 +449,7 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct *
435 /* Clients waiting for us should not easily timeout */ 449 /* Clients waiting for us should not easily timeout */
436 fdstate_set_expiry(sock, 0); 450 fdstate_set_expiry(sock, 0);
437 fullscrape_deliver(sock, format); 451 fullscrape_deliver(sock, format);
438 http_interest_drop(sock, cookie, EVENT_IN); 452 http_interest_set(sock, cookie, 0);
439 return ws->reply_size = -2; 453 return ws->reply_size = -2;
440} 454}
441#endif 455#endif