Commit d06c786a6d6c8591b18ea7df16662bd77069eef9

jeanne 2024-10-15T17:40:25

wip httpd

diff --git a/http/http_response.c b/http/http_response.c
index fa56578..010f7a4 100644
--- a/http/http_response.c
+++ b/http/http_response.c
@@ -98,7 +98,7 @@ sw http_response_buf_write (const s_http_response *response,
   s_str content_length_str = {0};
   s_tag default_messages = {0};
   s32 e;
-  uw end;
+  sw end;
   s32 fd;
   s_ident ident = {0};
   s_buf *in;
@@ -110,7 +110,7 @@ sw http_response_buf_write (const s_http_response *response,
   sw result = 0;
   sw s;
   sw size;
-  uw start;
+  sw start;
   s_str str;
   s_tag tag_code = {0};
   s_tag tag_message = {0};
@@ -282,15 +282,19 @@ sw http_response_buf_write (const s_http_response *response,
              map->key[1].data.sym == sym_1("fd") &&
              map->value[1].type == TAG_S32 &&
              map->key[2].data.sym == sym_1("start") &&
-             map->value[2].type == TAG_UW &&
-             map->key[0].data.sym == sym_1("end") &&
-             map->value[0].type == TAG_UW) {
+             map->value[2].type == TAG_SW &&
+             map->key[0].data.sym == sym_1("end_") &&
+             map->value[0].type == TAG_SW) {
       fd    = map->value[1].data.s32;
-      start = map->value[2].data.uw;
-      end   = map->value[0].data.uw;
+      start = map->value[2].data.sw;
+      end   = map->value[0].data.sw;
+      if (start < 0)
+        start = content_length + start + 1;
+      if (end < 0)
+        end = content_length + end + 1;
       if (content_length < 0 ||
           start > end ||
-          start > (uw) content_length) {
+          start > content_length) {
         err_puts("http_response_buf_write:"
                  " 416 Requested Range Not Satisfiable");
         assert(!("http_response_buf_write:"
diff --git a/lib/kc3/0.1/httpd.kc3 b/lib/kc3/0.1/httpd.kc3
index 6020e33..ae4a67a 100644
--- a/lib/kc3/0.1/httpd.kc3
+++ b/lib/kc3/0.1/httpd.kc3
@@ -237,6 +237,29 @@ defmodule HTTPd do
     (url, i) { "/" + url_eat(Str.split(url, "/"), i + 1) }
   }
 
+  def parse_range = fn {
+    (false) { { (Sw) 0, (Sw) -1 } }
+    (range) {
+      if Str.starts_with?(range, "bytes=") do
+        range = Str.slice(range, 6, -1)
+        [start, end_] = Str.split(range, "-")
+        if start do
+          start = (Sw) start
+          end_ = if end_ != "" do
+            (Sw) end_
+          else
+            (Sw) -1
+          end
+          { start, end_ }
+        else
+          { (Sw) 0, (Sw) -1 }
+        end
+      else
+        { (Sw) 0, (Sw) -1 }
+      end
+    }
+  }
+    
   def def_static_route = fn (prefix, root_dir, url_skip) {
     directory_page = HTTPd.fn (request) {
       url = url_eat(request.url, url_skip)
@@ -281,11 +304,13 @@ defmodule HTTPd do
             header_value
           end
         end)
-        puts("Range: #{inspect(range)}")
+        {range_start, range_end} = parse_range(range)
         headers = [{"Content-Type", (Str) mime},
                    {"Content-Length", (Str) stat.st_size},
+                   {"Content-Range", "bytes=#{range_start}-#{range_end}"}
                    {"Last-Modified", last_modified}]
-        body = File.open_r(path)
+        fd = File.open_r(path)
+        body = %{fd: fd, start: range_start, end_: range_end}
         %HTTP.Response{body: body, headers: headers}
       else
         error_404_page(request)
diff --git a/libkc3/s.c.in b/libkc3/s.c.in
index 97c7f47..916bb7d 100644
--- a/libkc3/s.c.in
+++ b/libkc3/s.c.in
@@ -70,6 +70,10 @@ s_bits$ * s_bits$_init_cast
   case TAG_S8:
     *s = (s_bits$) tag->data.s8;
     return s;
+  case TAG_STR:
+    if (! s_bits$_init_str(s, &tag->data.str))
+      return NULL;
+    return s;
   case TAG_U8:
     *s = (s_bits$) tag->data.u8;
     return s;
diff --git a/libkc3/s16.c b/libkc3/s16.c
index 4a5711f..f6c1f4f 100644
--- a/libkc3/s16.c
+++ b/libkc3/s16.c
@@ -70,6 +70,10 @@ s16 * s16_init_cast
   case TAG_S8:
     *s = (s16) tag->data.s8;
     return s;
+  case TAG_STR:
+    if (! s16_init_str(s, &tag->data.str))
+      return NULL;
+    return s;
   case TAG_U8:
     *s = (s16) tag->data.u8;
     return s;
diff --git a/libkc3/s32.c b/libkc3/s32.c
index 2e6a5e4..0c09785 100644
--- a/libkc3/s32.c
+++ b/libkc3/s32.c
@@ -70,6 +70,10 @@ s32 * s32_init_cast
   case TAG_S8:
     *s = (s32) tag->data.s8;
     return s;
+  case TAG_STR:
+    if (! s32_init_str(s, &tag->data.str))
+      return NULL;
+    return s;
   case TAG_U8:
     *s = (s32) tag->data.u8;
     return s;
diff --git a/libkc3/s64.c b/libkc3/s64.c
index eb04fab..7b852c8 100644
--- a/libkc3/s64.c
+++ b/libkc3/s64.c
@@ -70,6 +70,10 @@ s64 * s64_init_cast
   case TAG_S8:
     *s = (s64) tag->data.s8;
     return s;
+  case TAG_STR:
+    if (! s64_init_str(s, &tag->data.str))
+      return NULL;
+    return s;
   case TAG_U8:
     *s = (s64) tag->data.u8;
     return s;
diff --git a/libkc3/s8.c b/libkc3/s8.c
index a7b899d..4b178c0 100644
--- a/libkc3/s8.c
+++ b/libkc3/s8.c
@@ -70,6 +70,10 @@ s8 * s8_init_cast
   case TAG_S8:
     *s = (s8) tag->data.s8;
     return s;
+  case TAG_STR:
+    if (! s8_init_str(s, &tag->data.str))
+      return NULL;
+    return s;
   case TAG_U8:
     *s = (s8) tag->data.u8;
     return s;
diff --git a/libkc3/sw.c b/libkc3/sw.c
index d9e7651..18da7b8 100644
--- a/libkc3/sw.c
+++ b/libkc3/sw.c
@@ -70,6 +70,10 @@ sw * sw_init_cast
   case TAG_S8:
     *s = (sw) tag->data.s8;
     return s;
+  case TAG_STR:
+    if (! sw_init_str(s, &tag->data.str))
+      return NULL;
+    return s;
   case TAG_U8:
     *s = (sw) tag->data.u8;
     return s;