[Server] Listen and serve on a unix socket
Allow to use a unix socket as a listener. To specify an endpoint type we use an optional configuration field 'net', as there's no way to distinguish a relative socket path from a hostname. Signed-off-by: Anton Tiurin <noxiouz@yandex.ru>
This commit is contained in:
parent
ced8a0378b
commit
ad80cbe1ea
5 changed files with 157 additions and 55 deletions
|
@ -21,6 +21,7 @@ import (
|
||||||
_ "github.com/docker/distribution/registry/auth/silly"
|
_ "github.com/docker/distribution/registry/auth/silly"
|
||||||
_ "github.com/docker/distribution/registry/auth/token"
|
_ "github.com/docker/distribution/registry/auth/token"
|
||||||
"github.com/docker/distribution/registry/handlers"
|
"github.com/docker/distribution/registry/handlers"
|
||||||
|
"github.com/docker/distribution/registry/listener"
|
||||||
_ "github.com/docker/distribution/registry/storage/driver/azure"
|
_ "github.com/docker/distribution/registry/storage/driver/azure"
|
||||||
_ "github.com/docker/distribution/registry/storage/driver/filesystem"
|
_ "github.com/docker/distribution/registry/storage/driver/filesystem"
|
||||||
_ "github.com/docker/distribution/registry/storage/driver/inmemory"
|
_ "github.com/docker/distribution/registry/storage/driver/inmemory"
|
||||||
|
@ -67,14 +68,26 @@ func main() {
|
||||||
go debugServer(config.HTTP.Debug.Addr)
|
go debugServer(config.HTTP.Debug.Addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.HTTP.TLS.Certificate == "" {
|
server := &http.Server{
|
||||||
context.GetLogger(app).Infof("listening on %v", config.HTTP.Addr)
|
Handler: handler,
|
||||||
if err := http.ListenAndServe(config.HTTP.Addr, handler); err != nil {
|
}
|
||||||
context.GetLogger(app).Fatalln(err)
|
|
||||||
}
|
ln, err := listener.NewListener(config.HTTP.Net, config.HTTP.Addr)
|
||||||
} else {
|
if err != nil {
|
||||||
|
context.GetLogger(app).Fatalln(err)
|
||||||
|
}
|
||||||
|
defer ln.Close()
|
||||||
|
|
||||||
|
if config.HTTP.TLS.Certificate != "" {
|
||||||
tlsConf := &tls.Config{
|
tlsConf := &tls.Config{
|
||||||
ClientAuth: tls.NoClientCert,
|
ClientAuth: tls.NoClientCert,
|
||||||
|
NextProtos: []string{"http/1.1"},
|
||||||
|
Certificates: make([]tls.Certificate, 1),
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsConf.Certificates[0], err = tls.LoadX509KeyPair(config.HTTP.TLS.Certificate, config.HTTP.TLS.Key)
|
||||||
|
if err != nil {
|
||||||
|
context.GetLogger(app).Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(config.HTTP.TLS.ClientCAs) != 0 {
|
if len(config.HTTP.TLS.ClientCAs) != 0 {
|
||||||
|
@ -99,16 +112,14 @@ func main() {
|
||||||
tlsConf.ClientCAs = pool
|
tlsConf.ClientCAs = pool
|
||||||
}
|
}
|
||||||
|
|
||||||
context.GetLogger(app).Infof("listening on %v, tls", config.HTTP.Addr)
|
ln = tls.NewListener(ln, tlsConf)
|
||||||
server := &http.Server{
|
context.GetLogger(app).Infof("listening on %v, tls", ln.Addr())
|
||||||
Addr: config.HTTP.Addr,
|
} else {
|
||||||
Handler: handler,
|
context.GetLogger(app).Infof("listening on %v", ln.Addr())
|
||||||
TLSConfig: tlsConf,
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if err := server.ListenAndServeTLS(config.HTTP.TLS.Certificate, config.HTTP.TLS.Key); err != nil {
|
if err := server.Serve(ln); err != nil {
|
||||||
context.GetLogger(app).Fatalln(err)
|
context.GetLogger(app).Fatalln(err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,9 @@ type Configuration struct {
|
||||||
// Addr specifies the bind address for the registry instance.
|
// Addr specifies the bind address for the registry instance.
|
||||||
Addr string `yaml:"addr,omitempty"`
|
Addr string `yaml:"addr,omitempty"`
|
||||||
|
|
||||||
|
// Net specifies the net portion of the bind address. A default empty value means tcp.
|
||||||
|
Net string `yaml:"net,omitempty"`
|
||||||
|
|
||||||
Prefix string `yaml:"prefix,omitempty"`
|
Prefix string `yaml:"prefix,omitempty"`
|
||||||
|
|
||||||
// Secret specifies the secret key which HMAC tokens are created with.
|
// Secret specifies the secret key which HMAC tokens are created with.
|
||||||
|
|
|
@ -61,6 +61,7 @@ var configStruct = Configuration{
|
||||||
},
|
},
|
||||||
HTTP: struct {
|
HTTP: struct {
|
||||||
Addr string `yaml:"addr,omitempty"`
|
Addr string `yaml:"addr,omitempty"`
|
||||||
|
Net string `yaml:"net,omitempty"`
|
||||||
Prefix string `yaml:"prefix,omitempty"`
|
Prefix string `yaml:"prefix,omitempty"`
|
||||||
Secret string `yaml:"secret,omitempty"`
|
Secret string `yaml:"secret,omitempty"`
|
||||||
TLS struct {
|
TLS struct {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<!--GITHUB
|
<!--GITHUB
|
||||||
page_title: Configure a Registry
|
page_title: Configure a Registry
|
||||||
page_description: Explains how to deploy a registry
|
page_description: Explains how to deploy a registry
|
||||||
page_keywords: registry, service, images, repository
|
page_keywords: registry, service, images, repository
|
||||||
IGNORES-->
|
IGNORES-->
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ http:
|
||||||
debug:
|
debug:
|
||||||
addr: localhost:5001
|
addr: localhost:5001
|
||||||
notifications:
|
notifications:
|
||||||
endpoints:
|
endpoints:
|
||||||
- name: alistener
|
- name: alistener
|
||||||
disabled: false
|
disabled: false
|
||||||
url: https://my.listener.com/event
|
url: https://my.listener.com/event
|
||||||
|
@ -158,7 +158,7 @@ directory.
|
||||||
>configuration.
|
>configuration.
|
||||||
|
|
||||||
|
|
||||||
## version
|
## version
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: 0.1
|
version: 0.1
|
||||||
|
@ -166,7 +166,7 @@ version: 0.1
|
||||||
|
|
||||||
The `version` option is **required**. It specifies the configuration's version.
|
The `version` option is **required**. It specifies the configuration's version.
|
||||||
It is expected to remain a top-level field, to allow for a consistent version
|
It is expected to remain a top-level field, to allow for a consistent version
|
||||||
check before parsing the remainder of the configuration file.
|
check before parsing the remainder of the configuration file.
|
||||||
|
|
||||||
## log
|
## log
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ You must configure one backend; if you configure more, the registry returns an e
|
||||||
|
|
||||||
Use the `cache` subsection to enable caching of data accessed in the storage
|
Use the `cache` subsection to enable caching of data accessed in the storage
|
||||||
backend. Currently, the only available cache provides fast access to layer
|
backend. Currently, the only available cache provides fast access to layer
|
||||||
metadata. This, if configured, uses the `layerinfo` field.
|
metadata. This, if configured, uses the `layerinfo` field.
|
||||||
|
|
||||||
You can set `layerinfo` field to `redis` or `inmemory`. The `redis` value uses
|
You can set `layerinfo` field to `redis` or `inmemory`. The `redis` value uses
|
||||||
a Redis pool to cache layer metadata. The `inmemory` value uses an in memory
|
a Redis pool to cache layer metadata. The `inmemory` value uses an in memory
|
||||||
|
@ -296,7 +296,7 @@ here so make sure there is adequate space available.
|
||||||
|
|
||||||
### azure
|
### azure
|
||||||
|
|
||||||
This storage backend uses Microsoft's Azure Storage platform.
|
This storage backend uses Microsoft's Azure Storage platform.
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -336,7 +336,7 @@ This storage backend uses Microsoft's Azure Storage platform.
|
||||||
<td>
|
<td>
|
||||||
Name of the Azure container into which to store data.
|
Name of the Azure container into which to store data.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
@ -455,7 +455,7 @@ This storage backend uses Amazon's Simple Storage Service (S3).
|
||||||
<td>
|
<td>
|
||||||
This is a prefix that will be applied to all S3 keys to allow you to segment data in your bucket if necessary.
|
This is a prefix that will be applied to all S3 keys to allow you to segment data in your bucket if necessary.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
### Maintenance
|
### Maintenance
|
||||||
|
@ -466,7 +466,7 @@ maintenance functions which are related to storage can be configured under the m
|
||||||
### Upload Purging
|
### Upload Purging
|
||||||
|
|
||||||
Upload purging is a background process that periodically removes orphaned files from the upload
|
Upload purging is a background process that periodically removes orphaned files from the upload
|
||||||
directories of the registry. Upload purging is enabled by default. To
|
directories of the registry. Upload purging is enabled by default. To
|
||||||
configure upload directory purging, the following parameters
|
configure upload directory purging, the following parameters
|
||||||
must be set.
|
must be set.
|
||||||
|
|
||||||
|
@ -475,10 +475,10 @@ must be set.
|
||||||
--------- | -------- | -----------
|
--------- | -------- | -----------
|
||||||
`enabled` | yes | Set to true to enable upload purging. Default=true. |
|
`enabled` | yes | Set to true to enable upload purging. Default=true. |
|
||||||
`age` | yes | Upload directories which are older than this age will be deleted. Default=168h (1 week)
|
`age` | yes | Upload directories which are older than this age will be deleted. Default=168h (1 week)
|
||||||
`interval` | yes | The interval between upload directory purging. Default=24h.
|
`interval` | yes | The interval between upload directory purging. Default=24h.
|
||||||
`dryrun` | yes | dryrun can be set to true to obtain a summary of what directories will be deleted. Default=false.
|
`dryrun` | yes | dryrun can be set to true to obtain a summary of what directories will be deleted. Default=false.
|
||||||
|
|
||||||
Note: `age` and `interval` are strings containing a number with optional fraction and a unit suffix: e.g. 45m, 2h10m, 168h (1 week).
|
Note: `age` and `interval` are strings containing a number with optional fraction and a unit suffix: e.g. 45m, 2h10m, 168h (1 week).
|
||||||
|
|
||||||
## auth
|
## auth
|
||||||
|
|
||||||
|
@ -505,7 +505,7 @@ The `silly` auth is only for development purposes. It simply checks for the
|
||||||
existence of the `Authorization` header in the HTTP request. It has no regard for
|
existence of the `Authorization` header in the HTTP request. It has no regard for
|
||||||
the header's value. If the header does not exist, the `silly` auth responds with a
|
the header's value. If the header does not exist, the `silly` auth responds with a
|
||||||
challenge response, echoing back the realm, service, and scope that access was
|
challenge response, echoing back the realm, service, and scope that access was
|
||||||
denied for.
|
denied for.
|
||||||
|
|
||||||
The following values are used to configure the response:
|
The following values are used to configure the response:
|
||||||
|
|
||||||
|
@ -545,7 +545,7 @@ The following values are used to configure the response:
|
||||||
|
|
||||||
Token based authentication allows the authentication system to be decoupled from
|
Token based authentication allows the authentication system to be decoupled from
|
||||||
the registry. It is a well established authentication paradigm with a high
|
the registry. It is a well established authentication paradigm with a high
|
||||||
degree of security.
|
degree of security.
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -592,14 +592,14 @@ the token so it must match the value configured for the issuer.
|
||||||
<code>rootcertbundle</code>
|
<code>rootcertbundle</code>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
yes
|
yes
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
The absolute path to the root certificate bundle. This bundle contains the
|
The absolute path to the root certificate bundle. This bundle contains the
|
||||||
public part of the certificates that is used to sign authentication tokens.
|
public part of the certificates that is used to sign authentication tokens.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
For more information about Token based authentication configuration, see the [specification.]
|
For more information about Token based authentication configuration, see the [specification.]
|
||||||
|
|
||||||
|
@ -613,7 +613,7 @@ object they're wrapping. This means a registry middleware must implement the
|
||||||
`driver.StorageDriver`.
|
`driver.StorageDriver`.
|
||||||
|
|
||||||
Currently only one middleware, `cloudfront`, a storage middleware, is supported
|
Currently only one middleware, `cloudfront`, a storage middleware, is supported
|
||||||
in the registry implementation.
|
in the registry implementation.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
middleware:
|
middleware:
|
||||||
|
@ -747,7 +747,7 @@ configuration may contain both.
|
||||||
<codde>production</code>,<codde>staging</code>, or
|
<codde>production</code>,<codde>staging</code>, or
|
||||||
<codde>development</code>.
|
<codde>development</code>.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<code>endpoint</code>
|
<code>endpoint</code>
|
||||||
|
@ -756,9 +756,9 @@ configuration may contain both.
|
||||||
no
|
no
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
Specify the enterprise Bugsnag endpoint.
|
Specify the enterprise Bugsnag endpoint.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
@ -791,7 +791,7 @@ configuration may contain both.
|
||||||
<td>
|
<td>
|
||||||
New Relic application name.
|
New Relic application name.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<code>verbose</code>
|
<code>verbose</code>
|
||||||
|
@ -802,7 +802,7 @@ configuration may contain both.
|
||||||
<td>
|
<td>
|
||||||
Enable New Relic debugging output on stdout.
|
Enable New Relic debugging output on stdout.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
## http
|
## http
|
||||||
|
@ -810,6 +810,7 @@ configuration may contain both.
|
||||||
```yaml
|
```yaml
|
||||||
http:
|
http:
|
||||||
addr: localhost:5000
|
addr: localhost:5000
|
||||||
|
net: tcp
|
||||||
prefix: /my/nested/registry/
|
prefix: /my/nested/registry/
|
||||||
secret: asecretforlocaldevelopment
|
secret: asecretforlocaldevelopment
|
||||||
tls:
|
tls:
|
||||||
|
@ -838,7 +839,20 @@ The `http` option details the configuration for the HTTP server that hosts the r
|
||||||
yes
|
yes
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
The <code>HOST:PORT</code> for which the server should accept connections.
|
The address for which the server should accept connections. The form depends on a network type (see <code>net</code> option):
|
||||||
|
<code>HOST:PORT</code> for tcp and <code>FILE</code> for a unix socket.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>net</code>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
no
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
The network which is used to create a listening socket. Known networks are <code>unix</code> and <code>tcp</code>.
|
||||||
|
The default empty value means tcp.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -915,7 +929,7 @@ and proxy connections to the registry server.
|
||||||
<td>
|
<td>
|
||||||
An array of absolute paths to a x509 CA file
|
An array of absolute paths to a x509 CA file
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
@ -934,7 +948,7 @@ specifies the `HOST:PORT` on which the debug server should accept connections.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
notifications:
|
notifications:
|
||||||
endpoints:
|
endpoints:
|
||||||
- name: alistener
|
- name: alistener
|
||||||
disabled: false
|
disabled: false
|
||||||
url: https://my.listener.com/event
|
url: https://my.listener.com/event
|
||||||
|
@ -965,7 +979,7 @@ Endpoints is a list of named services (URLs) that can accept event notifications
|
||||||
yes
|
yes
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
A human readable name for the service.
|
A human readable name for the service.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -989,7 +1003,7 @@ A boolean to enable/disable notifications for a service.
|
||||||
<td>
|
<td>
|
||||||
The URL to which events should be published.
|
The URL to which events should be published.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<code>headers</code>
|
<code>headers</code>
|
||||||
|
@ -1000,7 +1014,7 @@ The URL to which events should be published.
|
||||||
<td>
|
<td>
|
||||||
Static headers to add to each request.
|
Static headers to add to each request.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<code>timeout</code>
|
<code>timeout</code>
|
||||||
|
@ -1021,7 +1035,7 @@ The URL to which events should be published.
|
||||||
</ul>
|
</ul>
|
||||||
If you omit the suffix, the system interprets the value as nanoseconds.
|
If you omit the suffix, the system interprets the value as nanoseconds.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<code>threshold</code>
|
<code>threshold</code>
|
||||||
|
@ -1032,7 +1046,7 @@ The URL to which events should be published.
|
||||||
<td>
|
<td>
|
||||||
An integer specifying how long to wait before backing off a failure.
|
An integer specifying how long to wait before backing off a failure.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<code>backoff</code>
|
<code>backoff</code>
|
||||||
|
@ -1054,7 +1068,7 @@ The URL to which events should be published.
|
||||||
</ul>
|
</ul>
|
||||||
If you omit the suffix, the system interprets the value as nanoseconds.
|
If you omit the suffix, the system interprets the value as nanoseconds.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1129,7 +1143,7 @@ with the [pool](#pool) subsection.
|
||||||
<td>
|
<td>
|
||||||
Timeout for connecting to a redis instance.
|
Timeout for connecting to a redis instance.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<code>readtimeout</code>
|
<code>readtimeout</code>
|
||||||
|
@ -1140,7 +1154,7 @@ with the [pool](#pool) subsection.
|
||||||
<td>
|
<td>
|
||||||
Timeout for reading from redis connections.
|
Timeout for reading from redis connections.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<code>writetimeout</code>
|
<code>writetimeout</code>
|
||||||
|
@ -1151,7 +1165,7 @@ with the [pool](#pool) subsection.
|
||||||
<td>
|
<td>
|
||||||
Timeout for writing to redis connections.
|
Timeout for writing to redis connections.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1206,7 +1220,7 @@ Configure the behavior of the Redis connection pool.
|
||||||
sets the amount time to wait before closing
|
sets the amount time to wait before closing
|
||||||
inactive connections.
|
inactive connections.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1216,7 +1230,7 @@ The following is a simple example you can use for local development:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: 0.1
|
version: 0.1
|
||||||
log:
|
log:
|
||||||
level: debug
|
level: debug
|
||||||
storage:
|
storage:
|
||||||
filesystem:
|
filesystem:
|
||||||
|
@ -1229,7 +1243,7 @@ http:
|
||||||
```
|
```
|
||||||
|
|
||||||
The above configures the registry instance to run on port `5000`, binding to
|
The above configures the registry instance to run on port `5000`, binding to
|
||||||
`localhost`, with the `debug` server enabled. Registry data storage is in the
|
`localhost`, with the `debug` server enabled. Registry data storage is in the
|
||||||
`/tmp/registry-dev` directory. Logging is in `debug` mode, which is the most
|
`/tmp/registry-dev` directory. Logging is in `debug` mode, which is the most
|
||||||
verbose.
|
verbose.
|
||||||
|
|
||||||
|
@ -1242,7 +1256,7 @@ Both are generally useful for local development.
|
||||||
|
|
||||||
This example illustrates how to configure storage middleware in a registry.
|
This example illustrates how to configure storage middleware in a registry.
|
||||||
Middleware allows the registry to serve layers via a content delivery network
|
Middleware allows the registry to serve layers via a content delivery network
|
||||||
(CDN). This is useful for reducing requests to the storage layer.
|
(CDN). This is useful for reducing requests to the storage layer.
|
||||||
|
|
||||||
Currently, the registry supports [Amazon
|
Currently, the registry supports [Amazon
|
||||||
Cloudfront](http://aws.amazon.com/cloudfront/). You can only use Cloudfront in
|
Cloudfront](http://aws.amazon.com/cloudfront/). You can only use Cloudfront in
|
||||||
|
@ -1263,7 +1277,7 @@ conjunction with the S3 storage driver.
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>options:</code></td>
|
<td><code>options:</code></td>
|
||||||
<td>
|
<td>
|
||||||
A set of key/value options to configure the middleware.
|
A set of key/value options to configure the middleware.
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>baseurl:</code> The Cloudfront base URL.</li>
|
<li><code>baseurl:</code> The Cloudfront base URL.</li>
|
||||||
|
@ -1293,4 +1307,3 @@ middleware:
|
||||||
>**Note**: Cloudfront keys exist separately to other AWS keys. See
|
>**Note**: Cloudfront keys exist separately to other AWS keys. See
|
||||||
>[the documentation on AWS credentials](http://docs.aws.amazon.com/AWSSecurityCredentials/1.0/AboutAWSCredentials.html#KeyPairs)
|
>[the documentation on AWS credentials](http://docs.aws.amazon.com/AWSSecurityCredentials/1.0/AboutAWSCredentials.html#KeyPairs)
|
||||||
>for more information.
|
>for more information.
|
||||||
|
|
||||||
|
|
74
registry/listener/listener.go
Normal file
74
registry/listener/listener.go
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package listener
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
|
||||||
|
// connections. It's used by ListenAndServe and ListenAndServeTLS so
|
||||||
|
// dead TCP connections (e.g. closing laptop mid-download) eventually
|
||||||
|
// go away.
|
||||||
|
// it is a plain copy-paste from net/http/server.go
|
||||||
|
type tcpKeepAliveListener struct {
|
||||||
|
*net.TCPListener
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
|
||||||
|
tc, err := ln.AcceptTCP()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tc.SetKeepAlive(true)
|
||||||
|
tc.SetKeepAlivePeriod(3 * time.Minute)
|
||||||
|
return tc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewListener announces on laddr and net. Accepted values of the net are
|
||||||
|
// 'unix' and 'tcp'
|
||||||
|
func NewListener(net, laddr string) (net.Listener, error) {
|
||||||
|
switch net {
|
||||||
|
case "unix":
|
||||||
|
return newUnixListener(laddr)
|
||||||
|
case "tcp", "": // an empty net means tcp
|
||||||
|
return newTCPListener(laddr)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown address type %s", net)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newUnixListener(laddr string) (net.Listener, error) {
|
||||||
|
fi, err := os.Stat(laddr)
|
||||||
|
if err == nil {
|
||||||
|
// the file exists.
|
||||||
|
// try to remove it if it's a socket
|
||||||
|
if !isSocket(fi.Mode()) {
|
||||||
|
return nil, fmt.Errorf("file %s exists and is not a socket", laddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.Remove(laddr); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else if !os.IsNotExist(err) {
|
||||||
|
// we can't do stat on the file.
|
||||||
|
// it means we can not remove it
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return net.Listen("unix", laddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSocket(m os.FileMode) bool {
|
||||||
|
return m&os.ModeSocket != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTCPListener(laddr string) (net.Listener, error) {
|
||||||
|
ln, err := net.Listen("tcp", laddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tcpKeepAliveListener{ln.(*net.TCPListener)}, nil
|
||||||
|
}
|
Loading…
Reference in a new issue