Sobes.tech
Back to questions
Middle+
9

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)) }

Companies where asked
MAX LTD Group

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 из горутины нельзя.