mirror of
https://git.checksum.fail/alec/erythros
synced 2025-12-10 13:09:55 +02:00
Applications/Internet/Cyberia: Initial support for cookies
This commit is contained in:
@@ -469,6 +469,116 @@ U0 @cyberia_msgbox_error_wrapper(U8* msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
U0 @cyberia_get_key_value(U8* s, U64* key_ptr, U64* value_ptr)
|
||||||
|
{
|
||||||
|
I64 i;
|
||||||
|
I64 len = StrLen(s);
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (!(*key_ptr)) {
|
||||||
|
switch (s[i]) {
|
||||||
|
case ' ':
|
||||||
|
case '\t':
|
||||||
|
case '\r':
|
||||||
|
case '\n':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*key_ptr = s + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (s[i]) {
|
||||||
|
case '=':
|
||||||
|
s[i] = NULL;
|
||||||
|
*value_ptr = s + i + 1;
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
U0 @cyberia_set_cookie_baked(U8* domain, U8* key, U8* value)
|
||||||
|
{
|
||||||
|
if (!cyberia->o("cookies")->@(domain)) {
|
||||||
|
cyberia->o("cookies")->set(domain, Json.CreateObject(erythros_mem_task), JSON_OBJECT);
|
||||||
|
}
|
||||||
|
cyberia->o("cookies")->o(domain)->set(key, value, JSON_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
U0 @cyberia_set_cookie_raw(@browser* browser, U8* s)
|
||||||
|
{
|
||||||
|
// - Parse key=value pairs from value
|
||||||
|
// by default, Set-Cookie or Clear-Site-Data effects domain.tld as well as ...*.*.*.*.domain.tld
|
||||||
|
|
||||||
|
if (!browser || !s || !StrLen(s)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
U8* domain = browser->renderer->current_url->host;
|
||||||
|
|
||||||
|
// A user agent MUST use an algorithm equivalent to the following algorithm to parse a set-cookie-string:
|
||||||
|
|
||||||
|
// If the set-cookie-string contains a %x00-08 / %x0A-1F / %x7F character (CTL characters excluding HTAB):
|
||||||
|
// Abort this algorithm and ignore the set-cookie-string entirely.
|
||||||
|
|
||||||
|
I64 i;
|
||||||
|
I64 len = StrLen(s);
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
switch (s[i]) {
|
||||||
|
case 0x00...0x08:
|
||||||
|
case 0x0a...0x1f:
|
||||||
|
case 0x7f:
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: For now, we are going to ignore unparsed-attributes, and match against domain.tld
|
||||||
|
U8* t = StrFind(";", s);
|
||||||
|
if (t) {
|
||||||
|
*t = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
U64 key = NULL;
|
||||||
|
U64 value = NULL;
|
||||||
|
|
||||||
|
@cyberia_get_key_value(s, &key, &value);
|
||||||
|
|
||||||
|
if (domain && key && value) {
|
||||||
|
@cyberia_set_cookie_baked(domain, key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
U0 @cyberia_set_cookies(@browser* browser, @http_response* resp)
|
||||||
|
{
|
||||||
|
if (!browser || !resp || !browser->renderer || !resp->headers) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
I64 i = 0;
|
||||||
|
U8* value = NULL;
|
||||||
|
JsonArray* a = NULL;
|
||||||
|
JsonKey* keys = resp->headers->keys;
|
||||||
|
while (keys) {
|
||||||
|
if (!StrICmp(keys->name, "set-cookie")) {
|
||||||
|
switch (keys->type) {
|
||||||
|
case JSON_ARRAY:
|
||||||
|
a = keys->value;
|
||||||
|
for (i = 0; i < a->length; i++) {
|
||||||
|
@cyberia_set_cookie_raw(browser, a->@(i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
@cyberia_set_cookie_raw(browser, keys->value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keys = keys->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
U0 @cyberia_navigate(Bool refresh = FALSE)
|
U0 @cyberia_navigate(Bool refresh = FALSE)
|
||||||
{
|
{
|
||||||
win->focused_widget = NULL;
|
win->focused_widget = NULL;
|
||||||
@@ -546,6 +656,10 @@ U0 @cyberia_navigate(Bool refresh = FALSE)
|
|||||||
MemSet(buffer, 0, HTTP_FETCH_BUFFER_SIZE);
|
MemSet(buffer, 0, HTTP_FETCH_BUFFER_SIZE);
|
||||||
|
|
||||||
@http_response* resp = NULL;
|
@http_response* resp = NULL;
|
||||||
|
JsonObject* headers = NULL;
|
||||||
|
U8* domain = renderer->current_url->host;
|
||||||
|
JsonKey* cookie_keys = NULL;
|
||||||
|
U8 cookie_buf[2048];
|
||||||
|
|
||||||
if (!StrCmp(&addressbar1->text, "about:newtab")) {
|
if (!StrCmp(&addressbar1->text, "about:newtab")) {
|
||||||
resp = CAlloc(sizeof(@http_response));
|
resp = CAlloc(sizeof(@http_response));
|
||||||
@@ -556,7 +670,26 @@ U0 @cyberia_navigate(Bool refresh = FALSE)
|
|||||||
StrCpy(&addressbar1->text, "");
|
StrCpy(&addressbar1->text, "");
|
||||||
win->focused_widget = addressbar1;
|
win->focused_widget = addressbar1;
|
||||||
} else {
|
} else {
|
||||||
resp = Http.Get(renderer->current_url, buffer);
|
if (cyberia->o("cookies")->@(domain)) {
|
||||||
|
headers = Json.CreateObject(browser_task);
|
||||||
|
cookie_keys = cyberia->o("cookies")->o(domain)->keys;
|
||||||
|
StrCpy(cookie_buf, "");
|
||||||
|
while (cookie_keys) {
|
||||||
|
StrPrint(cookie_buf + StrLen(cookie_buf), "%s=%s", cookie_keys->name, cookie_keys->value);
|
||||||
|
if (cookie_keys->next) {
|
||||||
|
StrCpy(cookie_buf + StrLen(cookie_buf), "; ");
|
||||||
|
}
|
||||||
|
cookie_keys = cookie_keys->next;
|
||||||
|
}
|
||||||
|
headers->set("Cookie", cookie_buf, JSON_STRING);
|
||||||
|
}
|
||||||
|
if (renderer->form_data_str) {
|
||||||
|
resp = Http.Post(renderer->current_url, buffer, renderer->form_data_str, headers);
|
||||||
|
// FIXME: form_data_str should be freed
|
||||||
|
renderer->form_data_str = NULL;
|
||||||
|
} else {
|
||||||
|
resp = Http.Get(renderer->current_url, buffer, NULL, headers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (resp->state != HTTP_STATE_DONE) {
|
while (resp->state != HTTP_STATE_DONE) {
|
||||||
|
|||||||
Reference in New Issue
Block a user