Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
Assignment Async Web Server
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Darius-Andrei CONSTANTIN
Assignment Async Web Server
Commits
f11a816f
Commit
f11a816f
authored
3 months ago
by
Darius-Andrei CONSTANTIN
Browse files
Options
Downloads
Patches
Plain Diff
Cleaned up code and used commented functions.
Signed-off-by:
Darius Constantin
<
darius.constantin04@stud.acs.upb.ro
>
parent
89de121f
No related branches found
No related tags found
No related merge requests found
Pipeline
#98677
passed
3 months ago
Stage: test
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/aws.c
+70
-77
70 additions, 77 deletions
src/aws.c
with
70 additions
and
77 deletions
src/aws.c
+
70
−
77
View file @
f11a816f
...
...
@@ -23,6 +23,10 @@
#include
"utils/sock_util.h"
#include
"utils/w_epoll.h"
static
const
char
HTTP_HEADER
[]
=
"HTTP/1.0 200 OK
\r\n
Content-Length: %ld
\r\n
Connection: close
\r\n\r\n
"
;
static
const
char
NOT_FOUND
[]
=
"HTTP/1.0 404 Not Found
\r\n\r\n
"
;
/* server socket file descriptor */
static
int
listenfd
;
...
...
@@ -60,20 +64,11 @@ int parse_header(struct connection *conn)
http_parser_init
(
&
conn
->
request_parser
,
HTTP_REQUEST
);
conn
->
request_parser
.
data
=
conn
;
http_parser_execute
(
&
conn
->
request_parser
,
&
settings_on_path
,
conn
->
recv_buffer
,
strlen
(
conn
->
recv_buffer
));
http_parser_execute
(
&
conn
->
request_parser
,
&
settings_on_path
,
conn
->
recv_buffer
,
strlen
(
conn
->
recv_buffer
));
return
0
;
}
//static void connection_prepare_send_reply_header(struct connection *conn)
//{
///* TODO: Prepare the connection buffer to send the reply header. */
//}
//static void connection_prepare_send_404(struct connection *conn)
//{
///* TODO: Prepare the connection buffer to send the 404 header. */
//}
static
enum
resource_type
connection_get_resource_type
(
struct
connection
*
conn
)
{
conn
->
res_type
=
RESOURCE_TYPE_NONE
;
...
...
@@ -84,6 +79,22 @@ static enum resource_type connection_get_resource_type(struct connection *conn)
return
conn
->
res_type
;
}
static
void
connection_prepare_send_reply_header
(
struct
connection
*
conn
)
{
connection_get_resource_type
(
conn
);
conn
->
send_len
=
snprintf
(
conn
->
send_buffer
,
BUFSIZ
,
HTTP_HEADER
,
conn
->
file_size
);
dlog
(
LOG_INFO
,
"Set header with len %zu
\n
"
,
conn
->
send_len
);
conn
->
state
=
STATE_SENDING_HEADER
;
}
static
void
connection_prepare_send_404
(
struct
connection
*
conn
)
{
conn
->
state
=
STATE_SENDING_404
;
strcpy
(
conn
->
send_buffer
,
NOT_FOUND
);
conn
->
send_len
=
strlen
(
NOT_FOUND
);
}
int
connection_open_file
(
struct
connection
*
conn
)
{
struct
stat
stat_buf
;
...
...
@@ -196,12 +207,9 @@ struct connection *connection_create(int sockfd)
void
connection_remove
(
struct
connection
*
conn
)
{
dlog
(
LOG_INFO
,
"Client disconnected1
\n
"
);
DIE
(
w_epoll_remove_ptr
(
epollfd
,
conn
->
sockfd
,
conn
)
<
0
,
"Could not remove sockfd from epoll"
);
dlog
(
LOG_INFO
,
"Client disconnected2
\n
"
);
DIE
(
tcp_close_connection
(
conn
->
sockfd
)
<
0
,
"Could not close connection"
);
dlog
(
LOG_INFO
,
"Client disconnected3
\n
"
);
DIE
(
io_destroy
(
conn
->
ctx
)
!=
0
,
"Could not destroy io ctx"
);
dlog
(
LOG_INFO
,
"Client disconnected
\n
"
);
conn
->
state
=
STATE_CONNECTION_CLOSED
;
...
...
@@ -233,32 +241,51 @@ void receive_data(struct connection *conn)
enum
connection_state
connection_send_static
(
struct
connection
*
conn
)
{
/* TODO: Send static data using sendfile(2). */
return
STATE_NO_STATE
;
}
int
rc
;
int
connection_send_data
(
struct
connection
*
conn
)
{
/* May be used as a helper function. */
/* TODO: Send as much data as possible from the connection send buffer.
* Returns the number of bytes sent or -1 if an error occurred
*/
return
-
1
;
rc
=
sendfile
(
conn
->
sockfd
,
conn
->
fd
,
&
conn
->
file_pos
,
conn
->
file_size
-
conn
->
file_pos
);
if
(
rc
<
0
)
if
(
errno
!=
EAGAIN
)
dlog
(
LOG_ERR
,
"sendfile failed"
);
if
(
conn
->
file_pos
==
conn
->
file_size
)
{
DIE
(
close
(
conn
->
fd
),
"Cannot close fd
\n
"
);
dlog
(
LOG_INFO
,
"Finished sendfile()
\n
"
);
conn
->
state
=
STATE_DATA_SENT
;
}
return
conn
->
state
;
}
int
connection_send_dynamic
(
struct
connection
*
conn
)
{
/* TODO: Read data asynchronously.
* Returns 0 on success and -1 on error.
*/
int
rc
;
rc
=
send
(
conn
->
sockfd
,
conn
->
send_buffer
+
conn
->
send_pos
,
conn
->
send_len
-
conn
->
send_pos
,
0
);
if
(
rc
<
0
)
{
if
(
errno
!=
EAGAIN
&&
errno
!=
EWOULDBLOCK
)
{
dlog
(
LOG_ERR
,
"send failed"
);
return
-
1
;
}
}
else
{
conn
->
send_pos
+=
rc
;
}
dlog
(
LOG_INFO
,
"Sending from send_buffer (with offset %zu): %zu bytes
\n
"
,
conn
->
send_pos
,
conn
->
send_len
-
conn
->
send_pos
);
if
(
conn
->
send_pos
==
conn
->
send_len
)
{
conn
->
async_read_len
+=
conn
->
send_len
;
dlog
(
LOG_INFO
,
"Finished sending dynamic file segment
\n
"
);
if
(
conn
->
async_read_len
==
conn
->
file_size
)
{
conn
->
state
=
STATE_DATA_SENT
;
dlog
(
LOG_INFO
,
"Finished sending dynamic file fully
\n
"
);
DIE
(
close
(
conn
->
fd
),
"Cannot close fd
\n
"
);
}
else
{
connection_start_async_io
(
conn
);
}
}
return
0
;
}
static
const
char
HTTP_HEADER
[]
=
"HTTP/1.0 200 OK
\r\n
Content-Length: %ld
\r\n
Connection: close
\r\n\r\n
"
;
static
const
char
NOT_FOUND
[]
=
"HTTP/1.0 404 Not Found
\r\n\r\n
"
;
void
handle_input
(
struct
connection
*
conn
)
{
switch
(
conn
->
state
)
{
...
...
@@ -282,24 +309,17 @@ void handle_output(struct connection *conn)
case
STATE_REQUEST_RECEIVED
:
parse_header
(
conn
);
rc
=
connection_open_file
(
conn
);
if
(
rc
>=
0
)
{
connection_get_resource_type
(
conn
);
conn
->
send_len
=
snprintf
(
conn
->
send_buffer
,
BUFSIZ
,
HTTP_HEADER
,
conn
->
file_size
);
dlog
(
LOG_INFO
,
"Set header with len %zu
\n
"
,
conn
->
send_len
);
conn
->
state
=
STATE_SENDING_HEADER
;
}
else
{
conn
->
state
=
STATE_SENDING_404
;
strcpy
(
conn
->
send_buffer
,
NOT_FOUND
);
conn
->
send_len
=
strlen
(
NOT_FOUND
);
}
if
(
rc
>=
0
)
connection_prepare_send_reply_header
(
conn
);
else
connection_prepare_send_404
(
conn
);
break
;
case
STATE_SENDING_HEADER
:
rc
=
send
(
conn
->
sockfd
,
conn
->
send_buffer
+
conn
->
send_pos
,
conn
->
send_len
-
conn
->
send_pos
,
0
);
if
(
rc
<
0
)
{
if
(
errno
!=
EAGAIN
&&
errno
!=
EWOULDBLOCK
)
DIE
(
rc
<
-
1
,
"Could not send header"
);
dlog
(
LOG_ERR
,
"Could not send header"
);
}
else
{
conn
->
send_pos
+=
rc
;
if
(
conn
->
send_pos
==
conn
->
send_len
)
{
...
...
@@ -310,7 +330,8 @@ void handle_output(struct connection *conn)
connection_start_async_io
(
conn
);
break
;
case
RESOURCE_TYPE_STATIC
:
dlog
(
LOG_INFO
,
"Finished sending header:
\n
%s"
,
conn
->
send_buffer
);
dlog
(
LOG_INFO
,
"Finished sending header:
\n
%s"
,
conn
->
send_buffer
);
conn
->
state
=
STATE_SENDING_DATA
;
break
;
default:
...
...
@@ -328,39 +349,10 @@ void handle_output(struct connection *conn)
case
STATE_SENDING_DATA
:
switch
(
conn
->
res_type
)
{
case
RESOURCE_TYPE_DYNAMIC
:
rc
=
send
(
conn
->
sockfd
,
conn
->
send_buffer
+
conn
->
send_pos
,
conn
->
send_len
-
conn
->
send_pos
,
0
);
if
(
rc
<
0
)
{
if
(
errno
!=
EAGAIN
&&
errno
!=
EWOULDBLOCK
)
DIE
(
rc
<
0
,
"send failed"
);
}
else
{
conn
->
send_pos
+=
rc
;
}
dlog
(
LOG_INFO
,
"Sending from send_buffer (with offset %zu): %zu bytes
\n
"
,
conn
->
send_pos
,
conn
->
send_len
-
conn
->
send_pos
);
if
(
conn
->
send_pos
==
conn
->
send_len
)
{
conn
->
async_read_len
+=
conn
->
send_len
;
dlog
(
LOG_INFO
,
"Finished sending dynamic file segment
\n
"
);
if
(
conn
->
async_read_len
==
conn
->
file_size
)
{
conn
->
state
=
STATE_DATA_SENT
;
dlog
(
LOG_INFO
,
"Finished sending dynamic file fully
\n
"
);
close
(
conn
->
fd
);
}
else
{
connection_start_async_io
(
conn
);
}
}
connection_send_dynamic
(
conn
);
break
;
case
RESOURCE_TYPE_STATIC
:
rc
=
sendfile
(
conn
->
sockfd
,
conn
->
fd
,
&
conn
->
file_pos
,
conn
->
file_size
-
conn
->
file_pos
);
if
(
rc
<
0
)
if
(
errno
!=
EAGAIN
)
DIE
(
1
,
"sendfile failed"
);
if
(
conn
->
file_pos
==
conn
->
file_size
)
{
DIE
(
close
(
conn
->
fd
),
"Cannot close fd
\n
"
);
dlog
(
LOG_INFO
,
"Finished sendfile()
\n
"
);
conn
->
state
=
STATE_DATA_SENT
;
}
connection_send_static
(
conn
);
break
;
default:
DIE
(
1
,
"Could not figure out resource type"
);
...
...
@@ -403,7 +395,8 @@ int main(void)
rc
=
w_epoll_add_fd_in
(
epollfd
,
listenfd
);
DIE
(
rc
<
0
,
"w_epoll_add_fd_in failed"
);
dlog
(
LOG_INFO
,
"Server waiting for connections on port %d
\n
"
,
AWS_LISTEN_PORT
);
dlog
(
LOG_INFO
,
"Server waiting for connections on port %d
\n
"
,
AWS_LISTEN_PORT
);
/* server main loop */
while
(
1
)
{
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment