Icap | Чанковое чтение тела http.response вызывает закрытие соединения
Я использую оболочку go-icap стандартного http-сервера для создания своего рода прокси-сервера: для извлечения всех файлов, загружаемых клиентами через http.
Итак, что я делаю, так это просто обрабатываю RESAPMOD от icaps, сохраняя тело ответа и возвращая ответ обратно.
Что-то вроде этого:
func respModHandler(w icap.ResponseWriter, req *icap.Request) {
h := w.Header()
h.Set("ISTag", ISTag)
h.Set("Service", "Cappuccino respmod")
switch req.Method {
case "OPTIONS":
h := w.Header()
h.Set("Methods", "RESPMOD")
h.Set("Allow", "204")
h.Set("Preview", "1024")
h.Set("Transfer-Preview", "*")
w.WriteHeader(200, nil, false)
case "RESPMOD":
switch req.Response.StatusCode {
case 200:
if downloadable(req.Response) {
body, readErr := ioutil.ReadAll(response.Body)
w.WriteHeader(req.Response.StatusCode, req.Response, true)
w.write(body)
Info.Println(formatRequest(req.Request))
Info.Println(formatResponse(req.Response))
go save(buf)
} else {
w.WriteHeader(204, nil, false)
}
case 206:
...
default:
w.WriteHeader(204, nil, false)
}
default:
w.WriteHeader(405, nil, false)
fmt.Println("Invalid request method")
}
}
Но такой подход заставляет клиента ждать меня, пока я не закончу с чтением всего тела.
Затем я решил прочитать небольшие куски из тела в некоторый буфер и немедленно отправить их обратно:
if downloadable(req.Response) {
w.WriteHeader(req.Response.StatusCode, req.Response, true)
buf := make([]byte, 0, req.Response.ContentLength)
for {
last_index := 0
n, err := req.Response.Body.Read(buf)
fmt.Println(n)
if n == 0 {
if err != nil {
Error.Println(err)
}
break
}
last_index = n
Info.Println(buf)
w.Write(buf[last_index:n])
}
И этот код не работает из-за read tcp 172.18.0.3:1344->172.18.0.2:38388: read: connection reset by peer
после прочтения первых 1024 байта из тела.
Я уверен, что не я закрываю соединение, но все же я понятия не имею, что происходит и как это исправить.