英文:
Send uploaded file
问题
我使用echo框架来构建REST API。
我通过HTTP请求接收文件,并且需要通过POST请求将其发送到下一个API服务。
我如何在不存储文件的情况下完成这个操作?
我尝试了以下方法,但感觉不对,因为我在响应中收到了一个错误消息"Could not parse content as FormData"。
func (h *Handler) UploadFile(c echo.Context) error {
formFile, err := c.FormFile("file")
if err != nil {
return err
}
file, err := formFile.Open()
if err != nil {
return err
}
defer file.Close()
cid, err := h.s.Upload(context.Background(), file)
if err != nil {
return err
}
return c.String(http.StatusOK, "Ok")
}
func (s *Storage) Upload(ctx context.Context, file io.Reader) (cid.Cid, error) {
req, err := http.NewRequest(http.MethodPost, s.config.endpoint+"/upload", file)
if err != nil {
return cid.Undef, err
}
req.Header.Set("accept", "application/json")
req.Header.Set("Content-Type", "multipart/form-data")
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", s.config.token))
res, err := s.config.hc.Do(req)
if err != nil {
return cid.Undef, err
}
d := json.NewDecoder(res.Body)
if res.StatusCode != 200 {
return cid.Undef, fmt.Errorf("unexpected response status: %d", res.StatusCode)
}
var out struct {
Cid string `json:"cid"`
}
err = d.Decode(&out)
if err != nil {
return cid.Undef, err
}
return cid.Parse(out.Cid)
}
英文:
I use echo framework for building REST API.
I receive file via http request and i need to send it to the next API service by post request.
How i can do this without storing file?
I've tried this way, but it doesn't feel right, because i have an error in response "Could not parse content as FormData"
func (h *Handler) UploadFile(c echo.Context) error {
formFile, err := c.FormFile("file")
if err != nil {
return err
}
file, err := formFile.Open()
if err != nil {
return err
}
defer file.Close()
cid, err := h.s.Upload(context.Background(), file)
if err != nil {
return err
}
return c.String(http.StatusOK, "Ok")
}
func (s *Storage) Upload(ctx context.Context, file io.Reader) (cid.Cid, error) {
req, err := http.NewRequest(http.MethodPost, s.config.endpoint+"/upload", file)
if err != nil {
return cid.Undef, err
}
req.Header.Set("accept", "application/json")
req.Header.Set("Content-Type", "multipart/form-data")
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", s.config.token))
res, err := s.config.hc.Do(req)
if err != nil {
return cid.Undef, err
}
d := json.NewDecoder(res.Body)
if res.StatusCode != 200 {
return cid.Undef, fmt.Errorf("unexpected response status: %d", res.StatusCode)
}
var out struct {
Cid string `json:"cid"`
}
err = d.Decode(&out)
if err != nil {
return cid.Undef, err
}
return cid.Parse(out.Cid)
}
答案1
得分: 1
这里 是解决方案。
感谢 Vlad Vladov。
func (s *Storage) Upload(ctx context.Context, file multipart.File, fileHeader *multipart.FileHeader) (cid.Cid, error) {
rCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
buf := new(bytes.Buffer)
writer := multipart.NewWriter(buf)
part, err := writer.CreateFormFile("file", fileHeader.Filename)
if err != nil {
return cid.Undef, err
}
b, err := ioutil.ReadAll(file)
if err != nil {
return cid.Undef, err
}
part.Write(b)
writer.Close()
req, err := http.NewRequestWithContext(rCtx, http.MethodPost, s.config.endpoint+"/upload", buf)
if err != nil {
return cid.Undef, err
}
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", s.config.token))
req.Header.Set("X-Client", "web3.storage/go")
res, err := s.config.hc.Do(req)
if err != nil {
return cid.Undef, err
}
d := json.NewDecoder(res.Body)
if res.StatusCode != 200 {
var out responseError
d.Decode(&out)
log.Error(out)
return cid.Undef, fmt.Errorf("unexpected response status: %d", res.StatusCode)
}
var out struct {
Cid string `json:"cid"`
}
err = d.Decode(&out)
if err != nil {
return cid.Undef, err
}
return cid.Parse(out.Cid)
}
英文:
Here is the solution.
Thanks Vlad Vladov.
func (s *Storage) Upload(ctx context.Context, file multipart.File, fileHeader *multipart.FileHeader) (cid.Cid, error) {
rCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
buf := new(bytes.Buffer)
writer := multipart.NewWriter(buf)
part, err := writer.CreateFormFile("file", fileHeader.Filename)
if err != nil {
return cid.Undef, err
}
b, err := ioutil.ReadAll(file)
if err != nil {
return cid.Undef, err
}
part.Write(b)
writer.Close()
req, err := http.NewRequestWithContext(rCtx, http.MethodPost, s.config.endpoint+"/upload", buf)
if err != nil {
return cid.Undef, err
}
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", s.config.token))
req.Header.Set("X-Client", "web3.storage/go")
res, err := s.config.hc.Do(req)
if err != nil {
return cid.Undef, err
}
d := json.NewDecoder(res.Body)
if res.StatusCode != 200 {
var out responseError
d.Decode(&out)
log.Error(out)
return cid.Undef, fmt.Errorf("unexpected response status: %d", res.StatusCode)
}
var out struct {
Cid string `json:"cid"`
}
err = d.Decode(&out)
if err != nil {
return cid.Undef, err
}
return cid.Parse(out.Cid)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论