UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2016 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "nametrans.h" 30 31 #include "../daemon/log.h" 32 #include "../daemon/request.h" 33 #include "../util/pblock.h" 34 #include "../util/util.h" 35 36 /* 37 * assign_name 38 * 39 * Assigns the name specified by the name parameter if the uri has the 40 * specified prefix. 41 * 42 * pblock parameter: 43 * name object name 44 * from optional uri prefix 45 */ 46 int assign_name(pblock *pb, Session *sn, Request *rq) { 47 /* TODO: expression instead of simple prefix */ 48 49 char *name = pblock_findkeyval(pb_key_name, pb); 50 char *from = pblock_findkeyval(pb_key_from, pb); 51 52 if(!name) { 53 log_ereport(LOG_MISCONFIG, "assign-name: missing name parameter"); 54 protocol_status(sn, rq, 500, NULL); 55 return REQ_ABORTED; 56 } 57 58 if(from) { 59 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); 60 char c; 61 int i = 0; 62 while((c = from[i]) != 0) { 63 if(c != uri[i]) { 64 return REQ_NOACTION; 65 } 66 i++; 67 } 68 } 69 70 // add object to rq->vars 71 pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars); 72 73 return REQ_NOACTION; 74 } 75 76 /* 77 * document_root 78 * 79 * Specifies the document root directory. 80 * 81 * pblock parameter: 82 * root path to document root 83 */ 84 int document_root(pblock *pb, Session *sn, Request *rq) { 85 char *root = pblock_findkeyval(pb_key_root, pb); 86 if(!root) { 87 log_ereport(LOG_MISCONFIG, "document-root: missing root parameter"); 88 protocol_status(sn, rq, 500, NULL); 89 return REQ_ABORTED; 90 } 91 92 sstr_t root_str = sstr(root); 93 sstr_t uri_str = sstr(pblock_findkeyval(pb_key_uri, rq->reqpb)); 94 95 request_set_path(root_str, uri_str, rq->vars); 96 97 return REQ_PROCEED; 98 } 99 100 /* 101 * pfx2dir 102 * 103 * ... 104 * 105 * pblock parameter: 106 * from prefix 107 * dir file system directory 108 * name (optional) object name 109 * 110 */ 111 int pfx2dir(pblock *pb, Session *sn, Request *rq) { 112 char *from = pblock_findkeyval(pb_key_from, pb); 113 char *dir = pblock_findkeyval(pb_key_dir, pb); 114 char *name = pblock_findkeyval(pb_key_name, pb); 115 116 if(!from || !dir) { 117 if(!from && dir) { 118 log_ereport(LOG_MISCONFIG, "pfx2dir: missing from parameter"); 119 } else if(!dir && from) { 120 log_ereport(LOG_MISCONFIG, "pfx2dir: missing dir parameter"); 121 } else { 122 log_ereport( 123 LOG_MISCONFIG, 124 "pfx2dir: missing from and dir parameter"); 125 } 126 protocol_status(sn, rq, 500, NULL); 127 return REQ_ABORTED; 128 } 129 130 // check prefix 131 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); 132 char fc; 133 char uc; 134 int i = 0; 135 while((fc = from[i]) != 0) { 136 uc = uri[i]; 137 if(fc != uc) { 138 return REQ_NOACTION; 139 } 140 i++; 141 } 142 143 // url has the specified prefix 144 145 uri = uri + i; 146 if(uri[0] == '/') { 147 uri++; 148 } 149 150 request_set_path(sstr(dir), sstr(uri), rq->vars); 151 152 if(name) { 153 // add object to rq->vars 154 pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars); 155 } 156 157 return REQ_PROCEED; 158 } 159 160 161 int redirect(pblock *pb, Session *sn, Request *rq) { 162 char *from = pblock_findval("from", pb); 163 char *url = pblock_findval("url", pb); 164 165 if(!from || !url) { 166 log_ereport(LOG_MISCONFIG, "redirect: missing parameter (from, url)"); 167 return REQ_ABORTED; 168 } 169 170 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); 171 if(!strcmp(uri, from)) { 172 pblock_nvinsert("location", url, rq->srvhdrs); 173 174 protocol_status(sn, rq, 302, NULL); 175 return REQ_ABORTED; 176 } 177 178 return REQ_NOACTION; 179 } 180 181 /* 182 * provisional rewrite saf 183 */ 184 int simple_rewrite(pblock *pb, Session *sn, Request *rq) { 185 char *from = pblock_findval("from", pb); 186 char *root = pblock_findval("root", pb); 187 char *path = pblock_findval("path", pb); 188 char *name = pblock_findval("name", pb); 189 190 if(!from || !path || !root) { 191 log_ereport(LOG_MISCONFIG, "simple-rewrite: missing parameter (from, root, path)"); 192 return REQ_ABORTED; 193 } 194 195 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); 196 sstr_t u = sstr(uri); 197 sstr_t f = sstr(from); 198 if(sstrprefix(u, f)) { 199 sstr_t suf = sstrsubs(u, f.length); 200 sstr_t ppath = sstrcat(2, sstr(path), suf); 201 202 request_set_path(sstr(root), ppath, rq->vars); 203 free(ppath.ptr); 204 205 if(name) { 206 // add object to rq->vars 207 pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars); 208 } 209 } 210 211 return REQ_NOACTION; 212 } 213