Esempio n. 1
0
static ret_t
do_send_socket (cherokee_socket_t        *sock,
		cherokee_buffer_t        *buffer,
		cherokee_socket_status_t *blocking)
{
	ret_t  ret;
	size_t written = 0;

	ret = cherokee_socket_bufwrite (sock, buffer, &written);
	switch (ret) {
	case ret_ok:
		break;
	case ret_eagain:
		if (written > 0) {
			break;
		}

		TRACE (ENTRIES, "Post write: EAGAIN, wrote nothing of %d\n", buffer->len);
		*blocking = socket_writing;
		return ret_eagain;
	default:
		return ret_error;
	}

	cherokee_buffer_move_to_begin (buffer, written);
	TRACE (ENTRIES, "sent=%d, remaining=%d\n", written, buffer->len);

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

	return ret_ok;
}
Esempio n. 2
0
static ret_t
downloader_send_buffer (cherokee_downloader_t *downloader, cherokee_buffer_t *buf)
{
	ret_t              ret;
	size_t             written = 0;
	cherokee_socket_t *sock    = &downloader->socket;;

	ret = cherokee_socket_bufwrite (sock, buf, &written);
	switch (ret) {
	case ret_ok:
		/* Drop the header that has been sent
		 */
		cherokee_buffer_drop_ending (buf, written);
		if (cherokee_buffer_is_empty (buf)) {
			return ret_ok;
		}

		return ret_eagain;

	case ret_eagain:
		return ret;

	default:
		return ret_error;
	}
}
ret_t
cherokee_handler_proxy_conn_send (cherokee_handler_proxy_conn_t *pconn,
				  cherokee_buffer_t             *buf)
{
	ret_t  ret;
	size_t sent = 0;

	ret = cherokee_socket_bufwrite (&pconn->socket, buf, &sent);
	if (unlikely(ret != ret_ok)) {
		return ret;
	}

	if (sent >= buf->len) {
		cherokee_buffer_clean (buf);
		return ret_ok;
	}

	cherokee_buffer_move_to_begin (buf, sent);
	return ret_eagain;
}
Esempio n. 4
0
static ret_t
reply_100_continue (cherokee_post_t       *post,
		    cherokee_connection_t *conn)
{
	ret_t  ret;
	size_t written;

	ret = cherokee_socket_bufwrite (&conn->socket, &post->read_header_100cont, &written);
	if (ret != ret_ok) {
		TRACE(ENTRIES, "Could not send a '100 Continue' response. Error=500.\n");
		return ret;
	}

	if (written >= post->read_header_100cont.len) {
		TRACE(ENTRIES, "Sent a '100 Continue' response.\n");
		return ret_ok;
	}

	TRACE(ENTRIES, "Sent partial '100 Continue' response: %d bytes\n", written);
	cherokee_buffer_move_to_begin (&post->read_header_100cont, written);

	return ret_eagain;
}
Esempio n. 5
0
ret_t
cherokee_downloader_step (cherokee_downloader_t *downloader,
                          cherokee_buffer_t     *ext_tmp1,
                          cherokee_buffer_t     *ext_tmp2)
{
	ret_t              ret;
	cherokee_buffer_t *tmp1;
	cherokee_buffer_t *tmp2;

	/* Set the temporary buffers
	 */
	tmp1 = (ext_tmp1) ? ext_tmp1 : &downloader->tmp1;
	tmp2 = (ext_tmp2) ? ext_tmp2 : &downloader->tmp2;

	TRACE (ENTRIES, "phase=%d\n", downloader->phase);

	/* Process it
	 */
	switch (downloader->phase) {
	case downloader_phase_init: {
		cherokee_request_header_t *req = &downloader->request;

		TRACE(ENTRIES, "Phase %s\n", "init");

		/* Maybe add the post info
		 */
		if (! cherokee_buffer_is_empty (&downloader->post)) {
			req->method   = http_post;
			req->post_len = downloader->post.len;
		}

		/* Build the request header
		 */
		ret = cherokee_request_header_build_string (req, &downloader->request_header, tmp1, tmp2);
		if (unlikely(ret < ret_ok))
			return ret;

		/* Deal with the connection
		 */
		if (! is_connected (downloader)) {
			ret = cherokee_downloader_connect (downloader);
			if (ret < ret_ok) return ret;
		}

		/* Everything is ok, go ahead!
		 */
		downloader->phase = downloader_phase_send_headers;
	}
	case downloader_phase_send_headers:
		TRACE(ENTRIES, "Phase %s\n", "send_headers");

		ret = downloader_send_buffer (downloader, &downloader->request_header);
		if (unlikely(ret != ret_ok))
			return ret;

		BIT_SET (downloader->status, downloader_status_headers_sent);
		downloader->phase = downloader_phase_send_post;

	case downloader_phase_send_post:
		TRACE(ENTRIES, "Phase %s\n", "send_post");

		if (! cherokee_buffer_is_empty (&downloader->post)) {
			size_t written = 0;

			ret = cherokee_socket_bufwrite (&downloader->socket, &downloader->post, &written);
			if (ret != ret_ok) {
				return ret;
			}

			cherokee_buffer_move_to_begin (&downloader->post, written);
			if (! cherokee_buffer_is_empty (&downloader->post)) {
				return ret_eagain;
			}
		}

		BIT_SET (downloader->status, downloader_status_post_sent);
		downloader->phase = downloader_phase_read_headers;
		break;

	case downloader_phase_read_headers:
		TRACE(ENTRIES, "Phase %s\n", "read_headers");

		ret = downloader_header_read (downloader, tmp1, tmp2);
		if (unlikely(ret != ret_ok))
			return ret;

		/* We have the header parsed, continue..
		 */
		BIT_SET (downloader->status, downloader_status_headers_received);
		downloader->phase = downloader_phase_step;

		/* Does it read the full reply in the first received chunk?
		 */
		if (downloader->info.body_recv >= downloader->content_length) {
			BIT_SET (downloader->status, downloader_status_data_available);
			BIT_SET (downloader->status, downloader_status_finished);
			return ret_eof_have_data;
		}

	case downloader_phase_step:
		TRACE(ENTRIES, "Phase %s\n", "step");

		ret = downloader_step (downloader);
		switch (ret) {
		case ret_error:
			break;
		case ret_ok:
			BIT_SET (downloader->status, downloader_status_data_available);
			break;
		case ret_eof_have_data:
			BIT_SET (downloader->status, downloader_status_data_available);
			BIT_SET (downloader->status, downloader_status_finished);
			break;
		case ret_eof:
			BIT_UNSET (downloader->status, downloader_status_data_available);
			BIT_SET   (downloader->status, downloader_status_finished);
			break;
		case ret_eagain:
			BIT_UNSET (downloader->status, downloader_status_data_available);
			break;
		default:
			RET_UNKNOWN(ret);
		}
		return ret;

	case downloader_phase_finished:
		TRACE(ENTRIES, "Phase %s\n", "finished");

		BIT_SET   (downloader->status, downloader_status_finished);
		BIT_UNSET (downloader->status, downloader_status_data_available);
		return ret_ok;

	default:
		SHOULDNT_HAPPEN;
		break;
	}

	return ret_ok;
}