예제 #1
0
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;
}
예제 #2
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);
	}

}
예제 #3
0
파일: scgi.c 프로젝트: bennypk/uwsgi
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;
}
예제 #4
0
/** 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);
    }
  }
}