adds find-pathinfo saf

Sun, 23 Oct 2016 10:52:54 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 23 Oct 2016 10:52:54 +0200
changeset 116
d7a186cf87f6
parent 115
51d9a15eac98
child 117
a94cf2e94492

adds find-pathinfo saf

nametrans sets ntrans-base when possible
using path instead of ppath after nametrans

src/server/daemon/httprequest.c file | annotate | diff | comparison | revisions
src/server/daemon/request.c file | annotate | diff | comparison | revisions
src/server/daemon/request.h file | annotate | diff | comparison | revisions
src/server/daemon/ws-fn.c file | annotate | diff | comparison | revisions
src/server/safs/nametrans.c file | annotate | diff | comparison | revisions
src/server/safs/objecttype.c file | annotate | diff | comparison | revisions
src/server/safs/objs.mk file | annotate | diff | comparison | revisions
src/server/safs/pcheck.c file | annotate | diff | comparison | revisions
src/server/safs/pcheck.h file | annotate | diff | comparison | revisions
src/server/safs/service.c file | annotate | diff | comparison | revisions
templates/config/obj.conf file | annotate | diff | comparison | revisions
--- a/src/server/daemon/httprequest.c	Sat Oct 22 11:27:39 2016 +0200
+++ b/src/server/daemon/httprequest.c	Sun Oct 23 10:52:54 2016 +0200
@@ -612,8 +612,12 @@
             rq->rq.vars);
         */
         sstr_t uri = sstr(pblock_findkeyval(pb_key_uri, rq->rq.reqpb));
-        util_add_ppath(docroot, uri, rq->rq.vars);
+        request_set_path(docroot, uri, rq->rq.vars);
     }
+    
+    // TODO: remove ppath
+    char *pp = pblock_findkeyval(pb_key_ppath, rq->rq.vars);
+    pblock_kvinsert(pb_key_path, pp, strlen(pp), rq->rq.vars);
 
     return REQ_PROCEED;
 }
@@ -984,10 +988,9 @@
             (Session*)data->sn,
             (Request*)data->rq);
     
+    nsapi_function_return((Session*)data->sn, (Request*)data->rq, r);
     free(data);
     
-    nsapi_function_return((Session*)data->sn, (Request*)data->rq, r);
-    
     return NULL;
 }
 
--- a/src/server/daemon/request.c	Sat Oct 22 11:27:39 2016 +0200
+++ b/src/server/daemon/request.c	Sun Oct 23 10:52:54 2016 +0200
@@ -123,6 +123,33 @@
     return s;
 }
 
+int request_set_path(sstr_t root, sstr_t path, pblock *vars) {
+    // TODO: maybe replace this code with request_set_path from req.cpp
+    
+    // concat path
+    size_t length = root.length + path.length;
+    char *translated_path = alloca(length + 1);
+    memcpy(translated_path, root.ptr, root.length);
+    if(root.ptr[root.length-1] == '/') {
+        memcpy(translated_path + root.length, path.ptr, path.length);
+    } else {
+        translated_path[root.length] = '/';
+        memcpy(translated_path + root.length + 1, path.ptr, path.length);
+        length++;
+    }
+    
+    // add path to specified pblock
+    pblock_kvinsert(
+            pb_key_ppath,
+            translated_path,
+            length,
+            vars);
+    
+    pblock_kvinsert(pb_key_ntrans_base, root.ptr, root.length, vars);
+    
+    return REQ_PROCEED;
+}
+
 void request_free(Request *rq) {
     // TODO: implement
 }
--- a/src/server/daemon/request.h	Sat Oct 22 11:27:39 2016 +0200
+++ b/src/server/daemon/request.h	Sun Oct 23 10:52:54 2016 +0200
@@ -52,6 +52,7 @@
 
 #define REQ_HASHSIZE 10
 
+int request_set_path(sstr_t root, sstr_t path, pblock *vars);
 
 #ifdef	__cplusplus
 }
--- a/src/server/daemon/ws-fn.c	Sat Oct 22 11:27:39 2016 +0200
+++ b/src/server/daemon/ws-fn.c	Sun Oct 23 10:52:54 2016 +0200
@@ -31,6 +31,7 @@
 #include "../safs/auth.h"
 #include "../safs/nametrans.h"
 #include "../safs/pathcheck.h"
+#include "../safs/pcheck.h"
 #include "../safs/objecttype.h"
 #include "../safs/service.h"
 #include "../safs/init.h"
@@ -56,6 +57,7 @@
     { "auth-db", auth_db, NULL, NULL, 0 },
     { "require-auth", require_auth, NULL, NULL, 0},
     { "require-access", require_access, NULL, NULL, 0},
+    { "find-pathinfo", pcheck_find_path, NULL, NULL, 0},
     { "append-acl", append_acl, NULL, NULL, 0},
     { "check-acl", check_acl, NULL, NULL, 0},
     { "print-message", print_message, NULL, NULL, 0},
--- a/src/server/safs/nametrans.c	Sat Oct 22 11:27:39 2016 +0200
+++ b/src/server/safs/nametrans.c	Sun Oct 23 10:52:54 2016 +0200
@@ -29,6 +29,7 @@
 #include "nametrans.h"
 
 #include "../daemon/log.h"
+#include "../daemon/request.h"
 #include "../util/pblock.h"
 #include "../util/util.h"
 
@@ -90,7 +91,8 @@
     
     sstr_t root_str = sstr(root);
     sstr_t uri_str = sstr(pblock_findkeyval(pb_key_uri, rq->reqpb));  
-    util_add_ppath(root_str, uri_str, rq->vars);
+    
+    request_set_path(root_str, uri_str, rq->vars);
     
     return REQ_PROCEED;
 }
@@ -144,13 +146,18 @@
     if(uri[0] == '/') {
         uri++;
     }
+    
+    
     sstr_t ppath = util_path_append(sn->pool, dir, uri);
+    
     pblock_kvinsert(
             pb_key_ppath,
             ppath.ptr,
             ppath.length,
             rq->vars);
     
+    request_set_path(sstr(dir), sstr(uri), rq->vars);
+    
     if(name) {
         // add object to rq->vars
         pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars);
--- a/src/server/safs/objecttype.c	Sat Oct 22 11:27:39 2016 +0200
+++ b/src/server/safs/objecttype.c	Sun Oct 23 10:52:54 2016 +0200
@@ -36,20 +36,20 @@
 #include "../daemon/session.h"
 
 int object_type_by_extension(pblock *pb, Session *sn, Request *rq) {
-    sstr_t ppath = sstr(pblock_findkeyval(pb_key_ppath, rq->vars));
-    //printf("\nobject_type_by_extension: {%s}[%d]\n\n", ppath);
+    sstr_t path = sstr(pblock_findkeyval(pb_key_path, rq->vars));
+    //printf("\nobject_type_by_extension: {%s}[%d]\n\n", path);
 
     sstr_t ct;
-    if(ppath.ptr[ppath.length - 1] == '/') {
+    if(path.ptr[path.length - 1] == '/') {
         // directory
         ct = sstrn("internal/directory", 18);
     } else {
         sstr_t ext;
         ext.length = 0;
-        for(int i=ppath.length - 1;i>=0;i--) {
-            if(ppath.ptr[i] == '.') {
-                ext.ptr = ppath.ptr + i + 1;
-                ext.length = ppath.length - i - 1;
+        for(int i=path.length - 1;i>=0;i--) {
+            if(path.ptr[i] == '.') {
+                ext.ptr = path.ptr + i + 1;
+                ext.length = path.length - i - 1;
             }
         }
 
--- a/src/server/safs/objs.mk	Sat Oct 22 11:27:39 2016 +0200
+++ b/src/server/safs/objs.mk	Sun Oct 23 10:52:54 2016 +0200
@@ -36,6 +36,7 @@
 SAFOBJ += init.o
 SAFOBJ += auth.o
 SAFOBJ += pathcheck.o
+SAFOBJ += pcheck.o
 SAFOBJ += common.o
 SAFOBJ += addlog.o
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/safs/pcheck.c	Sun Oct 23 10:52:54 2016 +0200
@@ -0,0 +1,233 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * open web server code from safs/pcheck.cpp
+ */
+
+#include "pcheck.h"
+
+#include "../util/pblock.h"
+
+/* --------------------------- pcheck_find_path --------------------------- */
+
+
+/*
+ * Takes a given path, and figures out if there is any path_info attached.
+ * If no explicit path_info was provided by nametrans, and the file doesn't 
+ * exist as specified, it tries to find it by groping through the filesystem.
+ * 
+ * This type of implicit path_info cannot be attached to directories. Such
+ * a request will be flagged as not found.
+ * 
+ * pb unused.
+ */
+
+static char* find_param(char *uri, char *param)
+{
+    // Find ;parameters on the end of uri
+    if (param > uri) {
+        if (*param == FILE_PATHSEP) {
+            --param;
+        }
+        while (param > uri && *param != FILE_PATHSEP && *param != ';') {
+            --param;
+        }
+        if (*param == ';') {
+            return param;
+        }
+    }
+
+    return NULL;
+}
+
+static PRBool set_path_info(Request *rq, char *uri, int path_info_depth)
+{
+    // Find trailing path components in uri, e.g. the "/baz;qux/quux" in
+    // "/cgi-bin/foo.pl;bar/baz;qux/quux" (here path_info_depth would be 2)
+    char *path_info = &uri[strlen(uri)];
+    while (path_info > uri && path_info_depth) {
+        --path_info;
+        if (*path_info == FILE_PATHSEP) {
+            --path_info_depth;
+        }
+    }
+
+    if (*path_info) {
+        pblock_nvinsert("path-info", path_info, rq->vars);
+        return PR_TRUE;
+    }
+
+    return PR_FALSE;
+}
+
+int pcheck_find_path(pblock *pb, Session *sn, Request *rq) 
+{
+    char *path = pblock_findkeyval (pb_key_path, rq -> vars);
+    char *path_info   = pblock_findkeyval (pb_key_path_info  , rq -> vars);
+    char *script_name = pblock_findkeyval (pb_key_script_name, rq -> vars);
+    //NSFCFileInfo *finfo = NULL;
+    struct stat *finfo;
+
+    rq->directive_is_cacheable = 1;
+
+    if (path_info != NULL || script_name != NULL || path == NULL)
+	return REQ_NOACTION;// ruslan: bail out right away for performance (no need to go into file cache)
+
+    if (!*path)
+        return REQ_NOACTION;
+
+    /*
+    if ((INTrequest_info_path(path, rq, NULL) == PR_SUCCESS))
+        return REQ_NOACTION;
+    */
+
+    rq->directive_is_cacheable = 0;
+
+    path_info = &path[strlen(path) - 1];
+
+    char *forward = pblock_findkeyval(pb_key_find_pathinfo_forward, rq->vars);
+    char *base = NULL;
+    if (forward) {
+        base   = pblock_findval("ntrans-base"  , rq -> vars);
+        if (!base) forward = NULL;
+    }
+
+    int path_info_depth = 0;
+    
+    if(!forward) {
+        while (1) {
+            /* Change all occurrences of '/' to FILE_PATHSEP for WIN32 */
+            for(  ; path_info != path; --path_info)
+                if (*path_info == FILE_PATHSEP)
+                    break;
+            for(  ; path_info != path; --path_info) {
+                ++path_info_depth;
+                if (*(path_info - 1) != FILE_PATHSEP)
+                    break;
+            }
+
+            if (path_info == path)
+                break;
+
+            *path_info = '\0';
+            //if ((INTrequest_info_path(path, rq, &finfo) == PR_SUCCESS) && finfo) {
+            if((finfo = request_stat_path(path, rq)) != NULL) {
+                //if (finfo->pr.type != PR_FILE_FILE) {
+                if(S_ISDIR(finfo->st_mode)) {
+                    *path_info = FILE_PATHSEP;
+                    if (set_path_info(rq, pblock_findkeyval(pb_key_uri, rq->reqpb), 0)) {
+                        free(finfo);
+                        return REQ_PROCEED;
+                    }
+                    break;
+                } else {
+                    set_path_info(rq, pblock_findkeyval(pb_key_uri, rq->reqpb), path_info_depth);
+                    free(finfo);
+                    return REQ_PROCEED;
+                }
+            } else {
+                *path_info-- = FILE_PATHSEP;
+            }
+        }
+        /* This was changed to support virtual documents */
+        return REQ_NOACTION;
+    } else {
+        int baselen = strlen(base);
+        if (strncmp(path, base, baselen))
+            return REQ_NOACTION;
+
+        path_info = &path[baselen];
+        if (*path_info == '/')
+            path_info++;
+
+        while (1) {
+            for(  ; *path_info; ++path_info)
+                if (*path_info == FILE_PATHSEP)
+                    break;
+
+            if (!*path_info) {
+                if (set_path_info(rq, pblock_findkeyval(pb_key_uri, rq->reqpb), 0)) {
+                    return REQ_PROCEED;
+                }
+                break;
+            }
+
+            *path_info = '\0';
+            //if ((INTrequest_info_path(path, rq, &finfo) == PR_SUCCESS) && finfo) {
+            if((finfo = request_stat_path(path, rq)) != NULL) {
+                //if (finfo->pr.type != PR_FILE_FILE) {
+                if(S_ISDIR(finfo->st_mode)) {
+                    *path_info++ = FILE_PATHSEP;
+                } else {
+                    char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
+                    *path_info = FILE_PATHSEP;
+    #ifdef XP_WIN32
+                    char *unmpath = pblock_findval("unmuri", rq->vars);
+                    if (unmpath) {
+                        char *nm = &path_info[strlen(path_info)-1];
+                        char *unm = &unmpath[strlen(unmpath)-1];
+                        while(nm != path_info && unm != unmpath) {
+                            if (*nm != *unm) {
+                                if (*unm == '\\' && *nm == '/')
+                                    *nm = *unm;
+                                else
+                                    PR_ASSERT(0);
+                            }
+                            nm--;
+                            unm--;
+                        }
+                        uri = unmpath;
+                    }
+    #endif
+                    char *t = path_info;
+                    for(; *t; ++t)
+                        if (*t == FILE_PATHSEP)
+                            ++path_info_depth;
+                    *path_info = '\0';
+                    set_path_info(rq, uri, path_info_depth);
+                    free(finfo);
+                    return REQ_PROCEED;
+                }
+                free(finfo);
+            }
+            else {
+               *path_info = FILE_PATHSEP;
+                break;
+            }
+        }
+
+        /* This was changed to support virtual documents */
+        return REQ_NOACTION;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/safs/pcheck.h	Sun Oct 23 10:52:54 2016 +0200
@@ -0,0 +1,46 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2016 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PCHECK_H
+#define PCHECK_H
+
+#include "../public/nsapi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int pcheck_find_path(pblock *pb, Session *sn, Request *rq);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PCHECK_H */
+
--- a/src/server/safs/service.c	Sat Oct 22 11:27:39 2016 +0200
+++ b/src/server/safs/service.c	Sun Oct 23 10:52:54 2016 +0200
@@ -53,10 +53,10 @@
  * return the opened file
  */
 SYS_FILE prepare_service_file(Session *sn, Request *rq, VFSContext *vfs, struct stat *s) {
-    char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
+    char *path = pblock_findkeyval(pb_key_path, rq->vars);
 
     // open the file
-    SYS_FILE fd = vfs_open(vfs, ppath, O_RDONLY);
+    SYS_FILE fd = vfs_open(vfs, path, O_RDONLY);
     if(!fd) {
         // vfs_open sets http status code
         return NULL;
@@ -349,6 +349,7 @@
     }
     net_printf(sn->csd, "%s--\r\n", sep);
     
+    free(r);
     return 0;
 }
 
@@ -451,14 +452,14 @@
 int service_index(pblock *pb, Session *sn, Request *rq) {
     //printf("service_index\n");
 
-    char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
+    char *path = pblock_findkeyval(pb_key_path, rq->vars);
     char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
 
     sstr_t r_uri = sstr(uri);
 
     // open the file
     VFSContext *vfs = vfs_request_context(sn, rq);
-    VFS_DIR dir = vfs_opendir(vfs, ppath);
+    VFS_DIR dir = vfs_opendir(vfs, path);
     if(!dir) {
         return REQ_ABORTED;
     }
--- a/templates/config/obj.conf	Sat Oct 22 11:27:39 2016 +0200
+++ b/templates/config/obj.conf	Sun Oct 23 10:52:54 2016 +0200
@@ -7,6 +7,7 @@
 <Object name="default">
 NameTrans fn="assign-name" from="/hello" name="hello"
 NameTrans fn="assign-name" from="/admin" name="admin"
+PathCheck fn="find-pathinfo"
 ObjectType fn="type-by-extension"
 Service fn="send-options" method="OPTIONS"
 Service fn="common-index" type="internal/directory"

mercurial