void on_read (uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) { size_t parsed; client_t* client = (client_t*) tcp->data; if (nread >= 0) { parsed = http_parser_execute ( &client->parser, &parser_settings, buf.base, nread); if (!parsed) { LOGF ("parse error %u %u",parsed,nread); uv_close ( (uv_handle_t*) &client->handle, on_close); } } else { uv_err_t err = uv_last_error (uv_loop); if (err.code != UV_EOF) { UVERR (err, "read"); } } free (buf.base); }
static void after_write(uv_write_t* req, int status) { dprint("after_write"); if (status) { uv_err_t err = uv_last_error(loop); UVERR(err,"uv_write error"); //ASSERT(0); } free(req); //uv_close((uv_handle_t*)req->handle, on_close); /* Free the read/write buffer and the request */ //@@@@@@@@@@@@@free(req); }
static void on_resolve_resource(sws_resource_info_t* info) { int r; sws_handle_req_t *handle_req = (sws_handle_req_t*) info->data; debug("resolved %s", sws_resource_info_str(info)); if (info->result) { UVERR(info->result, "resolve resource"); // TODO: return 404 sws_resolve_resource_init(loop, &handle_req->resource_info); sws_resolve_resource_start(&handle_req->resource_info, "/404.html", on_resolve_resource); } else { r = sws_pipe_file(loop, (uv_stream_t*)&handle_req->handle, info->full_path, info->size, on_pipe_file_complete); CHECK(r, "pipe file"); } }
static void on_req_read(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf) { size_t parsed; sws_handle_req_t *handle_req = (sws_handle_req_t*) tcp; if (nread == UV_EOF) { uv_close((uv_handle_t*) tcp, NULL); debug("closed req tcp connection due to unexpected EOF"); } else if (nread > 0) { log_info("[ %3d ] req (len %ld)", handle_req->id, nread); parsed = sws_req_parser_execute(&handle_req->parse_req, buf->base, nread); if (parsed < nread) { log_err("parsing http req"); uv_close((uv_handle_t*) &handle_req->handle, on_res_end); } } else { UVERR((int) nread, "reading req req"); } if (buf->base) free(buf->base); }
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; }