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

📄 proxy_ftp.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* FTP routines for Apache proxy */#include "mod_proxy.h"#include "http_main.h"#include "http_log.h"#include "http_core.h"#define AUTODETECT_PWD/* * Decodes a '%' escaped string, and returns the number of characters */static int decodeenc(char *x){    int i, j, ch;    if (x[0] == '\0')        return 0;               /* special case for no characters */    for (i = 0, j = 0; x[i] != '\0'; i++, j++) {/* decode it if not already done */        ch = x[i];        if (ch == '%' && ap_isxdigit(x[i + 1]) && ap_isxdigit(x[i + 2])) {            ch = ap_proxy_hex2c(&x[i + 1]);            i += 2;        }        x[j] = ch;    }    x[j] = '\0';    return j;}/* * checks an encoded ftp string for bad characters, namely, CR, LF or * non-ascii character */static int ftp_check_string(const char *x){    int i, ch;    for (i = 0; x[i] != '\0'; i++) {        ch = x[i];        if (ch == '%' && ap_isxdigit(x[i + 1]) && ap_isxdigit(x[i + 2])) {            ch = ap_proxy_hex2c(&x[i + 1]);            i += 2;        }        if (ch == CR || ch == LF || (OS_ASC(ch) & 0x80))            return 0;    }    return 1;}/* * Canonicalise ftp URLs. */int ap_proxy_ftp_canon(request_rec *r, char *url){    char *user, *password, *host, *path, *parms, *strp, sport[7];    pool *p = r->pool;    const char *err;    int port;    port = DEFAULT_FTP_PORT;    err = ap_proxy_canon_netloc(p, &url, &user, &password, &host, &port);    if (err)        return HTTP_BAD_REQUEST;    if (user != NULL && !ftp_check_string(user))        return HTTP_BAD_REQUEST;    if (password != NULL && !ftp_check_string(password))        return HTTP_BAD_REQUEST;/* now parse path/parameters args, according to rfc1738 *//* N.B. if this isn't a true proxy request, then the URL path * (but not query args) has already been decoded. * This gives rise to the problem of a ; being decoded into the * path. */    strp = strchr(url, ';');    if (strp != NULL) {        *(strp++) = '\0';        parms = ap_proxy_canonenc(p, strp, strlen(strp), enc_parm,                                  r->proxyreq);        if (parms == NULL)            return HTTP_BAD_REQUEST;    }    else        parms = "";    path = ap_proxy_canonenc(p, url, strlen(url), enc_path, r->proxyreq);    if (path == NULL)        return HTTP_BAD_REQUEST;    if (!ftp_check_string(path))        return HTTP_BAD_REQUEST;    if (r->proxyreq == NOT_PROXY && r->args != NULL) {        if (strp != NULL) {            strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_parm, STD_PROXY);            if (strp == NULL)                return HTTP_BAD_REQUEST;            parms = ap_pstrcat(p, parms, "?", strp, NULL);        }        else {            strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_fpath, STD_PROXY);            if (strp == NULL)                return HTTP_BAD_REQUEST;            path = ap_pstrcat(p, path, "?", strp, NULL);        }        r->args = NULL;    }/* now, rebuild URL */    if (port != DEFAULT_FTP_PORT)        ap_snprintf(sport, sizeof(sport), ":%d", port);    else        sport[0] = '\0';    r->filename = ap_pstrcat(p, "proxy:ftp://", (user != NULL) ? user : "",                             (password != NULL) ? ":" : "",                             (password != NULL) ? password : "",                          (user != NULL) ? "@" : "", host, sport, "/", path,                             (parms[0] != '\0') ? ";" : "", parms, NULL);    return OK;}/* * Returns the ftp status code; *  or -1 on I/O error, 0 on data error */static int ftp_getrc(BUFF *ctrl){    int len, status;    char linebuff[100], buff[5];    len = ap_bgets(linebuff, sizeof linebuff, ctrl);    if (len == -1)        return -1;/* check format */    if (len < 5 || !ap_isdigit(linebuff[0]) || !ap_isdigit(linebuff[1]) ||     !ap_isdigit(linebuff[2]) || (linebuff[3] != ' ' && linebuff[3] != '-'))        status = 0;    else        status = 100 * linebuff[0] + 10 * linebuff[1] + linebuff[2] - 111 * '0';    if (linebuff[len - 1] != '\n') {        (void)ap_bskiplf(ctrl);    }/* skip continuation lines */    if (linebuff[3] == '-') {        memcpy(buff, linebuff, 3);        buff[3] = ' ';        do {            len = ap_bgets(linebuff, sizeof linebuff, ctrl);            if (len == -1)                return -1;            if (linebuff[len - 1] != '\n') {                (void)ap_bskiplf(ctrl);            }        } while (memcmp(linebuff, buff, 4) != 0);    }    return status;}/* * Like ftp_getrc but returns both the ftp status code and * remembers the response message in the supplied buffer */static int ftp_getrc_msg(BUFF *ctrl, char *msgbuf, int msglen){    int len, status;    char linebuff[100], buff[5];    char *mb = msgbuf, *me = &msgbuf[msglen];    len = ap_bgets(linebuff, sizeof linebuff, ctrl);    if (len == -1)        return -1;    if (len < 5 || !ap_isdigit(linebuff[0]) || !ap_isdigit(linebuff[1]) ||     !ap_isdigit(linebuff[2]) || (linebuff[3] != ' ' && linebuff[3] != '-'))        status = 0;    else        status = 100 * linebuff[0] + 10 * linebuff[1] + linebuff[2] - 111 * '0';    mb = ap_cpystrn(mb, linebuff + 4, me - mb);    if (linebuff[len - 1] != '\n')        (void)ap_bskiplf(ctrl);    if (linebuff[3] == '-') {        memcpy(buff, linebuff, 3);        buff[3] = ' ';        do {            len = ap_bgets(linebuff, sizeof linebuff, ctrl);            if (len == -1)                return -1;            if (linebuff[len - 1] != '\n') {                (void)ap_bskiplf(ctrl);            }            mb = ap_cpystrn(mb, linebuff + 4, me - mb);        } while (memcmp(linebuff, buff, 4) != 0);    }    return status;}static long int send_dir(BUFF *data, request_rec *r, cache_req *c, char *cwd){    char *buf, *buf2;    size_t buf_size;    char *filename;    int searchidx = 0;    char *searchptr = NULL;    int firstfile = 1;    unsigned long total_bytes_sent = 0;    register int n;    conn_rec *con = r->connection;    pool *p = r->pool;    char *dir, *path, *reldir, *site, *type = NULL;    char *basedir = "";         /* By default, path is relative to the $HOME                                 * dir */    /* create default sized buffers for the stuff below */    buf_size = IOBUFSIZE;    buf = ap_palloc(r->pool, buf_size);    buf2 = ap_palloc(r->pool, buf_size);    /* Save "scheme://site" prefix without password */    site = ap_unparse_uri_components(p, &r->parsed_uri, UNP_OMITPASSWORD | UNP_OMITPATHINFO);    /* ... and path without query args */    path = ap_unparse_uri_components(p, &r->parsed_uri, UNP_OMITSITEPART | UNP_OMITQUERY);    /* If path began with /%2f, change the basedir */    if (strncasecmp(path, "/%2f", 4) == 0) {        basedir = "/%2f";    }    /* Strip off a type qualifier. It is ignored for dir listings */    if ((type = strstr(path, ";type=")) != NULL)        *type++ = '\0';    (void)decodeenc(path);    while (path[1] == '/')      /* collapse multiple leading slashes to one */        ++path;    /* Copy path, strip (all except the last) trailing slashes */    /* (the trailing slash is needed for the dir component loop below) */    path = dir = ap_pstrcat(r->pool, path, "/", NULL);    for (n = strlen(path); n > 1 && path[n - 1] == '/' && path[n - 2] == '/'; --n)        path[n - 1] = '\0';    /* print "ftp://host/" */    n = ap_snprintf(buf, buf_size, DOCTYPE_HTML_3_2                    "<html><head><title>%s%s%s</title>\n"                    "<base href=\"%s%s%s\"></head>\n"                    "<body><h2>Directory of "                    "<a href=\"/\">%s</a>/",                    site, basedir, ap_escape_html(p, path),                    site, basedir, ap_escape_uri(p, path),                    site);    total_bytes_sent += ap_proxy_bputs2(buf, con->client, c);    /* Add a link to the root directory (if %2f hack was used) */    if (basedir[0] != '\0') {        total_bytes_sent += ap_proxy_bputs2("<a href=\"/%2f/\">%2f</a>/", con->client, c);    }    for (dir = path + 1; (dir = strchr(dir, '/')) != NULL;) {        *dir = '\0';        if ((reldir = strrchr(path + 1, '/')) == NULL) {            reldir = path + 1;        }        else            ++reldir;        /* print "path/" component */        ap_snprintf(buf, buf_size, "<a href=\"%s%s/\">%s</a>/",                    basedir,                    ap_escape_uri(p, path),                    ap_escape_html(p, reldir));        total_bytes_sent += ap_proxy_bputs2(buf, con->client, c);        *dir = '/';        while (*dir == '/')            ++dir;    }    /* If the caller has determined the current directory, and it differs */    /* from what the client requested, then show the real name */    if (cwd == NULL || strncmp(cwd, path, strlen(cwd)) == 0) {        ap_snprintf(buf, buf_size, "</h2>\n<hr /><pre>");    }    else {        ap_snprintf(buf, buf_size, "</h2>\n(%s)\n<hr /><pre>",                    ap_escape_html(p, cwd));    }    total_bytes_sent += ap_proxy_bputs2(buf, con->client, c);    while (!con->aborted) {        n = ap_bgets(buf, buf_size, data);        if (n == -1) {          /* input error */            if (c != NULL) {                ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,                              "proxy: error reading from %s", c->url);                c = ap_proxy_cache_error(c);            }            break;        }        if (n == 0)            break;              /* EOF */        if (buf[n - 1] == '\n') /* strip trailing '\n' */            buf[--n] = '\0';        if (buf[n - 1] == '\r') /* strip trailing '\r' if present */            buf[--n] = '\0';        /* Handle unix-style symbolic link */        if (buf[0] == 'l' && (filename = strstr(buf, " -> ")) != NULL) {            char *link_ptr = filename;            do {                filename--;            } while (filename[0] != ' ' && filename > buf);            if (filename != buf)                *(filename++) = '\0';            *(link_ptr++) = '\0';            ap_snprintf(buf2, buf_size, "%s <a href=\"%s\">%s %s</a>\n",                        ap_escape_html(p, buf),                        ap_escape_uri(p, filename),                        ap_escape_html(p, filename),                        ap_escape_html(p, link_ptr));            ap_cpystrn(buf, buf2, buf_size);            n = strlen(buf);        }        /* Handle unix style or DOS style directory  */

⌨️ 快捷键说明

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