static void w_callback(picoev_loop* loop, int fd, int events, void* cb_arg) { client_t *client = ( client_t *)(cb_arg); int ret; #ifdef DEBUG printf("call w_callback \n"); #endif if ((events & PICOEV_TIMEOUT) != 0) { #ifdef DEBUG printf("** w_callback timeout ** \n"); #endif //timeout client->keep_alive = 0; close_conn(client, loop); } else if ((events & PICOEV_WRITE) != 0) { ret = process_body(client); picoev_set_timeout(loop, client->fd, WRITE_TIMEOUT_SECS); #ifdef DEBUG printf("process_body ret %d \n", ret); #endif if(ret != 0){ //ok or die close_conn(client, loop); } } }
static void timeout_callback(picoev_loop* loop, int fd, int events, void* cb_arg) { ClientObject *pyclient = (ClientObject *)(cb_arg); client_t *client = pyclient->client; if ((events & PICOEV_TIMEOUT) != 0) { #ifdef DEBUG printf("timeout_callback pyclient:%p client:%p fd:%d \n", pyclient, pyclient->client, pyclient->client->fd); #endif //next intval 30sec picoev_set_timeout(loop, client->fd, 30); // is_active ?? if(write(client->fd, "", 0) < 0){ //resume pyclient->suspended = 0; pyclient->resumed = 1; PyErr_SetFromErrno(PyExc_IOError); #ifdef DEBUG printf("closed \n"); #endif set_so_keepalive(client->fd, 0); switch_wsgi_app(loop, client->fd, (PyObject *)pyclient); } } }
static void rw_callback(picoev_loop* loop, int fd, int events, void* cb_arg) { if ((events & PICOEV_TIMEOUT) != 0) { /* timeout */ close_conn(loop, fd); } else if ((events & PICOEV_READ) != 0) { /* update timeout, and read */ char buf[1024]; ssize_t r; picoev_set_timeout(loop, fd, TIMEOUT_SECS); r = recv(picoev_w32_fd2sock(fd), buf, sizeof(buf), 0); switch (r) { case 0: /* connection closed by peer */ close_conn(loop, fd); break; case -1: /* error */ if (errno == EAGAIN || errno == EWOULDBLOCK) { /* try again later */ break; } else { /* fatal error */ close_conn(loop, fd); } break; default: /* got some data, send back */ if (send(picoev_w32_fd2sock(fd), buf, r, 0) != r) { close_conn(loop, fd); /* failed to send all data at once, close */ } break; } } }
static void r_callback(picoev_loop* loop, int fd, int events, void* cb_arg) { client_t *cli = ( client_t *)(cb_arg); if ((events & PICOEV_TIMEOUT) != 0) { #ifdef DEBUG printf("** r_callback timeout ** \n"); #endif //timeout cli->keep_alive = 0; close_conn(cli, loop); } else if ((events & PICOEV_READ) != 0) { #ifdef DEBUG printf("ready read \n"); #endif /* update timeout, and read */ int finish = 0, nread; char buf[INPUT_BUF_SIZE]; ssize_t r; if(!cli->keep_alive){ picoev_set_timeout(loop, cli->fd, SHORT_TIMEOUT_SECS); } r = read(cli->fd, buf, sizeof(buf)); switch (r) { case 0: finish = 1; break; case -1: /* error */ if (errno == EAGAIN || errno == EWOULDBLOCK) { /* try again later */ break; } else { /* fatal error */ rb_raise(rb_eException, "fatal error"); // TODO: // raise exception from errno /* rb_raise(); */ /* write_error_log(__FILE__, __LINE__); */ cli->keep_alive = 0; cli->status_code = 500; close_conn(cli, loop); return; } break; default: #ifdef DEBUG printf("read request fd %d bufsize %d \n", cli->fd, r); #endif nread = execute_parse(cli, buf, r); if(cli->bad_request_code > 0){ #ifdef DEBUG printf("fd %d bad_request code %d \n", cli->fd, cli->bad_request_code); #endif send_error_page(cli); close_conn(cli, loop); return; } if( nread != r ){ // parse error #ifdef DEBUG printf("fd %d parse error %d \n", cli->fd, cli->bad_request_code); #endif cli->bad_request_code = 400; send_error_page(cli); close_conn(cli, loop); return; } #ifdef DEBUG printf("parse ok, fd %d %d nread \n", cli->fd, nread); #endif if(parser_finish(cli) > 0){ finish = 1; } break; } if(finish == 1){ prepare_call_rack(cli); call_rack_app(cli, loop); return; } } }
static void r_callback(picoev_loop* loop, int fd, int events, void* cb_arg) { client_t *cli = ( client_t *)(cb_arg); //PyObject *body = NULL; char *key = NULL; int finish = 0, nread; if ((events & PICOEV_TIMEOUT) != 0) { #ifdef DEBUG printf("** r_callback timeout %d ** \n", fd); #endif //timeout cli->keep_alive = 0; if(cli->request_queue->size > 0){ //piplining set_bad_request_code(cli, 408); finish = 1; }else{ close_conn(cli, loop); } } else if ((events & PICOEV_READ) != 0) { char buf[INPUT_BUF_SIZE]; ssize_t r; if(!cli->keep_alive){ picoev_set_timeout(loop, cli->fd, READ_TIMEOUT_SECS); } Py_BEGIN_ALLOW_THREADS r = read(cli->fd, buf, sizeof(buf)); Py_END_ALLOW_THREADS switch (r) { case 0: cli->keep_alive = 0; //503?? if(cli->request_queue->size > 0){ //piplining set_bad_request_code(cli, 503); finish = 1; }else{ cli->status_code = 503; send_error_page(cli); close_conn(cli, loop); return; } case -1: /* error */ if (errno == EAGAIN || errno == EWOULDBLOCK) { /* try again later */ break; } else { /* fatal error */ if(cli->request_queue->size > 0){ //piplining set_bad_request_code(cli, 500); if(errno != ECONNRESET){ PyErr_SetFromErrno(PyExc_IOError); write_error_log(__FILE__, __LINE__); } finish = 1; }else{ if(cli->keep_alive && errno == ECONNRESET){ cli->keep_alive = 0; cli->status_code = 500; cli->header_done = 1; cli->response_closed = 1; }else{ PyErr_SetFromErrno(PyExc_IOError); write_error_log(__FILE__, __LINE__); cli->keep_alive = 0; cli->status_code = 500; if(errno != ECONNRESET){ send_error_page(cli); }else{ cli->header_done = 1; cli->response_closed = 1; } } close_conn(cli, loop); return; } } break; default: #ifdef DEBUG printf("********************\n%s\n", buf); #endif nread = execute_parse(cli, buf, r); #ifdef DEBUG printf("read request fd %d readed %d nread %d \n", cli->fd, r, nread); #endif if(cli->bad_request_code > 0){ #ifdef DEBUG printf("fd %d bad_request code %d \n",cli->fd, cli->bad_request_code); #endif set_bad_request_code(cli, cli->bad_request_code); ///force end finish = 1; break; } if(!cli->upgrade && nread != r){ // parse error #ifdef DEBUG printf("fd %d parse error Bad Request %d \n", cli->fd, cli->bad_request_code); #endif set_bad_request_code(cli, 400); ///force end finish = 1; break; } #ifdef DEBUG printf("parse ok, fd %d %d nread \n", cli->fd, nread); #endif if(parser_finish(cli) > 0){ if(cli->upgrade){ //WebSocket Key #ifdef DEBUG printf("upgrade websocket %d \n", cli->fd); #endif key = buf + nread + 1; buffer *b = new_buffer(r - nread -1, r - nread -1); if(write2buf(b, key, r - nread -1) == WRITE_OK){ cli->request_queue->tail->body = b; }else{ free_buffer(b); } } finish = 1; } break; } }