Make Django/DRF accept urls without trailing slash - django

Is it possible to avoid url redirections to url/ in Django/DjangoRestFramework? My point is that some frontend developers use url without trailing slashes and Django redirects such requests to url/ which slows down the API.
Adding
APPEND_SLASH = False
to settings doesn't solve the problem as it returns 404 responses.

Related

apache does not pass request to Django (404 not found)

I have a custom 404 page setup for the site, which works fine, like this:
when I hit mysite.com/fdsafsadfdsa which doesn't exist, the custom 404 page shows up.
However if I add a urlencoded '/' which is '%2f' at the end of url, mysite.com/fdsafsadfdsa%2f, and this gives me the apache 404 not found.
it looks like apache decided to handle this 404 itself instead of passing down to Django
Anybody has idea why this is happening?
Turns out it's a issue in Apache/Nginx. And somebody submit this issue to Django project before, see here: https://code.djangoproject.com/ticket/15718
and quote from the ticket, there's a workaround:
After investigation I've found that the 2nd issue (404 error directly from apache) is not related to django and can be avoided by adding "AllowEncodedSlashes On" into apache config. Unfortunately apache replaces %2f with / itself, so the behavior is exactly the same as in simple http server provided by django. In Apache 2.2.18 (which is not released yet, i guess), AllowEncodedSlashes allows value NoDecode. With the value NoDecode, such URLs are accepted, but encoded slashes are not decoded but left in their encoded state. Meanwhile I'm using the workaround
request_uri = force_unicode(environ.get('REQUEST_URI', u'/'))
if u'?' in request_uri:
path_info,query = request_uri.split('?',1)
else:
path_info,query = request_uri,''
instead of original
path_info = force_unicode(environ.get('PATH_INFO', u'/'))
in core/handlers/wsgi.py

Restangular fails with promise and cross-origin requests

I am reading about Restangular and everywhere is mentioned that Restangular promises and Angular works smart and the template is updating in situations like this:
As Angular supports setting promises to scope variables as soon as we
get the information from the server, it will be shown in our template
$scope.something = Restagular.one('something').get();
I am trying to do the same thing but the Restangular is in a service because I want to keep my controllers clean. When I make a request to my REST API the Angular template is not updating and I receive this error:
XMLHttpRequest cannot load http://localhost:3000/api/template/1. The request was redirected to 'http://localhost:3000/api/template/1/', which is disallowed for cross-origin requests that require preflight.
Here is my code:
in the service...
myAppServices.service('TemplateService', ['$http', '$cookies', '$cookieStore', Restangular',
function($http, $cookies, $cookieStore, Restangular) {
Restangular.setBaseUrl(constants.serverAddress);
var getTemplate = function(templateId) {
// Check the input
if (!isValidId(templateId))
return;
return Restangular.one('api/template', templateId).get();
};
// Public getters
this.getTemplate = getTemplate;
}]);
in the controller..
$scope.currentCard = TemplateService.getTemplate(1);
So where is the problem in this case - on the client or on the server. For my API I am using django-rest-framework but I don't have problems when I am getting list with all templates (without a specific id).
I know that I can try to return a promise from the service and from its .then() to set my scope variable but in the official repo of Restangular is mentioned this and I want to use it because the code remains clean.
The issue that you are having is because Django will automatically redirect urls without a slash to urls with a slash. This isn't framework specific, as I recently discovered it is an issue for ExtJS as well.
Because you are requesting the url api/templates/1 without the trailing slash and the API is being served at api/templates/1/, Django is automatically redirecting requests from one location to the other. Normally this issue an issue, you just see the redirect happening in the console and nobody cares, but CORS requires you to have permission for the url you requested, which means it can't redirect.
You can fix this two different ways: on the client side or on the server side.
If you want to fix this on the client side, and keep the server requiring slashes, you need to tell restangular to add a slash to the end. Restangular allows you to do this by setting
RestangularProvider.setRequestSuffix('/');
In your code, which will tell restangular to always add the trailing slash.
If you want to fix this on the server side, you are going to need to stop requiring slashes in your API. This has the unpleasant side effect of not allowing any requests with a slash, and may break existing applications which are working as expected. Django REST Framework allows you to do this on the router level by setting trailing_slash=False when initializing the router.
router = SimpleRouter(trailing_slash=False)
This will tell Django REST Framework to register all of the urls without a trailing slash.

