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;
}
Example #2
0
ret_t
cherokee_handler_admin_read_post (cherokee_handler_admin_t *hdl)
{
    int                      re;
    ret_t                    ret;
    char                    *tmp;
    cherokee_buffer_t        post = CHEROKEE_BUF_INIT;
    cherokee_buffer_t        line = CHEROKEE_BUF_INIT;
    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;
    }

    /* Process line per line
     */
    ret = cherokee_post_read (&conn->post, &conn->socket, &post);
    switch (ret) {
    case ret_ok:
    case ret_eagain:
        break;
    default:
        conn->error_code = http_bad_request;
        return ret_error;
    }

    /* Parse
     */
    TRACE (ENTRIES, "Post contains: '%s'\n", post.buf);

    cherokee_dwriter_list_open (&hdl->dwriter);

    for (tmp = post.buf;;) {
        char *end1 = strchr (tmp, CHR_LF);
        char *end2 = strchr (tmp, CHR_CR);
        char *end  = cherokee_min_str (end1, end2);

        if (end == NULL) break;
        if (end - tmp < 2) break;

        /* Copy current line and go to the next one
         */
        cherokee_buffer_add (&line, tmp, end - tmp);
        while ((*end == CHR_CR) || (*end == CHR_LF)) end++;
        tmp = end;

        /* Process current line
         */
        ret = process_request_line (hdl, &line);
        if (ret == ret_error) {
            conn->error_code = http_bad_request;
            ret = ret_error;
            goto exit2;
        }

        /* Clean up for the next iteration
         */
        cherokee_buffer_clean (&line);
    }

    cherokee_dwriter_list_close (&hdl->dwriter);

    /* There might be more POST to read
     */
    re = cherokee_post_read_finished (&conn->post);
    ret = re ? ret_ok : ret_eagain;

exit2:
    cherokee_buffer_mrproper (&post);
    cherokee_buffer_mrproper (&line);
    return ret;
}
Example #3
0
ret_t
cherokee_post_send_to_fd (cherokee_post_t          *post,
			  cherokee_socket_t        *sock_in,
			  int                       fd_out,
			  cherokee_buffer_t        *tmp,
			  cherokee_socket_status_t *blocking,
			  cherokee_boolean_t       *did_IO)
{
	ret_t              ret;
	int                r;
	cherokee_buffer_t *buffer = tmp ? tmp : &post->send.buffer;


	switch (post->send.phase) {
	case cherokee_post_send_phase_read:
		TRACE (ENTRIES, "Post send, phase: %s\n", "read");

		/* Read from the client
		 */
		ret = cherokee_post_read (post, sock_in, buffer);
		switch (ret) {
		case ret_ok:
			break;
		case ret_eagain:
			*blocking = socket_reading;
			return ret_eagain;
		default:
			return ret;
		}

		/* Did something, increase timeout
		 */
		*did_IO = true;

		/* Write it
		 */
		TRACE (ENTRIES, "Post buffer.len %d\n", buffer->len);
		post->send.phase = cherokee_post_send_phase_write;

	case cherokee_post_send_phase_write:
		TRACE (ENTRIES, "Post send, phase: write. Has %d bytes to send\n", buffer->len);

		if (! cherokee_buffer_is_empty (buffer)) {
			r = write (fd_out, buffer->buf, buffer->len);
			if (r < 0) {
				if (errno == EAGAIN) {
					*blocking = socket_writing;
					return ret_eagain;
				}

				TRACE(ENTRIES, "errno %d: %s\n", errno, strerror(errno));
				return ret_error;

			} else if (r == 0) {
				return ret_eagain;
			}

			cherokee_buffer_move_to_begin (buffer, r);

			/* Did something, increase timeout
			 */
			*did_IO = true;
		}

		/* Next iteration
		 */
		if (! cherokee_buffer_is_empty (buffer)) {
			return ret_eagain;
		}

		if (! cherokee_post_read_finished (post)) {
			post->send.phase = cherokee_post_send_phase_read;
			return ret_eagain;
		}

		TRACE (ENTRIES, "Post send: %s\n", "finished");

		cherokee_buffer_mrproper (&post->send.buffer);
		return ret_ok;

	default:
		SHOULDNT_HAPPEN;
	}

	return ret_error;
}
Example #4
0
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;
}
Example #5
0
ret_t
cherokee_post_send_to_socket (cherokee_post_t          *post,
			      cherokee_socket_t        *sock_in,
			      cherokee_socket_t        *sock_out,
			      cherokee_buffer_t        *tmp,
			      cherokee_socket_status_t *blocking,
			      cherokee_boolean_t       *did_IO)
{
	ret_t              ret;
	cherokee_buffer_t *buffer = tmp ? tmp : &post->send.buffer;

	switch (post->send.phase) {
	case cherokee_post_send_phase_read:
		TRACE (ENTRIES, "Post send, phase: %s\n", "read");

		/* Read from the client
		 */
		ret = cherokee_post_read (post, sock_in, buffer);
		switch (ret) {
		case ret_ok:
			break;
		case ret_eagain:
			*blocking = socket_reading;
			return ret_eagain;
		default:
			return ret;
		}

		/* Did something, increase timeout
		 */
		*did_IO = true;

		/* Write it
		 */
		TRACE (ENTRIES, "Post buffer.len %d\n", buffer->len);
		post->send.phase = cherokee_post_send_phase_write;

	case cherokee_post_send_phase_write:
		TRACE (ENTRIES, "Post send, phase: write. Buffered: %d bytes\n", buffer->len);

		if (! cherokee_buffer_is_empty (buffer)) {
			ret = do_send_socket (sock_out, buffer, blocking);
			switch (ret) {
                        case ret_ok:
                                break;
                        case ret_eagain:
                                return ret_eagain;
                        case ret_eof:
                        case ret_error:
                                return ret_error;
                        default:
				RET_UNKNOWN(ret);
				return ret_error;
                        }

			/* Did something, increase timeout
			 */
			*did_IO = true;
		}

		if (! cherokee_buffer_is_empty (buffer)) {
			return ret_eagain;
		}

		if (! cherokee_post_read_finished (post)) {
			post->send.phase = cherokee_post_send_phase_read;
			return ret_eagain;
		}

		TRACE (ENTRIES, "Post send: %s\n", "finished");

		cherokee_buffer_mrproper (&post->send.buffer);
		return ret_ok;

	default:
		SHOULDNT_HAPPEN;
	}

	return ret_error;
}