Github上的资源都是托管在Amazon S3上的,这就意味有些时候只几K的下载速度(我这里)。

  而我有个网站引用了一些Github上的资源,所以我需要一个输入代理地址就可以直接下载目标Github资源的东西(Github的链接一定是在我放的下载链接之前,并不是想盗链,只是想提供方便而已:) ),于是想到了nginx反代。

用户:
  访问链接->不跳转直接下载
服务器:
  获取用户访问链接->302至真实下载地址->返回目标

Nginx 配置:

server{
    ......
    ......

    # 设置Nginx用的DNS地址(注①)
    resolver 8.8.8.8;
    # 可以设置一个也可以设置多个DNS服务,还可以通过一个可选的参数valid来设置过期时间
    # resolver 8.8.8.8 8.8.4.4 valid=30s;

    # 当上游服务器的响应状态码大于等于300时,可以根据响应状态码的值进行拦截错误处理
    proxy_intercept_errors on;

    # 是否允许递归使用error_page(注②)
    # recursive_error_pages on;
    
    location /soft/ {
        # 设置状态码为200 302过期时间为10分钟
        proxy_cache_valid  200 301 302 1d;
    
        # 一些代理设置
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Referer https://github.com/;
        proxy_set_header Host github.com;
        proxy_pass https://github.com/;
    
        # 如果上游服务器的响应状态码为302时,转到@error_page_302处理
        error_page 302 = @error_page_302;
    }
    
    location @error_page_302 {
        # 一些代理设置
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Referer https://github.com/;
        # 这里需要将Host设置为github-cloud.s3.amazonaws.com(注③)
        proxy_set_header Host github-cloud.s3.amazonaws.com;
        # 这里不能直接使用$upstream_http_location(注④)
        set $download $upstream_http_location;
        proxy_pass $download;
    }
}

注①:
  不设置会产生 "no resolver defined to resolve" 错误(在我这里)。

注②:
  这里Github只进行了一次302,所以可以把它关掉,如果是多次302且需要处理,则需要把它打开。

注③:
  这里如果不设置Host为github-cloud.s3.amazonaws.com的话,会返回403错误。在这里只说对于amazonaws的处理,其他网站则为其他处理方式,也许:)。

注④:
  这里如果直接使用$upstream_http_location,一定会产生500错误"invalid URL prefix in "" while sending to client",所以需要先赋值再使用。


参考链接:

  用proxy_intercept_errors和recursive_error_pages代理多次302