2

Hello In my project I have the following htaccess. Everything works ok for example I enter the following url domain.com/ test some test / test /

which becomes domain.com/test+some+test/test as expected

The strange thing for me at least is when I edit domain.com/test+some+test/test to

domain.com/test+some+test         /test

and hit enter again then it results into this:

domain.com/test+some+test%20%20%20%20%20/test

Shouldn't that be escaped again? If I'm missing something please point it out.

Options All -Indexes +FollowSymLinks -MultiViews

    <IfModule mod_rewrite.c>

        # Turn mod_rewrite on
        RewriteEngine On
        RewriteBase /

        # remove spaces from start or after /
        RewriteRule ^(.*/|)[\s%20]+(.+)$ $1$2 [L]
        # remove spaces from end or before /
        RewriteRule ^(.+?)[\s%20]+(/.*|)$ $1$2 [L]


        # replace spaces by + in between
        RewriteRule ^([^\s%20]*)(?:\s|%20)+(.*)$ $1+$2 [L,R=301]


        # Remove trailing slash
        RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [L,R=301]

        # Add trailing slash
        #RewriteCond %{REQUEST_URI} !(/$|\.) 
        #RewriteRule (.*) %{REQUEST_URI}/ [L,R=301] 

        # Remove multiple slashes
        RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/{2,} [NC]
        RewriteRule ^(.*) $1 [R=301,L]

        # Clean url rewrite
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_URI} !^.*\.(png|jpg|jpeg|bmp|gif|css|js|json)$ [NC]
        RewriteRule ^(.*)$ /index.php?req=$1 [L,QSA]

    </IfModule>

UPDATE

After further investigation and Applying R switch on the first 2 rewriterules as suggested by Anubhava only 1 issue remains

if I enter http://tms.localhost/test+some+test /test it becomes http://tms.localhost/test+some+test%20%20%20/test but if I enter it like this http://tms.localhost/test some test /test it becomes as expected http://tms.localhost/test+some+test/test

anubhava
  • 761,203
  • 64
  • 569
  • 643
0x_Anakin
  • 3,229
  • 5
  • 47
  • 86

2 Answers2

1

Spaces that are encoded as either + or %20 get decoded before having any rewrite rules get applied. That means this regex pattern: [\s%20] matches spaces, percent signs, 2's and 0's.

That regex needs to simply be:

    # remove spaces from start or after /
    RewriteRule ^(.*/|)[\s]+(.+)$ $1$2 [L]
    # remove spaces from end or before /
    RewriteRule ^(.+?)[\s]+(/.*|)$ $1$2 [L]

The problem is, if the browser requests: /test+test%20test/, or /test%20test+test/, this is going to get trasnlated to (space) regardless. Therefore you need to match against the actual request instead:

# replace spaces by + in between
RewriteCond %{THE_REQUEST} \ /(.*?)(%20)+([^\?\ ]*)
RewriteRule ^ /%1+%3 [L,R=301,NE]
Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • @PanagiotisGeorgeRaditsas it only replaces `%20` with `+`, which seemed to me what you wanted. – Jon Lin Sep 27 '13 at 19:45
  • @PanagiotisGeorgeRaditsas I edited the regex to handle multiple `%20`'s – Jon Lin Sep 27 '13 at 19:47
  • @PanagiotisGeorgeRaditsas I'm not sure what you mean by "it becomes `http://tms.localhost/test+some+test%20%20%20/test`", as that is the browser itself URL encoding a space. It has nothing to do with what the server is doing. Most browsers these days encodes it as %20, and then sends that as the request. The code above that checks the `%{THE_REQUEST}` var looks for that type of encoding, and redirects the browser to encode them as `+` instead – Jon Lin Sep 27 '13 at 19:52
0

Add R flag in your initial 2 rules also:

# remove spaces from start or after /
RewriteRule ^(.*/|)[\s%20]+(.+)$ $1$2 [L,R,NE]
# remove spaces from end or before /
RewriteRule ^(.+?)[\s%20]+(/.*|)$ $1$2 [L,R,NE]
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Omg you again :P this fails Anubhava domain.com/hello+there+boy%20%20%20/test. Test: domain.com/hello+there+boy /test (3spaces as you see) – 0x_Anakin Sep 27 '13 at 19:34
  • In your browser you're entering `http://domain.com/test+some+test /test` right? – anubhava Sep 27 '13 at 19:37
  • right that's what I used in my testing after my suggested changes in pace. That URL became: `http://localhost/test+some+test/test` for me. – anubhava Sep 27 '13 at 19:38
  • Make sure to test in a different browser since you're using 301. – anubhava Sep 27 '13 at 19:41
  • So `http://tms.localhost/test+some+test /test` is the only issue now? Do you see literal `%20` in your browser? – anubhava Sep 27 '13 at 19:49
  • Pls add NE flag in earlier rule also: `RewriteRule ^([^\s%20]*)(?:\s|%20)+(.*)$ $1+$2 [L,R=301,NE]` and test in a different browser since you're using 301. – anubhava Sep 27 '13 at 19:52
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/38202/discussion-between-panagiotis-george-raditsas-and-anubhava) – 0x_Anakin Sep 27 '13 at 20:01