При копировании непосредственно из файла в автоответчик единственный способ сообщить клиенту, что что-то не так, - отправить тело неполного ответа.
Чтобы заставить сервер отправить неполное тело ответа, указать длину содержимого перед копированием тела:
w.Header().Set("Content-Length", strconv.Itoa(fileLen))
обработчик должен просто вернуться после копирования тела, ошибки или нет.
Сервер проверяет, указал ли обработчик количество байтов, указанное в заголовке длины содержимого. Если обработчик не записывал это количество байтов, сервер закрывает соединение.
Клиент может обнаружить, что соединение было закрыто до того, как все тело было прочитано.Многие HTTP-клиентские библиотеки сообщают об ошибке в этом сценарии.
Если вы забудете файл в памяти перед началом записи ответа, вы можете установить код состояния ответа, чтобы указать на ошибку. Если файл большой, вы можете не захотеть буферизировать.
Трудно, чтобы обработчик обнаружил, что io.Copy не удалось из-за ошибки чтения файла или записи ошибки клиенту. Учитывая количество возможных путей кода (разные ОС, TLS или нет, дополнительные оптимизации в io.Copy, ...), существует много потенциальных ошибок, возвращаемых из io.Copy. Ошибки могут быть даже не уникальными между ошибками файлов и клиентов.
Задание длины содержимого перед копированием файла имеет дополнительные преимущества: сервер всегда использует наиболее эффективную кодировку передачи (идентификационную кодировку), когда длина содержимого известна. В некоторых операционных системах операция io.Copy будет выполняться ядром.
Вы также должны рассмотреть возможность использования 'http.ServeFile' для возврата содержимого. Если вы не можете по какой-то причине или если это волшебство делает больше, чем вы хотите/нуждаетесь, возьмите гангстер о том, как это реализовано. Вы можете увидеть, как он справляется с ошибками и копирует эту обработку в ваш код снова, предполагая, что вы не можете просто использовать 'ServeFile' самостоятельно. –