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

📄 alias.c

📁 boa 一个简小的web服务器 资源占用极少
💻 C
📖 第 1 页 / 共 2 页
字号:
        memcpy(buffer, document_root, l1);
        if (virtualhost) {
            buffer[l1] = '/';
            memcpy(buffer + l1 + 1, req->local_ip_addr, l3);
            memcpy(buffer + l1 + 1 + l3, req->request_uri, l2 + 1);
        } else
            memcpy(buffer + l1, req->request_uri, l2 + 1);
    } else {
        /* not aliased.  not userdir.  not part of document_root.  BAIL */
        send_r_not_found(req);
        return 0;
    }

    /* if here,
     * o it may be aliased but it's not a redirect or a script...
     * o it may be a homedir
     * o it may be a document_root resource (with or without virtual host)
     */

    req->pathname = strdup(buffer);
    if (!req->pathname) {
        WARN("Could not strdup buffer for req->pathname!");
        send_r_error(req);
        return 0;
    }

    /* below we support cgis outside of a ScriptAlias */
    if (strcmp(CGI_MIME_TYPE, get_mime_type(buffer)) == 0) { /* cgi */
#ifdef FASCIST_LOGGING
        log_error_time();
        fprintf(stderr, "%s:%d - buffer is: \"%s\"\n",
                __FILE__, __LINE__, buffer);
#endif
        /* FIXME */
        /* script_name could end up as /cgi-bin/bob/extra_path */
        req->script_name = strdup(req->request_uri);
        if (!req->script_name) {
            WARN("Could not strdup req->request_uri for req->script_name");
            send_r_error(req);
            return 0;
        }
        if (req->simple)
            req->is_cgi = NPH;
        else
            req->is_cgi = CGI;
        return 1;
    } else if (req->method == M_POST) { /* POST to non-script */
        /* it's not a cgi, but we try to POST??? */
        send_r_bad_request(req);
        return 0;
    } else                      /* we are done!! */
        return 1;
}

/*
 * Name: init_script_alias
 *
 * Description: Performs full parsing on a ScriptAlias request
 * Sets path_info and script_name
 *
 * Return values:
 *
 * 0: failure, shut down
 * 1: success, continue
 */

int init_script_alias(request * req, alias * current1, int uri_len)
{
    static char pathname[MAX_HEADER_LENGTH + 1];
    struct stat statbuf;
    static char buffer[MAX_HEADER_LENGTH + 1];

    int index = 0;
    char c;
    int err;

    /* copies the "real" path + the non-alias portion of the
       uri to pathname.
     */

    if (uri_len - current1->fake_len + current1->real_len >
        MAX_HEADER_LENGTH) {
        log_error_doc(req);
        fputs("uri too long!\n", stderr);
        send_r_bad_request(req);
        return 0;
    }

    memcpy(pathname, current1->realname, current1->real_len);
    memcpy(pathname + current1->real_len,
           &req->request_uri[current1->fake_len],
           uri_len - current1->fake_len + 1); /* the +1 copies the NUL */
#ifdef FASCIST_LOGGING
    log_error_time();
    fprintf(stderr,
            "%s:%d - pathname in init_script_alias is: \"%s\" (\"%s\")\n",
            __FILE__, __LINE__, pathname, pathname + current1->real_len);
#endif
    if (strncmp("nph-", pathname + current1->real_len, 4) == 0
        || req->simple) req->is_cgi = NPH;
    else
        req->is_cgi = CGI;


    /* start at the beginning of the actual uri...
     (in /cgi-bin/bob, start at the 'b' in bob */
    index = current1->real_len;

    /* go to first and successive '/' and keep checking
     * if it is a full pathname
     * on success (stat (not lstat) of file is a *regular file*)
     */
    do {
        c = pathname[++index];
        if (c == '/') {
            pathname[index] = '\0';
            err = stat(pathname, &statbuf);
            pathname[index] = '/';
            if (err == -1) {
                send_r_not_found(req);
                return 0;
            }

            /* is it a dir? */
            if (!S_ISDIR(statbuf.st_mode)) {
                /* check access */
                if (!(statbuf.st_mode &
                      (S_IFREG | /* regular file */
                       (S_IRUSR | S_IXUSR) |    /* u+rx */
                       (S_IRGRP | S_IXGRP) |    /* g+rx */
                       (S_IROTH | S_IXOTH)))) { /* o+rx */
                    send_r_forbidden(req);
                    return 0;
                }
                /* stop here */
                break;
            }
        }
    } while (c != '\0');

    req->script_name = strdup(req->request_uri);
    if (!req->script_name) {
        send_r_error(req);
        WARN("unable to strdup req->request_uri for req->script_name");
        return 0;
    }

    if (c == '\0') {
        err = stat(pathname, &statbuf);
        if (err == -1) {
            send_r_not_found(req);
            return 0;
        }

        /* is it a dir? */
        if (!S_ISDIR(statbuf.st_mode)) {
            /* check access */
            if (!(statbuf.st_mode &
                  (S_IFREG | /* regular file */
                   (S_IRUSR | S_IXUSR) |    /* u+rx */
                   (S_IRGRP | S_IXGRP) |    /* g+rx */
                   (S_IROTH | S_IXOTH)))) { /* o+rx */
                send_r_forbidden(req);
                return 0;
            }
            /* stop here */
        } else {
            send_r_forbidden(req);
            return 0;
        }
    }

    /* we have path_info if c == '/'... still have to check for query */
    else if (c == '/') {
        int hash;
        alias *current;
        int path_len;

        req->path_info = strdup(pathname + index);
        if (!req->path_info) {
            send_r_error(req);
            WARN("unable to strdup pathname + index for req->path_info");
            return 0;
        }
        pathname[index] = '\0'; /* strip path_info from path */
        path_len = strlen(req->path_info);
        /* we need to fix script_name here */
        /* index points into pathname, which is
         * realname/cginame/foo
         * and index points to the '/foo' part
         */
        req->script_name[strlen(req->script_name) - path_len] = '\0'; /* zap off the /foo part */

        /* now, we have to re-alias the extra path info....
           this sucks.
         */
        hash = get_alias_hash_value(req->path_info);
        current = alias_hashtable[hash];
        while (current && !req->path_translated) {
            if (!strncmp(req->path_info, current->fakename,
                         current->fake_len)) {

                if (current->real_len +
                    path_len - current->fake_len > MAX_HEADER_LENGTH) {
                    log_error_doc(req);
                    fputs("uri too long!\n", stderr);
                    send_r_bad_request(req);
                    return 0;
                }

                memcpy(buffer, current->realname, current->real_len);
                strcpy(buffer + current->real_len,
                       &req->path_info[current->fake_len]);
                req->path_translated = strdup(buffer);
                if (!req->path_translated) {
                    send_r_error(req);
                    WARN("unable to strdup buffer for req->path_translated");
                    return 0;
                }
            }
            current = current->next;
        }
        /* no alias... try userdir */
        if (!req->path_translated && user_dir && req->path_info[1] == '~') {
            char *user_homedir;
            char *p;

            p = strchr(pathname + index + 1, '/');
            if (p)
                *p = '\0';

            user_homedir = get_home_dir(pathname + index + 2);
            if (p)
                *p = '/';

            if (!user_homedir) { /* no such user */
                send_r_not_found(req);
                return 0;
            }
            {
                int l1 = strlen(user_homedir);
                int l2 = strlen(user_dir);
                int l3;
                if (p)
                    l3 = strlen(p);
                else
                    l3 = 0;

                req->path_translated = malloc(l1 + l2 + l3 + 2);
                if (req->path_translated == NULL) {
                    send_r_error(req);
                    WARN("unable to malloc memory for req->path_translated");
                    return 0;
                }
                memcpy(req->path_translated, user_homedir, l1);
                req->path_translated[l1] = '/';
                memcpy(req->path_translated + l1 + 1, user_dir, l2 + 1);
                if (p)
                    memcpy(req->path_translated + l1 + 1 + l2, p, l3 + 1);
            }
        }
        if (!req->path_translated && document_root) {
            /* no userdir, no aliasing... try document root */
            int l1, l2;
            l1 = strlen(document_root);
            l2 = path_len;

            req->path_translated = malloc(l1 + l2 + 1);
            if (req->path_translated == NULL) {
                send_r_error(req);
                WARN("unable to malloc memory for req->path_translated");
                return 0;
            }
            memcpy(req->path_translated, document_root, l1);
            memcpy(req->path_translated + l1, req->path_info, l2 + 1);
        }
    }

    req->pathname = strdup(pathname);
    if (!req->pathname) {
        send_r_error(req);
        WARN("unable to strdup pathname for req->pathname");
        return 0;
    }

    return 1;
}

/*
 * Empties the alias hashtable, deallocating any allocated memory.
 */

void dump_alias(void)
{
    int i;
    alias *temp;

    for (i = 0; i < ALIAS_HASHTABLE_SIZE; ++i) { /* these limits OK? */
        if (alias_hashtable[i]) {
            temp = alias_hashtable[i];
            while (temp) {
                alias *temp_next;

                if (temp->fakename)
                    free(temp->fakename);
                if (temp->realname)
                    free(temp->realname);
                temp_next = temp->next;
                free(temp);
                temp = temp_next;
            }
            alias_hashtable[i] = NULL;
        }
    }
}

⌨️ 快捷键说明

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