Other headers disappear after adding Set-Cookie header

Hi,

I have the following problem.

In a configuration with several locations, I am using
add_header Set-Cookie “name=value; domain=xyz.com; path=/”;
and some other headers, like
add_header X-Info “Some information”

When the Set-Cookie header is added, all additional headers suddenly
disappear. When the Set-Cookie add_header call is disabled, the
additional headers appear as normal.

First I thought it might be a bug, but this behavior doesn’t occur when
I put this combination of headers in another location in another
(simpler) server block. I also upgraded from 0.7.67 to 0.8.49 to see if
that would make a difference, but it still happens.

Apparently there is something that drops the additional headers, but I
have no idea what. I have disabled all other locations, disabled all
other things (like expires), but without any effect.

The server block in which this happens is build up as follows:

  • Capture of a variable from the URL;
  • Rewrite of certain URLs to a static HTML page;
  • Location to serve the static HTML pages, which includes the add_header
    call for Set-Cookie, to pass on the value from the captured variable in
    a cookie;
  • Location to serve other static content (css, images, etc);
  • Location to proxy to apache.

I hope someone knows why this happens, and if it should be considered a
bug or not.

Thanks,

Raymond

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,120295,120295#msg-120295

Hello!

On Mon, Aug 16, 2010 at 07:57:51AM -0400, Unimatrix02 wrote:

disappear. When the Set-Cookie add_header call is disabled, the

bug or not.
Please show:

  1. Exact config which exposes the problem.

  2. nginx -V output

  3. Debug log.

See http://wiki.nginx.org/NginxDebugging for details.

Maxim D.

Hi Maxim,

Thanks for your reply. I hereby provide the requested details.

nginx -v output
nginx version: nginx/0.8.49
built by gcc 4.1.2 20080704 (Red Hat 4.1.2-48)
TLS SNI support disabled
configure arguments: --user=nginx --group=nginx
–prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx
–conf-path=/etc/nginx/nginx.conf
–error-log-path=/var/log/nginx/error.log
–http-log-path=/var/log/nginx/access.log
–http-client-body-temp-path=/var/lib/nginx/tmp/client_body
–http-proxy-temp-path=/var/lib/nginx/tmp/proxy
–http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi
–pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx
–with-http_secure_link_module --with-http_random_index_module
–with-http_ssl_module --with-http_realip_module
–with-http_addition_module --with-http_sub_module
–with-http_dav_module --with-http_flv_module
–with-http_gzip_static_module --with-http_stub_status_module
–with-http_perl_module --with-mail --with-mail_ssl_module
–with-cc-opt=’-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions
-fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic’
–with-ipv6
–add-module=/builddir/build/BUILD/nginx-0.8.49/nginx-upstream-fair
–add-module=/builddir/build/BUILD/nginx-0.8.49/nginx-upload-progress-module
–add-module=/builddir/build/BUILD/nginx-0.8.49/mod_zip-1.1.5
–add-module=/builddir/build/BUILD/nginx-0.8.49/nginx_upload_module-2.0.12
–add-module=/builddir/build/BUILD/nginx-0.8.49/nginx_mod_h264_streaming-2.2.7

nginx.conf
user nginx;

worker_processes 2;
worker_cpu_affinity 0001 0010;

error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;

events {
worker_connections 8192;
use epoll;
}

