int SCGIhandle::accept(void) { scgi_socket_t client_sock; if (scgi_accept(server_sock, &client_sock, NULL) == SCGI_SUCCESS) { if (scgi_parse(client_sock, &handle) == SCGI_SUCCESS) { return 1; } closesocket(client_sock); } return 0; }
static void callback(scgi_socket_t server_sock, scgi_socket_t *client_sock, struct sockaddr_in *addr) { scgi_handle_t handle = { 0 }; if (scgi_parse(*client_sock, &handle) == SCGI_SUCCESS) { scgi_param_t *pp; *client_sock = SCGI_SOCK_INVALID; for(pp = handle.params; pp; pp = pp->next) { printf("HEADER: [%s] VALUE: [%s]\n", pp->name, pp->value); } if (handle.body) { printf("\n\nBODY:\n%s\n\n", handle.body); } scgi_disconnect(&handle); } }
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; }
/** Reads the response from worker, deserialize it, render it to the Request. */ static void wr_resp_len_read_cb(struct ev_loop *loop, struct ev_io *w, int revents) { LOG_FUNCTION wr_req_t* req = (wr_req_t*) w->data; wr_wkr_t *worker = req->wkr; ssize_t read; LOG_DEBUG(DEBUG,"Request %d",req->id); if(!(revents & EV_READ)) return; read = recv(w->fd, req->resp_buf + req->bytes_received, WR_RESP_BUF_SIZE - req->bytes_received, 0); if(read <= 0) { ev_io_stop(loop,w); LOG_ERROR(WARN,"Error reading response:%s",strerror(errno)); worker->state += (WR_WKR_ERROR + WR_WKR_HANG); wr_ctl_free(worker->ctl); return; } req->bytes_received =+ read; //worker responding LOG_DEBUG(DEBUG,"Idle watcher reset for worker %d", worker->id); LOG_DEBUG(DEBUG,"bytes read = %d", req->bytes_received); scgi_t* scgi = scgi_parse(req->resp_buf, req->bytes_received); if(scgi) { ev_io_stop(loop,w); const char *value = scgi_header_value_get(scgi, SCGI_CONTENT_LENGTH); // Set response length if(value) req->resp_buf_len = atoi(value); else req->resp_buf_len = 0; // Set rsponse code value = scgi_header_value_get(scgi, RESP_CODE); if(value) req->resp_code = atoi(value); else req->resp_code = 0; // Set content length value = scgi_header_value_get(scgi, RESP_CONTENT_LENGTH); if(value) req->resp_body_len = atoi(value); else req->resp_body_len = 0; LOG_DEBUG(DEBUG,"resp_code = %d, content len = %d, resp len = %d", req->resp_code, req->resp_body_len, req->resp_buf_len); // Response length should be greater than 0 if(req->resp_buf_len == 0) { //TODO: Render 500 Internal Error, close Request, allocate worker to next Request LOG_ERROR(WARN,"Got response len 0"); ev_io_stop(loop,w); worker->state += (WR_WKR_ERROR + WR_WKR_HANG); wr_ctl_free(worker->ctl); return; } if(!req->conn_err && req->app && req->app->svr->conf->server->flag & WR_SVR_ACCESS_LOG) { wr_access_log(req); } scgi_free(req->scgi); req->scgi = NULL; req->bytes_received = scgi->body_length; LOG_DEBUG(DEBUG,"wr_resp_len_read_cb() bytes read = %d", req->bytes_received); if(req->bytes_received > 0 && !req->conn_err) { wr_conn_resp_body_add(req->conn, scgi->body, scgi->body_length); } scgi_free(scgi); // Check for response length if(req->resp_buf_len == req->bytes_received) { LOG_DEBUG(DEBUG,"Idle watcher stopped for worker %d", worker->id); // worker is done with current Request worker->req = NULL; req->using_wkr = FALSE; worker->state &= (~224); ev_timer_stop(worker->loop,&worker->t_wait); // Close Request once complete response read wr_wkr_release(req); } else { LOG_DEBUG(DEBUG,"wr_resp_len_read_cb() Request %d, read %d/%d", req->id, req->bytes_received, req->resp_buf_len); ev_io_init(w,wr_resp_read_cb, w->fd,EV_READ); ev_io_start(loop,w); wr_wait_watcher_start(worker); } } }