# HG changeset patch # User Olaf Wintermann # Date 1445109454 -7200 # Node ID 7fbcdbad0baaae03a77a45f1b383618609669834 # Parent e9bb8449df02106f104034d004f200c7632e997a added support for absolute URIs and improved keep alive diff -r e9bb8449df02 -r 7fbcdbad0baa make/clang.mk --- a/make/clang.mk Sat Oct 17 18:07:04 2015 +0200 +++ b/make/clang.mk Sat Oct 17 21:17:34 2015 +0200 @@ -30,7 +30,7 @@ LDFLAGS = -Wl,-R,'$$ORIGIN/../lib' CC = clang -CXX = clang +CXX = clang++ LD = clang SHLIB_CFLAGS = -fPIC diff -r e9bb8449df02 -r 7fbcdbad0baa src/server/config/acl.c --- a/src/server/config/acl.c Sat Oct 17 18:07:04 2015 +0200 +++ b/src/server/config/acl.c Sat Oct 17 21:17:34 2015 +0200 @@ -110,7 +110,7 @@ ACLConfig *cur = f->cur; UcxAllocator *mp = f->parser.mp; - size_t tkn = 0; + ssize_t tkn = 0; sstr_t *tk = sstrsplit(line, sstr(":"), &tkn); if(!tk || tkn < 3) { fprintf(stderr, "parse_ace: to few tokens\n"); @@ -161,7 +161,7 @@ } s = tk[n]; - size_t maskn = 0; + ssize_t maskn = 0; sstr_t *accessmask = sstrsplit(s, sstr(","), &maskn); for(int i=0;iparser.mp; - size_t tkn = 0; + ssize_t tkn = 0; sstr_t *tk = sstrsplit(line, sstrn(";", 1), &tkn); if(tkn < 2) { @@ -115,7 +115,7 @@ // get groups if(tkn == 3) { sstr_t groups_str = sstrtrim(tk[2]); - size_t ngroups = 0; + ssize_t ngroups = 0; sstr_t *groups = sstrsplit(groups_str, sstrn(",", 1), &ngroups); entry->groups = mp->calloc(mp->pool, ngroups, sizeof(sstr_t)); entry->numgroups = ngroups; diff -r e9bb8449df02 -r 7fbcdbad0baa src/server/config/mimeconf.c --- a/src/server/config/mimeconf.c Sat Oct 17 18:07:04 2015 +0200 +++ b/src/server/config/mimeconf.c Sat Oct 17 21:17:34 2015 +0200 @@ -83,7 +83,7 @@ } else if(!sstrcmp(param->name, sstr("exts"))) { // comma-separated file extensions - size_t nx = 0; + ssize_t nx = 0; sstr_t *exts = sstrsplit(param->value, sstrn(",", 1), &nx); for(int i=0;istate = 0; parser->start_line.ptr = (char*)request->netbuf->inbuf; parser->start_line.length = 0; + + parser->offset = 0; return parser; } @@ -75,16 +77,23 @@ while(buf->pos < buf->cursize) { unsigned char c = buf->inbuf[buf->pos]; if(c == '\n') { - if(buf->pos <= 1) { + size_t lnlen = buf->pos - parser->offset + 1; + if(lnlen <= 2) { + if(lnlen == 1 || buf->inbuf[buf->pos-1] == '\r') { + // skip empty line + buf->pos++; + parser->offset = buf->pos; + return 1; + } // insufficient chars for request, return error return 2; } if(buf->inbuf[buf->pos - 1] == '\r') { - parser->start_line.length = buf->pos; + parser->start_line.length = lnlen - 1; } else { - parser->start_line.length = buf->pos + 1; + parser->start_line.length = lnlen; } - parser->start_line.ptr = (char*)buf->inbuf; + parser->start_line.ptr = (char*)buf->inbuf + parser->offset; buf->pos++; return 0; } @@ -98,7 +107,9 @@ parser->offset = buf->pos; // line offset parser->name.ptr = NULL; + parser->name.length = 0; parser->value.ptr = NULL; + parser->value.length = 0; while(1) { if(buf->pos >= buf->cursize) { return 1; @@ -109,7 +120,7 @@ parser->wl = 0; if(c == ':' && parser->value.ptr == NULL) { parser->name.ptr = (char*)buf->inbuf + parser->offset; - buf->inbuf[buf->pos-1] = 0; + parser->name.length = buf->pos - parser->offset - 1; } else if(parser->name.ptr != NULL && parser->value.ptr == NULL) { parser->value.ptr = (char*)buf->inbuf + buf->pos - 1; } @@ -121,21 +132,24 @@ } else { parser->offset = buf->pos; if(parser->value.ptr != NULL) { - buf->inbuf[buf->pos-1] = 0; + parser->value.length = (buf->inbuf + buf->pos - 1) + - (unsigned char*)parser->value.ptr; if(buf->inbuf[buf->pos-2] == '\r') { - buf->inbuf[buf->pos-2] = 0; + parser->value.length--; } // add header header_add( parser->request->headers, - parser->name.ptr, - parser->value.ptr); + parser->name, + parser->value); } else { // error: no value return 2; } parser->name.ptr = NULL; parser->value.ptr = NULL; + parser->name.length = 0; + parser->value.length = 0; parser->wl = 1; } } diff -r e9bb8449df02 -r 7fbcdbad0baa src/server/daemon/httprequest.c --- a/src/server/daemon/httprequest.c Sat Oct 17 18:07:04 2015 +0200 +++ b/src/server/daemon/httprequest.c Sat Oct 17 21:17:34 2015 +0200 @@ -56,6 +56,33 @@ req->headers = hd; } +void http_request_cleanup(HTTPRequest *req) { + // TODO: implement +} + +sstr_t http_request_get_abspath(HTTPRequest *req) { + sstr_t uri = req->uri; + + int i = 0; + if(uri.ptr[0] == '/') { + return uri; + } else if(sstrprefix(uri, S("http://"))) { + i = 7; + } else if(sstrprefix(uri, S("https://"))) { + i = 8; + } else if(!sstrcmp(uri, S("*"))) { + return uri; + } + + for(;ihttpv.ptr, request->httpv.length, rq->rq.reqpb); - // TODO: protocol num + + if(!sstrcmp(request->httpv, S("HTTP/1.1"))) { + rq->rq.protv_num = PROTOCOL_VERSION_HTTP11; + } else if(!sstrcmp(request->httpv, S("HTTP/1.0"))) { + rq->rq.protv_num = PROTOCOL_VERSION_HTTP10; + } else { + // TODO: invalid protocol version - abort + } /* * get absolute path and query of the request uri */ // TODO: check for '#' - sstr_t absPath = request->uri; + sstr_t absPath = http_request_get_abspath(request); + if(!absPath.ptr) { + // TODO: error msg + return 1; + } else if(absPath.ptr[0] == '*') { + // TODO: implement global OPTIONS + return 1; + } + sstr_t query; query.length = 0; @@ -200,24 +242,38 @@ i = 0; hlen = ha->len; } + + Header header = ha->headers[i]; - if(ha->headers[i].name[0] < 90) { - ha->headers[i].name[0] += 32; + if(header.name.ptr[0] < 90) { + header.name.ptr[0] += 32; } // change to lower case - char *header_name = ha->headers[i].name; - for(int i=0;header_name[i]!=0;i++) { - if(header_name[i] > 64 && header_name[i] < 97) { - header_name[i] += 32; + for(int i=0;i 64 && header.name.ptr[i] < 97) { + header.name.ptr[i] += 32; } } - - pblock_nvinsert( - ha->headers[i].name, - ha->headers[i].value, + + pblock_nvlinsert( + header.name.ptr, + header.name.length, + header.value.ptr, + header.value.length, rq->rq.headers); } + + // parse connection header + rq->rq.rq_attr.keep_alive = (rq->rq.protv_num >= PROTOCOL_VERSION_HTTP11); + char *conn_str = pblock_findkeyval(pb_key_connection, rq->rq.headers); + if(conn_str) { + if(!strcasecmp(conn_str, "keep-alive")) { + rq->rq.rq_attr.keep_alive = 1; + } else if(!strcasecmp(conn_str, "close")) { + rq->rq.rq_attr.keep_alive = 0; + } + } // check for request body and prepare input buffer char *ctlen_str = pblock_findkeyval(pb_key_content_length, rq->rq.headers); @@ -284,7 +340,7 @@ -void header_add(HeaderArray *hd, char *name, char *value) { +void header_add(HeaderArray *hd, sstr_t name, sstr_t value) { while(hd->len >= hd->alloc) { if(hd->next == NULL) { HeaderArray *block = malloc(sizeof(HeaderArray)); diff -r e9bb8449df02 -r 7fbcdbad0baa src/server/daemon/httprequest.h --- a/src/server/daemon/httprequest.h Sat Oct 17 18:07:04 2015 +0200 +++ b/src/server/daemon/httprequest.h Sat Oct 17 21:17:34 2015 +0200 @@ -56,8 +56,8 @@ }; struct _header { - char *name; - char *value; + sstr_t name; + sstr_t value; }; struct _header_array { @@ -70,6 +70,8 @@ void http_request_init(HTTPRequest *req); void http_request_cleanup(HTTPRequest *req); +sstr_t http_request_get_abspath(HTTPRequest *req); + /* * starts request processing after reading the request header * @@ -80,7 +82,7 @@ -void header_add(HeaderArray *hd, char *name, char *value); +void header_add(HeaderArray *hd, sstr_t name, sstr_t value); void header_array_free(HeaderArray *hd); int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq); diff -r e9bb8449df02 -r 7fbcdbad0baa src/server/daemon/ldap_auth.c --- a/src/server/daemon/ldap_auth.c Sat Oct 17 18:07:04 2015 +0200 +++ b/src/server/daemon/ldap_auth.c Sat Oct 17 21:17:34 2015 +0200 @@ -249,7 +249,7 @@ values[i]->bv_len); wsgroup->members[i].name = sstrdup(member).ptr; // TODO: uid? - printf("added member: %.*s\n", member.length, member.ptr); + printf("added member: %.*s\n", (int)member.length, member.ptr); } } } diff -r e9bb8449df02 -r 7fbcdbad0baa src/server/daemon/protocol.c --- a/src/server/daemon/protocol.c Sat Oct 17 18:07:04 2015 +0200 +++ b/src/server/daemon/protocol.c Sat Oct 17 21:17:34 2015 +0200 @@ -342,15 +342,14 @@ add_http_response_header(out, rq); // add connection header - char *conn_str = pblock_findkeyval(pb_key_connection, rq->headers); - if(conn_str && !strcasecmp(conn_str, "keep-alive")) { + if(rq->rq_attr.keep_alive) { sbuf_write(out, "Connection: keep-alive\r\n", 24); pblock_kvinsert(pb_key_connection, "keep-alive", 10, rq->srvhdrs); - rq->rq_attr.keep_alive = 1; } else { sbuf_write(out, "Connection: close\r\n", 19); pblock_kvinsert(pb_key_connection, "close", 5, rq->srvhdrs); } + // response header end sbuf_write(out, "\r\n", 2);