Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

ADMISSION: i've posted this same question on stackoverflow, before realising it's probabaly better suited to superuser, but it kind of depends on the answer: If it turns out to be a problem in my nginx config, it's definitely superuser. If it turns out to be a problem in my Rails config (or code) then it's arguably stackoverflow.

I'm adding some https pages to my rails site. In order to test it locally, i'm running my site under one mongrel_rails instance (on 3000) and nginx.

I've managed to get my nginx config to the point where i can actually go to the https pages, and they load. Except, the javascript and css files all fail to load: looking in the Network tab in chrome web tools, i can see that it is trying to load them via an https url. Eg, one of the non-working file urls is

https://cmw-local.co.uk/stylesheets/cmw-logged-out.css?1383759216

I have these set up (or at least think i do) in my nginx config to redirect to the http versions of the static files. This seems to be working for graphics, but not for css and js files.

If i click on this in the Network tab, it takes me to the above url, which redirects to the http version. So, the redirect seems to be working in some sense, but not when they're loaded by an https page. Like i say, i thought i had this covered in the second try_files directive in my config below, but maybe not.

Can anyone see what i'm doing wrong? thanks, Max

Here's my nginx config - sorry it's a bit lengthy! I think the error is likely to be in the first (ssl) server block:

NOTE: the urls in here (elearning.dev, cmw-dev.co.uk, etc) are all just local host names, ie they're all just aliases for 127.0.0.1

server {
  listen 443 ssl;
  keepalive_timeout   70;

  ssl_certificate /home/max/work/charanga/elearn_container/elearn/config/nginx/certs/max-local-server.crt;
  ssl_certificate_key /home/max/work/charanga/elearn_container/elearn/config/nginx/certs/max-local-server.key;

  ssl_session_cache shared:SSL:10m;
  ssl_session_timeout 10m;
  ssl_protocols SSLv3 TLSv1;
  ssl_ciphers RC4:HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers on;

  server_name elearning.dev cmw-dev.co.uk cmw-dev.com cmw-nginx.co.uk cmw-local.co.uk;

  root /home/max/work/charanga/elearn_container/elearn;

  # ensure that we serve css, js, other statics when requested
  # as SSL, but if the files don't exist (i.e. any non /basket controller)
  # then redirect to the non-https version
  location / {
    try_files $uri @non-ssl-redirect;
  }

  # securely serve everything under /basket (/basket/checkout etc)
  # we need general too, because of the email/username checking
  location ~ ^/(basket|general|cmw/account/check_username_availability) {
    # make sure cached copies are revalidated once they're stale
    add_header Cache-Control  "public, must-revalidate, proxy-revalidate";

    # this serves Rails static files that exist without running
    # other rewrite tests
    try_files $uri @rails-ssl;
    expires 1h;
  }

  location @non-ssl-redirect {
    return 301 http://$host$request_uri;
  }

  location @rails-ssl {

    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_read_timeout 180; 

    proxy_next_upstream off;
    proxy_pass http://127.0.0.1:3000;
    expires 0d;
  }

}

#upstream elrs {
#  server 127.0.0.1:3000;
#}

