Apache错误:文件名太长:无法映射GET [英] Apache error: File name too long: Cannot map GET

查看:125
本文介绍了Apache错误:文件名太长:无法映射GET的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们最近开始在apache日志中看到一个新错误:

We've recently started seeing a new error in our apache logs:

[Wed Mar 16 08:32:59 2011] [error] [client 10.40.1.2] (36)File name too long: Cannot map GET /static/app/js <..lots of javascript...>

似乎页面中的JavaScript是在请求中发送到服务器的.但是,目前尚不清楚这将如何发生.通过搜索互联网,看起来某些东西已经发生在某些wordpress插件上,但是那里没有太多其他信息.

It looks as though JavaScript from a page is being sent in a request to the server. However it's unclear how this would occur. From searching t'internet, looks like this kind of thing has occurred with certain wordpress plugins, but there isn't much other information out there.

有关环境的说明:客户端使用在英国Citrix瘦客户端上运行的IE8.Web服务器距离1700公里,因此存在一些延迟.该网站大量使用了AJAX和大型Cookie.

Note about the environment: Clients use IE8 running on a Citrix thin client in the UK. The web servers are 1700km away, so there's a bit of latency. The site makes heavy use of AJAX and large cookies.

有人可以建议如何调试此问题吗?

Could anyone advise on how to debug this issue please?

谢谢

安德鲁

推荐答案

我也通过一个PHP框架实现了这一点,该框架允许对URL进行格式化,从而使

I'm getting this too, with a PHP framework that allows URLs formatted so that

index.php?controller=doohickey&id=z61

可以改写为

index.php/controller/doohickey/z61

以及框架代码中的正则表达式.

along with a regex in the framework code.

错误看起来像(/var/log/apache/error_log):

The errors looks like (/var/log/apache/error_log):

GET /index.php/accounts_badoink/confirmaction/WUW%253DWBW%25253DV0tXPWM3Nzc1....

->在这种情况下,apache将文件名解析为

-> in this case, apache is parsing the filename as

/index.php/accounts_badoink/confirmaction/WUW%253DWBW%25253DV0tXPWM3Nzc1....

(我正在序列化对象状态并将其传递).

(I'm serializing an object state and passing it around).

我必须将此代码(至少是带有长附加序列化对象的URL)重写为更常用的样式:

I have to rewrite this (at least the URLs with long appended serialized objects) to the more-customary style:

  GET /index.php?controller=accounts_badoink&confirmaction=WUW%253DWBW%25253DV0tXPWM3Nzc1....

->在这种情况下,Apache将文件名解析为 index.php

-> in this case, Apache is parsing the file name as index.php

因此,简而言之,请尽可能早地重写URL并包含?,以将数据作为CGI样式的参数而不是路径元素进行传递.

So in short, rewrite your URLs and include a ? as early as possible, to pass data as CGI-style parameters instead of path elements.

我为每个Apache进程ID(由 pidof apache2 报告")运行 strace -p $ PID& :

I Ran strace -p $PID & for each Apache process id (as reported by pidof apache2) :

# pidof apache2 | tr ' ' '\n' | grep -v 21561 | sed "s|\(.*\)|strace -p \1 \&|g" | sh -

完成:

# kill -HUP `pidof strace`

然后查看apache2进行的内核调用:

And see the kernel calls make by apache2:

accept(3, {sa_family=AF_INET, sin_port=htons(38985), sin_addr=inet_addr("127.0.0.1")}, [16]) = 13
fcntl(13, F_GETFD)                      = 0
fcntl(13, F_SETFD, FD_CLOEXEC)          = 0
fcntl(13, F_GETFL)                      = 0x2 (flags O_RDWR)
fcntl(13, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
read(13, "GET /newregcon/index.php/account"..., 8000) = 4949
write(2, "[Wed May 11 15:39:36 2011] [erro"..., 4451) = 4451
writev(13, [{"HTTP/1.1 403 Forbidden\r\nDate: We"..., 219}, {"<!DOCTYPE HTML PUBLIC \"-//IETF//"..., 4610}], 2) = 4829

由于这些系统调用不会返回错误(例如'... = -1'),因此我下载了apache2源代码,并发现:

As these system calls don't return errors (e.g. ' ... = -1' ), I downloaded the apache2 sources, and found:

无法映射"的Grep:

Grep for "Cannot map" :

server/core.c

3489:AP_DECLARE_NONSTD(int) ap_core_translate(request_rec *r)
3490:{

3520:        if ((rv = apr_filepath_merge(&r->filename, conf->ap_document_root, path,
3521:                                     APR_FILEPATH_TRUENAME
3522:                                   | APR_FILEPATH_SECUREROOT, r->pool))
3523:                    != APR_SUCCESS) {
3524:            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
3525:                         "Cannot map %s to file", r->the_request);
3526:            return HTTP_FORBIDDEN;
3527:        }

寻找 apr_filepath_merge ...

srclib/apr/file_io/unix/filepath.c

81:APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
82:                                             const char *rootpath,
83:                                             const char *addpath,
84:                                             apr_int32_t flags,
85:                                             apr_pool_t *p)
86:{
87:    char *path;
88:    apr_size_t rootlen; /* is the length of the src rootpath */
89:    apr_size_t maxlen;  /* maximum total path length */

149:    rootlen = strlen(rootpath);
150:    maxlen = rootlen + strlen(addpath) + 4; /* 4 for slashes at start, after
151:                                             * root, and at end, plus trailing
152:                                             * null */
153:    if (maxlen > APR_PATH_MAX) {
154:        return APR_ENAMETOOLONG;
155:    }

找到 APR_PATH_MAX ...

Netware

./srclib/apr/include/apr.hnw:424:#define APR_PATH_MAX PATH_MAX

WIN32

./srclib/apr/include/apr.hw:584:#define APR_PATH_MAX 8192

./srclib/apr/include/apr.h.in

./srclib/apr/include/apr.h.in

/* header files for PATH_MAX, _POSIX_PATH_MAX */
#if APR_HAVE_LIMITS_H
#include <limits.h>

/usr/src/linux-headers-2.6.35-28/include/linux/limits.h

/usr/src/linux-headers-2.6.35-28/include/linux/limits.h

#define PATH_MAX        4096    /* # chars in a path name including nul */

这篇关于Apache错误:文件名太长:无法映射GET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