diff options
Diffstat (limited to 'src/c')
-rw-r--r-- | src/c/cgi.c | 2 | ||||
-rw-r--r-- | src/c/fastcgi.c | 53 | ||||
-rw-r--r-- | src/c/http.c | 2 | ||||
-rw-r--r-- | src/c/request.c | 11 | ||||
-rw-r--r-- | src/c/urweb.c | 29 |
5 files changed, 68 insertions, 29 deletions
diff --git a/src/c/cgi.c b/src/c/cgi.c index 1d92073d..38cb7da4 100644 --- a/src/c/cgi.c +++ b/src/c/cgi.c @@ -103,7 +103,7 @@ int main(int argc, char *argv[]) { rr = uw_request(rc, ctx, method, path, query_string, body, body_pos, on_success, on_failure, NULL, log_error, log_debug, - -1); + -1, NULL, NULL); uw_print(ctx, 1); if (rr == SERVED) diff --git a/src/c/fastcgi.c b/src/c/fastcgi.c index 369b6d96..ed51133a 100644 --- a/src/c/fastcgi.c +++ b/src/c/fastcgi.c @@ -113,7 +113,7 @@ static void on_failure(uw_context ctx) { uw_write_header(ctx, "Status: 500 Internal Server Error\r\n"); } -static int write_stdout(void *data, char *buf, size_t len) { +static int write_stdout(void *data, const char *buf, size_t len) { FCGI_Output *o = (FCGI_Output *)data; while (len > 0) { size_t len2 = len; @@ -256,6 +256,42 @@ static int read_nvp(char *buf, int len, nvp *nv) { return 0; } +static int fastcgi_close_with(FCGI_Output *out, request_result rr) { + FCGI_EndRequestBody *erb = (FCGI_EndRequestBody *)out->r.contentData; + + close_stream(out, FCGI_STDOUT); + close_stream(out, FCGI_STDERR); + + if (rr == SERVED) + erb->appStatusB3 = erb->appStatusB2 = erb->appStatusB1 = erb->appStatusB0 = 0; + else + erb->appStatusB3 = erb->appStatusB2 = erb->appStatusB1 = erb->appStatusB0 = 0xFF; + + erb->protocolStatus = FCGI_REQUEST_COMPLETE; + fastcgi_send(out, FCGI_END_REQUEST, sizeof(FCGI_EndRequestBody)); + return close(out->sock); +} + +static int fastcgi_close(int sock) { + FCGI_Output out; + out.sock = sock; + out.r.version = FCGI_VERSION_1; + out.r.paddingLength = 0; + out.r.reserved = 0; + + return fastcgi_close_with(&out, SERVED); +} + +int fastcgi_send_normal(int sock, const void *buf, ssize_t len) { + FCGI_Output out; + out.sock = sock; + out.r.version = FCGI_VERSION_1; + out.r.paddingLength = 0; + out.r.reserved = 0; + + return write_stdout(&out, buf, len); +} + static void *worker(void *data) { int me = *(int *)data; FCGI_Input *in = fastcgi_input(); @@ -411,27 +447,18 @@ static void *worker(void *data) { { request_result rr; - FCGI_EndRequestBody *erb = (FCGI_EndRequestBody *)out->r.contentData; rr = uw_request(rc, ctx, method, path, query_string, body, body_read, on_success, on_failure, out, log_error, log_debug, - in->sock); + in->sock, fastcgi_send_normal, fastcgi_close); if (rr == KEEP_OPEN) goto done2; uw_output(ctx, write_stdout, out); - close_stream(out, FCGI_STDOUT); - close_stream(out, FCGI_STDERR); - - if (rr == SERVED) - erb->appStatusB3 = erb->appStatusB2 = erb->appStatusB1 = erb->appStatusB0 = 0; - else - erb->appStatusB3 = erb->appStatusB2 = erb->appStatusB1 = erb->appStatusB0 = 0xFF; - - erb->protocolStatus = FCGI_REQUEST_COMPLETE; - fastcgi_send(out, FCGI_END_REQUEST, sizeof(FCGI_EndRequestBody)); + fastcgi_close_with(out, rr); + goto done2; } done: diff --git a/src/c/http.c b/src/c/http.c index e4e79848..9550bd4f 100644 --- a/src/c/http.c +++ b/src/c/http.c @@ -188,7 +188,7 @@ static void *worker(void *data) { rr = uw_request(rc, ctx, method, path, query_string, body, back - body, on_success, on_failure, NULL, log_error, log_debug, - sock); + sock, uw_really_send, close); uw_send(ctx, sock); if (rr == SERVED || rr == FAILED) diff --git a/src/c/request.c b/src/c/request.c index 0dbf6290..bbc39d34 100644 --- a/src/c/request.c +++ b/src/c/request.c @@ -151,12 +151,16 @@ void uw_free_request_context(uw_request_context r) { free(r); } +extern char *uw_url_prefix; + request_result uw_request(uw_request_context rc, uw_context ctx, char *method, char *path, char *query_string, char *body, size_t body_len, void (*on_success)(uw_context), void (*on_failure)(uw_context), void *logger_data, uw_logger log_error, uw_logger log_debug, - int sock) { + int sock, + int (*send)(int sockfd, const void *buf, size_t len), + int (*close)(int fd)) { int retries_left = MAX_RETRIES; char *s; failure_kind fk; @@ -201,7 +205,8 @@ request_result uw_request(uw_request_context rc, uw_context ctx, return FAILED; } - if (!strcmp(path, "/.msgs")) { + if (!strncmp(path, uw_url_prefix, strlen(uw_url_prefix)) + && !strcmp(path + strlen(uw_url_prefix), ".msgs")) { char *id = uw_Basis_requestHeader(ctx, "UrWeb-Client"); char *pass = uw_Basis_requestHeader(ctx, "UrWeb-Pass"); @@ -212,7 +217,7 @@ request_result uw_request(uw_request_context rc, uw_context ctx, if (id && pass) { unsigned idn = atoi(id); - uw_client_connect(idn, atoi(pass), sock); + uw_client_connect(idn, atoi(pass), sock, send, close); log_error(logger_data, "Processed request for messages by client %u\n\n", idn); return KEEP_OPEN; } diff --git a/src/c/urweb.c b/src/c/urweb.c index f5f11a2b..6e217e08 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -19,7 +19,7 @@ uw_unit uw_unit_v = {}; // Socket extras -int uw_really_send(int sock, const void *buf, size_t len) { +int uw_really_send(int sock, const void *buf, ssize_t len) { while (len > 0) { ssize_t n = send(sock, buf, len, 0); @@ -112,6 +112,8 @@ typedef struct client { pthread_mutex_t lock, pull_lock; buf msgs; int sock; + int (*send)(int sockfd, const void *buf, ssize_t len); + int (*close)(int fd); time_t last_contact; unsigned n_channels; unsigned refcount; @@ -202,7 +204,9 @@ void uw_set_on_success(char *s) { on_success = s; } -void uw_client_connect(unsigned id, int pass, int sock) { +void uw_client_connect(unsigned id, int pass, int sock, + int (*send)(int sockfd, const void *buf, ssize_t len), + int (*close)(int fd)) { client *c = find_client(id); if (c == NULL) { @@ -228,21 +232,24 @@ void uw_client_connect(unsigned id, int pass, int sock) { } if (c->sock != -1) { - close(c->sock); + c->close(c->sock); c->sock = -1; } c->last_contact = time(NULL); if (buf_used(&c->msgs) > 0) { - uw_really_send(sock, on_success, strlen(on_success)); - uw_really_send(sock, begin_msgs, sizeof(begin_msgs) - 1); - uw_really_send(sock, c->msgs.start, buf_used(&c->msgs)); + send(sock, on_success, strlen(on_success)); + send(sock, begin_msgs, sizeof(begin_msgs) - 1); + send(sock, c->msgs.start, buf_used(&c->msgs)); buf_reset(&c->msgs); close(sock); } - else + else { c->sock = sock; + c->send = send; + c->close = close; + } pthread_mutex_unlock(&c->lock); } @@ -264,10 +271,10 @@ static void client_send(client *c, buf *msg) { pthread_mutex_lock(&c->lock); if (c->sock != -1) { - uw_really_send(c->sock, on_success, strlen(on_success)); - uw_really_send(c->sock, begin_msgs, sizeof(begin_msgs) - 1); - uw_really_send(c->sock, msg->start, buf_used(msg)); - close(c->sock); + c->send(c->sock, on_success, strlen(on_success)); + c->send(c->sock, begin_msgs, sizeof(begin_msgs) - 1); + c->send(c->sock, msg->start, buf_used(msg)); + c->close(c->sock); c->sock = -1; } else buf_append(&c->msgs, msg->start, buf_used(msg)); |