Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache error: File name too long: Cannot map GET

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...>

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.

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?

Thanks

Andrew

like image 688
Andy Longwill Avatar asked Mar 17 '11 10:03

Andy Longwill


1 Answers

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

index.php?controller=doohickey&id=z61

can be rewritten as

index.php/controller/doohickey/z61

along with a regex in the framework code.

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

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

-> 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).

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....

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

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

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 -

to finish :

# kill -HUP `pidof strace`

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

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

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:        }

look for 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:    }

find 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

/* 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

#define PATH_MAX        4096    /* # chars in a path name including nul */
like image 138
jmullee Avatar answered Nov 14 '22 23:11

jmullee