inline void switch_wsgi_app(picoev_loop* loop, int fd, PyObject *obj) { ClientObject *pyclient = (ClientObject *)obj; //clear event picoev_del(loop, fd); // resume resume_wsgi_app(pyclient, loop); pyclient->resumed = 0; }
static inline void resume_wsgi_app(ClientObject *pyclient, picoev_loop* loop) { int ret; client_t *client = pyclient->client; ret = process_resume_wsgi_app(pyclient); switch(ret){ case -1: //Internal Server Error client->bad_request_code = 500; send_error_page(client); close_conn(client, loop); return; case 0: // suspend return; default: break; } if(client->response_closed){ //closed close_conn(client, loop); return; } ret = response_start(client); switch(ret){ case -1: // Internal Server Error client->bad_request_code = 500; send_error_page(client); close_conn(client, loop); return; case 0: // continue // set callback #ifdef DEBUG printf("set write callback %d \n", ret); #endif //clear event picoev_del(loop, client->fd); picoev_add(loop, client->fd, PICOEV_WRITE, 0, w_callback, (void *)client); return; default: // send OK close_conn(client, loop); } }
static inline void close_conn(client_t *cli, picoev_loop* loop) { client_t *new_client; if(!cli->response_closed){ close_response(cli); } picoev_del(loop, cli->fd); clean_cli(cli); #ifdef DEBUG printf("start close client:%p fd:%d status_code %d \n", cli, cli->fd, cli->status_code); printf("picoev_del client:%p fd:%d \n", cli, cli->fd); printf("remain http pipeline size :%d \n", cli->request_queue->size); #endif if(cli->request_queue->size > 0){ if(check_status_code(cli) > 0){ //process pipeline prepare_call_wsgi(cli); call_wsgi_app(cli, loop); } return ; } if(cli->http != NULL){ PyMem_Free(cli->http); } free_request_queue(cli->request_queue); if(!cli->keep_alive){ close(cli->fd); #ifdef DEBUG printf("close client:%p fd:%d status_code %d \n", cli, cli->fd, cli->status_code); #endif }else{ disable_cork(cli); new_client = new_client_t(cli->fd, cli->remote_addr, cli->remote_port); new_client->keep_alive = 1; init_parser(new_client, server_name, server_port); picoev_add(main_loop, new_client->fd, PICOEV_READ, keep_alive_timeout, r_callback, (void *)new_client); } //PyMem_Free(cli); dealloc_client(cli); #ifdef DEBUG printf("********************\n\n"); #endif }
static void read_cb(picoev_loop* loop, int fd, int revents, void* cb_arg) { char buf[16384]; const char* method, * path; size_t method_len, path_len, num_headers; int minor_version, r; struct phr_header headers[128]; /* read request */ assert((revents & PICOEV_READ) != 0); r = read(fd, buf, sizeof(buf)); if (r == 0) { goto CLOSE; } else if (r == -1) { if (errno == EINTR || errno == EAGAIN) { return; } goto CLOSE; } /* parse request, should arrive in one packat :-p */ num_headers = sizeof(headers) / sizeof(headers[0]); r = phr_parse_request(buf, r, &method, &method_len, &path, &path_len, &minor_version, headers, &num_headers, 0); assert(r > 0); #define RES "HTTP\1.0 200 OK\r\n" \ "Connection: keep-alive\r\n" \ "Content-Length: 13\r\n" \ "Content-Type: text/plain\r\n" \ "\r\n" \ "hello world!\n" r = write(fd, RES, sizeof(RES) - 1); assert(r == sizeof(RES) - 1); #undef RES return; CLOSE: picoev_del(loop, fd); close(fd); }
static void call_rack_app(client_t *client, picoev_loop* loop) { int ret; if(!process_rack_app(client)){ //Internal Server Error client->bad_request_code = 500; send_error_page(client); close_conn(client, loop); return; } ret = response_start(client); /* printf("response_start done: %d\n", ret); */ switch(ret){ case -1: // Internal Server Error client->bad_request_code = 500; send_error_page(client); close_conn(client, loop); return; case 0: // continue // set callback #ifdef DEBUG printf("set write callback %d \n", ret); #endif //clear event picoev_del(loop, client->fd); picoev_add(loop, client->fd, PICOEV_WRITE, WRITE_TIMEOUT_SECS, w_callback, (void *)client); return; default: // send OK close_conn(client, loop); } }
static void close_conn(picoev_loop* loop, int fd) { picoev_del(loop, fd); close(picoev_w32_fd2sock(fd)); printf("closed: %d\n", fd); }