Ejemplo n.º 1
0
static ret_t
downloader_step (cherokee_downloader_t *downloader)
{
	ret_t               ret;
	size_t              read_ = 0;
	cherokee_socket_t  *sock  = &downloader->socket;

	ret = cherokee_socket_bufread (sock, &downloader->body, DEFAULT_RECV_SIZE, &read_);
	switch (ret) {
	case ret_eagain:
		return ret_eagain;

	case ret_ok:
		/* Count
		 */
		downloader->info.body_recv += read_;

		/* Has it finished?
		 */
		if (downloader->info.body_recv >= downloader->content_length) {
			return ret_eof_have_data;
		}

		return ret_ok;
	default:
		return ret;
	}

	return ret_ok;
}
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;
}
Ejemplo n.º 3
0
static ret_t
do_read_plain (cherokee_post_t   *post,
	       cherokee_socket_t *sock_in,
	       cherokee_buffer_t *buffer,
	       off_t              to_read)
{
	ret_t  ret;
	size_t len;

	/* Surplus from header read
	 */
	if (! cherokee_buffer_is_empty (&post->header_surplus)) {
		TRACE (ENTRIES, "Post appending %d surplus bytes\n", post->header_surplus.len);
		post->send.read += post->header_surplus.len;

		cherokee_buffer_add_buffer (buffer, &post->header_surplus);
		cherokee_buffer_clean (&post->header_surplus);

		return ret_ok;
	}

	/* Read
	 */
	if (to_read <= 0) {
		return ret_ok;
	}

	TRACE (ENTRIES, "Post reading from client (to_read=%d)\n", to_read);
	ret = cherokee_socket_bufread (sock_in, buffer, to_read, &len);
	TRACE (ENTRIES, "Post read from client: ret=%d len=%d\n", ret, len);

	if (ret != ret_ok) {
		return ret;
	}

	post->send.read += len;
	return ret_ok;
}
ret_t
cherokee_handler_proxy_conn_recv_headers (cherokee_handler_proxy_conn_t *pconn,
					  cherokee_buffer_t             *body,
					  cherokee_boolean_t             flexible)
{
	ret_t    ret;
	char    *end;
	cuint_t  sep_len;
	size_t   size     = 0;

	/* Read
	 */
	ret = cherokee_socket_bufread (&pconn->socket,
				       &pconn->header_in_raw,
				       DEFAULT_RECV_SIZE, &size);
	switch (ret) {
	case ret_ok:
		break;
	case ret_eof:
	case ret_error:
		return ret;
	case ret_eagain:
		if (cherokee_buffer_is_empty (&pconn->header_in_raw)) {
			return ret_eagain;
		}
		break;
	default:
		RET_UNKNOWN(ret);
	}

	/* Look for the end of header
	 */
	ret = cherokee_find_header_end (&pconn->header_in_raw, &end, &sep_len);
	switch (ret) {
	case ret_ok:
		break;
	case ret_not_found:
		return ret_eagain;
	default:
		/* Did not success
		 */
		if (! flexible) {
			goto error;
		}

		/* Plan B!
		 */
		TRACE (ENTRIES, "Header end not found. Being more flexible about malformed headers\n");

		ret = find_header_end_flexible (&pconn->header_in_raw, &end, &sep_len);
		switch (ret) {
		case ret_ok:
			break;
		case ret_not_found:
			return ret_eagain;
		default:
			goto error;
		}
	}

	/* Copy the body if there is any
	 */
	size = (pconn->header_in_raw.buf + pconn->header_in_raw.len) - (end + sep_len);

	cherokee_buffer_add (body, end+sep_len, size);
	cherokee_buffer_drop_ending (&pconn->header_in_raw, size);

	return ret_ok;

error:
	LOG_ERROR (CHEROKEE_ERROR_PROXY_HEADER_PARSE,
		   pconn->header_in_raw.len,
		   pconn->header_in_raw.buf);

	return ret_error;
}
Ejemplo n.º 5
0
static ret_t
downloader_header_read (cherokee_downloader_t *downloader,
                        cherokee_buffer_t     *tmp1,
                        cherokee_buffer_t     *tmp2)
{
	ret_t               ret;
	cuint_t             len;
	size_t              read_      = 0;
	cherokee_socket_t  *sock       = &downloader->socket;
	cherokee_http_t     error_code = http_bad_request;

	UNUSED(tmp2);

	ret = cherokee_socket_bufread (sock, &downloader->reply_header, DEFAULT_RECV_SIZE, &read_);
	switch (ret) {
	case ret_eof:
		return ret_eof;

	case ret_eagain:
		return ret_eagain;

	case ret_ok:
		/* Count
		 */
		downloader->info.headers_recv += read_;

		/* Check the header. Is it complete?
		 */
		ret = cherokee_header_has_header (downloader->header, &downloader->reply_header, 0);
		switch (ret) {
		case ret_ok:
			break;
		case ret_not_found:
			/* It needs to read more headers ...
			 */
			return ret_eagain;
		default:
			/* Too many initial CRLF
			 */
			return ret_error;
		}

		/* Parse the header
		 */
		ret = cherokee_header_parse (downloader->header,
		                             &downloader->reply_header,
		                             &error_code);
		if (unlikely (ret != ret_ok)) return ret_error;

		/* Look for the length, it will need to drop out the header from the buffer
		 */
		cherokee_header_get_length (downloader->header, &len);

		/* Maybe it has some body
		 */
		if (downloader->reply_header.len > len) {
			uint32_t body_chunk;

			/* Skip the CRLF separator and copy the body
			 */
			len += 2;
			body_chunk = downloader->reply_header.len - len;

			downloader->info.body_recv += body_chunk;
			cherokee_buffer_add (&downloader->body, downloader->reply_header.buf + len, body_chunk);

			cherokee_buffer_drop_ending (&downloader->reply_header, body_chunk);
		}

		/* Try to read the "Content-Length" response header
		 */
		ret = cherokee_header_has_known (downloader->header, header_content_length);
		if (ret == ret_ok) {
			cherokee_buffer_clean (tmp1);
			ret = cherokee_header_copy_known (downloader->header, header_content_length, tmp1);
			if (ret == ret_ok) {
				ret = cherokee_atou (tmp1->buf, &downloader->content_length);
#ifdef TRACE_ENABLED
				if (ret == ret_ok) {
					TRACE (ENTRIES, "Known length: %d bytes\n", downloader->content_length);
				} else {
					TRACE (ENTRIES, "Could not parse Content-Length\n");
				}
#endif
			}
		}

		return ret_ok;

	case ret_error:
		/* Opsss.. something has failed
		 */
		return ret_error;

	default:
		RET_UNKNOWN (ret);
		return ret;
	}

	return ret_error;
}