mirror of https://github.com/portainer/portainer
fix(backend): use a thread-safe implementation of map for proxies (#728)
parent
9e818c2882
commit
a99c6c4cbe
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue