From 0ad54a45d9caf8302a0dee6f3e2917cf8c36b36b Mon Sep 17 00:00:00 2001 From: Erik Dubbelboer Date: Sun, 28 Sep 2025 02:33:14 +0200 Subject: [PATCH] Update lint and fix new lint errors --- .github/workflows/lint.yml | 2 +- brotli.go | 4 +- client.go | 6 +- fasthttpproxy/dialer.go | 20 +-- fasthttpproxy/dialer_test.go | 4 +- fasthttputil/pipeconns.go | 2 +- headers.go | 252 +++++++++++++++-------------------- headerscanner.go | 4 +- prefork/prefork.go | 6 +- server.go | 42 +++--- tcplisten/tcplisten_linux.go | 4 +- 11 files changed, 152 insertions(+), 194 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 069ca2a..488aafd 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -25,5 +25,5 @@ jobs: - name: Run golangci-lint uses: golangci/golangci-lint-action@v8 with: - version: v2.4.0 + version: v2.5.0 args: --verbose diff --git a/brotli.go b/brotli.go index 1e8e0f0..a89189d 100644 --- a/brotli.go +++ b/brotli.go @@ -17,8 +17,8 @@ const ( CompressBrotliBestSpeed = brotli.BestSpeed CompressBrotliBestCompression = brotli.BestCompression - // Choose a default brotli compression level comparable to - // CompressDefaultCompression (gzip 6) + // CompressBrotliDefaultCompression chooses a default brotli compression level comparable to + // CompressDefaultCompression (gzip 6). // See: https://github.com/valyala/fasthttp/issues/798#issuecomment-626293806 CompressBrotliDefaultCompression = 4 ) diff --git a/client.go b/client.go index 65c3493..6d16696 100644 --- a/client.go +++ b/client.go @@ -924,7 +924,7 @@ type clientConn struct { lastUseTime time.Time } -// CreatedTime returns net.Conn the client. +// Conn returns the underlying net.Conn associated with the client connection. func (cc *clientConn) Conn() net.Conn { return cc.c } @@ -1115,7 +1115,7 @@ var ( // exceed the max count. ErrTooManyRedirects = errors.New("too many redirects detected when doing the request") - // HostClients are only able to follow redirects to the same protocol. + // ErrHostClientRedirectToDifferentScheme is returned when a HostClient follows a redirect to a different protocol. ErrHostClientRedirectToDifferentScheme = errors.New("HostClient can't follow redirects to a different protocol," + " please use Client instead") ) @@ -1522,7 +1522,7 @@ func (e *timeoutError) Error() string { return "timeout" } -// Only implement the Timeout() function of the net.Error interface. +// Timeout implements the Timeout behavior of the net.Error interface. // This allows for checks like: // // if x, ok := err.(interface{ Timeout() bool }); ok && x.Timeout() { diff --git a/fasthttpproxy/dialer.go b/fasthttpproxy/dialer.go index 2eb941b..20725ce 100644 --- a/fasthttpproxy/dialer.go +++ b/fasthttpproxy/dialer.go @@ -103,7 +103,7 @@ func (d *Dialer) GetDialFunc(useEnv bool) (dialFunc fasthttp.DialFunc, err error case "socks5", "socks5h": proxyDialer, err = proxy.FromURL(proxyURL, d) if err != nil { - return + return nil, err } case "http": proxyAddr, auth := addrAndAuth(proxyURL) @@ -128,7 +128,7 @@ func (d *Dialer) GetDialFunc(useEnv bool) (dialFunc fasthttp.DialFunc, err error reqURL := &url.URL{Host: addr, Scheme: scheme} proxyURL, err = proxyFunc(reqURL) if err != nil { - return + return nil, err } if proxyURL == nil { // dial directly @@ -138,7 +138,7 @@ func (d *Dialer) GetDialFunc(useEnv bool) (dialFunc fasthttp.DialFunc, err error case "socks5", "socks5h": proxyDialer, err = proxy.FromURL(proxyURL, d) if err != nil { - return + return nil, err } case "http": proxyAddr, auth := addrAndAuth(proxyURL) @@ -167,7 +167,7 @@ func (d *Dialer) Dial(network, addr string) (conn net.Conn, err error) { return d.TCPDialer.DialDualStack(addr) } err = errors.New("dont support the network: " + network) - return + return nil, err } func (d *Dialer) connectTimeout() time.Duration { @@ -193,7 +193,7 @@ func (d DialerFunc) Dial(network, addr string) (net.Conn, error) { func httpProxyDial(dialer proxy.Dialer, network, addr, proxyAddr, auth string) (conn net.Conn, err error) { conn, err = dialer.Dial(network, proxyAddr) if err != nil { - return + return nil, err } var connectTimeout time.Duration hp, ok := dialer.(httpProxyDialer) @@ -218,21 +218,21 @@ func httpProxyDial(dialer proxy.Dialer, network, addr, proxyAddr, auth string) ( _, err = conn.Write([]byte(req)) if err != nil { _ = conn.Close() - return + return nil, err } res := fasthttp.AcquireResponse() defer fasthttp.ReleaseResponse(res) res.SkipBody = true if err = res.Read(bufio.NewReaderSize(conn, 1024)); err != nil { _ = conn.Close() - return + return nil, err } if res.Header.StatusCode() != 200 { _ = conn.Close() err = fmt.Errorf("could not connect to proxyAddr: %s status code: %d", proxyAddr, res.Header.StatusCode()) - return + return nil, err } - return + return conn, err } // Cache authentication information for HTTP proxies. @@ -244,7 +244,7 @@ type proxyInfo struct { func addrAndAuth(pu *url.URL) (proxyAddr, auth string) { if pu.User == nil { proxyAddr = pu.Host + pu.Path - return + return proxyAddr, auth } var info *proxyInfo v, ok := authCache.Load(pu) diff --git a/fasthttpproxy/dialer_test.go b/fasthttpproxy/dialer_test.go index 4f58ccd..40e3c18 100644 --- a/fasthttpproxy/dialer_test.go +++ b/fasthttpproxy/dialer_test.go @@ -273,7 +273,7 @@ func startProxyServer(t *testing.T, ports []string, counts []atomic.Int64) (lns fasthttp.ReleaseRequest(req) }() } - return + return lns } func getDialer(httpProxy, httpsProxy, noProxy string) *Dialer { @@ -290,7 +290,7 @@ func getCounts(counts []atomic.Int64) (r []int64) { for i := 0; i < len(counts); i++ { r = append(r, counts[i].Load()) } - return + return r } func countsEqual(a, b []int64) bool { diff --git a/fasthttputil/pipeconns.go b/fasthttputil/pipeconns.go index aca5d72..f125182 100644 --- a/fasthttputil/pipeconns.go +++ b/fasthttputil/pipeconns.go @@ -229,7 +229,7 @@ func (e *timeoutError) Error() string { return "timeout" } -// Only implement the Timeout() function of the net.Error interface. +// Timeout implements the Timeout method of the net.Error interface. // This allows for checks like: // // if x, ok := err.(interface{ Timeout() bool }); ok && x.Timeout() { diff --git a/headers.go b/headers.go index e06b734..57ed2c0 100644 --- a/headers.go +++ b/headers.go @@ -1,165 +1,123 @@ package fasthttp -// Headers. const ( - // Authentication. - HeaderAuthorization = "Authorization" - HeaderProxyAuthenticate = "Proxy-Authenticate" - HeaderProxyAuthorization = "Proxy-Authorization" - HeaderWWWAuthenticate = "WWW-Authenticate" - - // Caching. - HeaderAge = "Age" - HeaderCacheControl = "Cache-Control" - HeaderClearSiteData = "Clear-Site-Data" - HeaderExpires = "Expires" - HeaderPragma = "Pragma" - HeaderWarning = "Warning" - - // Client hints. - HeaderAcceptCH = "Accept-CH" - HeaderAcceptCHLifetime = "Accept-CH-Lifetime" - HeaderContentDPR = "Content-DPR" - HeaderDPR = "DPR" - HeaderEarlyData = "Early-Data" - HeaderSaveData = "Save-Data" - HeaderViewportWidth = "Viewport-Width" - HeaderWidth = "Width" - - // Conditionals. - HeaderETag = "ETag" - HeaderIfMatch = "If-Match" - HeaderIfModifiedSince = "If-Modified-Since" - HeaderIfNoneMatch = "If-None-Match" - HeaderIfUnmodifiedSince = "If-Unmodified-Since" - HeaderLastModified = "Last-Modified" - HeaderVary = "Vary" - - // Connection management. - HeaderConnection = "Connection" - HeaderKeepAlive = "Keep-Alive" - HeaderProxyConnection = "Proxy-Connection" - - // Content negotiation. - HeaderAccept = "Accept" - HeaderAcceptCharset = "Accept-Charset" - HeaderAcceptEncoding = "Accept-Encoding" - HeaderAcceptLanguage = "Accept-Language" - - // Controls. - HeaderCookie = "Cookie" - HeaderExpect = "Expect" - HeaderMaxForwards = "Max-Forwards" - HeaderSetCookie = "Set-Cookie" - - // CORS. - HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials" - HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers" - HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods" - HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin" - HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers" - HeaderAccessControlMaxAge = "Access-Control-Max-Age" - HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers" - HeaderAccessControlRequestMethod = "Access-Control-Request-Method" - HeaderOrigin = "Origin" - HeaderTimingAllowOrigin = "Timing-Allow-Origin" - HeaderXPermittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies" - - // Do Not Track. - HeaderDNT = "DNT" - HeaderTk = "Tk" - - // Downloads. - HeaderContentDisposition = "Content-Disposition" - - // Message body information. - HeaderContentEncoding = "Content-Encoding" - HeaderContentLanguage = "Content-Language" - HeaderContentLength = "Content-Length" - HeaderContentLocation = "Content-Location" - HeaderContentType = "Content-Type" - - // Proxies. - HeaderForwarded = "Forwarded" - HeaderVia = "Via" - HeaderXForwardedFor = "X-Forwarded-For" - HeaderXForwardedHost = "X-Forwarded-Host" - HeaderXForwardedProto = "X-Forwarded-Proto" - - // Redirects. - HeaderLocation = "Location" - - // Request context. - HeaderFrom = "From" - HeaderHost = "Host" - HeaderReferer = "Referer" - HeaderReferrerPolicy = "Referrer-Policy" - HeaderUserAgent = "User-Agent" - - // Response context. - HeaderAllow = "Allow" - HeaderServer = "Server" - - // Range requests. - HeaderAcceptRanges = "Accept-Ranges" - HeaderContentRange = "Content-Range" - HeaderIfRange = "If-Range" - HeaderRange = "Range" - - // Security. + HeaderAccept = "Accept" + HeaderAcceptCH = "Accept-CH" + HeaderAcceptCharset = "Accept-Charset" + HeaderAcceptCHLifetime = "Accept-CH-Lifetime" + HeaderAcceptEncoding = "Accept-Encoding" + HeaderAcceptLanguage = "Accept-Language" + HeaderAcceptPatch = "Accept-Patch" + HeaderAcceptPushPolicy = "Accept-Push-Policy" + HeaderAcceptRanges = "Accept-Ranges" + HeaderAcceptSignature = "Accept-Signature" + HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials" + HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers" + HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods" + HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin" + HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers" + HeaderAccessControlMaxAge = "Access-Control-Max-Age" + HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers" + HeaderAccessControlRequestMethod = "Access-Control-Request-Method" + HeaderAge = "Age" + HeaderAllow = "Allow" + HeaderAltSvc = "Alt-Svc" + HeaderAuthorization = "Authorization" + HeaderCacheControl = "Cache-Control" + HeaderClearSiteData = "Clear-Site-Data" + HeaderConnection = "Connection" + HeaderContentDisposition = "Content-Disposition" + HeaderContentDPR = "Content-DPR" + HeaderContentEncoding = "Content-Encoding" + HeaderContentLanguage = "Content-Language" + HeaderContentLength = "Content-Length" + HeaderContentLocation = "Content-Location" + HeaderContentRange = "Content-Range" HeaderContentSecurityPolicy = "Content-Security-Policy" HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only" + HeaderContentType = "Content-Type" + HeaderCookie = "Cookie" HeaderCrossOriginResourcePolicy = "Cross-Origin-Resource-Policy" + HeaderDate = "Date" + HeaderDNT = "DNT" + HeaderDPR = "DPR" + HeaderEarlyData = "Early-Data" + HeaderETag = "ETag" + HeaderExpect = "Expect" HeaderExpectCT = "Expect-CT" + HeaderExpires = "Expires" HeaderFeaturePolicy = "Feature-Policy" + HeaderForwarded = "Forwarded" + HeaderFrom = "From" + HeaderHost = "Host" + HeaderIfMatch = "If-Match" + HeaderIfModifiedSince = "If-Modified-Since" + HeaderIfNoneMatch = "If-None-Match" + HeaderIfRange = "If-Range" + HeaderIfUnmodifiedSince = "If-Unmodified-Since" + HeaderIndex = "Index" + HeaderKeepAlive = "Keep-Alive" + HeaderLargeAllocation = "Large-Allocation" + HeaderLastEventID = "Last-Event-ID" + HeaderLastModified = "Last-Modified" + HeaderLink = "Link" + HeaderLocation = "Location" + HeaderMaxForwards = "Max-Forwards" + HeaderNEL = "NEL" + HeaderOrigin = "Origin" + HeaderPingFrom = "Ping-From" + HeaderPingTo = "Ping-To" + HeaderPragma = "Pragma" + HeaderProxyAuthenticate = "Proxy-Authenticate" + HeaderProxyAuthorization = "Proxy-Authorization" + HeaderProxyConnection = "Proxy-Connection" HeaderPublicKeyPins = "Public-Key-Pins" HeaderPublicKeyPinsReportOnly = "Public-Key-Pins-Report-Only" + HeaderPushPolicy = "Push-Policy" + HeaderRange = "Range" + HeaderReferer = "Referer" + HeaderReferrerPolicy = "Referrer-Policy" + HeaderReportTo = "Report-To" + HeaderRetryAfter = "Retry-After" + HeaderSaveData = "Save-Data" + HeaderSecWebSocketAccept = "Sec-WebSocket-Accept" + HeaderSecWebSocketExtensions = "Sec-WebSocket-Extensions" // #nosec G101 + HeaderSecWebSocketKey = "Sec-WebSocket-Key" + HeaderSecWebSocketProtocol = "Sec-WebSocket-Protocol" + HeaderSecWebSocketVersion = "Sec-WebSocket-Version" + HeaderServer = "Server" + HeaderServerTiming = "Server-Timing" + HeaderSetCookie = "Set-Cookie" + HeaderSignature = "Signature" + HeaderSignedHeaders = "Signed-Headers" + HeaderSourceMap = "SourceMap" HeaderStrictTransportSecurity = "Strict-Transport-Security" + HeaderTE = "TE" + HeaderTimingAllowOrigin = "Timing-Allow-Origin" + HeaderTk = "Tk" + HeaderTrailer = "Trailer" + HeaderTransferEncoding = "Transfer-Encoding" + HeaderUpgrade = "Upgrade" HeaderUpgradeInsecureRequests = "Upgrade-Insecure-Requests" + HeaderUserAgent = "User-Agent" + HeaderVary = "Vary" + HeaderVia = "Via" + HeaderViewportWidth = "Viewport-Width" + HeaderWarning = "Warning" + HeaderWidth = "Width" + HeaderWWWAuthenticate = "WWW-Authenticate" HeaderXContentTypeOptions = "X-Content-Type-Options" + HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control" HeaderXDownloadOptions = "X-Download-Options" + HeaderXForwardedFor = "X-Forwarded-For" + HeaderXForwardedHost = "X-Forwarded-Host" + HeaderXForwardedProto = "X-Forwarded-Proto" HeaderXFrameOptions = "X-Frame-Options" + HeaderXPermittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies" + HeaderXPingback = "X-Pingback" HeaderXPoweredBy = "X-Powered-By" + HeaderXRequestedWith = "X-Requested-With" + HeaderXRobotsTag = "X-Robots-Tag" + HeaderXUACompatible = "X-UA-Compatible" HeaderXXSSProtection = "X-XSS-Protection" - - // Server-sent event. - HeaderLastEventID = "Last-Event-ID" - HeaderNEL = "NEL" - HeaderPingFrom = "Ping-From" - HeaderPingTo = "Ping-To" - HeaderReportTo = "Report-To" - - // Transfer coding. - HeaderTE = "TE" - HeaderTrailer = "Trailer" - HeaderTransferEncoding = "Transfer-Encoding" - - // WebSockets. - HeaderSecWebSocketAccept = "Sec-WebSocket-Accept" - HeaderSecWebSocketExtensions = "Sec-WebSocket-Extensions" // #nosec G101 - HeaderSecWebSocketKey = "Sec-WebSocket-Key" - HeaderSecWebSocketProtocol = "Sec-WebSocket-Protocol" - HeaderSecWebSocketVersion = "Sec-WebSocket-Version" - - // Other. - HeaderAcceptPatch = "Accept-Patch" - HeaderAcceptPushPolicy = "Accept-Push-Policy" - HeaderAcceptSignature = "Accept-Signature" - HeaderAltSvc = "Alt-Svc" - HeaderDate = "Date" - HeaderIndex = "Index" - HeaderLargeAllocation = "Large-Allocation" - HeaderLink = "Link" - HeaderPushPolicy = "Push-Policy" - HeaderRetryAfter = "Retry-After" - HeaderServerTiming = "Server-Timing" - HeaderSignature = "Signature" - HeaderSignedHeaders = "Signed-Headers" - HeaderSourceMap = "SourceMap" - HeaderUpgrade = "Upgrade" - HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control" - HeaderXPingback = "X-Pingback" - HeaderXRequestedWith = "X-Requested-With" - HeaderXRobotsTag = "X-Robots-Tag" - HeaderXUACompatible = "X-UA-Compatible" ) diff --git a/headerscanner.go b/headerscanner.go index f3129a7..109504f 100644 --- a/headerscanner.go +++ b/headerscanner.go @@ -88,7 +88,7 @@ func (s *headerScanner) readLine() (line []byte) { } if len(line) == 0 { - return + return nil } // drop \n and possible preceding \r @@ -99,7 +99,7 @@ func (s *headerScanner) readLine() (line []byte) { } line = line[:len(line)-drop] } - return + return line } // readContinuedLineSlice reads continued lines from b until it finds a line diff --git a/prefork/prefork.go b/prefork/prefork.go index 46d308a..9541a8f 100644 --- a/prefork/prefork.go +++ b/prefork/prefork.go @@ -153,7 +153,7 @@ func (p *Prefork) prefork(addr string) (err error) { } if err = p.setTCPListenerFiles(addr); err != nil { - return + return err } // defer for closing the net.Listener opened by setTCPListenerFiles. @@ -184,7 +184,7 @@ func (p *Prefork) prefork(addr string) (err error) { var cmd *exec.Cmd if cmd, err = p.doCommand(); err != nil { p.logger().Printf("failed to start a child prefork process, error: %v\n", err) - return + return err } childProcs[cmd.Process.Pid] = cmd @@ -219,7 +219,7 @@ func (p *Prefork) prefork(addr string) (err error) { }() } - return + return err } // ListenAndServe serves HTTP requests from the given TCP addr. diff --git a/server.go b/server.go index 222d7e4..f27d8de 100644 --- a/server.go +++ b/server.go @@ -1123,14 +1123,14 @@ func SaveMultipartFile(fh *multipart.FileHeader, path string) (err error) { ) f, err = fh.Open() if err != nil { - return + return err } var ok bool if ff, ok = f.(*os.File); ok { // Windows can't rename files that are opened. if err = f.Close(); err != nil { - return + return err } // If renaming fails we try the normal copying method. @@ -1141,7 +1141,7 @@ func SaveMultipartFile(fh *multipart.FileHeader, path string) (err error) { // Reopen f for the code below. if f, err = fh.Open(); err != nil { - return + return err } } @@ -1153,7 +1153,7 @@ func SaveMultipartFile(fh *multipart.FileHeader, path string) (err error) { }() if ff, err = os.Create(path); err != nil { - return + return err } defer func() { e := ff.Close() @@ -1162,7 +1162,7 @@ func SaveMultipartFile(fh *multipart.FileHeader, path string) (err error) { } }() _, err = copyZeroAlloc(ff, f) - return + return err } // FormValue returns form value associated with the given key. @@ -1649,26 +1649,26 @@ func (s *Server) NextProto(key string, nph ServeHandler) { s.nextProtos[key] = nph } -func (s *Server) getNextProto(c net.Conn) (proto string, err error) { +func (s *Server) getNextProto(c net.Conn) (string, error) { if tlsConn, ok := c.(connTLSer); ok { if s.ReadTimeout > 0 { - if err = c.SetReadDeadline(time.Now().Add(s.ReadTimeout)); err != nil { - return + if err := c.SetReadDeadline(time.Now().Add(s.ReadTimeout)); err != nil { + return "", err } } if s.WriteTimeout > 0 { - if err = c.SetWriteDeadline(time.Now().Add(s.WriteTimeout)); err != nil { - return + if err := c.SetWriteDeadline(time.Now().Add(s.WriteTimeout)); err != nil { + return "", err } } - err = tlsConn.Handshake() + err := tlsConn.Handshake() if err == nil { - proto = tlsConn.ConnectionState().NegotiatedProtocol + return tlsConn.ConnectionState().NegotiatedProtocol, nil } } - return + return "", nil } // ListenAndServe serves HTTP requests from the given TCP4 addr. @@ -2173,20 +2173,20 @@ func (s *Server) serveConnCleanup() { s.concurrency.Add(^uint32(0)) } -func (s *Server) serveConn(c net.Conn) (err error) { +func (s *Server) serveConn(c net.Conn) error { defer s.serveConnCleanup() s.concurrency.Add(1) - var proto string - if proto, err = s.getNextProto(c); err != nil { - return + proto, err := s.getNextProto(c) + if err != nil { + return err } if handler, ok := s.nextProtos[proto]; ok { // Remove read or write deadlines that might have previously been set. // The next handler is responsible for setting its own deadlines. if s.ReadTimeout > 0 || s.WriteTimeout > 0 { - if err = c.SetDeadline(zeroTime); err != nil { - return + if err := c.SetDeadline(zeroTime); err != nil { + return err } } @@ -2589,7 +2589,7 @@ func (s *Server) serveConn(c net.Conn) (err error) { } s.idleConnsMu.Unlock() - return + return err } func (s *Server) setState(nc net.Conn, state ConnState) { @@ -2818,7 +2818,7 @@ func (ctx *RequestCtx) Init(req *Request, remoteAddr net.Addr, logger Logger) { // This method always returns 0, false and is only present to make // RequestCtx implement the context interface. func (ctx *RequestCtx) Deadline() (deadline time.Time, ok bool) { - return + return time.Time{}, false } // Done returns a channel that's closed when work done on behalf of this diff --git a/tcplisten/tcplisten_linux.go b/tcplisten/tcplisten_linux.go index b4bf8df..1aacf41 100644 --- a/tcplisten/tcplisten_linux.go +++ b/tcplisten/tcplisten_linux.go @@ -59,7 +59,7 @@ func soMaxConn() (int, error) { func kernelVersion() (major, minor int) { var uname unix.Utsname if err := unix.Uname(&uname); err != nil { - return + return 0, 0 } rl := uname.Release @@ -87,7 +87,7 @@ func kernelVersion() (major, minor int) { case 2: return values[0], values[1] } - return + return major, minor } // Linux stores the backlog as: