read from stdin (http req body), write to stdout (http resp body), bug fixes in http parsing

main
phani 5 years ago
parent f019193952
commit ae392fdfe3

@ -37,14 +37,4 @@ struct http_response {
uv_buf_t bufs[HTTP_HEADERS_MAX * 2 + 3]; //max headers, one line for status code, remaining for body!
};
int http_request_body_get(char **body);
int http_request_parse(void);
int http_response_header_set(char *h, int len);
int http_response_body_set(char *body, int len);
int http_response_status_set(char *status, int len);
int http_response_uv(void);
void http_init(void);
#endif /* SFRT_HTTP_H */

@ -0,0 +1,51 @@
#ifndef SRFT_HTTP_API_H
#define SRFT_HTTP_API_H
#include <http.h>
int http_request_body_get_sb(struct sandbox *s, char **body);
int http_request_parse_sb(struct sandbox *s, size_t l);
int http_response_header_set_sb(struct sandbox *s, char *h, int len);
int http_response_body_set_sb(struct sandbox *s, char *body, int len);
int http_response_status_set_sb(struct sandbox *s, char *status, int len);
int http_response_uv_sb(struct sandbox *s);
void http_init(void);
static inline int
http_request_body_get(char **b)
{
return http_request_body_get_sb(sandbox_current(), b);
}
static inline int
http_response_header_set(char *key, int len)
{
return http_response_header_set_sb(sandbox_current(), key, len);
}
static inline int
http_response_body_set(char *body, int len)
{
return http_response_body_set_sb(sandbox_current(), body, len);
}
static inline int
http_response_status_set(char *status, int len)
{
return http_response_status_set_sb(sandbox_current(), status, len);
}
static inline int
http_response_uv(void)
{
return http_response_uv_sb(sandbox_current());
}
static inline int
http_request_parse(size_t l)
{
return http_request_parse_sb(sandbox_current(), l);
}
#endif /* SRFT_HTTP_API_H */

