improves cgi error handling and allows requests with empty headers

Sat, 28 Jan 2017 10:38:34 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 28 Jan 2017 10:38:34 +0100
changeset 162
b169992137a8
parent 161
aadda87bad1b
child 163
3589ed579127

improves cgi error handling and allows requests with empty headers

also fixes broken windows porting commit

src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/event.h file | annotate | diff | comparison | revisions
src/server/daemon/event_linux.c file | annotate | diff | comparison | revisions
src/server/daemon/event_solaris.c file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/httpparser.c file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.c file | annotate | diff | comparison | revisions
src/server/daemon/ldap_auth.h file | annotate | diff | comparison | revisions
src/server/daemon/protocol.h file | annotate | diff | comparison | revisions
src/server/daemon/sessionhandler.c file | annotate | diff | comparison | revisions
src/server/daemon/webserver.c file | annotate | diff | comparison | revisions
src/server/daemon/websocket.c file | annotate | diff | comparison | revisions
src/server/daemon/ws-fn.c file | annotate | diff | comparison | revisions
src/server/public/auth.h file | annotate | diff | comparison | revisions
src/server/safs/cgi.c file | annotate | diff | comparison | revisions
src/server/safs/cgi.h file | annotate | diff | comparison | revisions
src/server/safs/common.c file | annotate | diff | comparison | revisions
src/server/safs/common.h file | annotate | diff | comparison | revisions
src/server/safs/init.c file | annotate | diff | comparison | revisions
src/server/util/atomic.h file | annotate | diff | comparison | revisions
src/server/util/io.h file | annotate | diff | comparison | revisions
src/server/util/pblock.h file | annotate | diff | comparison | revisions
src/server/util/systhr.c file | annotate | diff | comparison | revisions
src/server/util/uri.cpp file | annotate | diff | comparison | revisions
--- a/src/server/daemon/config.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/config.c	Sat Jan 28 10:38:34 2017 +0100
@@ -35,7 +35,7 @@
 #include <sys/types.h>
 #include <sys/file.h>
 #include <sys/stat.h>
-//include <sys/mman.h>
+#include <sys/mman.h>
 
 #include <ucx/string.h>
 #include <ucx/utils.h>
--- a/src/server/daemon/event.h	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/event.h	Sat Jan 28 10:38:34 2017 +0100
@@ -54,6 +54,7 @@
     int          events;
     int          poll;
     void         *cookie;
