tgoop.com/golang_interview/492
Create:
Last Update:
Last Update:
func HandleRequest(client http.Client, request *http.Request)
(*http.Response, error) {
response, err := client.Do(request)
defer response.Body.Close()
if err != nil {
return nil, err
}
}
А теперь вопрос: почему это должно работать, ведь тело всё равно закрыто, не зависимо до проверки или после?
Известно, что полное отсутствие строки
defer response.Body.Close() приводит к гарантированным проблемам, но как протестировать вышеупомянутую уязвимость?defer response.Body.Close() означает, что response.Body.Close() должно быть выполнено в точке выхода из функции. Ни о каком закрытии тела до проверки ошибки речь не идёт.Проблема здесь в другом — в случае ошибки
response может быть nil, и выполнение отложенной инструкции в ветке if err != nil {... return ...} в таком случае приведет к панике из-за обращения к нулевому указателю.panic: runtime error: invalid memory address or nil pointer dereference
А вот собственно и код:
package main
import (
"fmt"
"io"
"net/http"
"net/url"
"os"
)
func main() {
client := http.Client{}
url, _ := url.Parse("https://no.such.host")
request := &http.Request{
Method: "GET",
URL: url,
}
response, err := client.Do(request)
defer response.Body.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "Request failed: %s\n", err.Error())
}
io.Copy(os.Stdout, response.Body)
}
Как-то так
@golang_interview

