Override Content-Type header with proxied requests

Please refer this page

Posted at Nginx Forum:

Hello All,

Can somebody answer this question? I am facing this issue from many
days.

–Manish

Posted at Nginx Forum:

Hello,

you can use many values on the map, take a look on its docs.
One quickly example may be (not tested)

map $uri $custom_content_type {
default “text/html”;
~(.*.json)$ “application/json”;
}

location ~ .json$ {
proxy_hide_header Content-Type;
add_header Content-Type $custom_content_type;

# other proxy configurations like proxy_pass

}

Or try to use the types {} directive which is specific to make the
relationship between extensions and content-type.

Did you tried to only hide the header with
proxy_hide_header Content-Type;
and let nginx use the mime.types to set the content type?

Do not set the add_header Content-Type manually.

Let me know the result.

Hello wandenberg,

Thank you for your response. I truly appreciate your help. I tried this
options given below

######First Method###############

  1. Edit nginx.conf and add
    map $uri $custom_content_type {
    default “text/html”;
    ~(.*.json)$ “application/json”;
    }

  2. Put the custom map in location directive
    location / {
    proxy_redirect off;
    proxy_set_header Host
    www-aaa.com.s3.amazonaws.com;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Referer www-aaa.com;
    proxy_pass http://www-aaa.com.s3.amazonaws.com/;
    add_header Pragma “no-cache”;
    proxy_cache_valid 200 302 10m;
    proxy_read_timeout 60s;
    proxy_hide_header Content-Type;
    add_header Content-Type $custom_content_type;
    }

######Second Method###############

  1. Edit nginx.conf and add
    map $uri $custom_content_type {
    default “text/html”;
    ~(.*.json)$ “application/json”;
    }

  2. Put the custom map in location directive
    location / {
    proxy_redirect off;
    proxy_set_header Host
    www-aaa.com.s3.amazonaws.com;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Referer www-aaa.com;
    proxy_pass http://www-aaa.com.s3.amazonaws.com/;
    add_header Pragma “no-cache”;
    proxy_cache_valid 200 302 10m;
    proxy_read_timeout 60s;
    location ~ .json$ {
    proxy_hide_header Content-Type;
    add_header Content-Type $custom_content_type;
    }
    }

##Third Method####################

  1. Enter this in server block of nginx.
    location ~ .json$ {
    types { }
    default_type application/json;
    }

#################################

  1. When I tried first method I put below content in “location / { }” and
    due
    to this the JSON file served as application/json but all other files
    loaded
    as text/html as it was default in the map directive which caused
    image/css
    to not load. I thought it would read the mime.types files and will
    select
    the appropriate Content-Type.
    #########################
    proxy_hide_header Content-Type;
    add_header Content-Type $custom_content_type;
    ##########################

  2. When I tried second and third method, I am getting 404 because it is
    taking docroot as /var/empty

2014/08/07 17:13:22 [error] 14205#0: *33 open()
“/var/empty/aaa/bbb/ccc/ddd/eee.json” failed (2: No such file or
directory),
client: 5.5.5.5., server: www-aaa.com, request: “GET
/aaa/bbb/ccc/ddd/eee.json HTTP/1.1”, host: “www.aaa.coml”

So my question is where should I put the location ~.json block(in
location
/ {} or in server directive)?

my NGINX.conf******
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
worker_rlimit_nofile 30000;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format  main  '$remote_addr - $remote_user [$time_local] 

$request ’
'“$status” $body_bytes_sent “$http_referer” ’
‘“$http_user_agent” “$http_x_forwarded_for”’;
log_format combined_time ‘$remote_addr - $remote_user [$time_local]’
'“$request” $status $body_bytes_sent ’
‘“$http_referer” “$http_user_agent” $request_time’;

access_log  /var/log/nginx/access.log  combined_time;

