Everywhere: Make session->header() callable

This commit is contained in:
Alec Murphy 2025-02-19 21:53:31 -05:00
parent 0960af9aef
commit 71c8db66f1
7 changed files with 62 additions and 29 deletions

View file

@ -57,7 +57,7 @@ U0 @slon_api_v1_statuses_post(SlonHttpSession* session)
SLON_AUTH_ACCOUNT_ID
Bool idempotency_key_already_seen = FALSE;
U8* idempotency_key = @slon_http_request_header(session, "idempotency-key");
U8* idempotency_key = session->header("idempotency-key");
if (StrLen(idempotency_key) > 0 && db->o("idempotency_keys")->@(idempotency_key)) {
idempotency_key_already_seen = TRUE;
}

View file

@ -1,4 +1,4 @@
if (String.BeginsWith("/users/", @slon_http_request_path(session)) && String.EndsWith("json", @slon_http_request_header(session, "accept"))) {
if (String.BeginsWith("/users/", @slon_http_request_path(session)) && String.EndsWith("json", session->header("accept"))) {
@slon_activitypub_users_get(session);
return;
}

View file

@ -285,7 +285,7 @@ U0 @slon_admin_server_get(SlonHttpSession* session)
if (!db->@("setup")) {
if (StrICmp("/", @slon_http_request_path(session))) {
session->status(302);
@slon_http_set_header(session, "Location", "/");
session->header("Location", "/");
} else {
@slon_http_send_html_file(session, "M:/Slon/Static/html/admin/setup_instance.html");
}
@ -335,7 +335,7 @@ U0 @slon_admin_setup_instance(SlonHttpSession* session)
U0 @slon_admin_server_post(SlonHttpSession* session)
{
if (StrFind("json", @slon_http_request_header(session, "content-type")) > 0) {
if (StrFind("json", session->header("content-type")) > 0) {
@slon_http_parse_request_as_json(session);
}
@ -402,8 +402,8 @@ U0 @slon_admin_http_task(TcpSocket* s)
}
// If we have a content-length header, consume until we receive all the data, then set request->data pointer and size
if (StrLen(@slon_http_request_header(session, "content-length"))) {
I64 content_length = Str2I64(@slon_http_request_header(session, "content-length"));
if (StrLen(session->header("content-length"))) {
I64 content_length = Str2I64(session->header("content-length"));
while (session->request->buffer->data + session->request->buffer->size - session->request->data < content_length)
@slon_http_receive(session);
}

View file

@ -164,7 +164,7 @@ U0 @slon_local_server_get(SlonHttpSession* session)
if (IsDir(scratch_buffer)) {
session->status(301);
StrPrint(scratch_buffer, "%s/", path);
@slon_http_set_header(session, "Location", scratch_buffer);
session->header("Location", scratch_buffer);
} else {
@slon_local_server_send_file(session, scratch_buffer);
}
@ -214,8 +214,8 @@ U0 @slon_local_http_task(TcpSocket* s)
}
// If we have a content-length header, consume until we receive all the data, then set request->data pointer and size
if (StrLen(@slon_http_request_header(session, "content-length"))) {
I64 content_length = Str2I64(@slon_http_request_header(session, "content-length"));
if (StrLen(session->header("content-length"))) {
I64 content_length = Str2I64(session->header("content-length"));
while (session->request->buffer->data + session->request->buffer->size - session->request->data < content_length)
@slon_http_receive(session);
}

View file

@ -43,6 +43,7 @@ U0 @slon_http_free_session(SlonHttpSession* session)
@slon_http_free_response(session, session->response);
@slon_http_free_request(session, session->request);
I64 bytes_used = session->bytes_used - MSize2(session);
Free(session->header);
Free(session->status);
Free(session);
if (bytes_used) {
@ -84,6 +85,23 @@ SlonHttpSession* @slon_http_init_session(TcpSocket* s)
a += 0x10;
MemSetI64(a, session, 1);
// Create a copy of function and patch header
code_size = MSize(&@slon_session_header_wrapper_function);
session->header = CAlloc(code_size, adam_task->code_heap);
MemCpy(session->header, &@slon_session_header_wrapper_function, code_size);
a = session->header;
a += 0x16;
MemSetI64(a, session, 1);
a = session->header;
a += 0x26;
@patch_call_rel32(a, &@slon_http_request_header);
a = session->header;
a += 0x31;
@patch_call_rel32(a, &@slon_http_set_header);
return session;
}
@ -215,8 +233,8 @@ slon_http_parse_request_headers:
U0 @slon_http_authorize(SlonHttpSession* session)
{
if (StrLen(@slon_http_request_header(session, "authorization"))) {
U8* access_token = StrFind(" ", @slon_http_request_header(session, "authorization")) + 1;
if (StrLen(session->header("authorization"))) {
U8* access_token = StrFind(" ", session->header("authorization")) + 1;
session->auth = db->o("oauth")->o("tokens")->@(access_token);
}
}
@ -283,7 +301,7 @@ U8* @slon_http_json_string_from_multipart_form_data(SlonHttpSession* session, U8
String.Append(json_string, "{");
U8* multipart_form_data_copy = @slon_strnew(session, multipart_form_data);
U8* boundary = StrFind("boundary=", @slon_http_request_header(session, "content-type")) + 9;
U8* boundary = StrFind("boundary=", session->header("content-type")) + 9;
// Strip begin double-quotes and ending CRLF, double-quotes
while (boundary[0] == '"')
boundary++;
@ -430,13 +448,13 @@ U0 @slon_http_handle_get_request(SlonHttpSession* session)
U0 @slon_http_handle_patch_request(SlonHttpSession* session)
{
if (StrFind("json", @slon_http_request_header(session, "content-type")) > 0) {
if (StrFind("json", session->header("content-type")) > 0) {
@slon_http_parse_request_as_json(session);
}
if (String.BeginsWith("application/x-www-form-urlencoded", @slon_http_request_header(session, "content-type"))) {
if (String.BeginsWith("application/x-www-form-urlencoded", session->header("content-type"))) {
@slon_http_parse_request_as_form_urlencoded(session);
}
if (String.BeginsWith("multipart/form-data", @slon_http_request_header(session, "content-type"))) {
if (String.BeginsWith("multipart/form-data", session->header("content-type"))) {
@slon_http_parse_request_as_multipart_form_data(session);
}
@ -453,17 +471,17 @@ U0 @slon_http_handle_patch_request(SlonHttpSession* session)
U0 @slon_http_handle_post_request(SlonHttpSession* session)
{
if (StrFind("json", @slon_http_request_header(session, "content-type")) > 0) {
if (StrFind("json", session->header("content-type")) > 0) {
@slon_http_parse_request_as_json(session);
}
if (String.BeginsWith("application/x-www-form-urlencoded", @slon_http_request_header(session, "content-type"))) {
if (String.BeginsWith("application/x-www-form-urlencoded", session->header("content-type"))) {
@slon_http_parse_request_as_form_urlencoded(session);
}
if (String.BeginsWith("multipart/form-data", @slon_http_request_header(session, "content-type"))) {
if (String.BeginsWith("multipart/form-data", session->header("content-type"))) {
@slon_http_parse_request_as_multipart_form_data(session);
}
// Workaround for IceCubesApp: https://github.com/Dimillian/IceCubesApp/issues/2235
if (!StrLen(@slon_http_request_header(session, "content-type")) && @slon_http_request_has_query_string(session)) {
if (!StrLen(session->header("content-type")) && @slon_http_request_has_query_string(session)) {
@slon_http_parse_query_string(session);
}
@ -533,8 +551,8 @@ U0 @slon_http_task(TcpSocket* s)
//@slon_http_debug_print_request(session, FALSE);
// If we have a content-length header, consume until we receive all the data, then set request->data pointer and size
if (StrLen(@slon_http_request_header(session, "content-length"))) {
I64 content_length = Str2I64(@slon_http_request_header(session, "content-length"));
if (StrLen(session->header("content-length"))) {
I64 content_length = Str2I64(session->header("content-length"));
while (session->request->buffer->data + session->request->buffer->size - session->request->data < content_length)
@slon_http_receive(session);
}

View file

@ -13,19 +13,19 @@ Bool @slon_activitypub_http_signature_is_valid(SlonHttpSession* session)
no_warn scratch_buffer;
// 1. Check that we have a signature and digest
if (!StrLen(@slon_http_request_header(session, "signature")) || !StrLen(@slon_http_request_header(session, "digest"))) {
if (!StrLen(session->header("signature")) || !StrLen(session->header("digest"))) {
AdamLog("[verify_signature] no signature or digest header present\n");
return FALSE;
}
// 2. Check that digest 1) is SHA-256 and 2) matches content
U8* request_digest = @slon_http_request_header(session, "digest");
U8* request_digest = session->header("digest");
if (!(String.BeginsWith("SHA-256", request_digest) || String.BeginsWith("sha-256", request_digest))) {
AdamLog("[verify_signature] digest is not SHA-256\n");
return FALSE;
}
request_digest = StrFind("=", request_digest) + 1;
I64 content_length = Str2I64(@slon_http_request_header(session, "content-length"));
I64 content_length = Str2I64(session->header("content-length"));
if (!content_length) {
AdamLog("[verify_signature] content-length is 0\n");
return FALSE;
@ -44,7 +44,7 @@ Bool @slon_activitypub_http_signature_is_valid(SlonHttpSession* session)
}
// Parse values from Signature header
U8* signature_header = @slon_http_request_header(session, "signature");
U8* signature_header = session->header("signature");
I64 signature_fragment_count = 0;
U8** signature_fragments = String.Split(signature_header, ',', &signature_fragment_count);
@ -192,7 +192,7 @@ Bool @slon_activitypub_http_signature_is_valid(SlonHttpSession* session)
U8** headers_split = String.Split(headers, ' ', &headers_split_count);
i = 0;
while (i < headers_split_count) {
sig_string_alloc_length += StrLen(@slon_http_request_header(session, headers_split[i]));
sig_string_alloc_length += StrLen(session->header(headers_split[i]));
++i;
}
sig_string_alloc_length += StrLen(@slon_http_request_verb(session));
@ -209,7 +209,7 @@ Bool @slon_activitypub_http_signature_is_valid(SlonHttpSession* session)
if (!StrCmp("(request-target)", headers_split[i])) {
String.Append(sig_string, "(request-target): %s %s", "post", @slon_http_request_path(session));
} else {
String.Append(sig_string, "%s: %s", headers_split[i], @slon_http_request_header(session, headers_split[i]));
String.Append(sig_string, "%s: %s", headers_split[i], session->header(headers_split[i]));
}
++i;
if (i < headers_split_count) {

View file

@ -63,6 +63,7 @@ class SlonHttpSession {
JsonObject* auth;
U8* actor_for_key_id;
U8* (*header)(U8* key, U8* value = NULL);
I64 (*status)(I64 code = NULL);
};
@ -148,12 +149,16 @@ JsonObject* @slon_http_request_json(SlonHttpSession* session)
U0 @slon_http_set_header(SlonHttpSession* session, U8* key, U8* value)
{
Json.Set(session->response->headers, key, value, JSON_STRING);
if (!StrICmp(value, "")) {
Json.Unset(session->response->headers, key);
} else {
Json.Set(session->response->headers, key, value, JSON_STRING);
}
}
U0 @slon_http_set_content_type(SlonHttpSession* session, U8* value)
{
@slon_http_set_header(session, "content-type", value);
session->header("content-type", value);
}
U0 @slon_http_send_ap_json(SlonHttpSession* session, U64 json)
@ -263,3 +268,13 @@ I64 @slon_session_status_wrapper_function(I64 code)
}
return session->response->status_code;
}
U8* @slon_session_header_wrapper_function(U8* key, U8* value = NULL)
{
SlonHttpSession* session = SLON_WRAPPER_MAGIC_NUMBER;
if (!value) {
return @slon_http_request_header(session, key);
}
@slon_http_set_header(session, key, value);
return value;
}