You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2008/07/22 06:35:46 UTC
svn commit: r678637 [26/46] - in
/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd: ./
autom4te.cache/ cygwin/ doc/ openwrt/ src/ tests/ tests/docroot/
tests/docroot/123/ tests/docroot/www/ tests/docroot/www/dummydir/
tests/docroot/www/expire/ ...
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_linux_rtsig.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_linux_rtsig.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_linux_rtsig.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_linux_rtsig.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,260 @@
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <limits.h>
+
+#define __USE_GNU
+#include <fcntl.h>
+
+#include "fdevent.h"
+#include "settings.h"
+#include "buffer.h"
+
+#ifdef USE_LINUX_SIGIO
+static void fdevent_linux_rtsig_free(fdevents *ev) {
+ free(ev->pollfds);
+ if (ev->unused.ptr) free(ev->unused.ptr);
+
+ bitset_free(ev->sigbset);
+}
+
+
+static int fdevent_linux_rtsig_event_del(fdevents *ev, int fde_ndx, int fd) {
+ if (fde_ndx < 0) return -1;
+
+ if ((size_t)fde_ndx >= ev->used) {
+ fprintf(stderr, "%s.%d: del! out of range %d %zu\n", __FILE__, __LINE__, fde_ndx, ev->used);
+ SEGFAULT();
+ }
+
+ if (ev->pollfds[fde_ndx].fd == fd) {
+ size_t k = fde_ndx;
+
+ ev->pollfds[k].fd = -1;
+
+ bitset_clear_bit(ev->sigbset, fd);
+
+ if (ev->unused.size == 0) {
+ ev->unused.size = 16;
+ ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
+ } else if (ev->unused.size == ev->unused.used) {
+ ev->unused.size += 16;
+ ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
+ }
+
+ ev->unused.ptr[ev->unused.used++] = k;
+ } else {
+ fprintf(stderr, "%s.%d: del! %d %d\n", __FILE__, __LINE__, ev->pollfds[fde_ndx].fd, fd);
+
+ SEGFAULT();
+ }
+
+ return -1;
+}
+
+#if 0
+static int fdevent_linux_rtsig_event_compress(fdevents *ev) {
+ size_t j;
+
+ if (ev->used == 0) return 0;
+ if (ev->unused.used != 0) return 0;
+
+ for (j = ev->used - 1; j + 1 > 0; j--) {
+ if (ev->pollfds[j].fd == -1) ev->used--;
+ }
+
+
+ return 0;
+}
+#endif
+
+static int fdevent_linux_rtsig_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
+ /* known index */
+ if (fde_ndx != -1) {
+ if (ev->pollfds[fde_ndx].fd == fd) {
+ ev->pollfds[fde_ndx].events = events;
+
+ return fde_ndx;
+ }
+ fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
+ SEGFAULT();
+ }
+
+ if (ev->unused.used > 0) {
+ int k = ev->unused.ptr[--ev->unused.used];
+
+ ev->pollfds[k].fd = fd;
+ ev->pollfds[k].events = events;
+
+ bitset_set_bit(ev->sigbset, fd);
+
+ return k;
+ } else {
+ if (ev->size == 0) {
+ ev->size = 16;
+ ev->pollfds = malloc(sizeof(*ev->pollfds) * ev->size);
+ } else if (ev->size == ev->used) {
+ ev->size += 16;
+ ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
+ }
+
+ ev->pollfds[ev->used].fd = fd;
+ ev->pollfds[ev->used].events = events;
+
+ bitset_set_bit(ev->sigbset, fd);
+
+ return ev->used++;
+ }
+}
+
+static int fdevent_linux_rtsig_poll(fdevents *ev, int timeout_ms) {
+ struct timespec ts;
+ int r;
+
+#if 0
+ fdevent_linux_rtsig_event_compress(ev);
+#endif
+
+ ev->in_sigio = 1;
+
+ ts.tv_sec = timeout_ms / 1000;
+ ts.tv_nsec = (timeout_ms % 1000) * 1000000;
+ r = sigtimedwait(&(ev->sigset), &(ev->siginfo), &(ts));
+
+ if (r == -1) {
+ if (errno == EAGAIN) return 0;
+ return r;
+ } else if (r == SIGIO) {
+ struct sigaction act;
+
+ /* flush the signal queue */
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = SIG_IGN;
+ sigaction(ev->signum, &act, NULL);
+
+ /* re-enable the signal queue */
+ act.sa_handler = SIG_DFL;
+ sigaction(ev->signum, &act, NULL);
+
+ ev->in_sigio = 0;
+ r = poll(ev->pollfds, ev->used, timeout_ms);
+
+ return r;
+ } else if (r == ev->signum) {
+# if 0
+ fprintf(stderr, "event: %d %02lx\n", ev->siginfo.si_fd, ev->siginfo.si_band);
+# endif
+ return bitset_test_bit(ev->sigbset, ev->siginfo.si_fd);
+ } else {
+ /* ? */
+ return -1;
+ }
+}
+
+static int fdevent_linux_rtsig_event_get_revent(fdevents *ev, size_t ndx) {
+ if (ev->in_sigio == 1) {
+# if 0
+ if (ev->siginfo.si_band == POLLERR) {
+ fprintf(stderr, "event: %d %02lx %02x %s\n", ev->siginfo.si_fd, ev->siginfo.si_band, errno, strerror(errno));
+ }
+# endif
+ if (ndx != 0) {
+ fprintf(stderr, "+\n");
+ return 0;
+ }
+
+ return ev->siginfo.si_band & 0x3f;
+ } else {
+ if (ndx >= ev->used) {
+ fprintf(stderr, "%s.%d: event: %zu %zu\n", __FILE__, __LINE__, ndx, ev->used);
+ return 0;
+ }
+ return ev->pollfds[ndx].revents;
+ }
+}
+
+static int fdevent_linux_rtsig_event_get_fd(fdevents *ev, size_t ndx) {
+ if (ev->in_sigio == 1) {
+ return ev->siginfo.si_fd;
+ } else {
+ return ev->pollfds[ndx].fd;
+ }
+}
+
+static int fdevent_linux_rtsig_fcntl_set(fdevents *ev, int fd) {
+ static pid_t pid = 0;
+
+ if (pid == 0) pid = getpid();
+
+ if (-1 == fcntl(fd, F_SETSIG, ev->signum)) return -1;
+
+ if (-1 == fcntl(fd, F_SETOWN, (int) pid)) return -1;
+
+ return fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK | O_RDWR);
+}
+
+
+static int fdevent_linux_rtsig_event_next_fdndx(fdevents *ev, int ndx) {
+ if (ev->in_sigio == 1) {
+ if (ndx < 0) return 0;
+ return -1;
+ } else {
+ size_t i;
+
+ i = (ndx < 0) ? 0 : ndx + 1;
+ for (; i < ev->used; i++) {
+ if (ev->pollfds[i].revents) break;
+ }
+
+ return i;
+ }
+}
+
+int fdevent_linux_rtsig_init(fdevents *ev) {
+ ev->type = FDEVENT_HANDLER_LINUX_RTSIG;
+#define SET(x) \
+ ev->x = fdevent_linux_rtsig_##x;
+
+ SET(free);
+ SET(poll);
+
+ SET(event_del);
+ SET(event_add);
+
+ SET(event_next_fdndx);
+ SET(fcntl_set);
+ SET(event_get_fd);
+ SET(event_get_revent);
+
+ ev->signum = SIGRTMIN + 1;
+
+ sigemptyset(&(ev->sigset));
+ sigaddset(&(ev->sigset), ev->signum);
+ sigaddset(&(ev->sigset), SIGIO);
+ if (-1 == sigprocmask(SIG_BLOCK, &(ev->sigset), NULL)) {
+ fprintf(stderr, "%s.%d: sigprocmask failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
+ __FILE__, __LINE__, strerror(errno));
+
+ return -1;
+ }
+
+ ev->in_sigio = 1;
+
+ ev->sigbset = bitset_init(ev->maxfds);
+
+ return 0;
+}
+#else
+int fdevent_linux_rtsig_init(fdevents *ev) {
+ UNUSED(ev);
+
+ fprintf(stderr, "%s.%d: linux-rtsig not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
+ __FILE__, __LINE__);
+ return -1;
+}
+#endif
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_linux_sysepoll.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_linux_sysepoll.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_linux_sysepoll.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_linux_sysepoll.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,160 @@
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+
+#include "fdevent.h"
+#include "settings.h"
+#include "buffer.h"
+
+#ifdef USE_LINUX_EPOLL
+static void fdevent_linux_sysepoll_free(fdevents *ev) {
+ close(ev->epoll_fd);
+ free(ev->epoll_events);
+}
+
+static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) {
+ struct epoll_event ep;
+
+ if (fde_ndx < 0) return -1;
+
+ memset(&ep, 0, sizeof(ep));
+
+ ep.data.fd = fd;
+ ep.data.ptr = NULL;
+
+ if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, &ep)) {
+ fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
+
+ SEGFAULT();
+
+ return 0;
+ }
+
+
+ return -1;
+}
+
+static int fdevent_linux_sysepoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
+ struct epoll_event ep;
+ int add = 0;
+
+ if (fde_ndx == -1) add = 1;
+
+ memset(&ep, 0, sizeof(ep));
+
+ ep.events = 0;
+
+ if (events & FDEVENT_IN) ep.events |= EPOLLIN;
+ if (events & FDEVENT_OUT) ep.events |= EPOLLOUT;
+
+ /**
+ *
+ * with EPOLLET we don't get a FDEVENT_HUP
+ * if the close is delay after everything has
+ * sent.
+ *
+ */
+
+ ep.events |= EPOLLERR | EPOLLHUP /* | EPOLLET */;
+
+ ep.data.ptr = NULL;
+ ep.data.fd = fd;
+
+ if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &ep)) {
+ fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
+
+ SEGFAULT();
+
+ return 0;
+ }
+
+ return fd;
+}
+
+static int fdevent_linux_sysepoll_poll(fdevents *ev, int timeout_ms) {
+ return epoll_wait(ev->epoll_fd, ev->epoll_events, ev->maxfds, timeout_ms);
+}
+
+static int fdevent_linux_sysepoll_event_get_revent(fdevents *ev, size_t ndx) {
+ int events = 0, e;
+
+ e = ev->epoll_events[ndx].events;
+ if (e & EPOLLIN) events |= FDEVENT_IN;
+ if (e & EPOLLOUT) events |= FDEVENT_OUT;
+ if (e & EPOLLERR) events |= FDEVENT_ERR;
+ if (e & EPOLLHUP) events |= FDEVENT_HUP;
+ if (e & EPOLLPRI) events |= FDEVENT_PRI;
+
+ return e;
+}
+
+static int fdevent_linux_sysepoll_event_get_fd(fdevents *ev, size_t ndx) {
+# if 0
+ fprintf(stderr, "%s.%d: %d, %d\n", __FILE__, __LINE__, ndx, ev->epoll_events[ndx].data.fd);
+# endif
+
+ return ev->epoll_events[ndx].data.fd;
+}
+
+static int fdevent_linux_sysepoll_event_next_fdndx(fdevents *ev, int ndx) {
+ size_t i;
+
+ UNUSED(ev);
+
+ i = (ndx < 0) ? 0 : ndx + 1;
+
+ return i;
+}
+
+int fdevent_linux_sysepoll_init(fdevents *ev) {
+ ev->type = FDEVENT_HANDLER_LINUX_SYSEPOLL;
+#define SET(x) \
+ ev->x = fdevent_linux_sysepoll_##x;
+
+ SET(free);
+ SET(poll);
+
+ SET(event_del);
+ SET(event_add);
+
+ SET(event_next_fdndx);
+ SET(event_get_fd);
+ SET(event_get_revent);
+
+ if (-1 == (ev->epoll_fd = epoll_create(ev->maxfds))) {
+ fprintf(stderr, "%s.%d: epoll_create failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
+ __FILE__, __LINE__, strerror(errno));
+
+ return -1;
+ }
+
+ if (-1 == fcntl(ev->epoll_fd, F_SETFD, FD_CLOEXEC)) {
+ fprintf(stderr, "%s.%d: epoll_create failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
+ __FILE__, __LINE__, strerror(errno));
+
+ close(ev->epoll_fd);
+
+ return -1;
+ }
+
+ ev->epoll_events = malloc(ev->maxfds * sizeof(*ev->epoll_events));
+
+ return 0;
+}
+
+#else
+int fdevent_linux_sysepoll_init(fdevents *ev) {
+ UNUSED(ev);
+
+ fprintf(stderr, "%s.%d: linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
+ __FILE__, __LINE__);
+
+ return -1;
+}
+#endif
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_poll.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_poll.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_poll.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_poll.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,182 @@
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+
+#include "fdevent.h"
+#include "settings.h"
+#include "buffer.h"
+
+#ifdef USE_POLL
+static void fdevent_poll_free(fdevents *ev) {
+ free(ev->pollfds);
+ if (ev->unused.ptr) free(ev->unused.ptr);
+}
+
+static int fdevent_poll_event_del(fdevents *ev, int fde_ndx, int fd) {
+ if (fde_ndx < 0) return -1;
+
+ if ((size_t)fde_ndx >= ev->used) {
+ fprintf(stderr, "%s.%d: del! out of range %d %zd\n", __FILE__, __LINE__, fde_ndx, ev->used);
+ SEGFAULT();
+ }
+
+ if (ev->pollfds[fde_ndx].fd == fd) {
+ size_t k = fde_ndx;
+
+ ev->pollfds[k].fd = -1;
+ /* ev->pollfds[k].events = 0; */
+ /* ev->pollfds[k].revents = 0; */
+
+ if (ev->unused.size == 0) {
+ ev->unused.size = 16;
+ ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
+ } else if (ev->unused.size == ev->unused.used) {
+ ev->unused.size += 16;
+ ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
+ }
+
+ ev->unused.ptr[ev->unused.used++] = k;
+ } else {
+ SEGFAULT();
+ }
+
+ return -1;
+}
+
+#if 0
+static int fdevent_poll_event_compress(fdevents *ev) {
+ size_t j;
+
+ if (ev->used == 0) return 0;
+ if (ev->unused.used != 0) return 0;
+
+ for (j = ev->used - 1; j + 1 > 0 && ev->pollfds[j].fd == -1; j--) ev->used--;
+
+ return 0;
+}
+#endif
+
+static int fdevent_poll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
+ /* known index */
+
+ if (fde_ndx != -1) {
+ if (ev->pollfds[fde_ndx].fd == fd) {
+ ev->pollfds[fde_ndx].events = events;
+
+ return fde_ndx;
+ }
+ fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
+ SEGFAULT();
+ }
+
+ if (ev->unused.used > 0) {
+ int k = ev->unused.ptr[--ev->unused.used];
+
+ ev->pollfds[k].fd = fd;
+ ev->pollfds[k].events = events;
+
+ return k;
+ } else {
+ if (ev->size == 0) {
+ ev->size = 16;
+ ev->pollfds = malloc(sizeof(*ev->pollfds) * ev->size);
+ } else if (ev->size == ev->used) {
+ ev->size += 16;
+ ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
+ }
+
+ ev->pollfds[ev->used].fd = fd;
+ ev->pollfds[ev->used].events = events;
+
+ return ev->used++;
+ }
+}
+
+static int fdevent_poll_poll(fdevents *ev, int timeout_ms) {
+#if 0
+ fdevent_poll_event_compress(ev);
+#endif
+ return poll(ev->pollfds, ev->used, timeout_ms);
+}
+
+static int fdevent_poll_event_get_revent(fdevents *ev, size_t ndx) {
+ int r, poll_r;
+ if (ndx >= ev->used) {
+ fprintf(stderr, "%s.%d: dying because: event: %zd >= %zd\n", __FILE__, __LINE__, ndx, ev->used);
+
+ SEGFAULT();
+
+ return 0;
+ }
+
+ if (ev->pollfds[ndx].revents & POLLNVAL) {
+ /* should never happen */
+ SEGFAULT();
+ }
+
+ r = 0;
+ poll_r = ev->pollfds[ndx].revents;
+
+ /* map POLL* to FDEVEN_* */
+
+ if (poll_r & POLLIN) r |= FDEVENT_IN;
+ if (poll_r & POLLOUT) r |= FDEVENT_OUT;
+ if (poll_r & POLLERR) r |= FDEVENT_ERR;
+ if (poll_r & POLLHUP) r |= FDEVENT_HUP;
+ if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
+ if (poll_r & POLLPRI) r |= FDEVENT_PRI;
+
+ return ev->pollfds[ndx].revents;
+}
+
+static int fdevent_poll_event_get_fd(fdevents *ev, size_t ndx) {
+ return ev->pollfds[ndx].fd;
+}
+
+static int fdevent_poll_event_next_fdndx(fdevents *ev, int ndx) {
+ size_t i;
+
+ i = (ndx < 0) ? 0 : ndx + 1;
+ for (; i < ev->used; i++) {
+ if (ev->pollfds[i].revents) break;
+ }
+
+ return i;
+}
+
+int fdevent_poll_init(fdevents *ev) {
+ ev->type = FDEVENT_HANDLER_POLL;
+#define SET(x) \
+ ev->x = fdevent_poll_##x;
+
+ SET(free);
+ SET(poll);
+
+ SET(event_del);
+ SET(event_add);
+
+ SET(event_next_fdndx);
+ SET(event_get_fd);
+ SET(event_get_revent);
+
+ return 0;
+}
+
+
+
+
+#else
+int fdevent_poll_init(fdevents *ev) {
+ UNUSED(ev);
+
+ fprintf(stderr, "%s.%d: poll is not supported, try to set server.event-handler = \"select\"\n",
+ __FILE__, __LINE__);
+ return -1;
+}
+#endif
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_select.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_select.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_select.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_select.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,131 @@
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <assert.h>
+
+#include "fdevent.h"
+#include "settings.h"
+#include "buffer.h"
+
+#ifdef USE_SELECT
+
+static int fdevent_select_reset(fdevents *ev) {
+ FD_ZERO(&(ev->select_set_read));
+ FD_ZERO(&(ev->select_set_write));
+ FD_ZERO(&(ev->select_set_error));
+ ev->select_max_fd = -1;
+
+ return 0;
+}
+
+static int fdevent_select_event_del(fdevents *ev, int fde_ndx, int fd) {
+ if (fde_ndx < 0) return -1;
+
+ FD_CLR(fd, &(ev->select_set_read));
+ FD_CLR(fd, &(ev->select_set_write));
+ FD_CLR(fd, &(ev->select_set_error));
+
+ return -1;
+}
+
+static int fdevent_select_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
+ UNUSED(fde_ndx);
+
+ /* we should be protected by max-fds, but you never know */
+ assert(fd < FD_SETSIZE);
+
+ if (events & FDEVENT_IN) {
+ FD_SET(fd, &(ev->select_set_read));
+ FD_CLR(fd, &(ev->select_set_write));
+ }
+ if (events & FDEVENT_OUT) {
+ FD_CLR(fd, &(ev->select_set_read));
+ FD_SET(fd, &(ev->select_set_write));
+ }
+ FD_SET(fd, &(ev->select_set_error));
+
+ if (fd > ev->select_max_fd) ev->select_max_fd = fd;
+
+ return fd;
+}
+
+static int fdevent_select_poll(fdevents *ev, int timeout_ms) {
+ struct timeval tv;
+
+ tv.tv_sec = timeout_ms / 1000;
+ tv.tv_usec = (timeout_ms % 1000) * 1000;
+
+ ev->select_read = ev->select_set_read;
+ ev->select_write = ev->select_set_write;
+ ev->select_error = ev->select_set_error;
+
+ return select(ev->select_max_fd + 1, &(ev->select_read), &(ev->select_write), &(ev->select_error), &tv);
+}
+
+static int fdevent_select_event_get_revent(fdevents *ev, size_t ndx) {
+ int revents = 0;
+
+ if (FD_ISSET(ndx, &(ev->select_read))) {
+ revents |= FDEVENT_IN;
+ }
+ if (FD_ISSET(ndx, &(ev->select_write))) {
+ revents |= FDEVENT_OUT;
+ }
+ if (FD_ISSET(ndx, &(ev->select_error))) {
+ revents |= FDEVENT_ERR;
+ }
+
+ return revents;
+}
+
+static int fdevent_select_event_get_fd(fdevents *ev, size_t ndx) {
+ UNUSED(ev);
+
+ return ndx;
+}
+
+static int fdevent_select_event_next_fdndx(fdevents *ev, int ndx) {
+ int i;
+
+ i = (ndx < 0) ? 0 : ndx + 1;
+
+ for (; i < ev->select_max_fd + 1; i++) {
+ if (FD_ISSET(i, &(ev->select_read))) break;
+ if (FD_ISSET(i, &(ev->select_write))) break;
+ if (FD_ISSET(i, &(ev->select_error))) break;
+ }
+
+ return i;
+}
+
+int fdevent_select_init(fdevents *ev) {
+ ev->type = FDEVENT_HANDLER_SELECT;
+#define SET(x) \
+ ev->x = fdevent_select_##x;
+
+ SET(reset);
+ SET(poll);
+
+ SET(event_del);
+ SET(event_add);
+
+ SET(event_next_fdndx);
+ SET(event_get_fd);
+ SET(event_get_revent);
+
+ return 0;
+}
+
+#else
+int fdevent_select_init(fdevents *ev) {
+ UNUSED(ev);
+
+ return -1;
+}
+#endif
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_solaris_devpoll.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_solaris_devpoll.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_solaris_devpoll.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/fdevent_solaris_devpoll.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,158 @@
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+
+#include "fdevent.h"
+#include "settings.h"
+#include "buffer.h"
+
+#ifdef USE_SOLARIS_DEVPOLL
+
+static void fdevent_solaris_devpoll_free(fdevents *ev) {
+ free(ev->devpollfds);
+ close(ev->devpoll_fd);
+}
+
+/* return -1 is fine here */
+
+static int fdevent_solaris_devpoll_event_del(fdevents *ev, int fde_ndx, int fd) {
+ struct pollfd pfd;
+
+ if (fde_ndx < 0) return -1;
+
+ pfd.fd = fd;
+ pfd.events = POLLREMOVE;
+ pfd.revents = 0;
+
+ if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
+ fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n",
+ __FILE__, __LINE__,
+ fd, strerror(errno));
+
+ return -1;
+ }
+
+ return -1;
+}
+
+static int fdevent_solaris_devpoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
+ struct pollfd pfd;
+ int add = 0;
+
+ if (fde_ndx == -1) add = 1;
+
+ pfd.fd = fd;
+ pfd.events = events;
+ pfd.revents = 0;
+
+ if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
+ fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n",
+ __FILE__, __LINE__,
+ fd, strerror(errno));
+
+ return -1;
+ }
+
+ return fd;
+}
+
+static int fdevent_solaris_devpoll_poll(fdevents *ev, int timeout_ms) {
+ struct dvpoll dopoll;
+ int ret;
+
+ dopoll.dp_timeout = timeout_ms;
+ dopoll.dp_nfds = ev->maxfds - 1;
+ dopoll.dp_fds = ev->devpollfds;
+
+ ret = ioctl(ev->devpoll_fd, DP_POLL, &dopoll);
+
+ return ret;
+}
+
+static int fdevent_solaris_devpoll_event_get_revent(fdevents *ev, size_t ndx) {
+ return ev->devpollfds[ndx].revents;
+}
+
+static int fdevent_solaris_devpoll_event_get_fd(fdevents *ev, size_t ndx) {
+ return ev->devpollfds[ndx].fd;
+}
+
+static int fdevent_solaris_devpoll_event_next_fdndx(fdevents *ev, int last_ndx) {
+ size_t i;
+
+ UNUSED(ev);
+
+ i = (last_ndx < 0) ? 0 : last_ndx + 1;
+
+ return i;
+}
+
+int fdevent_solaris_devpoll_reset(fdevents *ev) {
+ /* a forked process does only inherit the filedescriptor,
+ * but every operation on the device will lead to a EACCES */
+ if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
+ fprintf(stderr, "%s.%d: opening /dev/poll failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
+ __FILE__, __LINE__, strerror(errno));
+
+ return -1;
+ }
+
+ if (fcntl(ev->devpoll_fd, F_SETFD, FD_CLOEXEC) < 0) {
+ fprintf(stderr, "%s.%d: opening /dev/poll failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
+ __FILE__, __LINE__, strerror(errno));
+
+ close(ev->devpoll_fd);
+
+ return -1;
+ }
+ return 0;
+}
+int fdevent_solaris_devpoll_init(fdevents *ev) {
+ ev->type = FDEVENT_HANDLER_SOLARIS_DEVPOLL;
+#define SET(x) \
+ ev->x = fdevent_solaris_devpoll_##x;
+
+ SET(free);
+ SET(poll);
+ SET(reset);
+
+ SET(event_del);
+ SET(event_add);
+
+ SET(event_next_fdndx);
+ SET(event_get_fd);
+ SET(event_get_revent);
+
+ ev->devpollfds = malloc(sizeof(*ev->devpollfds) * ev->maxfds);
+
+ if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
+ fprintf(stderr, "%s.%d: opening /dev/poll failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
+ __FILE__, __LINE__, strerror(errno));
+
+ return -1;
+ }
+
+ /* we just wanted to check if it works */
+ close(ev->devpoll_fd);
+
+ ev->devpoll_fd = -1;
+
+ return 0;
+}
+
+#else
+int fdevent_solaris_devpoll_init(fdevents *ev) {
+ UNUSED(ev);
+
+ fprintf(stderr, "%s.%d: solaris-devpoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
+ __FILE__, __LINE__);
+
+ return -1;
+}
+#endif
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http-header-glue.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http-header-glue.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http-header-glue.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http-header-glue.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,350 @@
+#define _GNU_SOURCE
+
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#include "base.h"
+#include "array.h"
+#include "buffer.h"
+#include "log.h"
+#include "etag.h"
+
+/*
+ * This was 'borrowed' from tcpdump.
+ *
+ *
+ * This is fun.
+ *
+ * In older BSD systems, socket addresses were fixed-length, and
+ * "sizeof (struct sockaddr)" gave the size of the structure.
+ * All addresses fit within a "struct sockaddr".
+ *
+ * In newer BSD systems, the socket address is variable-length, and
+ * there's an "sa_len" field giving the length of the structure;
+ * this allows socket addresses to be longer than 2 bytes of family
+ * and 14 bytes of data.
+ *
+ * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553
+ * variant of the old BSD scheme (with "struct sockaddr_storage" rather
+ * than "struct sockaddr"), and some use the new BSD scheme.
+ *
+ * Some versions of GNU libc use neither scheme, but has an "SA_LEN()"
+ * macro that determines the size based on the address family. Other
+ * versions don't have "SA_LEN()" (as it was in drafts of RFC 2553
+ * but not in the final version). On the latter systems, we explicitly
+ * check the AF_ type to determine the length; we assume that on
+ * all those systems we have "struct sockaddr_storage".
+ */
+
+#ifdef HAVE_IPV6
+# ifndef SA_LEN
+# ifdef HAVE_SOCKADDR_SA_LEN
+# define SA_LEN(addr) ((addr)->sa_len)
+# else /* HAVE_SOCKADDR_SA_LEN */
+# ifdef HAVE_STRUCT_SOCKADDR_STORAGE
+static size_t get_sa_len(const struct sockaddr *addr) {
+ switch (addr->sa_family) {
+
+# ifdef AF_INET
+ case AF_INET:
+ return (sizeof (struct sockaddr_in));
+# endif
+
+# ifdef AF_INET6
+ case AF_INET6:
+ return (sizeof (struct sockaddr_in6));
+# endif
+
+ default:
+ return (sizeof (struct sockaddr));
+
+ }
+}
+# define SA_LEN(addr) (get_sa_len(addr))
+# else /* HAVE_SOCKADDR_STORAGE */
+# define SA_LEN(addr) (sizeof (struct sockaddr))
+# endif /* HAVE_SOCKADDR_STORAGE */
+# endif /* HAVE_SOCKADDR_SA_LEN */
+# endif /* SA_LEN */
+#endif
+
+
+
+
+int response_header_insert(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) {
+ data_string *ds;
+
+ UNUSED(srv);
+
+ if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
+ ds = data_response_init();
+ }
+ buffer_copy_string_len(ds->key, key, keylen);
+ buffer_copy_string_len(ds->value, value, vallen);
+
+ array_insert_unique(con->response.headers, (data_unset *)ds);
+
+ return 0;
+}
+
+int response_header_overwrite(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) {
+ data_string *ds;
+
+ UNUSED(srv);
+
+ /* if there already is a key by this name overwrite the value */
+ if (NULL != (ds = (data_string *)array_get_element(con->response.headers, key))) {
+ buffer_copy_string(ds->value, value);
+
+ return 0;
+ }
+
+ return response_header_insert(srv, con, key, keylen, value, vallen);
+}
+
+int http_response_redirect_to_directory(server *srv, connection *con) {
+ buffer *o;
+
+ o = buffer_init();
+
+ if (con->conf.is_ssl) {
+ buffer_copy_string(o, "https://");
+ } else {
+ buffer_copy_string(o, "http://");
+ }
+ if (con->uri.authority->used) {
+ buffer_append_string_buffer(o, con->uri.authority);
+ } else {
+ /* get the name of the currently connected socket */
+ struct hostent *he;
+#ifdef HAVE_IPV6
+ char hbuf[256];
+#endif
+ sock_addr our_addr;
+ socklen_t our_addr_len;
+
+ our_addr_len = sizeof(our_addr);
+
+ if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
+ con->http_status = 500;
+
+ log_error_write(srv, __FILE__, __LINE__, "ss",
+ "can't get sockname", strerror(errno));
+
+ buffer_free(o);
+ return 0;
+ }
+
+
+ /* Lookup name: secondly try to get hostname for bind address */
+ switch(our_addr.plain.sa_family) {
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6),
+ SA_LEN((const struct sockaddr *)&our_addr.ipv6),
+ hbuf, sizeof(hbuf), NULL, 0, 0)) {
+
+ char dst[INET6_ADDRSTRLEN];
+
+ log_error_write(srv, __FILE__, __LINE__,
+ "SSS", "NOTICE: getnameinfo failed: ",
+ strerror(errno), ", using ip-address instead");
+
+ buffer_append_string(o,
+ inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr,
+ dst, sizeof(dst)));
+ } else {
+ buffer_append_string(o, hbuf);
+ }
+ break;
+#endif
+ case AF_INET:
+ if (NULL == (he = gethostbyaddr((char *)&our_addr.ipv4.sin_addr, sizeof(struct in_addr), AF_INET))) {
+ log_error_write(srv, __FILE__, __LINE__,
+ "SdS", "NOTICE: gethostbyaddr failed: ",
+ h_errno, ", using ip-address instead");
+
+ buffer_append_string(o, inet_ntoa(our_addr.ipv4.sin_addr));
+ } else {
+ buffer_append_string(o, he->h_name);
+ }
+ break;
+ default:
+ log_error_write(srv, __FILE__, __LINE__,
+ "S", "ERROR: unsupported address-type");
+
+ buffer_free(o);
+ return -1;
+ }
+
+ if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) ||
+ (con->conf.is_ssl == 1 && srv->srvconf.port == 443))) {
+ buffer_append_string(o, ":");
+ buffer_append_long(o, srv->srvconf.port);
+ }
+ }
+ buffer_append_string_buffer(o, con->uri.path);
+ buffer_append_string(o, "/");
+ if (!buffer_is_empty(con->uri.query)) {
+ buffer_append_string(o, "?");
+ buffer_append_string_buffer(o, con->uri.query);
+ }
+
+ response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(o));
+
+ con->http_status = 301;
+ con->file_finished = 1;
+
+ buffer_free(o);
+
+ return 0;
+}
+
+buffer * strftime_cache_get(server *srv, time_t last_mod) {
+ struct tm *tm;
+ size_t i;
+
+ for (i = 0; i < FILE_CACHE_MAX; i++) {
+ /* found cache-entry */
+ if (srv->mtime_cache[i].mtime == last_mod) return srv->mtime_cache[i].str;
+
+ /* found empty slot */
+ if (srv->mtime_cache[i].mtime == 0) break;
+ }
+
+ if (i == FILE_CACHE_MAX) {
+ i = 0;
+ }
+
+ srv->mtime_cache[i].mtime = last_mod;
+ buffer_prepare_copy(srv->mtime_cache[i].str, 1024);
+ tm = gmtime(&(srv->mtime_cache[i].mtime));
+ srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr,
+ srv->mtime_cache[i].str->size - 1,
+ "%a, %d %b %Y %H:%M:%S GMT", tm);
+ srv->mtime_cache[i].str->used++;
+
+ return srv->mtime_cache[i].str;
+}
+
+
+int http_response_handle_cachable(server *srv, connection *con, buffer *mtime) {
+ /*
+ * 14.26 If-None-Match
+ * [...]
+ * If none of the entity tags match, then the server MAY perform the
+ * requested method as if the If-None-Match header field did not exist,
+ * but MUST also ignore any If-Modified-Since header field(s) in the
+ * request. That is, if no entity tags match, then the server MUST NOT
+ * return a 304 (Not Modified) response.
+ */
+
+ /* last-modified handling */
+ if (con->request.http_if_none_match) {
+ if (etag_is_equal(con->physical.etag, con->request.http_if_none_match)) {
+ if (con->request.http_method == HTTP_METHOD_GET ||
+ con->request.http_method == HTTP_METHOD_HEAD) {
+
+ /* check if etag + last-modified */
+ if (con->request.http_if_modified_since) {
+ size_t used_len;
+ char *semicolon;
+
+ if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
+ used_len = strlen(con->request.http_if_modified_since);
+ } else {
+ used_len = semicolon - con->request.http_if_modified_since;
+ }
+
+ if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
+ con->http_status = 304;
+ return HANDLER_FINISHED;
+ } else {
+ char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
+ time_t t_header, t_file;
+ struct tm tm;
+
+ /* check if we can safely copy the string */
+ if (used_len >= sizeof(buf)) {
+ log_error_write(srv, __FILE__, __LINE__, "ssdd",
+ "DEBUG: Last-Modified check failed as the received timestamp was too long:",
+ con->request.http_if_modified_since, used_len, sizeof(buf) - 1);
+
+ con->http_status = 412;
+ return HANDLER_FINISHED;
+ }
+
+
+ strncpy(buf, con->request.http_if_modified_since, used_len);
+ buf[used_len] = '\0';
+
+ if (NULL == strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm)) {
+ con->http_status = 412;
+ return HANDLER_FINISHED;
+ }
+ t_header = mktime(&tm);
+
+ strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
+ t_file = mktime(&tm);
+
+ if (t_file > t_header) return HANDLER_GO_ON;
+
+ con->http_status = 304;
+ return HANDLER_FINISHED;
+ }
+ } else {
+ con->http_status = 304;
+ return HANDLER_FINISHED;
+ }
+ } else {
+ con->http_status = 412;
+ return HANDLER_FINISHED;
+ }
+ }
+ } else if (con->request.http_if_modified_since) {
+ size_t used_len;
+ char *semicolon;
+
+ if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
+ used_len = strlen(con->request.http_if_modified_since);
+ } else {
+ used_len = semicolon - con->request.http_if_modified_since;
+ }
+
+ if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
+ con->http_status = 304;
+ return HANDLER_FINISHED;
+ } else {
+ char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
+ time_t t_header, t_file;
+ struct tm tm;
+
+ /* convert to timestamp */
+ if (used_len >= sizeof(buf)) return HANDLER_GO_ON;
+
+ strncpy(buf, con->request.http_if_modified_since, used_len);
+ buf[used_len] = '\0';
+
+ if (NULL == strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm)) {
+ /**
+ * parsing failed, let's get out of here
+ */
+ log_error_write(srv, __FILE__, __LINE__, "ss",
+ "strptime() failed on", buf);
+ return HANDLER_GO_ON;
+ }
+ t_header = mktime(&tm);
+
+ strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
+ t_file = mktime(&tm);
+
+ if (t_file > t_header) return HANDLER_GO_ON;
+
+ con->http_status = 304;
+ return HANDLER_FINISHED;
+ }
+ }
+
+ return HANDLER_GO_ON;
+}
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,1186 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_CRYPT_H
+# include <crypt.h>
+#elif defined(__linux__)
+/* linux needs _XOPEN_SOURCE */
+# define _XOPEN_SOURCE
+#endif
+
+#ifdef HAVE_LIBCRYPT
+# define HAVE_CRYPT
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "server.h"
+#include "log.h"
+#include "http_auth.h"
+#include "http_auth_digest.h"
+#include "inet_ntop_cache.h"
+#include "stream.h"
+
+#ifdef USE_OPENSSL
+# include <openssl/md5.h>
+#else
+# include "md5.h"
+#endif
+
+/**
+ * the $apr1$ handling is taken from apache 1.3.x
+ */
+
+/*
+ * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
+ * MD5 crypt() function, which is licenced as follows:
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <ph...@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
+
+static const char base64_pad = '=';
+
+static const short base64_reverse_table[256] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+
+static unsigned char * base64_decode(buffer *out, const char *in) {
+ unsigned char *result;
+ int ch, j = 0, k;
+ size_t i;
+
+ size_t in_len = strlen(in);
+
+ buffer_prepare_copy(out, in_len);
+
+ result = (unsigned char *)out->ptr;
+
+ ch = in[0];
+ /* run through the whole string, converting as we go */
+ for (i = 0; i < in_len; i++) {
+ ch = in[i];
+
+ if (ch == '\0') break;
+
+ if (ch == base64_pad) break;
+
+ ch = base64_reverse_table[ch];
+ if (ch < 0) continue;
+
+ switch(i % 4) {
+ case 0:
+ result[j] = ch << 2;
+ break;
+ case 1:
+ result[j++] |= ch >> 4;
+ result[j] = (ch & 0x0f) << 4;
+ break;
+ case 2:
+ result[j++] |= ch >>2;
+ result[j] = (ch & 0x03) << 6;
+ break;
+ case 3:
+ result[j++] |= ch;
+ break;
+ }
+ }
+ k = j;
+ /* mop things up if we ended on a boundary */
+ if (ch == base64_pad) {
+ switch(i % 4) {
+ case 0:
+ case 1:
+ return NULL;
+ case 2:
+ k++;
+ case 3:
+ result[k++] = 0;
+ }
+ }
+ result[k] = '\0';
+
+ out->used = k;
+
+ return result;
+}
+
+static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *username, buffer *realm, buffer *password) {
+ int ret = -1;
+
+ if (!username->used|| !realm->used) return -1;
+
+ if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
+ stream f;
+ char * f_line;
+
+ if (buffer_is_empty(p->conf.auth_htdigest_userfile)) return -1;
+
+ if (0 != stream_open(&f, p->conf.auth_htdigest_userfile)) {
+ log_error_write(srv, __FILE__, __LINE__, "sbss", "opening digest-userfile", p->conf.auth_htdigest_userfile, "failed:", strerror(errno));
+
+ return -1;
+ }
+
+ f_line = f.start;
+
+ while (f_line - f.start != f.size) {
+ char *f_user, *f_pwd, *e, *f_realm;
+ size_t u_len, pwd_len, r_len;
+
+ f_user = f_line;
+
+ /*
+ * htdigest format
+ *
+ * user:realm:md5(user:realm:password)
+ */
+
+ if (NULL == (f_realm = memchr(f_user, ':', f.size - (f_user - f.start) ))) {
+ log_error_write(srv, __FILE__, __LINE__, "sbs",
+ "parsed error in", p->conf.auth_htdigest_userfile,
+ "expected 'username:realm:hashed password'");
+
+ stream_close(&f);
+
+ return -1;
+ }
+
+ if (NULL == (f_pwd = memchr(f_realm + 1, ':', f.size - (f_realm + 1 - f.start)))) {
+ log_error_write(srv, __FILE__, __LINE__, "sbs",
+ "parsed error in", p->conf.auth_plain_userfile,
+ "expected 'username:realm:hashed password'");
+
+ stream_close(&f);
+
+ return -1;
+ }
+
+ /* get pointers to the fields */
+ u_len = f_realm - f_user;
+ f_realm++;
+ r_len = f_pwd - f_realm;
+ f_pwd++;
+
+ if (NULL != (e = memchr(f_pwd, '\n', f.size - (f_pwd - f.start)))) {
+ pwd_len = e - f_pwd;
+ } else {
+ pwd_len = f.size - (f_pwd - f.start);
+ }
+
+ if (username->used - 1 == u_len &&
+ (realm->used - 1 == r_len) &&
+ (0 == strncmp(username->ptr, f_user, u_len)) &&
+ (0 == strncmp(realm->ptr, f_realm, r_len))) {
+ /* found */
+
+ buffer_copy_string_len(password, f_pwd, pwd_len);
+
+ ret = 0;
+ break;
+ }
+
+ /* EOL */
+ if (!e) break;
+
+ f_line = e + 1;
+ }
+
+ stream_close(&f);
+ } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD ||
+ p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
+ stream f;
+ char * f_line;
+ buffer *auth_fn;
+
+ auth_fn = (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) ? p->conf.auth_htpasswd_userfile : p->conf.auth_plain_userfile;
+
+ if (buffer_is_empty(auth_fn)) return -1;
+
+ if (0 != stream_open(&f, auth_fn)) {
+ log_error_write(srv, __FILE__, __LINE__, "sbss",
+ "opening plain-userfile", auth_fn, "failed:", strerror(errno));
+
+ return -1;
+ }
+
+ f_line = f.start;
+
+ while (f_line - f.start != f.size) {
+ char *f_user, *f_pwd, *e;
+ size_t u_len, pwd_len;
+
+ f_user = f_line;
+
+ /*
+ * htpasswd format
+ *
+ * user:crypted passwd
+ */
+
+ if (NULL == (f_pwd = memchr(f_user, ':', f.size - (f_user - f.start) ))) {
+ log_error_write(srv, __FILE__, __LINE__, "sbs",
+ "parsed error in", auth_fn,
+ "expected 'username:hashed password'");
+
+ stream_close(&f);
+
+ return -1;
+ }
+
+ /* get pointers to the fields */
+ u_len = f_pwd - f_user;
+ f_pwd++;
+
+ if (NULL != (e = memchr(f_pwd, '\n', f.size - (f_pwd - f.start)))) {
+ pwd_len = e - f_pwd;
+ } else {
+ pwd_len = f.size - (f_pwd - f.start);
+ }
+
+ if (username->used - 1 == u_len &&
+ (0 == strncmp(username->ptr, f_user, u_len))) {
+ /* found */
+
+ buffer_copy_string_len(password, f_pwd, pwd_len);
+
+ ret = 0;
+ break;
+ }
+
+ /* EOL */
+ if (!e) break;
+
+ f_line = e + 1;
+ }
+
+ stream_close(&f);
+ } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
+ ret = 0;
+ } else {
+ return -1;
+ }
+
+ return ret;
+}
+
+static int http_auth_match_rules(server *srv, mod_auth_plugin_data *p, const char *url, const char *username, const char *group, const char *host) {
+ const char *r = NULL, *rules = NULL;
+ size_t i;
+ int username_len;
+ data_string *require;
+ array *req;
+
+ UNUSED(group);
+ UNUSED(host);
+
+ /* check what has to be match to fullfil the request */
+ /* search auth-directives for path */
+ for (i = 0; i < p->conf.auth_require->used; i++) {
+ if (p->conf.auth_require->data[i]->key->used == 0) continue;
+
+ if (0 == strncmp(url, p->conf.auth_require->data[i]->key->ptr, p->conf.auth_require->data[i]->key->used - 1)) {
+ break;
+ }
+ }
+
+ if (i == p->conf.auth_require->used) {
+ return -1;
+ }
+
+ req = ((data_array *)(p->conf.auth_require->data[i]))->value;
+
+ require = (data_string *)array_get_element(req, "require");
+
+ /* if we get here, the user we got a authed user */
+ if (0 == strcmp(require->value->ptr, "valid-user")) {
+ return 0;
+ }
+
+ /* user=name1|group=name3|host=name4 */
+
+ /* seperate the string by | */
+#if 0
+ log_error_write(srv, __FILE__, __LINE__, "sb", "rules", require->value);
+#endif
+
+ username_len = username ? strlen(username) : 0;
+
+ r = rules = require->value->ptr;
+
+ while (1) {
+ const char *eq;
+ const char *k, *v, *e;
+ int k_len, v_len, r_len;
+
+ e = strchr(r, '|');
+
+ if (e) {
+ r_len = e - r;
+ } else {
+ r_len = strlen(rules) - (r - rules);
+ }
+
+ /* from r to r + r_len is a rule */
+
+ if (0 == strncmp(r, "valid-user", r_len)) {
+ log_error_write(srv, __FILE__, __LINE__, "sb",
+ "parsing the 'require' section in 'auth.require' failed: valid-user cannot be combined with other require rules",
+ require->value);
+ return -1;
+ }
+
+ /* search for = in the rules */
+ if (NULL == (eq = strchr(r, '='))) {
+ log_error_write(srv, __FILE__, __LINE__, "sb",
+ "parsing the 'require' section in 'auth.require' failed: a = is missing",
+ require->value);
+ return -1;
+ }
+
+ /* = out of range */
+ if (eq > r + r_len) {
+ log_error_write(srv, __FILE__, __LINE__, "sb",
+ "parsing the 'require' section in 'auth.require' failed: = out of range",
+ require->value);
+
+ return -1;
+ }
+
+ /* the part before the = is user|group|host */
+
+ k = r;
+ k_len = eq - r;
+ v = eq + 1;
+ v_len = r_len - k_len - 1;
+
+ if (k_len == 4) {
+ if (0 == strncmp(k, "user", k_len)) {
+ if (username &&
+ username_len == v_len &&
+ 0 == strncmp(username, v, v_len)) {
+ return 0;
+ }
+ } else if (0 == strncmp(k, "host", k_len)) {
+ log_error_write(srv, __FILE__, __LINE__, "s", "host ... (not implemented)");
+ } else {
+ log_error_write(srv, __FILE__, __LINE__, "s", "unknown key");
+ return -1;
+ }
+ } else if (k_len == 5) {
+ if (0 == strncmp(k, "group", k_len)) {
+ log_error_write(srv, __FILE__, __LINE__, "s", "group ... (not implemented)");
+ } else {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "unknown key", k);
+ return -1;
+ }
+ } else {
+ log_error_write(srv, __FILE__, __LINE__, "s", "unknown key");
+ return -1;
+ }
+
+ if (!e) break;
+ r = e + 1;
+ }
+
+ log_error_write(srv, __FILE__, __LINE__, "s", "nothing matched");
+
+ return -1;
+}
+
+#define APR_MD5_DIGESTSIZE 16
+#define APR1_ID "$apr1$"
+
+/*
+ * The following MD5 password encryption code was largely borrowed from
+ * the FreeBSD 3.0 /usr/src/lib/libcrypt/crypt.c file, which is
+ * licenced as stated at the top of this file.
+ */
+
+static void to64(char *s, unsigned long v, int n)
+{
+ static unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+ while (--n >= 0) {
+ *s++ = itoa64[v&0x3f];
+ v >>= 6;
+ }
+}
+
+static void apr_md5_encode(const char *pw, const char *salt, char *result, size_t nbytes) {
+ /*
+ * Minimum size is 8 bytes for salt, plus 1 for the trailing NUL,
+ * plus 4 for the '$' separators, plus the password hash itself.
+ * Let's leave a goodly amount of leeway.
+ */
+
+ char passwd[120], *p;
+ const char *sp, *ep;
+ unsigned char final[APR_MD5_DIGESTSIZE];
+ ssize_t sl, pl, i;
+ MD5_CTX ctx, ctx1;
+ unsigned long l;
+
+ /*
+ * Refine the salt first. It's possible we were given an already-hashed
+ * string as the salt argument, so extract the actual salt value from it
+ * if so. Otherwise just use the string up to the first '$' as the salt.
+ */
+ sp = salt;
+
+ /*
+ * If it starts with the magic string, then skip that.
+ */
+ if (!strncmp(sp, APR1_ID, strlen(APR1_ID))) {
+ sp += strlen(APR1_ID);
+ }
+
+ /*
+ * It stops at the first '$' or 8 chars, whichever comes first
+ */
+ for (ep = sp; (*ep != '\0') && (*ep != '$') && (ep < (sp + 8)); ep++) {
+ continue;
+ }
+
+ /*
+ * Get the length of the true salt
+ */
+ sl = ep - sp;
+
+ /*
+ * 'Time to make the doughnuts..'
+ */
+ MD5_Init(&ctx);
+
+ /*
+ * The password first, since that is what is most unknown
+ */
+ MD5_Update(&ctx, pw, strlen(pw));
+
+ /*
+ * Then our magic string
+ */
+ MD5_Update(&ctx, APR1_ID, strlen(APR1_ID));
+
+ /*
+ * Then the raw salt
+ */
+ MD5_Update(&ctx, sp, sl);
+
+ /*
+ * Then just as many characters of the MD5(pw, salt, pw)
+ */
+ MD5_Init(&ctx1);
+ MD5_Update(&ctx1, pw, strlen(pw));
+ MD5_Update(&ctx1, sp, sl);
+ MD5_Update(&ctx1, pw, strlen(pw));
+ MD5_Final(final, &ctx1);
+ for (pl = strlen(pw); pl > 0; pl -= APR_MD5_DIGESTSIZE) {
+ MD5_Update(&ctx, final,
+ (pl > APR_MD5_DIGESTSIZE) ? APR_MD5_DIGESTSIZE : pl);
+ }
+
+ /*
+ * Don't leave anything around in vm they could use.
+ */
+ memset(final, 0, sizeof(final));
+
+ /*
+ * Then something really weird...
+ */
+ for (i = strlen(pw); i != 0; i >>= 1) {
+ if (i & 1) {
+ MD5_Update(&ctx, final, 1);
+ }
+ else {
+ MD5_Update(&ctx, pw, 1);
+ }
+ }
+
+ /*
+ * Now make the output string. We know our limitations, so we
+ * can use the string routines without bounds checking.
+ */
+ strcpy(passwd, APR1_ID);
+ strncat(passwd, sp, sl);
+ strcat(passwd, "$");
+
+ MD5_Final(final, &ctx);
+
+ /*
+ * And now, just to make sure things don't run too fast..
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ for (i = 0; i < 1000; i++) {
+ MD5_Init(&ctx1);
+ if (i & 1) {
+ MD5_Update(&ctx1, pw, strlen(pw));
+ }
+ else {
+ MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE);
+ }
+ if (i % 3) {
+ MD5_Update(&ctx1, sp, sl);
+ }
+
+ if (i % 7) {
+ MD5_Update(&ctx1, pw, strlen(pw));
+ }
+
+ if (i & 1) {
+ MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE);
+ }
+ else {
+ MD5_Update(&ctx1, pw, strlen(pw));
+ }
+ MD5_Final(final,&ctx1);
+ }
+
+ p = passwd + strlen(passwd);
+
+ l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p, l, 4); p += 4;
+ l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p, l, 4); p += 4;
+ l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p, l, 4); p += 4;
+ l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p, l, 4); p += 4;
+ l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p, l, 4); p += 4;
+ l = final[11] ; to64(p, l, 2); p += 2;
+ *p = '\0';
+
+ /*
+ * Don't leave anything around in vm they could use.
+ */
+ memset(final, 0, sizeof(final));
+
+ /* FIXME
+ */
+#define apr_cpystrn strncpy
+ apr_cpystrn(result, passwd, nbytes - 1);
+}
+
+
+/**
+ *
+ *
+ * @param password password-string from the auth-backend
+ * @param pw password-string from the client
+ */
+
+static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p, array *req, buffer *username, buffer *realm, buffer *password, const char *pw) {
+ UNUSED(srv);
+ UNUSED(req);
+
+ if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
+ /*
+ * htdigest format
+ *
+ * user:realm:md5(user:realm:password)
+ */
+
+ MD5_CTX Md5Ctx;
+ HASH HA1;
+ char a1[256];
+
+ MD5_Init(&Md5Ctx);
+ MD5_Update(&Md5Ctx, (unsigned char *)username->ptr, username->used - 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)realm->ptr, realm->used - 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)pw, strlen(pw));
+ MD5_Final(HA1, &Md5Ctx);
+
+ CvtHex(HA1, a1);
+
+ if (0 == strcmp(password->ptr, a1)) {
+ return 0;
+ }
+ } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) {
+ char sample[120];
+ if (!strncmp(password->ptr, APR1_ID, strlen(APR1_ID))) {
+ /*
+ * The hash was created using $apr1$ custom algorithm.
+ */
+ apr_md5_encode(pw, password->ptr, sample, sizeof(sample));
+ return (strcmp(sample, password->ptr) == 0) ? 0 : 1;
+ } else {
+#ifdef HAVE_CRYPT
+ char salt[32];
+ char *crypted;
+ size_t salt_len = 0;
+ /*
+ * htpasswd format
+ *
+ * user:crypted password
+ */
+
+ /*
+ * Algorithm Salt
+ * CRYPT_STD_DES 2-character (Default)
+ * CRYPT_EXT_DES 9-character
+ * CRYPT_MD5 12-character beginning with $1$
+ * CRYPT_BLOWFISH 16-character beginning with $2$
+ */
+
+ if (password->used < 13 + 1) {
+ fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
+ return -1;
+ }
+
+ if (password->used == 13 + 1) {
+ /* a simple DES password is 2 + 11 characters */
+ salt_len = 2;
+ } else if (password->ptr[0] == '$' && password->ptr[2] == '$') {
+ char *dollar = NULL;
+
+ if (NULL == (dollar = strchr(password->ptr + 3, '$'))) {
+ fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
+ return -1;
+ }
+
+ salt_len = dollar - password->ptr;
+ }
+
+ if (salt_len > sizeof(salt) - 1) {
+ fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
+ return -1;
+ }
+
+ strncpy(salt, password->ptr, salt_len);
+
+ salt[salt_len] = '\0';
+
+ crypted = crypt(pw, salt);
+
+ if (0 == strcmp(password->ptr, crypted)) {
+ return 0;
+ } else {
+ fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
+ }
+
+#endif
+ }
+ } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
+ if (0 == strcmp(password->ptr, pw)) {
+ return 0;
+ }
+ } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
+#ifdef USE_LDAP
+ LDAP *ldap;
+ LDAPMessage *lm, *first;
+ char *dn;
+ int ret;
+ char *attrs[] = { LDAP_NO_ATTRS, NULL };
+ size_t i;
+
+ /* for now we stay synchronous */
+
+ /*
+ * 1. connect anonymously (done in plugin init)
+ * 2. get DN for uid = username
+ * 3. auth against ldap server
+ * 4. (optional) check a field
+ * 5. disconnect
+ *
+ */
+
+ /* check username
+ *
+ * we have to protect us againt username which modifies out filter in
+ * a unpleasant way
+ */
+
+ for (i = 0; i < username->used - 1; i++) {
+ char c = username->ptr[i];
+
+ if (!isalpha(c) &&
+ !isdigit(c)) {
+
+ log_error_write(srv, __FILE__, __LINE__, "sbd",
+ "ldap: invalid character (a-zA-Z0-9 allowed) in username:", username, i);
+
+ return -1;
+ }
+ }
+
+ if (p->conf.auth_ldap_allow_empty_pw != 1 && pw[0] == '\0')
+ return -1;
+
+ /* build filter */
+ buffer_copy_string_buffer(p->ldap_filter, p->conf.ldap_filter_pre);
+ buffer_append_string_buffer(p->ldap_filter, username);
+ buffer_append_string_buffer(p->ldap_filter, p->conf.ldap_filter_post);
+
+
+ /* 2. */
+ if (p->conf.ldap == NULL ||
+ LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) {
+ if (auth_ldap_init(srv, &p->conf) != HANDLER_GO_ON)
+ return -1;
+ if (LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) {
+
+ log_error_write(srv, __FILE__, __LINE__, "sssb",
+ "ldap:", ldap_err2string(ret), "filter:", p->ldap_filter);
+
+ return -1;
+ }
+ }
+
+ if (NULL == (first = ldap_first_entry(p->conf.ldap, lm))) {
+ log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
+
+ ldap_msgfree(lm);
+
+ return -1;
+ }
+
+ if (NULL == (dn = ldap_get_dn(p->conf.ldap, first))) {
+ log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
+
+ ldap_msgfree(lm);
+
+ return -1;
+ }
+
+ ldap_msgfree(lm);
+
+
+ /* 3. */
+ if (NULL == (ldap = ldap_init(p->conf.auth_ldap_hostname->ptr, LDAP_PORT))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));
+ return -1;
+ }
+
+ ret = LDAP_VERSION3;
+ if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
+
+ ldap_unbind_s(ldap);
+
+ return -1;
+ }
+
+ if (p->conf.auth_ldap_starttls == 1) {
+ if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(ldap, NULL, NULL))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));
+
+ ldap_unbind_s(ldap);
+
+ return -1;
+ }
+ }
+
+
+ if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, dn, pw))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
+
+ ldap_unbind_s(ldap);
+
+ return -1;
+ }
+
+ /* 5. */
+ ldap_unbind_s(ldap);
+
+ /* everything worked, good, access granted */
+
+ return 0;
+#endif
+ }
+ return -1;
+}
+
+int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str) {
+ buffer *username, *password;
+ char *pw;
+
+ data_string *realm;
+
+ realm = (data_string *)array_get_element(req, "realm");
+
+ username = buffer_init();
+
+ if (!base64_decode(username, realm_str)) {
+ log_error_write(srv, __FILE__, __LINE__, "sb", "decodeing base64-string failed", username);
+
+ buffer_free(username);
+ return 0;
+ }
+
+ /* r2 == user:password */
+ if (NULL == (pw = strchr(username->ptr, ':'))) {
+ log_error_write(srv, __FILE__, __LINE__, "sb", ": is missing in", username);
+
+ buffer_free(username);
+ return 0;
+ }
+
+ *pw++ = '\0';
+
+ username->used = pw - username->ptr;
+
+ password = buffer_init();
+ /* copy password to r1 */
+ if (http_auth_get_password(srv, p, username, realm->value, password)) {
+ buffer_free(username);
+ buffer_free(password);
+
+ log_error_write(srv, __FILE__, __LINE__, "s", "get_password failed");
+
+ return 0;
+ }
+
+ /* password doesn't match */
+ if (http_auth_basic_password_compare(srv, p, req, username, realm->value, password, pw)) {
+ log_error_write(srv, __FILE__, __LINE__, "sbbss", "password doesn't match for ", con->uri.path, username, ", IP:", inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
+
+ buffer_free(username);
+ buffer_free(password);
+
+ return 0;
+ }
+
+ /* value is our allow-rules */
+ if (http_auth_match_rules(srv, p, url->ptr, username->ptr, NULL, NULL)) {
+ buffer_free(username);
+ buffer_free(password);
+
+ log_error_write(srv, __FILE__, __LINE__, "s", "rules didn't match");
+
+ return 0;
+ }
+
+ /* remember the username */
+ buffer_copy_string_buffer(p->auth_user, username);
+
+ buffer_free(username);
+ buffer_free(password);
+
+ return 1;
+}
+
+typedef struct {
+ const char *key;
+ int key_len;
+ char **ptr;
+} digest_kv;
+
+int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str) {
+ char a1[256];
+ char a2[256];
+
+ char *username;
+ char *realm;
+ char *nonce;
+ char *uri;
+ char *algorithm;
+ char *qop;
+ char *cnonce;
+ char *nc;
+ char *respons;
+
+ char *e, *c;
+ const char *m = NULL;
+ int i;
+ buffer *password, *b, *username_buf, *realm_buf;
+
+ MD5_CTX Md5Ctx;
+ HASH HA1;
+ HASH HA2;
+ HASH RespHash;
+ HASHHEX HA2Hex;
+
+
+ /* init pointers */
+#define S(x) \
+ x, sizeof(x)-1, NULL
+ digest_kv dkv[10] = {
+ { S("username=") },
+ { S("realm=") },
+ { S("nonce=") },
+ { S("uri=") },
+ { S("algorithm=") },
+ { S("qop=") },
+ { S("cnonce=") },
+ { S("nc=") },
+ { S("response=") },
+
+ { NULL, 0, NULL }
+ };
+#undef S
+
+ dkv[0].ptr = &username;
+ dkv[1].ptr = &realm;
+ dkv[2].ptr = &nonce;
+ dkv[3].ptr = &uri;
+ dkv[4].ptr = &algorithm;
+ dkv[5].ptr = &qop;
+ dkv[6].ptr = &cnonce;
+ dkv[7].ptr = &nc;
+ dkv[8].ptr = &respons;
+ dkv[9].ptr = NULL;
+
+ UNUSED(req);
+
+ for (i = 0; dkv[i].key; i++) {
+ *(dkv[i].ptr) = NULL;
+ }
+
+
+ if (p->conf.auth_backend != AUTH_BACKEND_HTDIGEST &&
+ p->conf.auth_backend != AUTH_BACKEND_PLAIN) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "digest: unsupported backend (only htdigest or plain)");
+
+ return -1;
+ }
+
+ b = buffer_init_string(realm_str);
+
+ /* parse credentials from client */
+ for (c = b->ptr; *c; c++) {
+ /* skip whitespaces */
+ while (*c == ' ' || *c == '\t') c++;
+ if (!*c) break;
+
+ for (i = 0; dkv[i].key; i++) {
+ if ((0 == strncmp(c, dkv[i].key, dkv[i].key_len))) {
+ if ((c[dkv[i].key_len] == '"') &&
+ (NULL != (e = strchr(c + dkv[i].key_len + 1, '"')))) {
+ /* value with "..." */
+ *(dkv[i].ptr) = c + dkv[i].key_len + 1;
+ c = e;
+
+ *e = '\0';
+ } else if (NULL != (e = strchr(c + dkv[i].key_len, ','))) {
+ /* value without "...", terminated by ',' */
+ *(dkv[i].ptr) = c + dkv[i].key_len;
+ c = e;
+
+ *e = '\0';
+ } else {
+ /* value without "...", terminated by EOL */
+ *(dkv[i].ptr) = c + dkv[i].key_len;
+ c += strlen(c) - 1;
+ }
+ }
+ }
+ }
+
+ if (p->conf.auth_debug > 1) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "username", username);
+ log_error_write(srv, __FILE__, __LINE__, "ss", "realm", realm);
+ log_error_write(srv, __FILE__, __LINE__, "ss", "nonce", nonce);
+ log_error_write(srv, __FILE__, __LINE__, "ss", "uri", uri);
+ log_error_write(srv, __FILE__, __LINE__, "ss", "algorigthm", algorithm);
+ log_error_write(srv, __FILE__, __LINE__, "ss", "qop", qop);
+ log_error_write(srv, __FILE__, __LINE__, "ss", "cnonce", cnonce);
+ log_error_write(srv, __FILE__, __LINE__, "ss", "nc", nc);
+ log_error_write(srv, __FILE__, __LINE__, "ss", "response", respons);
+ }
+
+ /* check if everything is transmitted */
+ if (!username ||
+ !realm ||
+ !nonce ||
+ !uri ||
+ (qop && (!nc || !cnonce)) ||
+ !respons ) {
+ /* missing field */
+
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "digest: missing field");
+
+ buffer_free(b);
+ return -1;
+ }
+
+ /**
+ * protect the md5-sess against missing cnonce and nonce
+ */
+ if (algorithm &&
+ 0 == strcasecmp(algorithm, "md5-sess") &&
+ (!nonce || !cnonce)) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "digest: (md5-sess: missing field");
+
+ buffer_free(b);
+ return -1;
+ }
+
+ m = get_http_method_name(con->request.http_method);
+
+ /* password-string == HA1 */
+ password = buffer_init();
+ username_buf = buffer_init_string(username);
+ realm_buf = buffer_init_string(realm);
+ if (http_auth_get_password(srv, p, username_buf, realm_buf, password)) {
+ buffer_free(password);
+ buffer_free(b);
+ buffer_free(username_buf);
+ buffer_free(realm_buf);
+ return 0;
+ }
+
+ buffer_free(username_buf);
+ buffer_free(realm_buf);
+
+ if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
+ /* generate password from plain-text */
+ MD5_Init(&Md5Ctx);
+ MD5_Update(&Md5Ctx, (unsigned char *)username, strlen(username));
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)realm, strlen(realm));
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)password->ptr, password->used - 1);
+ MD5_Final(HA1, &Md5Ctx);
+ } else if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
+ /* HA1 */
+ /* transform the 32-byte-hex-md5 to a 16-byte-md5 */
+ for (i = 0; i < HASHLEN; i++) {
+ HA1[i] = hex2int(password->ptr[i*2]) << 4;
+ HA1[i] |= hex2int(password->ptr[i*2+1]);
+ }
+ } else {
+ /* we already check that above */
+ SEGFAULT();
+ }
+
+ buffer_free(password);
+
+ if (algorithm &&
+ strcasecmp(algorithm, "md5-sess") == 0) {
+ MD5_Init(&Md5Ctx);
+ MD5_Update(&Md5Ctx, (unsigned char *)HA1, 16);
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)nonce, strlen(nonce));
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce));
+ MD5_Final(HA1, &Md5Ctx);
+ }
+
+ CvtHex(HA1, a1);
+
+ /* calculate H(A2) */
+ MD5_Init(&Md5Ctx);
+ MD5_Update(&Md5Ctx, (unsigned char *)m, strlen(m));
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)uri, strlen(uri));
+ if (qop && strcasecmp(qop, "auth-int") == 0) {
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)"", HASHHEXLEN);
+ }
+ MD5_Final(HA2, &Md5Ctx);
+ CvtHex(HA2, HA2Hex);
+
+ /* calculate response */
+ MD5_Init(&Md5Ctx);
+ MD5_Update(&Md5Ctx, (unsigned char *)a1, HASHHEXLEN);
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)nonce, strlen(nonce));
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ if (qop && *qop) {
+ MD5_Update(&Md5Ctx, (unsigned char *)nc, strlen(nc));
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce));
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)qop, strlen(qop));
+ MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
+ };
+ MD5_Update(&Md5Ctx, (unsigned char *)HA2Hex, HASHHEXLEN);
+ MD5_Final(RespHash, &Md5Ctx);
+ CvtHex(RespHash, a2);
+
+ if (0 != strcmp(a2, respons)) {
+ /* digest not ok */
+
+ if (p->conf.auth_debug) {
+ log_error_write(srv, __FILE__, __LINE__, "sss",
+ "digest: digest mismatch", a2, respons);
+ }
+
+ log_error_write(srv, __FILE__, __LINE__, "sss",
+ "digest: auth failed for ", username, ": wrong password, IP:", inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
+
+ buffer_free(b);
+ return 0;
+ }
+
+ /* value is our allow-rules */
+ if (http_auth_match_rules(srv, p, url->ptr, username, NULL, NULL)) {
+ buffer_free(b);
+
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "digest: rules did match");
+
+ return 0;
+ }
+
+ /* remember the username */
+ buffer_copy_string(p->auth_user, username);
+
+ buffer_free(b);
+
+ if (p->conf.auth_debug) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "digest: auth ok");
+ }
+ return 1;
+}
+
+
+int http_auth_digest_generate_nonce(server *srv, mod_auth_plugin_data *p, buffer *fn, char out[33]) {
+ HASH h;
+ MD5_CTX Md5Ctx;
+ char hh[32];
+
+ UNUSED(p);
+
+ /* generate shared-secret */
+ MD5_Init(&Md5Ctx);
+ MD5_Update(&Md5Ctx, (unsigned char *)fn->ptr, fn->used - 1);
+ MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
+
+ /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
+ LI_ltostr(hh, srv->cur_ts);
+ MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
+ LI_ltostr(hh, rand());
+ MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
+
+ MD5_Final(h, &Md5Ctx);
+
+ CvtHex(h, out);
+
+ return 0;
+}
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,73 @@
+#ifndef _HTTP_AUTH_H_
+#define _HTTP_AUTH_H_
+
+#include "server.h"
+#include "plugin.h"
+
+#if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
+# define USE_LDAP
+# include <ldap.h>
+#endif
+
+typedef enum {
+ AUTH_BACKEND_UNSET,
+ AUTH_BACKEND_PLAIN,
+ AUTH_BACKEND_LDAP,
+ AUTH_BACKEND_HTPASSWD,
+ AUTH_BACKEND_HTDIGEST
+} auth_backend_t;
+
+typedef struct {
+ /* auth */
+ array *auth_require;
+
+ buffer *auth_plain_groupfile;
+ buffer *auth_plain_userfile;
+
+ buffer *auth_htdigest_userfile;
+ buffer *auth_htpasswd_userfile;
+
+ buffer *auth_backend_conf;
+
+ buffer *auth_ldap_hostname;
+ buffer *auth_ldap_basedn;
+ buffer *auth_ldap_binddn;
+ buffer *auth_ldap_bindpw;
+ buffer *auth_ldap_filter;
+ buffer *auth_ldap_cafile;
+ unsigned short auth_ldap_starttls;
+ unsigned short auth_ldap_allow_empty_pw;
+
+ unsigned short auth_debug;
+
+ /* generated */
+ auth_backend_t auth_backend;
+
+#ifdef USE_LDAP
+ LDAP *ldap;
+
+ buffer *ldap_filter_pre;
+ buffer *ldap_filter_post;
+#endif
+} mod_auth_plugin_config;
+
+typedef struct {
+ PLUGIN_DATA;
+ buffer *tmp_buf;
+
+ buffer *auth_user;
+
+#ifdef USE_LDAP
+ buffer *ldap_filter;
+#endif
+
+ mod_auth_plugin_config **config_storage;
+
+ mod_auth_plugin_config conf; /* this is only used as long as no handler_ctx is setup */
+} mod_auth_plugin_data;
+
+int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str);
+int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str);
+int http_auth_digest_generate_nonce(server *srv, mod_auth_plugin_data *p, buffer *fn, char hh[33]);
+
+#endif
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth_digest.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth_digest.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth_digest.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth_digest.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,19 @@
+#include <string.h>
+#include "http_auth_digest.h"
+
+#include "buffer.h"
+
+#ifndef USE_OPENSSL
+# include "md5.h"
+#endif
+
+void CvtHex(IN HASH Bin, OUT HASHHEX Hex) {
+ unsigned short i;
+
+ for (i = 0; i < HASHLEN; i++) {
+ Hex[i*2] = int2hex((Bin[i] >> 4) & 0xf);
+ Hex[i*2+1] = int2hex(Bin[i] & 0xf);
+ }
+ Hex[HASHHEXLEN] = '\0';
+}
+
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth_digest.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth_digest.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth_digest.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_auth_digest.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,24 @@
+#ifndef _DIGCALC_H_
+#define _DIGCALC_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define HASHLEN 16
+typedef unsigned char HASH[HASHLEN];
+#define HASHHEXLEN 32
+typedef char HASHHEX[HASHHEXLEN+1];
+#ifdef USE_OPENSSL
+#define IN const
+#else
+#define IN
+#endif
+#define OUT
+
+void CvtHex(
+ IN HASH Bin,
+ OUT HASHHEX Hex
+ );
+
+#endif
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_chunk.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_chunk.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_chunk.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_chunk.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,132 @@
+/**
+ * the HTTP chunk-API
+ *
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include "server.h"
+#include "chunk.h"
+#include "http_chunk.h"
+#include "log.h"
+
+static int http_chunk_append_len(server *srv, connection *con, size_t len) {
+ size_t i, olen = len, j;
+ buffer *b;
+
+ b = srv->tmp_chunk_len;
+
+ if (len == 0) {
+ buffer_copy_string(b, "0");
+ } else {
+ for (i = 0; i < 8 && len; i++) {
+ len >>= 4;
+ }
+
+ /* i is the number of hex digits we have */
+ buffer_prepare_copy(b, i + 1);
+
+ for (j = i-1, len = olen; j+1 > 0; j--) {
+ b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
+ len >>= 4;
+ }
+ b->used = i;
+ b->ptr[b->used++] = '\0';
+ }
+
+ buffer_append_string(b, "\r\n");
+ chunkqueue_append_buffer(con->write_queue, b);
+
+ return 0;
+}
+
+
+int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) {
+ chunkqueue *cq;
+
+ if (!con) return -1;
+
+ cq = con->write_queue;
+
+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
+ http_chunk_append_len(srv, con, len);
+ }
+
+ chunkqueue_append_file(cq, fn, offset, len);
+
+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) {
+ chunkqueue_append_mem(cq, "\r\n", 2 + 1);
+ }
+
+ return 0;
+}
+
+int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
+ chunkqueue *cq;
+
+ if (!con) return -1;
+
+ cq = con->write_queue;
+
+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
+ http_chunk_append_len(srv, con, mem->used - 1);
+ }
+
+ chunkqueue_append_buffer(cq, mem);
+
+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) {
+ chunkqueue_append_mem(cq, "\r\n", 2 + 1);
+ }
+
+ return 0;
+}
+
+int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) {
+ chunkqueue *cq;
+
+ if (!con) return -1;
+
+ cq = con->write_queue;
+
+ if (len == 0) {
+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
+ chunkqueue_append_mem(cq, "0\r\n\r\n", 5 + 1);
+ } else {
+ chunkqueue_append_mem(cq, "", 1);
+ }
+ return 0;
+ }
+
+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
+ http_chunk_append_len(srv, con, len - 1);
+ }
+
+ chunkqueue_append_mem(cq, mem, len);
+
+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
+ chunkqueue_append_mem(cq, "\r\n", 2 + 1);
+ }
+
+ return 0;
+}
+
+
+off_t http_chunkqueue_length(server *srv, connection *con) {
+ if (!con) {
+ log_error_write(srv, __FILE__, __LINE__, "s", "connection is NULL!!");
+
+ return 0;
+ }
+
+ return chunkqueue_length(con->write_queue);
+}
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_chunk.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_chunk.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_chunk.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/http_chunk.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,12 @@
+#ifndef _HTTP_CHUNK_H_
+#define _HTTP_CHUNK_H_
+
+#include "server.h"
+#include <sys/types.h>
+
+int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len);
+int http_chunk_append_buffer(server *srv, connection *con, buffer *mem);
+int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len);
+off_t http_chunkqueue_length(server *srv, connection *con);
+
+#endif
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/inet_ntop_cache.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/inet_ntop_cache.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/inet_ntop_cache.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/inet_ntop_cache.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,53 @@
+#include <sys/types.h>
+
+#include <string.h>
+
+
+#include "base.h"
+#include "inet_ntop_cache.h"
+#include "sys-socket.h"
+
+const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr) {
+#ifdef HAVE_IPV6
+ size_t ndx = 0, i;
+ for (i = 0; i < INET_NTOP_CACHE_MAX; i++) {
+ if (srv->inet_ntop_cache[i].ts != 0) {
+ if (srv->inet_ntop_cache[i].family == AF_INET6 &&
+ 0 == memcmp(srv->inet_ntop_cache[i].addr.ipv6.s6_addr, addr->ipv6.sin6_addr.s6_addr, 16)) {
+ /* IPv6 found in cache */
+ break;
+ } else if (srv->inet_ntop_cache[i].family == AF_INET &&
+ srv->inet_ntop_cache[i].addr.ipv4.s_addr == addr->ipv4.sin_addr.s_addr) {
+ /* IPv4 found in cache */
+ break;
+
+ }
+ }
+ }
+
+ if (i == INET_NTOP_CACHE_MAX) {
+ /* not found in cache */
+
+ i = ndx;
+ inet_ntop(addr->plain.sa_family,
+ addr->plain.sa_family == AF_INET6 ?
+ (const void *) &(addr->ipv6.sin6_addr) :
+ (const void *) &(addr->ipv4.sin_addr),
+ srv->inet_ntop_cache[i].b2, INET6_ADDRSTRLEN);
+
+ srv->inet_ntop_cache[i].ts = srv->cur_ts;
+ srv->inet_ntop_cache[i].family = addr->plain.sa_family;
+
+ if (srv->inet_ntop_cache[i].family == AF_INET) {
+ srv->inet_ntop_cache[i].addr.ipv4.s_addr = addr->ipv4.sin_addr.s_addr;
+ } else if (srv->inet_ntop_cache[i].family == AF_INET6) {
+ memcpy(srv->inet_ntop_cache[i].addr.ipv6.s6_addr, addr->ipv6.sin6_addr.s6_addr, 16);
+ }
+ }
+
+ return srv->inet_ntop_cache[i].b2;
+#else
+ UNUSED(srv);
+ return inet_ntoa(addr->ipv4.sin_addr);
+#endif
+}
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/inet_ntop_cache.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/inet_ntop_cache.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/inet_ntop_cache.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/inet_ntop_cache.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,7 @@
+#ifndef _INET_NTOP_CACHE_H_
+#define _INET_NTOP_CACHE_H_
+
+#include "base.h"
+const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr);
+
+#endif
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/joblist.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/joblist.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/joblist.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/joblist.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,63 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "base.h"
+#include "joblist.h"
+#include "log.h"
+
+int joblist_append(server *srv, connection *con) {
+ if (con->in_joblist) return 0;
+
+ if (srv->joblist->size == 0) {
+ srv->joblist->size = 16;
+ srv->joblist->ptr = malloc(sizeof(*srv->joblist->ptr) * srv->joblist->size);
+ } else if (srv->joblist->used == srv->joblist->size) {
+ srv->joblist->size += 16;
+ srv->joblist->ptr = realloc(srv->joblist->ptr, sizeof(*srv->joblist->ptr) * srv->joblist->size);
+ }
+
+ srv->joblist->ptr[srv->joblist->used++] = con;
+
+ return 0;
+}
+
+void joblist_free(server *srv, connections *joblist) {
+ UNUSED(srv);
+
+ free(joblist->ptr);
+ free(joblist);
+}
+
+connection *fdwaitqueue_unshift(server *srv, connections *fdwaitqueue) {
+ connection *con;
+ UNUSED(srv);
+
+
+ if (fdwaitqueue->used == 0) return NULL;
+
+ con = fdwaitqueue->ptr[0];
+
+ memmove(fdwaitqueue->ptr, &(fdwaitqueue->ptr[1]), --fdwaitqueue->used * sizeof(*(fdwaitqueue->ptr)));
+
+ return con;
+}
+
+int fdwaitqueue_append(server *srv, connection *con) {
+ if (srv->fdwaitqueue->size == 0) {
+ srv->fdwaitqueue->size = 16;
+ srv->fdwaitqueue->ptr = malloc(sizeof(*(srv->fdwaitqueue->ptr)) * srv->fdwaitqueue->size);
+ } else if (srv->fdwaitqueue->used == srv->fdwaitqueue->size) {
+ srv->fdwaitqueue->size += 16;
+ srv->fdwaitqueue->ptr = realloc(srv->fdwaitqueue->ptr, sizeof(*(srv->fdwaitqueue->ptr)) * srv->fdwaitqueue->size);
+ }
+
+ srv->fdwaitqueue->ptr[srv->fdwaitqueue->used++] = con;
+
+ return 0;
+}
+
+void fdwaitqueue_free(server *srv, connections *fdwaitqueue) {
+ UNUSED(srv);
+ free(fdwaitqueue->ptr);
+ free(fdwaitqueue);
+}
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/joblist.h
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/joblist.h?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/joblist.h (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/joblist.h Mon Jul 21 21:35:35 2008
@@ -0,0 +1,13 @@
+#ifndef _JOB_LIST_H_
+#define _JOB_LIST_H_
+
+#include "base.h"
+
+int joblist_append(server *srv, connection *con);
+void joblist_free(server *srv, connections *joblist);
+
+int fdwaitqueue_append(server *srv, connection *con);
+void fdwaitqueue_free(server *srv, connections *fdwaitqueue);
+connection *fdwaitqueue_unshift(server *srv, connections *fdwaitqueue);
+
+#endif
Added: webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/keyvalue.c
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/keyvalue.c?rev=678637&view=auto
==============================================================================
--- webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/keyvalue.c (added)
+++ webservices/axis2/branches/c/lighttpd_mod_axis2/lighttpd/src/keyvalue.c Mon Jul 21 21:35:35 2008
@@ -0,0 +1,388 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "server.h"
+#include "keyvalue.h"
+
+static keyvalue http_versions[] = {
+ { HTTP_VERSION_1_1, "HTTP/1.1" },
+ { HTTP_VERSION_1_0, "HTTP/1.0" },
+ { HTTP_VERSION_UNSET, NULL }
+};
+
+static keyvalue http_methods[] = {
+ { HTTP_METHOD_GET, "GET" },
+ { HTTP_METHOD_POST, "POST" },
+ { HTTP_METHOD_HEAD, "HEAD" },
+ { HTTP_METHOD_PROPFIND, "PROPFIND" },
+ { HTTP_METHOD_PROPPATCH, "PROPPATCH" },
+ { HTTP_METHOD_REPORT, "REPORT" },
+ { HTTP_METHOD_OPTIONS, "OPTIONS" },
+ { HTTP_METHOD_MKCOL, "MKCOL" },
+ { HTTP_METHOD_PUT, "PUT" },
+ { HTTP_METHOD_DELETE, "DELETE" },
+ { HTTP_METHOD_COPY, "COPY" },
+ { HTTP_METHOD_MOVE, "MOVE" },
+ { HTTP_METHOD_LABEL, "LABEL" },
+ { HTTP_METHOD_CHECKOUT, "CHECKOUT" },
+ { HTTP_METHOD_CHECKIN, "CHECKIN" },
+ { HTTP_METHOD_MERGE, "MERGE" },
+ { HTTP_METHOD_LOCK, "LOCK" },
+ { HTTP_METHOD_UNLOCK, "UNLOCK" },
+ { HTTP_METHOD_MKACTIVITY, "MKACTIVITY" },
+ { HTTP_METHOD_UNCHECKOUT, "UNCHECKOUT" },
+ { HTTP_METHOD_VERSION_CONTROL, "VERSION-CONTROL" },
+ { HTTP_METHOD_CONNECT, "CONNECT" },
+
+ { HTTP_METHOD_UNSET, NULL }
+};
+
+static keyvalue http_status[] = {
+ { 100, "Continue" },
+ { 101, "Switching Protocols" },
+ { 102, "Processing" }, /* WebDAV */
+ { 200, "OK" },
+ { 201, "Created" },
+ { 202, "Accepted" },
+ { 203, "Non-Authoritative Information" },
+ { 204, "No Content" },
+ { 205, "Reset Content" },
+ { 206, "Partial Content" },
+ { 207, "Multi-status" }, /* WebDAV */
+ { 300, "Multiple Choices" },
+ { 301, "Moved Permanently" },
+ { 302, "Found" },
+ { 303, "See Other" },
+ { 304, "Not Modified" },
+ { 305, "Use Proxy" },
+ { 306, "(Unused)" },
+ { 307, "Temporary Redirect" },
+ { 400, "Bad Request" },
+ { 401, "Unauthorized" },
+ { 402, "Payment Required" },
+ { 403, "Forbidden" },
+ { 404, "Not Found" },
+ { 405, "Method Not Allowed" },
+ { 406, "Not Acceptable" },
+ { 407, "Proxy Authentication Required" },
+ { 408, "Request Timeout" },
+ { 409, "Conflict" },
+ { 410, "Gone" },
+ { 411, "Length Required" },
+ { 412, "Precondition Failed" },
+ { 413, "Request Entity Too Large" },
+ { 414, "Request-URI Too Long" },
+ { 415, "Unsupported Media Type" },
+ { 416, "Requested Range Not Satisfiable" },
+ { 417, "Expectation Failed" },
+ { 422, "Unprocessable Entity" }, /* WebDAV */
+ { 423, "Locked" }, /* WebDAV */
+ { 424, "Failed Dependency" }, /* WebDAV */
+ { 426, "Upgrade Required" }, /* TLS */
+ { 500, "Internal Server Error" },
+ { 501, "Not Implemented" },
+ { 502, "Bad Gateway" },
+ { 503, "Service Not Available" },
+ { 504, "Gateway Timeout" },
+ { 505, "HTTP Version Not Supported" },
+ { 507, "Insufficient Storage" }, /* WebDAV */
+
+ { -1, NULL }
+};
+
+static keyvalue http_status_body[] = {
+ { 400, "400.html" },
+ { 401, "401.html" },
+ { 403, "403.html" },
+ { 404, "404.html" },
+ { 411, "411.html" },
+ { 416, "416.html" },
+ { 500, "500.html" },
+ { 501, "501.html" },
+ { 503, "503.html" },
+ { 505, "505.html" },
+
+ { -1, NULL }
+};
+
+
+const char *keyvalue_get_value(keyvalue *kv, int k) {
+ int i;
+ for (i = 0; kv[i].value; i++) {
+ if (kv[i].key == k) return kv[i].value;
+ }
+ return NULL;
+}
+
+int keyvalue_get_key(keyvalue *kv, const char *s) {
+ int i;
+ for (i = 0; kv[i].value; i++) {
+ if (0 == strcmp(kv[i].value, s)) return kv[i].key;
+ }
+ return -1;
+}
+
+keyvalue_buffer *keyvalue_buffer_init(void) {
+ keyvalue_buffer *kvb;
+
+ kvb = calloc(1, sizeof(*kvb));
+
+ return kvb;
+}
+
+int keyvalue_buffer_append(keyvalue_buffer *kvb, int key, const char *value) {
+ size_t i;
+ if (kvb->size == 0) {
+ kvb->size = 4;
+
+ kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
+
+ for(i = 0; i < kvb->size; i++) {
+ kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
+ }
+ } else if (kvb->used == kvb->size) {
+ kvb->size += 4;
+
+ kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
+
+ for(i = kvb->used; i < kvb->size; i++) {
+ kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
+ }
+ }
+
+ kvb->kv[kvb->used]->key = key;
+ kvb->kv[kvb->used]->value = strdup(value);
+
+ kvb->used++;
+
+ return 0;
+}
+
+void keyvalue_buffer_free(keyvalue_buffer *kvb) {
+ size_t i;
+
+ for (i = 0; i < kvb->size; i++) {
+ if (kvb->kv[i]->value) free(kvb->kv[i]->value);
+ free(kvb->kv[i]);
+ }
+
+ if (kvb->kv) free(kvb->kv);
+
+ free(kvb);
+}
+
+
+s_keyvalue_buffer *s_keyvalue_buffer_init(void) {
+ s_keyvalue_buffer *kvb;
+
+ kvb = calloc(1, sizeof(*kvb));
+
+ return kvb;
+}
+
+int s_keyvalue_buffer_append(s_keyvalue_buffer *kvb, const char *key, const char *value) {
+ size_t i;
+ if (kvb->size == 0) {
+ kvb->size = 4;
+ kvb->used = 0;
+
+ kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
+
+ for(i = 0; i < kvb->size; i++) {
+ kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
+ }
+ } else if (kvb->used == kvb->size) {
+ kvb->size += 4;
+
+ kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
+
+ for(i = kvb->used; i < kvb->size; i++) {
+ kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
+ }
+ }
+
+ kvb->kv[kvb->used]->key = key ? strdup(key) : NULL;
+ kvb->kv[kvb->used]->value = strdup(value);
+
+ kvb->used++;
+
+ return 0;
+}
+
+void s_keyvalue_buffer_free(s_keyvalue_buffer *kvb) {
+ size_t i;
+
+ for (i = 0; i < kvb->size; i++) {
+ if (kvb->kv[i]->key) free(kvb->kv[i]->key);
+ if (kvb->kv[i]->value) free(kvb->kv[i]->value);
+ free(kvb->kv[i]);
+ }
+
+ if (kvb->kv) free(kvb->kv);
+
+ free(kvb);
+}
+
+
+httpauth_keyvalue_buffer *httpauth_keyvalue_buffer_init(void) {
+ httpauth_keyvalue_buffer *kvb;
+
+ kvb = calloc(1, sizeof(*kvb));
+
+ return kvb;
+}
+
+int httpauth_keyvalue_buffer_append(httpauth_keyvalue_buffer *kvb, const char *key, const char *realm, httpauth_type type) {
+ size_t i;
+ if (kvb->size == 0) {
+ kvb->size = 4;
+
+ kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
+
+ for(i = 0; i < kvb->size; i++) {
+ kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
+ }
+ } else if (kvb->used == kvb->size) {
+ kvb->size += 4;
+
+ kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
+
+ for(i = kvb->used; i < kvb->size; i++) {
+ kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
+ }
+ }
+
+ kvb->kv[kvb->used]->key = strdup(key);
+ kvb->kv[kvb->used]->realm = strdup(realm);
+ kvb->kv[kvb->used]->type = type;
+
+ kvb->used++;
+
+ return 0;
+}
+
+void httpauth_keyvalue_buffer_free(httpauth_keyvalue_buffer *kvb) {
+ size_t i;
+
+ for (i = 0; i < kvb->size; i++) {
+ if (kvb->kv[i]->key) free(kvb->kv[i]->key);
+ if (kvb->kv[i]->realm) free(kvb->kv[i]->realm);
+ free(kvb->kv[i]);
+ }
+
+ if (kvb->kv) free(kvb->kv);
+
+ free(kvb);
+}
+
+
+const char *get_http_version_name(int i) {
+ return keyvalue_get_value(http_versions, i);
+}
+
+const char *get_http_status_name(int i) {
+ return keyvalue_get_value(http_status, i);
+}
+
+const char *get_http_method_name(http_method_t i) {
+ return keyvalue_get_value(http_methods, i);
+}
+
+const char *get_http_status_body_name(int i) {
+ return keyvalue_get_value(http_status_body, i);
+}
+
+int get_http_version_key(const char *s) {
+ return keyvalue_get_key(http_versions, s);
+}
+
+http_method_t get_http_method_key(const char *s) {
+ return (http_method_t)keyvalue_get_key(http_methods, s);
+}
+
+
+
+
+pcre_keyvalue_buffer *pcre_keyvalue_buffer_init(void) {
+ pcre_keyvalue_buffer *kvb;
+
+ kvb = calloc(1, sizeof(*kvb));
+
+ return kvb;
+}
+
+int pcre_keyvalue_buffer_append(pcre_keyvalue_buffer *kvb, const char *key, const char *value) {
+#ifdef HAVE_PCRE_H
+ size_t i;
+ const char *errptr;
+ int erroff;
+ pcre_keyvalue *kv;
+#endif
+
+ if (!key) return -1;
+
+#ifdef HAVE_PCRE_H
+ if (kvb->size == 0) {
+ kvb->size = 4;
+ kvb->used = 0;
+
+ kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
+
+ for(i = 0; i < kvb->size; i++) {
+ kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
+ }
+ } else if (kvb->used == kvb->size) {
+ kvb->size += 4;
+
+ kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
+
+ for(i = kvb->used; i < kvb->size; i++) {
+ kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
+ }
+ }
+
+ kv = kvb->kv[kvb->used];
+ if (NULL == (kv->key = pcre_compile(key,
+ 0, &errptr, &erroff, NULL))) {
+
+ fprintf(stderr, "%s.%d: rexexp compilation error at %s\n", __FILE__, __LINE__, errptr);
+ return -1;
+ }
+
+ if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) &&
+ errptr != NULL) {
+ return -1;
+ }
+
+ kv->value = buffer_init_string(value);
+
+ kvb->used++;
+
+ return 0;
+#else
+ UNUSED(kvb);
+ UNUSED(value);
+
+ return -1;
+#endif
+}
+
+void pcre_keyvalue_buffer_free(pcre_keyvalue_buffer *kvb) {
+#ifdef HAVE_PCRE_H
+ size_t i;
+ pcre_keyvalue *kv;
+
+ for (i = 0; i < kvb->size; i++) {
+ kv = kvb->kv[i];
+ if (kv->key) pcre_free(kv->key);
+ if (kv->key_extra) pcre_free(kv->key_extra);
+ if (kv->value) buffer_free(kv->value);
+ free(kv);
+ }
+
+ if (kvb->kv) free(kvb->kv);
+#endif
+
+ free(kvb);
+}