| 
									
										
										
										
											2015-07-01 11:15:48 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
											  
											
												config/main: Re-write config files - add to new config v3
- New config format.
```
{
	"version": "3",
	"address": ":9000",
    "backend": {
          "type": "fs",
          "disk": "/path"
    },
	"credential": {
		"accessKey": "WLGDGYAQYIGI833EV05A",
		"secretKey": "BYvgJM101sHngl2uzjXS/OBF/aMxAN06JrJ3qJlF"
	},
	"region": "us-east-1",
	"logger": {
		"file": {
			"enable": false,
			"fileName": "",
			"level": "error"
		},
		"syslog": {
			"enable": false,
			"address": "",
			"level": "debug"
		},
		"console": {
			"enable": true,
			"level": "fatal"
		}
	}
}
```
New command lines in lieu of supporting XL.
Minio initialize filesystem backend.
~~~
$ minio init fs <path>
~~~
Minio initialize XL backend.
~~~
$ minio init xl <url1>...<url16>
~~~
For 'fs' backend it starts the server.
~~~
$ minio server
~~~
For 'xl' backend it waits for servers to join.
~~~
$ minio server
... [PROGRESS BAR] of servers connecting
~~~
Now on other servers execute 'join' and they connect.
~~~
....
minio join <url1> -- from <url2> && minio server
minio join <url1> -- from <url3> && minio server
...
...
minio join <url1> -- from <url16> && minio server
~~~
											
										 
											2016-02-13 07:27:10 +08:00
										 |  |  |  * Minio Cloud Storage, (C) 2015, 2016 Minio, Inc. | 
					
						
							| 
									
										
										
										
											2015-07-01 11:15:48 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  | package cmd | 
					
						
							| 
									
										
										
										
											2015-07-01 11:15:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2016-07-28 19:00:33 +08:00
										 |  |  | 	"os" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2015-07-01 11:15:48 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-23 09:34:00 +08:00
										 |  |  | 	router "github.com/gorilla/mux" | 
					
						
							| 
									
										
										
										
											2015-07-01 11:15:48 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 10:22:27 +08:00
										 |  |  | func newObjectLayerFn() ObjectLayer { | 
					
						
							|  |  |  | 	objLayerMutex.Lock() | 
					
						
							|  |  |  | 	defer objLayerMutex.Unlock() | 
					
						
							|  |  |  | 	return globalObjectAPI | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-11 05:38:15 +08:00
										 |  |  | // newObjectLayer - initialize any object layer depending on the number of disks.
 | 
					
						
							|  |  |  | func newObjectLayer(disks, ignoredDisks []string) (ObjectLayer, error) { | 
					
						
							| 
									
										
										
										
											2016-09-07 04:30:05 +08:00
										 |  |  | 	var objAPI ObjectLayer | 
					
						
							|  |  |  | 	var err error | 
					
						
							| 
									
										
										
										
											2016-07-11 05:38:15 +08:00
										 |  |  | 	if len(disks) == 1 { | 
					
						
							| 
									
										
										
										
											2016-04-30 05:24:10 +08:00
										 |  |  | 		// Initialize FS object layer.
 | 
					
						
							| 
									
										
										
										
											2016-09-07 04:30:05 +08:00
										 |  |  | 		objAPI, err = newFSObjects(disks[0]) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		// Initialize XL object layer.
 | 
					
						
							|  |  |  | 		objAPI, err = newXLObjects(disks, ignoredDisks) | 
					
						
							| 
									
										
										
										
											2016-03-28 12:52:38 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-07 04:30:05 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2016-05-14 14:04:10 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-07 04:30:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 10:22:27 +08:00
										 |  |  | 	// Migrate bucket policy from configDir to .minio.sys/buckets/
 | 
					
						
							|  |  |  | 	err = migrateBucketPolicyConfig(objAPI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-08-25 14:04:34 +08:00
										 |  |  | 		errorIf(err, "Unable to migrate bucket policy from config directory") | 
					
						
							| 
									
										
										
										
											2016-08-31 10:22:27 +08:00
										 |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 10:22:27 +08:00
										 |  |  | 	err = cleanupOldBucketPolicyConfigs() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-08-25 14:04:34 +08:00
										 |  |  | 		errorIf(err, "Unable to clean up bucket policy from config directory.") | 
					
						
							| 
									
										
										
										
											2016-08-31 10:22:27 +08:00
										 |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 10:22:27 +08:00
										 |  |  | 	// Register the callback that should be called when the process shuts down.
 | 
					
						
							|  |  |  | 	globalShutdownCBs.AddObjectLayerCB(func() errCode { | 
					
						
							| 
									
										
										
										
											2016-09-07 04:30:05 +08:00
										 |  |  | 		if objAPI != nil { | 
					
						
							|  |  |  | 			if sErr := objAPI.Shutdown(); sErr != nil { | 
					
						
							| 
									
										
										
										
											2016-09-15 07:41:39 +08:00
										 |  |  | 				errorIf(err, "Unable to shutdown object API.") | 
					
						
							| 
									
										
										
										
											2016-09-07 04:30:05 +08:00
										 |  |  | 				return exitFailure | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-08-31 10:22:27 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return exitSuccess | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 10:22:27 +08:00
										 |  |  | 	// Initialize a new event notifier.
 | 
					
						
							|  |  |  | 	err = initEventNotifier(objAPI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-08-25 14:04:34 +08:00
										 |  |  | 		errorIf(err, "Unable to initialize event notification.") | 
					
						
							| 
									
										
										
										
											2016-08-31 10:22:27 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 10:22:27 +08:00
										 |  |  | 	// Initialize and load bucket policies.
 | 
					
						
							|  |  |  | 	err = initBucketPolicies(objAPI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-08-25 14:04:34 +08:00
										 |  |  | 		errorIf(err, "Unable to load all bucket policies.") | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-08-31 10:22:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Success.
 | 
					
						
							|  |  |  | 	return objAPI, nil | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												routers: Fix a crash while initializing network fs. (#1382)
Crash happens when 'minio server filename' a file name is
provided instead of a directory on command line argument.
```
panic: runtime error: slice bounds out of range
goroutine 1 [running]:
panic(0x5eb460, 0xc82000e0b0)
	/usr/local/opt/go/libexec/src/runtime/panic.go:464 +0x3e6
main.splitNetPath(0x7fff5fbff9bd, 0x7, 0x0, 0x0, 0x0, 0x0)
	/Users/harsha/mygo/src/github.com/minio/minio/network-fs.go:49 +0xb7
main.newNetworkFS(0x7fff5fbff9bd, 0x7, 0x0, 0x0, 0x0, 0x0)
	/Users/harsha/mygo/src/github.com/minio/minio/network-fs.go:90 +0x20a
main.configureServerHandler(0xc82024e1c8, 0x5, 0xc8200640e0, 0x1, 0x1, 0x0, 0x0)
	/Users/harsha/mygo/src/github.com/minio/minio/routers.go:43 +0x6ce
main.configureServer(0xc82024e1c8, 0x5, 0xc8200640e0, 0x1, 0x1, 0x5)
	/Users/harsha/mygo/src/github.com/minio/minio/server-main.go:86 +0x67
```
											
										 
											2016-04-26 09:10:40 +08:00
										 |  |  | // configureServer handler returns final handler for the http server.
 | 
					
						
							|  |  |  | func configureServerHandler(srvCmdConfig serverCmdConfig) http.Handler { | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 	// Initialize storage rpc servers for every disk that is hosted on this node.
 | 
					
						
							|  |  |  | 	storageRPCs, err := newRPCServer(srvCmdConfig) | 
					
						
							| 
									
										
										
										
											2016-05-17 05:31:28 +08:00
										 |  |  | 	fatalIf(err, "Unable to initialize storage RPC server.") | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-17 14:24:51 +08:00
										 |  |  | 	// Initialize and monitor shutdown signals.
 | 
					
						
							|  |  |  | 	err = initGracefulShutdown(os.Exit) | 
					
						
							|  |  |  | 	fatalIf(err, "Unable to initialize graceful shutdown operation") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												config/main: Re-write config files - add to new config v3
- New config format.
```
{
	"version": "3",
	"address": ":9000",
    "backend": {
          "type": "fs",
          "disk": "/path"
    },
	"credential": {
		"accessKey": "WLGDGYAQYIGI833EV05A",
		"secretKey": "BYvgJM101sHngl2uzjXS/OBF/aMxAN06JrJ3qJlF"
	},
	"region": "us-east-1",
	"logger": {
		"file": {
			"enable": false,
			"fileName": "",
			"level": "error"
		},
		"syslog": {
			"enable": false,
			"address": "",
			"level": "debug"
		},
		"console": {
			"enable": true,
			"level": "fatal"
		}
	}
}
```
New command lines in lieu of supporting XL.
Minio initialize filesystem backend.
~~~
$ minio init fs <path>
~~~
Minio initialize XL backend.
~~~
$ minio init xl <url1>...<url16>
~~~
For 'fs' backend it starts the server.
~~~
$ minio server
~~~
For 'xl' backend it waits for servers to join.
~~~
$ minio server
... [PROGRESS BAR] of servers connecting
~~~
Now on other servers execute 'join' and they connect.
~~~
....
minio join <url1> -- from <url2> && minio server
minio join <url1> -- from <url3> && minio server
...
...
minio join <url1> -- from <url16> && minio server
~~~
											
										 
											2016-02-13 07:27:10 +08:00
										 |  |  | 	// Initialize API.
 | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	apiHandlers := objectAPIHandlers{ | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 		ObjectAPI: newObjectLayerFn, | 
					
						
							| 
									
										
											  
											
												config/main: Re-write config files - add to new config v3
- New config format.
```
{
	"version": "3",
	"address": ":9000",
    "backend": {
          "type": "fs",
          "disk": "/path"
    },
	"credential": {
		"accessKey": "WLGDGYAQYIGI833EV05A",
		"secretKey": "BYvgJM101sHngl2uzjXS/OBF/aMxAN06JrJ3qJlF"
	},
	"region": "us-east-1",
	"logger": {
		"file": {
			"enable": false,
			"fileName": "",
			"level": "error"
		},
		"syslog": {
			"enable": false,
			"address": "",
			"level": "debug"
		},
		"console": {
			"enable": true,
			"level": "fatal"
		}
	}
}
```
New command lines in lieu of supporting XL.
Minio initialize filesystem backend.
~~~
$ minio init fs <path>
~~~
Minio initialize XL backend.
~~~
$ minio init xl <url1>...<url16>
~~~
For 'fs' backend it starts the server.
~~~
$ minio server
~~~
For 'xl' backend it waits for servers to join.
~~~
$ minio server
... [PROGRESS BAR] of servers connecting
~~~
Now on other servers execute 'join' and they connect.
~~~
....
minio join <url1> -- from <url2> && minio server
minio join <url1> -- from <url3> && minio server
...
...
minio join <url1> -- from <url16> && minio server
~~~
											
										 
											2016-02-13 07:27:10 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
											  
											
												fs: Break fs package to top-level and introduce ObjectAPI interface.
ObjectAPI interface brings in changes needed for XL ObjectAPI layer.
The new interface for any ObjectAPI layer is as below
```
// ObjectAPI interface.
type ObjectAPI interface {
        // Bucket resource API.
        DeleteBucket(bucket string) *probe.Error
        ListBuckets() ([]BucketInfo, *probe.Error)
        MakeBucket(bucket string) *probe.Error
        GetBucketInfo(bucket string) (BucketInfo, *probe.Error)
        // Bucket query API.
        ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsResult, *probe.Error)
        ListMultipartUploads(bucket string, resources BucketMultipartResourcesMetadata) (BucketMultipartResourcesMetadata, *probe.Error)
        // Object resource API.
        GetObject(bucket, object string, startOffset int64) (io.ReadCloser, *probe.Error)
        GetObjectInfo(bucket, object string) (ObjectInfo, *probe.Error)
        PutObject(bucket string, object string, size int64, data io.Reader, metadata map[string]string) (ObjectInfo, *probe.Error)
        DeleteObject(bucket, object string) *probe.Error
        // Object query API.
        NewMultipartUpload(bucket, object string) (string, *probe.Error)
        PutObjectPart(bucket, object, uploadID string, partID int, size int64, data io.Reader, md5Hex string) (string, *probe.Error)
        ListObjectParts(bucket, object string, resources ObjectResourcesMetadata) (ObjectResourcesMetadata, *probe.Error)
        CompleteMultipartUpload(bucket string, object string, uploadID string, parts []CompletePart) (ObjectInfo, *probe.Error)
        AbortMultipartUpload(bucket, object, uploadID string) *probe.Error
}
```
											
										 
											2016-03-31 07:15:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												config/main: Re-write config files - add to new config v3
- New config format.
```
{
	"version": "3",
	"address": ":9000",
    "backend": {
          "type": "fs",
          "disk": "/path"
    },
	"credential": {
		"accessKey": "WLGDGYAQYIGI833EV05A",
		"secretKey": "BYvgJM101sHngl2uzjXS/OBF/aMxAN06JrJ3qJlF"
	},
	"region": "us-east-1",
	"logger": {
		"file": {
			"enable": false,
			"fileName": "",
			"level": "error"
		},
		"syslog": {
			"enable": false,
			"address": "",
			"level": "debug"
		},
		"console": {
			"enable": true,
			"level": "fatal"
		}
	}
}
```
New command lines in lieu of supporting XL.
Minio initialize filesystem backend.
~~~
$ minio init fs <path>
~~~
Minio initialize XL backend.
~~~
$ minio init xl <url1>...<url16>
~~~
For 'fs' backend it starts the server.
~~~
$ minio server
~~~
For 'xl' backend it waits for servers to join.
~~~
$ minio server
... [PROGRESS BAR] of servers connecting
~~~
Now on other servers execute 'join' and they connect.
~~~
....
minio join <url1> -- from <url2> && minio server
minio join <url1> -- from <url3> && minio server
...
...
minio join <url1> -- from <url16> && minio server
~~~
											
										 
											2016-02-13 07:27:10 +08:00
										 |  |  | 	// Initialize Web.
 | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	webHandlers := &webAPIHandlers{ | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 		ObjectAPI: newObjectLayerFn, | 
					
						
							| 
									
										
										
										
											2015-09-19 17:36:50 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-02-18 18:13:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 05:50:50 +08:00
										 |  |  | 	// Initialize Controller.
 | 
					
						
							| 
									
										
										
										
											2016-08-25 01:14:14 +08:00
										 |  |  | 	controllerHandlers := &controllerAPIHandlers{ | 
					
						
							| 
									
										
										
										
											2016-08-19 05:50:50 +08:00
										 |  |  | 		ObjectAPI: newObjectLayerFn, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-28 03:37:21 +08:00
										 |  |  | 	// Initialize router.
 | 
					
						
							|  |  |  | 	mux := router.NewRouter() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Register all routers.
 | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 	registerStorageRPCRouters(mux, storageRPCs) | 
					
						
							| 
									
										
										
										
											2016-08-19 05:50:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Initialize distributed NS lock.
 | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 	initDistributedNSLock(mux, srvCmdConfig) | 
					
						
							| 
									
										
										
										
											2016-07-28 19:00:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-25 01:14:14 +08:00
										 |  |  | 	// Register controller rpc router.
 | 
					
						
							|  |  |  | 	registerControllerRPCRouter(mux, controllerHandlers) | 
					
						
							| 
									
										
										
										
											2016-08-18 02:36:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-28 19:00:33 +08:00
										 |  |  | 	// set environmental variable MINIO_BROWSER=off to disable minio web browser.
 | 
					
						
							|  |  |  | 	// By default minio web browser is enabled.
 | 
					
						
							|  |  |  | 	if !strings.EqualFold(os.Getenv("MINIO_BROWSER"), "off") { | 
					
						
							|  |  |  | 		registerWebRouter(mux, webHandlers) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-28 03:37:21 +08:00
										 |  |  | 	// Add new routers here.
 | 
					
						
							| 
									
										
										
										
											2016-08-25 01:14:14 +08:00
										 |  |  | 	registerAPIRouter(mux, apiHandlers) | 
					
						
							| 
									
										
										
										
											2016-03-28 03:37:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-25 01:14:14 +08:00
										 |  |  | 	// List of some generic handlers which are applied for all incoming requests.
 | 
					
						
							| 
									
										
										
										
											2016-02-05 06:57:20 +08:00
										 |  |  | 	var handlerFns = []HandlerFunc{ | 
					
						
							| 
									
										
										
										
											2016-06-26 18:18:07 +08:00
										 |  |  | 		// Limits the number of concurrent http requests.
 | 
					
						
							|  |  |  | 		setRateLimitHandler, | 
					
						
							| 
									
										
										
										
											2016-07-29 03:02:22 +08:00
										 |  |  | 		// Limits all requests size to a maximum fixed limit
 | 
					
						
							|  |  |  | 		setRequestSizeLimitHandler, | 
					
						
							| 
									
										
										
										
											2016-07-28 10:53:55 +08:00
										 |  |  | 		// Adds 'crossdomain.xml' policy handler to serve legacy flash clients.
 | 
					
						
							|  |  |  | 		setCrossDomainPolicy, | 
					
						
							|  |  |  | 		// Redirect some pre-defined browser request paths to a static location prefix.
 | 
					
						
							| 
									
										
										
										
											2016-02-17 10:50:36 +08:00
										 |  |  | 		setBrowserRedirectHandler, | 
					
						
							|  |  |  | 		// Validates if incoming request is for restricted buckets.
 | 
					
						
							|  |  |  | 		setPrivateBucketHandler, | 
					
						
							|  |  |  | 		// Adds cache control for all browser requests.
 | 
					
						
							|  |  |  | 		setBrowserCacheControlHandler, | 
					
						
							|  |  |  | 		// Validates all incoming requests to have a valid date header.
 | 
					
						
							| 
									
										
										
										
											2016-02-05 06:57:20 +08:00
										 |  |  | 		setTimeValidityHandler, | 
					
						
							| 
									
										
										
										
											2016-02-17 10:50:36 +08:00
										 |  |  | 		// CORS setting for all browser API requests.
 | 
					
						
							|  |  |  | 		setCorsHandler, | 
					
						
							|  |  |  | 		// Validates all incoming URL resources, for invalid/unsupported
 | 
					
						
							|  |  |  | 		// resources client receives a HTTP error.
 | 
					
						
							| 
									
										
										
										
											2016-02-05 06:57:20 +08:00
										 |  |  | 		setIgnoreResourcesHandler, | 
					
						
							| 
									
										
										
										
											2016-02-17 10:50:36 +08:00
										 |  |  | 		// Auth handler verifies incoming authorization headers and
 | 
					
						
							|  |  |  | 		// routes them accordingly. Client receives a HTTP error for
 | 
					
						
							|  |  |  | 		// invalid/unsupported signatures.
 | 
					
						
							| 
									
										
										
										
											2016-02-16 09:42:39 +08:00
										 |  |  | 		setAuthHandler, | 
					
						
							| 
									
										
										
										
											2016-03-28 03:37:21 +08:00
										 |  |  | 		// Add new handlers here.
 | 
					
						
							| 
									
										
										
										
											2015-10-07 14:32:20 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-02-18 18:13:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Register rest of the handlers.
 | 
					
						
							| 
									
										
										
										
											2016-02-05 06:57:20 +08:00
										 |  |  | 	return registerHandlers(mux, handlerFns...) | 
					
						
							| 
									
										
										
										
											2015-07-01 11:15:48 +08:00
										 |  |  | } |