@ -33,7 +33,7 @@ struct module {
// rest of the connection is handled in sandboxing threads, with per-core(per-thread) tls data-structures.
// so, using direct epoll for accepting connections.
// uv_handle_t srvuv;
unsigned long max_req_sz, max_resp_sz, max_rr_sz; // req/resp from http..
unsigned long max_req_sz, max_resp_sz, max_rr_sz; // req/resp from http, (resp size including headers!)..
int nreqhdrs, nresphdrs;
char reqhdrs[HTTP_HEADERS_MAX][HTTP_HEADER_MAXSZ];
char rqctype[HTTP_HEADERVAL_MAXSZ];

@ -61,6 +61,7 @@ struct sandbox {
struct sockaddr client; //client requesting connection!
int csock;
uv_tcp_t cuv;
uv_shutdown_t cuvsr;
http_parser hp;
struct http_request rqi;
struct http_response rsi;

@ -148,7 +148,7 @@ typedef enum {
#define SBOX_RESP_STRSZ 32
#define MOD_BACKLOG 100
#define MOD_BACKLOG 10000
#define EPOLL_MAX 1024
#define MOD_REQ_RESP_DEFAULT (PAGE_SIZE)
#define QUIESCENSE_TIME (1<<20) //cycles!

@ -1,34 +1,44 @@
#include <http.h>
#include <sandbox.h>
#include <uv.h>
#include <http_api.h>
http_parser_settings settings;
static inline int
http_on_msg_begin(http_parser *parser)
{
struct http_request *r = parser->data;
#ifndef STANDALONE
struct sandbox *s = parser->data;
struct http_request *r = &s->rqi;
r->message_begin = 1;
r->last_was_value = 1; //should always start with a header..
#endif
return 0;
}
static inline int
http_on_msg_end(http_parser *parser)
{
struct http_request *r = parser->data;
#ifndef STANDALONE
struct sandbox *s = parser->data;
struct http_request *r = &s->rqi;
r->message_end = 1;
#endif
return 0;
}
static inline int
http_on_header_end(http_parser *parser)
{
struct http_request *r = parser->data;
#ifndef STANDALONE
struct sandbox *s = parser->data;
struct http_request *r = &s->rqi;
r->header_end = 1;
#endif
return 0;
}
@ -36,8 +46,8 @@ static inline int
http_on_url(http_parser* parser, const char *at, size_t length)
{
#ifndef STANDALONE
struct sandbox *s = sandbox_current();
struct http_request *r = parser->data;
struct sandbox *s = parser->data;
struct http_request *r = &s->rqi;
assert(strncmp(s->mod->name, (at + 1), length - 1) == 0);
#endif
@ -47,7 +57,8 @@ http_on_url(http_parser* parser, const char *at, size_t length)
static inline int
http_on_header_field(http_parser* parser, const char *at, size_t length)
{
struct http_request *r = parser->data;
struct sandbox *s = parser->data;
struct http_request *r = &s->rqi;
if (r->last_was_value) r->nheaders ++;
assert(r->nheaders <= HTTP_HEADERS_MAX);
@ -62,7 +73,8 @@ http_on_header_field(http_parser* parser, const char *at, size_t length)
static inline int
http_on_header_value(http_parser* parser, const char *at, size_t length)
{
struct http_request *r = parser->data;
struct sandbox *s = parser->data;
struct http_request *r = &s->rqi;
r->last_was_value = 1;
assert(r->nheaders <= HTTP_HEADERS_MAX);
@ -77,22 +89,23 @@ static inline int
http_on_body(http_parser* parser, const char *at, size_t length)
{
#ifndef STANDALONE
struct http_request *r = parser->data;
struct sandbox *c = sandbox_current();
struct sandbox *s = parser->data;
struct http_request *r = &s->rqi;
assert(length <= c->mod->max_req_sz);
r->body = (char *)at;
r->bodylen = length;
assert(r->bodylen + length <= s->mod->max_req_sz);
if (!r->body) r->body = (char *)at;
else assert(r->body + r->bodylen == at);
r->bodylen += length;
#endif
return 0;
}
int
http_request_body_get(char **b)
http_request_body_get_sb(struct sandbox *s, char **b)
{
#ifndef STANDALONE
struct sandbox *s = sandbox_current();
struct http_request *r = &s->rqi;
*b = r->body;
@ -103,11 +116,10 @@ http_request_body_get(char **b)
}
int
http_response_header_set(char *key, int len)
http_response_header_set_sb(struct sandbox *c, char *key, int len)
{
#ifndef STANDALONE
// by now, req_resp_data should only be containing response!
struct sandbox *c = sandbox_current();
struct http_response *r = &c->rsi;
assert(r->nheaders < HTTP_HEADERS_MAX);
@ -119,13 +131,13 @@ http_response_header_set(char *key, int len)
return 0;
}
int http_response_body_set(char *body, int len)
int
http_response_body_set_sb(struct sandbox *c, char *body, int len)
{
#ifndef STANDALONE
struct sandbox *c = sandbox_current();
struct http_response *r = &c->rsi;
assert(len < c->mod->max_resp_sz);
assert(len <= c->mod->max_resp_sz);
r->body = body;
r->bodylen = len;
#endif
@ -133,10 +145,10 @@ int http_response_body_set(char *body, int len)
return 0;
}
int http_response_status_set(char *status, int len)
int
http_response_status_set_sb(struct sandbox *c, char *status, int len)
{
#ifndef STANDALONE
struct sandbox *c = sandbox_current();
struct http_response *r = &c->rsi;
r->status = status;
@ -146,11 +158,11 @@ int http_response_status_set(char *status, int len)
return 0;
}
int http_response_uv(void)
int
http_response_uv_sb(struct sandbox *c)
{
int nb = 0;
#ifndef STANDALONE
struct sandbox *c = sandbox_current();
struct http_response *r = &c->rsi;
@ -173,11 +185,10 @@ int http_response_uv(void)
}
int
http_request_parse(void)
http_request_parse_sb(struct sandbox *s, size_t l)
{
#ifndef STANDALONE
struct sandbox *s = sandbox_current();
http_parser_execute(&s->hp, &settings, s->req_resp_data, s->rr_data_len);
http_parser_execute(&s->hp, &settings, s->req_resp_data + s->rr_data_len, l);
#endif
return 0;
}

@ -100,8 +100,20 @@ i32
wasm_write(i32 fd, i32 buf_offset, i32 buf_size)
{
if (fd == 1 || fd == 2) {
#ifdef STANDALONE
char* buf = get_memory_ptr_void(buf_offset, buf_size);
return write(fd, buf, buf_size);
#else
char* buf = get_memory_ptr_void(buf_offset, buf_size);
struct sandbox *s = sandbox_current();
int l = s->mod->max_resp_sz - s->rr_data_len;
l = l > buf_size ? buf_size : l;
if (l == 0) return 0;
memcpy(s->req_resp_data + s->rr_data_len, buf, l);
s->rr_data_len += l;
return l;
#endif
}
int f = io_handle_fd(fd);
// TODO: read on other file types

@ -8,7 +8,7 @@
#include <sched.h>
#include <softint.h>
#include <uv.h>
#include <http.h>
#include <http_api.h>
struct deque_sandbox *glb_dq;
pthread_mutex_t glbq_mtx = PTHREAD_MUTEX_INITIALIZER;

@ -5,6 +5,7 @@
#include <pthread.h>
#include <signal.h>
#include <uv.h>
#include <http_api.h>
static inline struct sandbox *
sandbox_memory_map(struct module *m)
@ -45,6 +46,7 @@ sandbox_args_setup(i32 argc)
{
struct sandbox *curr = sandbox_current();
char *args = sandbox_args();
if (!args) return;
// whatever gregor has, to be able to pass args to a module!
curr->args_offset = sandbox_lmbound;
@ -71,44 +73,53 @@ sb_read_callback(uv_stream_t *s, ssize_t nr, const uv_buf_t *b)
{
struct sandbox *c = s->data;
if (nr > 0) c->rr_data_len += nr;
if (nr > 0) {
if (http_request_parse_sb(c, nr) != 0) return;
c->rr_data_len += nr;
struct http_request *rh = &c->rqi;
if (!rh->message_end) return;
}
uv_read_stop(s);
sandbox_wakeup(c);
}
static inline void
sb_write_callback(uv_write_t *w, int status)
sb_close_callback(uv_handle_t *s)
{
struct sandbox *c = w->data;
struct sandbox *c = s->data;
sandbox_wakeup(c);
}
static inline void
sb_alloc_callback(uv_handle_t *h, size_t suggested, uv_buf_t *buf)
sb_shutdown_callback(uv_shutdown_t *req, int status)
{
struct sandbox *c = h->data;
#ifndef STANDALONE
buf->base = (c->req_resp_data + c->rr_data_len);
buf->len = (c->mod->max_rr_sz - c->rr_data_len);
#endif
struct sandbox *c = req->data;
sandbox_wakeup(c);
}
static inline void
sb_close_callback(uv_handle_t *s)
sb_write_callback(uv_write_t *w, int status)
{
struct sandbox *c = s->data;
struct sandbox *c = w->data;
if (status < 0) {
c->cuvsr.data = c;
uv_shutdown(&c->cuvsr, (uv_stream_t *)&c->cuv, sb_shutdown_callback);
return;
}
sandbox_wakeup(c);
}
static inline void
sb_shutdown_callback(uv_shutdown_t *req, int status)
sb_alloc_callback(uv_handle_t *h, size_t suggested, uv_buf_t *buf)
{
struct sandbox *c = req->data;
struct sandbox *c = h->data;
sandbox_wakeup(c);
#ifndef STANDALONE
size_t l = (c->mod->max_rr_sz - c->rr_data_len);
buf->base = (c->req_resp_data + c->rr_data_len);
buf->len = l > suggested ? suggested : l;
#endif
}
static inline int
@ -121,16 +132,27 @@ sandbox_client_request_get(void)
#ifndef USE_UVIO
int r = 0;
r = recv(curr->csock, (curr->req_resp_data), curr->mod->max_req_sz, 0);
if (r < 0) {
if (r <= 0) {
perror("recv");
return r;
}
curr->rr_data_len = r;
while (r > 0) {
if (http_request_parse(r) != 0) return -1;
curr->rr_data_len += r;
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);
if (r < 0) {
perror("recv");
return r;
}
}
#else
int r = uv_read_start((uv_stream_t *)&curr->cuv, sb_alloc_callback, sb_read_callback);
sandbox_block();
if (curr->rr_data_len == 0) return 0;
#endif
if (http_request_parse() != 0) return -1;
return 1;
#else
@ -227,7 +249,7 @@ sandbox_entry(void)
#ifndef STANDALONE
http_parser_init(&curr->hp, HTTP_REQUEST);
curr->hp.data = &curr->rqi;
curr->hp.data = curr;
#ifdef USE_UVIO
int r = uv_tcp_init(runtime_uvio(), (uv_tcp_t *)&curr->cuv);
assert(r == 0);
@ -251,9 +273,6 @@ sandbox_entry(void)
#ifndef STANDALONE
#ifdef USE_UVIO
uv_shutdown_t sr = { .data = curr, };
r = uv_shutdown(&sr, (uv_stream_t *)&curr->cuv, sb_shutdown_callback);
sandbox_block();
uv_close((uv_handle_t *)&curr->cuv, sb_close_callback);
sandbox_block();
#else

@ -2,12 +2,15 @@
#include <stdio.h>
#include <string.h>
#define MAX_BUF (1024*1024) //1m
int
main(int argc, char **argv)
{
printf("hello\n");
// char d[16] = { 0 };
// int r = read(0, d, 15);
// printf("hello [%s]\n", d);
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
if (r <= 0) printf("%s\n", r == 0 ? "empty" : "error");
else write(1, d, MAX_BUF);
return 0;
}

@ -6,8 +6,8 @@
"argsize" : 1,
"http-req-headers" : [ ],
"http-req-content-type" : "text/plain",
"http-req-size": 102400,
"http-req-size": 1048576,
"http-resp-headers" : [ ],
"http-resp-size" : 10240,
"http-resp-size" : 1048776,
"http-resp-content-type" : "text/plain"
}

Loading…
Cancel
Save