Skip to content

Commit 6d5bdff

Browse files
committed
Add flag to enable cross domain requests in Api
Add the -api-enable-cors flag when running docker in daemon mode to allow CORS requests to be made to the Remote Api. The default value is false for this flag to not allow cross origin request to be made. Also added a handler for OPTIONS requests the standard for cross domain requests is to initially make an OPTIONS request to the api.
1 parent 10ef4f7 commit 6d5bdff

5 files changed

Lines changed: 56 additions & 6 deletions

File tree

api.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,11 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
703703
return nil
704704
}
705705

706+
func writeCorsHeaders(w http.ResponseWriter, r *http.Request) {
707+
w.Header().Add("Access-Control-Allow-Origin", "*")
708+
w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
709+
}
710+
706711
func ListenAndServe(addr string, srv *Server, logging bool) error {
707712
r := mux.NewRouter()
708713
log.Printf("Listening for HTTP on %s\n", addr)
@@ -773,12 +778,20 @@ func ListenAndServe(addr string, srv *Server, logging bool) error {
773778
w.WriteHeader(http.StatusNotFound)
774779
return
775780
}
781+
if srv.enableCors {
782+
writeCorsHeaders(w, r)
783+
}
776784
if err := localFct(srv, version, w, r, mux.Vars(r)); err != nil {
777785
httpError(w, err)
778786
}
779787
}
780788
r.Path("/v{version:[0-9.]+}" + localRoute).Methods(localMethod).HandlerFunc(f)
781789
r.Path(localRoute).Methods(localMethod).HandlerFunc(f)
790+
r.Methods("OPTIONS").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
791+
if srv.enableCors {
792+
writeCorsHeaders(w, r)
793+
}
794+
})
782795
}
783796
}
784797
return http.ListenAndServe(addr, r)

api_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,32 @@ func TestDeleteContainers(t *testing.T) {
12391239
}
12401240
}
12411241

1242+
func TestGetEnabledCors(t *testing.T) {
1243+
runtime, err := newTestRuntime()
1244+
if err != nil {
1245+
t.Fatal(err)
1246+
}
1247+
defer nuke(runtime)
1248+
1249+
srv := &Server{runtime: runtime, enableCors: true}
1250+
1251+
r := httptest.NewRecorder()
1252+
1253+
if err := getVersion(srv, API_VERSION, r, nil, nil); err != nil {
1254+
t.Fatal(err)
1255+
}
1256+
1257+
allowOrigin := r.Header().Get("Access-Control-Allow-Origin")
1258+
allowHeaders := r.Header().Get("Access-Control-Allow-Headers")
1259+
1260+
if allowOrigin != "*" {
1261+
t.Errorf("Expected header Access-Control-Allow-Origin to be \"*\", %s found.", allowOrigin)
1262+
}
1263+
if allowHeaders != "Origin, X-Requested-With, Content-Type, Accept" {
1264+
t.Errorf("Expected header Access-Control-Allow-Headers to be \"Origin, X-Requested-With, Content-Type, Accept\", %s found.", allowHeaders)
1265+
}
1266+
}
1267+
12421268
func TestDeleteImages(t *testing.T) {
12431269
//FIXME: Implement this test
12441270
t.Log("Test not implemented")

docker/docker.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func main() {
3333
bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge")
3434
pidfile := flag.String("p", "/var/run/docker.pid", "File containing process PID")
3535
flHost := flag.String("H", fmt.Sprintf("%s:%d", host, port), "Host:port to bind/connect to")
36+
flEnableCors := flag.Bool("api-enable-cors", false, "Enable CORS requests in the remote api.")
3637
flag.Parse()
3738
if *bridgeName != "" {
3839
docker.NetworkBridgeIface = *bridgeName
@@ -65,7 +66,7 @@ func main() {
6566
flag.Usage()
6667
return
6768
}
68-
if err := daemon(*pidfile, host, port, *flAutoRestart); err != nil {
69+
if err := daemon(*pidfile, host, port, *flAutoRestart, *flEnableCors); err != nil {
6970
log.Fatal(err)
7071
os.Exit(-1)
7172
}
@@ -104,7 +105,7 @@ func removePidFile(pidfile string) {
104105
}
105106
}
106107

107-
func daemon(pidfile, addr string, port int, autoRestart bool) error {
108+
func daemon(pidfile, addr string, port int, autoRestart, enableCors bool) error {
108109
if addr != "127.0.0.1" {
109110
log.Println("/!\\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\")
110111
}
@@ -122,7 +123,7 @@ func daemon(pidfile, addr string, port int, autoRestart bool) error {
122123
os.Exit(0)
123124
}()
124125

125-
server, err := docker.NewServer(autoRestart)
126+
server, err := docker.NewServer(autoRestart, enableCors)
126127
if err != nil {
127128
return err
128129
}

docs/sources/api/docker_remote_api.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,3 +1056,11 @@ Here are the steps of 'docker run' :
10561056

10571057
In this first version of the API, some of the endpoints, like /attach, /pull or /push uses hijacking to transport stdin,
10581058
stdout and stderr on the same socket. This might change in the future.
1059+
1060+
1061+
3.3 CORS Requests
1062+
-----------------
1063+
1064+
To enable cross origin requests to the remote api add the flag "-api-enable-cors" when running docker in daemon mode.
1065+
1066+
docker -d -H="192.168.1.9:4243" -api-enable-cors

server.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ func (srv *Server) ImageInspect(name string) (*Image, error) {
870870
return nil, fmt.Errorf("No such image: %s", name)
871871
}
872872

873-
func NewServer(autoRestart bool) (*Server, error) {
873+
func NewServer(autoRestart, enableCors bool) (*Server, error) {
874874
if runtime.GOARCH != "amd64" {
875875
log.Fatalf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH)
876876
}
@@ -879,12 +879,14 @@ func NewServer(autoRestart bool) (*Server, error) {
879879
return nil, err
880880
}
881881
srv := &Server{
882-
runtime: runtime,
882+
runtime: runtime,
883+
enableCors: enableCors,
883884
}
884885
runtime.srv = srv
885886
return srv, nil
886887
}
887888

888889
type Server struct {
889-
runtime *Runtime
890+
runtime *Runtime
891+
enableCors bool
890892
}

0 commit comments

Comments
 (0)