Commit e87b914332621529b239fcf3e91fb51109f639d5

Baptiste 2024-08-07T15:43:40

fix bugs in httpd

diff --git a/http/http.h b/http/http.h
index d5907c5..9386600 100644
--- a/http/http.h
+++ b/http/http.h
@@ -15,8 +15,8 @@
 
 #include "types.h"
 
-s_tag *          http_header_split (s_str *header, s_tag *dest);
-s_http_request * http_request_buf_parse (s_http_request *req, s_buf *buf);
+s_tag * http_header_split (s_str *header, s_tag *dest);
+s_tag * http_request_buf_parse (s_tag *request, s_buf *buf);
 
 
 #endif /* HTTP_H */
diff --git a/http/http_request.c b/http/http_request.c
index 6a2d71d..d6c4011 100644
--- a/http/http_request.c
+++ b/http/http_request.c
@@ -15,21 +15,22 @@
 #include <string.h>
 #include "socket.h"
 
-s_http_request * http_request_buf_parse (s_http_request *req, s_buf *buf)
+s_tag * http_request_buf_parse (s_tag *req, s_buf *buf)
 {
   s_str line;
   sw r;
   s_buf_save save;
   s_list **tail;
-  s_http_request tmp = {0};
+  s_tag tmp = {0};
+  s_http_request tmp_req = {0};
   assert(req);
   assert(buf);
   buf_save_init(buf, &save);
   if ((r = buf_read_1(buf, "GET ")) < 0)
     goto restore;
   if (r > 0)
-    tmp.method = sym_1("get");
-  if (! tmp.method) {
+    tmp_req.method = sym_1("get");
+  if (! tmp_req.method) {
     err_write_1("http_request_buf_parse: no method: ");
     err_inspect_buf(buf);
     err_write_1("\n");
@@ -37,28 +38,28 @@ s_http_request * http_request_buf_parse (s_http_request *req, s_buf *buf)
   }
   if (false) {
     err_write_1("http_request_buf_parse: method: ");
-    err_inspect_sym(&tmp.method);
+    err_inspect_sym(&tmp_req.method);
     err_write_1("\n");
   }
-  if (! buf_read_until_1_into_str(buf, " ", &tmp.url)) {
+  if (! buf_read_until_1_into_str(buf, " ", &tmp_req.url)) {
     err_puts("http_request_buf_parse: invalid URL");
     goto restore;
   }
   if (false) {
     err_write_1("http_request_buf_parse: url: ");
-    err_inspect_str(&tmp.url);
+    err_inspect_str(&tmp_req.url);
     err_write_1("\n");
   }
-  if (! buf_read_until_1_into_str(buf, "\r\n", &tmp.protocol)) {
+  if (! buf_read_until_1_into_str(buf, "\r\n", &tmp_req.protocol)) {
     err_puts("http_request_buf_parse: invalid protocol");
     goto restore;
   }
   if (false) {
     err_write_1("http_request_buf_parse: protocol: ");
-    err_inspect_str(&tmp.protocol);
+    err_inspect_str(&tmp_req.protocol);
     err_write_1("\n");
   }
-  tail = &tmp.headers;
+  tail = &tmp_req.headers;
   while (1) {
     if (! buf_read_until_1_into_str(buf, "\r\n", &line)) {
       err_puts("http_request_buf_parse: invalid header");
@@ -72,11 +73,18 @@ s_http_request * http_request_buf_parse (s_http_request *req, s_buf *buf)
       goto restore;
     tail = &(*tail)->next.data.list;
   }
-  buf_save_clean(buf, &save);
-  *req = tmp;
-  return req;
+  if (! tag_init_struct(&tmp, sym_1("HTTP.Request")))
+    goto restore;
+  if (! struct_allocate(&tmp.data.struct_)) {
+    tag_void(&tmp);
+    goto restore;
+  }
+  *((s_http_request *) tmp.data.struct_.data) = tmp_req;
+  goto clean;
  restore:
   buf_save_restore_rpos(buf, &save);
+ clean:
   buf_save_clean(buf, &save);
-  return NULL;
+  *req = tmp;
+  return req;
 }
diff --git a/lib/kc3/0.1/http/request.kc3 b/lib/kc3/0.1/http/request.kc3
index 1debeed..3bbc651 100644
--- a/lib/kc3/0.1/http/request.kc3
+++ b/lib/kc3/0.1/http/request.kc3
@@ -7,6 +7,6 @@ defmodule HTTP.Request do
 
   dlopen(__DIR__ + "../http.so")
 
-  def buf_parse = cfn HTTP.Request "http_request_buf_parse" (Result, Buf)
+  def buf_parse = cfn Tag "http_request_buf_parse" (Result, Buf)
 
 end
diff --git a/lib/kc3/0.1/httpd.kc3 b/lib/kc3/0.1/httpd.kc3
index 7c214d1..2c0691b 100644
--- a/lib/kc3/0.1/httpd.kc3
+++ b/lib/kc3/0.1/httpd.kc3
@@ -25,11 +25,13 @@ defmodule HTTPd do
 
   def main = fn {
     () {
+      HTTP.mime_type_load("mime.types")
       host = getenv("KC3_HTTPD_HOST")
       port = getenv("KC3_HTTPD_PORT")
       server(host, port)
     }
     (host, port) {
+      HTTP.mime_type_load("mime.types")
       server(host, port)
     }
   }
@@ -123,11 +125,7 @@ defmodule HTTPd do
       if File.is_directory?(path) do
         directory_page
       else
-        if Str.ends_with?(path, ".html") do
-          show_page
-        else
-          debug_page
-        end
+        show_page
       end
     else
       error_404_page
diff --git a/libkc3/buf.c b/libkc3/buf.c
index 3078663..f398e8d 100644
--- a/libkc3/buf.c
+++ b/libkc3/buf.c
@@ -68,32 +68,36 @@ sw buf_ignore (s_buf *buf, uw size)
   assert(buf);
   if (size == 0)
     return 0;
-  if ((r = buf_refill(buf, size)) < 0)
+  if ((r = buf_refill(buf, size)) < 0) {
+    err_puts("buf_ignore: buf_refill");
     return r;
-  if ((uw) r < size)
+  }
+  if ((uw) r < size) {
+    err_puts("buf_ignore: buf_refill < size");
     return -1;
-  if (buf->line >= 0) {
-    while (i < size) {
-      if ((r = buf_read_character_utf8(buf, &c)) < 0)
-        return r;
-      if (r > 0) {
-        i += r;
-        continue;
-      }
-      if ((r = buf_read_u8(buf, &b)) < 0)
-        return r;
-      if (r > 0) {
-          buf->column++;
-        i += r;
-        continue;
-      }
-      error("buf_ignore");
-      return -1;
+  }
+  while (i < size) {
+    if ((r = buf_read_character_utf8(buf, &c)) < 0) {
+      err_puts("buf_ignore: buf_read_character_utf8");
+      return r;
+    }
+    if (r > 0) {
+      i += r;
+      continue;
     }
-    assert(i == size);
+    if ((r = buf_read_u8(buf, &b)) < 0) {
+      err_puts("buf_ignore: buf_read_u8");
+      return r;
+    }
+    if (r > 0) {
+        buf->column++;
+      i += r;
+      continue;
+    }
+    err_puts("buf_ignore: failed to read");
+    return -1;
   }
-  else
-    buf->rpos += size;
+  assert(i == size);
   return size;
 }
 
diff --git a/libkc3/file.c b/libkc3/file.c
index 927378f..e890eae 100644
--- a/libkc3/file.c
+++ b/libkc3/file.c
@@ -18,6 +18,7 @@
 #include <dirent.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include "alloc.h"
 #include "buf.h"
 #include "buf_file.h"
 #include "buf_save.h"
@@ -221,24 +222,42 @@ s_str * file_pwd (s_str *dest)
 
 s_str * file_read (const s_str *path, s_str *dest)
 {
-  s_buf buf;
-  FILE *fp;
-  struct file_stat sb;
-  file_stat(path, &sb);
-  if (! sb.st_mode)
+  char *buf;
+  s32 e;
+  s32 fd;
+  uw r;
+  sw size = 0;
+  struct stat sb;
+  if (stat(path->ptr.pchar, &sb)) {
+    err_puts("file_read: stat");
     return NULL;
-  fp = file_open(path->ptr.pchar, "rb");
-  if (! fp)
+  }
+  fd = open(path->ptr.pchar, O_RDONLY | O_BINARY);
+  if (fd < 0) {
+    e = errno;
+    err_write_1("file_read: open: ");
+    err_write_1(strerror(e));
+    err_write_1(": ");
+    err_write_str(path);
     return NULL;
-  buf_init_alloc(&buf, sb.st_size);
-  if (! buf_file_open_r(&buf, fp)) {
-    fclose(fp);
+  }
+  buf = alloc(sb.st_size);
+  if (! buf) {
+    err_puts("file_read: failed to allocate buf");
+    close(fd);
     return NULL;
   }
-  buf_refill(&buf, sb.st_size);
-  buf_read_to_str(&buf, dest);
-  buf_file_close(&buf);
-  fclose(fp);
+  while (size < sb.st_size) {
+    if (! (r = read(fd, buf, sb.st_size))) {
+      err_puts("file_read: read = 0");
+      free(buf);
+      close(fd);
+      return NULL;
+    }
+    size += r;
+  }
+  close(fd);
+  str_init(dest, buf, sb.st_size, buf);
   return dest;
 }