aboutsummaryrefslogtreecommitdiffstats
path: root/src/blogc-runserver/httpd-utils.c
diff options
context:
space:
mode:
authorRafael G. Martins <rafael@rafaelmartins.eng.br>2016-09-25 02:57:21 +0200
committerRafael G. Martins <rafael@rafaelmartins.eng.br>2016-09-25 02:57:21 +0200
commit6ac53d4c783340ae9139c7f4dcfe9bfddace5892 (patch)
tree2637740546dcf002fbfe39eb94d6f722a2c5c7d6 /src/blogc-runserver/httpd-utils.c
parent0c916e2c8b56c320fdc81f68d445194559479041 (diff)
downloadblogc-6ac53d4c783340ae9139c7f4dcfe9bfddace5892.tar.gz
blogc-6ac53d4c783340ae9139c7f4dcfe9bfddace5892.tar.bz2
blogc-6ac53d4c783340ae9139c7f4dcfe9bfddace5892.zip
runserver: reimplemented http server without libevent
yeah, this patch implements a "complete" http server for static files. It is not the best code possible, and would be easily DDoS'able if used in production, as it spawns a thread for each request, without limiting. I'm sickish and this is the best code I can deliver now. At least it works! ;)
Diffstat (limited to 'src/blogc-runserver/httpd-utils.c')
-rw-r--r--src/blogc-runserver/httpd-utils.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/blogc-runserver/httpd-utils.c b/src/blogc-runserver/httpd-utils.c
new file mode 100644
index 0000000..e935668
--- /dev/null
+++ b/src/blogc-runserver/httpd-utils.c
@@ -0,0 +1,100 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include "../common/utils.h"
+#include "httpd-utils.h"
+
+
+char*
+br_readline(int socket)
+{
+ bc_string_t *rv = bc_string_new();
+ char buffer[READLINE_BUFFER_SIZE];
+ ssize_t len;
+
+ while ((len = read(socket, buffer, READLINE_BUFFER_SIZE)) != -1) {
+ for (ssize_t i = 0; i < len; i++) {
+ if (buffer[i] == '\r' || buffer[i] == '\n')
+ goto end;
+ bc_string_append_c(rv, buffer[i]);
+ }
+ }
+
+end:
+ return bc_string_free(rv, false);
+}
+
+
+int
+br_hextoi(const char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return -1;
+}
+
+
+char*
+br_urldecode(const char *str)
+{
+ bc_string_t *rv = bc_string_new();
+
+ for (size_t i = 0; i < strlen(str); i++) {
+ switch (str[i]) {
+ case '%':
+ if (i + 2 < strlen(str)) {
+ int p1 = br_hextoi(str[i + 1]) * 16;
+ int p2 = br_hextoi(str[i + 2]);
+ if (p1 >= 0 && p2 >= 0) {
+ bc_string_append_c(rv, p1 + p2);
+ i += 2;
+ continue;
+ }
+ }
+ bc_string_append_c(rv, '%');
+ break;
+ case '+':
+ bc_string_append_c(rv, ' ');
+ break;
+ default:
+ bc_string_append_c(rv, str[i]);
+ }
+ }
+
+ return bc_string_free(rv, false);
+}
+
+
+const char*
+br_get_extension(const char *filename)
+{
+ const char *ext = NULL;
+ unsigned int i;
+ for (i = strlen(filename); i > 0; i--) {
+ if (filename[i] == '.') {
+ ext = filename + i + 1;
+ break;
+ }
+ if ((filename[i] == '/') || (filename[i] == '\\'))
+ return NULL;
+ }
+ if (i == 0)
+ return NULL;
+ return ext;
+}