diff --git a/config/nginx.conf.erb b/config/nginx.conf.erb new file mode 100644 index 00000000..2e0a0142 --- /dev/null +++ b/config/nginx.conf.erb @@ -0,0 +1,64 @@ +daemon off; +#Heroku dynos have 4 cores. +worker_processes 4; + +events { + use epoll; + accept_mutex on; + worker_connections 1024; +} + +http { + gzip on; + gzip_comp_level 2; + gzip_min_length 512; + + log_format l2met 'measure.nginx.service=$request_time request_id=$http_heroku_request_id'; + access_log logs/nginx/access.log l2met; + error_log logs/nginx/error.log; + + include mime.types; + default_type application/octet-stream; + sendfile on; + + #Must read the body in 5 seconds. + client_body_timeout 5; + + upstream app_server { + server unix:/tmp/nginx.socket fail_timeout=0; + } + + server { + listen <%= ENV["PORT"] %>; + server_name _; + keepalive_timeout 5; + + location / { + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Credentials' 'true'; + add_header 'Access-Control-Expose-Headers' 'Content-Type, Cache-Control, Expires, Etag, Last-Modified'; + + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Credentials' 'true'; + add_header 'Access-Control-Expose-Headers' 'Content-Type, Cache-Control, Expires, Etag, Last-Modified'; + + # Tell browser to cache this pre-flight info for 20 days + add_header 'Access-Control-Max-Age' 1728000; + + add_header 'Access-Control-Allow-Methods' 'HEAD, GET, POST, PATCH, PUT, DELETE, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, Accept, If-None-Match, If-Modified-Since'; + + add_header 'Content-Length' 0; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + + return 204; + } + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_redirect off; + proxy_pass http://app_server; + } + } +} diff --git a/lib/travis/api/app.rb b/lib/travis/api/app.rb index 354fc753..774ae840 100644 --- a/lib/travis/api/app.rb +++ b/lib/travis/api/app.rb @@ -31,7 +31,6 @@ module Travis::Api autoload :Helpers, 'travis/api/app/helpers' autoload :Middleware, 'travis/api/app/middleware' autoload :Responders, 'travis/api/app/responders' - autoload :Cors, 'travis/api/app/cors' Rack.autoload :SSL, 'rack/ssl' @@ -80,7 +79,6 @@ module Travis::Api [ 420, {}, ['Enhance Your Calm']] end - use Travis::Api::App::Cors use Raven::Rack if Endpoint.production? use Rack::Protection::PathTraversal use Rack::SSL if Endpoint.production? diff --git a/lib/travis/api/app/cors.rb b/lib/travis/api/app/cors.rb deleted file mode 100644 index 781efc00..00000000 --- a/lib/travis/api/app/cors.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'travis/api/app' - -class Travis::Api::App - # Implements Cross-Origin Resource Sharing. Supported by all major browsers. - # See http://www.w3.org/TR/cors/ - # - # TODO: Be smarter about origin. - class Cors < Base - before do - headers['Access-Control-Allow-Origin'] = "*" - headers['Access-Control-Allow-Credentials'] = "true" - headers['Access-Control-Expose-Headers'] = "Content-Type, Cache-Control, Expires, Etag, Last-Modified" - end - - options // do - headers['Access-Control-Allow-Methods'] = "HEAD, GET, POST, PATCH, PUT, DELETE" - headers['Access-Control-Allow-Headers'] = "Content-Type, Authorization, Accept, If-None-Match, If-Modified-Since" - end - end -end diff --git a/spec/unit/cors_spec.rb b/spec/unit/cors_spec.rb deleted file mode 100644 index 83e79914..00000000 --- a/spec/unit/cors_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'spec_helper' - -describe Travis::Api::App::Cors do - before do - mock_app do - use Travis::Api::App::Cors - get('/check_cors') { 'ok' } - end - end - - describe 'normal request' do - before { get('/check_cors').should be_ok } - - it 'sets Access-Control-Allow-Origin' do - headers['Access-Control-Allow-Origin'].should == "*" - end - - it 'sets Access-Control-Allow-Credentials' do - headers['Access-Control-Allow-Credentials'].should == "true" - end - - it 'sets Access-Control-Expose-Headers' do - headers['Access-Control-Expose-Headers'].should == "Content-Type, Cache-Control, Expires, Etag, Last-Modified" - end - end - - describe 'OPTIONS requests' do - before { options('/').should be_ok } - - it 'sets Access-Control-Allow-Origin' do - headers['Access-Control-Allow-Origin'].should == "*" - end - - it 'sets Access-Control-Allow-Credentials' do - headers['Access-Control-Allow-Credentials'].should == "true" - end - - it 'sets Access-Control-Expose-Headers' do - headers['Access-Control-Expose-Headers'].should == "Content-Type, Cache-Control, Expires, Etag, Last-Modified" - end - - it 'sets Access-Control-Allow-Methods' do - headers['Access-Control-Allow-Methods'].should == "HEAD, GET, POST, PATCH, PUT, DELETE" - end - - it 'sets Access-Control-Allow-Headers' do - headers['Access-Control-Allow-Headers'].should == "Content-Type, Authorization, Accept, If-None-Match, If-Modified-Since" - end - end -end