Skip to content

Commit

Permalink
feat: add server DisableHeaderNamesNormalizing option
Browse files Browse the repository at this point in the history
  • Loading branch information
li-jin-gou authored and welkeyever committed Sep 9, 2023
1 parent 2adc039 commit 404144e
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 28 deletions.
7 changes: 7 additions & 0 deletions pkg/app/server/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,10 @@ func WithOnConnect(fn func(ctx context.Context, conn network.Conn) context.Conte
o.OnConnect = fn
}}
}

// WithDisableHeaderNamesNormalizing is used to set whether disable header names normalizing.
func WithDisableHeaderNamesNormalizing(disable bool) config.Option {
return config.Option{F: func(o *config.Options) {
o.DisableHeaderNamesNormalizing = disable
}}
}
19 changes: 19 additions & 0 deletions pkg/common/config/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,22 @@ type Options struct {
// The HTML template will reload according to files' changing event
// otherwise it will reload after AutoReloadInterval.
AutoReloadInterval time.Duration

// Header names are passed as-is without normalization
// if this option is set.
//
// Disabled header names' normalization may be useful only for proxying
// responses to other clients expecting case-sensitive header names.
//
// By default request and response header names are normalized, i.e.
// The first letter and the first letters following dashes
// are uppercased, while all the other letters are lowercased.
// Examples:
//
// * HOST -> Host
// * content-type -> Content-Type
// * cONTENT-lenGTH -> Content-Length
DisableHeaderNamesNormalizing bool
}

func (o *Options) Apply(opts []Option) {
Expand Down Expand Up @@ -225,6 +241,9 @@ func NewOptions(opts []Option) *Options {
TraceLevel: new(interface{}),

Registry: registry.NoopRegistry,

// Disabled header names' normalization, default false
DisableHeaderNamesNormalizing: false,
}
options.Apply(opts)
return options
Expand Down
35 changes: 21 additions & 14 deletions pkg/protocol/http1/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,21 @@ var (
)

type Option struct {
StreamRequestBody bool
GetOnly bool
DisablePreParseMultipartForm bool
DisableKeepalive bool
NoDefaultServerHeader bool
MaxRequestBodySize int
IdleTimeout time.Duration
ReadTimeout time.Duration
ServerName []byte
TLS *tls.Config
HTMLRender render.HTMLRender
EnableTrace bool
ContinueHandler func(header *protocol.RequestHeader) bool
HijackConnHandle func(c network.Conn, h app.HijackHandler)
StreamRequestBody bool
GetOnly bool
DisablePreParseMultipartForm bool
DisableKeepalive bool
NoDefaultServerHeader bool
MaxRequestBodySize int
IdleTimeout time.Duration
ReadTimeout time.Duration
ServerName []byte
TLS *tls.Config
HTMLRender render.HTMLRender
EnableTrace bool
ContinueHandler func(header *protocol.RequestHeader) bool
HijackConnHandle func(c network.Conn, h app.HijackHandler)
DisableHeaderNamesNormalizing bool
}

type Server struct {
Expand Down Expand Up @@ -179,6 +180,12 @@ func (s Server) Serve(c context.Context, conn network.Conn) (err error) {
internalStats.Record(ti, stats.ReadHeaderFinish, err)
})
}

if s.DisableHeaderNamesNormalizing {
ctx.Request.Header.DisableNormalizing()
ctx.Response.Header.DisableNormalizing()
}

// Read Headers
if err = req.ReadHeader(&ctx.Request.Header, zr); err == nil {
if s.EnableTrace {
Expand Down
29 changes: 15 additions & 14 deletions pkg/route/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -990,20 +990,21 @@ func iterate(method string, routes RoutesInfo, root *node) RoutesInfo {
// for built-in http1 impl only.
func newHttp1OptionFromEngine(engine *Engine) *http1.Option {
opt := &http1.Option{
StreamRequestBody: engine.options.StreamRequestBody,
GetOnly: engine.options.GetOnly,
DisablePreParseMultipartForm: engine.options.DisablePreParseMultipartForm,
DisableKeepalive: engine.options.DisableKeepalive,
NoDefaultServerHeader: engine.options.NoDefaultServerHeader,
MaxRequestBodySize: engine.options.MaxRequestBodySize,
IdleTimeout: engine.options.IdleTimeout,
ReadTimeout: engine.options.ReadTimeout,
ServerName: engine.GetServerName(),
ContinueHandler: engine.ContinueHandler,
TLS: engine.options.TLS,
HTMLRender: engine.htmlRender,
EnableTrace: engine.IsTraceEnable(),
HijackConnHandle: engine.HijackConnHandle,
StreamRequestBody: engine.options.StreamRequestBody,
GetOnly: engine.options.GetOnly,
DisablePreParseMultipartForm: engine.options.DisablePreParseMultipartForm,
DisableKeepalive: engine.options.DisableKeepalive,
NoDefaultServerHeader: engine.options.NoDefaultServerHeader,
MaxRequestBodySize: engine.options.MaxRequestBodySize,
IdleTimeout: engine.options.IdleTimeout,
ReadTimeout: engine.options.ReadTimeout,
ServerName: engine.GetServerName(),
ContinueHandler: engine.ContinueHandler,
TLS: engine.options.TLS,
HTMLRender: engine.htmlRender,
EnableTrace: engine.IsTraceEnable(),
HijackConnHandle: engine.HijackConnHandle,
DisableHeaderNamesNormalizing: engine.options.DisableHeaderNamesNormalizing,
}
// Idle timeout of standard network must not be zero. Set it to -1 seconds if it is zero.
// Due to the different triggering ways of the network library, see the actual use of this value for the detailed reasons.
Expand Down

0 comments on commit 404144e

Please sign in to comment.