From 0c92419978e6a7818c7659800f6bca84ac9705e6 Mon Sep 17 00:00:00 2001 From: phani Date: Mon, 13 Jan 2020 12:11:08 -0500 Subject: [PATCH] fixed syscall based sync http-req/resp --- runtime/Makefile | 2 +- runtime/include/types.h | 5 ++ runtime/src/sandbox.c | 151 ++++++++++++++++++++++++++++------------ 3 files changed, 113 insertions(+), 45 deletions(-) diff --git a/runtime/Makefile b/runtime/Makefile index c3759ad..06a36ea 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -16,7 +16,7 @@ CFLAGS += -D_GNU_SOURCE #CFLAGS += -DNOSTDIO #CFLAGS += -DSTANDALONE CFLAGS += -DUSE_UVIO -CFLAGS += -DUSE_HTTP_UVIO -DUSE_HTTP_SYNC +#CFLAGS += -DUSE_HTTP_UVIO #-DUSE_HTTP_SYNC CFLAGS += -DSBOX_SCALE_ALLOC #CFLAGS += -DUSE_SYSCALL #CFLAGS += -DPREEMPT_DISABLE diff --git a/runtime/include/types.h b/runtime/include/types.h index 27d5839..59f8361 100644 --- a/runtime/include/types.h +++ b/runtime/include/types.h @@ -157,4 +157,9 @@ typedef enum { #define HTTP_HEADER_MAXSZ 32 #define HTTP_HEADERVAL_MAXSZ 64 +#define HTTP_RESP_200OK "HTTP/1.1 200 OK\r\n" +#define HTTP_RESP_CONTTYPE "Content-type: \r\n" +#define HTTP_RESP_CONTLEN "Content-length: \r\n\r\n" //content body follows this +#define HTTP_RESP_CONTTYPE_PLAIN "text/plain" + #endif /* SFRT_TYPES_H */ diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index f677478..bd798e8 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -146,7 +146,7 @@ sandbox_client_request_get(void) struct http_request *rh = &curr->rqi; if (rh->message_end) break; - r = recv(curr->csock, (curr->req_resp_data + r), curr->mod->max_req_sz - r, 0); + r = recv(curr->csock, (curr->req_resp_data + curr->rr_data_len), curr->mod->max_req_sz - curr->rr_data_len, 0); if (r < 0) { perror("recv2"); return r; @@ -168,61 +168,118 @@ static inline int sandbox_client_response_set(void) { #ifndef STANDALONE + int sndsz = 0; struct sandbox *curr = sandbox_current(); - - int bodylen = curr->rr_data_len; - if (bodylen > 0) { - http_response_body_set(curr->req_resp_data, bodylen); - char len[16] = { 0 }; - sprintf(len, "%d", bodylen); - //content-length = body length - char *key = curr->req_resp_data + curr->rr_data_len; - int lenlen = strlen("content-length: "), dlen = strlen(len); - strcpy(key, "content-length: "); - strncat(key + lenlen, len, dlen); - strncat(key + lenlen + dlen, "\r\n", 2); - http_response_header_set(key, lenlen + dlen + 2); - curr->rr_data_len += lenlen + dlen + 2; - - //content-type as set in the headers. - key = curr->req_resp_data + curr->rr_data_len; - strcpy(key, "content-type: "); - lenlen = strlen("content-type: "); - dlen = strlen(curr->mod->rspctype); - if (dlen == 0) { - int l = strlen("text/plain\r\n\r\n"); - strncat(key + lenlen, "text/plain\r\n\r\n", l); - http_response_header_set(key, lenlen + l); - curr->rr_data_len += lenlen + l; - } else { - strncat(key + lenlen, curr->mod->rspctype, dlen); - strncat(key + lenlen + dlen, "\r\n\r\n", 4); - http_response_header_set(key, lenlen + dlen + 4); - curr->rr_data_len += lenlen + dlen + 4; - } - //TODO - other headers requested in module! + int rsp_hdr_len = strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN); + int bodylen = curr->rr_data_len - rsp_hdr_len; + + memset(curr->req_resp_data, 0, strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN)); + strncpy(curr->req_resp_data, HTTP_RESP_200OK, strlen(HTTP_RESP_200OK)); + sndsz += strlen(HTTP_RESP_200OK); + + if (bodylen == 0) goto done; + strncpy(curr->req_resp_data + sndsz, HTTP_RESP_CONTTYPE, strlen(HTTP_RESP_CONTTYPE)); + if (strlen(curr->mod->rspctype) <= 0) { + strncpy(curr->req_resp_data + sndsz + strlen("Content-type: "), HTTP_RESP_CONTTYPE_PLAIN, strlen(HTTP_RESP_CONTTYPE_PLAIN)); + } else { + strncpy(curr->req_resp_data + sndsz + strlen("Content-type: "), curr->mod->rspctype, strlen(curr->mod->rspctype)); } + sndsz += strlen(HTTP_RESP_CONTTYPE); + char len[10] = { 0 }; + sprintf(len, "%d", bodylen); + strncpy(curr->req_resp_data + sndsz, HTTP_RESP_CONTLEN, strlen(HTTP_RESP_CONTLEN)); + strncpy(curr->req_resp_data + sndsz + strlen("Content-length: "), len, strlen(len)); + sndsz += strlen(HTTP_RESP_CONTLEN); + sndsz += bodylen; - char *st = curr->req_resp_data + curr->rr_data_len; - strcpy(st, "HTTP/1.1 200 OK\r\n"); - curr->rr_data_len += strlen("HTTP/1.1 200 OK\r\n"); +done: + assert(sndsz == curr->rr_data_len); - http_response_status_set(st, strlen("HTTP/1.1 200 OK\r\n")); - int n = http_response_vector(); #ifndef USE_HTTP_UVIO - int r = writev(curr->csock, curr->rsi.bufs, n); - if (r < 0) perror("writev"); + int r = send(curr->csock, curr->req_resp_data, sndsz, 0); + if (r < 0) { + perror("send"); + return -1; + } + while (r < sndsz) { + int s = send(curr->csock, curr->req_resp_data + r, sndsz - r, 0); + if (s < 0) { + perror("send"); + return -1; + } + r += s; + } #else uv_write_t req = { .data = curr, }; - int r = uv_write(&req, (uv_stream_t *)&curr->cuv, curr->rsi.bufs, n, sb_write_callback); + uv_buf_t bufv = uv_buf_init(curr->req_resp_data, sndsz); + int r = uv_write(&req, (uv_stream_t *)&curr->cuv, &bufv, 1, sb_write_callback); sandbox_block_http(); #endif - return 0; -#else + + return 0; #endif } +//static inline int +//sandbox_client_response_set(void) +//{ +//#ifndef STANDALONE +// struct sandbox *curr = sandbox_current(); +// +// int bodylen = curr->rr_data_len; +// if (bodylen > 0) { +// http_response_body_set(curr->req_resp_data, bodylen); +// char len[16] = { 0 }; +// sprintf(len, "%d", bodylen); +// //content-length = body length +// char *key = curr->req_resp_data + curr->rr_data_len; +// int lenlen = strlen("content-length: "), dlen = strlen(len); +// strcpy(key, "content-length: "); +// strncat(key + lenlen, len, dlen); +// strncat(key + lenlen + dlen, "\r\n", 2); +// http_response_header_set(key, lenlen + dlen + 2); +// curr->rr_data_len += lenlen + dlen + 2; +// +// //content-type as set in the headers. +// key = curr->req_resp_data + curr->rr_data_len; +// strcpy(key, "content-type: "); +// lenlen = strlen("content-type: "); +// dlen = strlen(curr->mod->rspctype); +// if (dlen == 0) { +// int l = strlen("text/plain\r\n\r\n"); +// strncat(key + lenlen, "text/plain\r\n\r\n", l); +// http_response_header_set(key, lenlen + l); +// curr->rr_data_len += lenlen + l; +// } else { +// strncat(key + lenlen, curr->mod->rspctype, dlen); +// strncat(key + lenlen + dlen, "\r\n\r\n", 4); +// http_response_header_set(key, lenlen + dlen + 4); +// curr->rr_data_len += lenlen + dlen + 4; +// } +// //TODO - other headers requested in module! +// } +// +// char *st = curr->req_resp_data + curr->rr_data_len; +// strcpy(st, "HTTP/1.1 200 OK\r\n"); +// curr->rr_data_len += strlen("HTTP/1.1 200 OK\r\n"); +// +// http_response_status_set(st, strlen("HTTP/1.1 200 OK\r\n")); +// int n = http_response_vector(); +//#ifndef USE_HTTP_UVIO +// int r = writev(curr->csock, curr->rsi.bufs, n); +// if (r < 0) perror("writev"); +//#else +// uv_write_t req = { .data = curr, }; +// int r = uv_write(&req, (uv_stream_t *)&curr->cuv, curr->rsi.bufs, n, sb_write_callback); +// sandbox_block_http(); +//#endif +// return 0; +//#else +// return 0; +//#endif +//} + void sandbox_entry(void) { @@ -248,6 +305,8 @@ sandbox_entry(void) #ifndef STANDALONE http_parser_init(&curr->hp, HTTP_REQUEST); curr->hp.data = curr; + // NOTE: if more headers, do offset by that! + int rsp_hdr_len = strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN); #ifdef USE_HTTP_UVIO #ifndef USE_UVIO printf("UVIO not enabled!\n"); @@ -262,7 +321,11 @@ sandbox_entry(void) if (sandbox_client_request_get() > 0) #endif { - curr->rr_data_len = 0; // TODO: do this on first write to body. +#ifndef STANDALONE + curr->rr_data_len = rsp_hdr_len; // TODO: do this on first write to body. +#else + curr->rr_data_len = 0; +#endif alloc_linear_memory(); // perhaps only initialized for the first instance? or TODO! //module_table_init(curr_mod);