英文:
Why am I not able to read the request body when I construct a HTTP request from a dump?
问题
我正在尝试使用以下代码在Lambda中将SQS事件构建为HTTP请求。我能够获取到头部信息,但请求体为空。如果传入的请求有一个Content-Length
头部,那么请求体中会有一些内容,但该请求是由外部系统生成的,不带有该头部。我做错了什么?
package main
import (
"bufio"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
)
func main() {
sqsEvent := `{
"Type" : "Notification",
"MessageId" : "d66493a6-7e62-5104-9e8f-c8de60b5fb85",
"TopicArn" : "arn:aws:sns:us-east-1:1234567890:msgbridge-my-sns-topic",
"Message" : "POST /endpoint HTTP/1.1\r\nAccept: */*\r\nAccept-Encoding: deflate, gzip\r\nContent-Type: application/json\r\nX-Amzn-Trace-Id: Root=1-62fe1c96-098f3f26680ffa54742d9aa2\r\nX-Forwarded-For: 173.252.127.12\r\nX-Forwarded-Port: 443\r\nX-Forwarded-Proto: https\r\n\r\n{\"status\":\"ok\"}",
"Timestamp" : "2022-08-18T11:03:51.069Z",
"SignatureVersion" : "1",
"Signature" : "s+M8QtMEYC5XfBIFIokrI8+ChHSTAzp7i+/1+hSkVQx/0vzQA7g6GQle5jrYPclrob2oIWy7FeEs+EGoKPZQ8YuxdZf6xrGIpV7qyVUcrLWpxm0HyYViJ3q/qbcjZPWmVxaYrOV30m1CBkpDcwYvFGHl0neFefkOpybZAdRgEXkbChAlanAiIgh91Sm1IWD4J1Doth1UF84afMov9TfSZMSgGQ+e7LCnNMtcSpUT34aDQDUxOB51NsLd9+tmYSzdqIanUQItcaB2zGJFp/yk2u6pJUjLJ1oybh3olgjhrmVQrO8mBTOVbMH3i/TyZUl1aogikhe+3hKQoDoCuMc/KQ=="
}`
var req struct {
Message string `json:"Message"`
}
if err := json.Unmarshal([]byte(sqsEvent), &req); err != nil {
fmt.Printf("error unmarshalling; error=%s\n", err)
return
}
hreq, err := http.ReadRequest(bufio.NewReader(strings.NewReader(req.Message)))
if err != nil {
fmt.Printf("failed to convert message body to http request, error=%s\n", err)
return
}
fmt.Printf("X-Amzn-Trace-Id=%s\n", hreq.Header.Get("X-Amzn-Trace-Id"))
body, err := ioutil.ReadAll(hreq.Body)
if err != nil {
fmt.Printf("failed to read body, error=%s\n", err)
return
}
fmt.Printf("Body = %s\n", string(body))
}
输出:
> go run .
X-Amzn-Trace-Id=Root=1-62fe1c96-098f3f26680ffa54742d9aa2
Body =
>
请注意,我只会返回翻译好的部分,不会回答关于翻译的问题。
英文:
I am trying to construct a HTTP request out of a SQS event within a Lambda using the code below. I am able to get the headers but the request body is empty. If the incoming request has a Content-Length
header, then there is some content in the body but the request is generated from an external system and it doesn't come with the header. What am I doing wrong?
package main
import (
"bufio"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
)
func main() {
sqsEvent := `{
"Type" : "Notification",
"MessageId" : "d66493a6-7e62-5104-9e8f-c8de60b5fb85",
"TopicArn" : "arn:aws:sns:us-east-1:1234567890:msgbridge-my-sns-topic",
"Message" : "POST /endpoint HTTP/1.1\r\nAccept: */*\r\nAccept-Encoding: deflate, gzip\r\nContent-Type: application/json\r\nX-Amzn-Trace-Id: Root=1-62fe1c96-098f3f26680ffa54742d9aa2\r\nX-Forwarded-For: 173.252.127.12\r\nX-Forwarded-Port: 443\r\nX-Forwarded-Proto: https\r\n\r\n{\"status\":\"ok\"}",
"Timestamp" : "2022-08-18T11:03:51.069Z",
"SignatureVersion" : "1",
"Signature" : "s+M8QtMEYC5XfBIFIokrI8+ChHSTAzp7i+/1+hSkVQx/0vzQA7g6GQle5jrYPclrob2oIWy7FeEs+EGoKPZQ8YuxdZf6xrGIpV7qyVUcrLWpxm0HyYViJ3q/qbcjZPWmVxaYrOV30m1CBkpDcwYvFGHl0neFefkOpybZAdRgEXkbChAlanAiIgh91Sm1IWD4J1Doth1UF84afMov9TfSZMSgGQ+e7LCnNMtcSpUT34aDQDUxOB51NsLd9+tmYSzdqIanUQItcaB2zGJFp/yk2u6pJUjLJ1oybh3olgjhrmVQrO8mBTOVbMH3i/TyZUl1aogikhe+3hKQoDoCuMc/KQ=="
}`
var req struct {
Message string `json:"Message"`
}
if err := json.Unmarshal([]byte(sqsEvent), &req); err != nil {
fmt.Printf("error unmarshalling; error=%s\n", err)
return
}
hreq, err := http.ReadRequest(bufio.NewReader(strings.NewReader(req.Message)))
if err != nil {
fmt.Printf("failed to convert message body to http request, error=%s\n", err)
return
}
fmt.Printf("X-Amzn-Trace-Id=%s\n", hreq.Header.Get("X-Amzn-Trace-Id"))
body, err := ioutil.ReadAll(hreq.Body)
if err != nil {
fmt.Printf("failed to read body, error=%s\n", err)
return
}
fmt.Printf("Body = %s\n", string(body))
}
Output:
> go run .
X-Amzn-Trace-Id=Root=1-62fe1c96-098f3f26680ffa54742d9aa2
Body =
>
答案1
得分: 1
在这里你没有太多可以做的。带有非空主体的HTTP POST请求需要设置Content-Length(或分块传输编码)。如果源系统没有提供有效的HTTP请求,你需要在尝试读取请求之前确定内容长度并设置它。例如,可以像这样进行操作:
i := strings.Index(req.Message, "\r\n\r\n")
cl := len(req.Message) - i - 4
req.Message = fmt.Sprintf("%s\r\nContent-Length: %d%s",
req.Message[:i], cl, req.Message[i:])
英文:
There is not much you can do here. HTTP POST requests with a non-empty body require a set Content-Length (or a chunked Transfer-Encoding). If the source system doesn't provide you a valid HTTP request you will have to determine the content length and set it before trying to read the request. E.g. like
i := strings.Index(req.Message, "\r\n\r\n")
cl := len(req.Message) - i - 4
req.Message = fmt.Sprintf("%s\r\nContent-Length: %d%s",
req.Message[:i], cl, req.Message[i:])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论