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;