+    int          error;
 };
 
 typedef struct event_handler_conf {
--- a/src/server/daemon/event_linux.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/event_linux.c	Sat Jan 28 10:38:34 2017 +0100
@@ -108,9 +108,11 @@
                 if(!event->fn(ev, event)) {
                     // event fn returned 0 -> remove event from epoll
                     if(epoll_ctl(ep, EPOLL_CTL_DEL, event->object, NULL)) {
+                        event->error = 1;
                         log_ereport(
                                 LOG_FAILURE,
-                                "epoll_ctl failed: %s",
+                                "epoll_ctl failed: fd: %d error: %s",
+                                event->object,
                                 strerror(errno));
                     }
                     
--- a/src/server/daemon/event_solaris.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/event_solaris.c	Sat Jan 28 10:38:34 2017 +0100
@@ -158,7 +158,7 @@
 int ev_pollout(event_handler_t *h, int fd, event_t *event) {
     event->object = (intptr_t)fd;
     event->events = POLLOUT;
-    event->poll EVENT_POLLOUT;
+    event->poll = EVENT_POLLOUT;
     return port_associate(
             ev_get_port(h),
             PORT_SOURCE_FD,
--- a/src/server/daemon/httplistener.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/httplistener.c	Sat Jan 28 10:38:34 2017 +0100
@@ -407,9 +407,22 @@
             int ssl_ar = SSL_accept(ssl);
             if(ssl_ar <= 0) {
                 int error = SSL_get_error(ssl, ssl_ar);
-                log_ereport(LOG_INFORM, "SSL accept error: %d", error);
+                char *errstr;
+                switch(error) {
+                    default: errstr = "unknown"; break;
+                    case SSL_ERROR_ZERO_RETURN: errstr = "SSL_ERROR_ZERO_RETURN"; break;
+                    case SSL_ERROR_WANT_READ: errstr = "SSL_ERROR_WANT_READ"; break;
+                    case SSL_ERROR_WANT_WRITE: errstr = "SSL_ERROR_WANT_WRITE"; break;
+                    case SSL_ERROR_WANT_CONNECT: errstr = "SSL_ERROR_WANT_CONNECT"; break;
+                    case SSL_ERROR_WANT_ACCEPT: errstr = "SSL_ERROR_WANT_ACCEPT"; break;
+                    case SSL_ERROR_WANT_X509_LOOKUP: errstr = "SSL_ERROR_WANT_X509_LOOKUP"; break;
+                    case SSL_ERROR_SYSCALL: errstr = "SSL_ERROR_SYSCALL"; break;
+                    case SSL_ERROR_SSL: errstr = "SL_ERROR_SSL"; break;
+                }
+                log_ereport(LOG_VERBOSE, "SSL accept error[%d]: %s", error, errstr);
                 free(conn);
                 conn = NULL;
+                close(clientfd);
             } else {
                 conn->ssl = ssl;
                 conn->read = connection_ssl_read;
--- a/src/server/daemon/httpparser.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/httpparser.c	Sat Jan 28 10:38:34 2017 +0100
@@ -131,11 +131,13 @@
                 return 0;
             } else {
                 parser->offset = buf->pos;
-                if(parser->value.ptr != NULL) {
-                    parser->value.length = (buf->inbuf + buf->pos - 1)
+                if(parser->name.length != 0) {
+                    if(parser->value.ptr) {
+                        parser->value.length = (buf->inbuf + buf->pos - 1)
                             - (unsigned char*)parser->value.ptr;
-                    if(buf->inbuf[buf->pos-2] == '\r') {
-                        parser->value.length--;
+                        if(buf->inbuf[buf->pos-2] == '\r') {
+                            parser->value.length--;
+                        }
                     }
                     // add header
                     header_add(
--- a/src/server/daemon/httprequest.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/httprequest.c	Sat Jan 28 10:38:34 2017 +0100
@@ -89,7 +89,7 @@
 
 int handle_request(HTTPRequest *request, threadpool_t *thrpool) {
     // handle nsapi request
-    
+     
     // create pool
     pool_handle_t *pool = pool_create();
 
--- a/src/server/daemon/ldap_auth.h	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/ldap_auth.h	Sat Jan 28 10:38:34 2017 +0100
@@ -29,18 +29,11 @@
 #ifndef LDAP_AUTH_H
 #define	LDAP_AUTH_H
 
-#include "../public/nsapi.h"
 #include "../public/auth.h"
 #include <sys/types.h>
+#include <ldap.h>
 #include <ucx/map.h>
 
-#ifdef XP_UNIX
-#include <ldap.h>
-#endif
-#ifdef XP_WIN32
-#include <Winldap.h> 
-#endif
-
 #ifdef	__cplusplus
 extern "C" {
 #endif
--- a/src/server/daemon/protocol.h	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/protocol.h	Sat Jan 28 10:38:34 2017 +0100
@@ -31,6 +31,7 @@
 
 #include "../public/nsapi.h"
 #include "../util/io.h"
+#include <sys/uio.h>
 #include "../util/strbuf.h"
 
 #ifdef	__cplusplus
--- a/src/server/daemon/sessionhandler.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/sessionhandler.c	Sat Jan 28 10:38:34 2017 +0100
@@ -42,6 +42,7 @@
 typedef struct _event_http_io {
     HTTPRequest *request;
     HttpParser  *parser;
+    int         error;
 } EventHttpIO;
 
 
@@ -212,6 +213,7 @@
     }
     io->request = request;
     io->parser  = parser;
+    io->error = 0;
     
     /*
      * to start the request handling, we begin with a poll on the socket,
@@ -222,6 +224,7 @@
     event_handler_t *ev = ((EventSessionHandler*)handler)->eventhandler;
     
     event_t *event = malloc(sizeof(event_t));
+    ZERO(event, sizeof(event_t));
     event->fn = evt_request_input;
     event->finish = evt_request_finish;
     event->cookie = io;
@@ -263,6 +266,7 @@
         }
         
         event->finish = evt_request_error;
+        io->error = 1;
         return 0;
     }
     //fwrite(buf->inbuf + buf->pos, 1, r, stdout);
@@ -274,6 +278,7 @@
         // parse error
         fatal_error(request, 400);
         event->finish = evt_request_error;
+        io->error = 2;
         return 0;
     } else if(state == 1) {
         /*
@@ -294,6 +299,7 @@
     if (fcntl(request->connection->fd, F_SETFL, flags & ~O_NONBLOCK) != 0) {
         // just close the connection if fcntl fails
         event->finish = evt_request_error;
+        io->error = 3;
         return 0;
     }
      
@@ -332,11 +338,15 @@
     return 0;
 }
 
-int evt_request_error(event_handler_t *h, event_t *event) {
+int evt_request_error(event_handler_t *h, event_t *event) { 
     EventHttpIO *io = event->cookie;
     HttpParser  *parser  = io->parser;
     HTTPRequest *request = io->request;
     
+    if(event->error) {
+        log_ereport(LOG_VERBOSE, "sessionhandler http io error: %d", io->error);
+    }
+    
     free(request->netbuf->inbuf);
     free(request->netbuf);
     
--- a/src/server/daemon/webserver.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/webserver.c	Sat Jan 28 10:38:34 2017 +0100
@@ -48,6 +48,8 @@
 #include "../util/io.h"
 #include "../util/util.h"
 
+#include "../safs/common.h"
+
 #include "func.h"
 #include "config.h"
 #include "configmanager.h"
@@ -103,6 +105,9 @@
     fclose(pidfile);
     free(pid_file_path);
     
+    // init SAFs
+    common_saf_init();
+    
     // set global vars
     conf_global_vars_s *vars = conf_getglobals();
     
--- a/src/server/daemon/websocket.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/websocket.c	Sat Jan 28 10:38:34 2017 +0100
@@ -304,7 +304,7 @@
 
 NSAPI_PUBLIC int websocket_send_text(SYS_NETFD csd, char *msg, size_t len) {
     char frame[WS_FRAMEHEADER_BUFLEN];
-    frame[0] = 0b10000001;
+    frame[0] = 129; // 0b10000001
     size_t hlen;
     if(len < 126) {
         frame[1] = (char)len;
--- a/src/server/daemon/ws-fn.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/daemon/ws-fn.c	Sat Jan 28 10:38:34 2017 +0100
@@ -67,6 +67,7 @@
     { "find-index", find_index, NULL, NULL, 0},
     { "dir-redirect", dir_redirect, NULL, NULL, 0},
     { "print-message", print_message, NULL, NULL, 0},
+    { "set-variable", set_variable, NULL, NULL, 0},
     { "common-log", common_log, NULL, NULL, 0},
     { "send-cgi", send_cgi, NULL, NULL, 0},
     {NULL, NULL, NULL, NULL, 0}
--- a/src/server/public/auth.h	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/public/auth.h	Sat Jan 28 10:38:34 2017 +0100
@@ -35,7 +35,7 @@
 extern "C" {
 #endif
 
-#ifdef _WIN32
+#ifdef XP_WIN32
 typedef int uid_t;
 typedef int gid_t;
 #endif
--- a/src/server/safs/cgi.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/safs/cgi.c	Sat Jan 28 10:38:34 2017 +0100
@@ -32,6 +32,10 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/wait.h>
+
 #include "../util/util.h"
 #include "../util/pblock.h"
 #include "../../ucx/string.h"
@@ -99,11 +103,26 @@
         while(n < content_length) {
             r = netbuf_getbytes(sn->inbuf, buf, 4096);
             if(r <= 0) {
-                // TODO: handleerror
+                // TODO: handle error
+                log_ereport(
+                        LOG_FAILURE,
+                        "send-cgi: script: %s: cannot read request body",
+                        path);
+                kill(cgip.pid, SIGTERM);
                 cgi_close(&cgip);
-                return REQ_ABORTED; 
+                return REQ_ABORTED;
             }
-            write(cgip.in[1], buf, r);
+            ssize_t w = write(cgip.in[1], buf, r);
+            if(w <= 0) {
+                // TODO: handle error
+                log_ereport(
+                        LOG_FAILURE,
+                        "send-cgi: script: %s: cannot send request body to cgi process",
+                        path);
+                kill(cgip.pid, SIGKILL);
+                cgi_close(&cgip);
+                return REQ_ABORTED;
+            }
             n += r;
         }
     }
@@ -114,17 +133,19 @@
     CGIResponseParser *parser = cgi_parser_new(sn, rq);
     WSBool cgiheader = TRUE;
     ssize_t wr = 0;
-    int result = REQ_PROCEED;   
+    int result = REQ_PROCEED;
+    size_t response_length = 0;
     while((r = read(cgip.out[0], buf, 4096)) > 0) {
         if(cgiheader) {
             size_t pos;
             ret = cgi_parse_response(parser, buf, r, &pos);
             if(ret == -1) {
+                log_ereport(
+                        LOG_FAILURE,
+                        "broken cgi script response: path: %s", path);
                 protocol_status(sn, rq, 500, NULL);
                 result = REQ_ABORTED;
                 break;
-            } else if(ret == 0) {
-                
             } else if(ret == 1) {
                 cgiheader = FALSE;
                 if(parser->status > 0) {
@@ -132,6 +153,7 @@
                 }
                 http_start_response(sn, rq);
                 if(pos < r) {
+                    response_length += r-pos;
                     wr = net_write(sn->csd, &buf[pos], r-pos);
                     if(wr <= 0) {
                         result = REQ_ABORTED;
@@ -140,6 +162,7 @@
                 }
             }
         } else {
+            response_length = r;
             wr = net_write(sn->csd, buf, r);
             if(wr <= 0) {
                 result = REQ_ABORTED;
@@ -148,7 +171,26 @@
         }
     }
     
-    cgi_close(&cgip);
+    char *ctlen_header = pblock_findkeyval(pb_key_content_length, rq->srvhdrs);
+    if(ctlen_header) {
+        int64_t ctlenhdr;
+        if(util_strtoint(ctlen_header, &ctlenhdr)) {
+            if(ctlenhdr != response_length) {
+                log_ereport(
+                        LOG_FAILURE,
+                        "cgi-send: script: %s: content length mismatch",
+                        path);
+                rq->rq_attr.keep_alive = 0;
+                result = REQ_ABORTED;
+            }
+        }
+    }
+    
+    if(result == REQ_ABORTED) {
+        log_ereport(LOG_FAILURE, "cgi-send: kill script: %s", path);
+        kill(cgip.pid, SIGKILL);
+    }
+    cgi_close(&cgip); // TODO: check return value
       
     cgi_parser_free(parser);
     return result;
@@ -209,7 +251,10 @@
     return REQ_PROCEED;
 }
 
-void cgi_close(CGIProcess *p) {
+int cgi_close(CGIProcess *p) {
+    int status = -1;
+    waitpid(p->pid, &status, 0);
+    
     if(p->in[0] != -1) {
         close(p->in[0]);
     }
@@ -222,6 +267,8 @@
     if(p->out[1] != -1) {
         close(p->out[1]);
     }
+    
+    return 0;
 }
 
 CGIResponseParser* cgi_parser_new(Session *sn, Request *rq) {
@@ -386,5 +433,4 @@
             return 1;
         }
     }
-}
-
+}
\ No newline at end of file
--- a/src/server/safs/cgi.h	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/safs/cgi.h	Sat Jan 28 10:38:34 2017 +0100
@@ -56,7 +56,7 @@
 
 int cgi_start(CGIProcess *p, char *path, char *const argv[], char *const envp[]);
 
-void cgi_close(CGIProcess *p);
+int cgi_close(CGIProcess *p);
 
 CGIResponseParser* cgi_parser_new(Session *sn, Request *rq);
 void cgi_parser_free(CGIResponseParser *parser);
--- a/src/server/safs/common.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/safs/common.c	Sat Jan 28 10:38:34 2017 +0100
@@ -31,12 +31,202 @@
 #include "../daemon/httprequest.h"
 #include "../daemon/log.h"
 
+#include "../util/pblock.h"
+#include "../util/util.h"
+#include "../../ucx/map.h"
+
+static UcxMap *var_names;
+
+enum SAFVarNames {
+    COMMONSAF_INSERT_CLIENT = 1,
+    COMMONSAF_INSERT_VARS,
+    COMMONSAF_INSERT_REQPB,
+    COMMONSAF_INSERT_HEADERS,
+    COMMONSAF_INSERT_SRVHDRS,
+    COMMONSAF_SET_CLIENT,
+    COMMONSAF_SET_VARS,
+    COMMONSAF_SET_REQPB,
+    COMMONSAF_SET_HEADERS,
+    COMMONSAF_SET_SRVHDRS,
+    COMMONSAF_REMOVE_CLIENT,
+    COMMONSAF_REMOVE_VARS,
+    COMMONSAF_REMOVE_REQPB,
+    COMMONSAF_REMOVE_HEADERS,
+    COMMONSAF_REMOVE_SRVHDRS,
+    COMMONSAF_ABORT,
+    COMMONSAF_NOACTION,
+    COMMONSAF_ERROR,
+    COMMONSAF_ESCAPE,
+    COMMONSAF_FIND_PATHINFO_FORWARD,
+    COMMONSAF_HTTP_DOWNGRADE,
+    COMMONSAF_HTTP_UPGRADE,
+    COMMONSAF_KEEP_ALIVE,
+    COMMONSAF_NAME,
+    COMMONSAF_SENTHDRS,
+    COMMONSAF_STOP,
+    COMMONSAF_URL
+};
+
+#define COMMONSAF_RET_DEF 0
+#define COMMONSAF_RET_NOACTION 1
+#define COMMONSAF_RET_STOP 2
+#define COMMONSAF_REQ_ABORTED -1
+#define COMMONSAF_RET_ERROR -2
+
+void common_saf_init() {
+    var_names = ucx_map_new(32);
+    
+    ucx_map_cstr_put(var_names, "insert-client", (intptr_t)COMMONSAF_INSERT_CLIENT);
+    ucx_map_cstr_put(var_names, "insert-vars", (intptr_t)COMMONSAF_INSERT_VARS);
+    ucx_map_cstr_put(var_names, "insert-reqpb", (intptr_t)COMMONSAF_INSERT_REQPB);
+    ucx_map_cstr_put(var_names, "insert-headers", (intptr_t)COMMONSAF_INSERT_HEADERS);
+    ucx_map_cstr_put(var_names, "insert-srvhdrs", (intptr_t)COMMONSAF_INSERT_SRVHDRS);
+    
+    ucx_map_cstr_put(var_names, "set-client", (intptr_t)COMMONSAF_SET_CLIENT);
+    ucx_map_cstr_put(var_names, "set-vars", (intptr_t)COMMONSAF_SET_VARS);
+    ucx_map_cstr_put(var_names, "set-reqpb", (intptr_t)COMMONSAF_SET_REQPB);
+    ucx_map_cstr_put(var_names, "set-headers", (intptr_t)COMMONSAF_SET_HEADERS);
+    ucx_map_cstr_put(var_names, "set-srvhdrs", (intptr_t)COMMONSAF_SET_SRVHDRS);
+    
+    ucx_map_cstr_put(var_names, "remove-client", (intptr_t)COMMONSAF_REMOVE_CLIENT);
+    ucx_map_cstr_put(var_names, "remove-vars", (intptr_t)COMMONSAF_REMOVE_VARS);
+    ucx_map_cstr_put(var_names, "remove-reqpb", (intptr_t)COMMONSAF_REMOVE_REQPB);
+    ucx_map_cstr_put(var_names, "remove-headers", (intptr_t)COMMONSAF_REMOVE_HEADERS);
+    ucx_map_cstr_put(var_names, "remove-srvhdrs", (intptr_t)COMMONSAF_REMOVE_SRVHDRS);
+    
+    ucx_map_cstr_put(var_names, "abort", (intptr_t)COMMONSAF_ABORT);
+    ucx_map_cstr_put(var_names, "noaction", (intptr_t)COMMONSAF_NOACTION);
+    ucx_map_cstr_put(var_names, "error", (intptr_t)COMMONSAF_ERROR);
+    ucx_map_cstr_put(var_names, "escape", (intptr_t)COMMONSAF_ESCAPE);
+    ucx_map_cstr_put(var_names, "find-pathinfo-forward", (intptr_t)COMMONSAF_FIND_PATHINFO_FORWARD);
+    ucx_map_cstr_put(var_names, "http-downgrade", (intptr_t)COMMONSAF_HTTP_DOWNGRADE);
+    ucx_map_cstr_put(var_names, "http-upgrade", (intptr_t)COMMONSAF_HTTP_UPGRADE);
+    ucx_map_cstr_put(var_names, "keep-alive", (intptr_t)COMMONSAF_KEEP_ALIVE);
+    ucx_map_cstr_put(var_names, "name", (intptr_t)COMMONSAF_NAME);
+}
+
 int print_message(pblock *pb, Session *sn, Request *rq) {
     char *msg = pblock_findval("msg", pb);
     if(msg) {
-        printf("%s\n", msg);
         log_ereport(LOG_INFORM, "%s", msg);
     }    
     
     return REQ_NOACTION;
 }
+
+static void var_set(char *value, pblock *pb, WSBool insert) {
+    sstr_t n;
+    sstr_t v;
+    v.ptr = NULL;
+    
+    n.ptr = value;
+    int i;
+    int len = strlen(value);
+    for(i=1;i<len;i++) {
+        if(value[i] == '=') {
+            n.length = i;
+            v = sstrsubs(sstrn(value, len), i + 1);
+            break;
+        }
+    }
+    if(!v.ptr || v.length == 0) {
+        log_ereport(
+                LOG_MISCONFIG,
+                "set-variable: string '%s' has not name=value format",
+                value);
+        return;
+    }
+    
+    if(!insert) {
+        // TODO
+    }
+    pblock_nvlinsert(n.ptr, n.length, v.ptr, v.length, pb);
+}
+
+static int set_var(Session *sn, Request *rq, char *var, char *value) {
+    intptr_t v = (intptr_t)ucx_map_cstr_get(var_names, var);
+    switch(v) {
+        default: break;
+        case COMMONSAF_INSERT_CLIENT: var_set(value, sn->client, TRUE); break;
+        case COMMONSAF_INSERT_VARS: var_set(value, rq->vars, TRUE); break;
+        case COMMONSAF_INSERT_REQPB: var_set(value, rq->reqpb, TRUE); break;
+        case COMMONSAF_INSERT_HEADERS: var_set(value, rq->headers, TRUE); break;
+        case COMMONSAF_INSERT_SRVHDRS: var_set(value, rq->srvhdrs, TRUE); break;
+        case COMMONSAF_SET_CLIENT: var_set(value, sn->client, FALSE); break;
+        case COMMONSAF_SET_VARS: var_set(value, rq->vars, FALSE); break;
+        case COMMONSAF_SET_REQPB: var_set(value, rq->reqpb, FALSE); break;
+        case COMMONSAF_SET_HEADERS: var_set(value, rq->headers, FALSE); break;
+        case COMMONSAF_SET_SRVHDRS: var_set(value, rq->srvhdrs, FALSE); break;
+        case COMMONSAF_REMOVE_CLIENT: pblock_remove(value, sn->client); break;
+        case COMMONSAF_REMOVE_VARS: pblock_remove(value, rq->vars); break;
+        case COMMONSAF_REMOVE_HEADERS: pblock_remove(value, rq->headers);break;
+        case COMMONSAF_REMOVE_SRVHDRS: pblock_remove(value, rq->srvhdrs); break;
+        case COMMONSAF_ABORT: return COMMONSAF_REQ_ABORTED;
+        case COMMONSAF_NOACTION: return COMMONSAF_RET_NOACTION;
+        case COMMONSAF_ERROR: {
+            int len = strlen(value);
+            WSBool isnum = TRUE;
+            int i;
+            for(i=0;i<len;i++) {
+                if(!isdigit(value[i])) {
+                    isnum = FALSE;
+                    break;
+                }
+            }
+            
+            int64_t status;
+            int ret = util_strtoint(value, &status);
+            if(status < 100 || ret > 999 || !ret) {
+                log_ereport(
+                        LOG_MISCONFIG,
+                        "set-variable: error value must contain a 3-digit http status code");
+                protocol_status(sn, rq, 500, NULL);
+                return COMMONSAF_RET_ERROR;
+            }
+            
+            char *msg = isnum ? NULL : sstrtrim(sstr(value + i)).ptr;
+            protocol_status(sn, rq, (int)status, msg);
+            
+            return COMMONSAF_REQ_ABORTED;
+        }
+        case COMMONSAF_ESCAPE: break;
+        case COMMONSAF_FIND_PATHINFO_FORWARD: break;
+        case COMMONSAF_HTTP_DOWNGRADE: break;
+        case COMMONSAF_HTTP_UPGRADE: break;
+        case COMMONSAF_KEEP_ALIVE: {
+            rq->rq_attr.keep_alive = util_getboolean(var, 0);
+            break;
+        }
+        case COMMONSAF_NAME: {
+            pblock_kvinsert(pb_key_name, value, strlen(value), rq->vars);
+            break;
+        }
+        case COMMONSAF_SENTHDRS: break;
+        case COMMONSAF_STOP: return COMMONSAF_RET_STOP;
+        case COMMONSAF_URL: break;
+    }
+    return COMMONSAF_RET_DEF;
+}
+
+int set_variable(pblock *pb, Session *sn, Request *rq) {
+    int ret = REQ_NOACTION;
+    int set = 0;
+    
+    for(int i=0;i<pb->hsize;i++) {
+        pb_entry *entry = pb->ht[i];
+        while(entry) {
+            int r = set_var(sn, rq, entry->param->name, entry->param->value);
+            switch(r) {
+                default:
+                case COMMONSAF_RET_DEF: break;
+                case COMMONSAF_RET_NOACTION: set = 1; ret = REQ_NOACTION; break;
+                case COMMONSAF_RET_STOP: set = 1; ret = REQ_PROCEED; break;
+                case COMMONSAF_REQ_ABORTED: ret = set ? ret : REQ_ABORTED; break;
+                case COMMONSAF_RET_ERROR: return REQ_ABORTED;
+            }
+            entry = entry->next;
+        }
+    }
+    
+    return ret;
+}
--- a/src/server/safs/common.h	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/safs/common.h	Sat Jan 28 10:38:34 2017 +0100
@@ -35,8 +35,12 @@
 extern "C" {
 #endif
 
+void common_saf_init();
+    
 int print_message(pblock *pb, Session *sn, Request *rq);
 
+int set_variable(pblock *pb, Session *sn, Request *rq);
+
 
 #ifdef	__cplusplus
 }
--- a/src/server/safs/init.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/safs/init.c	Sat Jan 28 10:38:34 2017 +0100
@@ -26,13 +26,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifdef XP_UNIX
 #include <dlfcn.h> 
-#endif
-#ifdef XP_WIN32
-
-#endif
-
 #include <ucx/string.h>
 
 #include "../daemon/func.h"
@@ -45,8 +39,6 @@
     return REQ_PROCEED;
 }
 
-#ifdef XP_UNIX
-
 int load_modules(pblock *pb, Session *sn, Request *rq) {
     char *shlib = pblock_findval("shlib", pb);
     char *funcs = pblock_findval("funcs", pb);
@@ -137,15 +129,3 @@
     
     return REQ_PROCEED;
 }
-
-#endif
-
-#ifdef XP_WIN32
-
-int load_modules(pblock *pb, Session *sn, Request *rq) {
-    // TODO: implement
-    return 0;
-}
-
-#endif
-
--- a/src/server/util/atomic.h	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/util/atomic.h	Sat Jan 28 10:38:34 2017 +0100
@@ -33,7 +33,7 @@
 extern "C" {
 #endif
 
-#if defined(__gnu_linux__) || defined(WINDOWS)
+#ifdef __gnu_linux__
 
 #define ws_atomic_inc32(intptr) __sync_fetch_and_add(intptr, 1)
 #define ws_atomic_dec32(intptr) __sync_fetch_and_sub(intptr, 1)
@@ -51,7 +51,6 @@
 #define ws_atomic_dec32(intptr) __sync_fetch_and_sub(intptr, 1)
 #define ws_atomic_add32(intptr, val) __sync_fetch_and_add(intptr, val)
 #define ws_atomic_sub32(intptr, val) __sync_fetch_and_sub(intptr, va
-    
 #else
 // use atomic.h
 #include <atomic.h>
--- a/src/server/util/io.h	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/util/io.h	Sat Jan 28 10:38:34 2017 +0100
@@ -34,8 +34,8 @@
 #include "systems.h"
 
 #ifdef _WIN32
+#include <windows.h>
 #include <winsock2.h>
-#include <windows.h>
 #endif
 
 #ifdef	__cplusplus
--- a/src/server/util/pblock.h	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/util/pblock.h	Sat Jan 28 10:38:34 2017 +0100
@@ -60,10 +60,8 @@
 #ifdef XP_WIN32
 #ifdef BUILD_DLL
 #define BASE_DLL _declspec(dllexport)
-#define BASE_DLL
 #else
-//define BASE_DLL _declspec(dllimport)
-#define BASE_DLL
+#define BASE_DLL _declspec(dllimport)
 #endif
 #else
 #define BASE_DLL
@@ -111,199 +109,198 @@
 
 typedef struct pb_key pb_key;
 
-BASE_DLL extern const pb_key *const pb_key_accept;
-BASE_DLL extern const pb_key *const pb_key_accept_charset;
-BASE_DLL extern const pb_key *const pb_key_accept_encoding;
-BASE_DLL extern const pb_key *const pb_key_accept_language;
-BASE_DLL extern const pb_key *const pb_key_accept_ranges;
-BASE_DLL extern const pb_key *const pb_key_actual_route;
-BASE_DLL extern const pb_key *const pb_key_age;
-BASE_DLL extern const pb_key *const pb_key_always_allow_chunked;
-BASE_DLL extern const pb_key *const pb_key_always_use_keep_alive;
-BASE_DLL extern const pb_key *const pb_key_auth_cert;
-BASE_DLL extern const pb_key *const pb_key_auth_expiring;
-BASE_DLL extern const pb_key *const pb_key_auth_group;
-BASE_DLL extern const pb_key *const pb_key_auth_type;
-BASE_DLL extern const pb_key *const pb_key_auth_user;
-BASE_DLL extern const pb_key *const pb_key_authorization;
-BASE_DLL extern const pb_key *const pb_key_browser;
-BASE_DLL extern const pb_key *const pb_key_c2p_cl;
-BASE_DLL extern const pb_key *const pb_key_c2p_hl;
-BASE_DLL extern const pb_key *const pb_key_cache_info;
-BASE_DLL extern const pb_key *const pb_key_charset;
-BASE_DLL extern const pb_key *const pb_key_check_http_server;
-BASE_DLL extern const pb_key *const pb_key_ChunkedRequestBufferSize;
-BASE_DLL extern const pb_key *const pb_key_ChunkedRequestTimeout;
-BASE_DLL extern const pb_key *const pb_key_cipher;
-BASE_DLL extern const pb_key *const pb_key_clf_request;
-BASE_DLL extern const pb_key *const pb_key_cli_status;
-BASE_DLL extern const pb_key *const pb_key_client_cert_nickname;
-BASE_DLL extern const pb_key *const pb_key_client_ip;
-BASE_DLL extern const pb_key *const pb_key_close;
-BASE_DLL extern const pb_key *const pb_key_connect_timeout;
-BASE_DLL extern const pb_key *const pb_key_connection;
-BASE_DLL extern const pb_key *const pb_key_cont;
-BASE_DLL extern const pb_key *const pb_key_content_encoding;
-BASE_DLL extern const pb_key *const pb_key_content_language;
-BASE_DLL extern const pb_key *const pb_key_content_length;
-BASE_DLL extern const pb_key *const pb_key_content_location;
-BASE_DLL extern const pb_key *const pb_key_content_md5;
-BASE_DLL extern const pb_key *const pb_key_content_range;
-BASE_DLL extern const pb_key *const pb_key_content_type;
-BASE_DLL extern const pb_key *const pb_key_cookie;
-BASE_DLL extern const pb_key *const pb_key_date;
-BASE_DLL extern const pb_key *const pb_key_DATE_GMT;
-BASE_DLL extern const pb_key *const pb_key_DATE_LOCAL;
-BASE_DLL extern const pb_key *const pb_key_dir;
-BASE_DLL extern const pb_key *const pb_key_Directive;
-BASE_DLL extern const pb_key *const pb_key_dns;
-BASE_DLL extern const pb_key *const pb_key_DOCUMENT_NAME;
-BASE_DLL extern const pb_key *const pb_key_DOCUMENT_URI;
-BASE_DLL extern const pb_key *const pb_key_domain;
-BASE_DLL extern const pb_key *const pb_key_enc;
-BASE_DLL extern const pb_key *const pb_key_engine;
-BASE_DLL extern const pb_key *const pb_key_error_action;
-BASE_DLL extern const pb_key *const pb_key_error_desc;
-BASE_DLL extern const pb_key *const pb_key_error_fn;
-BASE_DLL extern const pb_key *const pb_key_escape;
-BASE_DLL extern const pb_key *const pb_key_escaped;
-BASE_DLL extern const pb_key *const pb_key_etag;
-BASE_DLL extern const pb_key *const pb_key_expect;
-BASE_DLL extern const pb_key *const pb_key_expires;
-BASE_DLL extern const pb_key *const pb_key_expr;
-BASE_DLL extern const pb_key *const pb_key_filter;
-BASE_DLL extern const pb_key *const pb_key_find_pathinfo_forward;
-BASE_DLL extern const pb_key *const pb_key_flushTimer;
-BASE_DLL extern const pb_key *const pb_key_fn;
-BASE_DLL extern const pb_key *const pb_key_from;
-BASE_DLL extern const pb_key *const pb_key_full_headers;
-BASE_DLL extern const pb_key *const pb_key_hdr;
-BASE_DLL extern const pb_key *const pb_key_host;
-BASE_DLL extern const pb_key *const pb_key_hostname;
-BASE_DLL extern const pb_key *const pb_key_if_match;
-BASE_DLL extern const pb_key *const pb_key_if_modified_since;
-BASE_DLL extern const pb_key *const pb_key_if_none_match;
-BASE_DLL extern const pb_key *const pb_key_if_range;
-BASE_DLL extern const pb_key *const pb_key_if_unmodified_since;
-BASE_DLL extern const pb_key *const pb_key_ip;
-BASE_DLL extern const pb_key *const pb_key_iponly;
-BASE_DLL extern const pb_key *const pb_key_issuer_dn;
-BASE_DLL extern const pb_key *const pb_key_jroute;
-BASE_DLL extern const pb_key *const pb_key_keep_alive;
-BASE_DLL extern const pb_key *const pb_key_keep_alive_timeout;
-BASE_DLL extern const pb_key *const pb_key_keysize;
-BASE_DLL extern const pb_key *const pb_key_lang;
-BASE_DLL extern const pb_key *const pb_key_LAST_MODIFIED;
-BASE_DLL extern const pb_key *const pb_key_last_modified;
-BASE_DLL extern const pb_key *const pb_key_level;
-BASE_DLL extern const pb_key *const pb_key_location;
-BASE_DLL extern const pb_key *const pb_key_lock_owner;
-BASE_DLL extern const pb_key *const pb_key_magnus_charset;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_dav_src;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_default_acls_only;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_error_j2ee;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_j2ee_nsapi;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_preserve_srvhdrs;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_set_request_status;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_set_response_status;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_webapp_errordesc;
-BASE_DLL extern const pb_key *const pb_key_matched_browser;
-BASE_DLL extern const pb_key *const pb_key_max_age;
-BASE_DLL extern const pb_key *const pb_key_max_forwards;
-BASE_DLL extern const pb_key *const pb_key_message;
-BASE_DLL extern const pb_key *const pb_key_method;
-BASE_DLL extern const pb_key *const pb_key_name;
-BASE_DLL extern const pb_key *const pb_key_nocache;
-BASE_DLL extern const pb_key *const pb_key_nostat;
-BASE_DLL extern const pb_key *const pb_key_ntrans_base;
-BASE_DLL extern const pb_key *const pb_key_offline_origin_addr;
-BASE_DLL extern const pb_key *const pb_key_offline_proxy_addr;
-BASE_DLL extern const pb_key *const pb_key_origin_addr;
-BASE_DLL extern const pb_key *const pb_key_p2c_cl;
-BASE_DLL extern const pb_key *const pb_key_p2c_hl;
-BASE_DLL extern const pb_key *const pb_key_p2r_cl;
-BASE_DLL extern const pb_key *const pb_key_p2r_hl;
-BASE_DLL extern const pb_key *const pb_key_parse_timeout;
-BASE_DLL extern const pb_key *const pb_key_password;
-BASE_DLL extern const pb_key *const pb_key_path;
-BASE_DLL extern const pb_key *const pb_key_PATH_INFO;
-BASE_DLL extern const pb_key *const pb_key_path_info;
-BASE_DLL extern const pb_key *const pb_key_pblock;
-BASE_DLL extern const pb_key *const pb_key_poll_interval;
-BASE_DLL extern const pb_key *const pb_key_pool; // new
-BASE_DLL extern const pb_key *const pb_key_port;
-BASE_DLL extern const pb_key *const pb_key_ppath;
-BASE_DLL extern const pb_key *const pb_key_pragma;
-BASE_DLL extern const pb_key *const pb_key_process_request_body;
-BASE_DLL extern const pb_key *const pb_key_process_response_body;
-BASE_DLL extern const pb_key *const pb_key_protocol;
-BASE_DLL extern const pb_key *const pb_key_proxy_addr;
-BASE_DLL extern const pb_key *const pb_key_proxy_agent;
-BASE_DLL extern const pb_key *const pb_key_proxy_auth_cert;
-BASE_DLL extern const pb_key *const pb_key_proxy_authorization;
-BASE_DLL extern const pb_key *const pb_key_proxy_cipher;
-BASE_DLL extern const pb_key *const pb_key_proxy_issuer_dn;
-BASE_DLL extern const pb_key *const pb_key_proxy_jroute;
-BASE_DLL extern const pb_key *const pb_key_proxy_keysize;
-BASE_DLL extern const pb_key *const pb_key_proxy_ping;
-BASE_DLL extern const pb_key *const pb_key_proxy_request;
-BASE_DLL extern const pb_key *const pb_key_proxy_secret_keysize;
-BASE_DLL extern const pb_key *const pb_key_proxy_ssl_id;
-BASE_DLL extern const pb_key *const pb_key_proxy_user_dn;
-BASE_DLL extern const pb_key *const pb_key_query;
-BASE_DLL extern const pb_key *const pb_key_QUERY_STRING;
-BASE_DLL extern const pb_key *const pb_key_QUERY_STRING_UNESCAPED;
-BASE_DLL extern const pb_key *const pb_key_r2p_cl;
-BASE_DLL extern const pb_key *const pb_key_r2p_hl;
-BASE_DLL extern const pb_key *const pb_key_range;
-BASE_DLL extern const pb_key *const pb_key_referer;
-BASE_DLL extern const pb_key *const pb_key_reformat_request_headers;
-BASE_DLL extern const pb_key *const pb_key_remote_status;
-BASE_DLL extern const pb_key *const pb_key_request_jroute;
-BASE_DLL extern const pb_key *const pb_key_required_rights;
-BASE_DLL extern const pb_key *const pb_key_retries;
-BASE_DLL extern const pb_key *const pb_key_rewrite_content_location;
-BASE_DLL extern const pb_key *const pb_key_rewrite_host;
-BASE_DLL extern const pb_key *const pb_key_rewrite_location;
-BASE_DLL extern const pb_key *const pb_key_rewrite_set_cookie;
-BASE_DLL extern const pb_key *const pb_key_root;
-BASE_DLL extern const pb_key *const pb_key_route;
-BASE_DLL extern const pb_key *const pb_key_route_cookie;
-BASE_DLL extern const pb_key *const pb_key_route_hdr;
-BASE_DLL extern const pb_key *const pb_key_route_offline;
-BASE_DLL extern const pb_key *const pb_key_script_name;
-BASE_DLL extern const pb_key *const pb_key_secret_keysize;
-BASE_DLL extern const pb_key *const pb_key_secure;
-BASE_DLL extern const pb_key *const pb_key_server;
-BASE_DLL extern const pb_key *const pb_key_set_cookie;
-BASE_DLL extern const pb_key *const pb_key_socks_addr;
-BASE_DLL extern const pb_key *const pb_key_ssl_id;
-BASE_DLL extern const pb_key *const pb_key_ssl_unclean_shutdown;
-BASE_DLL extern const pb_key *const pb_key_status;
-BASE_DLL extern const pb_key *const pb_key_sticky_cookie;
-BASE_DLL extern const pb_key *const pb_key_sticky_param;
-BASE_DLL extern const pb_key *const pb_key_suppress_request_headers;
-BASE_DLL extern const pb_key *const pb_key_svr_status;
-BASE_DLL extern const pb_key *const pb_key_timeout;
-BASE_DLL extern const pb_key *const pb_key_to;
-BASE_DLL extern const pb_key *const pb_key_transfer_encoding;
-BASE_DLL extern const pb_key *const pb_key_transmit_timeout;
-BASE_DLL extern const pb_key *const pb_key_tunnel_non_http_response;
-BASE_DLL extern const pb_key *const pb_key_type;
-BASE_DLL extern const pb_key *const pb_key_upstream_jroute;
-BASE_DLL extern const pb_key *const pb_key_uri;
-BASE_DLL extern const pb_key *const pb_key_url;
-BASE_DLL extern const pb_key *const pb_key_url_prefix;
-BASE_DLL extern const pb_key *const pb_key_UseOutputStreamSize;
-BASE_DLL extern const pb_key *const pb_key_user;
-BASE_DLL extern const pb_key *const pb_key_user_agent;
-BASE_DLL extern const pb_key *const pb_key_user_dn;
-BASE_DLL extern const pb_key *const pb_key_validate_server_cert;
-BASE_DLL extern const pb_key *const pb_key_value;
-BASE_DLL extern const pb_key *const pb_key_vary;
-BASE_DLL extern const pb_key *const pb_key_via;
-BASE_DLL extern const pb_key *const pb_key_warning;
+extern const pb_key *const pb_key_accept;
+extern const pb_key *const pb_key_accept_charset;
+extern const pb_key *const pb_key_accept_encoding;
+extern const pb_key *const pb_key_accept_language;
+extern const pb_key *const pb_key_accept_ranges;
+extern const pb_key *const pb_key_actual_route;
+extern const pb_key *const pb_key_age;
+extern const pb_key *const pb_key_always_allow_chunked;
+extern const pb_key *const pb_key_always_use_keep_alive;
+extern const pb_key *const pb_key_auth_cert;
+extern const pb_key *const pb_key_auth_expiring;
+extern const pb_key *const pb_key_auth_group;
+extern const pb_key *const pb_key_auth_type;
+extern const pb_key *const pb_key_auth_user;
+extern const pb_key *const pb_key_authorization;
+extern const pb_key *const pb_key_browser;
+extern const pb_key *const pb_key_c2p_cl;
+extern const pb_key *const pb_key_c2p_hl;
+extern const pb_key *const pb_key_cache_info;
+extern const pb_key *const pb_key_charset;
+extern const pb_key *const pb_key_check_http_server;
+extern const pb_key *const pb_key_ChunkedRequestBufferSize;
+extern const pb_key *const pb_key_ChunkedRequestTimeout;
+extern const pb_key *const pb_key_cipher;
+extern const pb_key *const pb_key_clf_request;
+extern const pb_key *const pb_key_cli_status;
+extern const pb_key *const pb_key_client_cert_nickname;
+extern const pb_key *const pb_key_client_ip;
+extern const pb_key *const pb_key_close;
+extern const pb_key *const pb_key_connect_timeout;
+extern const pb_key *const pb_key_connection;
+extern const pb_key *const pb_key_cont;
+extern const pb_key *const pb_key_content_encoding;
+extern const pb_key *const pb_key_content_language;
+extern const pb_key *const pb_key_content_length;
+extern const pb_key *const pb_key_content_location;
+extern const pb_key *const pb_key_content_md5;
+extern const pb_key *const pb_key_content_range;
+extern const pb_key *const pb_key_content_type;
+extern const pb_key *const pb_key_cookie;
+extern const pb_key *const pb_key_date;
+extern const pb_key *const pb_key_DATE_GMT;
+extern const pb_key *const pb_key_DATE_LOCAL;
+extern const pb_key *const pb_key_dir;
+extern const pb_key *const pb_key_Directive;
+extern const pb_key *const pb_key_dns;
+extern const pb_key *const pb_key_DOCUMENT_NAME;
+extern const pb_key *const pb_key_DOCUMENT_URI;
+extern const pb_key *const pb_key_domain;
+extern const pb_key *const pb_key_enc;
+extern const pb_key *const pb_key_engine;
+extern const pb_key *const pb_key_error_action;
+extern const pb_key *const pb_key_error_desc;
+extern const pb_key *const pb_key_error_fn;
+extern const pb_key *const pb_key_escape;
+extern const pb_key *const pb_key_escaped;
+extern const pb_key *const pb_key_etag;
+extern const pb_key *const pb_key_expect;
+extern const pb_key *const pb_key_expires;
+extern const pb_key *const pb_key_expr;
+extern const pb_key *const pb_key_filter;
+extern const pb_key *const pb_key_find_pathinfo_forward;
+extern const pb_key *const pb_key_flushTimer;
+extern const pb_key *const pb_key_fn;
+extern const pb_key *const pb_key_from;
+extern const pb_key *const pb_key_full_headers;
+extern const pb_key *const pb_key_hdr;
+extern const pb_key *const pb_key_host;
+extern const pb_key *const pb_key_hostname;
+extern const pb_key *const pb_key_if_match;
+extern const pb_key *const pb_key_if_modified_since;
+extern const pb_key *const pb_key_if_none_match;
+extern const pb_key *const pb_key_if_range;
+extern const pb_key *const pb_key_if_unmodified_since;
+extern const pb_key *const pb_key_ip;
+extern const pb_key *const pb_key_iponly;
+extern const pb_key *const pb_key_issuer_dn;
+extern const pb_key *const pb_key_jroute;
+extern const pb_key *const pb_key_keep_alive;
+extern const pb_key *const pb_key_keep_alive_timeout;
+extern const pb_key *const pb_key_keysize;
+extern const pb_key *const pb_key_lang;
+extern const pb_key *const pb_key_last_modified;
+extern const pb_key *const pb_key_level;
+extern const pb_key *const pb_key_location;
+extern const pb_key *const pb_key_lock_owner;
+extern const pb_key *const pb_key_magnus_charset;
+extern const pb_key *const pb_key_magnus_internal;
+extern const pb_key *const pb_key_magnus_internal_dav_src;
+extern const pb_key *const pb_key_magnus_internal_default_acls_only;
+extern const pb_key *const pb_key_magnus_internal_error_j2ee;
+extern const pb_key *const pb_key_magnus_internal_j2ee_nsapi;
+extern const pb_key *const pb_key_magnus_internal_preserve_srvhdrs;
+extern const pb_key *const pb_key_magnus_internal_set_request_status;
+extern const pb_key *const pb_key_magnus_internal_set_response_status;
+extern const pb_key *const pb_key_magnus_internal_webapp_errordesc;
+extern const pb_key *const pb_key_matched_browser;
+extern const pb_key *const pb_key_max_age;
+extern const pb_key *const pb_key_max_forwards;
+extern const pb_key *const pb_key_message;
+extern const pb_key *const pb_key_method;
+extern const pb_key *const pb_key_name;
+extern const pb_key *const pb_key_nocache;
+extern const pb_key *const pb_key_nostat;
+extern const pb_key *const pb_key_ntrans_base;
+extern const pb_key *const pb_key_offline_origin_addr;
+extern const pb_key *const pb_key_offline_proxy_addr;
+extern const pb_key *const pb_key_origin_addr;
+extern const pb_key *const pb_key_p2c_cl;
+extern const pb_key *const pb_key_p2c_hl;
+extern const pb_key *const pb_key_p2r_cl;
+extern const pb_key *const pb_key_p2r_hl;
+extern const pb_key *const pb_key_parse_timeout;
+extern const pb_key *const pb_key_password;
+extern const pb_key *const pb_key_path;
+extern const pb_key *const pb_key_PATH_INFO;
+extern const pb_key *const pb_key_path_info;
+extern const pb_key *const pb_key_pblock;
+extern const pb_key *const pb_key_poll_interval;
+extern const pb_key *const pb_key_pool; // new
+extern const pb_key *const pb_key_port;
+extern const pb_key *const pb_key_ppath;
+extern const pb_key *const pb_key_pragma;
+extern const pb_key *const pb_key_process_request_body;
+extern const pb_key *const pb_key_process_response_body;
+extern const pb_key *const pb_key_protocol;
+extern const pb_key *const pb_key_proxy_addr;
+extern const pb_key *const pb_key_proxy_agent;
+extern const pb_key *const pb_key_proxy_auth_cert;
+extern const pb_key *const pb_key_proxy_authorization;
+extern const pb_key *const pb_key_proxy_cipher;
+extern const pb_key *const pb_key_proxy_issuer_dn;
+extern const pb_key *const pb_key_proxy_jroute;
+extern const pb_key *const pb_key_proxy_keysize;
+extern const pb_key *const pb_key_proxy_ping;
+extern const pb_key *const pb_key_proxy_request;
+extern const pb_key *const pb_key_proxy_secret_keysize;
+extern const pb_key *const pb_key_proxy_ssl_id;
+extern const pb_key *const pb_key_proxy_user_dn;
+extern const pb_key *const pb_key_query;
+extern const pb_key *const pb_key_QUERY_STRING;
+extern const pb_key *const pb_key_QUERY_STRING_UNESCAPED;
+extern const pb_key *const pb_key_r2p_cl;
+extern const pb_key *const pb_key_r2p_hl;
+extern const pb_key *const pb_key_range;
+extern const pb_key *const pb_key_referer;
+extern const pb_key *const pb_key_reformat_request_headers;
+extern const pb_key *const pb_key_remote_status;
+extern const pb_key *const pb_key_request_jroute;
+extern const pb_key *const pb_key_required_rights;
+extern const pb_key *const pb_key_retries;
+extern const pb_key *const pb_key_rewrite_content_location;
+extern const pb_key *const pb_key_rewrite_host;
+extern const pb_key *const pb_key_rewrite_location;
+extern const pb_key *const pb_key_rewrite_set_cookie;
+extern const pb_key *const pb_key_root;
+extern const pb_key *const pb_key_route;
+extern const pb_key *const pb_key_route_cookie;
+extern const pb_key *const pb_key_route_hdr;
+extern const pb_key *const pb_key_route_offline;
+extern const pb_key *const pb_key_script_name;
+extern const pb_key *const pb_key_secret_keysize;
+extern const pb_key *const pb_key_secure;
+extern const pb_key *const pb_key_server;
+extern const pb_key *const pb_key_set_cookie;
+extern const pb_key *const pb_key_socks_addr;
+extern const pb_key *const pb_key_ssl_id;
+extern const pb_key *const pb_key_ssl_unclean_shutdown;
+extern const pb_key *const pb_key_status;
+extern const pb_key *const pb_key_sticky_cookie;
+extern const pb_key *const pb_key_sticky_param;
+extern const pb_key *const pb_key_suppress_request_headers;
+extern const pb_key *const pb_key_svr_status;
+extern const pb_key *const pb_key_timeout;
+extern const pb_key *const pb_key_to;
+extern const pb_key *const pb_key_transfer_encoding;
+extern const pb_key *const pb_key_transmit_timeout;
+extern const pb_key *const pb_key_tunnel_non_http_response;
+extern const pb_key *const pb_key_type;
+extern const pb_key *const pb_key_upstream_jroute;
+extern const pb_key *const pb_key_uri;
+extern const pb_key *const pb_key_url;
+extern const pb_key *const pb_key_url_prefix;
+extern const pb_key *const pb_key_UseOutputStreamSize;
+extern const pb_key *const pb_key_user;
+extern const pb_key *const pb_key_user_agent;
+extern const pb_key *const pb_key_user_dn;
+extern const pb_key *const pb_key_validate_server_cert;
+extern const pb_key *const pb_key_value;
+extern const pb_key *const pb_key_vary;
+extern const pb_key *const pb_key_via;
+extern const pb_key *const pb_key_warning;
 
 NSAPI_PUBLIC pool_handle_t *pblock_pool(pblock *pb);
 
--- a/src/server/util/systhr.c	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/util/systhr.c	Sat Jan 28 10:38:34 2017 +0100
@@ -62,7 +62,6 @@
 }
 
 
-#ifdef XP_UNIX
 
 SYS_THREAD systhread_start(int prio, int stksz, thrstartfunc fn, void *arg) {
     pthread_t      thr = 0;
@@ -155,64 +154,4 @@
 }
 
 NSAPI_PUBLIC void systhread_dummy(void) {
-    
 }
-
-#endif
-
-#ifdef XP_WIN32
-
-SYS_THREAD systhread_start(int prio, int stksz, thrstartfunc fn, void *arg) {
-    
-}
-
-SYS_THREAD systhread_current(void) {
-    
-}
-
-void systhread_yield(void) {
-    
-}
-
-void systhread_timerset(int usec) {
-   
-}
-
-SYS_THREAD systhread_attach(void) {
-    
-}
-
-void systhread_detach(SYS_THREAD thr) {
-    
-}
-
-void systhread_terminate(SYS_THREAD thr) {
-    
-}
-
-void systhread_sleep(int msec) {
-    
-}
-
-NSAPI_PUBLIC int systhread_newkey() {
-    
-}
-
-NSAPI_PUBLIC void* systhread_getdata(int key) {
-    
-}
-
-NSAPI_PUBLIC void systhread_setdata(int key, void *data) {
-    
-}
-
-NSAPI_PUBLIC void systhread_init(char *name)
-{
-    
-}
-
-NSAPI_PUBLIC void systhread_dummy(void) {
-    
-}
-
-#endif
--- a/src/server/util/uri.cpp	Thu Jan 26 18:53:52 2017 +0100
+++ b/src/server/util/uri.cpp	Sat Jan 28 10:38:34 2017 +0100
@@ -31,17 +31,17 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifdef XP_WIN32
+#define _MBCS
+#include <windows.h>
+#include <mbctype.h>
+#endif
+
 #include "util.h"
 #include "pool.h"
 //include "frame/conf_api.h"
 //include "support/stringvalue.h"
 
-#ifdef WINDOWS
-#define _MBCS
-#include <windows.h>
-#include <mbctype.h>
-#endif
-
 #ifdef XP_WIN32
 static PRBool _getfullpathname = -1;
 #endif /* XP_WIN32 */

mercurial