olofom
olofom

Reputation: 6491

Correct escaping of % in the URL with Apache

I have a Django project where I have a search page which takes input through a POST and redirect to /search/<search string>/ and this page renders the result. The percentage sign (%) is used as a wildcard in the search (tes%er returns testuser, tester, etc and the url looks like this then: example.com/search/tes%25er/) and everything works fine with the Django development server. If I manually write tes%er in the url it changes to tes%25er automatically.

Now I'm deploying on an Apache server with mod_wsgi and when my search page redirects to example.com/search/tes%er/ I get the server error: Bad Request. Your browser sent a request that this server could not understand.. If I manually add '25' to the url, like the encoded % sign so it looks like the development server it works fine.

Is there a way for Apache to automatically escape the %-sign and create a url that works, understand % unescaped or do I need to do ugly hacks in my search page that builds the url? (I'd rather not do ugly hacks like this cause then the users can't manually add % to the url and get it to work).

Edit: The code that sends the query from the search page to the search url.

if form.is_valid():
    if 'search_user' in request.POST:
        q = request.POST['search_user']
        return redirect('/search/'+q)

Upvotes: 1

Views: 682

Answers (1)

Wouter Klein Heerenbrink
Wouter Klein Heerenbrink

Reputation: 1391

As Ignacio already suggested, you should not redirect to an invalid url. So to answer your question:

you can (or perhaps its better to say 'should') not ask your Apache server to escape your url. The reason you escape your URL is because some characters have another meaning. For example, take a querystring:

somedomain.com/?key=value

If we would want to use a ? or a = in your value you would have a problem because your server would think that you are using operators of your querystring.

The same for the %-symbol. When your apache server sees a %-symbol he thinks he will find an enconded and will try to decode it. If your querystring is %20, apache will translate this to a space, while you meant "wildcard20".

In summary: apache decodes your string, so you dont want him to encode it.

But this does not solve your problem. You can solve your problem by changing your code into the following:

from urllib import urlencode
if form.is_valid():
    if 'search_user' in request.POST:
        q = request.POST['search_user']
        return redirect('/search/?q='+urlencode(q))

In case you wonder: what if my user would type /search/?q=%; in that case he'ld have a problem for he has typed an invalid address.

Hope this helps :-).

Wout

Upvotes: 1

Related Questions