From 269ac0c501d951e372d2e428d83be8e6275071c7 Mon Sep 17 00:00:00 2001 From: Felicia Seo Date: Sun, 11 Dec 2022 19:10:09 -0500 Subject: [PATCH] comments --- src/http.c | 52 +++++++++++++++++++++++++++++++++++++--------------- src/http.h | 9 ++++----- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/http.c b/src/http.c index 694b2b0..274f924 100644 --- a/src/http.c +++ b/src/http.c @@ -118,35 +118,45 @@ http_process_headers(struct http_transaction *ta) ta->req_content_len = atoi(field_value); } - ta->valid_token = false; // special case? + ta->valid_token = false; /* Handle other headers here. Both field_value and field_name * are zero-terminated strings. */ + + // Cookie header if (!strcasecmp(field_name, "Cookie")) { + // Gets the cookies. char* cookie2; char* cookie1 = strtok_r(field_value, ";", &cookie2); cookie2++; + // Stores the 2nd cookie. ta->extra_cookie = cookie2; + // Determines if the 1st cookie is invalid. if ((cookie1 == NULL) || (strlen(cookie1) <= 11)) { ta->resp_status = HTTP_PERMISSION_DENIED; return false; } - ta->token = cookie1 + 11; // + 11 gets rid of "auth_token=" heading. + // If not, find token. + ta->token = cookie1 + 11; // + 11 gets rid of "auth_token=" heading. ta->valid_token = validate_token_exp(ta, ta->token); } + // Range header if (!strcasecmp(field_name, "Range")){ + // Gets token. char *endp; char *token = strtok_r(field_value, "= ", &endp); while (token != NULL && strcasecmp(token, "bytes")) { token = strtok_r(NULL, "= ", &endp); } token = strtok_r(NULL, "= ", &endp); + + // Determines if the token exist. if (token != NULL) { if (token[0] == '-') { ta->to = atol(token + 1); @@ -361,8 +371,6 @@ bool validate_token_exp(struct http_transaction *ta, char* token) { const char *sub; json_unpack(jgrants, "{s:I, s:I, s:s}", "exp", &exp, "iat", &iat, "sub", &sub); - ta->exp = exp; - // Check expiration time. if (time(NULL) >= exp) return false; @@ -463,12 +471,14 @@ out: return success; } +/* Handles api/login POST */ static bool post_handle_login(struct http_transaction *ta) { http_add_header(&ta->resp_headers, "Content-Type", "application/json"); char* req_body = bufio_offset2ptr(ta->client->bufio, ta->req_body); + // Gets the username and password. req_body[ta->req_content_len] = '\0'; json_error_t error; json_t *jgrants = json_loadb(req_body, strlen(req_body), 0, &error); @@ -480,6 +490,7 @@ post_handle_login(struct http_transaction *ta) return send_error(ta, HTTP_PERMISSION_DENIED, "???"); } + // Authenticates the username and password. if (!strcmp(username, "user0") && !strcmp(password, "thepassword")) { int iat = time(NULL); @@ -527,21 +538,22 @@ post_handle_login(struct http_transaction *ta) return send_response(ta); } - return send_error(ta, HTTP_PERMISSION_DENIED, "???"); + return send_error(ta, HTTP_PERMISSION_DENIED, "Permission denied"); } - +/* Handles api/login GET */ static bool get_handle_login(struct http_transaction *ta) { http_add_header(&ta->resp_headers, "Content-Type", "application/json"); + // Determines if the token is invalid. if (!ta->valid_token) { buffer_appends(&ta->resp_body, "{}"); ta->resp_status = HTTP_OK; return send_response(ta); } + // If not, send response. buffer_appends(&ta->resp_body, ta->grants); - ta->resp_status = HTTP_OK; return send_response(ta); } @@ -585,7 +597,7 @@ static char *list_videos(DIR* dir) { return json_dumps(list, 0); } - +/* Determines what the API request is. */ static int val_api_url(struct http_transaction *ta) { char *req_path = bufio_offset2ptr(ta->client->bufio, ta->req_path); if (!strcmp(req_path, "/api/login")) { @@ -600,6 +612,8 @@ static int val_api_url(struct http_transaction *ta) { return -1; } + +/* Handles API requests like login/logout/video. */ static bool handle_api(struct http_transaction *ta) { @@ -609,6 +623,7 @@ handle_api(struct http_transaction *ta) return send_not_found(ta); } + // API login if (val == 0) { if (ta->req_method == HTTP_POST) { // Handle login post @@ -625,24 +640,26 @@ handle_api(struct http_transaction *ta) } } + // API video if (val == 1) { http_add_header(&ta->resp_headers, "Accept-Ranges", "bytes"); + DIR* dir = opendir(server_root); - char *json = list_videos(dir); + char *json = list_videos(dir); // handling fprintf(stderr, "json: %s\n", json); http_add_header(&ta->resp_headers, "Content-Type", "application/json"); - + // Ensures response can be sent and sends it. char *body = buffer_ensure_capacity(&ta->resp_body, MAX_HEADER_LEN); int len = snprintf(body, strlen(json) + 2, "%s\n", json); int length = len > MAX_HEADER_LEN ? MAX_HEADER_LEN - 1 : len; ta->resp_body.len += length; ta->resp_status = HTTP_OK; - return send_response(ta); } - if (val == 2) // handles logout + // API logout + if (val == 2) { // Add Set-Cookie header. http_add_header(&ta->resp_headers, "Set-Cookie", "auth_token=; Path=/; Max-Age=0; HttpOnly"); @@ -664,28 +681,33 @@ http_setup_client(struct http_client *self, struct bufio *bufio) self->bufio = bufio; } +/* Handles attempts to access private files. */ static bool handle_private(struct http_transaction *ta) { + // Determines if the token from the 1st cookie is valid. if (ta->valid_token) { ta->resp_status = HTTP_OK; return handle_static_asset(ta, server_root); } - + // Determines if there's a 2nd cookie. if ((ta->extra_cookie == NULL) || (strlen(ta->extra_cookie) <= 11)) { - return send_error(ta, HTTP_PERMISSION_DENIED, "???"); + return send_error(ta, HTTP_PERMISSION_DENIED, "Permission denied."); } + // If so, find its token. ta->token = ta->extra_cookie + 11; // + 11 gets rid of "auth_token=" heading. ta->valid_token = validate_token_exp(ta, ta->token); + // valid if (ta->valid_token) { ta->resp_status = HTTP_OK; return handle_static_asset(ta, server_root); } - return send_error(ta, HTTP_PERMISSION_DENIED, "???"); + // invalid + return send_error(ta, HTTP_PERMISSION_DENIED, "Permission denied."); } /* Handle a single HTTP transaction. Returns true on success. */ diff --git a/src/http.h b/src/http.h index e79b99f..8810733 100644 --- a/src/http.h +++ b/src/http.h @@ -40,12 +40,11 @@ struct http_transaction { size_t req_body; // ditto int req_content_len; // content length of request body - char* extra_cookie; + char* extra_cookie; // the 2nd cookie if it exists. - char *token; // authentication token - bool valid_token; - long exp; - char* grants; + char *token; // authentication token + bool valid_token; // true if valid, false if not. + char* grants; // exp, iat, sub /* response related fields */ enum http_response_status resp_status;