Nginx MP3 下载 206 部分内容 HTTP 响应

Nginx MP3 Download 206 Partial Content HTTP Response

全部:

我可以通过 Nginx (1.19.2) 成功浏览 MP3 网站并播放 MP3 流。

但是,当我尝试通过 Nginx 下载 MP3 时,我收到了 206 部分内容 HTTP 响应:

192.168.0.154 - - [07/Nov/2020:10:25:22 +0000] "GET music.mp3 HTTP/1.1" 206 1982193 "http://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38"

A Client-Side 数据包跟踪显示带有来自 Nginx 的 RST 的 206 部分内容 HTTP 响应:

3390    42.119998   192.168.0.154   192.168.0.2 TCP 54  61978 → 80 [ACK] Seq=526 Ack=2293125 Win=1629440 Len=0
3391    42.120434   192.168.0.2 192.168.0.154   HTTP    347 HTTP/1.1 206 Partial Content  (audio/mpeg)
3392    42.120449   192.168.0.154   192.168.0.2 TCP 54  61978 → 80 [ACK] Seq=526 Ack=2293418 Win=1629184 Len=0
4375    69.116574   192.168.0.154   192.168.0.2 TCP 54  [TCP Window Update] 61978 → 80 [ACK] Seq=526 Ack=2293418 Win=4219392 Len=0
4984    87.122995   192.168.0.154   192.168.0.2 TCP 55  [TCP Keep-Alive] 61978 → 80 [ACK] Seq=525 Ack=2293418 Win=4219392 Len=1
4985    87.123324   192.168.0.2 192.168.0.154   TCP 66  [TCP Keep-Alive ACK] 80 → 61978 [ACK] Seq=2293418 Ack=526 Win=6912 Len=0 SLE=525 SRE=526
5761    117.117822  192.168.0.2 192.168.0.154   TCP 60  80 → 61978 [FIN, ACK] Seq=2293418 Ack=526 Win=6912 Len=0
5762    117.117911  192.168.0.154   192.168.0.2 TCP 54  61978 → 80 [ACK] Seq=526 Ack=2293419 Win=4219392 Len=0
7291    162.122574  192.168.0.154   192.168.0.2 TCP 55  [TCP Keep-Alive] 61978 → 80 [ACK] Seq=525 Ack=2293419 Win=4219392 Len=1
7292    162.123048  192.168.0.2 192.168.0.154   TCP 60  [TCP Keep-Alive ACK] 80 → 61978 [ACK] Seq=2293419 Ack=526 Win=6912 Len=0
7591    173.888730  192.168.0.154   192.168.0.2 TCP 54  61978 → 80 [FIN, ACK] Seq=526 Ack=2293419 Win=4219392 Len=0
7594    173.889906  192.168.0.2 192.168.0.154   TCP 60  80 → 61978 [RST] Seq=2293419 Win=0 Len=0

我尝试了几种不同的浏览器(即 Chrome、Edge 等),但都遇到了同样的问题。

不使用Nginx直接浏览下载成功

知道为什么使用 Nginx 下载 MP3 失败吗?

非常感谢。

加里

编辑:

我发现失败的请求正在对 Nginx 的端口 443 进行后续的异步 AJAX 调用,其中连接失败并显示针对我的 self-signed 证书的“证书未知”。

Click-Link方法:

GET http://example.com/ajax/inc/1488440 HTTP/1.1
Host: example.com
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36
X-Requested-With: XMLHttpRequest
Referer: http://example.com/mp3/search?keywords=california+gurls
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: PHPSESSID=k6o4mq4np28bdr6n2g2pbgq190; zvAuth=1; zvLang=0; ZvcurrentVolume=100; nua=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F86.0.4240.75%20Safari%2F537.36; asus_token=81G3BJcZjrt06SpsxUrh; z1_n=5

HTTP/1.1 200 OK
Server: nginx/1.19.2
Date: Sun, 08 Nov 2020 07:38:33 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=d3d5b5d9e0cbf7321ca040f0b126eb6631604821113; expires=Tue, 08-Dec-20 07:38:33 GMT; path=/; domain=.example.com; HttpOnly; SameSite=Lax; Secure
Vary: Accept-Encoding
CF-Cache-Status: DYNAMIC
cf-request-id: 064863f2fb00000b786e0c5000000001
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=uoLAfVO2XqMqj6FJI%2BwyHFz52QFckDptxRfYjClxWfJvGUxnyAlsIR5Im37T5tC2j%2Big2WIgIfXajj0EWpPBMCxdTtC5ZA%3D%3D"}],"group":"cf-nel","max_age":604800}
NEL: {"report_to":"cf-nel","max_age":604800}
CF-RAY: 5eeda297ffb90b78-AMS
Content-Encoding: gzip
CONNECT example.com:443 HTTP/1.1
Host: example.com:443
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36

334 7.593054    192.168.0.154   192.168.0.2 TLSv1.2 61  Alert (Level: Fatal, Description: Certificate Unknown)

我想通过 Nginx 的端口 80 强制 AJAX 连接。是否可以为 :443 评估主机 header,如果存在,则将其更改为 :80?如果是这样,完成此任务的最有效方法是什么?

顺便说一句...我已经实现了 proxy_redirect https:// http://;指令,它适用于 URL 但不适用于主机 header.

感谢您的帮助。

恭敬地,

加里

编辑:

我在 copy/paste AJAX URL 到我的浏览器 address-bar 时取得了更多进展,成功发出了 MP3 下载请求并且MP3 已下载(与前面示例相反,当我点击 MP3 下载 link)。

有趣的是,copy/paste 方法产生初始 302 响应,而 click-link 方法产生 200 响应。

Copy/Paste方法:

GET http://example.com/ajax/inc/283544 HTTP/1.1
Host: example.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: PHPSESSID=k6o4mq4np28bdr6n2g2pbgq190; zvAuth=1; zvLang=0; ZvcurrentVolume=100; nua=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F86.0.4240.75%20Safari%2F537.36; asus_token=81G3BJcZjrt06SpsxUrh; _zvBoobs_=%2F%2F_-%29

HTTP/1.1 302 Found
Server: nginx/1.19.2
Date: Sun, 08 Nov 2020 14:27:53 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Set-Cookie: __cfduid=d2f42248bc953328459ea277d77ee62671604845673; expires=Tue, 08-Dec-20 14:27:53 GMT; path=/; domain=.example.com; HttpOnly; SameSite=Lax; Secure
Location: http://example.com/download/283544
CF-Cache-Status: DYNAMIC
cf-request-id: 0649dab4e200000b6bce8a6000000001
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=SRYrhqPuwCUwe1MPbJ4RGW%2F8yqt4t8UD19zHwUrcNqX94%2FD8VZ6EW1vl2dogVCCaFkeDh3%2BCwogueN4i3K6Gc5SMenGqRg%3D%3D"}],"group":"cf-nel","max_age":604800}
NEL: {"report_to":"cf-nel","max_age":604800}
CF-RAY: 5eeffa349c0d0b6b-AMS
Content-Length: 0
GET http://example.com/download/283544 HTTP/1.1
Host: example.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: PHPSESSID=k6o4mq4np28bdr6n2g2pbgq190; zvAuth=1; zvLang=0; ZvcurrentVolume=100; nua=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F86.0.4240.75%20Safari%2F537.36; asus_token=81G3BJcZjrt06SpsxUrh; _zvBoobs_=%2F%2F_-%29

