Forum Moderators: phranque

Message Too Old, No Replies

mod rewrite pages don't carry session info, non mod rewrite pages do

In a shopping cart system I'm modifying, I am having this problem

         

sc0ttkclark

3:40 am on Dec 3, 2007 (gmt 0)

10+ Year Member



I'm modifying Zen Cart (PHP) to have SEO URLs for the Category pages. However, all mod_rewrite pages act as if there is no session. When I click a link to another page that is not a mod_rewrite page, my session is as if it was uninterrupted.

Below is the htaccess file I'm using:


php_value session.use_only_cookies 1
php_value session.use_trans_sid 0

RewriteEngine on
Options FollowSymLinks Includes

RewriteCond %{QUERY_STRING} ^main_page=index&cPath=(.*)$
RewriteCond %{QUERY_STRING}!^action=(.*)$
RewriteRule ^index.php(.*)$ seourl.php?convert=cat&id=%1 [L,QSA]

RewriteCond %{REQUEST_FILENAME}!-f
RewriteCond %{REQUEST_FILENAME}!-d
RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/$ seourl.php?category=$6 [L,QSA]
RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)/$ seourl.php?category=$5 [L,QSA]
RewriteRule ^(.*)/(.*)/(.*)/(.*)/$ seourl.php?category=$4 [L,QSA]
RewriteRule ^(.*)/(.*)/(.*)/$ seourl.php?category=$3 [L,QSA]
RewriteRule ^(.*)/(.*)/$ seourl.php?category=$2 [L,QSA]
RewriteRule ^(.*)/$ seourl.php?category=$1 [L,QSA]

And I've tried a few variations, but no luck. I saw the post in 2005 located here:

[webmasterworld.com ]

But that was left fairly open-ended and I wasn't able to find anything online that would help me in over an hour.

jdMorgan

2:44 pm on Dec 3, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



All of your rules include [QSA], so if the session ID is carried as part of the query string, it's likely the session is being dropped in your script itself. If it is carried as a cookie, then carefully examine the "domain" and "path" for which that cookie is defined; Changing your URLs to make them SEO-friendly may have moved them outside the cookie's declared domain and path. More on Cookies [wp.netscape.com]

Be aware that RewriteConds apply only to the first single rule that follows them. Your code will need some restructuring if your "-f -d" checks are to be applied to all of your last set of rules.

Your URL-path patterns are highly-inefficient, and may slow your server noticeably. As an example, your most complex pattern will execute much more efficiently if rewritten as:


RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ seourl.php?category=$6 [L,QSA]

Using the negative-match pattern as shown allows the requested URL-path to be evaluated in a single left-to-right pass, and avoids requiring potentially thousands of 'trial' matches by the regex parser. More on that subject is included in this thread [webmasterworld.com].

Jim

sc0ttkclark

3:54 pm on Dec 3, 2007 (gmt 0)

10+ Year Member



The path for the cookie is '/' and the domain is '.mysub.mydomain.com'

From looking at the PHP setcookie function, having the path '/' is best because it encompasses the entire domain. So I'm not sure if that's the problem in this case. Correct me if I'm wrong of course.

sc0ttkclark

4:01 pm on Dec 3, 2007 (gmt 0)

10+ Year Member



I've also updated my htaccess to use the following:

RewriteCond %{REQUEST_FILENAME}!-f
RewriteCond %{REQUEST_FILENAME}!-d
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ seourl.php?category=$6 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ seourl.php?category=$5 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ seourl.php?category=$4 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ seourl.php?category=$3 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/$ seourl.php?category=$2 [L,QSA]
RewriteRule ^([^/]+)/$ seourl.php?category=$1 [L,QSA]

jdMorgan

4:04 pm on Dec 3, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Be aware that RewriteConds apply only to the first single rule that follows them. Your code will need some restructuring if your "-f -d" checks are to be applied to all of your last set of rules.

Jim

sc0ttkclark

4:08 pm on Dec 3, 2007 (gmt 0)

10+ Year Member



Oh, how do I get it to apply to a group of them?

UPDATE: I'm now looking at your previous post at [webmasterworld.com ]

sc0ttkclark

4:12 pm on Dec 3, 2007 (gmt 0)

10+ Year Member



After looking over your example code for skipping, I tried this out:

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [S=6]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ seourl.php?category=$6 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ seourl.php?category=$5 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ seourl.php?category=$4 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ seourl.php?category=$3 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/$ seourl.php?category=$2 [L,QSA]
RewriteRule ^([^/]+)/$ seourl.php?category=$1 [L,QSA]

jdMorgan

4:23 pm on Dec 3, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That looks correct. If this hasn't helped, then I'm afraid I only have a couple of additional suggestions.

First, examine the script to determine how it "GETs" the requested URL-path info to figure out what page content to serve. It may use a GET() function, or it may directly examine server variables. If the latter, make sure that each variable that it examines is one that is updated by mod_rewrite; Otherwise it may be looking at the SEO-friendly URL and getting lost.

The other thing you might try is to install the "Live HTTP Headers" add-on for Firefox and Mozilla browsers, clear your cache(s), and surf into your site to see if/when the query string and/or cookie is getting dropped or modified. Beyond that, adding a few "echo" statements to output query/cookie status at the bottom of each page might also give you some troubleshooting direction.

Jim

sc0ttkclark

4:48 pm on Dec 3, 2007 (gmt 0)

10+ Year Member



I do notice that on pages that are rewritten, this is returned:

HTTP/1.x 200 OK
Content-Type: text/html
Server: Microsoft-IIS/6.0
X-Powered-By: PHP/5.1.4, ASP.NET
Date: Mon, 03 Dec 2007 16:42:12 GMT
Connection: close

where as pages that aren't rewritten, this is returned

HTTP/1.x 200 OK
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Type: text/html; charset=iso-8859-1
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: PHP/5.1.4, ASP.NET
Set-Cookie: cookie_test=please_accept_for_session; expires=Wed, 02-Jan-2008 16:43:56 GMT; path=/; domain=mysub.mydomain.com
Date: Mon, 03 Dec 2007 16:43:57 GMT
Connection: close

I'm not sure why it's not doing the right thing on the rewritten URLs. Thanks for your help, you have helped me a great deal already.

jdMorgan

5:30 pm on Dec 3, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



So indeed, neither the cookie nor the cache-control headers are being set for SEO-friendly requests, and that is the problem. Because mod_rewrite has no direct effect on either of these functions, look to your script to find out why the cookies and headers are not being set for SEO-friendly URL requests -- Check variable dependencies as already mentioned above.

Jim

gergoe

1:08 am on Dec 4, 2007 (gmt 0)

10+ Year Member



Cache-Control and Set-Cookie headers are set by the
session_start()
function call in PHP. There are few cases when the cache headers and the cookies are not set:
  • The call to this function is (simply) not made;
  • The call to this function is made, but there were something sent to the browser already, in that case the headers can not be modified anymore. This is quite serious if the
    output_buffering
    is not enabled, because then a single character can cause this behavior;
  • The output buffers are cleared after the call to the mentioned function, but before sending them to the browser. Not really sure about this one though;
Did you tried to call the script straight, in the same manner as mod_rewrite would call it? If so, what's the result if you go to the /seourl.php?category=whatever address?

sc0ttkclark

1:52 pm on Dec 4, 2007 (gmt 0)

10+ Year Member



I've got the URLs using a formated version of the product titles. From there, it goes through the htaccess and goes to a php file that grabs the correct cPath for the page and then this code pulls the correct page.

include_once "http://mysub.mysite.com/index.php?main_page=index&cPath=4_6";

UPDATE: Instead of including the PHP page with a remote URL, I included the index.php locally and set the $_GET variables correctly. That did not work. My only solution to get it to work was to copy everything from index.php and put it at the bottom of my seourl.php page. From there, I set the $_GET variables at the top based upon the HTACCESS response and my function to convert from the URL name into the cPath. This works! I just wish I knew a way to get around having all of the php from index.php in there!

jdMorgan

2:05 pm on Dec 4, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Glad you found a temporary work-around, anyway!

I just noticed something about your code that I hadn't noted before. If all you want to do is extract the last path-part to use as "category," then all of your rules above can be replaced by this one:


RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(([^/]+)/)*([^/]+)/$ seourl.php?category=$3 [L,QSA]

This takes any number (including zero) of "<something>/" followed by "<final_thing>/" and puts <final_thing> into $3.

Running this one rule will be faster than running the seven rules above.

Jim

sc0ttkclark

2:09 pm on Dec 4, 2007 (gmt 0)

10+ Year Member



Great! I've always wondered how it would be possible to cover multiple recursive URLs! Perfect!

gergoe

4:00 pm on Dec 4, 2007 (gmt 0)

10+ Year Member



I've got the URLs using a formated version of the product titles. From there, it goes through the htaccess and goes to a php file that grabs the correct cPath for the page and then this code pulls the correct page.

include_once "http://mysub.mysite.com/index.php?main_page=index&cPath=4_6";

That's why your sessions are broken, when you do an

include_once
with a fully qualified URI, the PHP will open a HTTP connection to that address, and fetch that resource and returns it to the browser. This is done in a separate process, it has no direct relation to the first request, no cookies, no additional headers will make it through (in nether directions). So if you browse to the seo page, your browser will send the appropriate cookies, but when the URI is fetched by
include_once
, these cookies are not forwarded, and when the response to the
include_once
contains headers or cookies, those are also ignored, they are not sent back to the browser. So the reason you loose session state is that you use fully qualified URI with the
include_once
.

If I remember well you can pass parameters in the same way to locally included files as you would do with remote resources, so the

include_once "index.php?main_page=index&cPath=4_6";

is also valid, and this will make the $_GET array properly set in the index.php. See [php.net...]

Anyway, it is clear that it is a PHP issue from now on :-)