Useful extensions for the tpee library
git clone git://soophie.de/tpee_ext
blob: 63453fb676806b41d9184a868888c909ddf17bb5 (6358 bytes)[raw]
1
/*2
* Copyright (C) 2026 Sophie Sitzler3
*4
* This program is free software: you can redistribute it and/or modify5
* it under the terms of the GNU General Public License as published by6
* the Free Software Foundation, either version 3 of the License, or7
* (at your option) any later version.8
*9
* This program is distributed in the hope that it will be useful,10
* but WITHOUT ANY WARRANTY; without even the implied warranty of11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12
* GNU General Public License for more details.13
*14
* You should have received a copy of the GNU General Public License15
* along with this program. If not, see <https://www.gnu.org/licenses/>.16
*/18
// @file tpee_ext.h19
#pragma once21
// @include <tpee.h>22
// @desc tpee library handling HTTP communication.23
#include <tpee.h>25
char *tpee_ext_detect_mime_type(char *filename);26
tpee_resp_t tpee_ext_serve_page(char *filename);27
tpee_resp_t tpee_ext_serve_file(char *filename);28
bool tpee_ext_is_path_match(char *path, char *label);29
char *tpee_ext_get_path_var(char *path, char *label, char *key);31
#ifdef TPEE_EXT_IMPL33
#include <ctype.h>35
static int _tpee_ext_read_file(char *filename, char **bytes) {36
FILE *fp = fopen(filename, "rb");37
if (fp == NULL) {38
return -1;39
}40
fseek(fp, 0, SEEK_END);41
long len = ftell(fp);42
fseek(fp, 0, SEEK_SET);43
*bytes = realloc(*bytes, sizeof(char) * len);44
fread(*bytes, len, sizeof(char), fp);45
fclose(fp);46
return len;47
}49
static char *_tpee_ext_read_text_file(char *filename) {50
FILE *fp = fopen(filename, "r");51
if (fp == NULL) {52
return NULL;53
}54
fseek(fp, 0, SEEK_END);55
long len = ftell(fp);56
fseek(fp, 0, SEEK_SET);57
char *content = malloc(sizeof(char) * (len + 1));58
fread(content, len, sizeof(char), fp);59
content[len] = '\0';60
fclose(fp);61
return content;62
}64
char *tpee_ext_detect_mime_type(char *filename) {65
int i = strlen(filename);66
for (; i >= 0; i--) {67
if (filename[i] == '.') {68
break;69
}70
}71
char *filename_ext = filename + i + 1;72
if (strcmp(filename_ext, "css") == 0) {73
return "text/css";74
}75
if (strcmp(filename_ext, "js") == 0) {76
return "text/javascript";77
}78
if (strcmp(filename_ext, "png") == 0) {79
return "image/png";80
}81
if (strcmp(filename_ext, "jpg") == 0) {82
return "image/jpg";83
}84
if (strcmp(filename_ext, "json") == 0) {85
return "application/json";86
}87
if (strcmp(filename_ext, "wasm") == 0) {88
return "application/wasm";89
}90
if (strcmp(filename_ext, "svg") == 0) {91
return "image/svg+xml";92
}93
return NULL;94
}96
tpee_resp_t tpee_ext_serve_page(char *filename) {97
char *html = _tpee_ext_read_text_file(filename);98
tpee_resp_t rsp = tpee_resp_create(TPEE_STATUS_OK);99
tpee_resp_header(&rsp, "Content-Type", "text/html");100
tpee_resp_body(&rsp, html, strlen(html));101
free(html);102
return rsp;103
}105
tpee_resp_t tpee_ext_serve_file(char *filename) {106
char *bytes = NULL;107
int len = _tpee_ext_read_file(filename, &bytes);108
if (len == -1) {109
return tpee_resp_create(TPEE_STATUS_NOT_FOUND);110
}111
tpee_resp_t resp = tpee_resp_create(TPEE_STATUS_OK);112
char *filetype = tpee_ext_detect_mime_type(filename);113
if (filetype != NULL) {114
tpee_resp_header(&resp, "Content-Type", filetype);115
}116
tpee_resp_body(&resp, bytes, len);117
free(bytes);118
return resp;119
}121
bool tpee_ext_is_path_match(char *path, char *label) {122
bool is_var = false;123
size_t len = strlen(label);124
size_t var_len = 0;125
size_t idx = 0;126
size_t i = 0;127
size_t path_len = strcspn(path, "?");128
for (; i < path_len; i++) {129
char c = path[i];130
if (!is_var && label[idx] == '{') {131
is_var = true;132
var_len = 0;133
}134
if (is_var) {135
if (!(isalpha(c) || isdigit(c) || c == '-' || c == '_')) {136
is_var = false;137
if (var_len == 0) {138
return false;139
}140
for (; idx < len; idx++) {141
if (label[idx] == '}') {142
idx++;143
break;144
}145
}146
if (c != label[idx]) {147
return false;148
}149
idx++;150
}151
else {152
var_len++;153
}154
}155
else {156
if (c != label[idx]) {157
return false;158
}159
idx++;160
}161
}162
if (is_var) {163
for (; idx < len; idx++) {164
if (label[idx] == '}') {165
idx++;166
break;167
}168
}169
if (var_len == 0) {170
return false;171
}172
is_var = false;173
}174
if (idx != len) {175
return false;176
}177
if (i != path_len) {178
return false;179
}180
return true;181
}183
char *tpee_ext_get_path_var(char *path, char *label, char *key) {184
bool is_var = false;185
size_t len = strlen(label);186
size_t var_len = 0;187
size_t idx = 0;188
size_t i = 0;189
for (; i < strlen(path); i++) {190
char c = path[i];191
if (!is_var && label[idx] == '{') {192
is_var = true;193
var_len = 0;194
}195
if (is_var) {196
if (!(isalpha(c) || isdigit(c) || c == '-' || c == '_')) {197
is_var = false;198
size_t set = idx + 1;199
for (; idx < len; idx++) {200
if (label[idx] == '}') {201
idx++;202
break;203
}204
}205
if (var_len == 0) {206
return NULL;207
}208
size_t name_len = idx - set - 1;209
char name[name_len + 1];210
memcpy(name, label + set, name_len);211
name[name_len] = '\0';212
if (strcmp(key, name) == 0) {213
char *value = malloc(var_len + 1);214
memcpy(value, path + i - var_len, var_len);215
value[var_len] = '\0';216
return value;217
}218
if (c != label[idx]) {219
return NULL;220
}221
idx++;222
}223
else {224
var_len++;225
}226
}227
else {228
if (c != label[idx]) {229
return NULL;230
}231
idx++;232
}233
}234
if (is_var) {235
size_t set = idx + 1;236
for (; idx < len; idx++) {237
if (label[idx] == '}') {238
idx++;239
break;240
}241
}242
if (var_len == 0) {243
return NULL;244
}245
size_t name_len = idx - set - 1;246
char name[name_len + 1];247
memcpy(name, label + set, name_len);248
name[name_len] = '\0';249
if (strcmp(key, name) == 0) {250
char *value = malloc(var_len + 1);251
memcpy(value, path + i - var_len, var_len);252
value[var_len] = '\0';253
return value;254
}255
is_var = false;256
}257
if (idx != len) {258
return NULL;259
}260
if (i != strlen(path)) {261
return NULL;262
}263
return NULL;264
}266
#endif /* TPEE_EXT_IMPL */