mirror of
https://github.com/caddyserver/caddy.git
synced 2024-11-26 02:09:47 +08:00
b0d5c2c8ae
* implement default values for header directive closes #3804 * remove `set_default` header op and rely on "require" handler instead This has the following advantages over the previous attempt: - It does not introduce a new operation for headers, but rather nicely extends over an existing feature in the header handler. - It removes the need to specify the header as "deferred" because it is already implicitely deferred by the use of the require handler. This should be less confusing to the user. * add integration test for header directive in caddyfile * bubble up errors when parsing caddyfile header directive * don't export unnecessarily and don't canonicalize headers unnecessarily * fix response headers not passed in blocks * caddyfile: fix clash when using default header in block Each header is now set in a separate handler so that it doesn't clash with other headers set/added/deleted in the same block. * caddyhttp: New idle_timeout default of 5m * reverseproxy: fix random hangs on http/2 requests with server push (#3875) see https://github.com/golang/go/issues/42534 * Refactor and cleanup with improvements * More specific link Co-authored-by: Matthew Holt <mholt@users.noreply.github.com> Co-authored-by: Денис Телюх <telyukh.denis@gmail.com>
107 lines
3.1 KiB
Go
107 lines
3.1 KiB
Go
// Copyright 2015 Matthew Holt and The Caddy Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package push
|
|
|
|
import (
|
|
"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
|
|
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
|
"github.com/caddyserver/caddy/v2/modules/caddyhttp/headers"
|
|
)
|
|
|
|
func init() {
|
|
httpcaddyfile.RegisterHandlerDirective("push", parseCaddyfile)
|
|
}
|
|
|
|
// parseCaddyfile sets up the push handler. Syntax:
|
|
//
|
|
// push [<matcher>] [<resource>] {
|
|
// [GET|HEAD] <resource>
|
|
// headers {
|
|
// [+]<field> [<value|regexp> [<replacement>]]
|
|
// -<field>
|
|
// }
|
|
// }
|
|
//
|
|
// A single resource can be specified inline without opening a
|
|
// block for the most common/simple case. Or, a block can be
|
|
// opened and multiple resources can be specified, one per
|
|
// line, optionally preceded by the method. The headers
|
|
// subdirective can be used to customize the headers that
|
|
// are set on each (synthetic) push request, using the same
|
|
// syntax as the 'header' directive for request headers.
|
|
// Placeholders are accepted in resource and header field
|
|
// name and value and replacement tokens.
|
|
func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
|
|
handler := new(Handler)
|
|
|
|
for h.Next() {
|
|
if h.NextArg() {
|
|
handler.Resources = append(handler.Resources, Resource{Target: h.Val()})
|
|
}
|
|
|
|
// optional block
|
|
for outerNesting := h.Nesting(); h.NextBlock(outerNesting); {
|
|
switch h.Val() {
|
|
case "headers":
|
|
if h.NextArg() {
|
|
return nil, h.ArgErr()
|
|
}
|
|
for innerNesting := h.Nesting(); h.NextBlock(innerNesting); {
|
|
var err error
|
|
|
|
// include current token, which we treat as an argument here
|
|
args := []string{h.Val()}
|
|
args = append(args, h.RemainingArgs()...)
|
|
|
|
if handler.Headers == nil {
|
|
handler.Headers = new(HeaderConfig)
|
|
}
|
|
|
|
switch len(args) {
|
|
case 1:
|
|
err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], "", "")
|
|
case 2:
|
|
err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], args[1], "")
|
|
case 3:
|
|
err = headers.CaddyfileHeaderOp(&handler.Headers.HeaderOps, args[0], args[1], args[2])
|
|
default:
|
|
return nil, h.ArgErr()
|
|
}
|
|
|
|
if err != nil {
|
|
return nil, h.Err(err.Error())
|
|
}
|
|
}
|
|
|
|
case "GET", "HEAD":
|
|
method := h.Val()
|
|
if !h.NextArg() {
|
|
return nil, h.ArgErr()
|
|
}
|
|
target := h.Val()
|
|
handler.Resources = append(handler.Resources, Resource{
|
|
Method: method,
|
|
Target: target,
|
|
})
|
|
|
|
default:
|
|
handler.Resources = append(handler.Resources, Resource{Target: h.Val()})
|
|
}
|
|
}
|
|
}
|
|
|
|
return handler, nil
|
|
}
|