/* async SCGI protocol parser */ #include extern struct uwsgi_server uwsgi; static int scgi_parse(struct wsgi_request *wsgi_req) { char *buf = wsgi_req->proto_parser_buf; size_t len = wsgi_req->proto_parser_pos; size_t i; size_t scgi_len = 0; for(i=0;i len) { return 0; } i++; size_t vars = i; char *key = buf + i; size_t keylen = 0; char *value = NULL; size_t vallen = 0; for(i=vars;i 0 && value == NULL) { value = buf + i; } if (buf[i] == 0) { if (value) { vallen = (buf+i) - value; uint16_t pktsize = proto_base_add_uwsgi_var(wsgi_req, key, keylen, value, vallen); if (pktsize == 0) return -1; wsgi_req->len += pktsize; key = NULL; value = NULL; keylen = 0; vallen = 0; } else { keylen = (buf+i) - key; value = NULL; } } } if (buf[i] == ',') { if (len > i+1) { wsgi_req->proto_parser_remains = len-(i+1); wsgi_req->proto_parser_remains_buf = buf + i + 1; } return 1; } return -1; } int uwsgi_proto_scgi_parser(struct wsgi_request *wsgi_req) { // first round ? (wsgi_req->proto_parser_buf is freed at the end of the request) if (!wsgi_req->proto_parser_buf) { wsgi_req->proto_parser_buf = uwsgi_malloc(uwsgi.buffer_size); } if (uwsgi.buffer_size - wsgi_req->proto_parser_pos == 0) { uwsgi_log("invalid SCGI request size (max %u)...skip\n", uwsgi.buffer_size); return -1; } char *ptr = wsgi_req->proto_parser_buf; ssize_t len = read(wsgi_req->fd, ptr + wsgi_req->proto_parser_pos, uwsgi.buffer_size - wsgi_req->proto_parser_pos); if (len > 0) { wsgi_req->proto_parser_pos += len; int ret = scgi_parse(wsgi_req); if (ret > 0) { wsgi_req->uh->modifier1 = uwsgi.scgi_modifier1; wsgi_req->uh->modifier2 = uwsgi.scgi_modifier2; return UWSGI_OK; } if (ret == 0) return UWSGI_AGAIN; return -1; } if (len < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { return UWSGI_AGAIN; } uwsgi_error("uwsgi_proto_scgi_parser()"); return -1; } // 0 len if (wsgi_req->proto_parser_pos > 0) { uwsgi_error("uwsgi_proto_scgi_parser()"); } return -1; } void uwsgi_proto_scgi_setup(struct uwsgi_socket *uwsgi_sock) { uwsgi_sock->proto = uwsgi_proto_scgi_parser; uwsgi_sock->proto_accept = uwsgi_proto_base_accept; uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_cgi_prepare_headers; uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header; uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers; uwsgi_sock->proto_read_body = uwsgi_proto_base_read_body; uwsgi_sock->proto_write = uwsgi_proto_base_write; uwsgi_sock->proto_writev = uwsgi_proto_base_writev; uwsgi_sock->proto_write_headers = uwsgi_proto_base_write; uwsgi_sock->proto_sendfile = uwsgi_proto_base_sendfile; uwsgi_sock->proto_close = uwsgi_proto_base_close; } void uwsgi_proto_scgi_nph_setup(struct uwsgi_socket *uwsgi_sock) { uwsgi_sock->proto = uwsgi_proto_scgi_parser; uwsgi_sock->proto_accept = uwsgi_proto_base_accept; uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_prepare_headers; uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header; uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers; uwsgi_sock->proto_read_body = uwsgi_proto_base_read_body; uwsgi_sock->proto_write = uwsgi_proto_base_write; uwsgi_sock->proto_writev = uwsgi_proto_base_writev; uwsgi_sock->proto_write_headers = uwsgi_proto_base_write; uwsgi_sock->proto_sendfile = uwsgi_proto_base_sendfile; uwsgi_sock->proto_close = uwsgi_proto_base_close; }