英文:
Golang - SignatureDoesNotMatch error from S3 when attempting GET request
问题
我正在尝试从http://freemusicarchive.org下载一首音轨。一般来说,你可以通过在音轨URL后面添加/download来下载文件,这将返回一个重定向到S3上资源的链接。
例如,尝试点击这个链接:
http://freemusicarchive.org//music//Zola_Jesus//Live_at_WFMU_on_Scott_McDowells_Show_1709//Odessa/download
为了查看重定向,将该链接放在这里:
http://www.wheregoes.com/retracer.php
我可以通过以下代码获取重定向的位置:
req, err := http.NewRequest("GET", url, nil)
errHndlr(err)
transport := http.Transport{}
resp, err := transport.RoundTrip(req)
defer resp.Body.Close()
errHndlr(err)
redirect := resp.Header.Get("Location")
我已经通过将重定向链接打印到控制台并复制粘贴到浏览器中验证了重定向链接的有效性,但是当我在相同的URL上调用http.Get时,我从AWS得到一个"SignatureDoesNotMatch"错误。
如果有人能够提供关于这里出了什么问题的见解,我将非常感激。
英文:
I am attempting to download a track from http://freemusicarchive.org. Generally speaking, you can download a file by appending /download to the track URL, which responds with a redirect to the asset on S3.
For example, try this link:
http://freemusicarchive.org//music//Zola_Jesus//Live_at_WFMU_on_Scott_McDowells_Show_1709//Odessa/download
To see the redirect, put that link here:
http://www.wheregoes.com/retracer.php
I am able to get the redirect location with code that looks like this:
req, err := http.NewRequest("GET", url, nil)
errHndlr(err)
transport := http.Transport{}
resp, err := transport.RoundTrip(req)
defer resp.Body.Close()
errHndlr(err)
redirect := resp.Header.Get("Location")
I have verified the redirect link works by printing it to the console and copy/pasting it into my browser, but when I call http.Get on the same url, I get a "SignatureDoesNotMatch" error from AWS.
If anyone can offer insight as to what is going wrong here, I would greatly appreciate it.
答案1
得分: 5
搞定了。在处理URL时,Go会将Unicode解析回纯文本。我需要使用request.URL.Opaque
。
更多信息请参考这里:https://stackoverflow.com/a/17322831/733860
> 这个问题与Unicode有关。在我的命令中有一个%2F(在我的原始问题中没有显示),Go将其转换为/,而实际上应该保留为%2F(cURL正确地保留为%2F)。将%2F更改为%252F解决了这个问题。
>
> 另外,当创建一个新的HTTP请求时,Go会将你的Unicode解析回纯文本,所以如果你在提交给HTTP请求初始化器的URL中有%3D,它会将其转换为=。我原以为一个明显的解决方案是在URL中放入%253D,但显然Go中存在一个bug,它会将%3D转换为=,但不会将%25转换为%。我不得不使用Opaque URL请求(request.Url.Opaque
)来解决这个问题。
英文:
Figured it out. Go parses unicode back to plain-text when processing a url. I needed to use request.URL.Opaque.
More info here: https://stackoverflow.com/a/17322831/733860
> The issue was unicode-related. There was a %2F in my command (not displayed in my original question) that Go was converting to / that should have been left as %2F (cURL was properly leaving it as %2F). Changing the %2F to %252F fixed the issue.
>
> It also appears that when creating a new HTTP request Go will parse your unicode back to plain text, so if you have %3D in the URL you submit to the HTTP request initializer it will convert it to =. I thought an obvious solution would be to put %253D into the URL but apparently there is a bug in Go that will convert %3D to = but NOT %25 to %. I had to use the Opaque URL request (request.Url.Opaque) to get around this.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论