Commit 54eeee39f168293b96dcd02d4549e76c70f6be34

Thomas de Grivel 2024-09-11T01:42:51

alist_access

diff --git a/lib/kc3/0.1/httpd.kc3 b/lib/kc3/0.1/httpd.kc3
index 3f88688..b68bb18 100644
--- a/lib/kc3/0.1/httpd.kc3
+++ b/lib/kc3/0.1/httpd.kc3
@@ -47,7 +47,18 @@ defmodule HTTPd do
         FD.set_blocking(socket, true)
         r = HTTP.Response.buf_write(res, client.buf_rw.w,
           req.method != :head)
-        puts("#{res.code} #{client.addr_str} #{res.message} #{req.method} #{req.url}")
+        client_addr = if client.addr_str != "127.0.0.1" do
+          client.addr_str
+        else
+          headers = req.headers
+          forwarded_for = headers["X-Forwarded-For"]
+          if (forwarded_for) do
+            forwarded_for
+          else
+            client.addr_str
+          end
+        end
+        puts("#{res.code} #{client_addr} #{req.method} #{req.url}")
         FD.set_blocking(socket, false)
       end
     end
@@ -80,7 +91,7 @@ defmodule HTTPd do
     socket = Socket.listen(host, port)
     puts("KC3 HTTPd: listening on #{host}:#{port}")
     acceptor_ev = Event.new(event_base, socket.fd, [:read, :persist],
-                                 acceptor, void)
+                            acceptor, void)
     r = Event.add(acceptor_ev, timeout)
     r = Event.dispatch(event_base)
     if r do
diff --git a/libkc3/alist.c b/libkc3/alist.c
index 10b2e8d..3a66a04 100644
--- a/libkc3/alist.c
+++ b/libkc3/alist.c
@@ -20,11 +20,46 @@
 #include "buf_parse.h"
 #include "compare.h"
 #include "data.h"
+#include "kc3_main.h"
 #include "list.h"
 #include "sym.h"
 #include "tag.h"
 #include "tuple.h"
 
+s_tag * alist_access (const s_list * const *alist,
+                      const s_list * const *key,
+                      s_tag *dest)
+{
+  const s_tag *first;
+  const s_list *next;
+  s_tag *r;
+  s_tag tag;
+  assert(alist);
+  assert(key);
+  assert(dest);
+  if (! list_is_alist(alist)) {
+    err_puts("alist_access: not an associative list");
+    assert(! "alist_access: not an associative list");
+    return NULL;
+  }
+  first = &(*key)->tag;
+  next = list_next(*key);
+  if (! next)
+    return alist_get(alist, first, dest);
+  if (! alist_get(alist, first, &tag)) {
+    err_write_1("alist_access: alist_get(");
+    err_inspect_list(alist);
+    err_write_1(", ");
+    err_inspect_tag(first);
+    err_write_1(")\n");
+    assert(! "alist_access: alist_get");
+    return NULL;
+  }
+  r = kc3_access(&tag, &next, dest);
+  tag_clean(&tag);
+  return r;
+}
+
 s_tag * alist_get (const s_list * const *alist, const s_tag *key,
                    s_tag *dest)
 {
diff --git a/libkc3/alist.h b/libkc3/alist.h
index 5dc38af..d96f3c8 100644
--- a/libkc3/alist.h
+++ b/libkc3/alist.h
@@ -22,6 +22,9 @@
 #include "types.h"
 
 /* Observers */
+s_tag * alist_access (const s_list * const *alist,
+                      const s_list * const *key,
+                      s_tag *dest);
 s_tag * alist_get (const s_list * const *alist, const s_tag *key,
                    s_tag *dest);
 
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index a48743d..b5a03ec 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -15,6 +15,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include "alist.h"
 #include "array.h"
 #include "assert.h"
 #include "bool.h"
@@ -51,6 +52,14 @@ s_tag * kc3_access (const s_tag *tag, const s_list * const *key,
   switch (tag->type) {
   case TAG_ARRAY:
     return array_access(&tag->data.array, key, dest);
+  case TAG_LIST:
+    if (list_is_alist((const s_list * const *) &tag->data.list)) {
+      if (! alist_access((const s_list * const *) &tag->data.list,
+                         key, dest))
+        return tag_init_void(dest);
+      return dest;
+    }
+    break;
   case TAG_MAP:
     return map_access(&tag->data.map, key, dest);
   case TAG_STRUCT: