Browse code

Add cors header flag and leave boolean flag not changed

Deprecate api-enable-cors

Update docs & man files

Signed-off-by: harry zhang <resouer@163.com>

resouer authored on 2015/02/09 16:15:07
Showing 7 changed files
... ...
@@ -1229,8 +1229,9 @@ func optionsHandler(eng *engine.Engine, version version.Version, w http.Response
1229 1229
 	w.WriteHeader(http.StatusOK)
1230 1230
 	return nil
1231 1231
 }
1232
-func writeCorsHeaders(w http.ResponseWriter, r *http.Request) {
1233
-	w.Header().Add("Access-Control-Allow-Origin", "*")
1232
+func writeCorsHeaders(w http.ResponseWriter, r *http.Request, corsHeaders string) {
1233
+	log.Debugf("CORS header is enabled and set to: %s", corsHeaders)
1234
+	w.Header().Add("Access-Control-Allow-Origin", corsHeaders)
1234 1235
 	w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth")
1235 1236
 	w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS")
1236 1237
 }
... ...
@@ -1240,7 +1241,7 @@ func ping(eng *engine.Engine, version version.Version, w http.ResponseWriter, r
1240 1240
 	return err
1241 1241
 }
1242 1242
 
1243
-func makeHttpHandler(eng *engine.Engine, logging bool, localMethod string, localRoute string, handlerFunc HttpApiFunc, enableCors bool, dockerVersion version.Version) http.HandlerFunc {
1243
+func makeHttpHandler(eng *engine.Engine, logging bool, localMethod string, localRoute string, handlerFunc HttpApiFunc, corsHeaders string, dockerVersion version.Version) http.HandlerFunc {
1244 1244
 	return func(w http.ResponseWriter, r *http.Request) {
1245 1245
 		// log the request
1246 1246
 		log.Debugf("Calling %s %s", localMethod, localRoute)
... ...
@@ -1259,8 +1260,8 @@ func makeHttpHandler(eng *engine.Engine, logging bool, localMethod string, local
1259 1259
 		if version == "" {
1260 1260
 			version = api.APIVERSION
1261 1261
 		}
1262
-		if enableCors {
1263
-			writeCorsHeaders(w, r)
1262
+		if corsHeaders != "" {
1263
+			writeCorsHeaders(w, r, corsHeaders)
1264 1264
 		}
1265 1265
 
1266 1266
 		if version.GreaterThan(api.APIVERSION) {
... ...
@@ -1302,7 +1303,8 @@ func AttachProfiler(router *mux.Router) {
1302 1302
 	router.HandleFunc("/debug/pprof/threadcreate", pprof.Handler("threadcreate").ServeHTTP)
1303 1303
 }
1304 1304
 
1305
-func createRouter(eng *engine.Engine, logging, enableCors bool, dockerVersion string) *mux.Router {
1305
+// we keep enableCors just for legacy usage, need to be removed in the future
1306
+func createRouter(eng *engine.Engine, logging, enableCors bool, corsHeaders string, dockerVersion string) *mux.Router {
1306 1307
 	r := mux.NewRouter()
1307 1308
 	if os.Getenv("DEBUG") != "" {
1308 1309
 		AttachProfiler(r)
... ...
@@ -1364,6 +1366,12 @@ func createRouter(eng *engine.Engine, logging, enableCors bool, dockerVersion st
1364 1364
 		},
1365 1365
 	}
1366 1366
 
1367
+	// If "api-cors-header" is not given, but "api-enable-cors" is true, we set cors to "*"
1368
+	// otherwise, all head values will be passed to HTTP handler
1369
+	if corsHeaders == "" && enableCors {
1370
+		corsHeaders = "*"
1371
+	}
1372
+
1367 1373
 	for method, routes := range m {
1368 1374
 		for route, fct := range routes {
1369 1375
 			log.Debugf("Registering %s, %s", method, route)
... ...
@@ -1373,7 +1381,7 @@ func createRouter(eng *engine.Engine, logging, enableCors bool, dockerVersion st
1373 1373
 			localMethod := method
1374 1374
 
1375 1375
 			// build the handler function
1376
-			f := makeHttpHandler(eng, logging, localMethod, localRoute, localFct, enableCors, version.Version(dockerVersion))
1376
+			f := makeHttpHandler(eng, logging, localMethod, localRoute, localFct, corsHeaders, version.Version(dockerVersion))
1377 1377
 
1378 1378
 			// add the new route
1379 1379
 			if localRoute == "" {
... ...
@@ -1392,7 +1400,7 @@ func createRouter(eng *engine.Engine, logging, enableCors bool, dockerVersion st
1392 1392
 // FIXME: refactor this to be part of Server and not require re-creating a new
1393 1393
 // router each time. This requires first moving ListenAndServe into Server.
1394 1394
 func ServeRequest(eng *engine.Engine, apiversion version.Version, w http.ResponseWriter, req *http.Request) {
1395
-	router := createRouter(eng, false, true, "")
1395
+	router := createRouter(eng, false, true, "", "")
1396 1396
 	// Insert APIVERSION into the request as a convenience
1397 1397
 	req.URL.Path = fmt.Sprintf("/v%s%s", apiversion, req.URL.Path)
1398 1398
 	router.ServeHTTP(w, req)
... ...
@@ -1401,7 +1409,7 @@ func ServeRequest(eng *engine.Engine, apiversion version.Version, w http.Respons
1401 1401
 // serveFd creates an http.Server and sets it up to serve given a socket activated
1402 1402
 // argument.
1403 1403
 func serveFd(addr string, job *engine.Job) error {
1404
-	r := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("Version"))
1404
+	r := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("CorsHeaders"), job.Getenv("Version"))
1405 1405
 
1406 1406
 	ls, e := systemd.ListenFD(addr)
1407 1407
 	if e != nil {
... ...
@@ -1543,7 +1551,7 @@ func setupTcpHttp(addr string, job *engine.Job) (*HttpServer, error) {
1543 1543
 		log.Infof("/!\\ DON'T BIND ON ANY IP ADDRESS WITHOUT setting -tlsverify IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\")
1544 1544
 	}
1545 1545
 
1546
-	r := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("Version"))
1546
+	r := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("CorsHeaders"), job.Getenv("Version"))
1547 1547
 
1548 1548
 	l, err := newListener("tcp", addr, job.GetenvBool("BufferRequests"))
1549 1549
 	if err != nil {
... ...
@@ -27,7 +27,7 @@ func NewServer(proto, addr string, job *engine.Job) (Server, error) {
27 27
 }
28 28
 
29 29
 func setupUnixHttp(addr string, job *engine.Job) (*HttpServer, error) {
30
-	r := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("Version"))
30
+    r := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("CorsHeaders"), job.Getenv("Version"))
31 31
 
32 32
 	if err := syscall.Unlink(addr); err != nil && !os.IsNotExist(err) {
33 33
 		return nil, err
... ...
@@ -39,6 +39,7 @@ type Config struct {
39 39
 	Mtu                         int
40 40
 	SocketGroup                 string
41 41
 	EnableCors                  bool
42
+	CorsHeaders                 string
42 43
 	DisableNetwork              bool
43 44
 	EnableSelinuxSupport        bool
44 45
 	Context                     map[string][]string
... ...
@@ -68,7 +69,8 @@ func (config *Config) InstallFlags() {
68 68
 	flag.BoolVar(&config.EnableSelinuxSupport, []string{"-selinux-enabled"}, false, "Enable selinux support")
69 69
 	flag.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, "Set the containers network MTU")
70 70
 	flag.StringVar(&config.SocketGroup, []string{"G", "-group"}, "docker", "Group for the unix socket")
71
-	flag.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API")
71
+	flag.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "#-api-enable-cors"}, false, "Enable CORS headers in the remote API")
72
+	flag.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", "Set CORS headers in the remote API")
72 73
 	opts.IPVar(&config.DefaultIp, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports")
73 74
 	opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options")
74 75
 	// FIXME: why the inconsistency between "hosts" and "sockets"?
... ...
@@ -131,6 +131,7 @@ func mainDaemon() {
131 131
 	job := eng.Job("serveapi", flHosts...)
132 132
 	job.SetenvBool("Logging", true)
133 133
 	job.SetenvBool("EnableCors", daemonCfg.EnableCors)
134
+	job.Setenv("CorsHeaders", daemonCfg.CorsHeaders)
134 135
 	job.Setenv("Version", dockerversion.VERSION)
135 136
 	job.Setenv("SocketGroup", daemonCfg.SocketGroup)
136 137
 
... ...
@@ -37,6 +37,9 @@ unix://[/path/to/socket] to use.
37 37
 **--api-enable-cors**=*true*|*false*
38 38
   Enable CORS headers in the remote API. Default is false.
39 39
 
40
+**--api-cors-header**=""
41
+  Set CORS headers in the remote API. Default is cors disabled. Give urls like "http://foo, http://bar, ...". Give "*" to allow all.
42
+
40 43
 **-b**=""
41 44
   Attach containers to a pre\-existing network bridge; use 'none' to disable container networking
42 45
 
... ...
@@ -1968,7 +1968,7 @@ This might change in the future.
1968 1968
 
1969 1969
 ## 3.3 CORS Requests
1970 1970
 
1971
-To enable cross origin requests to the remote api add the flag
1972
-"--api-enable-cors" when running docker in daemon mode.
1971
+To set cross origin requests to the remote api, please add flag "--api-enable-cors"
1972
+when running docker in daemon mode.
1973 1973
 
1974
-    $ docker -d -H="192.168.1.9:2375" --api-enable-cors
1974
+    $ docker -d -H="192.168.1.9:2375" --api-cors-header="http://foo.bar"
... ...
@@ -75,6 +75,7 @@ expect an integer, and they can only be specified once.
75 75
 
76 76
     Options:
77 77
       --api-enable-cors=false                Enable CORS headers in the remote API
78
+      --api-cors-header=""                   Set CORS headers in the remote API
78 79
       -b, --bridge=""                        Attach containers to a network bridge
79 80
       --bip=""                               Specify network bridge IP
80 81
       -D, --debug=false                      Enable debug mode