fix(backend): use a thread-safe implementation of map for proxies (#728)

pull/731/head
Anthony Lapenna 2017-03-28 14:28:17 +02:00 committed by GitHub
parent 9e818c2882
commit a99c6c4cbe
1 changed files with 9 additions and 5 deletions

View File

@ -11,6 +11,7 @@ import (
"os" "os"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/orcaman/concurrent-map"
) )
// DockerHandler represents an HTTP API handler for proxying requests to the Docker API. // DockerHandler represents an HTTP API handler for proxying requests to the Docker API.
@ -19,7 +20,7 @@ type DockerHandler struct {
Logger *log.Logger Logger *log.Logger
EndpointService portainer.EndpointService EndpointService portainer.EndpointService
ProxyFactory ProxyFactory ProxyFactory ProxyFactory
proxies map[portainer.EndpointID]http.Handler proxies cmap.ConcurrentMap
} }
// NewDockerHandler returns a new instance of DockerHandler. // NewDockerHandler returns a new instance of DockerHandler.
@ -30,7 +31,7 @@ func NewDockerHandler(mw *middleWareService, resourceControlService portainer.Re
ProxyFactory: ProxyFactory{ ProxyFactory: ProxyFactory{
ResourceControlService: resourceControlService, ResourceControlService: resourceControlService,
}, },
proxies: make(map[portainer.EndpointID]http.Handler), proxies: cmap.New(),
} }
h.PathPrefix("/{id}/").Handler( h.PathPrefix("/{id}/").Handler(
mw.authenticated(http.HandlerFunc(h.proxyRequestsToDockerAPI))) mw.authenticated(http.HandlerFunc(h.proxyRequestsToDockerAPI)))
@ -72,13 +73,16 @@ func (handler *DockerHandler) proxyRequestsToDockerAPI(w http.ResponseWriter, r
return return
} }
proxy := handler.proxies[endpointID] var proxy http.Handler
if proxy == nil { item, ok := handler.proxies.Get(string(endpointID))
if !ok {
proxy, err = handler.createAndRegisterEndpointProxy(endpoint) proxy, err = handler.createAndRegisterEndpointProxy(endpoint)
if err != nil { if err != nil {
Error(w, err, http.StatusBadRequest, handler.Logger) Error(w, err, http.StatusBadRequest, handler.Logger)
return return
} }
} else {
proxy = item.(http.Handler)
} }
http.StripPrefix("/"+id, proxy).ServeHTTP(w, r) http.StripPrefix("/"+id, proxy).ServeHTTP(w, r)
} }
@ -105,6 +109,6 @@ func (handler *DockerHandler) createAndRegisterEndpointProxy(endpoint *portainer
proxy = handler.ProxyFactory.newSocketProxy(endpointURL.Path) proxy = handler.ProxyFactory.newSocketProxy(endpointURL.Path)
} }
handler.proxies[endpoint.ID] = proxy handler.proxies.Set(string(endpoint.ID), proxy)
return proxy, nil return proxy, nil
} }