Repository: caddyserver/caddy
File: modules/caddyhttp/reverseproxy/fastcgi/client.go (Go)

Code before:
var pad [maxPad]byte

// client implements a FastCGI client, which is a standard for
// interfacing external applications with Web servers.
type client struct {
	rwc net.Conn
	// keepAlive bool // TODO: implement
	reqID  uint16
	stderr bool
	logger *zap.Logger
}

// Do made the request and returns a io.Reader that translates the data read
// from fcgi responder out of fcgi packet before returning it.
func (c *client) Do(p map[string]string, req io.Reader) (r io.Reader, err error) {
	// check for CONTENT_LENGTH, since the lack of it or wrong value will cause the backend to hang
	if clStr, ok := p["CONTENT_LENGTH"]; !ok {
		return nil, caddyhttp.Error(http.StatusLengthRequired, nil)
	} else {
		cl, err := strconv.ParseInt(clStr, 10, 64)
		// stdlib won't return a negative Content-Length, but we check just in case,
		// the most likely cause is from a missing content length, which is -1
		if err != nil || cl < 0 {
			return nil, caddyhttp.Error(http.StatusLengthRequired, err)
		}
	}

	writer := &streamWriter{c: c}
	writer.buf = bufPool.Get().(*bytes.Buffer)
	writer.buf.Reset()
	defer bufPool.Put(writer.buf)

	err = writer.writeBeginRequest(uint16(Responder), 0)
	if err != nil {
		return
	}

	writer.recType = Params
	err = writer.writePairs(p)
	if err != nil {
		return
	}

	writer.recType = Stdin
	if req != nil {
		_, err = io.Copy(writer, req)
		if err != nil {
			return nil, err
		}
	}
	err = writer.FlushStream()

Review comment (refactor):
```suggestion
	} else if _, err := strconv.ParseUint(clStr, 10, 64); err != nil {
		// stdlib won't return a negative Content-Length, but we check just in case,
		// the most likely cause is from a missing content length, which is -1
		return nil, caddyhttp.Error(http.StatusLengthRequired, err)
	}
```

ParseUint will allow to simplify the code a bit

Code after:
var pad [maxPad]byte

// client implements a FastCGI client, which is a standard for
// interfacing external applications with Web servers.
type client struct {
	rwc net.Conn
	// keepAlive bool // TODO: implement
	reqID  uint16
	stderr bool
	logger *zap.Logger
}

// Do made the request and returns a io.Reader that translates the data read
// from fcgi responder out of fcgi packet before returning it.
func (c *client) Do(p map[string]string, req io.Reader) (r io.Reader, err error) {
	// check for CONTENT_LENGTH, since the lack of it or wrong value will cause the backend to hang
	if clStr, ok := p["CONTENT_LENGTH"]; !ok {
		return nil, caddyhttp.Error(http.StatusLengthRequired, nil)
	} else if _, err := strconv.ParseUint(clStr, 10, 64); err != nil {
		// stdlib won't return a negative Content-Length, but we check just in case,
		// the most likely cause is from a missing content length, which is -1
		return nil, caddyhttp.Error(http.StatusLengthRequired, err)
	}

	writer := &streamWriter{c: c}
	writer.buf = bufPool.Get().(*bytes.Buffer)
	writer.buf.Reset()
	defer bufPool.Put(writer.buf)

	err = writer.writeBeginRequest(uint16(Responder), 0)
	if err != nil {
		return
	}

	writer.recType = Params
	err = writer.writePairs(p)
	if err != nil {
		return
	}

	writer.recType = Stdin
	if req != nil {
		_, err = io.Copy(writer, req)
		if err != nil {
			return nil, err
		}
	}
	err = writer.FlushStream()
	if err != nil {
		return nil, err
	}