⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alias.c

📁 用于移植到嵌入式linux系统的boa http服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Boa, an http server *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com> *  Copyright (C) 1996 Russ Nelson <nelson@crynwr.com> *  Copyright (C) 1996-2005 Larry Doolittle <ldoolitt@boa.org> *  Copyright (C) 1996-2004 Jon Nelson <jnelson@boa.org> * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 1, or (at your option) *  any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *//* $Id: alias.c,v 1.70.2.20 2005/02/22 14:11:29 jnelson Exp $ */#include "boa.h"struct alias {    char *fakename;             /* URI path to file */    char *realname;             /* Actual path to file */    enum ALIAS type;            /* ALIAS, SCRIPTALIAS, REDIRECT */    unsigned int fake_len;      /* strlen of fakename */    unsigned int real_len;      /* strlen of realname */    struct alias *next;};typedef struct alias alias;static alias *alias_hashtable[ALIAS_HASHTABLE_SIZE];static alias *find_alias(char *uri, unsigned int urilen);static int init_script_alias(request * req, alias * current1, unsigned int uri_len);static unsigned int get_alias_hash_value(const char *file);/* * Name: get_alias_hash_value * * Description: adds the ASCII values of the file letters * and mods by the hashtable size to get the hash value * Note: stops at first '/' (or '\0') */static unsigned int get_alias_hash_value(const char *file){    unsigned int hash = 0;    unsigned int i = 0;    char c;    if (file == NULL) {        WARN("file sent to get_alias_hash_value is NULL");        return 0;    } else if (file[0] == '\0') {        WARN("file sent to get_alias_hash_value is empty");        return 0;    }    hash = (unsigned int) file[i++];    while ((c = file[i++]) && c != '/')        hash += (unsigned int) c;    return hash % ALIAS_HASHTABLE_SIZE;}/* * Name: add_alias * * Description: add an Alias, Redirect, or ScriptAlias to the * alias hash table. */void add_alias(const char *fakename, const char *realname, enum ALIAS type){    unsigned int hash;    alias *old, *new;    unsigned int fakelen, reallen;    /* sanity checking */    if (fakename == NULL || realname == NULL) {        DIE("NULL values sent to add_alias");    }    fakelen = strlen(fakename);    reallen = strlen(realname);    if (fakelen == 0 || reallen == 0) {        DIE("empty values sent to add_alias");    }    hash = get_alias_hash_value(fakename);    DEBUG(DEBUG_ALIAS) {        log_error_time();        fprintf(stderr, "%s:%d - Going to add alias: \"%s\" -=> \"%s\" (hash: %u)\n",                __FILE__, __LINE__, fakename, realname, hash);    }    old = alias_hashtable[hash];    if (old) {        while (old->next) {            if (!strcmp(fakename, old->fakename)) /* don't add twice */                return;            old = old->next;        }    }    new = (alias *) malloc(sizeof (alias));    if (!new) {        DIE("out of memory adding alias to hash");    }    if (old)        old->next = new;    else        alias_hashtable[hash] = new;    new->fakename = strdup(fakename);    if (!new->fakename) {        DIE("failed strdup");    }    new->fake_len = fakelen;    /* check for "here" */    new->realname = strdup(realname);    if (!new->realname) {        DIE("strdup of realname failed");    }    new->real_len = reallen;    new->type = type;    new->next = NULL;    DEBUG(DEBUG_ALIAS) {        log_error_time();        fprintf(stderr,                "%s:%d - ADDED alias: \"%s\" -=> \"%s\" hash: %u\n",                __FILE__, __LINE__, fakename, realname, hash);    }}/* * Name: find_alias * * Description: Locates uri in the alias hashtable if it exists. * * Returns: * * alias structure or NULL if not found */static alias *find_alias(char *uri, unsigned int urilen){    alias *current;    unsigned int hash;    /* Find ScriptAlias, Alias, or Redirect */    if (urilen == 0) {        WARN("uri len is 0!");        urilen = strlen(uri);    }    hash = get_alias_hash_value(uri);    DEBUG(DEBUG_ALIAS) {        log_error_time();        fprintf(stderr,                "%s:%d - looking for \"%s\" (hash=%u,len=%u)...\n",                __FILE__, __LINE__, uri, hash, urilen);    }    current = alias_hashtable[hash];    while (current) {        DEBUG(DEBUG_ALIAS) {            log_error_time();            fprintf(stderr,                    "%s:%d - comparing \"%s\" (request) to \"%s\" (alias): ",                    __FILE__, __LINE__, uri, current->fakename);        }        /* current->fake_len must always be:         *  shorter or equal to the uri         */        /*         * when performing matches:         * If the virtual part of the URL ends in '/', and         * we get a match, stop there.         * Otherwise, we require '/' or '\0' at the end of the URL.         * We only check if the virtual path does *not* end in '/'         */        if (current->fake_len <= urilen &&            !memcmp(uri, current->fakename, current->fake_len) &&            (current->fakename[current->fake_len - 1] == '/' ||             (current->fakename[current->fake_len - 1] != '/' &&              (uri[current->fake_len] == '\0' ||               uri[current->fake_len] == '/')))) {            DEBUG(DEBUG_ALIAS) {                fprintf(stderr, "Got it! (%s)\n", current->realname);            }            return current;        } else {            DEBUG(DEBUG_ALIAS) {                fprintf(stderr, "Don't Got it!\n");            }        }        current = current->next;    }    return current;}/* * Name: translate_uri * * Description: Parse a request's virtual path. * Sets query_string, pathname directly. * Also sets path_info, path_translated, and script_name via *  init_script_alias * * Note: NPH in user dir is currently broken * * Note -- this should be broken up. * * Return values: *   0: failure, close it down *   1: success, continue */int translate_uri(request * req){    static char buffer[MAX_HEADER_LENGTH + 1];    alias *current;    char *p;    unsigned int uri_len;    if (req->request_uri[0] != '/') {        send_r_bad_request(req);        return 0;    }    uri_len = strlen(req->request_uri);    current = find_alias(req->request_uri, uri_len);    if (current) {        if (current->type == SCRIPTALIAS) /* Script */            return init_script_alias(req, current, uri_len);        /* not a script alias, therefore begin filling in data */        if (current->real_len + uri_len - current->fake_len + 1 > sizeof(buffer)) {            log_error_doc(req);            fputs("uri too long!\n", stderr);            send_r_bad_request(req);            return 0;        }        memcpy(buffer, current->realname, current->real_len);        memcpy(buffer + current->real_len,               req->request_uri + current->fake_len,               uri_len - current->fake_len + 1);        if (current->type == REDIRECT) { /* Redirect */            if (req->method == M_POST) { /* POST to non-script */                /* it's not a cgi, but we try to POST??? */                log_error_doc(req);                fputs("POST to non-script is disallowed.\n", stderr);                send_r_bad_request(req);                return 0;       /* not a script alias, therefore begin filling in data */            }            send_r_moved_temp(req, buffer, "");            return 0;        } else {                /* Alias */            req->pathname = strdup(buffer);            if (!req->pathname) {                boa_perror(req, "unable to strdup buffer onto req->pathname");                return 0;            }            return 1;        }    }    /*       The reason why this is *not* an 'else if' is that,       after aliasing, we still have to check for '~' expansion     */    if (user_dir && req->request_uri[1] == '~') {        char *user_homedir;        char *req_urip;        if (req->request_uri[2] == '\0') {            log_error_doc(req);            fputs("Empty user-dir in URI\n", stderr);            send_r_bad_request(req);            return 0;        }        req_urip = req->request_uri + 2;        /* since we have uri_len which is from strlen(req->request_uri) */        p = memchr(req_urip, '/', uri_len - 2);        if (p)            *p = '\0';        user_homedir = get_home_dir(req_urip);        if (p)                  /* have to restore request_uri in case of error */            *p = '/';        if (!user_homedir) {    /*no such user */            send_r_not_found(req);            return 0;        } else {            unsigned int l1 = strlen(user_homedir);            unsigned int l2 = strlen(user_dir);            unsigned int l3 = (p ? strlen(p) : 0);            /* we need l1 + '/' + l2 + l3 + '\0' */            if (l1 + 1 + l2 + l3 + 1 > sizeof(buffer)) {                log_error_doc(req);                fputs("uri too long!\n", stderr);                send_r_bad_request(req);                return 0;            }            memcpy(buffer, user_homedir, l1);            buffer[l1] = '/';            /* copy the NUL in case 'p' is NULL */            memcpy(buffer + l1 + 1, user_dir, l2 + 1);            if (p)                memcpy(buffer + l1 + 1 + l2, p, l3 + 1);        }    } else if (vhost_root) {        /* no aliasing, no userdir... */        unsigned int l1, l2, l3, l4, l5;        char *ap = NULL;        /* form         * vhost_root + '/' + ip + '/' + host + '/' + htdocs + '/' + resource         */        l1 = strlen(vhost_root);        l2 = strlen(req->local_ip_addr);        ap = req->host;        l3 = strlen(ap);        l4 = strlen("htdocs");        l5 = strlen(req->request_uri);        if (l1 + 1 + l2 + 1 + l3 + 1 + l4 + l5 + 1 > sizeof(buffer)) {            log_error_doc(req);            fputs("uri too long!\n", stderr);            send_r_bad_request(req);            return 0;        }        memcpy(buffer, vhost_root, l1);        buffer[l1] = '/';        memcpy(buffer + l1 + 1, req->local_ip_addr, l2);        buffer[l1 + 1 + l2] = '/';        memcpy(buffer + l1 + 1 + l2 + 1, ap, l3);        buffer[l1 + 1 + l2 + 1 + l3] = '/';        memcpy(buffer + l1 + 1 + l2 + 1 + l3 + 1, "htdocs", l4);        /* request_uri starts with '/' */        memcpy(buffer + l1 + 1 + l2 + 1 + l3 + 1 + l4, req->request_uri,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -