📄 mod_rewrite.c
字号:
return 0; } conf->rewritelogfp = ap_piped_log_write_fd(pl); } else { apr_status_t rc; fname = ap_server_root_relative(p, conf->rewritelogfile); if (!fname) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, "mod_rewrite: Invalid RewriteLog " "path %s", conf->rewritelogfile); return 0; } if ((rc = apr_file_open(&conf->rewritelogfp, fname, REWRITELOG_FLAGS, REWRITELOG_MODE, p)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, "mod_rewrite: could not open RewriteLog " "file %s", fname); return 0; } } return 1;}static void do_rewritelog(request_rec *r, int level, char *perdir, const char *fmt, ...){ rewrite_server_conf *conf; char *logline, *text; const char *rhost, *rname; apr_size_t nbytes; int redir; apr_status_t rv; request_rec *req; va_list ap; conf = ap_get_module_config(r->server->module_config, &rewrite_module); if (!conf->rewritelogfp || level > conf->rewriteloglevel) { return; } rhost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NOLOOKUP, NULL); rname = ap_get_remote_logname(r); for (redir=0, req=r; req->prev; req = req->prev) { ++redir; } va_start(ap, fmt); text = apr_pvsprintf(r->pool, fmt, ap); va_end(ap); logline = apr_psprintf(r->pool, "%s %s %s %s [%s/sid#%pp][rid#%pp/%s%s%s] " "(%d) %s%s%s%s" APR_EOL_STR, rhost ? rhost : "UNKNOWN-HOST", rname ? rname : "-", r->user ? (*r->user ? r->user : "\"\"") : "-", current_logtime(r), ap_get_server_name(r), (void *)(r->server), (void *)r, r->main ? "subreq" : "initial", redir ? "/redir#" : "", redir ? apr_itoa(r->pool, redir) : "", level, perdir ? "[perdir " : "", perdir ? perdir : "", perdir ? "] ": "", text); rv = apr_global_mutex_lock(rewrite_log_lock); if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "apr_global_mutex_lock(rewrite_log_lock) failed"); /* XXX: Maybe this should be fatal? */ } nbytes = strlen(logline); apr_file_write(conf->rewritelogfp, logline, &nbytes); rv = apr_global_mutex_unlock(rewrite_log_lock); if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "apr_global_mutex_unlock(rewrite_log_lock) failed"); /* XXX: Maybe this should be fatal? */ } return;}#endif /* !REWRITELOG_DISABLED *//* * +-------------------------------------------------------+ * | | * | URI and path functions * | | * +-------------------------------------------------------+ *//* return number of chars of the scheme (incl. '://') * if the URI is absolute (includes a scheme etc.) * otherwise 0. * * NOTE: If you add new schemes here, please have a * look at escape_absolute_uri and splitout_queryargs. * Not every scheme takes query strings and some schemes * may be handled in a special way. * * XXX: we may consider a scheme registry, perhaps with * appropriate escape callbacks to allow other modules * to extend mod_rewrite at runtime. */static unsigned is_absolute_uri(char *uri){ /* fast exit */ if (*uri == '/' || strlen(uri) <= 5) { return 0; } switch (*uri++) { case 'a': case 'A': if (!strncasecmp(uri, "jp://", 5)) { /* ajp:// */ return 6; } case 'b': case 'B': if (!strncasecmp(uri, "alancer://", 10)) { /* balancer:// */ return 11; } break; case 'f': case 'F': if (!strncasecmp(uri, "tp://", 5)) { /* ftp:// */ return 6; } break; case 'g': case 'G': if (!strncasecmp(uri, "opher://", 8)) { /* gopher:// */ return 9; } break; case 'h': case 'H': if (!strncasecmp(uri, "ttp://", 6)) { /* http:// */ return 7; } else if (!strncasecmp(uri, "ttps://", 7)) { /* https:// */ return 8; } break; case 'l': case 'L': if (!strncasecmp(uri, "dap://", 6)) { /* ldap:// */ return 7; } break; case 'm': case 'M': if (!strncasecmp(uri, "ailto:", 6)) { /* mailto: */ return 7; } break; case 'n': case 'N': if (!strncasecmp(uri, "ews:", 4)) { /* news: */ return 5; } else if (!strncasecmp(uri, "ntp://", 6)) { /* nntp:// */ return 7; } break; } return 0;}/* * escape absolute uri, which may or may not be path oriented. * So let's handle them differently. */static char *escape_absolute_uri(apr_pool_t *p, char *uri, unsigned scheme){ char *cp; /* be safe. * NULL should indicate elsewhere, that something's wrong */ if (!scheme || strlen(uri) < scheme) { return NULL; } cp = uri + scheme; /* scheme with authority part? */ if (cp[-1] == '/') { /* skip host part */ while (*cp && *cp != '/') { ++cp; } /* nothing after the hostpart. ready! */ if (!*cp || !*++cp) { return apr_pstrdup(p, uri); } /* remember the hostname stuff */ scheme = cp - uri; /* special thing for ldap. * The parts are separated by question marks. From RFC 2255: * ldapurl = scheme "://" [hostport] ["/" * [dn ["?" [attributes] ["?" [scope] * ["?" [filter] ["?" extensions]]]]]] */ if (!strncasecmp(uri, "ldap", 4)) { char *token[5]; int c = 0; token[0] = cp = apr_pstrdup(p, cp); while (*cp && c < 4) { if (*cp == '?') { token[++c] = cp + 1; *cp = '\0'; } ++cp; } return apr_pstrcat(p, apr_pstrndup(p, uri, scheme), ap_escape_uri(p, token[0]), (c >= 1) ? "?" : NULL, (c >= 1) ? ap_escape_uri(p, token[1]) : NULL, (c >= 2) ? "?" : NULL, (c >= 2) ? ap_escape_uri(p, token[2]) : NULL, (c >= 3) ? "?" : NULL, (c >= 3) ? ap_escape_uri(p, token[3]) : NULL, (c >= 4) ? "?" : NULL, (c >= 4) ? ap_escape_uri(p, token[4]) : NULL, NULL); } } /* Nothing special here. Apply normal escaping. */ return apr_pstrcat(p, apr_pstrndup(p, uri, scheme), ap_escape_uri(p, cp), NULL);}/* * split out a QUERY_STRING part from * the current URI string */static void splitout_queryargs(request_rec *r, int qsappend){ char *q; /* don't touch, unless it's an http or mailto URL. * See RFC 1738 and RFC 2368. */ if (is_absolute_uri(r->filename) && strncasecmp(r->filename, "ajp", 3) && strncasecmp(r->filename, "balancer", 8) && strncasecmp(r->filename, "http", 4) && strncasecmp(r->filename, "mailto", 6)) { r->args = NULL; /* forget the query that's still flying around */ return; } q = ap_strchr(r->filename, '?'); if (q != NULL) { char *olduri; apr_size_t len; olduri = apr_pstrdup(r->pool, r->filename); *q++ = '\0'; if (qsappend) { r->args = apr_pstrcat(r->pool, q, "&", r->args, NULL); } else { r->args = apr_pstrdup(r->pool, q); } len = strlen(r->args); if (!len) { r->args = NULL; } else if (r->args[len-1] == '&') { r->args[len-1] = '\0'; } rewritelog((r, 3, NULL, "split uri=%s -> uri=%s, args=%s", olduri, r->filename, r->args ? r->args : "<none>")); } return;}/* * strip 'http[s]://ourhost/' from URI */static void reduce_uri(request_rec *r){ char *cp; apr_size_t l; cp = (char *)ap_http_scheme(r); l = strlen(cp); if ( strlen(r->filename) > l+3 && strncasecmp(r->filename, cp, l) == 0 && r->filename[l] == ':' && r->filename[l+1] == '/' && r->filename[l+2] == '/' ) { unsigned short port; char *portp, *host, *url, *scratch; scratch = apr_pstrdup(r->pool, r->filename); /* our scratchpad */ /* cut the hostname and port out of the URI */ cp = host = scratch + l + 3; /* 3 == strlen("://") */ while (*cp && *cp != '/' && *cp != ':') { ++cp; } if (*cp == ':') { /* additional port given */ *cp++ = '\0'; portp = cp; while (*cp && *cp != '/') { ++cp; } *cp = '\0'; port = atoi(portp); url = r->filename + (cp - scratch); if (!*url) { url = "/"; } } else if (*cp == '/') { /* default port */ *cp = '\0'; port = ap_default_port(r); url = r->filename + (cp - scratch); } else { port = ap_default_port(r); url = "/"; } /* now check whether we could reduce it to a local path... */ if (ap_matches_request_vhost(r, host, port)) { rewritelog((r, 3, NULL, "reduce %s -> %s", r->filename, url)); r->filename = apr_pstrdup(r->pool, url); } } return;}/* * add 'http[s]://ourhost[:ourport]/' to URI * if URI is still not fully qualified */static void fully_qualify_uri(request_rec *r){ if (!is_absolute_uri(r->filename)) { const char *thisserver; char *thisport; int port; thisserver = ap_get_server_name(r); port = ap_get_server_port(r); thisport = ap_is_default_port(port, r) ? "" : apr_psprintf(r->pool, ":%u", port); r->filename = apr_psprintf(r->pool, "%s://%s%s%s%s", ap_http_scheme(r), thisserver, thisport, (*r->filename == '/') ? "" : "/", r->filename); } return;}/* * stat() only the first segment of a path */static int prefix_stat(const char *path, apr_pool_t *pool){ const char *curpath = path; const char *root; const char *slash; char *statpath; apr_status_t rv; rv = apr_filepath_root(&root, &curpath, APR_FILEPATH_TRUENAME, pool); if (rv != APR_SUCCESS) { return 0; } /* let's recognize slashes only, the mod_rewrite semantics are opaque * enough. */ if ((slash = ap_strchr_c(curpath, '/')) != NULL) { rv = apr_filepath_merge(&statpath, root, apr_pstrndup(pool, curpath, (apr_size_t)(slash - curpath)), APR_FILEPATH_NOTABOVEROOT | APR_FILEPATH_NOTRELATIVE, pool); } else { rv = apr_filepath_merge(&statpath, root, curpath, APR_FILEPATH_NOTABOVEROOT | APR_FILEPATH_NOTRELATIVE, pool); } if (rv == APR_SUCCESS) { apr_finfo_t sb; if (apr_stat(&sb, statpath, APR_FINFO_MIN, pool) == APR_SUCCESS) { return 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -