forked from mirrors/treebird
40d411eac2
FossilOrigin-Name: cda981b0d0981fecb211e7119a1eda982891f589a1d7dde5515a7893c1ddba12
145 lines
3.7 KiB
C
145 lines
3.7 KiB
C
/*
|
|
* Treebird - Lightweight frontend for Pleroma
|
|
* Copyright (C) 2022 Nekobit
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "cookie.h"
|
|
#include "key.h"
|
|
|
|
enum cookie_state
|
|
{
|
|
STATE_C_NEUTRAL,
|
|
STATE_C_STARTSP,
|
|
STATE_K_START,
|
|
STATE_V_START,
|
|
};
|
|
|
|
struct cookie_values cookies = { 0 };
|
|
|
|
char* read_cookies_env()
|
|
{
|
|
struct http_cookie_info info;
|
|
char* cookies_env = getenv("HTTP_COOKIE");
|
|
|
|
// Is it even work bothering with?
|
|
if (!cookies_env)
|
|
return NULL;
|
|
|
|
char* cookies_str = malloc(strlen(cookies_env));
|
|
if (!cookies_str)
|
|
{
|
|
perror("malloc");
|
|
return NULL;
|
|
}
|
|
strcpy(cookies_str, cookies_env);
|
|
char* cookies_read = cookies_str;
|
|
|
|
// Will loop through these
|
|
struct key_value_refs refs[] = {
|
|
{ "access_token", &(cookies.access_token) },
|
|
{ "logged_in", &(cookies.logged_in) },
|
|
{ "theme", &(cookies.theme) }
|
|
};
|
|
|
|
do
|
|
{
|
|
cookies_read = parse_cookies(cookies_read, &info);
|
|
|
|
if (!(info.key && info.val)) break;
|
|
for (int i = 0; i < (sizeof(refs)/sizeof(refs[0])); ++i)
|
|
{
|
|
if (strcmp(info.key, refs[i].key) == 0)
|
|
*(refs[i].val) = info.val;
|
|
}
|
|
}
|
|
while (cookies_read);
|
|
|
|
// User is responsible for freeing when done!
|
|
return cookies_str;
|
|
}
|
|
|
|
char* parse_cookies(char* begin, struct http_cookie_info* info)
|
|
{
|
|
int keydone = 0;
|
|
enum cookie_state state = STATE_C_STARTSP;
|
|
int end = 0;
|
|
size_t val_s = 0;
|
|
|
|
for (; *begin != ';' && *begin != '\0'; ++begin)
|
|
{
|
|
switch (*begin)
|
|
{
|
|
case '=':
|
|
if (state == STATE_K_START) keydone = 1;
|
|
state = STATE_C_STARTSP;
|
|
*begin = '\0'; // Null ptr
|
|
break;
|
|
case ' ':
|
|
// longkeyval = res;
|
|
// ^ ^
|
|
if (state == STATE_C_STARTSP ||
|
|
state == STATE_K_START)
|
|
break;
|
|
// fall
|
|
default:
|
|
if (state == STATE_C_STARTSP)
|
|
{
|
|
if (keydone) info->val = begin;
|
|
else info->key = begin;
|
|
state = keydone ? STATE_V_START : STATE_K_START;
|
|
}
|
|
if (keydone) ++val_s;
|
|
}
|
|
}
|
|
|
|
// Which character did we stop at?
|
|
if (*begin == '\0')
|
|
end = 1;
|
|
else if (*begin == ';')
|
|
*begin = '\0';
|
|
|
|
// The val length may be large, so strlen can waste time
|
|
info->val_len = val_s;
|
|
|
|
return end ? NULL : begin+1;
|
|
}
|
|
|
|
int cookie_get_val(char* src, char* key, struct http_cookie_info* info)
|
|
{
|
|
struct http_cookie_info read_info;
|
|
char* src_read = src;
|
|
|
|
while (1)
|
|
{
|
|
src_read = parse_cookies(src_read, &read_info);
|
|
|
|
if (!(read_info.key && read_info.val)) break;
|
|
if (strcmp(read_info.key, key) == 0)
|
|
{
|
|
info->key = read_info.key;
|
|
info->val = read_info.val;
|
|
info->val_len = read_info.val_len;
|
|
return 0;
|
|
}
|
|
|
|
if (!src_read) break;
|
|
}
|
|
|
|
return 1;
|
|
}
|