Пример #1
0
static void
ev_io_on_read(struct ev_loop* mainloop, ev_io* watcher, const int events)
{
  static char read_buf[READ_BUFFER_SIZE];

  Request* request = REQUEST_FROM_WATCHER(watcher);

  ssize_t read_bytes = read(
    request->client_fd,
    read_buf,
    READ_BUFFER_SIZE
  );

  GIL_LOCK(0);

  if(read_bytes <= 0) {
    if(errno != EAGAIN && errno != EWOULDBLOCK) {
      if(read_bytes == 0)
        DBG_REQ(request, "Client disconnected");
      else
        DBG_REQ(request, "Hit errno %d while read()ing", errno);
      close(request->client_fd);
      Request_free(request);
      ev_io_stop(mainloop, &request->ev_watcher);
    }
    goto out;
  }

  Request_parse(request, read_buf, (size_t)read_bytes);

  if(request->state.error_code) {
    DBG_REQ(request, "Parse error");
    request->current_chunk = PyString_FromString(
      http_error_messages[request->state.error_code]);
    assert(request->iterator == NULL);
  }
  else if(request->state.parse_finished) {
    if(!wsgi_call_application(request)) {
      assert(PyErr_Occurred());
      PyErr_Print();
      assert(!request->state.chunked_response);
      Py_XCLEAR(request->iterator);
      request->current_chunk = PyString_FromString(
        http_error_messages[HTTP_SERVER_ERROR]);
    }
  } else {
    /* Wait for more data */
    goto out;
  }

  ev_io_stop(mainloop, &request->ev_watcher);
  ev_io_init(&request->ev_watcher, &ev_io_on_write,
             request->client_fd, EV_WRITE);
  ev_io_start(mainloop, &request->ev_watcher);

out:
  GIL_UNLOCK(0);
  return;
}
Пример #2
0
static void
close_connection(struct ev_loop *mainloop, Request* request)
{
  DBG_REQ(request, "Closing socket");
  ev_io_stop(mainloop, &request->ev_watcher);
  close(request->client_fd);
  Request_free(request);
}
Пример #3
0
static void on_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
	Request* request;
	dprint("go on_read");
	request =(Request*)handle->data;
	GIL_LOCK(0);
	if (nread <= 0) {
		//@@@@@@@@@@@@@@@uv_err_t err = uv_last_error(loop);
		//@@@@@@@@@@@@@@@UVERR(err, "uv read error");
		if(nread == 0)
		        dprint("Client disconnected");
		uv_close((uv_handle_t*)handle, on_close);
		Request_free(request);
		if (buf.base) {
		  free(buf.base);
		}
		goto out;
	}
    Request_parse(request, buf.base, nread);	//处理Request解析
	free(buf.base);
    if(request->state.error_code) {
      DBG_REQ(request, "Parse error");
      request->current_chunk = PyString_FromString(http_error_messages[request->state.error_code]);//处理有错误的信息返回
	  assert(request->iterator == NULL);
	  //@@@@@@@@@ uv_close((uv_handle_t*) &request->ev_watcher, on_close);//解析有错误的请求直接关闭客户端连接
	  //@@@@@@@@@@ Request_free(request);
	  //@@@@@@@@@ goto out;
    }
    else if(request->state.parse_finished) {	// 解析好后
	  dprint("执行wsgi程序 >>>");
      if(!wsgi_call_application(request)) {	// 执行wsgi
	    dprint("wsgi执行包含错误");
        assert(PyErr_Occurred());
        PyErr_Print();	//打印python错误的跟踪堆栈信息
        assert(!request->state.chunked_response);
        Py_XCLEAR(request->iterator);
        request->current_chunk = PyString_FromString(	//返回错误信息给客户端
          http_error_messages[HTTP_SERVER_ERROR]);
      }
    } else {
      /* Wait for more data */
      goto out;
    }
    dprint("开始客户端数据返回 >>>");
    while(request->current_chunk){	//客户端返回循环
	  io_write(request);
    }

	out:
	  GIL_UNLOCK(0);
	  return;
}
Пример #4
0
static void
on_request(Connection* conn, Request* request)
{
	UNUSED(conn);
	CXLOG(conn, "ON REQUEST");

	/* restart the connection timeout */
	conn->f_timer_start(conn, CONNECTION_TIMEOUT_MILLIS);

	StringBuffer* request_buffer = (StringBuffer*)Request_get_data(request);
	XFLOG("request >>>>\n%s\n", StringBuffer_value(request_buffer));
	Request_free(request);
	conn->f_send(conn, Response_new(request_buffer), NULL);
}
Пример #5
0
static void
ev_io_on_read(struct ev_loop* mainloop, ev_io* watcher, const int events)
{
    char read_buf[READ_BUFFER_SIZE];
    Request* request = ADDR_FROM_MEMBER(watcher, Request, ev_watcher);
    ssize_t read_bytes = read(request->client_fd, read_buf, READ_BUFFER_SIZE);

    DBG_REQ(request, "read %zd bytes", read_bytes);

    GIL_LOCK(0);

    if(read_bytes == -1) {
        if(errno != EAGAIN && errno != EWOULDBLOCK) {
            close(request->client_fd);
            Request_free(request);
            ev_io_stop(mainloop, &request->ev_watcher);
        }
        goto out;
    }

    Request_parse(request, read_buf, read_bytes);

    if(request->state.error) {
        DBG_REQ(request, "Parse error");
        set_error(request, request->state.error_code);
    }
    else if(request->state.parse_finished) {
        DBG_REQ(request, "Parse done");
        if(!wsgi_call_application(request)) {
            assert(PyErr_Occurred());
            PyErr_Print();
            set_error(request, HTTP_SERVER_ERROR);
        }
    } else {
        DBG_REQ(request, "Waiting for more data");
        goto out;
    }

    ev_io_stop(mainloop, &request->ev_watcher);
    ev_io_init(&request->ev_watcher, &ev_io_on_write,
               request->client_fd, EV_WRITE);
    ev_io_start(mainloop, &request->ev_watcher);

out:
    GIL_UNLOCK(0);
    return;
}
Пример #6
0
static void
ev_io_on_write(struct ev_loop* mainloop, ev_io* watcher, const int events)
{
    GIL_LOCK(0);

    Request* request = ADDR_FROM_MEMBER(watcher, Request, ev_watcher);
    assert(request->current_chunk);

    if(send_chunk(request))
        goto notfinished;

    if(request->iterable) {
        PyObject* next_chunk;
        DBG_REQ(request, "Getting next iterable chunk.");
        next_chunk = wsgi_iterable_get_next_chunk(request);
        if(next_chunk == NULL) {
            if(PyErr_Occurred()) {
                /* Internal server error. */
                PyErr_Print();
                set_error(request, HTTP_SERVER_ERROR);
                goto notfinished;
            }
            DBG_REQ(request, "Iterable exhausted");
            goto bye;
        }
        request->current_chunk = next_chunk;
        assert(request->current_chunk_p == 0);
        goto notfinished;
    }

bye:
    DBG_REQ(request, "Done");

    /* Everything done, bye client! */
    ev_io_stop(mainloop, &request->ev_watcher);
    close(request->client_fd);
    Request_free(request);

notfinished:
    GIL_UNLOCK(0);
}
Пример #7
0
/* XXX too many gotos */
static void
ev_io_on_write(struct ev_loop* mainloop, ev_io* watcher, const int events)
{
  Request* request = REQUEST_FROM_WATCHER(watcher);

  GIL_LOCK(0);

  if(request->state.use_sendfile) {
    /* sendfile */
    if(request->current_chunk) {
      /* current_chunk contains the HTTP headers */
      if(send_chunk(request))
        goto out;
      assert(!request->current_chunk_p);
      /* abuse current_chunk_p to store the file fd */
      request->current_chunk_p = PyObject_AsFileDescriptor(request->iterable);
      goto out;
    }
    if(do_sendfile(request))
      goto out;
  } else {
    /* iterable */
    if(send_chunk(request))
      goto out;

    if(request->iterator) {
      PyObject* next_chunk;
      next_chunk = wsgi_iterable_get_next_chunk(request);
      if(next_chunk) {
        if(request->state.chunked_response) {
          request->current_chunk = wrap_http_chunk_cruft_around(next_chunk);
          Py_DECREF(next_chunk);
        } else {
          request->current_chunk = next_chunk;
        }
        assert(request->current_chunk_p == 0);
        goto out;
      } else {
        if(PyErr_Occurred()) {
          PyErr_Print();
          /* We can't do anything graceful here because at least one
           * chunk is already sent... just close the connection */
          DBG_REQ(request, "Exception in iterator, can not recover");
          ev_io_stop(mainloop, &request->ev_watcher);
          close(request->client_fd);
          Request_free(request);
          goto out;
        }
        Py_CLEAR(request->iterator);
      }
    }

    if(request->state.chunked_response) {
      /* We have to send a terminating empty chunk + \r\n */
      request->current_chunk = PyString_FromString("0\r\n\r\n");
      assert(request->current_chunk_p == 0);
      request->state.chunked_response = false;
      goto out;
    }
  }

  ev_io_stop(mainloop, &request->ev_watcher);
  if(request->state.keep_alive) {
    DBG_REQ(request, "done, keep-alive");
    Request_clean(request);
    Request_reset(request);
    ev_io_init(&request->ev_watcher, &ev_io_on_read,
               request->client_fd, EV_READ);
    ev_io_start(mainloop, &request->ev_watcher);
  } else {
    DBG_REQ(request, "done, close");
    close(request->client_fd);
    Request_free(request);
  }

out:
  GIL_UNLOCK(0);
}
Пример #8
0
static void io_write(Request* request)
{
  //GIL_LOCK(0);

  if(request->state.use_sendfile) {
	dprint("发送文件给客户端");
    /* sendfile */
    if(request->current_chunk && send_chunk(request))
      goto out;
    /* abuse current_chunk_p to store the file fd */
    request->current_chunk_p = PyObject_AsFileDescriptor(request->iterable);
    if(do_sendfile(request))
      goto out;
  } else {
    dprint("发送字符");
    /* iterable */
	if(send_chunk(request)){
	  dprint("一次发送即完成");
	  //uv_close((uv_handle_t*) &request->ev_watcher, _http_uv__on_close__cb);
      goto out;
	}

    if(request->iterator) {
      PyObject* next_chunk;
	  dprint("request迭代");
      next_chunk = wsgi_iterable_get_next_chunk(request);
      if(next_chunk) {
		dprint("下一块chunk发送");
        if(request->state.chunked_response) {
          request->current_chunk = wrap_http_chunk_cruft_around(next_chunk);
          Py_DECREF(next_chunk);
        } else {
          request->current_chunk = next_chunk;
        }
        assert(request->current_chunk_p == 0);
		//io_write(request);
        goto out;
      } else {
        if(PyErr_Occurred()) {
		  uv_err_t err;
		  dprint("迭代出错");
          PyErr_Print();
          DBG_REQ(request, "Exception in iterator, can not recover");
		  uv_close((uv_handle_t*) request->ev_watcher, on_close);
		  Request_free(request);
		  err = uv_last_error(loop);
		  UVERR(err, "uv_write error on next chunk");
		  ASSERT(0);
          goto out;
        }
		dprint("没有下一块chunk");
        Py_CLEAR(request->iterator);
      }
    }

    if(request->state.chunked_response) {
      dprint("如果是chunked_response 发送收尾数据,并置空chunked_response");
      /* We have to send a terminating empty chunk + \r\n */
      request->current_chunk = PyString_FromString("0\r\n\r\n");
      assert(request->current_chunk_p == 0);
	  //io_write(request);
      request->state.chunked_response = false;
      goto out;
    }
  }
  dprint("响应完成");
  if(request->state.keep_alive) {
    DBG_REQ(request, "done, keep-alive");
    Request_clean(request);
    Request_reset(request);
  } else {
	dprint("done not keep alive");
	uv_close((uv_handle_t*) request->ev_watcher, on_close);
	Request_free(request);
  }

out:
  dprint("本次字符发送结束");
  //GIL_UNLOCK(0);
  return;
}
Пример #9
0
// Public
void Request_cb(struct evhttp_request *req, void * data)
{
	Request_T R = Request_new(req, data);
	Request_handle(R);
	Request_free(&R);
}