我需要实现处理tar.gz文件的web服务,我想知道什么是正确的方法,我需要定义什么内容类型等等。
另外,我发现很多东西都是自动处理的 - 在客户端我只是发布了一个gzip阅读器作为请求体,Accept-Encoding: gzip
标题是自动添加的,而在服务器端 - 我不需要枪杀请求体,它已被提取到tar。那有意义吗?
我可以依赖它与任何客户一样吗?
服务器
func main() {
router := mux.NewRouter().StrictSlash(true)
router.Handle("/results", dataupload.NewUploadHandler()).Methods("POST")
log.Fatal(http.ListenAndServe(*address, router))
}
者:
package dataupload
import (
"errors"
log "github.com/Sirupsen/logrus"
"io"
"net/http"
)
// UploadHandler responds to /results http request, which is the result-service rest API for uploading results
type UploadHandler struct {
uploader Uploader
}
// NewUploadHandler creates UploadHandler instance
func NewUploadHandler() *UploadHandler {
return &UploadHandler{
uploader: TarUploader{},
}
}
func (uh UploadHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
retStatus := http.StatusOK
body, err := getBody(request)
if err != nil {
retStatus = http.StatusBadRequest
log.Error("Error fetching request body. ", err)
} else {
_, err := uh.uploader.Upload(body)
}
writer.WriteHeader(retStatus)
}
func getBody(request *http.Request) (io.ReadCloser, error) {
requestBody := request.Body
if requestBody == nil {
return nil, errors.New("Empty request body")
}
var err error
// this part is commented out since somehow the body is already gunzipped - no need to extract it.
/*if strings.Contains(request.Header.Get("Accept-Encoding"), "gzip") {
requestBody, err = gzip.NewReader(requestBody)
}*/
return requestBody, err
}
客户端
func main() {
f, err := os.Open("test.tar.gz")
if err != nil {
log.Fatalf("error openning file %s", err)
}
defer f.Close()
client := new(http.Client)
reader, err := gzip.NewReader(f)
if err != nil {
log.Fatalf("error gzip file %s", err)
}
request, err := http.NewRequest("POST", "http://localhost:8080/results", reader)
_, err = client.Do(request)
if err != nil {
log.Fatalf("error uploading file %s", err)
}
}
答案 0 :(得分:1)
您为客户编写的代码只是直接发送tarfile,因为这段代码:
reader, err := gzip.NewReader(f)
...
request, err := http.NewRequest("POST", "http://localhost:8080/results", reader)
如果您直接发送了.tar.gz
文件内容,那么 需要在服务器上进行gunzip。 E.g:
request, err := http.NewRequest(..., f)
我认为这更接近您应该期望第三方客户展示的行为。
答案 1 :(得分:0)
克莱尔没有,但也许......
Golang为http客户端(和服务器)提供了非常好的支持。这是支持http2的第一种语言之一,API的设计清楚地表明了他们对快速http的关注。
这就是他们自动添加Accept-Econding: gzip
的原因。这将大大减少服务器响应的大小,然后优化传输。
但是gzip仍然是http 1中的一个选项,并不是所有客户端都会将此标头推送到您的服务器。
请注意,Content-Type
描述了您要发送的数据类型(此处为tar.gz但可以是application/json
,test/javascript
,...),{{1}描述了为传输
Go将负责透明地为您处理Accept-Encoding
,因为它负责传输数据。然后由你来处理Accept-Encoding
,因为只有你知道如何理解你收到的内容