сервер echo искажает тело ответа изображения

#go

# #Вперед

Вопрос:

Пытаюсь написать простой эхо-сервер для изображений, но он искажает файл. Что происходит не так?

 package main

import (
    "fmt"
    "io"
    "net/http"
)

type FlushWriter struct {
    w io.Writer
}

func (fw *FlushWriter) Write(bytes []byte) (int, error) {
    count, e := fw.w.Write(bytes)
    fw.w.(http.Flusher).Flush()
    return count, e
}

func main() {
    http.HandleFunc("/", index)
    fmt.Println("listening on 8000")
    http.ListenAndServe(":8000", nil)
}

func index(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "image/jpeg")
    fw := amp;FlushWriter{ w: w }
    io.Copy(fw, r.Body)
}
 

И протестировать его.

 $ curl --data-binary @image.jpg -o test.jpg localhost:8000
 

Ответ №1:

Вы игнорируете ошибки в своем коде и пропускаете a ErrBodyReadAfterClose .

Вы не сможете читать с того http.Request.Body момента, как начнете писать на http.ResponseWriter

http://golang.org/pkg/net/http/#pkg-variables

Ошибка bodyreadafterclose возвращается при чтении тела запроса или ответа после закрытия тела. Обычно это происходит, когда тело считывается после того, как обработчик HTTP вызывает WriteHeader или Write в своем ResponseWriter

Вам нужно будет буферизировать изображение на сервере, прежде чем записывать его обратно.

Помимо того факта, что Go не позволит вам сделать это, даже если бы вы создали работающий обработчик, большинство клиентов привели бы к тупиковой ситуации с изображениями, превышающими сумму всех задействованных буферов. Для этого требуется клиент, который может одновременно отправлять и получать, что делают очень немногие, если таковые имеются.

Комментарии:

1. Действительно интересно. Спасибо.