Problems with fastcgi php migration

Sigh…I hate it when a missed step gets in the way of real debugging.
So ignore most of my last email…in my cutting and pasting I forgot to
add the fastcgi_pass after the new parameter changes.

So with that error corrected and out of the way, I created a
/testgalleries file that was just phpinfo()

Here are the results:

URL: /testgalleries
the URL gave a 404 error

URL: /testgalleries/
SCRIPT_FILENAME: $document_root/testgalleries/ <- note slash.
PATH_INFO:/testgalleries with no trailing slash. Should be /

URL: /testgalleries/30/1/1
SCRIPT_FILENAME: $document_root/testgalleries/30/1/1 Should be
$document_root/testgalleries
PATH_INFO: /testgalleries Should be /30/1/1

Igor S. wrote:

/galleries $document_root/galleries -
/galleries/ $document_root/galleries /
/galleries/30/1/1 $document_root/galleries /30/1/1

So it appears there’s still an issue with script_filename and path_info.
Not sure if the cgi.fix-pathinfo=0 was the right fix. Your previous
suggestion had everything running smoothly and the only stumbling block
was getting it to run properly if a visitor adds a trailing slash.

Thanks again for all your help. I know we’re 99.9% on the way to being
100% nginx. :slight_smile:

Igor S. wrote:

This is my mistype, it should be:

set $script_name $1;
set $path_info $2;

Unfortunately that caused a 404 in each of the three test cases.
Bizarre.

You did want me to set cgi.fix-pathinfo in php.ini to 0 (off) right?

Here’s the whole location with the fastcgi_params in case we’re missing
something:

location ~ ^/(testgalleries|galleries|poll|news)(/|$) {
root /usr/local/apache/htdocs;
set $script_name $uri;
set $path_info “”;

if ($uri ~ ^(/[^/]+)(/.*)) {
set $script_name $1;
set $path_info $2;
}

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param SCRIPT_FILENAME $document_root$script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_pass 127.0.0.1:10004;
}

Odd how it goes from incorrect path_info to 404’s.

Thanks.

Igor,

Turning cgi.fix-pathinfo back on appears to fix almost everything.

So a 99% cheer!

It fixes everything where the extensionless file is immediately in the
site’s root, e.g.

example.com/galleries

It still gives the octet/stream if the file is in another directory.
e.g. the script file “photos” can be in locations like:

example.com/academy/80/photos
example.com/tiff/fest/2008/2/photos

So some of the files can be several directories deep.

So, I imagine there’s just one final change to the location regex and
we’ll be 100% nginx.

How do I change…

location ~ ^/(testgalleries|galleries|poll|news)(/|$)

…to not care where the file is found?

Many thanks again.

location ~ ^/(testgalleries|galleries|poll|news)(/|$)

BTW, obviously I added ‘photos’ to the location on the server before I
tested this, just not in the one I posted. Ah the joys of hitting ‘send’
before proofreading.

So obviously the question re: finding the filename even if it’s buried
in a few layers of subdirectories still stands.

Thanks.

On Wed, Mar 12, 2008 at 05:47:07PM -0400, Ian M. Evans wrote:

Here’s the whole location with the fastcgi_params in case we’re missing
something:

location ~ ^/(testgalleries|galleries|poll|news)(/|$) {
root /usr/local/apache/htdocs;
set $script_name $uri;
set $path_info “”;

if ($uri ~ ^(/[^/]+)(/.*)) {
set $script_name $1;
set $path_info $2;

fastcgi_pass 127.0.0.1:10004;

Igor S. wrote:

if ($uri ~ ^(/[^/]+)(/.*)) {
set $script_name $1;
set $path_info $2;

fastcgi_pass 127.0.0.1:10004;

}

Not sure if you saw my next email after this one you responded too. It’s
99% working right now…but that’s for later.

The fastcgi_pass you added is unncessary as it’s already there at the
bottom of the location. (see below)

To confirm that I just did the following.

I turned cgi.fix-pathinfo=0 and added the fastcgi_pass to the if block
as you placed above. Restarted nginx and fastcgi servers.

Received 404s.

Reset it to what I had late last night:
cgi.fix-pathinfo=1

The following location, with cgi.fix-pathinfo=1, is 99% working:

location ~ ^/(testgalleries|galleries|poll|news|photos)(/|$) {
root /usr/local/apache/htdocs;
set $script_name $uri;
set $path_info “”;
if ($uri ~ ^(/[^/]+)(/.*)) {
set $script_name $1;
set $path_info $2;
}
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param SCRIPT_FILENAME $document_root$script_name;
fastcgi_param PATH_INFO $path_info;
#fastcgi_param REDIRECT_STATUS 200;
fastcgi_pass 127.0.0.1:10004;
}

So 99% success. The final, final hurdle as I mentioned in my 9:14PM
Eastern email is that the location regex works only if the extensionless
file is in the root, i.e. example.com/galleries

location ~ ^/(testgalleries|galleries|poll|news|photos)(/|$) {

However, the file photos can appear anywhere like:
example.com/academy/80/photos
example.com/fest/tiff/2008/1/photos

So the regex just needs one final tweak to allow it to find an
extensionless file no matter if it’s in root or any number of
subdirectories deep. I read several regex tutorials last night but my
brain goes on vacation with regex.

So we’re 99.9999% there. Thanks again.

On Thu, Mar 13, 2008 at 08:00:43AM -0400, Ian M. Evans wrote:

99% working right now…but that’s for later.
In this config I do not see fastcgi_pass inside if block.
Add it.

Hello Ian,

Thursday, March 13, 2008, 6:00:43 PM, you wrote:

So 99% success. The final, final hurdle as I mentioned in my 9:14PM
Eastern email is that the location regex works only if the extensionless
file is in the root, i.e. example.com/galleries

  • location ~ ^/(testgalleries|galleries|poll|news|photos)(/|$) {
  • location ~ /(testgalleries|galleries|poll|news|photos)(/|$) {

However, the file photos can appear anywhere like:
example.com/academy/80/photos
example.com/fest/tiff/2008/1/photos

So the regex just needs one final tweak to allow it to find an
extensionless file no matter if it’s in root or any number of
subdirectories deep. I read several regex tutorials last night but my
brain goes on vacation with regex.

On Thu, Mar 13, 2008 at 08:00:43AM -0400, Ian M. Evans wrote:

So the regex just needs one final tweak to allow it to find an
extensionless file no matter if it’s in root or any number of
subdirectories deep. I read several regex tutorials last night but my
brain goes on vacation with regex.

Well, could you show all locaitons of current config in form:

 location / {
     local
 }

 location ~ \.php$ {
     fastcgi
 }

 location ~ ^/(testgalleries|galleries|poll|news|photos)(/|$) {
     fastcgi
 }

?

Igor S. wrote:

In this config I do not see fastcgi_pass inside if block.
Add it.

Igor, I just added it in again and it doesn’t change anything. If
cgi.fix-pathinfo=0 is off it fails. If cgi.fix-pathinfo=1 it works.

Anyway, fastcgi_pass IS THERE at the bottom of the location. It gets run
along with all the other fastcgi_params.

So we can cheer. It’s 99.999% working. I can go to /galleries,
/galleries/ and /galleries/30/1/1 and they all work 100%.

The ONLY thing that doesn’t work is finding the file if it’s not in the
site’s root.

So as I said in the last email, the regex just needs a little tweak to
find, say photos in,

example.com/photos
example.com/subdir/photos
example.com/subdir/subdir/photos etc. etc.

Igor S. wrote:

The “if” block is ugly construction inside nginx.
It requires fastcgi_pass inside “if” block too.
It’s not enough fastcgi_pass at the bottom of the location.

It’s now in both places and there’s no change. All the root level files
(example.com/filename) work. 99% there as we just need to be to find the
filename in any directory.

To reiterate, the only final tweak now is the location regex.

location ~ ^/(testgalleries|galleries|poll|news|photos)(/|$) {

Like I said, I suck at regex, but from what I do understand, the

^/ is looking at the start of the line so it will find
/photos but not /subdir/photos or /subdir/subdir/photos (etc.)

what needs to be changed between ^/ and (testgalleries…) to enable it
to work with any number of subdirectories?

Thanks.

Denis F. Latypoff wrote:

  • location ~ ^/(testgalleries|galleries|poll|news|photos)(/|$) {
  • location ~ /(testgalleries|galleries|poll|news|photos)(/|$) {

That tosses a 404. I’ll toss up the locations list Igor just asked for.

On Thu, Mar 13, 2008 at 08:26:35AM -0400, Ian M. Evans wrote:

Igor S. wrote:

In this config I do not see fastcgi_pass inside if block.
Add it.

Igor, I just added it in again and it doesn’t change anything. If
cgi.fix-pathinfo=0 is off it fails. If cgi.fix-pathinfo=1 it works.

Anyway, fastcgi_pass IS THERE at the bottom of the location. It gets run
along with all the other fastcgi_params.

The “if” block is ugly construction inside nginx.
It requires fastcgi_pass inside “if” block too.
It’s not enough fastcgi_pass at the bottom of the location.

Igor S. wrote:

Well, could you show all locaitons of current config in form:

Here you go. Edited out the fastcgi_params for a shorter list.

location / {
local…
}

location ~ .(shtml|php)$ {
fastcgi_pass…
}

location ~ ^/(testgalleries|galleries|poll|news|photos)(/|$) {
fastcgi_pass…
}

location ~* ^.+.(jpg|etc|etc)$ {
local…
}

location ~* ^.+.(gif|js)$ {
local…
}

On Thu, Mar 13, 2008 at 08:53:35AM -0400, Ian M. Evans wrote:

To reiterate, the only final tweak now is the location regex.

location ~ ^/(testgalleries|galleries|poll|news|photos)(/|$) {

Like I said, I suck at regex, but from what I do understand, the

^/ is looking at the start of the line so it will find
/photos but not /subdir/photos or /subdir/subdir/photos (etc.)

what needs to be changed between ^/ and (testgalleries…) to enable it
to work with any number of subdirectories?

If you need throw ways /subdir/subdir/, you can try the followning:

location ~ /(testgalleries|galleries|poll|news|photos)(/|$) {
root /usr/local/apache/htdocs;

  set  $script_name  $uri;
  set  $path_info    "";

  if ($uri ~ 

^/(?:.+/)?(testgalleries|galleries|poll|news|photos)(/.*)) {
set $script_name /$1;
set $path_info $2;
fastcgi_pass …
}

Igor S. wrote:

        set  $path_info    $2;
        fastcgi_pass       ...
  }

I added that to the list of locations.

Also, I forgot to note that it needs to be able to handle more path
after the file name (in the examples a photo slide number) so the full
URL could end up being:

example.com/subdir/photos/1
example.com/subdir/subdir/photos/1

In the location regex above it would work on example.com/subdir/photos/1

Also, like before, it 404s if the person adds a trailing slash.

So:
example.com/subdir/photos <–works
example.com/subdir/subdir/photos <–works
example.com/subdir/photos/ ← adding trailing slash tosses a 404
example.com/subdir/photos/1 ← adding additional path tosses a 404

Denis F. Latypoff wrote:

hey, why aren’t you want to compile nginx with --with-debug and see what
happens in the error.log with the ‘error_log /path debug’ mode?

we are not telepaths.

I was not aware of that option. If I had, I guess this would’ve been a
shorter process.

Thanks.

Denis F. Latypoff wrote:

hey, why aren’t you want to compile nginx with --with-debug and see what
happens in the error.log with the ‘error_log /path debug’ mode?

Denis,

As requested, here’s the debug output. In this example,
/fest/tribeca/2003/2/photos works
/fest/tribeca/2003/2/photos/ tosses a 404
and in the debug, /fest/tribeca/2003/2/photos/1 tosses a 404:

10085#0: *741 find location for “/fest/tribeca/2003/2/photos/1”
10085#0: *741 find location: “/”
10085#0: *741 find location: ~ “.(shtml|php)$”
10085#0: *741 find location: ~
“^/(testgalleries|galleries|poll|news|photos)(/|$)”
10085#0: *741 find location: ~
“/(testgalleries|galleries|poll|news|photos)(/|$)”
10085#0: *741 using configuration
“/(testgalleries|galleries|poll|news|photos)(/|$)”
10085#0: *741 http cl:-1 max:1048576
10085#0: *741 generic phase: 2
10085#0: *741 http script complex value
10085#0: *741 http script var: “/fest/tribeca/2003/2/photos/1”
10085#0: *741 http script set var
10085#0: *741 http script value: “”
10085#0: *741 http script set var
10085#0: *741 http script var
10085#0: *741 http script var: “/fest/tribeca/2003/2/photos/1”
10085#0: 741 http script regex:
"^/(?:.+/)?(testgalleries|galleries|poll|news|photos)(/.
)"
10085#0: *741 http script if
10085#0: *741 http script complex value
10085#0: *741 http script capture: “photos”
10085#0: *741 http script set var
10085#0: *741 http script complex value
10085#0: *741 http script capture: “/1”
10085#0: *741 http script set var
10085#0: *741 post rewrite phase: 3
10085#0: *741 generic phase: 4
10085#0: *741 access phase: 5
10085#0: *741 access phase: 6
10085#0: *741 post access phase: 7
10085#0: *741 http init upstream, client timer: 0
10085#0: *741 http script copy: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http script var: “”
10085#0: *741 http script copy: “”
10085#0: *741 http cleanup add: 0825F484
10085#0: *741 get rr peer, try: 1
10085#0: *741 socket 16
10085#0: *741 rtsig add connection: fd:16 signo:43
10085#0: *741 connect to 127.0.0.1:10004, fd:16 #742
10085#0: *741 http upstream connect: -2
10085#0: *741 event timer add: 16: 60000:2825487964
10085#0: rtsig add connection: fd:6 signo:43
10085#0: *741 post event 08297384
10085#0: *741 delete posted event 08297384
10085#0: *741 http upstream send request handler
10085#0: *741 http upstream send request
10085#0: *741 chain writer buf fl:0 s:1512
10085#0: *741 chain writer in: 0825F490
10085#0: *741 writev: 1512
10085#0: *741 chain writer out: 00000000
10085#0: *741 event timer del: 16: 2825487964
10085#0: *741 event timer add: 16: 60000:2825487964
10085#0: rtsig add connection: fd:6 signo:43
10085#0: *741 post event 0825030C
10085#0: *741 delete posted event 0825030C
10085#0: *741 http upstream process header
10085#0: *741 malloc: 08230A98:4096
10085#0: *741 malloc: 08231AA0:4096
10085#0: *741 recv: fd:16 128 of 4096
10085#0: *741 http fastcgi record byte: 01
10085#0: *741 http fastcgi record byte: 06
10085#0: *741 http fastcgi record byte: 00
10085#0: *741 http fastcgi record byte: 01
10085#0: *741 http fastcgi record byte: 00
10085#0: *741 http fastcgi record byte: 64
10085#0: *741 http fastcgi record byte: 04
10085#0: *741 http fastcgi record byte: 00
10085#0: *741 http fastcgi record length: 100
10085#0: *741 http fastcgi parser: 0
10085#0: *741 http fastcgi header: “Status: 404 Not Found”

Hello Ian,

Thursday, March 13, 2008, 6:56:46 PM, you wrote:

Denis F. Latypoff wrote:

  • location ~ ^/(testgalleries|galleries|poll|news|photos)(/|$) {
  • location ~ /(testgalleries|galleries|poll|news|photos)(/|$) {

That tosses a 404. I’ll toss up the locations list Igor just asked for.

hey, why aren’t you want to compile nginx with --with-debug and see what
happens in the error.log with the ‘error_log /path debug’ mode?

we are not telepaths.

Igor S. wrote:

Try to delete them and use

fastcgi_param SCRIPT_FILENAME $document_root$script_name;
fastcgi_param PATH_INFO $path_info;

only.

Deleting fastcgi_param PATH_TRANSLATED and fastcgi_param REQUEST_URI
resulted in:

/fest/tribeca/2003/2/photos <-- working
/fest/tribeca/2003/2/photos/ <-- No input file specified.
/fest/tribeca/2003/2/photos/1 <-- No input file specified.

Would you like to see the debug?