diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index 09287d6074d..cd12dc777fb 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -52,6 +52,8 @@ const ( // Maximum duration before timing out read/write requests // Set to a value larger than the timeouts in each watch server. ReadWriteTimeout = time.Minute * 60 + //TODO: This can be tightened up. It still matches objects named watch or proxy. + defaultLongRunningRequestRE = "(/|^)((watch|proxy)(/|$)|(logs|portforward|exec)/?$)" ) // APIServer runs a kubernetes api server. @@ -203,7 +205,7 @@ func (s *APIServer) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&s.ExternalHost, "external-hostname", "", "The hostname to use when generating externalized URLs for this master (e.g. Swagger API Docs.)") fs.IntVar(&s.MaxRequestsInFlight, "max-requests-inflight", 400, "The maximum number of requests in flight at a given time. When the server exceeds this, it rejects requests. Zero for no limit.") fs.IntVar(&s.MinRequestTimeout, "min-request-timeout", 1800, "An optional field indicating the minimum number of seconds a handler must keep a request open before timing it out. Currently only honored by the watch request handler, which picks a randomized value above this number as the connection timeout, to spread out load.") - fs.StringVar(&s.LongRunningRequestRE, "long-running-request-regexp", "[.*\\/watch$][^\\/proxy.*]", "A regular expression matching long running requests which should be excluded from maximum inflight request handling.") + fs.StringVar(&s.LongRunningRequestRE, "long-running-request-regexp", defaultLongRunningRequestRE, "A regular expression matching long running requests which should be excluded from maximum inflight request handling.") fs.StringVar(&s.SSHUser, "ssh-user", "", "If non-empty, use secure SSH proxy to the nodes, using this user name") fs.StringVar(&s.SSHKeyfile, "ssh-keyfile", "", "If non-empty, use secure SSH proxy to the nodes, using this user keyfile") } diff --git a/cmd/kube-apiserver/app/server_test.go b/cmd/kube-apiserver/app/server_test.go new file mode 100644 index 00000000000..04ab483c5a6 --- /dev/null +++ b/cmd/kube-apiserver/app/server_test.go @@ -0,0 +1,59 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 app + +import ( + "regexp" + "testing" +) + +func TestLongRunningRequestRegexp(t *testing.T) { + regexp := regexp.MustCompile(defaultLongRunningRequestRE) + dontMatch := []string{ + "/api/v1/watch-namespace/", + "/api/v1/namespace-proxy/", + "/api/v1/namespace-watch", + "/api/v1/namespace-proxy", + "/api/v1/namespace-portforward/pods", + "/api/v1/portforward/pods", + ". anything", + "/ that", + } + doMatch := []string{ + "/api/v1/pods/watch", + "/api/v1/watch/stuff", + "/api/v1/default/service/proxy", + "/api/v1/pods/proxy/path/to/thing", + "/api/v1/namespaces/myns/pods/mypod/logs", + "/api/v1/namespaces/myns/pods/mypod/portforward", + "/api/v1/namespaces/myns/pods/mypod/exec", + "/api/v1/namespaces/myns/pods/mypod/logs/", + "/api/v1/namespaces/myns/pods/mypod/portforward/", + "/api/v1/namespaces/myns/pods/mypod/exec/", + "/api/v1/watch/namespaces/myns/pods", + } + for _, path := range dontMatch { + if regexp.MatchString(path) { + t.Errorf("path should not have match regexp but did: %s", path) + } + } + for _, path := range doMatch { + if !regexp.MatchString(path) { + t.Errorf("path should have match regexp did not: %s", path) + } + } +}