user www-data;
worker_processes 4;

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

events {
  worker_connections 1024;
}

http {
  include /etc/nginx/mime.types;

  access_log off;

  default_type application/octet-stream;

  sendfile on;
  tcp_nodelay on;
  tcp_nopush off;

  reset_timedout_connection on;

  server_tokens off;

  # Cache 100G worth of packages for up to 1 month
  proxy_cache_path /var/lib/nginx/pypi levels=1:2 keys_zone=pypi:16m inactive=1M max_size=100G;

  # Multiple server definitions makes nginx retry on errors
  upstream pypi {
    server pypi.python.org:443;
    server pypi.python.org:443;
    keepalive 16;
  }

  gzip on;
  gzip_types application/json text/css text/javascript;
  gzip_proxied any;
  gzip_vary on;

  server {
    listen 80 default_server;
    server_name pypi.example.com;

    root /var/www;

    proxy_cache pypi;
    proxy_cache_key $uri;
    proxy_cache_lock on;
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;

    proxy_http_version 1.1;
    proxy_set_header Host pypi.python.org;
    proxy_set_header Connection "";
    proxy_set_header Accept-Encoding "";

    # Rewrite any http redirects to use relative to proxy
    proxy_redirect ~https?://pypi.python.org(.*) $1;

    location / {
      # Replace any reference to actual pypi w/ caching proxy
      sub_filter 'https://pypi.python.org' $scheme://$host;
      sub_filter_once off;
      proxy_pass https://pypi;
      proxy_cache off;
    }

    location ^~ /simple {
      # Make sure URI ends with /
      rewrite ^(.*[^/])$ $1/ break;

      add_header X-Cache2 $upstream_cache_status;

      proxy_cache_valid any 5m;

      proxy_pass https://pypi;
    }

    location ^~ /packages {
      add_header X-Cache2 $upstream_cache_status;

      proxy_cache_valid any 1M;

      proxy_pass https://pypi;
    }
  }
}
