package main import ( "io" "log" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { go func() { resp, err := http.Get("[link] if err != nil { log.Println("request error:", err) return } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) w.Write(body) }() } func main() { http.HandleFunc("/proxy", handler) log.Fatal(http.ListenAndServe(":8080", nil)) }
Answer from AI
sobes.tech AI
В представленном коде есть ошибка: обработчик HTTP-запроса запускает горутину, которая выполняет HTTP-запрос и пишет ответ в http.ResponseWriter асинхронно. Это неправильно, потому что ResponseWriter не потокобезопасен и жизненный цикл запроса ограничен функцией обработчика.
Когда функция handler завершится, соединение с клиентом может быть закрыто, и попытка записи в w из горутины приведёт к панике или ошибке.
Правильный подход — выполнять HTTP-запрос синхронно в обработчике и только после получения ответа писать в w:
func handler(w http.ResponseWriter, r *http.Request) {
resp, err := http.Get("http://example.com")
if err != nil {
log.Println("request error:", err)
w.WriteHeader(http.StatusBadGateway)
return
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Println("read error:", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Write(body)
}
Если нужно выполнять запрос асинхронно, то надо использовать другие механизмы, например, WebSocket, или сохранять результат в кэш и отдавать клиенту позже, но напрямую писать в ResponseWriter из горутины нельзя.