-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
* client: simplify (*HostClient).do() Remove an allocation in favour of deferring a call to release the response. * client: remove panic in dialAddr Return an error instead of panicking if the user supplied a nonsensical DialFunc. * compression: remove panic on invalid compression level If a compression level exceeding gzip's boundaries is provided, fasthttp will panic. Instead it would be better to handle this error for them by limiting it to the minimum or maximum value, depending on the direction the user has exceeded the limits. Clamp the value of gzip to always be between gzip.BestSpeed and gzip.BestCompression. * peripconn: remove panic on negative connection count When a negative count is reached when unregistering a connection, a panic is caused even though data-integrity is not at risk. Replace the panic() with a simple clamp on the value to ensure the value does not exceed it's expected lower bounds. References: #1504 * compress: remove error on failed nonblocking writes Since there is no way of handling or even logging non-critical errors in stateless non-blocking writecalls, just drop them and hope the user notices and tries again. * workerPool: remove panic on redundant Start and Stop calls Instead of panicking for invalid behaviour, it's preferable to just turn the function into a noop. * http: remove panic on invalid form boundary * http: remove panic on negative reads Since bufio already panics on negative reads, it is not necessary to do so as well. If the length is zero and for some reason no error is returned, readBodyIdentity and appendBodyFixedSize now errors in these cases. Link: https://github.com/golang/go/blob/851f6fd61425c810959c7ab51e6dc86f8a63c970/src/bufio/bufio.go#L246 * fs: remove panic on negative reader count When a negative count is reached when unregistering a reader, a panic is thrown even though data-integrity is not at risk. Replace the panic() with a simple clamp on the value to ensure the value does not exceed it's expected lower bounds. * server: remove panic in favour of a segfault Panicking with "BUG: " obscures the error. As the segfault causes a panic anyway, just let the chaos unfold. * server: remove panic in favour of returning an error Writing on a timed-out response is not endangering data integrity and just fails. * chore: add comments to all panics * chore: fix minor typo
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1294,26 +1294,23 @@ func isIdempotent(req *Request) bool { | |
} | ||
|
||
func (c *HostClient) do(req *Request, resp *Response) (bool, error) { | ||
nilResp := false | ||
if resp == nil { | ||
nilResp = true | ||
resp = AcquireResponse() | ||
defer ReleaseResponse(resp) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
erikdubbelboer
Collaborator
|
||
} | ||
|
||
ok, err := c.doNonNilReqResp(req, resp) | ||
|
||
if nilResp { | ||
ReleaseResponse(resp) | ||
} | ||
|
||
return ok, err | ||
} | ||
|
||
func (c *HostClient) doNonNilReqResp(req *Request, resp *Response) (bool, error) { | ||
if req == nil { | ||
// for debugging purposes | ||
panic("BUG: req cannot be nil") | ||
} | ||
if resp == nil { | ||
// for debugging purposes | ||
panic("BUG: resp cannot be nil") | ||
} | ||
|
||
|
@@ -1994,7 +1991,7 @@ func dialAddr(addr string, dial DialFunc, dialDualStack, isTLS bool, tlsConfig * | |
return nil, err | ||
} | ||
if conn == nil { | ||
panic("BUG: DialFunc returned (nil, nil)") | ||
return nil, errors.New("dialling unsuccessful. Please report this bug!") | ||
} | ||
|
||
// We assume that any conn that has the Handshake() method is a TLS conn already. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -963,7 +963,7 @@ func WriteMultipartForm(w io.Writer, f *multipart.Form, boundary string) error { | |
// Do not care about memory allocations here, since multipart | ||
// form processing is slow. | ||
if len(boundary) == 0 { | ||
panic("BUG: form boundary cannot be empty") | ||
return errors.New("form boundary cannot be empty") | ||
} | ||
|
||
mw := multipart.NewWriter(w) | ||
|
@@ -2134,13 +2134,14 @@ func readBodyIdentity(r *bufio.Reader, maxBodySize int, dst []byte) ([]byte, err | |
for { | ||
nn, err := r.Read(dst[offset:]) | ||
if nn <= 0 { | ||
if err != nil { | ||
if err == io.EOF { | ||
return dst[:offset], nil | ||
} | ||
switch { | ||
case errors.Is(err, io.EOF): | ||
return dst[:offset], nil | ||
case err != nil: | ||
return dst[:offset], err | ||
default: | ||
return dst[:offset], fmt.Errorf("bufio.Read() returned (%d, nil)", nn) | ||
} | ||
panic(fmt.Sprintf("BUG: bufio.Read() returned (%d, nil)", nn)) | ||
} | ||
offset += nn | ||
if maxBodySize > 0 && offset > maxBodySize { | ||
|
@@ -2175,13 +2176,14 @@ func appendBodyFixedSize(r *bufio.Reader, dst []byte, n int) ([]byte, error) { | |
for { | ||
nn, err := r.Read(dst[offset:]) | ||
if nn <= 0 { | ||
if err != nil { | ||
if err == io.EOF { | ||
err = io.ErrUnexpectedEOF | ||
} | ||
switch { | ||
case errors.Is(err, io.EOF): | ||
This comment has been minimized.
Sorry, something went wrong.
regorov
|
||
return dst[:offset], io.ErrUnexpectedEOF | ||
case err != nil: | ||
return dst[:offset], err | ||
default: | ||
return dst[:offset], fmt.Errorf("bufio.Read() returned (%d, nil)", nn) | ||
} | ||
panic(fmt.Sprintf("BUG: bufio.Read() returned (%d, nil)", nn)) | ||
} | ||
offset += nn | ||
if offset == dstLen { | ||
|
@@ -2197,6 +2199,8 @@ type ErrBrokenChunk struct { | |
|
||
func readBodyChunked(r *bufio.Reader, maxBodySize int, dst []byte) ([]byte, error) { | ||
if len(dst) > 0 { | ||
// data integrity might be in danger. No idea what we received, | ||
// but nothing we should write to. | ||
panic("BUG: expected zero-length buffer") | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,7 +47,7 @@ type workerChan struct { | |
|
||
func (wp *workerPool) Start() { | ||
if wp.stopCh != nil { | ||
panic("BUG: workerPool already started") | ||
return | ||
This comment has been minimized.
Sorry, something went wrong.
regorov
|
||
} | ||
wp.stopCh = make(chan struct{}) | ||
stopCh := wp.stopCh | ||
|
@@ -72,7 +72,7 @@ func (wp *workerPool) Start() { | |
|
||
func (wp *workerPool) Stop() { | ||
if wp.stopCh == nil { | ||
panic("BUG: workerPool wasn't started") | ||
return | ||
} | ||
close(wp.stopCh) | ||
wp.stopCh = nil | ||
|
as I know, defer adds overhead! I would revert back changes in this function.