HTTP/1.1 307 Temporary Redirect
Server: nginx/1.19.2
Date: Sun, 08 Nov 2020 14:27:54 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Set-Cookie: __cfduid=db70304f5ae41939e5d51647d5b3dcc261604845674; expires=Tue, 08-Dec-20 14:27:54 GMT; path=/; domain=.example.com; HttpOnly; SameSite=Lax; Secure
X-Robots-Tag: noindex, nofollow
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Set-Cookie: _zvBoobs_=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/
Set-Cookie: _zvBoobs_=%2F%2F_-%29; expires=Mon, 09-Nov-2020 02:27:54 GMT; Max-Age=43200; path=/; domain=.example.com
Location: http://st1.example.com/music/9/68/katy_perry_feat._snoop_dogg_-_california_gurls_(mstrkrft_remix_radio)_(zvukoff.ru).mp3?download=force
CF-Cache-Status: DYNAMIC
cf-request-id: 0649dab7760000faa08984d000000001
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=0RmfU9QT43xEgj9rH4LUrpCFAVXYh6gMubnObVJWjNxnSn4CJl5zkJVoeoD6uoEOkvVzgUOlwy%2F7KbFbat6NF8Qj0b64Ig%3D%3D"}],"group":"cf-nel","max_age":604800}
NEL: {"report_to":"cf-nel","max_age":604800}
CF-RAY: 5eeffa38785bfaa0-AMS
Content-Length: 0
GET http://st1.example.com/music/9/68/katy_perry_feat._snoop_dogg_-_california_gurls_(mstrkrft_remix_radio)_(zvukoff.ru).mp3?download=force HTTP/1.1
Host: st1.example.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: zvAuth=1; zvLang=0; _zvBoobs_=%2F%2F_-%29

HTTP/1.1 200 OK
Server: nginx/1.19.2
Date: Sun, 08 Nov 2020 14:28:00 GMT
Content-Type: application/force-download
Content-Length: 6634727
Connection: keep-alive
Last-Modified: Thu, 26 Jul 2012 13:19:08 GMT
ETag: "501143cc-653ce7"
Content-Disposition: attachment; filename=katy_perry_feat._snoop_dogg_-_california_gurls_(mstrkrft_remix_radio)_(zvukoff.ru).mp3
Accept-Ranges: bytes

Nginx 访问日志(Click-Link 方法 - 失败):

192.168.0.154 - - [08/Nov/2020:14:27:00 +0000] "GET /ajax/inc/283544 HTTP/1.1" 200 94 "http://example.com/mp3/search?keywords=california+gurls" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38"

Nginx 访问日志(Copy/Paste 方法 - 成功):

192.168.0.154 - - [08/Nov/2020:14:27:53 +0000] "GET /ajax/inc/283544 HTTP/1.1" 302 5 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"
192.168.0.154 - - [08/Nov/2020:14:27:54 +0000] "GET /download/283544 HTTP/1.1" 307 5 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"
192.168.0.154 - - [08/Nov/2020:14:28:31 +0000] "GET /music/9/68/katy_perry_feat._snoop_dogg_-_california_gurls_(mstrkrft_remix_radio)_(zvukoff.ru).mp3?download=force HTTP/1.1" 200 6634727 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"

我可以使用额外的眼睛来查看 requests/responses 和 nginx 访问日志,以确认我是否遗漏了什么。

Click-Link 和 Copy/Paste 方法都通过 Nginx 反向代理。

非常感谢。

加里

编辑:

我在 Click-Link 200 HTTP 响应的 body 中找到以下内容:

{"url":"https:\/\/example.com\/download\/2770587","isSuccess":1}

对我来说,这似乎是 Nginx 不知道的 Javascript 重定向,其中 https 协议没有被重写为 http。

Nginx 是否可以评估响应的 body 并重写给定的字符串(即 https => http)?

我想我也许可以使用 GreaseMonkey 或类似工具来验证我的理论。

再次感谢您的时间和关注。

恭敬地,

加里

全部:

就是这样!随后的异步 AJAX 调用使用 Javascript 重定向进行响应,该重定向已使用 Nginx 的 sub_filter 指令进行补救。

        location / {
            resolver 103.86.99.100;
            proxy_bind $server_addr;
            proxy_pass https://$host$request_uri;
            proxy_redirect https:// http://;
            proxy_set_header Accept-Encoding ""; # Needed by sub_filter to disable gzip compression
            sub_filter_types text/javascript text/css text/xml;
            sub_filter 'https:' 'http:';
            sub_filter_once off;
        }

禁用 gzip 压缩、添加 sub_filter_types text/javascript 和创建 sub_filter 'https:' 'http:' 的组合重写了 Javascript 重定向的协议。

{"url":"http:\/\/z1.fm\/download\/3298838","isSuccess":1}

然后,只需单击 AJAX link,我就可以下载 MP3。