server {
  listen       80;
  server_name elearning.dev cmw-dev.co.uk cmw-dev.com cmw-nginx.co.uk cmw-local.co.uk;

  root /home/max/work/charanga/elearn_container/elearn;

  access_log /home/max/work/charanga/elearn_container/elearn/log/access.log;
  error_log  /home/max/work/charanga/elearn_container/elearn/log/error.log debug;
  client_max_body_size  50M;
  index index.html index.htm;

  # gzip html, css & javascript, but don't gzip javascript for pre-SP2 MSIE6 (i.e. those *without* SV1 in their user-agent string)
  gzip  on;   
  gzip_http_version 1.1;
  gzip_vary on;
  gzip_comp_level 6;
  gzip_proxied any;
  gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; #text/html 

  # make sure gzip does not lose large gzipped js or css files
  # see http://blog.leetsoft.com/2007/7/25/nginx-gzip-ssl
  gzip_buffers 16 8k;

  # Disable gzip for certain browsers.
  #gzip_disable "MSIE [1-6].(?!.*SV1)";
  gzip_disable "MSIE [1-6]";

  # blank gif like it's 1995
  location = /images/blank.gif {
    empty_gif;
  }

  # don't serve files beginning with dots
  location ~ /\. { access_log off; log_not_found off; deny all; }

  # we don't care if these are missing
  location = /robots.txt   { log_not_found off; }
  location = /favicon.ico   { log_not_found off; } 
  location ~ affiliate.xml { log_not_found off; }  
  location ~ copyright.xml { log_not_found off; }  

  # convert urls with multiple slashes to a single /
  if ($request ~ /+ ) {
    rewrite ^(/)+(.*) /$2 break;
  }

  # X-Accel-Redirect
  # Don't tie up mongrels with serving the lesson zips or exes, let Nginx do it instead
  location /zips {
   internal;
   root /var/www/apps/e_learning_resource/shared/assets;
  }

  location /tmp {
   internal;
   root /;
  }

  location /mnt{
   root /;
  }

  # resource library thumbnails should be served as usual
  location ~ ^/resource_library/.*/*thumbnail.jpg$ {
    if (!-f $request_filename) {
      rewrite ^(.*)$ /images/no-thumb.png
      break;
    }
    expires 1m;
  } 

    # don't make Rails generate the dynamic routes to the dcr and swf, we'll do it here
    location ~ "lesson viewer.dcr" {
      rewrite ^(.*)$ "/assets/players/lesson viewer.dcr" break;
    }

    # we need this rule so we don't serve the older lessonviewer when the rule below is matched
    location = /assets/players/virgin_lesson_viewer/_cha5513/lessonViewer.swf {
      rewrite ^(.*)$ /assets/players/virgin_lesson_viewer/_cha5513/lessonViewer.swf break;
    }

    location ~ v6lessonViewer.swf {
      rewrite ^(.*)$ /assets/players/v6lessonViewer.swf break;
    }

    location ~ lessonViewer.swf {
      rewrite ^(.*)$ /assets/players/lessonViewer.swf break;
    }

    location ~ lgn111.dat {
      empty_gif;
    } 

  # try to get autocomplete school names from memcache first, then
  # fallback to rails when we can't
  location /schools/autocomplete { 
    set $memcached_key $uri?q=$arg_q;
    memcached_pass     127.0.0.1:11211;
    default_type       text/html;

    error_page         404 =200 @rails; # 404 not really! Hand off to rails
  }  

  location / {

    # make sure cached copies are revalidated once they're stale
    add_header Cache-Control  "public, must-revalidate, proxy-revalidate";

    # this serves Rails static files that exist without running other rewrite tests
    try_files $uri @rails;

    expires 1h;
  }

  location @rails {

    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_read_timeout 180; 

    proxy_next_upstream off;
    proxy_pass http://127.0.0.1:3000;
    expires 0d;
  }
}
share|improve this question
    
Is this not an issue that your browser doesn't want to load insecure content on a secure page? Does everything work if you don't redirect CSS & JS? Can you really not afford the resource cost of transporting CSS & JS over HTTPS? –  deed02392 Nov 12 '13 at 9:47
    
@deed02392 - yep, i guess that's the issue. I don't have a problem with the resource cost, i have a problem that i don't know how to make it work :) –  Max Williams Nov 12 '13 at 13:22
    
Well YOU can't really make it work, since it's your clients who decide whether they want to accept insecure resources on an otherwise secured connection (HTML over HTTPS). So, I think your answer needs to be - don't do this. Offer those resources over HTTPS and your problem goes away. –  deed02392 Nov 12 '13 at 16:18
    
@deed02392 - i think i've worded this badly. I personally DON'T CARE whether the stylesheets go over https or not. What i care about is making them get loaded, without triggering warnings, whether you are on an http or an https page, without going in to the app and changing all the stylesheet links to be protocol dependent, or something like that. I think it's possible to achieve this via nginx config. That's what i'm asking. –  Max Williams Nov 13 '13 at 9:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.