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: