src/server/safs/common.c

changeset 162
b169992137a8
parent 161
aadda87bad1b
child 254
4784c14aa639
--- 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;
+}

mercurial