diff options
Diffstat (limited to 'ot_http.c')
| -rw-r--r-- | ot_http.c | 34 |
1 files changed, 17 insertions, 17 deletions
| @@ -6,6 +6,7 @@ | |||
| 6 | /* System */ | 6 | /* System */ |
| 7 | #define _GNU_SOURCE | 7 | #define _GNU_SOURCE |
| 8 | #include <arpa/inet.h> | 8 | #include <arpa/inet.h> |
| 9 | #include <errno.h> | ||
| 9 | #include <pthread.h> | 10 | #include <pthread.h> |
| 10 | #include <stdio.h> | 11 | #include <stdio.h> |
| 11 | #include <stdlib.h> | 12 | #include <stdlib.h> |
| @@ -85,6 +86,12 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) { | |||
| 85 | buf_reset(&cookie->request); | 86 | buf_reset(&cookie->request); |
| 86 | 87 | ||
| 87 | written_size = write(sock, ws->reply, ws->reply_size); | 88 | written_size = write(sock, ws->reply, ws->reply_size); |
| 89 | /* A send buffer with no room in it is not a failure: nothing went out, so | ||
| 90 | the whole reply goes into the batch below and leaves when the socket | ||
| 91 | drains. Only a real error ends the connection here. */ | ||
| 92 | if (written_size < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) | ||
| 93 | written_size = 0; | ||
| 94 | |||
| 88 | if ((written_size < 0) || ((written_size == ws->reply_size) && !ws->keep_alive)) { | 95 | if ((written_size < 0) || ((written_size == ws->reply_size) && !ws->keep_alive)) { |
| 89 | http_close(sock); | 96 | http_close(sock); |
| 90 | return; | 97 | return; |
| @@ -111,11 +118,9 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) { | |||
| 111 | batch_add(cookie->batch, outbuf, ws->reply_size - written_size); | 118 | batch_add(cookie->batch, outbuf, ws->reply_size - written_size); |
| 112 | 119 | ||
| 113 | /* writeable short data sockets just have a tcp timeout */ | 120 | /* writeable short data sockets just have a tcp timeout */ |
| 114 | if (!ws->keep_alive) { | 121 | if (!ws->keep_alive) |
| 115 | fdstate_set_expiry(sock, 0); | 122 | fdstate_set_expiry(sock, 0); |
| 116 | http_interest_drop(sock, cookie, EVENT_IN); | 123 | http_interest_set(sock, cookie, EVENT_OUT); |
| 117 | } | ||
| 118 | http_interest_add(sock, cookie, EVENT_OUT); | ||
| 119 | } | 124 | } |
| 120 | } | 125 | } |
| 121 | 126 | ||
| @@ -128,21 +133,16 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) { | |||
| 128 | #define HTTPERROR_403_IP return http_issue_error(sock, ws, CODE_HTTPERROR_403_IP) | 133 | #define HTTPERROR_403_IP return http_issue_error(sock, ws, CODE_HTTPERROR_403_IP) |
| 129 | #define HTTPERROR_404 return http_issue_error(sock, ws, CODE_HTTPERROR_404) | 134 | #define HTTPERROR_404 return http_issue_error(sock, ws, CODE_HTTPERROR_404) |
| 130 | #define HTTPERROR_500 return http_issue_error(sock, ws, CODE_HTTPERROR_500) | 135 | #define HTTPERROR_500 return http_issue_error(sock, ws, CODE_HTTPERROR_500) |
| 131 | static void http_interest(const int64_t sock, struct http_data *cookie, int what) { | 136 | /* A connection is either being read or being written, never both, so what it |
| 137 | waits for is set outright rather than added to and taken away again. The | ||
| 138 | event layer only hears about it when the answer changes. */ | ||
| 139 | void http_interest_set(const int64_t sock, struct http_data *cookie, int what) { | ||
| 132 | if (cookie->interest == what) | 140 | if (cookie->interest == what) |
| 133 | return; | 141 | return; |
| 134 | cookie->interest = what; | 142 | cookie->interest = what; |
| 135 | event_modify((int)sock, what, fdstate_generation((int)sock)); | 143 | event_modify((int)sock, what, fdstate_generation((int)sock)); |
| 136 | } | 144 | } |
| 137 | 145 | ||
| 138 | void http_interest_add(const int64_t sock, struct http_data *cookie, int what) { | ||
| 139 | http_interest(sock, cookie, cookie->interest | what); | ||
| 140 | } | ||
| 141 | |||
| 142 | void http_interest_drop(const int64_t sock, struct http_data *cookie, int what) { | ||
| 143 | http_interest(sock, cookie, cookie->interest & ~what); | ||
| 144 | } | ||
| 145 | |||
| 146 | ssize_t http_issue_error(const int64_t sock, struct ot_workstruct *ws, int code) { | 146 | ssize_t http_issue_error(const int64_t sock, struct ot_workstruct *ws, int code) { |
| 147 | const char *error_code[] = {"302 Found", "400 Invalid Request", "400 Invalid Request", "400 Invalid Request", "402 Payment Required", | 147 | const char *error_code[] = {"302 Found", "400 Invalid Request", "400 Invalid Request", "400 Invalid Request", "402 Payment Required", |
| 148 | "403 Not Modest", "403 Access Denied", "404 Not Found", "500 Internal Server Error"}; | 148 | "403 Not Modest", "403 Access Denied", "404 Not Found", "500 Internal Server Error"}; |
| @@ -187,7 +187,7 @@ ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t | |||
| 187 | 187 | ||
| 188 | /* If we came here, wait for the answer is over */ | 188 | /* If we came here, wait for the answer is over */ |
| 189 | if (cookie->flag & STRUCT_HTTP_FLAG_WAITINGFORTASK) { | 189 | if (cookie->flag & STRUCT_HTTP_FLAG_WAITINGFORTASK) { |
| 190 | http_interest_drop(sock, cookie, EVENT_IN); | 190 | http_interest_set(sock, cookie, 0); |
| 191 | cookie->flag &= ~STRUCT_HTTP_FLAG_WAITINGFORTASK; | 191 | cookie->flag &= ~STRUCT_HTTP_FLAG_WAITINGFORTASK; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| @@ -238,7 +238,7 @@ ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t | |||
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | fdstate_set_expiry(sock, time_future_seconds(OT_CLIENT_TIMEOUT_SEND)); | 240 | fdstate_set_expiry(sock, time_future_seconds(OT_CLIENT_TIMEOUT_SEND)); |
| 241 | http_interest_add(sock, cookie, EVENT_OUT); | 241 | http_interest_set(sock, cookie, EVENT_OUT); |
| 242 | return 0; | 242 | return 0; |
| 243 | } | 243 | } |
| 244 | 244 | ||
| @@ -333,7 +333,7 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c | |||
| 333 | /* Clients waiting for us should not easily timeout */ | 333 | /* Clients waiting for us should not easily timeout */ |
| 334 | fdstate_set_expiry(sock, 0); | 334 | fdstate_set_expiry(sock, 0); |
| 335 | fullscrape_deliver(sock, format); | 335 | fullscrape_deliver(sock, format); |
| 336 | http_interest_drop(sock, cookie, EVENT_IN); | 336 | http_interest_set(sock, cookie, 0); |
| 337 | return ws->reply_size = -2; | 337 | return ws->reply_size = -2; |
| 338 | } | 338 | } |
| 339 | #endif | 339 | #endif |
| @@ -428,7 +428,7 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct * | |||
| 428 | /* Clients waiting for us should not easily timeout */ | 428 | /* Clients waiting for us should not easily timeout */ |
| 429 | fdstate_set_expiry(sock, 0); | 429 | fdstate_set_expiry(sock, 0); |
| 430 | fullscrape_deliver(sock, format); | 430 | fullscrape_deliver(sock, format); |
| 431 | http_interest_drop(sock, cookie, EVENT_IN); | 431 | http_interest_set(sock, cookie, 0); |
| 432 | return ws->reply_size = -2; | 432 | return ws->reply_size = -2; |
| 433 | } | 433 | } |
| 434 | #endif | 434 | #endif |
