Jump to content

htaccess and url encoding ? Escaping + and &


Go to solution Solved by mac_gyver,

Recommended Posts

Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (?!^infos/)^(.+?)/?$ /dl.php?f=$1 [L,QSA,NC]

 

 

This htaccess is used to make user-friendly URL for downloads.

 

http://example.com/some_file_to_download.zip

will redirect to the download page at

http://example.com/dl.php?f=some_file_to_download.zip

 

 

Problem is that when the filename contains special characters like + or &, it will mess up the GET variable of dl.php

 

Example of a problematic URL:

http://example.com/file&special+characters

will redirect to

http://example.com/dl.php?f=file&special+chracters

So we have a problem here.

 

How can i escape those special characters in my htaccess file ? I have no control over the original URL (before it is being redirected to dl.php) so i can't just use php to urlencode.

 

Link to comment
https://forums.phpfreaks.com/topic/279363-htaccess-and-url-encoding-escaping-and/
Share on other sites

You sure it's happening exactly like that? mod_rewrite normally escapes things for you and you have to explicitly tell it not if you don't want it.

 

If so,

RewriteMap esc int:escape
and

RewriteRule (?!^infos/)^(.+?)/?$ /dl.php?f=${esc:$1} [L,QSA,NC]

You sure it's happening exactly like that? mod_rewrite normally escapes things for you and you have to explicitly tell it not if you don't want it.

 

If so,

RewriteMap esc int:escape
and

RewriteRule (?!^infos/)^(.+?)/?$ /dl.php?f=${esc:$1} [L,QSA,NC]

 

 

Yes i'm sure.

 

See here:

http://www.pirate-punk.com/Bérurier Noir + Haine Brigade - Split 7'' Ep.zip

 

It will display this page:

http://www.pirate-punk.com/dl.php?f=Bérurier Noir + Haine Brigade - Split 7'' Ep.zip

 

i added a line to display the value of $_GET['f'] on the top of the page, and as you can see the plus sign is missing.

 

When i tried your code in my htaccess, i got an Internal Server Error

Edited by ungovernable

I can't. This is a server where a group of users upload files through FTP. Then they access their file by using the URL http://www.pirate-punk.com/thefile.zip where "thefile.zip" is the file they have uploaded through FTP.

 

This is public URL is just an htaccess "virtual url" (rewriting) to access the real URL at = pirate-punk.com/dl.php?f=thefile.zip

Then this PHP file will locate the file on the server and generate a rawurlencode'd link.

 

Everything works perfectly except then i use plus signs or "&" symbols because it breaks the GET['f'] in dl.php

 

Working examples:

http://www.pirate-punk.com/86 Crew - 2000 - Bad Bad Reggae.zip

Also works with accents:

http://www.pirate-punk.com/Affliction - De La Révolte A La Révolution.zip

 

The problem is only when the filename has characters like + or &

 

I need to find a way to escape the + and & in the htaccess file that passes the filename to dl.php ...

 

is it possible to base64 encode the filename in the htaccess ?

so the htaccess would transform http://www.pirate-punk.com/Bérurier Noir + Haine Brigade - Split 7'' Ep.zip

to http://www.pirate-punk.com/dl.php?f=QulydXJpZXIgTm9pciArIEhhaW5lIEJyaWdhZGUgLSBTcGxpdCA3JycgRXAuemlw

 

Then dl.php could decode the base64 and the problems with + and & would be avoided.

Edited by ungovernable

If you have to do it in the .htaccess then that RewriteMap thing I posted would be the way to go. 500 you say? What does the error log say about why?

 

Also, insert the typical spiel about allowing people to upload files without doing anything to the filename and about putting them in the root directory and about not giving links to the files.

 

Options +FollowSymLinks -MultiViews

# Turn mod_rewrite on

RewriteEngine On

RewriteBase /

 

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-l

RewriteCond %{REQUEST_FILENAME} !-d

RewriteMap esc int:escape

RewriteRule (?!^infos/)^(.+?)/?$ /dl.php?f=${esc:$1} [L,QSA,NC]

 

RewriteRule ^$ http://www.pirate-punk.net [R=301,L]

 

Did i do something wrong ?

 

 

Error log says:

 

[Thu Jun 20 02:37:18 2013] [alert] [client 108.171.90.240] /var/www/clients/client0/web1/web/.htaccess: RewriteMap not allowed here

It isn't directly associated with the Rule. Think of it like a function definition: it should be put somewhere out of the way and not in the middle of a variable assignment or a loop.

 

"Out of the way" like

Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /

RewriteMap esc int:escape

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (?!^infos/)^(.+?)/?$ /dl.php?f=${esc:$1} [L,QSA,NC]

RewriteRule ^$ http://www.pirate-punk.net [R=301,L]
Edited by requinix

Oh, I didn't realize: RewriteMap is only allowed at the server configuration level - you can't put it in a .htaccess.

 

The only other thing I can think of is writing loops to find and replace characters in the request URI but that's a horrible thing to resort to, and I'm not even 100% sure how.

Damn..

 

Then would it be possible to base64 encode the url with the htaccess ?

 

so the htaccess would transform http://www.pirate-punk.com/Bérurier Noir + Haine Brigade - Split 7'' Ep.zip

topirate-punk.com/dl.php?f=QulydXJpZXIgTm9pciArIEhhaW5lIEJyaWdhZGUgLSBTcGxpdCA3JycgRXAuemlw

 

Special characters wouldn't be a problem anymore

  • Solution

unless you can re-urlencode those in the .htaccess, by the time this reaches the $_GET variables, any & will terminate the $_GET['f'] variable.

 

an option would be to not try to use the $_GET variable and parse the file name yourself out of $_SERVER['QUERY_STRING'] or $_SERVER['REQUEST_URI']

unless you can re-urlencode those in the .htaccess, by the time this reaches the $_GET variables, any & will terminate the $_GET['f'] variable.

 

an option would be to not try to use the $_GET variable and parse the file name yourself out of $_SERVER['QUERY_STRING'] or $_SERVER['REQUEST_URI']

 

Nice, thanks a lot ! I didn't think about that and i think i fixed my problem using QUERY_STRING !

  • 2 weeks later...
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.