include /etc/nginx/servers/*.conf;
}


*************************VHOST SETTING
server {
listen 80;
server_name www-aaa.com;
add_header Cache-Control off;
expires 1d;
root /var/empty;
error_log /var/log/nginx/www.aaa.com-error.log;
access_log /var/log/nginx/www.aaa.com-access.log
combined_time;
location = /favicon.ico {
root /www;
}
proxy_intercept_errors on;
error_page 400 401 402 403 404 406 407 408 409 410 411 412 413 414 415
416
417 495 496 497 500 501 502 503 504 505 506 507 = /error_page.pl;
error_page 405 =200 $uri;
location /error_page.pl {
fastcgi_pass 127.0.0.1:8999;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_pass_header “Status”;
}

location / {
proxy_redirect off;
proxy_set_header Host
www.aaa.com.s3.amazonaws.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Referer www.aaa.com;
proxy_pass http://www.aaa.com.s3.amazonaws.com/;
}
}


NOTE: All my files are served from s3 bucket and not a single files are
in
the server.

–Manish

Posted at Nginx Forum:

Hi Wandenberg,

As you suggested I added “proxy_hide_header Content-Type;” in location
/ {}
directive and I am getting 200 but how would I check what is the
Content-Type. I usually check with curl command. But with curl command I
don’t find the Content-Type since it is hidden now. Is there any other
way
to confirm the changes?

[root@LOCALHOST ~]# curl -v
http://www.aaa.com/aaa/bbb/ccc/ddd/eee/fff.json

  • Hostname was NOT found in DNS cache
  • Trying 5.5.5.5…
  • Connected to www.aaa.com (5.5.5.5) port 80 (#0)

GET /content/unittests/maja-test/essdev-2668/test2.json HTTP/1.1
User-Agent: curl/7.36.0
Host: www.aaa.com
Accept: /

< HTTP/1.1 200 OK

  • Server nginx is not blacklisted
    < Server: nginx
    < Date: Thu, 07 Aug 2014 18:06:53 GMT
    < Content-Length: 603
    < Connection: keep-alive
    < Keep-Alive: timeout=5
    < x-amz-id-2:
    6h0Xzm+Sa6+C7fPeocKD0iNJIRhm6thHqa1GJB+aOrOKwrT8T6YL2Lp2M74UlD39
    < x-amz-request-id: 62A0E211E69B6F9B
    < x-amz-meta-md5-hash: ab9b7b2c58d3a481e172aea95b1e87a0
    < Last-Modified: Fri, 25 Jul 2014 13:18:14 GMT
    < ETag: “ab9b7b2c58d3a481e172aea95b1e87a0”
    < Accept-Ranges: bytes
    < Expires: Fri, 08 Aug 2014 18:06:53 GMT
    <
    {
    JSON CONTENTS
  • Connection #0 to host www.aaa.com left intact
    }

–Manish

Posted at Nginx Forum:

Hello wandenberg,

This procedure is not working for internet explorer. The CSS are not
loading
properly. so we have to somehow get the Content-Type in the header. Is
there
anything we can use?

–Manish

Posted at Nginx Forum:

Hi Wandenberg,

Is there any way to show the Content-Type in the header as well?

–Manish

Posted at Nginx Forum:

One question, your backend are sending the content-type header if you
made
the request to it?
If yes, the value is right?
If not, I think the problem is on backend configuration.
You can set it on the nginx using the map like I suggest, but will have
to
add all possible file types on the map, like

map $uri $custom_content_type {
default “text/html”;
~(..json)$ “application/json”;
~(.
.css)$ “text/css”;
~(.*.js)$ “application/javascript”;

and all other formats

}

But I suggest to check the configuration on Backend server.

Hello Wandenberg,

Yes, the back-end(s3 bucket) is sending Content-Type header for each
request
and what I heard from the developers that the header is must for the
site to
work properly.

The issue started when I got the request of enabling content-type header
of
all the json files to application/json. As the default content-type in
NGINX
is application/octet-stream, the JSON files are served as
application/octet-stream. The jquery uses content-type header to
identify
the JSOn files and due to the application/octet-stream content type it
is
not able to identify the JSOn files.

I tried many options but each time one of the features(html files got
downloaded, CSS not loaded, CSS problem in internet explorer) got
impacted.

I will try adding all the mime types to the map directive and will let
you
know the result.

Here is my nginx.conf and vhost file for your reference

my NGINX.conf******
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
worker_rlimit_nofile 30000;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] $request ’
'“$status” $body_bytes_sent “$http_referer” ’
‘“$http_user_agent” “$http_x_forwarded_for”’;
log_format combined_time ‘$remote_addr - $remote_user [$time_local]’
'“$request” $status $body_bytes_sent ’
‘“$http_referer” “$http_user_agent” $request_time’;

access_log /var/log/nginx/access.log combined_time;
include /etc/nginx/servers/*.conf;
}


*************************VHOST SETTING
server {
listen 80;
server_name www-aaa.com;
add_header Cache-Control off;
expires 1d;
root /var/empty;
error_log /var/log/nginx/www.aaa.com-error.log;
access_log /var/log/nginx/www.aaa.com-access.log
combined_time;
location = /favicon.ico {
root /www;
}
proxy_intercept_errors on;
error_page 400 401 402 403 404 406 407 408 409 410 411 412 413 414 415
416
417 495 496 497 500 501 502 503 504 505 506 507 = /error_page.pl;
error_page 405 =200 $uri;
location /error_page.pl {
fastcgi_pass 127.0.0.1:8999;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_pass_header “Status”;
}

location / {
proxy_redirect off;
proxy_set_header Host www.aaa.com.s3.amazonaws.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Referer www.aaa.com;
proxy_pass http://www.aaa.com.s3.amazonaws.com/;
add_header Access-Control-Allow-Origin *;
}
}

Posted at Nginx Forum:

I wrote a module to process the problem
ena.GitHub - flygoast/ngx_http_types_filter: A NGINX module to change the `Content-Type` output header depending on an extension variable according to a condition specified in the 'if' clause.

our configuration in production like this:
location / {
types_filter $uri;

proxy_pass http://down_server;
}

Dear Manish!

Could you please share the file with mime types that you use to include
in a map?

manish-ezest wrote in post #1155024:

Hello Wandenberg,

Thanks for your help. Finally it is working. I included all the mime
types
in a file and included inside map directive and used it in the location
/ {}
directive with proxy hide parameter like you suggested.

–Manish

Posted at Nginx Forum:
Re: Override Content-Type header with proxied requests

Hello Wandenberg,

Thanks for your help. Finally it is working. I included all the mime
types
in a file and included inside map directive and used it in the location
/ {}
directive with proxy hide parameter like you suggested.

–Manish

Posted at Nginx Forum: