static ret_t send_query (cherokee_handler_dbslayer_t *hdl) { int re; cuint_t len; cherokee_connection_t *conn = HANDLER_CONN(hdl); cherokee_buffer_t *tmp = &HANDLER_THREAD(hdl)->tmp_buf1; /* Extract the SQL query */ if ((cherokee_buffer_is_empty (&conn->web_directory)) || (cherokee_buffer_is_ending (&conn->web_directory, '/'))) { len = conn->web_directory.len; } else { len = conn->web_directory.len + 1; } cherokee_buffer_clean (tmp); cherokee_buffer_add (tmp, conn->request.buf + len, conn->request.len - len); cherokee_buffer_unescape_uri (tmp); /* Send the query */ re = mysql_real_query (hdl->conn, tmp->buf, tmp->len); if (re != 0) return ret_error; return ret_ok; }
ret_t cherokee_handler_tmi_init (cherokee_handler_tmi_t *hdl) { ret_t ret; cherokee_connection_t *conn = HANDLER_CONN(hdl); cherokee_buffer_t *tmp = &HANDLER_THREAD(hdl)->tmp_buf1; cherokee_handler_tmi_props_t *props = HANDLER_TMI_PROPS(hdl); /* We are going to look for gzipped encoding */ cherokee_buffer_clean (tmp); ret = cherokee_header_copy_known (&conn->header, header_content_encoding, tmp); if (ret == ret_ok && cherokee_buffer_cmp_str(tmp, "gzip") == 0) { TRACE(ENTRIES, "ZeroMQ: incomming header '%s'\n", tmp->buf); hdl->inflated = true; } else { cherokee_buffer_clean (tmp); ret = cherokee_header_copy_known (&conn->header, header_content_type, tmp); if (ret == ret_ok && (cherokee_buffer_cmp_str(tmp, "application/gzip") == 0 || cherokee_buffer_cmp_str(tmp, "application/zip") == 0)) { TRACE(ENTRIES, "ZeroMQ: incomming header '%s'\n", tmp->buf); hdl->inflated = true; } else { hdl->inflated = false; } } #ifdef LIBXML_PUSH_ENABLED if (props->validate_xml) { hdl->validate_xml = true; hdl->ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL); xmlCtxtUseOptions(hdl->ctxt, XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NONET | XML_PARSE_COMPACT); if (hdl->inflated) { /* allocate inflate state */ hdl->strm.zalloc = Z_NULL; hdl->strm.zfree = Z_NULL; hdl->strm.opaque = Z_NULL; hdl->strm.avail_in = 0; hdl->strm.next_in = Z_NULL; hdl->z_ret = inflateInit2(&(hdl->strm), 16+MAX_WBITS); if (hdl->z_ret != Z_OK) hdl->validate_xml = false; } } #endif if (!hdl->inflated) { /* If we end up here that means content is plain, lets set up an encoder */ ret = props->encoder_props->instance_func((void **)&hdl->encoder, props->encoder_props); if (unlikely (ret != ret_ok)) { return ret_error; } ret = cherokee_encoder_init (hdl->encoder, conn); if (unlikely (ret != ret_ok)) { return ret_error; } } return ret_ok; }
ret_t cherokee_handler_cgi_read_post (cherokee_handler_cgi_t *cgi) { ret_t ret; cherokee_connection_t *conn = HANDLER_CONN(cgi); cherokee_socket_status_t blocking = socket_closed; cherokee_boolean_t did_IO = false; if (! conn->post.has_info) { return ret_ok; } ret = cherokee_post_send_to_fd (&conn->post, &conn->socket, cgi->pipeOutput, NULL, &blocking, &did_IO); if (did_IO) { cherokee_connection_update_timeout (conn); } switch (ret) { case ret_ok: break; case ret_eagain: if (blocking == socket_writing) { cherokee_thread_deactive_to_polling (HANDLER_THREAD(cgi), conn, cgi->pipeOutput, FDPOLL_MODE_WRITE, false); return ret_deny; } /* ret_eagain - Block on read * ret_deny - Block on back-end write */ if (cherokee_post_has_buffered_info (&conn->post)) { return ret_deny; } return ret_eagain; default: return ret; } TRACE (ENTRIES",post", "%s\n", "finished"); cherokee_fd_close (cgi->pipeOutput); cgi->pipeOutput = -1; return ret_ok; }
static ret_t read_from_cgi (cherokee_handler_cgi_base_t *cgi_base, cherokee_buffer_t *buffer) { ret_t ret; size_t read_ = 0; cherokee_handler_cgi_t *cgi = HDL_CGI(cgi_base); /* Sanity check: pipe() accessed */ if (unlikely (cgi->pipeInput < 0)) return ret_eof; /* Read the data from the pipe: */ ret = cherokee_buffer_read_from_fd (buffer, cgi->pipeInput, 4096, &read_); TRACE (ENTRIES, "read... ret=%d %d\n", ret, read_); switch (ret) { case ret_eagain: cherokee_thread_deactive_to_polling (HANDLER_THREAD(cgi), HANDLER_CONN(cgi), cgi->pipeInput, FDPOLL_MODE_READ, false); return ret_eagain; case ret_ok: TRACE (ENTRIES, "%d bytes read\n", read_); return ret_ok; case ret_eof: case ret_error: cgi_base->got_eof = true; return ret; default: RET_UNKNOWN(ret); } SHOULDNT_HAPPEN; return ret_error; }
static ret_t read_from_fcgi (cherokee_handler_cgi_base_t *cgi, cherokee_buffer_t *buffer) { ret_t ret; size_t read = 0; cherokee_handler_fcgi_t *fcgi = HDL_FCGI(cgi); ret = cherokee_socket_bufread (&fcgi->socket, &fcgi->write_buffer, DEFAULT_READ_SIZE, &read); switch (ret) { case ret_eagain: ret = cherokee_thread_deactive_to_polling (HANDLER_THREAD(cgi), HANDLER_CONN(cgi), fcgi->socket.socket, FDPOLL_MODE_READ, false); if (unlikely (ret != ret_ok)) { cgi->got_eof = true; return ret_error; } return ret_eagain; case ret_ok: ret = process_buffer (fcgi, &fcgi->write_buffer, buffer); TRACE (ENTRIES, "%d bytes read, buffer.len %d\n", read, buffer->len); if ((ret == ret_ok) && cgi->got_eof && (buffer->len > 0)) { return ret_eof_have_data; } return ret; case ret_eof: case ret_error: cgi->got_eof = true; return ret; default: RET_UNKNOWN(ret); } SHOULDNT_HAPPEN; return ret_error; }
ret_t cherokee_handler_zeromq_init (cherokee_handler_zeromq_t *hdl) { ret_t ret; cherokee_buffer_t *tmp = &HANDLER_THREAD(hdl)->tmp_buf1; cherokee_connection_t *conn = HANDLER_CONN(hdl); cherokee_handler_zeromq_props_t *props = HANDLER_ZEROMQ_PROPS(hdl); /* We are going to look for gzipped encoding */ cherokee_buffer_clean (tmp); ret = cherokee_header_copy_known (&conn->header, header_content_encoding, tmp); if (ret == ret_ok && cherokee_buffer_cmp_str(tmp, "gzip") == 0) { TRACE(ENTRIES, "ZeroMQ: incomming header '%s'\n", tmp->buf); return ret_ok; } else { cherokee_buffer_clean (tmp); ret = cherokee_header_copy_known (&conn->header, header_content_type, tmp); if (ret == ret_ok && cherokee_buffer_cmp_str(tmp, "application/gzip") == 0) { TRACE(ENTRIES, "ZeroMQ: incomming header '%s'\n", tmp->buf); return ret_ok; } } /* If we end up here that means content is plain, lets set up an encoder */ ret = props->encoder_props->instance_func((void **)&hdl->encoder, props->encoder_props); if (unlikely (ret != ret_ok)) { return ret_error; } ret = cherokee_encoder_init (hdl->encoder, conn); /* TODO: this is a great idea for KV78turbo, but being able to configure * the reply (KV6, 15, 17) sounds like a good idea too. */ conn->error_code = http_no_content; return ret_error; }
ret_t cherokee_handler_zeromq_read_post (cherokee_handler_zeromq_t *hdl) { zmq_msg_t message; int re; ret_t ret; cherokee_buffer_t *post = &HANDLER_THREAD(hdl)->tmp_buf1; cherokee_buffer_t *out = &HANDLER_THREAD(hdl)->tmp_buf2; cherokee_connection_t *conn = HANDLER_CONN(hdl); /* Check for the post info */ if (! conn->post.has_info) { conn->error_code = http_bad_request; return ret_error; } cherokee_buffer_clean (post); ret = cherokee_post_read (&conn->post, &conn->socket, post); switch (ret) { case ret_ok: cherokee_connection_update_timeout (conn); break; case ret_eagain: ret = cherokee_thread_deactive_to_polling (HANDLER_THREAD(hdl), HANDLER_CONN(hdl), conn->socket.socket, FDPOLL_MODE_READ, false); if (ret != ret_ok) { return ret_error; } else { return ret_eagain; } default: conn->error_code = http_bad_request; return ret_error; } TRACE (ENTRIES, "Post contains: '%s'\n", post->buf); re = cherokee_post_read_finished (&conn->post); ret = re ? ret_ok : ret_eagain; if (hdl->encoder != NULL) { cherokee_buffer_clean(out); if (ret == ret_ok) { cherokee_encoder_flush(hdl->encoder, post, out); } else { cherokee_encoder_encode(hdl->encoder, post, out); } post = out; } cherokee_buffer_add_buffer(&hdl->output, post); if (ret == ret_ok) { cherokee_buffer_t *tmp = &HANDLER_THREAD(hdl)->tmp_buf1; cherokee_handler_zeromq_props_t *props = HANDLER_ZEROMQ_PROPS(hdl); zmq_msg_t envelope; zmq_msg_t message; cuint_t len; if ((cherokee_buffer_is_empty (&conn->web_directory)) || (cherokee_buffer_is_ending (&conn->web_directory, '/'))) { len = conn->web_directory.len; } else { len = conn->web_directory.len + 1; } cherokee_buffer_clean (tmp); cherokee_buffer_add (tmp, conn->request.buf + len, conn->request.len - len); TRACE(ENTRIES, "ZeroMQ: incomming path '%s'\n", tmp->buf); zmq_msg_init_size (&envelope, tmp->len); memcpy (zmq_msg_data (&envelope), tmp->buf, tmp->len); zmq_msg_init_size (&message, hdl->output.len); memcpy (zmq_msg_data (&message), hdl->output.buf, hdl->output.len); /* Atomic Section */ CHEROKEE_MUTEX_LOCK (&props->mutex); zmq_msg_send (&envelope, props->socket, ZMQ_DONTWAIT | ZMQ_SNDMORE); zmq_msg_send (&message, props->socket, ZMQ_DONTWAIT); CHEROKEE_MUTEX_UNLOCK (&props->mutex); zmq_msg_close (&envelope); zmq_msg_close (&message); } return ret; }
ret_t cherokee_handler_tmi_read_post (cherokee_handler_tmi_t *hdl) { zmq_msg_t message; int re; ret_t ret; ret_t ret_final; cherokee_buffer_t *post = &HANDLER_THREAD(hdl)->tmp_buf1; cherokee_buffer_t *encoded = &HANDLER_THREAD(hdl)->tmp_buf2; cherokee_connection_t *conn = HANDLER_CONN(hdl); /* Check for the post info */ if (! conn->post.has_info) { conn->error_code = http_bad_request; return ret_error; } cherokee_buffer_clean (post); ret = cherokee_post_read (&conn->post, &conn->socket, post); switch (ret) { case ret_ok: cherokee_connection_update_timeout (conn); break; case ret_eagain: ret = cherokee_thread_deactive_to_polling (HANDLER_THREAD(hdl), HANDLER_CONN(hdl), conn->socket.socket, FDPOLL_MODE_READ, false); if (ret != ret_ok) { return ret_error; } else { return ret_eagain; } default: conn->error_code = http_bad_request; return ret_error; } TRACE (ENTRIES, "Post contains: '%s'\n", post->buf); re = cherokee_post_read_finished (&conn->post); ret_final = re ? ret_ok : ret_eagain; cherokee_buffer_clean(encoded); if (hdl->encoder != NULL) { if (ret == ret_ok) { cherokee_encoder_flush(hdl->encoder, post, encoded); } else { cherokee_encoder_encode(hdl->encoder, post, encoded); } } else { encoded = post; } cherokee_buffer_add_buffer(&hdl->output, post); if (ret_final == ret_ok) { cherokee_buffer_t *tmp = &HANDLER_THREAD(hdl)->tmp_buf1; cherokee_handler_tmi_props_t *props = HANDLER_TMI_PROPS(hdl); zmq_msg_t envelope; zmq_msg_t message; cuint_t len; if ((cherokee_buffer_is_empty (&conn->web_directory)) || (cherokee_buffer_is_ending (&conn->web_directory, '/'))) { len = conn->web_directory.len; } else { len = conn->web_directory.len + 1; } cherokee_buffer_clean (tmp); cherokee_buffer_add (tmp, conn->request.buf + len, conn->request.len - len); TRACE(ENTRIES, "ZeroMQ: incomming path '%s'\n", tmp->buf); zmq_msg_init_size (&envelope, tmp->len); memcpy (zmq_msg_data (&envelope), tmp->buf, tmp->len); zmq_msg_init_size (&message, hdl->output.len); memcpy (zmq_msg_data (&message), hdl->output.buf, hdl->output.len); /* Atomic Section */ CHEROKEE_MUTEX_LOCK (&props->mutex); zmq_msg_send (&envelope, props->socket, ZMQ_DONTWAIT | ZMQ_SNDMORE); zmq_msg_send (&message, props->socket, ZMQ_DONTWAIT); CHEROKEE_MUTEX_UNLOCK (&props->mutex); zmq_msg_close (&envelope); zmq_msg_close (&message); #ifdef LIBXML_PUSH_ENABLED if (hdl->validate_xml) { if (hdl->inflated) { hdl->strm.avail_in = hdl->output.len; hdl->strm.next_in = hdl->output.buf; /* run inflate() on input until output buffer not full */ do { #define CHUNK 131072 int have; char out[CHUNK]; hdl->strm.avail_out = CHUNK; hdl->strm.next_out = out; hdl->z_ret = inflate(&(hdl->strm), Z_NO_FLUSH); switch (hdl->z_ret) { case Z_NEED_DICT: hdl->z_ret = Z_DATA_ERROR; /* and fall through */ case Z_DATA_ERROR: case Z_MEM_ERROR: case Z_STREAM_ERROR: hdl->z_ret = Z_STREAM_ERROR; return ret_ok; } have = CHUNK - hdl->strm.avail_out; xmlParseChunk(hdl->ctxt, out, have, 0); } while (hdl->strm.avail_out == 0); } else { xmlParseChunk(hdl->ctxt, hdl->output.buf, hdl->output.len, 0); } } #endif } return ret_final; }