X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fnanohttp.c;fp=src%2Fnanohttp.c;h=3c0e9457f52001ebb10429fccb9eed66f3bbec1e;hb=3cb026de413f8130490ada85f2bc0b460172e4ef;hp=0000000000000000000000000000000000000000;hpb=770b156ad12cf75c816cdbe7f935493b812d6b5c;p=yaz-moved-to-github.git diff --git a/src/nanohttp.c b/src/nanohttp.c new file mode 100644 index 0000000..3c0e945 --- /dev/null +++ b/src/nanohttp.c @@ -0,0 +1,175 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2009 Index Data + * See the file LICENSE for details. + */ +/** + * \file + * \brief Small HTTP server + */ + +#include +#include +#include +#include +#include +#include + +typedef struct yaz_nano_srv_s *yaz_nano_srv_t; +typedef struct yaz_nano_pkg_s *yaz_nano_pkg_t; + +struct yaz_nano_pkg_s { + void *handle; + int listener_id; + ODR encode_odr; + Z_GDU *request_gdu; + Z_GDU *response_gdu; +}; + +struct yaz_nano_srv_s { + COMSTACK *cs_listeners; + size_t num_listeners; + NMEM nmem; + struct yaz_poll_fd *fds; +}; + +void yaz_nano_srv_destroy(yaz_nano_srv_t p) +{ + if (p) + { + size_t i; + for (i = 0; i < p->num_listeners; i++) + if (p->cs_listeners[i]) + cs_close(p->cs_listeners[i]); + nmem_destroy(p->nmem); + } +} + +yaz_nano_srv_t yaz_nano_srv_create(const char **listeners_str) +{ + NMEM nmem = nmem_create(); + yaz_nano_srv_t p = nmem_malloc(nmem, sizeof(*p)); + size_t i; + for (i = 0; listeners_str[i]; i++) + ; + p->nmem = nmem; + p->chan_list = 0; + p->free_list = 0; + p->num_listeners = i; + p->cs_listeners = + nmem_malloc(nmem, p->num_listeners * sizeof(*p->cs_listeners)); + for (i = 0; i < p->num_listeners; i++) + { + void *ap; + const char *where = listeners_str[i]; + COMSTACK l = cs_create_host(where, 2, &ap); + p->cs_listeners[i] = 0; /* not OK (yet) */ + if (!l) + { + yaz_log(YLOG_WARN|YLOG_ERRNO, "cs_create_host(%s) failed", where); + } + else + { + if (cs_bind(l, ap, CS_SERVER) < 0) + { + if (cs_errno(l) == CSYSERR) + yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to bind to %s", where); + else + yaz_log(YLOG_FATAL, "Failed to bind to %s: %s", where, + cs_strerror(l)); + cs_close(l); + } + else + p->cs_listeners[i] = l; /* success */ + } + } + /* check if all are OK */ + for (i = 0; i < p->num_listeners; i++) + if (!p->cs_listeners[i]) + { + yaz_nano_srv_destroy(p); + return 0; + } + + for (i = 0; i < p->num_listeners; i++) + { + struct socket_chan *chan = + socket_chan_new(p, cs_fileno(p->cs_listeners[i]), + p->cs_listeners + i); + socket_chan_set_mask(chan, yaz_poll_read | yaz_poll_except); + } + return p; +} + +Z_GDU *yaz_nano_pkg_req(yaz_nano_pkg_t pkg) +{ + return pkg->request_gdu; +} + +Z_GDU *yaz_nano_pkg_response(yaz_nano_pkg_t pkg) +{ + return pkg->response_gdu; +} + +ODR yaz_nano_pkg_encode(yaz_nano_pkg_t pkg) +{ + return pkg->encode_odr; +} + +int yaz_nano_pkg_listener_id(yaz_nano_pkg_t pkg) +{ + return pkg->listener_id; +} + +yaz_nano_pkg_t yaz_nano_srv_get_pkg(yaz_nano_srv_t p) +{ + size_t i; + int ret; + int num_fds = 0; + struct yaz_poll_fd *fds; + struct socket_chan *chan = p->chan_list; + for (chan = p->chan_list; chan; chan = chan->next) + num_fds++; + fds = xmalloc(num_fds * sizeof(*fds)); + for (i = 0, chan = p->chan_list; chan; chan = chan->next) + { + fds[i].input_mask = chan->mask; + fds[i].fd = chan->fd; + fds[i].client_data = chan; + } + ret = yaz_poll(fds, num_fds, 0, 0); + if (ret == -1) + { + yaz_log(YLOG_WARN, "yaz_poll error"); + } + else if (ret == 0) + { + yaz_log(YLOG_LOG, "yaz_poll timeout"); + } + else + { + for (i = 0, chan = p->chan_list; chan; chan = chan->next) + { + if (fds[i].output_mask) + { + yaz_log(YLOG_LOG, "event on chan=%p", chan); + } + } + } + xfree(fds); + return 0; +} + +void yaz_nano_srv_put_pkg(yaz_nano_srv_t p, yaz_nano_pkg_t pkg) +{ + +} + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +