Merge pull request #358 from gwsystems/fix-http-session-state-machine

fix: correct HTTP session state machine
master
Sean McBride 2 years ago committed by GitHub
commit 2d35778c9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -35,9 +35,10 @@ enum http_session_state
HTTP_SESSION_EXECUTION_COMPLETE,
HTTP_SESSION_SENDING_RESPONSE_HEADER,
HTTP_SESSION_SEND_RESPONSE_HEADER_BLOCKED,
HTTP_SESSION_SENDING_RESPONSE,
HTTP_SESSION_SEND_RESPONSE_BLOCKED,
HTTP_SESSION_SENT_RESPONSE
HTTP_SESSION_SENT_RESPONSE_HEADER,
HTTP_SESSION_SENDING_RESPONSE_BODY,
HTTP_SESSION_SEND_RESPONSE_BODY_BLOCKED,
HTTP_SESSION_SENT_RESPONSE_BODY
};
struct http_session {
@ -209,6 +210,9 @@ static inline int
http_session_send_response_header(struct http_session *session, void_star_cb on_eagain)
{
assert(session != NULL);
assert(session->state == HTTP_SESSION_EXECUTION_COMPLETE
|| session->state == HTTP_SESSION_SEND_RESPONSE_HEADER_BLOCKED);
session->state = HTTP_SESSION_SENDING_RESPONSE_HEADER;
while (session->response_header_length > session->response_header_written) {
ssize_t sent =
@ -223,6 +227,8 @@ http_session_send_response_header(struct http_session *session, void_star_cb on_
}
}
session->state = HTTP_SESSION_SENT_RESPONSE_HEADER;
return 0;
}
@ -237,6 +243,10 @@ http_session_send_response_body(struct http_session *session, void_star_cb on_ea
{
assert(session != NULL);
assert(session->state == HTTP_SESSION_SENT_RESPONSE_HEADER
|| session->state == HTTP_SESSION_SEND_RESPONSE_BODY_BLOCKED);
session->state = HTTP_SESSION_SENDING_RESPONSE_BODY;
while (session->response_buffer_written < session->response_buffer.length) {
ssize_t sent =
tcp_session_send(session->socket,
@ -250,6 +260,7 @@ http_session_send_response_body(struct http_session *session, void_star_cb on_ea
}
}
session->state = HTTP_SESSION_SENT_RESPONSE_BODY;
return 0;
}
@ -458,6 +469,8 @@ DONE:
static inline void
http_session_send_response(struct http_session *session, void_star_cb on_eagain)
{
assert(session->state == HTTP_SESSION_EXECUTION_COMPLETE);
int rc = http_session_send_response_header(session, on_eagain);
/* session blocked and registered to epoll so continue to next handle */
if (unlikely(rc == -EAGAIN)) {
@ -466,6 +479,8 @@ http_session_send_response(struct http_session *session, void_star_cb on_eagain)
goto CLOSE;
}
assert(session->state == HTTP_SESSION_SENT_RESPONSE_HEADER);
rc = http_session_send_response_body(session, on_eagain);
/* session blocked and registered to epoll so continue to next handle */
if (unlikely(rc == -EAGAIN)) {
@ -474,6 +489,8 @@ http_session_send_response(struct http_session *session, void_star_cb on_eagain)
goto CLOSE;
}
assert(session->state == HTTP_SESSION_SENT_RESPONSE_BODY);
/* Terminal State Logging for Http Session */
session->response_sent_timestamp = __getcycles();
http_session_perf_log_print_entry(session);

@ -83,9 +83,9 @@ listener_thread_register_http_session(struct http_session *http)
accept_evt.events = EPOLLOUT;
http->state = HTTP_SESSION_SEND_RESPONSE_HEADER_BLOCKED;
break;
case HTTP_SESSION_SENDING_RESPONSE:
case HTTP_SESSION_SENDING_RESPONSE_BODY:
accept_evt.events = EPOLLOUT;
http->state = HTTP_SESSION_SEND_RESPONSE_BLOCKED;
http->state = HTTP_SESSION_SEND_RESPONSE_BODY_BLOCKED;
break;
default:
panic("Invalid HTTP Session State: %d\n", http->state);
@ -251,9 +251,6 @@ on_client_request_received(struct http_session *session)
static void
on_client_response_header_sending(struct http_session *session)
{
assert(session->state = HTTP_SESSION_EXECUTION_COMPLETE);
session->state = HTTP_SESSION_SENDING_RESPONSE_HEADER;
int rc = http_session_send_response_header(session, (void_star_cb)listener_thread_register_http_session);
if (likely(rc == 0)) {
on_client_response_body_sending(session);
@ -289,6 +286,8 @@ on_client_response_body_sending(struct http_session *session)
static void
on_client_response_sent(struct http_session *session)
{
assert(session->state = HTTP_SESSION_SENT_RESPONSE_BODY);
/* Terminal State Logging for Http Session */
session->response_sent_timestamp = __getcycles();
http_session_perf_log_print_entry(session);
@ -343,7 +342,7 @@ on_client_socket_epoll_event(struct epoll_event *evt)
assert((evt->events & EPOLLOUT) == EPOLLOUT);
on_client_response_header_sending(session);
break;
case HTTP_SESSION_SEND_RESPONSE_BLOCKED:
case HTTP_SESSION_SEND_RESPONSE_BODY_BLOCKED:
assert((evt->events & EPOLLOUT) == EPOLLOUT);
on_client_response_body_sending(session);
break;

Loading…
Cancel
Save