Add headers to a Django redirect - django

I am returning a file to the client via redirect(s3_url). According to the docs I should be able to add a custom header:
response = redirect(s3_url)
response['File-Name'] = file_name
return response
In chrome dev tools, I don't see any File-Name header in the response headers.

Related

POST request with content type multipart/form-data with adding extra header at the AWS API GATEWAY

I have an AWS api gateway and i want to send a post request or any other request if possible when content type is multipart/form-data, the problem is that i want to add a conditional extra header at the api gateway level using template mappings, i was able to do this with GET request and content type is application/json, but the same code i applied doesn't seem to work when request is POST and content type is multipart/form-data, so how can i add an extra header when using different content tyes or different requests at the api gateway level ? my code that worked is this :
#set($header3Value = "service1")
$input.json("$")
#set($context.requestOverride.header.x-service-key = $header3Value)
#elseif
($method.request.header.x-api-key == "*******************nmMBBkbbkBVCXvjhvhkk")
#set($header3Value = "service1")
$input.json("$")
#set($context.requestOverride.header.x-service-key = $header3Value)
#elseif
($method.request.header.x-api-key == "*****IHOHMubbbVYVYUVVVVLkbkbbbmmlb")
#set($header3Value = "service2")
$input.json("$")
#set($context.requestOverride.header.x-service-key = $header3Value)
#end
Edit : When I prepare a template mapping for multipart/form-data with the same code i used for Application/json, i get "internal server error" with no other info, but when i empty the template and leave it blank, it goes back to working but of course, the custom header i want to add won't be added ...

Prevent Force Download of AWS S3 Files Django

I am using
storages.backends.s3boto3.S3Boto3Storage
storage backend to upload files in my django project.
field declaration in model:
document = models.FileField(upload_to=s3_directory_path.user_directory_path)
user_directory_path
def user_directory_path(instance, filename):
# TODO: Try to include this along with check filetype on the request object
document = instance.document
mime = magic.from_buffer(document.read(), mime=True)
extension = mimetypes.guess_extension(mime, strict=False)
file_name = str(uuid.uuid4()) + extension
document.seek(0)
return os.path.join("users", str(instance.user.id), file_name)
The saving of the document works perfectly fine, but the link which is generated force downloads the file. How can i avoid that?
Have a look at this answer to a general question about forcing file downloads via HTTP response headers. See also the MDN docs about Content-Disposition.
Can you show us the response headers you get when visiting the document URL?
It would be interesting to see how S3 delivers your files.
If you cannot change the headers in S3, you have the option to write a Django view that proxies the file download. Alternatively, configure your webserver (i.e. NGINX) to act as a proxy and set the required headers).
For Django, this section of the docs will show you how to set the headers.
response = HttpResponse(
document,
headers={
'Content-Type': mimetype,
'Content-Disposition': f'attachment; filename="{document.name}"',
}
)

Add auth token in request header in ember-file-upload

I am using ember vesrion 2.15.1 for my application. I am using ember-file-upload node module to support file upload and that is successful. Challenge is I am not able to add auth token to the request header. My request header looks like this:
I am not able to add userAuthToken in request header of file upload like below which I am able to add for other api calls:
I have tried uploading the file via
set(file, 'headers.userAuthToken', localStorage.getItem("userToken")); // this line is creating problems
let response = yield file.upload(url);
But unable to add userAuthToken in request header.
Any fix or workaround will be appreciated.
You can pass options as second parameter of upload method. One of possible options is headers. Something like this should work:
let response = yield file.upload(url, {
headers: {userAuthToken: localStorage.getItem("userToken")}
});
You can find other possible options here
You can add additional headers in application adapter, for example:
import ActiveModelAdapter from 'active-model-adapter';
var token = $('meta[name="csrf-token"]').attr('content');
export default ActiveModelAdapter.extend({
headers: {
"X-CSRF-Token": token
}
});

What type of Request Data can be Retrieved from ColdFusion Headers?

This is a good way to grab the request before the response: useragent = getHttpRequestData().headers["User-Agent"];
What I noticed is that it will not grab the request unless it is on the actual list of header request. An example is I that it seems to only pull the basic request data. For instance if I set the cache control in the web.config file it does set cache, max age and etag, but when setting etags = getHttpRequestData().headers["ETag"]; and trying to output the data for the ETag generated by the web.config file/server it will not grab the ETag data to output. A few others that I tested are:
useragent = getHttpRequestData().headers["User-Agent"];
acceptencoding = getHttpRequestData().headers["Accept-Encoding"];
acceptlanugage = getHttpRequestData().headers["Accept-Language"];
cachecontrol = getHttpRequestData().headers["Cache-Control"];
connection = getHttpRequestData().headers["Connection"];
accept = getHttpRequestData().headers['Accept'];
contentlength = getHttpRequestData().headers['Content-Length'];
Request data is sent from the browser. You can see that with ColdFusion. But IIS sets response headers (such as etag) after ColdFusion is done processing. It's a response not a request. You cannot see that with ColdFusion, but you can in your browser. EX:

custom HTTP headers for static files with Django

I'm writing an image bank with Django, and I want to add a button to get a hi-res version of an image (the low-res is shown in the details page). If I put just an <a> link, the browser will open the image instead of downloading it. Adding an HTTP header like:
Content-Disposition: attachment; filename="beach008.jpg"
works, but since it's an static file, I don't want to handle the request with Django. Currently, I'm using NGINX to serve static files, and dynamic pages are redirected via FastCGI to the Django process. I'm thinking about using NGINX add-header command, but could it set the filename="xx" part?. Or maybe there's some way to handle the request in Django, but make NGINX serve the content?
If your django app is proxied by nginx you can use x-accell-redirect. You need to pass a special header in your response, nginx will intercepet this and start serving the file, you can also pass Content-Disposition in the same response to force a download.
That solution is good if you want to control which users acess these files.
You can also use a configuration like this:
#files which need to be forced downloads
location /static/high_res/ {
root /project_root;
#don't ever send $request_filename in your response, it will expose your dir struct, use a quick regex hack to find just the filename
if ($request_filename ~* ^.*?/([^/]*?)$) {
set $filename $1;
}
#match images
if ($filename ~* ^.*?\.((jpg)|(png)|(gif))$) {
add_header Content-Disposition "attachment; filename=$filename";
}
}
location /static {
root /project_root;
}
This will force download on all images in some high_res folder (MEDIAROOT/high_rest). And for the other static files it will behave like normal. Please note that this is a modified quick hack that works for me. It may have security implications, so use it with precaution.
I wrote a simple decorator, for django.views.static.serve view
Which works for me perfectly.
def serve_download(view_func):
def _wrapped_view_func(request, *args, **kwargs):
response = view_func(request, *args, **kwargs)
response['Content-Type'] = 'application/octet-stream';
import os.path
response['Content-Disposition'] = 'attachment; filename="%s"' % os.path.basename(kwargs['path'])
return response
return _wrapped_view_func
Also you can play with nginx mime-types
http://wiki.codemongers.com/NginxHttpCoreModule#types
This solution didn't work for me, because I wanted to have both direct link for the file (so user can view images, for example), and download link.
What i'm doing now is to use a different URL for download than for 'views', and add the filename as an URL arg:
usual media link: http://xx.com/media/images/lores/f_123123.jpg
download link: http://xx.com/downs/hires/f_12323?beach008.jpg
and nginx has a config like this:
location /downs/ {
root /var/www/nginx-attachment;
add_header Content-Disposition 'attachment; filename="$args"';
}
but i really don't like the smell of it.