Amazon S3 URL redirect with trailing forward slash

I'm trying to do some URL redirects and the redirects are working properly, however if I try to redirect a URL that ends in a forward slash the redirect does not work. For example, I'd like to redirect http://mydomain/foo/ to /bar/ does not work. However http://mydomain/foo to /bar/ does redirect properly. Can anyone tell me how to redirect urls with training forward slashes properly?
I think that if a web server indicates a trailing slash, it immediately looks for the default file (e.g. index.html) in the given directory.
This convention is speeding up the web server work.
e.g.
http://mysite/test/ ==> is a directory
http://mystite/test ==> is a file

Facebook Like not appearing , if Url has "/" "%2F" in end

Our website url is ending with slash "/", it get encoded to "%2F". because of this slash facebook like button is not showing on the website.
Eg
Not working url: because in href parameter url has "%2F", but if i remove the "%2f", it starts working. Earlier it was working fine.
https://www.facebook.com/plugins/like.php?action=like&channel_url=https%3A%2F%2Fs-static.ak.facebook.com%2Fconnect%2Fxd_arbiter.php%3Fversion%3D9%23cb%3Df3e1268db4%26origin%3Dhttps%253A%252F%252Fwww.bcgperspectives.com%252Ff189b4c84c%26domain%3Dwww.bcgperspectives.com%26relation%3Dparent.parent&extended_social_context=false&font=arial&href=https%3A%2F%2Fwww.bcgperspectives.com%2Fcontent%2Fvideos%2Fleadership_paul_deighton_organizing_london_2012_olympics%2F&layout=button_count&locale=en_US&node_type=link&ref=.UCfPf5lBPRI.like&sdk=joey&show_faces=false&width=90
any solution for it.
I can’t get a like button shown on https://developers.facebook.com/docs/reference/plugins/like/ when I input your URL https://www.bcgperspectives.com/content/videos/leadership_paul_deighton_organizing_london_2012_olympics/, no matter whether the trailing slash is there or not.
However, it does get shown if I use http:// instead of https:// in front of your URL – then it works for both versions, the one with the trailing slash and the one without.
An interesting fact though is, that I can not see any information scraped from your page using the debug tool on your URL – doesn’t matter if its the slash or no-slash version or the HTTP vs the HTTPS version, since your server redirects to the HTTPS version with the trailing slash anyway. So that might point to some problem FB’s scraper has with your URL/domain (although no explicit error messages are shown).

Django ignores APPEND_SLASHES

I've set the APPEND_SLASHES directive to False in my settings.py file and yet Django carries on to redirect some (but not all) requests which is incredibly annoying. What could be causing this issue?
Basically, if I make a request without the slash, it will return the correct response body, but with a redirect (301), redirecting it to the same URL but with a slash at the end which will not match because it shouldn't end in a slash.
Is there a fix for that or do I just need to strip the slash redirection code from CommonMiddleware?
Edit: CommonMiddleware is not the culprit. The URL reaches it with a slash at the end.
Edit2: Only happens in Firefox. What the hell? Firebug registers two HTTP requests, one of which is a redirect. Only one request actually hits the server, and it's the one with the slash at the end. The 301 appears out of nowhere and isn't even sent (Wireshark doesn't register it).
301 are permament redirects. So if you have had this option set to true before firefox will still remember this permament redirect and go to page with slash appended. Try to clear firefoxes caches and offline contents.