Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bugfix/TT-12343 #6678

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

bugfix/TT-12343 #6678

wants to merge 1 commit into from

Conversation

sedkis
Copy link
Contributor

@sedkis sedkis commented Oct 28, 2024

Description

The enforced_timeout is being trumped by the global level default_proxy_timeout.

The enforced_timeout should take precedent when it is set.

How This Has Been Tested

  1. Manual testing
  2. Unit tests written with a matrix of different values for both fields

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Refactoring or add test (improvements in base code or adds test coverage to functionality)

Checklist

  • I ensured that the documentation is up to date

Description

  • Added a new parameter enforcedTimeout to the proxyTimeout function to allow path-specific timeouts to override global timeouts.
  • Updated the WrappedServeHTTP function to utilize the new enforcedTimeout parameter.
  • Introduced a comprehensive test suite TestTimeoutBehavior to validate the timeout logic, ensuring enforced timeouts are prioritized when set.
  • The tests cover scenarios with enforced timeouts both greater and lesser than the default proxy timeout, as well as cases where no enforced timeout is set.

Changes walkthrough 📝

Relevant files
Bug fix
reverse_proxy.go
Add enforced timeout logic to proxy timeout function         

gateway/reverse_proxy.go

  • Added a new parameter enforcedTimeout to the proxyTimeout function.
  • Implemented logic to prioritize path-specific enforced timeout over
    global timeout.
  • Updated function calls to include the new enforcedTimeout parameter.
  • +9/-2     
    Tests
    reverse_proxy_test.go
    Add tests for enforced and default proxy timeout behavior

    gateway/reverse_proxy_test.go

  • Added a new test TestTimeoutBehavior to verify timeout behavior.
  • Included multiple test cases to check enforced timeout and default
    proxy timeout.
  • Ensured tests handle timing and delays appropriately.
  • +124/-0 

    💡 PR-Agent usage: Comment /help "your question" on any pull request to receive relevant information

    @buger
    Copy link
    Member

    buger commented Oct 28, 2024

    💔 The detected issue is not in one of the allowed statuses 💔

    Detected Status Open
    Allowed Statuses In Dev,In Code Review,Ready for Testing,In Test,In Progress,In Review ✔️

    Please ensure your jira story is in one of the allowed statuses

    Copy link
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 PR contains tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Code Clarity
    The function proxyTimeout has a comment that could be more descriptive about the behavior when both timeouts are present. It should clearly state the precedence and conditions under which each timeout is applied.

    Test Coverage
    Ensure that the new tests cover scenarios where the proxyTimeout function might receive negative values for enforcedTimeout or extremely high values that could cause unexpected behavior.

    Copy link
    Contributor

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Score
    Possible bug
    Prevent potential nil pointer dereferences by checking if objects are nil before accessing their properties

    Consider handling the case where spec or spec.GlobalConfig might be nil to prevent
    potential nil pointer dereferences.

    gateway/reverse_proxy.go [551-553]

    -if spec.GlobalConfig.ProxyDefaultTimeout > 0 {
    +if spec != nil && spec.GlobalConfig != nil && spec.GlobalConfig.ProxyDefaultTimeout > 0 {
         return spec.GlobalConfig.ProxyDefaultTimeout
     }
    Suggestion importance[1-10]: 9

    Why: The suggestion addresses a potential bug by adding nil checks for spec and spec.GlobalConfig before accessing their properties. This is crucial for preventing runtime errors due to nil pointer dereferences, which can cause the application to crash.

    9

    Copy link
    Contributor

    API Changes

    --- prev.txt	2024-10-28 14:38:56.584801621 +0000
    +++ current.txt	2024-10-28 14:38:49.844763220 +0000
    @@ -2416,9 +2416,9 @@
     	Username string `bson:"username" json:"username"`
     	// Password is the password to be used for upstream basic authentication.
     	Password string `bson:"password" json:"password"`
    -	// Header holds the configuration for custom header name to be used for upstream basic authentication.
    +	// HeaderName is the custom header name to be used for upstream basic authentication.
     	// Defaults to `Authorization`.
    -	Header AuthSource `bson:"header" json:"header"`
    +	HeaderName string `bson:"header_name" json:"header_name"`
     }
         UpstreamBasicAuth holds upstream basic authentication configuration.
     
    @@ -5252,8 +5252,9 @@
     type UpstreamBasicAuth struct {
     	// Enabled enables upstream basic authentication.
     	Enabled bool `bson:"enabled" json:"enabled"`
    -	// Header contains configurations for the header value.
    -	Header *AuthSource `bson:"header,omitempty" json:"header,omitempty"`
    +	// HeaderName is the custom header name to be used for upstream basic authentication.
    +	// Defaults to `Authorization`.
    +	HeaderName string `bson:"headerName" json:"headerName"`
     	// Username is the username to be used for upstream basic authentication.
     	Username string `bson:"username" json:"username"`
     	// Password is the password to be used for upstream basic authentication.
    @@ -8183,87 +8184,6 @@
     }
         StreamsConfig represents a stream configuration.
     
    -# Package: ./ee/middleware/upstreambasicauth
    -
    -package upstreambasicauth // import "github.com/TykTechnologies/tyk/ee/middleware/upstreambasicauth"
    -
    -
    -CONSTANTS
    -
    -const (
    -	// ExtensionTykStreaming is the OAS extension for Tyk streaming.
    -	ExtensionTykStreaming = "x-tyk-streaming"
    -	StreamGCInterval      = 1 * time.Minute
    -)
    -
    -TYPES
    -
    -type APISpec struct {
    -	APIID string
    -	Name  string
    -	IsOAS bool
    -	OAS   oas.OAS
    -
    -	UpstreamAuth apidef.UpstreamAuth
    -}
    -    APISpec is a subset of gateway.APISpec for the values the middleware
    -    consumes.
    -
    -func NewAPISpec(id string, name string, isOasDef bool, oasDef oas.OAS, upstreamAuth apidef.UpstreamAuth) *APISpec
    -    NewAPISpec creates a new APISpec object based on the required inputs.
    -    The resulting object is a subset of `*gateway.APISpec`.
    -
    -type BaseMiddleware interface {
    -	model.LoggerProvider
    -}
    -    BaseMiddleware is the subset of BaseMiddleware APIs that the middleware
    -    uses.
    -
    -type Gateway interface {
    -	model.ConfigProvider
    -	model.ReplaceTykVariables
    -}
    -    Gateway is the subset of Gateway APIs that the middleware uses.
    -
    -type Middleware struct {
    -	Spec *APISpec
    -	Gw   Gateway
    -
    -	// Has unexported fields.
    -}
    -    Middleware implements upstream basic auth middleware.
    -
    -func NewMiddleware(gw Gateway, mw BaseMiddleware, spec *APISpec) *Middleware
    -    NewMiddleware returns a new instance of Middleware.
    -
    -func (m *Middleware) EnabledForSpec() bool
    -    EnabledForSpec checks if streaming is enabled on the config.
    -
    -func (m *Middleware) Init()
    -    Init initializes the middleware.
    -
    -func (m *Middleware) Logger() *logrus.Entry
    -    Logger returns a logger with middleware filled out.
    -
    -func (m *Middleware) Name() string
    -    Name returns the name for the middleware.
    -
    -func (m *Middleware) ProcessRequest(_ http.ResponseWriter, r *http.Request, _ interface{}) (error, int)
    -    ProcessRequest will handle upstream basic auth.
    -
    -type Provider struct {
    -	// Logger is the logger to be used.
    -	Logger *logrus.Entry
    -	// HeaderName is the header name to be used to fill upstream auth with.
    -	HeaderName string
    -	// AuthValue is the value of auth header.
    -	AuthValue string
    -}
    -    Provider implements upstream auth provider.
    -
    -func (u Provider) Fill(r *http.Request)
    -    Fill sets the request's HeaderName with AuthValue
    -
     # Package: ./gateway
     
     package gateway // import "github.com/TykTechnologies/tyk/gateway"
    @@ -11523,6 +11443,34 @@
         Enums representing the various statuses for a VersionInfo Path match during
         a proxy request
     
    +type UpstreamBasicAuth struct {
    +	*BaseMiddleware
    +}
    +    UpstreamBasicAuth is a middleware that will do basic authentication for
    +    upstream connections. UpstreamBasicAuth middleware is only supported in Tyk
    +    OAS API definitions.
    +
    +func (t *UpstreamBasicAuth) EnabledForSpec() bool
    +    EnabledForSpec returns true if the middleware is enabled based on API Spec.
    +
    +func (t *UpstreamBasicAuth) Name() string
    +    Name returns the name of middleware.
    +
    +func (t *UpstreamBasicAuth) ProcessRequest(_ http.ResponseWriter, r *http.Request, _ interface{}) (error, int)
    +    ProcessRequest will inject basic auth info into request context so that it
    +    can be used during reverse proxy.
    +
    +type UpstreamBasicAuthProvider struct {
    +	// HeaderName is the header name to be used to fill upstream auth with.
    +	HeaderName string
    +	// AuthValue is the value of auth header.
    +	AuthValue string
    +}
    +    UpstreamBasicAuthProvider implements upstream auth provider.
    +
    +func (u UpstreamBasicAuthProvider) Fill(r *http.Request)
    +    Fill sets the request's HeaderName with AuthValue
    +
     type UpstreamOAuth struct {
     	*BaseMiddleware
     }

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    2 participants