http {
server_names_hash_bucket_size 64;
include /etc/nginx/ibood-mime.types;
include /etc/nginx/conf.d/*.conf;
default_type application/octet-stream;

log_format common '$http_X_Cluster_Client_IP - $remote_user
[$time_local] “$request” ’
'$status $body_bytes_sent “$http_referer” ’
‘"$http_user_agent" “$http_x_forwarded_for”’;

log_format main '$remote_addr $proxy_add_x_forwarded_for $remote_user
[$time_local] $request ’
'"$status" $body_bytes_sent “$http_referer” ’
‘"$http_user_agent" “$http_x_forwarded_for”
“$http_x_cluster_client_ip”’;

log_format  details  '$http_X_Cluster_Client_IP $remote_user

[$time_local] $request ’
'"$status" $body_bytes_sent $bytes_sent
$connection “$pipe” ’
'$msec $request_time $request_length ’
'"$http_referer" ’
‘"$http_user_agent" “$http_x_forwarded_for”’;
access_log /var/log/nginx/access.log common;
sendfile on;
tcp_nopush on;
keepalive_timeout 15;

gzip off;

— Virtual hosts —

[ irrelevant vhosts cut out ]

The default server

server
{
listen 80 default backlog=1024;
server_name _;
server_name_in_redirect off;

# Look for affiliate in URI
set $aff_id "";
if ($request_uri ~* "(affiliate,|affiliate=)([a-z0-9]*)")
{
  set $aff_id $2;
}

# Redirect old NL variants to main NL variant
rewrite ^/(depers|ad|iex|nu)/nl(.*)$ /nl/nl$2 permanent;

# Redirect banners to ext
rewrite ^/(banners/.*)$ http://ext.ibood.com/$1 permanent;

# Redirect feed requests to ext.ibood.com
rewrite ^/feeds/ibood_([^_/]+)_([^_/]+)\.xml$

http://feeds.ibood.com/ibood/$1_$2 permanent;

# Redirect all traffic on /feeds to ext.ibood.com
rewrite ^/feeds/(.*)$ http://ext.ibood.com/$1 permanent;

rewrite ^(/cms/.*)$ $1 break;

# Static content ----
rewrite ^([^\.]*)/imgdesign/([^\.]*)\.([^\.]*)$ 

/main/imgdesign/$2.$3
last;
rewrite ^([^.])/style/(.).css$ /main/style/$2.css last;
rewrite ^([^.])/js/(.).js$ /main/js/$2.js last;
rewrite ^/img/(.).(swf|js|ico|gif|jpg|JPG|png|css)$ /img/$1.$2
last;
rewrite ^/templates_dynamic/(.
).(js|ico|gif|jpg|JPG|png|css)$
/templates_dynamic/$1.$2 last;

# Remove trailing slash from .html URIs
rewrite ^(.+)\.html/?$ $1.html last;

# Rewrite for affiliate handling
#if ($request_uri ~

“^/(pl/pl|nl/nl|de/de|uk/en|be/nl|ie/en|bild/de).(affiliate,|affiliate=).”)
#{
# rewrite ^.*$ /handle_affiliate.php last;
#}

# Serve static pages -----

# Only if not containing "affiliate"
#if ($request_uri !~ "(affiliate=|affiliate,)" )
#{
  rewrite

^/(pl/pl|nl/nl|de/de|uk/en|be/nl|ie/en|bild/de)/(product_specs/.)$
/static/generated/$1/$2 last;
rewrite ^/(pl/pl|nl/nl|de/de|uk/en|be/nl|ie/en|bild/de)(/?)$
/static/generated/$1/index.html last;
rewrite ^/(pl/pl|nl/nl|de/de|uk/en|be/nl|ie/en|bild/de)/index.

/static/generated/$1/index.html last;
#}

# Redirect to splash page if request uri is still /
rewrite ^/$ /index.html last;

# ----

# Serve generated HTML files directly, but expire immediately
location ~ /static/generated/.*\.html$
{
  # Set cookie with affiliate ID, if present
  if ($aff_id != "")
  {
    add_header  Set-Cookie  "iboodaffiliates=$aff_id; path=/;

domain=.ibood.com;";
}

  add_header  X-DebugInfo    aff_id=$aff_id;
  add_header  X-Info  "Served by nginx 1:$uri";

  root    /var/www/html;
  expires    -1h;
}

# Serve static files directly
location ~* \.(jpg|jpeg|gif|css|png|js|ico|xml|swf|pdf|doc|cur)$
{
  root    /var/www/html;
  access_log  off;
  # expires    30d;
  expires    12h;
  add_header  X-Info  "Served by nginx 2:$uri";
}

# Serve generated static pages
location /static/generated
{
  add_header  X-DebugInfo    aff_id=$aff_id;

  # Set cookie with affiliate ID, if present
  if ($aff_id != "")
  {
    #add_header  Set-Cookie  "testcookie=$aff_id; path=/;";
  }
  root    /var/www/html;
  access_log  off;
  expires    12h;
  add_header  X-Info  "Served by nginx 3:$uri";
}

# Set default languages
#rewrite ^/pl/?$    /pl/pl/    permanent;
#rewrite ^/nl/?$    /nl/nl/    permanent;
#rewrite ^/de/?$    /de/de/    permanent;
#rewrite ^/uk/?$    /uk/en/    permanent;
#rewrite ^/be/?$    /be/nl/    permanent;
#rewrite ^/ie/?$    /ie/en/    permanent;

#rewrite ^/$ /index.html last;
#rewrite ^(/cms/.*)$ $1 break;

# Pass calls to API client through without rewrites
#rewrite ^(/ac/.*)$ $1 break;

# Don't rewrite request to affiliate handler
#rewrite ^(/handle_affiliate.php) $1 break;

# Send everything to front controller
#rewrite ^.*$ /main/frontend.php break;

location /
{
  add_header  X-Info  "Served by apache";

  proxy_set_header   Host          $host;
  proxy_set_header   X-Cluster-Client-IP  $remote_addr;
  proxy_set_header   X-Forwarded-For    $proxy_add_x_forwarded_for;
  proxy_set_header   X-Request-URI      $request_uri;

  proxy_pass       http://127.0.0.1:8080;
  proxy_redirect     off;
}

error_page  404      /main/404.php;

}
}

debug log
2010/08/16 15:12:22 [notice] 24579#0: 1
"(affiliate,|affiliate=)([a-z0-9]
)" matches
“/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50, server: ,
request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host:
r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: 1 "^/(depers|ad|iex|nu)/nl(.)$"
does not match “/nl/nl/index/affiliate,Affilinet/”, client:
192.168.32.50, server: , request: “GET
/nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host: “r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: 1 "^/(banners/.)$" does not
match “/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50,
server: , request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”,
host: “r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: *1
"^/feeds/ibood
([^
/]+)
([^_/]+).xml$" does not match
“/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50, server: _,
request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host:
r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: 1 "^/feeds/(.)$" does not match
“/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50, server: _,
request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host:
r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: 1 "^(/cms/.)$" does not match
“/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50, server: _,
request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host:
r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: 1
"^([^.]
)/imgdesign/([^.]).([^.])$" does not match
“/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50, server: _,
request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host:
r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: 1 "^([^.])/style/(.).css$"
does not match “/nl/nl/index/affiliate,Affilinet/”, client:
192.168.32.50, server: _, request: “GET
/nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host: “r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: 1 "^([^.])/js/(.
).js$" does
not match “/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50,
server: _, request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”,
host: “r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: 1
"^/img/(.
).(swf|js|ico|gif|jpg|JPG|png|css)$" does not match
“/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50, server: _,
request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host:
r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: 1
"^/templates_dynamic/(.
).(js|ico|gif|jpg|JPG|png|css)$" does not match
“/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50, server: _,
request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host:
r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: *1 “^(.+).html/?$” does not match
“/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50, server: _,
request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host:
r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: 1
"^/(pl/pl|nl/nl|de/de|uk/en|be/nl|ie/en|bild/de)/(product_specs/.
)$"
does not match “/nl/nl/index/affiliate,Affilinet/”, client:
192.168.32.50, server: _, request: “GET
/nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host: “r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: *1
“^/(pl/pl|nl/nl|de/de|uk/en|be/nl|ie/en|bild/de)(/?)$” does not match
“/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50, server: _,
request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host:
r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: 1
"^/(pl/pl|nl/nl|de/de|uk/en|be/nl|ie/en|bild/de)/index.
" matches
“/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50, server: _,
request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host:
r.dev.ibood.com
2010/08/16 15:12:22 [notice] 24579#0: *1 rewritten data:
“/static/generated/nl/nl/index.html”, args: “”, client: 192.168.32.50,
server: _, request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”,
host: “r.dev.ibood.com

I hope this helps to figure it out. My idea is that it has something to
do with the placement of the add_header call in a specific location
block but I haven’t been able to reproduce this problem with a simpler
server block.

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,120295,120324#msg-120324

Ah, that explains it. Thank you very much.

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,120295,120348#msg-120348

Hello!

On Mon, Aug 16, 2010 at 09:22:07AM -0400, Unimatrix02 wrote:

[…]

  add_header  X-DebugInfo    aff_id=$aff_id;
  add_header  X-Info  "Served by nginx 1:$uri";

This code defines two locations. One of them has add_header array
set to “X-DebugInfo, X-Info” and another one (implicitly defined
by “if”) has it redefined to “Set-Cookie”.

You have to duplicate other add_header directives within implicit
location defined by “if”, i.e.

location ... {
    add_header X-DebugInfo ...
    add_header X-Info ...

    if (...) {
        add_header Set-Cookie ...
        add_header X-DebugInfo ...
        add_header X-Info ...
    }
}

Further reading:

http://wiki.nginx.org/IfIsEvil

[…]

debug log
2010/08/16 15:12:22 [notice] 24579#0: 1
"(affiliate,|affiliate=)([a-z0-9]
)" matches
“/nl/nl/index/affiliate,Affilinet/”, client: 192.168.32.50, server: _,
request: “GET /nl/nl/index/affiliate,Affilinet/ HTTP/1.1”, host:
r.dev.ibood.com

This isn’t a debug log as you haven’t recompiled nginx with
–with-debug option. Doesn’t matter though, problem is clear from
the config itself.

Maxim D.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs