1

I am migrating an Drupal 6 site to Drupal 7. I encountered some behavior, I cannot explain and would like to ask the community.

As I was testing if all urls work, I noticed, that there are urls like example.com/node&a=b (without ?), which return 200 on Drupal 6 site and 404 on Drupal 7 one. (Normal urls like example.com/node?a=b are served with 200)

As I understand, these urls are not correct (maybe lost the question mark on copy/paste), but I think it is still better to serve the page, because the main part of the url is correct. Even better would be to redirect to the correct page with 301.

But I cannot find, if the problem is in the Nginx configuration or if it is a desired behavior on Drupal 7. I am using the Nginx configuration example from http://wiki.nginx.org/Drupal.

Maybe someone could tell, if this behavior (404 on links without question mark is default for Nginx or Drupal 6/7)?

Edit: the malformed links come from access.log, there are some clients, which try to fetch them. Mostly search engines and bots.

  • Maybe it is an NGINX thing, but I have no idea how you had URLs working without the query parameter (the ?). Both Apache and IIS only work with parameters in the URL if they are preceded by a ? – Brady Sep 1 '15 at 10:48
  • is it on the same server? Is there any URL rewrite on the migrated site? – Gulok Sep 1 '15 at 12:51
  • No, the Drupal 6 is on "not so maintained" production server. And Drupal 7 is in my development environment. But the Nginx config on the Drupal 6 server has no special redirects. – hennadiy.verkh Sep 1 '15 at 16:46
2

After some debugging, I think, I can understand what happens.

Take a look at this Nginx rule from http://wiki.nginx.org/Drupal:

  location @rewrite {
            # You have 2 options here
            # For D7 and above:
            # Clean URLs are handled in drupal_environment_initialize().
            rewrite ^ /index.php;
            # For Drupal 6 and bwlow:
            # Some modules enforce no slash (/) at the end of the URL
            # Else this rewrite block wouldn't be needed (GlobalRedirect)
            #rewrite ^/(.*)$ /index.php?q=$1;
    }

I'm using the Drupal 7 rule and it tells Nginx to just execute the /index.php without any argument handling. Next, Drupal initializes and runs the drupal_environment_initialize() function, which calls the request_path() function. Here Drupal tries to parse the $_SERVER ['REQUEST_URI'] variable. And of course, here is no special handling for malformed urls, I see in my logs.

I think, that's the difference between my old Drupal 6 install and Drupal 7.

  1. Another rewrite rule from Nginx
  2. No url parsing by Drupal

Basically the question is not so big, if some search engine is too dumb to create malformed urls, it's not my problem. But I wanted to handle it, so I modified the Nginx config, by adding a rewrite string, which redirects malformed urls:

  location @rewrite {
            # You have 2 options here
            # For D7 and above:
            # Clean URLs are handled in drupal_environment_initialize().

            # redirect bad urls like /page&a=b to /page?a=b
            rewrite ^/([^?]*?)&(.+?)=(.+?)$ /index.php?q=$1&$2=$3 permanent;

            rewrite ^ /index.php;
            # For Drupal 6 and bwlow:
            # Some modules enforce no slash (/) at the end of the URL
            # Else this rewrite block wouldn't be needed (GlobalRedirect)
            #rewrite ^/(.*)$ /index.php?q=$1;
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.