// Copyright 2015 CoreOS, Inc. // // 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 proxy import ( "net/http" ) const ( // DefaultMaxIdleConnsPerHost indicates the default maximal idle connections // maintained between proxy and each member. We set it to 128 to // let proxy handle 128 concurrent requests in long term smoothly. // If the number of concurrent requests is bigger than this value, // proxy needs to create one new connection when handling each request in // the delta, which is bad because the creation consumes resource and // may eat up ephemeral ports. DefaultMaxIdleConnsPerHost = 128 ) // GetProxyURLs is a function which should return the current set of URLs to // which client requests should be proxied. This function will be queried // periodically by the proxy Handler to refresh the set of available // backends. type GetProxyURLs func() []string // NewHandler creates a new HTTP handler, listening on the given transport, // which will proxy requests to an etcd cluster. // The handler will periodically update its view of the cluster. func NewHandler(t *http.Transport, urlsFunc GetProxyURLs) http.Handler { return &reverseProxy{ director: newDirector(urlsFunc), transport: t, } } // NewReadonlyHandler wraps the given HTTP handler to allow only GET requests func NewReadonlyHandler(hdlr http.Handler) http.Handler { readonly := readonlyHandlerFunc(hdlr) return http.HandlerFunc(readonly) } func readonlyHandlerFunc(next http.Handler) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, req *http.Request) { if req.Method != "GET" { w.WriteHeader(http.StatusNotImplemented) return } next.ServeHTTP(w, req) } }