<commit_before>package httpzip

import (
	"compress/flate"
	"compress/gzip"
	"io"
	"net/http"
)

// NewRequestHandler return handler, which transparently decodes http requests
// which are using either gzip or deflate algorithm. Request should have
// Content-Encoding header set to the appropriate value. If content encoding is
// recognised, request body will be transparently uncompressed in the passed
// handler h and Content-Encoding header removed. No decoding errors are
// handled by the wrapper and they're all available through the regular request
// body read call.
//
// If content encoding is outside of the supported types, the request will be
// passed unaltered.
func NewRequestHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// New reader handling uncompression
		var nr io.ReadCloser

		switch r.Header.Get("Content-Encoding") {
		case "gzip":
			nr = newErrReader(gzip.NewReader(r.Body))
		case "deflate":
			nr = flate.NewReader(r.Body)
		}

		if nr != nil {
			r.Body = nr
			r.Header.Del("Content-Encoding")
		}

		// Pass to the wrapped handler
		h.ServeHTTP(w, r)
	})
}

// errReader reports error (if any) with the first call to Read
type errReader struct {
	io.ReadCloser
	err error
}

func newErrReader(r io.ReadCloser, err error) *errReader {
	return &errReader{r, err}
}

func (r *errReader) Read(p []byte) (int, error) {
	if r.err != nil {
		return 0, r.err
	}
	return r.ReadCloser.Read(p)
}<commit_msg>Fix panic on calling Close after gzip header error<commit_after>package httpzip

import (
	"compress/flate"
	"compress/gzip"
	"io"
	"io/ioutil"
	"net/http"
)

// NewRequestHandler return handler, which transparently decodes http requests
// which are using either gzip or deflate algorithm. Request should have
// Content-Encoding header set to the appropriate value. If content encoding is
// recognised, request body will be transparently uncompressed in the passed
// handler h and Content-Encoding header removed. No decoding errors are
// handled by the wrapper and they're all available through the regular request
// body read call.
//
// If content encoding is outside of the supported types, the request will be
// passed unaltered.
func NewRequestHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// New reader handling uncompression
		var nr io.ReadCloser

		switch r.Header.Get("Content-Encoding") {
		case "gzip":
			if r, err := gzip.NewReader(r.Body); err == nil {
				nr = r
			} else {
				nr = ioutil.NopCloser(&errReader{err})
			}
		case "deflate":
			nr = flate.NewReader(r.Body)
		}

		if nr != nil {
			r.Body = nr
			r.Header.Del("Content-Encoding")
		}

		// Pass to the wrapped handler
		h.ServeHTTP(w, r)
	})
}

// errReader reports error on every Read
type errReader struct {
	err error
}

func (r *errReader) Read(p []byte) (int, error) {
	return 0, r.err
}
{'fraction_non_alphanumeric': 0.10278154681139756, 'fraction_numerical': 0.0006784260515603799, 'mean_word_length': 3.622257053291536, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3563983', 'n_tokens_mistral': 979, 'n_tokens_neox': 914, 'n_words': 332}