Skip to content
Snippets Groups Projects
Commit 24837311 authored by Mihail NECULA's avatar Mihail NECULA
Browse files

Made the send buffer bigger to not give time out anymore at some tests. +...

Made the send buffer bigger to not give time out anymore at some tests. + Finished the restructuration.
parent 307b0cf6
No related branches found
No related tags found
No related merge requests found
Pipeline #99897 passed
......@@ -56,7 +56,7 @@ struct connection *connection_create(int sockfd)
{
struct connection *conn;
conn = (struct connection*)malloc(sizeof(struct connection));
conn = (struct connection *)malloc(sizeof(struct connection));
DIE(!conn, "malloc() failed\n");
conn->fd = -1;
......@@ -104,12 +104,12 @@ void connection_remove(struct connection *conn)
close(conn->sockfd);
free(conn);
dlog(LOG_INFO,"Server closed connection with: %s.\n", client_addr);
dlog(LOG_INFO, "Server closed connection with: %s.\n", client_addr);
}
/*****
* Handle a new connection request on the server socket.
*****/
*****/
void handle_new_connection(void)
{
struct sockaddr_in client_addr;
......@@ -120,7 +120,7 @@ void handle_new_connection(void)
/* Accept new connection. */
clientfd = accept(listenfd, (struct sockaddr *) &client_addr, &size_addr);
DIE(clientfd < 0, "accept() failed\n");
dlog(LOG_INFO,"Server accepted connection from: %s:%d\n",
dlog(LOG_INFO, "Server accepted connection from: %s:%d\n",
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
/* Set socket to be non-blocking. */
......@@ -144,7 +144,7 @@ void handle_new_connection(void)
/*****
* Receive message on socket.
* Store message in recv_buffer in struct connection.
*****/
*****/
int receive_data(struct connection *conn)
{
char client_addr[101], *buffer;
......@@ -161,7 +161,7 @@ int receive_data(struct connection *conn)
connection_remove(conn);
return -1;
}
conn->recv_len += recv_bytes;
return 0;
}
......@@ -173,11 +173,10 @@ int receive_data(struct connection *conn)
*****/
void connection_set_resource_type(struct connection *conn)
{
if (conn->request_path[2] == 's') {
if (conn->request_path[2] == 's')
conn->res_type = RESOURCE_TYPE_STATIC;
} else if (conn->request_path[2] =='d') {
else if (conn->request_path[2] == 'd')
conn->res_type = RESOURCE_TYPE_DYNAMIC;
}
}
/*****
......@@ -210,8 +209,10 @@ void parse_header(struct connection *conn)
*****/
void connection_open_file(struct connection *conn)
{
struct stat st;
conn->fd = open(conn->request_path, O_RDONLY);
if (conn->fd < 0) {
strcpy(conn->send_buffer, HTTP_404);
conn->send_len = strlen(HTTP_404);
......@@ -219,7 +220,6 @@ void connection_open_file(struct connection *conn)
strcpy(conn->send_buffer, HTTP_200);
conn->send_len = strlen(HTTP_200);
struct stat st;
stat(conn->request_path, &st);
conn->file_size = st.st_size;
conn->file_pos = 0;
......@@ -240,7 +240,7 @@ int connection_send_buffer(struct connection *conn)
DIE(rc == -1, "get_peer_address() failed\n");
bytes_sent = send(conn->sockfd, conn->send_buffer, conn->send_len, 0);
if (bytes_sent <= 0) {
dlog(LOG_INFO, "Server can't comunicate with: %s.\n",
client_addr);
......@@ -271,7 +271,7 @@ int connection_send_static(struct connection *conn)
DIE(rc == -1, "get_peer_address() failed\n");
bytes_sent = sendfile(conn->sockfd, conn->fd, &conn->file_pos, conn->file_size);
if (bytes_sent <= 0) {
dlog(LOG_INFO, "Server can't comunicate with: %s.\n",
client_addr);
......@@ -283,33 +283,39 @@ int connection_send_static(struct connection *conn)
return 0;
}
/*****
/*****
* Starts asynchronous operation (read from file).
* Uses io_submit(2) & friends for reading data asynchronously.
*****/
*****/
void connection_start_async_io(struct connection *conn)
{
int rc;
conn->async_read_len = BUFSIZ < conn->file_size ? BUFSIZ : conn->file_size;
/* Prepare the io control block. */
conn->async_read_len = 16 * BUFSIZ < conn->file_size ? 16 * BUFSIZ : conn->file_size;
memset(&conn->iocb, 0, sizeof(conn->iocb));
io_prep_pread(&conn->iocb, conn->fd, conn->send_buffer, conn->async_read_len, conn->file_pos);
/* Associate the operation with a fd. */
conn->eventfd = eventfd(0, 0);
DIE(conn->eventfd == -1, "eventfd() failed\n");
io_set_eventfd(&conn->iocb, conn->eventfd);
/* We won't send something to client, until this operation is done. */
rc = w_epoll_remove_ptr(epollfd, conn->sockfd, conn);
DIE(rc == -1, "w_epoll_add_ptr_in() failed\n");
DIE(rc == -1, "w_epoll_remove_ptr() failed\n");
/* We need to know when the operation is done. */
rc = w_epoll_add_ptr_in(epollfd, conn->eventfd, conn);
DIE(rc == -1, "w_epoll_add_ptr_in() failed\n");
/* Setup the context. */
memset(&conn->ctx, 0, sizeof(io_context_t));
rc = io_setup(1, &conn->ctx);
DIE(rc, "io_setup() failed\n");
/* Start the operation. */
rc = io_submit(conn->ctx, 1, conn->piocb);
dlog(LOG_INFO, "%s %d\n", strerror(errno), rc);
DIE(rc < 0, "io_submit() failed\n");
}
......@@ -326,8 +332,12 @@ void connection_complete_async_io(struct connection *conn)
rc = w_epoll_add_ptr_out(epollfd, conn->sockfd, conn);
DIE(rc == -1, "w_epoll_add_ptr_out() failed\n");
/*Why i can not put this at begining?*/
io_destroy(conn->ctx);
/* Why i can not put this at begining? */
rc = io_destroy(conn->ctx);
DIE(rc, "io_destroy() failed\n");
rc = close(conn->eventfd);
DIE(rc, "close() failed\n");
conn->eventfd = -1;
conn->send_len = conn->async_read_len;
......@@ -339,11 +349,11 @@ void connection_complete_async_io(struct connection *conn)
/*****
* Read data asynchronously and put it in connection send buffer,
* which is further sent to client.
*****/
*****/
int connection_send_dynamic(struct connection *conn)
{
char client_addr[101];
int rc, bytes_sent;
int rc;
rc = get_peer_address(conn->sockfd, client_addr, 100);
DIE(rc == -1, "get_peer_address() failed\n");
......@@ -353,17 +363,15 @@ int connection_send_dynamic(struct connection *conn)
return 0;
}
bytes_sent = connection_send_buffer(conn);
connection_send_buffer(conn);
return 0;
}
/*****
* Send as much data as possible from the connection send buffer / connection file.
*****/
*****/
int connection_send_data(struct connection *conn)
{
char client_addr[101];
int rc;
......@@ -371,7 +379,7 @@ int connection_send_data(struct connection *conn)
DIE(rc == -1, "get_peer_address() failed\n");
if (conn->state == STATE_SENDING_HEADER) {
connection_send_buffer(conn);
rc = connection_send_buffer(conn);
if (!conn->send_len) {
dlog(LOG_INFO, "Server sent reply header to: %s.\n", client_addr);
......@@ -386,9 +394,9 @@ int connection_send_data(struct connection *conn)
if (conn->state == STATE_SENDING_DATA) {
if (conn->res_type == RESOURCE_TYPE_STATIC)
connection_send_static(conn);
rc = connection_send_static(conn);
else
connection_send_dynamic(conn);
rc = connection_send_dynamic(conn);
if (!conn->send_len && !conn->file_size) {
dlog(LOG_INFO, "Server sent a file to: %s.\n", client_addr);
......@@ -396,7 +404,7 @@ int connection_send_data(struct connection *conn)
}
}
return 0;
return rc;
}
......@@ -405,12 +413,12 @@ int connection_send_data(struct connection *conn)
* Receives data from him and sends data to him.
*****/
void handle_client(uint32_t event, struct connection *conn)
{
{
int rc;
char *buffer_end;
if (event & EPOLLIN) {
rc = receive_data(conn);
rc = receive_data(conn);
if (rc == -1)
return;
......@@ -426,13 +434,11 @@ void handle_client(uint32_t event, struct connection *conn)
DIE(rc == -1, "w_epoll_update_ptr_out() failed\n");
conn->state = STATE_SENDING_HEADER;
}
if (event & EPOLLOUT) {
rc = connection_send_data(conn);
DIE(rc == -1, "connection_send_data() failed\n");
}
dlog(LOG_INFO, "%d %d\n", (int)conn->send_len, (int)conn->file_size);
}
int main(void)
......@@ -459,7 +465,7 @@ int main(void)
/* Wait for events. */
rc = epoll_wait(epollfd, &recv_ev, 1, -1);
DIE(rc <= 0, "epoll_wait() failed\n");
DIE(rc <= 0, "epoll_wait() failed\n");
/* Switch event type:
* - new connection requests (on server socket)
......@@ -467,19 +473,12 @@ int main(void)
*/
struct connection *conn = (struct connection *)recv_ev.data.ptr;
if (recv_ev.data.fd == listenfd) {
dlog(LOG_INFO, "New connection\n");
if (recv_ev.data.fd == listenfd)
handle_new_connection();
} else if (conn->eventfd >= 0) {
dlog(LOG_INFO, "Finished io asynchronous\n");
conn->state = STATE_SENDING_DATA;
else if (conn->eventfd >= 0)
connection_complete_async_io(conn);
} else {
dlog(LOG_INFO, "Resolve request\n");
dlog(LOG_INFO, "%d %d\n", BUFSIZ, (int)conn->async_read_len);
else
handle_client(recv_ev.events, conn);
}
}
close(listenfd);
......
......@@ -63,7 +63,7 @@ struct connection {
size_t recv_len;
/* Used for sending data (headers, 404 or data populated through async IO). */
char send_buffer[BUFSIZ];
char send_buffer[16 * BUFSIZ];
size_t send_len;
size_t send_pos;
off_t file_pos;
......
......@@ -41,8 +41,6 @@ enum {
fprintf(stderr, " [%s(), %s:%u] " format, \
__func__, __FILE__, __LINE__, \
##__VA_ARGS__)
#else
#define dprintf(format, ...)
#endif
#if defined DEBUG
......@@ -51,8 +49,6 @@ enum {
if (level <= LOG_LEVEL) \
dprintf(format, ##__VA_ARGS__); \
} while (0)
#else
#define dlog(level, format, ...)
#endif
#ifdef __cplusplus
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment