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; }
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; }
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; }
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; }