Merge branch 'master' of https://github.com/coreos/etcd into proxy

Conflicts:
	config/config.go
	server/peer_server.go
	server/transporter.go
	tests/server_utils.go
This commit is contained in:
Ben Johnson 2014-03-24 15:30:14 -07:00
commit 62b89a128a
67 changed files with 1543 additions and 1318 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
/machine*
/bin
/src
.vagrant

View File

@ -28,6 +28,12 @@ This is a rough outline of what a contributor's workflow looks like:
Thanks for you contributions!
### Code style
The coding style suggested by the Golang community is used in etcd. See [style doc](https://code.google.com/p/go-wiki/wiki/Style) for details.
Please follow this style to make etcd easy to review, maintain and develop.
### Format of the commit message
etcd follow a rough convention for commit messages borrowed from Angularjs.

View File

@ -21,7 +21,7 @@ The key space consists of directories and keys which are generically referred to
### Setting the value of a key
Lets set the first key-value pair in the datastore.
Let's set the first key-value pair in the datastore.
In this case the key is `/message` and the value is `Hello world`.
```sh
@ -118,11 +118,10 @@ curl -L http://127.0.0.1:4001/v2/keys/message -XPUT -d value="Hello etcd"
"value": "Hello etcd"
},
"prevNode": {
"createdIndex":2
"createdIndex": 2
"key": "/message",
"value": "Hello world",
"modifiedIndex": 2,
}
}
```
@ -379,11 +378,11 @@ curl 'http://127.0.0.1:4001/v2/keys/dir/asdf?consistent=true&wait=true'
"modifiedIndex": 15
},
"prevNode": {
"createdIndex":8,
"createdIndex": 8,
"key": "/dir",
"dir":true,
"modifiedIndex": 17,
"expiration":"2013-12-11T10:39:35.689275857-08:00"
"expiration": "2013-12-11T10:39:35.689275857-08:00"
},
}
```
@ -438,14 +437,15 @@ This will try to compare the previous value of the key and the previous value we
```json
{
"cause": "[two != one] [0 != 8]",
"cause": "[two != one]",
"errorCode": 101,
"index": 8,
"message": "Test Failed"
}
```
which means `CompareAndSwap` failed.
which means `CompareAndSwap` failed. `cause` explains why the test failed.
Note: the condition prevIndex=0 always passes.
Let's try a valid condition:
@ -465,7 +465,7 @@ The response should be:
"value": "two"
},
"prevNode": {
"createdIndex":8,
"createdIndex": 8,
"key": "/foo",
"modifiedIndex": 8,
"value": "one"
@ -504,7 +504,7 @@ The error code explains the problem:
{
"errorCode": 101,
"message": "Compare failed",
"cause": "[two != one] [0 != 8]",
"cause": "[two != one]",
"index": 8
}
```
@ -519,7 +519,7 @@ curl -L http://127.0.0.1:4001/v2/keys/foo?prevIndex=1 -XDELETE
{
"errorCode": 101,
"message": "Compare failed",
"cause": "[ != one] [1 != 8]",
"cause": "[1 != 8]",
"index": 8
}
```
@ -783,6 +783,39 @@ curl -L http://127.0.0.1:4001/v2/keys/
Here we see the `/message` key but our hidden `/_message` key is not returned.
### Setting a key from a file
You can also use etcd to store small configuration files, json documents, XML documents, etc directly.
For example you can use curl to upload a simple text file and encode it:
```
echo "Hello\nWorld" > afile.txt
curl -L http://127.0.0.1:4001/v2/keys/afile -XPUT --data-urlencode value@afile.txt
```
```json
{
"action": "get",
"node": {
"createdIndex": 2,
"key": "/afile",
"modifiedIndex": 2,
"value": "Hello\nWorld\n"
}
}
```
### Read Consistency
Followers in a cluster can be behind the leader in their copy of the keyspace.
If your application wants or needs the most up-to-date version of a key then it should ensure it reads from the current leader.
By using the `consistent=true` flag in your GET requests, etcd will make sure you are talking to the current master.
As an example of how a machine can be behind the leader let's start with a three machine cluster: L, F1, and F2.
A client makes a write to L and F1 acknowledges the request.
The client is told the write was successful and the keyspace is updated.
Meanwhile F2 has partitioned from the network and will have an out-of-date version of the keyspace until the partition resolves.
Since F2 missed the most recent write, a client reading from F2 will have an out-of-date version of the keyspace.
## Lock Module
@ -1056,7 +1089,7 @@ Each node keeps a number of internal statistics:
- `sendAppendRequestCnt`: number of requests that this node has sent
- `sendBandwidthRate`: number of bytes per second this node is receiving (leader only). This value is undefined on single machine clusters.
- `sendPkgRate`: number of requests per second this node is receiving (leader only). This value is undefined on single machine clusters.
- `state`: either leader or folower
- `state`: either leader or follower
- `startTime`: the time when this node was started
This is an example response from a follower machine:
@ -1087,7 +1120,7 @@ And this is an example response from a leader machine:
curl -L http://127.0.0.1:4001/v2/stats/self
```
```
```json
{
"leaderInfo": {
"leader": "machine0",

View File

@ -20,21 +20,21 @@ configuration files.
* `-addr` - The advertised public hostname:port for client communication. Defaults to `127.0.0.1:4001`.
* `-discovery` - A URL to use for discovering the peer list. (i.e `"https://discovery.etcd.io/your-unique-key"`).
* `-bind-addr` - The listening hostname for client communication. Defaults to advertised ip.
* `-bind-addr` - The listening hostname for client communication. Defaults to advertised IP.
* `-peers` - A comma separated list of peers in the cluster (i.e `"203.0.113.101:7001,203.0.113.102:7001"`).
* `-peers-file` - The file path containing a comma separated list of peers in the cluster.
* `-ca-file` - The path of the client CAFile. Enables client cert authentication when present.
* `-cert-file` - The cert file of the client.
* `-key-file` - The key file of the client.
* `-config` - The path of the etcd config file. Defaults to `/etc/etcd/etcd.conf`.
* `-config` - The path of the etcd configuration file. Defaults to `/etc/etcd/etcd.conf`.
* `-cors` - A comma separated white list of origins for cross-origin resource sharing.
* `-cpuprofile` - The path to a file to output cpu profile data. Enables cpu profiling when present.
* `-cpuprofile` - The path to a file to output CPU profile data. Enables CPU profiling when present.
* `-data-dir` - The directory to store log and snapshot. Defaults to the current working directory.
* `-max-result-buffer` - The max size of result buffer. Defaults to `1024`.
* `-max-cluster-size` - The max size of the cluster. Defaults to `9`.
* `-max-retry-attempts` - The max retry attempts when trying to join a cluster. Defaults to `3`.
* `-peer-addr` - The advertised public hostname:port for server communication. Defaults to `127.0.0.1:7001`.
* `-peer-bind-addr` - The listening hostname for server communication. Defaults to advertised ip.
* `-peer-bind-addr` - The listening hostname for server communication. Defaults to advertised IP.
* `-peer-ca-file` - The path of the CAFile. Enables client/peer cert authentication when present.
* `-peer-cert-file` - The cert file of the server.
* `-peer-key-file` - The key file of the server.

View File

@ -44,10 +44,10 @@ See an [example collectd deploy script](https://github.com/coreos/etcd/contrib/c
## Profiling
etcd exposes profiling information from the Go pprof package over HTTP.
The basic browseable interface is served by etcd at the `/debug/pprof` HTTP endpoint (i.e. `http://127.0.0.1:4001/debug/pprof`).
The basic browsable interface is served by etcd at the `/debug/pprof` HTTP endpoint (i.e. `http://127.0.0.1:4001/debug/pprof`).
For more information on using profiling tools, see http://blog.golang.org/profiling-go-programs.
**NOTE**: In the following examples you need to ensure that the `./bin/etcd` is identical to the `./bin/etcd` that you are targetting (same git hash, arch, platform, etc).
**NOTE**: In the following examples you need to ensure that the `./bin/etcd` is identical to the `./bin/etcd` that you are targeting (same git hash, arch, platform, etc).
#### Heap memory profile

View File

@ -14,7 +14,7 @@ a new cluster. We assume the user doesn't want to start a brand new cluster with
## Logical Workflow
Start a etcd machine:
Start an etcd machine:
```
If discovery url is given:

View File

@ -0,0 +1,12 @@
# Development tools
## Vagrant
For fast start you can use Vagrant. `vagrant up` will make etcd build and running on virtual machine. Required Vagrant version is 1.5.0.
Next lets set a single key and then retrieve it:
```
curl -L http://127.0.0.1:4001/v2/keys/mykey -XPUT -d value="this is awesome"
curl -L http://127.0.0.1:4001/v2/keys/mykey
```

View File

@ -20,7 +20,7 @@ UUID=$(uuidgen)
Now that you have your cluster ID you can start bringing up machines. Every machine will follow this protocol internally in etcd if given a `-discovery`.
### Registering your Machine
### Registering your Machine
The first thing etcd must do is register your machine. This is done by using the machine name (from the `-name` arg) and posting it with a long TTL to the given key.

View File

@ -21,6 +21,7 @@ Error code corresponding strerror
EcodeNotDir = 104
EcodeNodeExist = 105
EcodeKeyIsPreserved = 106
EcodeRootROnly = 107
EcodeValueRequired = 200
EcodePrevValueRequired = 201
@ -42,6 +43,7 @@ Error code corresponding strerror
errors[104] = "Not A Directory"
errors[105] = "Already exists" // create
errors[106] = "The prefix of given key is a keyword in etcd"
errors[107] = "Root is read only"
// Post form related errors
errors[200] = "Value is Required in POST form"

View File

@ -77,7 +77,7 @@ Unless overridden, a node naturally inherits the ACL names of its parent directo
For each ACL name, it has three children: *R (Reading)*, *W (Writing)*, *C (Changing)*
Each permission is also a node. Under the node it contains the users who have this permission for the file refering to this ACL name.
Each permission is also a node. Under the node it contains the users who have this permission for the file referring to this ACL name.
### Example
[TODO]

View File

@ -26,7 +26,7 @@ Advantages
Disadvantages
- Follower knows better what versions of the interal protocol it can talk than the leader
- Follower knows better what versions of the internal protocol it can talk than the leader
### Follower Controlled

View File

@ -4,6 +4,7 @@
- [etcdctl](https://github.com/coreos/etcdctl) - A command line client for etcd
- [etcd-dump](https://npmjs.org/package/etcd-dump) - Command line utility for dumping/restoring etcd.
- [etcd-fs](https://github.com/xetorthio/etcd-fs) - FUSE filesystem for etcd
**Go libraries**
@ -46,7 +47,16 @@
- [marshall-lee/etcd.erl](https://github.com/marshall-lee/etcd.erl)
**.Net Libraries**
-[drusellers/etcetera](https://github.com/drusellers/etcetera)
- [drusellers/etcetera](https://github.com/drusellers/etcetera)
**PHP Libraries**
- [linkorb/etcd-php](https://github.com/linkorb/etcd-php)
**Haskell libraries**
- [wereHamster/etcd-hs](https://github.com/wereHamster/etcd-hs)
A detailed recap of client functionalities can be found in the [clients compatibility matrix][clients-matrix.md].
@ -77,3 +87,4 @@ A detailed recap of client functionalities can be found in the [clients compatib
- [mattn/etcdenv](https://github.com/mattn/etcdenv) - "env" shebang with etcd integration
- [kelseyhightower/confd](https://github.com/kelseyhightower/confd) - Manage local app config files using templates and data from etcd
- [configdb](https://git.autistici.org/ai/configdb/tree/master) - A REST relational abstraction on top of arbitrary database backends, aimed at storing configs and inventories.
- [scrz](https://github.com/scrz/scrz) - Container manager, stores configuration in etcd.

View File

@ -26,7 +26,7 @@ coreos­etcdctl­0.2.0           Simple commandline client for et
r@fbsd­10:/ #
```
5. Youre ready to use etcd and etcdctl! For more information about using pkgng, plese
5. Youre ready to use etcd and etcdctl! For more information about using pkgng, please
see: http://www.freebsd.org/doc/handbook/pkgng­intro.html
 
### Using ports system
@ -37,7 +37,7 @@ may take some time depending on your hardware and network connection)
2. Build etcd with `cd /usr/ports/devel/etcd && make install clean`, you
will get an option to build and install documentation and etcdctl with it.
3. If you havent install it with etcdctl, and you would like to install it later, you can build it
3. If you haven't installed it with etcdctl, and you would like to install it later, you can build it
with `cd /usr/ports/devel/etcdctl && make install clean`
4. Verify successful installation with `pkg info | grep etcd` and you should get:
@ -55,8 +55,8 @@ please see: https://www.freebsd.org/doc/handbook/ports­using.html
## Issues
If you find any issues with the build/install procedure or youve found a problem that
youve verified is local to FreeBSD version only (for example, by not being able to
If you find any issues with the build/install procedure or you've found a problem that
you've verified is local to FreeBSD version only (for example, by not being able to
reproduce it on any other platform, like OSX or Linux), please sent a
problem report using this page for more
information: http://www.freebsd.org/send­pr.html

View File

@ -7,6 +7,7 @@ Etcd supports SSL/TLS and client cert authentication for clients to server, as w
First, you need to have a CA cert `clientCA.crt` and signed key pair `client.crt`, `client.key`.
This site has a good reference for how to generate self-signed key pairs:
http://www.g-loaded.eu/2005/11/10/be-your-own-ca/
Or you could use [etcd-ca](https://github.com/coreos/etcd-ca) to generate certs and keys.
For testing you can use the certificates in the `fixtures/ca` directory.

View File

@ -1,46 +1,46 @@
## Tuning
The default settings in etcd should work well for installations on a local network where the average network latency is low.
However, when using etcd across multiple data centers or over networks with high latency you may need to tweak the heartbeat and election timeout settings.
However, when using etcd across multiple data centers or over networks with high latency you may need to tweak the heartbeat interval and election timeout settings.
### Timeouts
### Time Parameters
The underlying distributed consensus protocol relies on two separate timeouts to ensure that nodes can handoff leadership if one stalls or goes offline.
The first timeout is called the *Heartbeat Timeout*.
The underlying distributed consensus protocol relies on two separate time parameters to ensure that nodes can handoff leadership if one stalls or goes offline.
The first parameter is called the *Heartbeat Interval*.
This is the frequency with which the leader will notify followers that it is still the leader.
etcd batches commands together for higher throughput so this heartbeat timeout is also a delay for how long it takes for commands to be committed.
By default, etcd uses a `50ms` heartbeat timeout.
etcd batches commands together for higher throughput so this heartbeat interval is also a delay for how long it takes for commands to be committed.
By default, etcd uses a `50ms` heartbeat interval.
The second timeout is the *Election Timeout*.
The second parameter is the *Election Timeout*.
This timeout is how long a follower node will go without hearing a heartbeat before attempting to become leader itself.
By default, etcd uses a `200ms` election timeout.
Adjusting these values is a trade off.
Lowering the heartbeat timeout will cause individual commands to be committed faster but it will lower the overall throughput of etcd.
If your etcd instances have low utilization then lowering the heartbeat timeout can improve your command response time.
Lowering the heartbeat interval will cause individual commands to be committed faster but it will lower the overall throughput of etcd.
If your etcd instances have low utilization then lowering the heartbeat interval can improve your command response time.
The election timeout should be set based on the heartbeat timeout and your network ping time between nodes.
The election timeout should be set based on the heartbeat interval and your network ping time between nodes.
Election timeouts should be at least 10 times your ping time so it can account for variance in your network.
For example, if the ping time between your nodes is 10ms then you should have at least a 100ms election timeout.
You should also set your election timeout to at least 4 to 5 times your heartbeat timeout to account for variance in leader replication.
For a heartbeat timeout of 50ms you should set your election timeout to at least 200ms - 250ms.
You should also set your election timeout to at least 4 to 5 times your heartbeat interval to account for variance in leader replication.
For a heartbeat interval of 50ms you should set your election timeout to at least 200ms - 250ms.
You can override the default values on the command line:
```sh
# Command line arguments:
$ etcd -peer-heartbeat-timeout=100 -peer-election-timeout=500
$ etcd -peer-heartbeat-interval=100 -peer-election-timeout=500
# Environment variables:
$ ETCD_PEER_HEARTBEAT_TIMEOUT=100 ETCD_PEER_ELECTION_TIMEOUT=500 etcd
$ ETCD_PEER_HEARTBEAT_INTERVAL=100 ETCD_PEER_ELECTION_TIMEOUT=500 etcd
```
Or you can set the values within the configuration file:
```toml
[peer]
heartbeat_timeout = 100
heartbeat_interval = 100
election_timeout = 100
```

View File

@ -2,8 +2,6 @@
README version 0.3.0
[![Build Status](https://drone.io/github.com/coreos/etcd/status.png)](https://drone.io/github.com/coreos/etcd/latest)
A highly-available key value store for shared configuration and service discovery.
etcd is inspired by zookeeper and doozer, with a focus on:
@ -47,6 +45,10 @@ _NOTE_: you need go 1.2+. Please check your installation with
go version
```
See the [development tools documentation][development-tools.md] for alternative build methods like using Vagrant.
[development-tools.md]: https://github.com/coreos/etcd/blob/master/Documentation/development-tools.md
### Running
First start a single machine cluster of etcd:

27
Vagrantfile vendored Normal file
View File

@ -0,0 +1,27 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
#
Vagrant.require_version '>= 1.5.0'
Vagrant.configure("2") do |config|
config.vm.box = "precise64"
config.vm.box_url = "http://files.vagrantup.com/precise64.box"
config.vm.network :forwarded_port, host: 4001, guest: 4001
config.vm.network :forwarded_port, host: 7001, guest: 7001
# Fix docker not being able to resolve private registry in VirtualBox
config.vm.provider :virtualbox do |vb, override|
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
end
config.vm.provision "docker" do |d|
d.build_image "/vagrant", args: '-t etcd'
d.run "etcd", args: "-p 4001:4001 -p 7001:7001", demonize: true
end
# plugin conflict
if Vagrant.has_plugin?("vagrant-vbguest")
config.vbguest.auto_update = false
end
end

View File

@ -24,24 +24,25 @@ const DefaultSystemConfigPath = "/etc/etcd/etcd.conf"
// A lookup of deprecated flags to their new flag name.
var newFlagNameLookup = map[string]string{
"C": "peers",
"CF": "peers-file",
"n": "name",
"c": "addr",
"cl": "bind-addr",
"s": "peer-addr",
"sl": "peer-bind-addr",
"d": "data-dir",
"m": "max-result-buffer",
"r": "max-retry-attempts",
"maxsize": "max-cluster-size",
"clientCAFile": "ca-file",
"clientCert": "cert-file",
"clientKey": "key-file",
"serverCAFile": "peer-ca-file",
"serverCert": "peer-cert-file",
"serverKey": "peer-key-file",
"snapshotCount": "snapshot-count",
"C": "peers",
"CF": "peers-file",
"n": "name",
"c": "addr",
"cl": "bind-addr",
"s": "peer-addr",
"sl": "peer-bind-addr",
"d": "data-dir",
"m": "max-result-buffer",
"r": "max-retry-attempts",
"maxsize": "max-cluster-size",
"clientCAFile": "ca-file",
"clientCert": "cert-file",
"clientKey": "key-file",
"serverCAFile": "peer-ca-file",
"serverCert": "peer-cert-file",
"serverKey": "peer-key-file",
"snapshotCount": "snapshot-count",
"peer-heartbeat-timeout": "peer-heartbeat-interval",
}
// Config represents the server configuration.
@ -72,13 +73,13 @@ type Config struct {
VeryVerbose bool `toml:"very_verbose" env:"ETCD_VERY_VERBOSE"`
VeryVeryVerbose bool `toml:"very_very_verbose" env:"ETCD_VERY_VERY_VERBOSE"`
Peer struct {
Addr string `toml:"addr" env:"ETCD_PEER_ADDR"`
BindAddr string `toml:"bind_addr" env:"ETCD_PEER_BIND_ADDR"`
CAFile string `toml:"ca_file" env:"ETCD_PEER_CA_FILE"`
CertFile string `toml:"cert_file" env:"ETCD_PEER_CERT_FILE"`
KeyFile string `toml:"key_file" env:"ETCD_PEER_KEY_FILE"`
HeartbeatTimeout int `toml:"heartbeat_timeout" env:"ETCD_PEER_HEARTBEAT_TIMEOUT"`
ElectionTimeout int `toml:"election_timeout" env:"ETCD_PEER_ELECTION_TIMEOUT"`
Addr string `toml:"addr" env:"ETCD_PEER_ADDR"`
BindAddr string `toml:"bind_addr" env:"ETCD_PEER_BIND_ADDR"`
CAFile string `toml:"ca_file" env:"ETCD_PEER_CA_FILE"`
CertFile string `toml:"cert_file" env:"ETCD_PEER_CERT_FILE"`
KeyFile string `toml:"key_file" env:"ETCD_PEER_KEY_FILE"`
HeartbeatInterval int `toml:"heartbeat_interval" env:"ETCD_PEER_HEARTBEAT_INTERVAL"`
ElectionTimeout int `toml:"election_timeout" env:"ETCD_PEER_ELECTION_TIMEOUT"`
}
strTrace string `toml:"trace" env:"ETCD_TRACE"`
GraphiteHost string `toml:"graphite_host" env:"ETCD_GRAPHITE_HOST"`
@ -95,7 +96,7 @@ func New() *Config {
c.Snapshot = true
c.SnapshotCount = 10000
c.Peer.Addr = "127.0.0.1:7001"
c.Peer.HeartbeatTimeout = defaultHeartbeatTimeout
c.Peer.HeartbeatInterval = defaultHeartbeatInterval
c.Peer.ElectionTimeout = defaultElectionTimeout
return c
}
@ -245,7 +246,7 @@ func (c *Config) LoadFlags(arguments []string) error {
f.IntVar(&c.MaxResultBuffer, "max-result-buffer", c.MaxResultBuffer, "")
f.IntVar(&c.MaxRetryAttempts, "max-retry-attempts", c.MaxRetryAttempts, "")
f.Float64Var(&c.RetryInterval, "retry-interval", c.RetryInterval, "")
f.IntVar(&c.Peer.HeartbeatTimeout, "peer-heartbeat-timeout", c.Peer.HeartbeatTimeout, "")
f.IntVar(&c.Peer.HeartbeatInterval, "peer-heartbeat-interval", c.Peer.HeartbeatInterval, "")
f.IntVar(&c.Peer.ElectionTimeout, "peer-election-timeout", c.Peer.ElectionTimeout, "")
f.StringVar(&cors, "cors", "", "")
@ -279,6 +280,7 @@ func (c *Config) LoadFlags(arguments []string) error {
f.IntVar(&c.MaxResultBuffer, "m", c.MaxResultBuffer, "(deprecated)")
f.IntVar(&c.MaxRetryAttempts, "r", c.MaxRetryAttempts, "(deprecated)")
f.IntVar(&c.SnapshotCount, "snapshotCount", c.SnapshotCount, "(deprecated)")
f.IntVar(&c.Peer.HeartbeatInterval, "peer-heartbeat-timeout", c.Peer.HeartbeatInterval, "(deprecated)")
// END DEPRECATED FLAGS
if err := f.Parse(arguments); err != nil {
@ -384,20 +386,20 @@ func (c *Config) Sanitize() error {
}
// EtcdTLSInfo retrieves a TLSInfo object for the etcd server
func (c *Config) EtcdTLSInfo() server.TLSInfo {
return server.TLSInfo{
CAFile: c.CAFile,
CertFile: c.CertFile,
KeyFile: c.KeyFile,
func (c *Config) EtcdTLSInfo() *server.TLSInfo {
return &server.TLSInfo{
CAFile: c.CAFile,
CertFile: c.CertFile,
KeyFile: c.KeyFile,
}
}
// PeerRaftInfo retrieves a TLSInfo object for the peer server.
func (c *Config) PeerTLSInfo() server.TLSInfo {
return server.TLSInfo{
CAFile: c.Peer.CAFile,
CertFile: c.Peer.CertFile,
KeyFile: c.Peer.KeyFile,
func (c *Config) PeerTLSInfo() *server.TLSInfo {
return &server.TLSInfo{
CAFile: c.Peer.CAFile,
CertFile: c.Peer.CertFile,
KeyFile: c.Peer.KeyFile,
}
}

View File

@ -5,5 +5,5 @@ const (
defaultElectionTimeout = 200
// The frequency (in ms) by which heartbeats are sent to followers.
defaultHeartbeatTimeout = 50
defaultHeartbeatInterval = 50
)

58
etcd.go
View File

@ -18,7 +18,6 @@ package main
import (
"fmt"
"net"
"net/http"
"os"
"path/filepath"
@ -109,10 +108,10 @@ func main() {
serverStats := server.NewRaftServerStats(config.Name)
// Calculate all of our timeouts
heartbeatTimeout := time.Duration(config.Peer.HeartbeatTimeout) * time.Millisecond
heartbeatInterval := time.Duration(config.Peer.HeartbeatInterval) * time.Millisecond
electionTimeout := time.Duration(config.Peer.ElectionTimeout) * time.Millisecond
dialTimeout := (3 * heartbeatTimeout) + electionTimeout
responseHeaderTimeout := (3 * heartbeatTimeout) + electionTimeout
dialTimeout := (3 * heartbeatInterval) + electionTimeout
responseHeaderTimeout := (3 * heartbeatInterval) + electionTimeout
// Create peer server
psConfig := server.PeerServerConfig{
@ -125,26 +124,8 @@ func main() {
}
ps := server.NewPeerServer(psConfig, registry, store, &mb, followersStats, serverStats)
var psListener net.Listener
if psConfig.Scheme == "https" {
peerServerTLSConfig, err := config.PeerTLSInfo().ServerConfig()
if err != nil {
log.Fatal("peer server TLS error: ", err)
}
psListener, err = server.NewTLSListener(config.Peer.BindAddr, peerServerTLSConfig)
if err != nil {
log.Fatal("Failed to create peer listener: ", err)
}
} else {
psListener, err = server.NewListener(config.Peer.BindAddr)
if err != nil {
log.Fatal("Failed to create peer listener: ", err)
}
}
// Create raft transporter and server
raftTransporter := server.NewTransporter(followersStats, serverStats, registry, heartbeatTimeout, dialTimeout, responseHeaderTimeout)
raftTransporter := server.NewTransporter(followersStats, serverStats, registry, heartbeatInterval, dialTimeout, responseHeaderTimeout)
if psConfig.Scheme == "https" {
raftClientTLSConfig, err := config.PeerTLSInfo().ClientConfig()
if err != nil {
@ -157,7 +138,7 @@ func main() {
log.Fatal(err)
}
raftServer.SetElectionTimeout(electionTimeout)
raftServer.SetHeartbeatInterval(heartbeatTimeout)
raftServer.SetHeartbeatInterval(heartbeatInterval)
ps.SetRaftServer(raftServer)
// Create etcd server
@ -167,34 +148,19 @@ func main() {
s.EnableTracing()
}
var sListener net.Listener
if config.EtcdTLSInfo().Scheme() == "https" {
etcdServerTLSConfig, err := config.EtcdTLSInfo().ServerConfig()
if err != nil {
log.Fatal("etcd TLS error: ", err)
}
sListener, err = server.NewTLSListener(config.BindAddr, etcdServerTLSConfig)
if err != nil {
log.Fatal("Failed to create TLS etcd listener: ", err)
}
} else {
sListener, err = server.NewListener(config.BindAddr)
if err != nil {
log.Fatal("Failed to create etcd listener: ", err)
}
}
ps.SetServer(s)
ps.Start(config.Snapshot, config.Discovery, config.Peers)
go func() {
log.Infof("peer server [name %s, listen on %s, advertised url %s]", ps.Config.Name, psListener.Addr(), ps.Config.URL)
log.Infof("peer server [name %s, listen on %s, advertised url %s]", ps.Config.Name, config.Peer.BindAddr, ps.Config.URL)
l := server.NewListener(psConfig.Scheme, config.Peer.BindAddr, config.PeerTLSInfo())
sHTTP := &ehttp.CORSHandler{ps.HTTPHandler(), corsInfo}
log.Fatal(http.Serve(psListener, sHTTP))
log.Fatal(http.Serve(l, sHTTP))
}()
log.Infof("etcd server [name %s, listen on %s, advertised url %s]", s.Name, sListener.Addr(), s.URL())
log.Infof("etcd server [name %s, listen on %s, advertised url %s]", s.Name, config.BindAddr, s.URL())
l := server.NewListener(config.EtcdTLSInfo().Scheme(), config.BindAddr, config.EtcdTLSInfo())
sHTTP := &ehttp.CORSHandler{s.HTTPHandler(), corsInfo}
log.Fatal(http.Serve(sListener, sHTTP))
log.Fatal(http.Serve(l, sHTTP))
}

View File

@ -1,21 +1,13 @@
Testing x509 certs for etcd
The steps to regenerate this CA:
The passphrases for the keys are `asdf`.
1. Get etcd-ca source code and generate binary.
# Make the CA cert
openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt -config openssl.cnf -extensions v3_ca
$ go get github.com/coreos/etcd-ca
# Make server cert and signing request
openssl genrsa -des3 -out server.key 4096
openssl req -new -key server.key -out server.csr -config openssl.cnf
2. Run generate_testing_certs.sh with etcd-ca binary location.
# Sign the server csr and generate a crt
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -extfile openssl.cnf -extensions v3_req
$ ./generate_testing_certs.sh
# Output unencrypted server key
openssl rsa -in server.key -out server.key.insecure
# Output "raw" public key from server crt
openssl x509 -pubkey -noout -in server.crt > server.pub
Details about generation are in the generate_testing_certs.sh script.
3. Check current directory to see regenerated files.

View File

@ -1,21 +0,0 @@
## Testing x509 certs for luvit
# Make the CA cert
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
# Make server cert and signing request
openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr
# Sign the server csr and generate a crt
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
# Output unencrypted server key
openssl rsa -in server.key -out server.key.insecure
# Output "raw" public key from server crt
openssl x509 -pubkey -noout -in server.crt > server.pub
# Sign the public key with the key (just for testing signatures)
openssl dgst -sign server.key.insecure -sha256 server.pub > server.pub.sig

View File

@ -1,33 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFtTCCA52gAwIBAgIJANfWYo0ePBBqMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTIwMzE1MjMxMzMwWhcNMTMwMzE1MjMxMzMwWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAyzBV/DH0PWmPxdnr3BTogxPYKVJQ4OQjiiALRRtYPjvQYKPWWsbt4Zlw
kfYsc6ihIKUL1tGEnjD6YDTtTwWH7DXeq0mWebFr3kQg/ssoTM5oHN9VglwPMRnx
7qqbBG0/LO/K2Go/UMFGmWHiRYRWcOYegq6DXJpj1sRJz8o3uk4Fxz/xr1sjng1l
EfAfE4segFLRhmXy1e6Ooy2U5WcpDeKGrD1O01DKsYdR+RavcgkmFYfZ5rdtaKrE
wpYLylJNmOAkss7w5tOyEEDLoZHtkRFX5Ss38wuU2h9Li8P9vhyL4Ylzcuy/pBXW
MA89D8bBXjR3G4Hk7qX7gqlI9GdRXtPqnRpgEy/vw/+6aJVfNJtLIRdabSr3vStL
rhF1y4ocr8OJdNjHGp8tssc9I0LhhItT7bWgjQLHTRezVXV5kzpggAlDCQc48bdc
aYjBoLuu8jH9mgGCnPtrJMyV+T96rV5V4XJieA9k4IQ3nWJk1Nslqm5S/FSQbM32
+ineL0ZlT/x8qXNnL3FHQFDOKCng3Ww6wC7M9BDf9+Di04lNtd37pri/i5dcvsn1
WaYzvHpSGom234Bl4NQSoupKlEhfgTc5w/uuhbGSWcsH+wB4Yi7dg5U7voNkwtVo
loEaZ58ldd4Dkz16lZSSg4wzwDbMQWpGCPRAfVDAVk/AxpfOiOsCAwEAAaOBpzCB
pDAdBgNVHQ4EFgQUpahFGYUWGD8RygULRRlo6TlAkxowdQYDVR0jBG4wbIAUpahF
GYUWGD8RygULRRlo6TlAkxqhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT
b21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDX
1mKNHjwQajAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQAvdXT3GIjK
diHYGurJKSGhja8nVcZ9vm0SICyMQU3nOaMhNdrFXUP21dqO1xP+uqgc7vHGOyPg
MNLvamCY7JtmcLEgByG5Z+aeNESdwGjP4Rl4YRB83JUyOHke0cONiJXYTjGwF7FL
vCXjJm/3t5rTj+gPPMkcN3FtYpiVUn2Ra5LURCiRucsqnStEKiLeIM3WluKOFssZ
AHGkUEGXpYyuobdBvejCqdc02+ywyqGuV05mOHB7dDAt0eS0tUqaEyoKlWgIuVlN
770LJGjQkQqa0oYwrbsgKuPjH4zu7MDjzooZsYkEpgPCaK64HQ03mdWYWiqW3KY5
JxT4TdOwSXQfvmeLbT/By1Qo0m9R2Sqb4Q0t3VDILyJmvTr4dLCRjAMfDaADxiPI
58cXUeT5kLbF2kHQ8GZIFXpWQRhX5Go0sETlv35HtL9szNK/p2ngob6XkbxJf8rC
ygP96Xa09J94CPrJF34slRM3hsdf/t92ytG8HTOf+42QjT60zgApibVVXwEYwx2S
M/1FZbt9xR2nfvrKBZG4luyPuIVbAI3VbtgfP2ywIxQI7OkBQec52Ck2e4AvZk9q
PUgxRqZbzpQSdEr3U3bhEtKf/Yq3Lgx/4Luo11BlZkWRKViBpK1yTUe1C4UkFo5Z
gZO0oCwwO5YWxTCA1xCJDJeSuz16snOXpw==
-----END CERTIFICATE-----

View File

@ -1,51 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -1,29 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIE/jCCAuYCAQEwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV
BAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0
ZDAeFw0xMjAzMTUyMzEzNDZaFw0xMzAzMTUyMzEzNDZaMEUxCzAJBgNVBAYTAkFV
MRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRz
IFB0eSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDOwQ+StykH
YPBXIQPgD+ZqU4RBgbwpT94p9Fvf5/OZIenI2Ujv9wCEeRbwdtbKj+RlvcM8BX2I
27MNp0dd5G9+dLizKbDgigjDRJXVNk4d9RPd7r/51jBT3WIkkI+4qkbTMjqfhkJn
iBQZisAajucaO02F6FGxdqlFcU/l92CG12MRbvmNqmJ9odWniylKHwAfV1jSbnQS
ckvtsxAc9bCNm3mDrjAwZlZCaHWEy0sq3VoBA7y1IWxOSg7aXR5t6NHEMs61ARfQ
/bdGR4ww4haGVdflS68oSZtOa9TJytv0BaMnIFLkFDvEpq39KXjP0yrSGqJQC5cA
3yh3uJQxUcZ9A2rPRR7LoS6ZVEk+4OWRP0kPW6FILDRiHMOlj0jeMmfLzLGLW/NW
WBPBAG6pwNJaO1Y4LLHZRUJE3dM70v/lNMmB/T1S3kJ7TX+pluTgdCKo2qjxvnQI
A0CnQeeQSV7TiefuIixXwAGGdg7dZO0MSkX8NASPiS/B3KWP4pSDDEzsRmz4UqRG
0tnkFRfCKHtkBPJ7OWdHapgXnlUBImQWO2MStPenmZBzuVcCkv52QwuFC8g/EKlr
tvzRl11Ajgg9LZApI0BaOtXE/LGkBpPpXNh0Pi10ETniPhvfZhX/RYb4g6WeVGsx
oD6V9vHrD1Psp4u+QKZRldsD0d1aRvXvzwIDAQABMA0GCSqGSIb3DQEBBQUAA4IC
AQCAzJrMHAIZVPupdJiiooCHvLc3M/4wn02Wws/NgvkIO3mNs+9uZvJ/IsLSOS/0
x9gIVIXscoT0y/RRCg9IUwCGmCp9XkfL0MzBNPfhOXZ2/SXLGv2ubBTv7nyXAeF9
Oh719bbir+vmEKoMXej0LBQ3qGT6zS8Zs2iKGj1bXZjZXiTt67YkYZgr65uZTYW4
XtywTnJ+vUg9Mp6fReXgOWDlM8BiJ6JKnRn9f5Y66INSePV4NvtcIrqNNvrBEDqX
LOWuh1Vs32gOySF8A1jM/GdSCdV1Wsng5HxGMMuGAKnw35YguW598Fk8LLfE8w5V
x9Gth2RdxvimMu+qsNMq0mc78C1yPDSfRXC51t8J8d5+hke/apb6KfB/47gooQeH
TCRMorOzO8tWhK6NDPp9iKoNSYznmtWq+0Lc4Upa+cc3ktIOCiTWh9OBaFsFd8jB
Dlhw3sqwhMtqxJEoEJIZMGSE0W9p9y+D1XeNqfHmJ04NaTvuqfkt2z6ROd+pPdqb
A+b6aFZfBdh+ynOq2g6Epwq8rNe338E23gVGgNfcw4pdFq9NmpdVKREIQKObQWCQ
oElaQwIgyPI9rkpkT3QsHHJnEb9mRn05tlEplOi6S05/NIb+yz07Jb09UdAjxHDR
4MiUfXVXZwUAvuWKBnKK4ZjjgEZe21aoliLDl3yekewVqA==
-----END CERTIFICATE-----

View File

@ -1,27 +0,0 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEijCCAnICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCAiIwDQYJKoZIhvcN
AQEBBQADggIPADCCAgoCggIBAM7BD5K3KQdg8FchA+AP5mpThEGBvClP3in0W9/n
85kh6cjZSO/3AIR5FvB21sqP5GW9wzwFfYjbsw2nR13kb350uLMpsOCKCMNEldU2
Th31E93uv/nWMFPdYiSQj7iqRtMyOp+GQmeIFBmKwBqO5xo7TYXoUbF2qUVxT+X3
YIbXYxFu+Y2qYn2h1aeLKUofAB9XWNJudBJyS+2zEBz1sI2beYOuMDBmVkJodYTL
SyrdWgEDvLUhbE5KDtpdHm3o0cQyzrUBF9D9t0ZHjDDiFoZV1+VLryhJm05r1MnK
2/QFoycgUuQUO8Smrf0peM/TKtIaolALlwDfKHe4lDFRxn0Das9FHsuhLplUST7g
5ZE/SQ9boUgsNGIcw6WPSN4yZ8vMsYtb81ZYE8EAbqnA0lo7VjgssdlFQkTd0zvS
/+U0yYH9PVLeQntNf6mW5OB0IqjaqPG+dAgDQKdB55BJXtOJ5+4iLFfAAYZ2Dt1k
7QxKRfw0BI+JL8HcpY/ilIMMTOxGbPhSpEbS2eQVF8Ioe2QE8ns5Z0dqmBeeVQEi
ZBY7YxK096eZkHO5VwKS/nZDC4ULyD8QqWu2/NGXXUCOCD0tkCkjQFo61cT8saQG
k+lc2HQ+LXQROeI+G99mFf9FhviDpZ5UazGgPpX28esPU+yni75AplGV2wPR3VpG
9e/PAgMBAAGgADANBgkqhkiG9w0BAQUFAAOCAgEAyqppt9mxmlqAUkYCbNxPnc+M
1d5OQZ1Fqy0a4eF9/WxK+PqjRTKbD+rvGEulYdeCGiz8wP5HxVCdT2xzdVZdhMUX
opZGG3x5H1xXy0YLzBsxB9rkYjz+NeVtl8lKXvWDfgZ1vjjRHOIc261Eq6CPoXjT
5ENHnTyT0xbDmdkyjGNT0qowl50rlZotx6Vb2VPquAtau1m2nrvx5t0wkbJPocPA
XTndphgdH0aecJXZOgN8MWh9LYObNM5UqIFPaiNHHAetJIOLoDDIpEl5ZVj4PwtU
uiiaWpNjz3ODx2j5tmEz1SUF+6vS0OfvKx/pInQzFFRLfudgphzGYLf9rwOswBI7
8d0sEfrUNEladzvIz/IvJpuRrWJ/uLfpE4LXYTNbGWP50d1YRGxv7Zl8Bio0CU34
q+Du1CXpWce5bcOJ25KYZd7Lrf0YVzQjneuyNbBCPrp2gbweeydQWd6LGdtUab0l
gjQ3lj4E8Y1vIpTOL2K3bvkqJxJYoaYdzzGEzuv6/FS7ATYVn5sBYxJrsUqgYdjp
SMx6RS6ImNbHVy56nb6MiaztwAE4uo59vkrdKdvIETvP5duD4qDBsZL3WzJwhMxl
d9An+z3VAqEABzNtM7/Cdq7pZmgdPAHgGFasB3eihdmHsONWqExRPhcmW4H1hpVQ
pkguJFDOpRqebdLHZPI=
-----END CERTIFICATE REQUEST-----

View File

@ -1,51 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -1,51 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -1,14 +0,0 @@
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzsEPkrcpB2DwVyED4A/m
alOEQYG8KU/eKfRb3+fzmSHpyNlI7/cAhHkW8HbWyo/kZb3DPAV9iNuzDadHXeRv
fnS4symw4IoIw0SV1TZOHfUT3e6/+dYwU91iJJCPuKpG0zI6n4ZCZ4gUGYrAGo7n
GjtNhehRsXapRXFP5fdghtdjEW75japifaHVp4spSh8AH1dY0m50EnJL7bMQHPWw
jZt5g64wMGZWQmh1hMtLKt1aAQO8tSFsTkoO2l0ebejRxDLOtQEX0P23RkeMMOIW
hlXX5UuvKEmbTmvUycrb9AWjJyBS5BQ7xKat/Sl4z9Mq0hqiUAuXAN8od7iUMVHG
fQNqz0Uey6EumVRJPuDlkT9JD1uhSCw0YhzDpY9I3jJny8yxi1vzVlgTwQBuqcDS
WjtWOCyx2UVCRN3TO9L/5TTJgf09Ut5Ce01/qZbk4HQiqNqo8b50CANAp0HnkEle
04nn7iIsV8ABhnYO3WTtDEpF/DQEj4kvwdylj+KUgwxM7EZs+FKkRtLZ5BUXwih7
ZATyezlnR2qYF55VASJkFjtjErT3p5mQc7lXApL+dkMLhQvIPxCpa7b80ZddQI4I
PS2QKSNAWjrVxPyxpAaT6VzYdD4tdBE54j4b32YV/0WG+IOlnlRrMaA+lfbx6w9T
7KeLvkCmUZXbA9HdWkb1788CAwEAAQ==
-----END PUBLIC KEY-----

Binary file not shown.

30
fixtures/ca/broken_ca.crt Normal file
View File

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFNDCCAx6gAwIBAgIBATALBgkqhkiG9w0BAQUwLTEMMAoGA1UEBhMDVVNBMRAw
DgYDVQQKEwdldGNkLWNhMQswCQYDVQQLEwJDQTAeFw0xNDAzMTMwMjA4NTRaFw0y
NDAzMTMwMjA4NTRaMC0xDDAKBgNVBAYTA1VTQTEQMA4GA1UEChMHZXRjZC1jYTEL
MAkGA1UECxMCQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGyDN5
EcwViDB+EpOvZNfW9AJ79EiY8yiGEgXF9M3BLVFoB09wDT0ASEmPrpZhMSZb1eSM
emUFELzuEEDtuEG0TrFFNI3/gScZm8Mp6+d7oCqWRF87ecBLfAUCmr3vA0VD/KQz
dj8F+4UWwEXkeyzJ67vPW5n35CJrZOq9Yp8bPUoVvE1/L03wbQHeIXynEHmgPIB2
syVuQwluhrgpNX8kEsWpy3GzusuorJ3jcTONin4y4h9pgaAZvR32mhXmCRh/6i+y
u4NOsx11kSAgPBWdLJBQcj5HH3YZan/7n+ygTAIbXKI9sHxgPYPgXW0P/7OhaUiH
LEcDw2ipGpYxZxj/8hkQVJ1b4YMgD4TIFHix9TeASufsZUwEkuiTYncXp7q38feq
4z4UNqgn5ozgOT0kqVDGSiEOJTH81Tq1SUhC7FsN6UkgIVWGSYsPMyxc7V+tH2EV
qpWCnRuw9MPr+CEZfGzM88alc65ZOwmxgIU4heTTi457d5RgXqinCBCfcUdHTFYa
E65MWh0FdO1jrSw7KzFDd+vt0ajZ1K64+tbBhV4QvIrd2ktQDMk3InawFx2GAIEv
l9TxC8jf+RoamPxt7sPwPzvZuiSXj4mO1H3GdiSBn94ZVzOnDT+UV/TwwyphvCtB
OOzV2SlKZ/bl1CmD7JoRpw18W0J72RV0vd219QIDAQABo2MwYTAOBgNVHQ8BAf8E
BAMCAAQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUze1XmPTcVbM2gSnXwfVx
1VQ/ZYwwHwYDVR0jBBgwFoAUze1XmPTcVbM2gSnXwfVx1VQ/ZYwwCwYJKoZIhvcN
AQEFA4ICAQC/4a4QiGt3NhEhl2fWMYDF+EAtQj82bFT8fod8rsQQZddI0baNOzTa
9GRzAqChpoDaxzH/ErhlMs6nLL7NC6NB8Jr596cgakbIOpLcQujoajDAvF7HhbGE
cnZWXFdjEZNkAg5RM3jCcjlnZ6HfsMlQJGO3mGPGMjHIhKv+RLquXY7NOy3fczrI
THyJFfL99l77u3Ieo6MstfWog5IUM0PmNzf6ocXJ4o5woQcrSLJVx7hlHaU7iTsV
e//oHh+S/yJHmeOzmI3LayMOEGRGjP2SJBqTuOak4cINutoqJnRnt8JIOvur9zCG
rEm6aCTRi/5fqMys4vQuATPalI9/lLQa9NlMs1xoFAGjE6j8ybAUWxrAWdTWOOQd
S7IA0TU2JTIcWt8fbKUwf4gkO8rfCcj2Y2Y4xZQu8uqZI7uXCse8yNE2zWPTqCPf
BzA9kZs42AP47mknVGSl59HNAovBTjQuXlFZZ1BnBDAzCq49sDR5wcr4uetC1rss
dFfFqQPPonAGcEAaKsSoaOHgVaBHfufMM7nq8JqJvZGOmLFhUgsTO3xEgnpDts9h
cfhSS/5YVofp2Vy3+++yIkSC3NDuyNCPwfzSLA2pW1GoiIv0hdSco7ALuG9FxsCs
gSc5qcrrTkazbjlCwM9rgM0BEH8pXOAkRAEZLlKd9eg6Lh3q4yBnhw==
-----END CERTIFICATE-----

54
fixtures/ca/broken_ca.key Normal file
View File

@ -0,0 +1,54 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,29382520d522b331
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
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFYjCCA0ygAwIBAgIBAjALBgkqhkiG9w0BAQUwLTEMMAoGA1UEBhMDVVNBMRAw
DgYDVQQKEwdldGNkLWNhMQswCQYDVQQLEwJDQTAeFw0xNDAzMTMwMjA5MDdaFw0y
NDAzMTMwMjA5MDdaMEwxDDAKBgNVBAYTA1VTQTEQMA4GA1UEChMHZXRjZC1jYTEW
MBQGA1UECwwNYnJva2VuX3NlcnZlcjESMBAGA1UEAxMJMTI3LjAuMC4xMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAymbo/4oo+oi0poLAvNyXIyFLw3xC
uO0pcALKCnA84KzTopAnB45+HLKtovkIyi4j2aSEWGVw1xXE6hsJJxpcuDeBGhA3
4QdUP2OyYWs65rSpx1G8Yxm5zBd8wGO0dRgSA2dAUgWETUXmaRuiR7W2NLDzZna0
LEe8jATn9Ex3o5IeVUAx3fw/sDr1AD/HkDh2dhoXB9PVDGqGBizS0qzRsDJxhH7f
xwL1Wb4Ug7YQ0oaWniZ8dPDlxbXC4C0xsaOb6rQGSS91ivZdvNksjht4qrFnCHYO
olqI4IFet9P/B7hcaPTe0oExoTZd0o3XNrZR/rfG0MPuKA5U2BG1E+VnntYamp/l
fds1YYahvFUoJVQ5PzwY38nb2JjQm14iM2jzWrLrqKjkdEdqH9Gf7j8vlXki9Riq
4vO665z0zim/u2CpraQq2VhgX6ShmoV4vmgEnD3p4MwbXqHkKtU/1kMSo15HSKBe
b3GSFPI0EDpFYfUp0FyfFGfHtgw/Y7V8z6g65Z5c3xjvIb0r5/40mRTUJpoCJbdG
5RG6pxBUsnAVM01G6TH5TPkRgWo+0it6+qQOAObNoPqN0dyGAfN8T1zD+BEMe6H4
6toKSyGlAYyCcnSspy8JA9wEm91ZkLqxkc5qeav6ZPqCcN+Clf544XSWEHVLcgPD
VpYNXNT2DZRtJZUCAwEAAaNyMHAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF
BwMCMB0GA1UdDgQWBBQX2fL+Aa48uIwgyYFJOoKGfIqRSzAfBgNVHSMEGDAWgBTN
7VeY9NxVszaBKdfB9XHVVD9ljDAPBgNVHREECDAGhwR/AAABMAsGCSqGSIb3DQEB
BQOCAgEAfYKCbV/hvhSUqvNmQBtl8GkZ2WrDvduRQ+nQLXiUpgO28k1bieKA5SrF
/yUyjUEoXP2lQdYxGiKNzXP+WCkldPn4mrbaAbktJABuqFW+AotOyu2juyNR8nTx
xBFULKpXgF+DDXa7DnSqjaxEWz8TFLWTb8h1pc7Ha3kejB1U3V6HbcxLBLVLL4vJ
ETU0V6PnjYOmHZJCQLixB4h4v0mCCns1u3OXQaR1dL9PwRVL7qzpFTbp0jF9Y2LO
gJFuW8if80le5A+ovXJLJMoAKpKeLfSRRzPy8j4EgLw/iJO5ZLJMWOIEa1P/SLap
xfL8yfRg5jBaMhHtdhbIku1Kmyqypch1XoZ8w5hNFY/pDVL0tff+cslzUJrFLMa/
XKZqHnX07dN5Cyz/oAZSz4DhZ2LlYrNq0FTo8tqNr3tf7oakpyFr6fr6i8u7Mmwx
U6Dsg1yJXnb0nA5ROWC8td714S7oIvzFbn69pyEnwGmCxBHvfTIBKoWeYlUTSxJu
7e3wR7yia5GV8ZgmzKgB9FUd0VBDYOR3quFl0ixxv2n2slqlRwbfbJTwBdijoaCs
FlYb3WlRRFQ1s2MiWwVHQY/SMXtan5xwT0l99pWVMS/D0y6tjALHKXWfDT4Pp/wX
xNjPqNR6L4Ru1eTb6nuUGzKAgonn/w9bYXqLiYnRye9pIf00gtU=
-----END CERTIFICATE-----

View File

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEAymbo/4oo+oi0poLAvNyXIyFLw3xCuO0pcALKCnA84KzTopAn
B45+HLKtovkIyi4j2aSEWGVw1xXE6hsJJxpcuDeBGhA34QdUP2OyYWs65rSpx1G8
Yxm5zBd8wGO0dRgSA2dAUgWETUXmaRuiR7W2NLDzZna0LEe8jATn9Ex3o5IeVUAx
3fw/sDr1AD/HkDh2dhoXB9PVDGqGBizS0qzRsDJxhH7fxwL1Wb4Ug7YQ0oaWniZ8
dPDlxbXC4C0xsaOb6rQGSS91ivZdvNksjht4qrFnCHYOolqI4IFet9P/B7hcaPTe
0oExoTZd0o3XNrZR/rfG0MPuKA5U2BG1E+VnntYamp/lfds1YYahvFUoJVQ5PzwY
38nb2JjQm14iM2jzWrLrqKjkdEdqH9Gf7j8vlXki9Riq4vO665z0zim/u2CpraQq
2VhgX6ShmoV4vmgEnD3p4MwbXqHkKtU/1kMSo15HSKBeb3GSFPI0EDpFYfUp0Fyf
FGfHtgw/Y7V8z6g65Z5c3xjvIb0r5/40mRTUJpoCJbdG5RG6pxBUsnAVM01G6TH5
TPkRgWo+0it6+qQOAObNoPqN0dyGAfN8T1zD+BEMe6H46toKSyGlAYyCcnSspy8J
A9wEm91ZkLqxkc5qeav6ZPqCcN+Clf544XSWEHVLcgPDVpYNXNT2DZRtJZUCAwEA
AQKCAgEAl7gIk/UWvqZW9DIzE98vE9BToJe21DRCyYnttWFo4OnsQoFYIFv5wL1X
V0DiC9wGV5Dw++oeabwRvYLCm6MxOY2xor3hhTcfOd0by9a7clCeq6BjXM3d7lT0
2KpkjRmb9x0go9sqz1nEW6mxPZvCl0DFU1tLt52WgkbzMLdZPy26uyDBwKrjetDW
8nbcuwj4E5N/DAkIPKRlDp/u8KlHDZLicPVB/UYEcF8BtbF2brkgkjA7PtWNB2U2
TSDTjVsc9xQ3WgjPTXlbzsHkmimRjDIrD7afRagjzlZrj9TD6R+TdcGIfbcGYtgE
AF7+oi6MzCkqSTd1gGUtyEGNwPpHbvyR0V3S/3Hqw7r+yIMLt7CWrX+n3j4CcQ6G
pVHef/Gs+rBtyl3LReX28C92VvTnEtEWC8R/5OqqXe1+UpOqfvln9PEHOSXRBVAI
ztzqma6+SgUy69b3WCMEaVL5AGFizPcJNuhUap2J5PqjZlxjy+oq/RPOwyn5aj00
ROpXLOKnFdrkqwGw3AVKEdSUcDz4s5v8ZWgJeGS1ZiqhMUcsXzeVyV+7eQvCp7dq
MnrdygRGNMXTlfN5dz4yZRDtYMGo8tMa/8GiX7ey5S8vQu55dXJry6i5vGK4+Qqb
NzhwznyU7+C9h+kUJkUR8MkzDNYhwSpQVFQJ/zNSxY5x01YAsIkCggEBAPddOBuZ
IGHyiNKZ697pn20AF6+46YyWNrceI3Y4MDzEKiFVfqxLmMxjq58gH9ZM4CRq/ZUz
vZbet6+IbtAUCIFPv6H+LI0U8Kejpizs02CJS42uFtGVT8F78abDKkZe1Mrb++zS
/qpoqZ/LMTOmZYTr4OZp+DmtVeSJhlYRaWWetE2b4XKjMbAmMK72v0dVPN/hQcSb
Yi3xR+45MLEKlItaZ9IbaE6bhXZKl6dRpjqgUhU5IWA7sQkFm/b++zKTrEplA/tz
TpPxqQPOds+RDGCCraxu2ICq62Y3FHJQK1DXFr9p0CNX9Dz9AbLK5JiYKihRFb23
GE+gz1xF5Pp+8UsCggEBANF32S+DEIWe6E52tXgmeap9xg66dUv5YMztYsGyaTnF
IbhdcT7M+EfxFm/vbPdd9mVREHDHu7h5kHIjWAix+DOJa/nrVmDfdtymv1cRxFse
rcrbeOJb37GJJS9EV+N20IPmSsPj437BmegB9Rc5BjmdVWLytzod5a5Mvvp9nGzX
SKPw5EUMR9C1bZxlRgzw6w65rB0yxKHIteB7eYgbpeBHRw3xq6PCzw3H10/553qX
tcfQB/YJ/hnqaqixY6LmXnPHJXU2wnXWR/QwTr0rk2UgnXgcONHlQ65MR4GxIAza
OTyu4r48XUH65F+rlHxIJqBDpVdzf/A46qOuzgs62J8CggEBAOd3XkJM5kVhGvDe
wR1ExT7M4F05DanVAfwWAp7j8xdZhAbPJop47tEKzxRGjiQMqYzKZOGRme2sGHvz
kaW5qT+/bRVbbzrRBmQHuT6+mQjzUDSSW53gNtJZdYVTiKJyqHHuqW0w/sZcy6TQ
EQlAwixAQKG7NWBbN01z9rVg85v4hsU8gRixZpRrGBEQqWpJc34XHWCo+ZT9+w4K
i+qOePNxNEciCFfOJXPMVt5lg8PGMyjS3c1b7cwAaLIWZN4t2wF+RtyrSDMd5ca/
EuQl2UwR3AvHaWX1CfMKxWI2bGHn8sxIalA4RD4xjb5NJt03PfOd9FcjFmeklYTF
jn9r+8MCggEAfKnzXE+Imb3FTE1iGyvq5QkNwt49yQWWEuCFEfp4naUxOGSEbXfX
nBlj3SKFm4MUjZ/9ROHaWyQeT4+xaRtiOGnlFUx2kBjuyMuEvPEaB5DupfiQrUc4
jpSsyMDH/dxMpPN+M6+BSYM3cdkYYMXTap60nrsNSU1Z0K5kSvhPDIfj9436jQ2O
ACy6G4Y6dqE7g/wE7yuz0wV9GSjjX5n00tIY+7eFC2V5jR4Ois6UcWWxDkZFNq0j
yZC2AcfxIJYySH2RUX1RpoftMus9MWCpzFno3f8N4f2sliNXu1wLUxrdTbxXvhh2
+Dm1iSq4qG7YbjFUSgO3dOSq4Ne8UPqoyQKCAQBr0KXHwlEUWGNCzlakbKkGgwp0
0dRQ4AASWKLOM8kyYJVLDYMEm/MEPRUnh6J4sIeL//vxMWhUaWDFuwYg1keIjCl1
3Q9tLbrIFwHdIWjR/dX5fwXJ+tzOAx+YkscIlb9206TLVbimTLeKo25EI2ZcQVb6
MUtkpdfGBEcXTI2LRPE6KnCSy0bpX25Y79qUj5ztzLrrI2Uy7FjRpdFyKoLN6al9
w/ELH0+dliF/RdP/t/goI0dvjS/S+KHcaQIdRcHxptk+3rl6Y9CVLDwcRL3Ttiq+
IcnupppZ+xNXwy6P7bweDCpWKTz+BZ0w2PG8nP0XjkFl2ioso4bnt+D8g8Pa
-----END RSA PRIVATE KEY-----

View File

@ -1,31 +1,30 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----

View File

@ -1,54 +1,54 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,5AD5C95753A0AE70
DEK-Info: DES-EDE3-CBC,d2e70acc12a86116
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
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,58 @@
#!/bin/bash
#
# This script is used to generate all cert related files for etcd testing.
# location for temporary depot
depot=".depot"
# The passphrases for the keys are `asdf`.
passphrase="--passphrase asdf"
# etcd-ca could be found at github.com/coreos/etcd-ca
if [ $# -eq 0 ]; then
# try to find it through $GOPATH
IFS=':' read -a paths <<< "${GOPATH}"
for path in ${paths[@]}; do
if [ -f "${path}/bin/etcd-ca" ]; then
ca="${path}/bin/etcd-ca --depot-path $depot"
break
fi
done
if [ "$ca" == "" ]; then echo "Failed finding etcd-ca binary"; exit 1; fi
else
# treat the first argument as the path to etcd-ca binary
ca="$1 --depot-path $depot"
fi
rm -rf $depot 2>/dev/null
# create ca, which is assumed to be the broken one
$ca init $passphrase
# export out and rename files
$ca export | tar xvf -
mv ca.crt broken_ca.crt
mv ca.key broken_ca.key
# create certificate
$ca new-cert $passphrase --ip 127.0.0.1 server
$ca sign $passphrase server
# export out and rename files
$ca export --insecure $passphrase server | tar xvf -
mv server.crt broken_server.crt
mv server.key.insecure broken_server.key.insecure
rm -rf $depot 2>/dev/null
# create ca
$ca init $passphrase
$ca export | tar xvf -
# create certificate for server
$ca new-cert $passphrase --ip 127.0.0.1 server
$ca sign $passphrase server
$ca export --insecure $passphrase server | tar xvf -
$ca chain server > server-chain.pem
# create certificate for server2
$ca new-cert $passphrase --ip 127.0.0.1 server2
$ca sign $passphrase server2
$ca export --insecure $passphrase server2 | tar xvf -
rm -rf $depot 2>/dev/null

View File

@ -1,337 +0,0 @@
[ new_oids ]
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
# Policies used by the TSA examples.
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = ./demoCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = default # use public key default MD
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
# utf8only: only UTF8Strings (PKIX recommendation after 2004).
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
string_mask = utf8only
req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = AU
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Some-State
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Internet Widgits Pty Ltd
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default =
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# This is required for TSA certificates.
# This is required for client Auth and server Auth
extendedKeyUsage = critical,timeStamping,serverAuth,clientAuth
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = critical,timeStamping,serverAuth,clientAuth
subjectAltName = @alt_names
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
keyUsage = keyCertSign, cRLSign
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always
[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
####################################################################
[ tsa ]
default_tsa = tsa_config1 # the default TSA section
[ tsa_config1 ]
# These are used by the TSA reply generation only.
dir = ./demoCA # TSA root directory
serial = $dir/tsaserial # The current serial number (mandatory)
crypto_device = builtin # OpenSSL engine to use for signing
signer_cert = $dir/tsacert.pem # The TSA signing certificate
# (optional)
certs = $dir/cacert.pem # Certificate chain to include in reply
# (optional)
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
default_policy = tsa_policy1 # Policy if request did not specify it
# (optional)
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
digests = md5, sha1 # Acceptable message digests (mandatory)
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
clock_precision_digits = 0 # number of digits after dot. (optional)
ordering = yes # Is ordering defined for timestamps?
# (optional, default: no)
tsa_name = yes # Must the TSA name be included in the reply?
# (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no)
[alt_names]
IP.1 = 127.0.0.1

View File

@ -1,63 +1,61 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFfDCCA2SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET
MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
dHkgTHRkMB4XDTEzMTExMzE5MDgxMloXDTE0MTExMzE5MDgxMlowZTELMAkGA1UE
BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp
ZGdpdHMgUHR5IEx0ZDEeMBwGA1UEAwwVaHR0cDovLzEyNy4wLjAuMTo0MDAxMIIC
IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1XBtjDav5Sl3H+/fUcGiQO36
oqtZG+YuC9D0z0u89Shq+XNs3tRtonGGCyEIrDtI6R7PItMJa6rQ1VuFoMWPrjmF
f5tFemSOZtQx/DF78H+5tWaIBVDA+Kw1zxdqj1n3/AQjAGsSuqhgcaIQQFqTNNtA
tW40048fDh17jWIDB9baF65az2uArq97uS4deDujG3CHV9svO7hoqpzYt039VDKK
4N+dDMUZFqhEmY2MqjyQySY2bd/gsYBjcGWSIuonALactiYDc4zIusAfNptnXycw
K/aQAqDwhwMcQA9L5YKQ5hoUukDTQFbvoNLJ3vNQDI/o8sjCh94EkMuopSp90tJ/
syTPKRlh/MaGMXvwu8Vab5iPeVop48jTKl3Z+G8NErGM8KKCyd1mQoGisVuIMQPK
uJUi7jOu6wgXlA8ZgUGfSQQDA4v2Q0tV/GlJmvsP5JshA3v7C/sSBY/3AnPHeWTl
ozXlNgXitxps1EwgR2jo+YW2gxrfM//xtgMCjMXjO9g2TsCnWR6j93oXWn88UP/C
eAcyjeTdJjW+piuLdvYOctY6+Yql5gm9Vx0u+w9jTmpzOCoh+9cNtjqmPiOhecFc
Vf71vMf4krMp6lmY/Nq1/km9u0ViNP5CJHk18YXG42vnj7sUgT7WgpLh8g/iPc2p
etH9lMd9te+Jyak/zA8CAwEAAaNXMFUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAw
KgYDVR0lAQH/BCAwHgYIKwYBBQUHAwgGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNV
HREECDAGhwR/AAABMA0GCSqGSIb3DQEBBQUAA4ICAQCmF13fF7kAcgCzRKBCpggz
ObVNSK9btGKUU+xyOZsRgEDWdfeBvG3VzXflLMDv3P45O90CHkcGfckbj1ISctIY
0OSnCn4vmIwnhwUWyYlCagtNB68GVcPH8XLxn/wsnT2MbiA/ohUStKXQtBmBxIUH
rI+7r28qcHW7AnT47G5BbSYzW0xYzlkUwyl8rBxRLDKVTHBJ5GmlREJKdAzKS7CS
6jhcsxa544Rsa7CDvjLKpJO0iploL0/GY+5oj3VdhgdEJgwqwvu3skfd1N8wkxH4
NQuRmyvXxcMSxKv4vbOOUm4PfOqOwwXiVZLoc29ePUv9zCU2AVdS21DD9zAZeKDb
B87VWnQKO6JUvL5vX7xsMnsSbnLHGA2kPv4IDZ6jKuZdVneM+whDZlBWpHRL2RKX
K0JZICf7+EbmrUW3Rwl+dIaIJ55Ni1rfDSZWeIYKFx04Mod6Wbch7ahb/XVvIDe9
SFjLfeNj7L/Iz0i+1lTarAMxIRC521IwcobhAxqxYCv3oNf6f+tz8DyCCvsTCc9W
/OLKX7sukh1ohle+0EFrSYpX5PzkHwZRVZjx55KwkIV/KtwBadJv+z6iwW3qOn/A
/1yC8Mbc2TdCaRPwFO80LAg9cz+XfT5vZoQUvOnOxIrhFnasQ/xiovy0zKCr2Fjg
ePQ4BNEN9wt3SsPp8ig39g==
MIIFWzCCA0WgAwIBAgIBAjALBgkqhkiG9w0BAQUwLTEMMAoGA1UEBhMDVVNBMRAw
DgYDVQQKEwdldGNkLWNhMQswCQYDVQQLEwJDQTAeFw0xNDAzMTMwMjA5MjJaFw0y
NDAzMTMwMjA5MjJaMEUxDDAKBgNVBAYTA1VTQTEQMA4GA1UEChMHZXRjZC1jYTEP
MA0GA1UECxMGc2VydmVyMRIwEAYDVQQDEwkxMjcuMC4wLjEwggIiMA0GCSqGSIb3
DQEBAQUAA4ICDwAwggIKAoICAQDI3EvqJrLWsnPbjAT8ENiMRyBINhhafubi5Nb+
glEzkbC2kv2zXkVkpkBubDRwyh3eomSbdwKYk3yz+IopT753teJueRpMPq9Ayr/+
PZl4Y1tG04KcjfOvOls6zPsDfHzluR8TE705If5wwZu3Bdwxzdtx9T0ROzIEgRt0
Axuce5qkg93IWNxOrIr+4LCxYfTpvpTXO20lz0IuQNm1Opo9PVoWn7PXdOmuCzSG
2hW1DcKqSyQP7IkplBJS0EhoovIsXavSkPKJssvQj73ZFIBVgKhXuHmPNdrypaQk
CtxsqbVdOOlojItqYTTDAiadwRQWkYgDOSQCGJiPqYVJx+rH4MlzxQ6n9x2qIcne
lfMr+VFDEc1YvHu1XLMg5b1ImD6ChutYW0RhFJ3CQVdQR2i4kJ8T1DSJYLISMODZ
ux1cZaUoSL/EkrC5/8POWZmP8nJXO6A4wrZDHF30/qWpo+T5PvsA6cABfX1jkcTx
PBXGK1qOZ8rToTxprJ2zc3zuZNxSgM32nzjcPUgn559Mgdl0HR4c4JeTZGsebWmx
MWmkz//BV4eUaGHqCpzRQHf3YIxysvDC2Xf4z2Alk8AlLRXp7/ksatdxAtyc+y8+
MWCc6N0YbI9zjv+ezCBqR+mu1P5Tb0HebPFz3dOdIpiC3kU8QyMEagw8u5xliZs4
AxwdNwIDAQABo3IwcDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYD
VR0OBBYEFD6UrVN8uolWz6et79jVeZetjd4XMB8GA1UdIwQYMBaAFJ1ZVb5LWPs5
S6RuN506RgFplJK2MA8GA1UdEQQIMAaHBH8AAAEwCwYJKoZIhvcNAQEFA4ICAQCo
sKn1Rjx0tIVWAZAZB4lCWvkQDp/txnb5zzQUlKhIW2o98IklASmOYYyZbE2PXlda
/n8TwKIzWgIoNh5AcgLWhtASrnZdGFXY88n5jGk6CVZ1+Dl+IX99h+r+YHQzf1jU
BjGrZHGv3pPjwhFGDS99lM/TEBk/eLI2Kx5laL+nWMTwa8M1OwSIh6ZxYPVlWUqb
rurk5l/YqW+UkYIXIQhe6LwtB7tBjr6nDIWBfHQ7uN8IdB8VIAF6lejr22VmERTW
j+zJ5eTzuQN1f0s930mEm8pW7KgGxlEqrUlSJtxlMFCv6ZHZk1Y4yEiOCBKlPNme
X3B+lhj//PH3gLNm3+ZRr5ena3k+wL9Dd3d3GDCIx0ERQyrGS/rJpqNPI+8ZQlG0
nrFlm7aP6UznESQnJoSFbydiD0EZ4hXSdmDdXQkTklRpeXfMcrYBGN7JrGZOZ2T2
WtXBMx2bgPeEH50KRrwUMFe122bchh0Fr+hGvNK2Q9/gRyQPiYHq6vSF4GzorzLb
aDuWA9JRH8/c0z8tMvJ7KjmmmIxd39WWGZqiBrGQR7utOJjpQl+HCsDIQM6yZ/Bu
RpwKj2yBz0OQg4tWbtqUuFkRMTkCR6vo3PadgO1VWokM7UFUXlScnYswcM5EwnzJ
/IsYJ2s1V706QVUzAGIbi3+wYi3enk7JfYoGIqa2oA==
-----END CERTIFICATE-----

View File

@ -1,32 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFfDCCA2SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET
MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
dHkgTHRkMB4XDTEzMTExMzE5MDgxMloXDTE0MTExMzE5MDgxMlowZTELMAkGA1UE
BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp
ZGdpdHMgUHR5IEx0ZDEeMBwGA1UEAwwVaHR0cDovLzEyNy4wLjAuMTo0MDAxMIIC
IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1XBtjDav5Sl3H+/fUcGiQO36
oqtZG+YuC9D0z0u89Shq+XNs3tRtonGGCyEIrDtI6R7PItMJa6rQ1VuFoMWPrjmF
f5tFemSOZtQx/DF78H+5tWaIBVDA+Kw1zxdqj1n3/AQjAGsSuqhgcaIQQFqTNNtA
tW40048fDh17jWIDB9baF65az2uArq97uS4deDujG3CHV9svO7hoqpzYt039VDKK
4N+dDMUZFqhEmY2MqjyQySY2bd/gsYBjcGWSIuonALactiYDc4zIusAfNptnXycw
K/aQAqDwhwMcQA9L5YKQ5hoUukDTQFbvoNLJ3vNQDI/o8sjCh94EkMuopSp90tJ/
syTPKRlh/MaGMXvwu8Vab5iPeVop48jTKl3Z+G8NErGM8KKCyd1mQoGisVuIMQPK
uJUi7jOu6wgXlA8ZgUGfSQQDA4v2Q0tV/GlJmvsP5JshA3v7C/sSBY/3AnPHeWTl
ozXlNgXitxps1EwgR2jo+YW2gxrfM//xtgMCjMXjO9g2TsCnWR6j93oXWn88UP/C
eAcyjeTdJjW+piuLdvYOctY6+Yql5gm9Vx0u+w9jTmpzOCoh+9cNtjqmPiOhecFc
Vf71vMf4krMp6lmY/Nq1/km9u0ViNP5CJHk18YXG42vnj7sUgT7WgpLh8g/iPc2p
etH9lMd9te+Jyak/zA8CAwEAAaNXMFUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAw
KgYDVR0lAQH/BCAwHgYIKwYBBQUHAwgGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNV
HREECDAGhwR/AAABMA0GCSqGSIb3DQEBBQUAA4ICAQCmF13fF7kAcgCzRKBCpggz
ObVNSK9btGKUU+xyOZsRgEDWdfeBvG3VzXflLMDv3P45O90CHkcGfckbj1ISctIY
0OSnCn4vmIwnhwUWyYlCagtNB68GVcPH8XLxn/wsnT2MbiA/ohUStKXQtBmBxIUH
rI+7r28qcHW7AnT47G5BbSYzW0xYzlkUwyl8rBxRLDKVTHBJ5GmlREJKdAzKS7CS
6jhcsxa544Rsa7CDvjLKpJO0iploL0/GY+5oj3VdhgdEJgwqwvu3skfd1N8wkxH4
NQuRmyvXxcMSxKv4vbOOUm4PfOqOwwXiVZLoc29ePUv9zCU2AVdS21DD9zAZeKDb
B87VWnQKO6JUvL5vX7xsMnsSbnLHGA2kPv4IDZ6jKuZdVneM+whDZlBWpHRL2RKX
K0JZICf7+EbmrUW3Rwl+dIaIJ55Ni1rfDSZWeIYKFx04Mod6Wbch7ahb/XVvIDe9
SFjLfeNj7L/Iz0i+1lTarAMxIRC521IwcobhAxqxYCv3oNf6f+tz8DyCCvsTCc9W
/OLKX7sukh1ohle+0EFrSYpX5PzkHwZRVZjx55KwkIV/KtwBadJv+z6iwW3qOn/A
/1yC8Mbc2TdCaRPwFO80LAg9cz+XfT5vZoQUvOnOxIrhFnasQ/xiovy0zKCr2Fjg
ePQ4BNEN9wt3SsPp8ig39g==
MIIFWzCCA0WgAwIBAgIBAjALBgkqhkiG9w0BAQUwLTEMMAoGA1UEBhMDVVNBMRAw
DgYDVQQKEwdldGNkLWNhMQswCQYDVQQLEwJDQTAeFw0xNDAzMTMwMjA5MjJaFw0y
NDAzMTMwMjA5MjJaMEUxDDAKBgNVBAYTA1VTQTEQMA4GA1UEChMHZXRjZC1jYTEP
MA0GA1UECxMGc2VydmVyMRIwEAYDVQQDEwkxMjcuMC4wLjEwggIiMA0GCSqGSIb3
DQEBAQUAA4ICDwAwggIKAoICAQDI3EvqJrLWsnPbjAT8ENiMRyBINhhafubi5Nb+
glEzkbC2kv2zXkVkpkBubDRwyh3eomSbdwKYk3yz+IopT753teJueRpMPq9Ayr/+
PZl4Y1tG04KcjfOvOls6zPsDfHzluR8TE705If5wwZu3Bdwxzdtx9T0ROzIEgRt0
Axuce5qkg93IWNxOrIr+4LCxYfTpvpTXO20lz0IuQNm1Opo9PVoWn7PXdOmuCzSG
2hW1DcKqSyQP7IkplBJS0EhoovIsXavSkPKJssvQj73ZFIBVgKhXuHmPNdrypaQk
CtxsqbVdOOlojItqYTTDAiadwRQWkYgDOSQCGJiPqYVJx+rH4MlzxQ6n9x2qIcne
lfMr+VFDEc1YvHu1XLMg5b1ImD6ChutYW0RhFJ3CQVdQR2i4kJ8T1DSJYLISMODZ
ux1cZaUoSL/EkrC5/8POWZmP8nJXO6A4wrZDHF30/qWpo+T5PvsA6cABfX1jkcTx
PBXGK1qOZ8rToTxprJ2zc3zuZNxSgM32nzjcPUgn559Mgdl0HR4c4JeTZGsebWmx
MWmkz//BV4eUaGHqCpzRQHf3YIxysvDC2Xf4z2Alk8AlLRXp7/ksatdxAtyc+y8+
MWCc6N0YbI9zjv+ezCBqR+mu1P5Tb0HebPFz3dOdIpiC3kU8QyMEagw8u5xliZs4
AxwdNwIDAQABo3IwcDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYD
VR0OBBYEFD6UrVN8uolWz6et79jVeZetjd4XMB8GA1UdIwQYMBaAFJ1ZVb5LWPs5
S6RuN506RgFplJK2MA8GA1UdEQQIMAaHBH8AAAEwCwYJKoZIhvcNAQEFA4ICAQCo
sKn1Rjx0tIVWAZAZB4lCWvkQDp/txnb5zzQUlKhIW2o98IklASmOYYyZbE2PXlda
/n8TwKIzWgIoNh5AcgLWhtASrnZdGFXY88n5jGk6CVZ1+Dl+IX99h+r+YHQzf1jU
BjGrZHGv3pPjwhFGDS99lM/TEBk/eLI2Kx5laL+nWMTwa8M1OwSIh6ZxYPVlWUqb
rurk5l/YqW+UkYIXIQhe6LwtB7tBjr6nDIWBfHQ7uN8IdB8VIAF6lejr22VmERTW
j+zJ5eTzuQN1f0s930mEm8pW7KgGxlEqrUlSJtxlMFCv6ZHZk1Y4yEiOCBKlPNme
X3B+lhj//PH3gLNm3+ZRr5ena3k+wL9Dd3d3GDCIx0ERQyrGS/rJpqNPI+8ZQlG0
nrFlm7aP6UznESQnJoSFbydiD0EZ4hXSdmDdXQkTklRpeXfMcrYBGN7JrGZOZ2T2
WtXBMx2bgPeEH50KRrwUMFe122bchh0Fr+hGvNK2Q9/gRyQPiYHq6vSF4GzorzLb
aDuWA9JRH8/c0z8tMvJ7KjmmmIxd39WWGZqiBrGQR7utOJjpQl+HCsDIQM6yZ/Bu
RpwKj2yBz0OQg4tWbtqUuFkRMTkCR6vo3PadgO1VWokM7UFUXlScnYswcM5EwnzJ
/IsYJ2s1V706QVUzAGIbi3+wYi3enk7JfYoGIqa2oA==
-----END CERTIFICATE-----

View File

@ -1,30 +0,0 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIFEDCCAvgCAQAwZTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEeMBwGA1UEAwwVaHR0
cDovLzEyNy4wLjAuMTo0MDAxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
AgEA1XBtjDav5Sl3H+/fUcGiQO36oqtZG+YuC9D0z0u89Shq+XNs3tRtonGGCyEI
rDtI6R7PItMJa6rQ1VuFoMWPrjmFf5tFemSOZtQx/DF78H+5tWaIBVDA+Kw1zxdq
j1n3/AQjAGsSuqhgcaIQQFqTNNtAtW40048fDh17jWIDB9baF65az2uArq97uS4d
eDujG3CHV9svO7hoqpzYt039VDKK4N+dDMUZFqhEmY2MqjyQySY2bd/gsYBjcGWS
IuonALactiYDc4zIusAfNptnXycwK/aQAqDwhwMcQA9L5YKQ5hoUukDTQFbvoNLJ
3vNQDI/o8sjCh94EkMuopSp90tJ/syTPKRlh/MaGMXvwu8Vab5iPeVop48jTKl3Z
+G8NErGM8KKCyd1mQoGisVuIMQPKuJUi7jOu6wgXlA8ZgUGfSQQDA4v2Q0tV/GlJ
mvsP5JshA3v7C/sSBY/3AnPHeWTlozXlNgXitxps1EwgR2jo+YW2gxrfM//xtgMC
jMXjO9g2TsCnWR6j93oXWn88UP/CeAcyjeTdJjW+piuLdvYOctY6+Yql5gm9Vx0u
+w9jTmpzOCoh+9cNtjqmPiOhecFcVf71vMf4krMp6lmY/Nq1/km9u0ViNP5CJHk1
8YXG42vnj7sUgT7WgpLh8g/iPc2petH9lMd9te+Jyak/zA8CAwEAAaBmMGQGCSqG
SIb3DQEJDjFXMFUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwKgYDVR0lAQH/BCAw
HgYIKwYBBQUHAwgGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNVHREECDAGhwR/AAAB
MA0GCSqGSIb3DQEBBQUAA4ICAQCeVkI4JwSyax5kJJ1iljkngfK+BdsrqBJWPITj
mrl9DH7/2ev0GdzHEG3oQrti6vMvsowS6vHtpgc1tsbS9UwDY/N0ZgFWgnb5O5k2
4zZfGkma3GHCvG9WXsA9+Gs7KedggsXxfnJTLe4B/sZqtRO0dMD/JZTJQ6reuayh
bYvVBVSmittAjsfer+9xuXkHYYAPNYmW52aUN1AhnIsS3TVp1vHcxgNoFOQglN21
lHwmeh5QbTx/paHFnWLLqLVydbiB/Qzz6x4zsEKESATd02WbN9XKUfGM0G+bG+57
ErtrU7yzsLjPYYPcP9nYg8dzfdwVgfdjg+yw2hdmkqjDQD3YAmxRcat7uK8htVa0
z4dfjdNRO3HhSLALKS/Tl9qpLKpEi8/0ByYErJz6i+Xyf4pkdPQcBQKybkFja136
9xkonhE7DLTo1zQobfAJlnfTMxuJc0mOGvT+DqGSCFmNEl3WgIAgu9m77mp81Bqo
0qwrB3pYSAzL9xHuluwZMn37sdmVFFReEkEaRllRgDTZL9vSQh2yOqtV920083/y
sHPUijSsKysSKz0RuzMBCc3RD07Kcs1TFg/NdZiYKf8V9NDDOgk5LC2Sqoin7v6F
yB4wpnm6RqQ7iSRpp/VBs3PAnK2uJEkoOU5p5jZdQ0IDtesHVzM7bCUIrQIX2pAr
owvMhQ==
-----END CERTIFICATE REQUEST-----

View File

@ -1,54 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,E445BB698AB9CDC4
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
-----END RSA PRIVATE KEY-----

View File

@ -1,51 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
MIIJKAIBAAKCAgEA1XBtjDav5Sl3H+/fUcGiQO36oqtZG+YuC9D0z0u89Shq+XNs
3tRtonGGCyEIrDtI6R7PItMJa6rQ1VuFoMWPrjmFf5tFemSOZtQx/DF78H+5tWaI
BVDA+Kw1zxdqj1n3/AQjAGsSuqhgcaIQQFqTNNtAtW40048fDh17jWIDB9baF65a
z2uArq97uS4deDujG3CHV9svO7hoqpzYt039VDKK4N+dDMUZFqhEmY2MqjyQySY2
bd/gsYBjcGWSIuonALactiYDc4zIusAfNptnXycwK/aQAqDwhwMcQA9L5YKQ5hoU
ukDTQFbvoNLJ3vNQDI/o8sjCh94EkMuopSp90tJ/syTPKRlh/MaGMXvwu8Vab5iP
eVop48jTKl3Z+G8NErGM8KKCyd1mQoGisVuIMQPKuJUi7jOu6wgXlA8ZgUGfSQQD
A4v2Q0tV/GlJmvsP5JshA3v7C/sSBY/3AnPHeWTlozXlNgXitxps1EwgR2jo+YW2
gxrfM//xtgMCjMXjO9g2TsCnWR6j93oXWn88UP/CeAcyjeTdJjW+piuLdvYOctY6
+Yql5gm9Vx0u+w9jTmpzOCoh+9cNtjqmPiOhecFcVf71vMf4krMp6lmY/Nq1/km9
u0ViNP5CJHk18YXG42vnj7sUgT7WgpLh8g/iPc2petH9lMd9te+Jyak/zA8CAwEA
AQKCAgBR1Tw7IRCJdT92IDroFqyF5nhM/BM7LiKDZ0clX22ANVHmeEnKmXm7aXky
NSUlG8nVj3ltaapX/HL7Co8OWBDBhM5ZYYfe6ETsyfisL7DMQbxK/5exKggCj8xF
rT2u3pjEqDVfSK4yoLHxf2hptBBymImTxkA8yMfoWodvap+s1sRhhfjNQ/NfhmqS
Ukr8OSlNMPTDS4cth4OhvmccyKsTKBm1JCcLqVn4JOXAVdQTxQriBGOj9s0oYQg/
JMJF3q67iEhHUgXKvLSNXXHaNvUIN3cxs+P9DgWKTjf7m6HGyiuR/Xfq/UXBilNv
vsGlWHZdiqOOykhDXW00stDjGoqIoVhkz4dxabY7il2BPW0MujdYNELVOJ/ikJ9v
0M+3jgyyS8UDhgBAz6LFYXRkAyREbRi6NwWGT4vWtrfycEd7tO02OZ9v7w9Xb6el
iU/AvNlb5MqfXaMp9gWJR2tDka66cMBhH+9VtMDd2J6Qpfjzwnn6VtEqUvt7Q+KF
LyPb0CtOTzxYuPdCc5ZpIiIiv6iudUXsDOSl9CsXMTGTD0W8g9RQ+GKo703fZWlu
LU9gOWVXq9c4VaR2dpLNjvOPzYxkChCHI5rNtcsnU6x7XumL/n1iJq+3/SMQ5K6t
QSqTXAuMDZkHGhLB38zrQBb4Zg9LsojzEC1AvCrhqvN3nx+UuQKCAQEA/TySUNIr
39j+oQtw0m6icqWDOMTKn6GamDOxq9+9gsNfY1mQt+W2XLYfPgScNXXXaggYxtXU
i4dhEc+f1a8crBSFPPIgVx/ggawTO1jBZAGrrO/ppcePvf8bGmj45ybmiB3NjzhO
Eg50neZ9/ciz0cmx76Flb/2zFto9aj1RhxKpjAQHq8aNdBCanPVuZC7ov2PgBpPI
UU8FZB/pYjVjha+on4+fUG2S3urEwJR6uA9zwSrNsLmJ4VrcqBGN2huAkrsqzUXP
vysrn82Y+sR4q5fmXb3Dn5pFZ3mSuRclnp0ESEFA//U95JTvG1aBtK4UGwzI78ia
FVIqyRqyOZ52xQKCAQEA18SuK51fglgLvdq62GlzteDcZy2GIk8JRh6/rJe3X/E4
4PgoWYEz++N3SMZsXWaz76KpGaAhirV6l60uy0/iG/yoV6P9amokFELdcWoj9+I2
OAVPbJrRjZOKFDDA/TwgZIKd7amUArfwwvZLAxCzG77HSaz6/DcxwRriKR32GPQ5
ty0sfK+xtU4li9kT2iOBHHjyjBcTfN2SjBupwaLQ4jHu37dpfWIEqfk9hEVaTPCh
UejbzKsbEvTg6R5YMDa5JPcf9x2Wxk4ZbC8FPWdCMcXYtprH8pwoHa4hqTgHBN+Z
LNQTgXKqItWPTMWuG14J/l2C71YcwtzCcYUaPfNEwwKCAQAnFqZvG0Hyd4g2S5HK
qZEhqTKsHJQ6N7OpMrGGGi8idA3RRA32lNqlTOddp1CFX/80OrO4XWFFeEwfd7Dw
RutiFHjMg4NCb4Uz/t+pFXYkfa2GMDIciMVDSpFgbjudUn/bGt6T8Nj8KIcPqHhi
KAy5oSx6FKuXsc1nBaDdOUHQW60YE7craKaE99slxyyXAjai9EOsQDt3cX8fiV14
70zBYe/hUUYCICe/iPV91G1s49W2R2kgkkMaKfBNcQg4Vm5uN73PmasLkxpUvGOU
sab+tZ+1cIk1pZZ49mcTcuM3rHzwukHSQIShN+wAiEXVIdmwozSQ7qH6EIjSKfDA
vBkRAoIBAHRX/zpRT1CvPRWQPbO3mMb3iqCv8WXKjEudBOmBnUVEgtD7vnYUrv0h
eA5rv77VRCzw3pGMwMlUddgXb+X9GwTQRc2MBXc96Fpse49OFjrxZR7r7hm3mUrn
xUqBx25E34qSy6l9COw2VsIpn+T1Oj65rifR+DvLXy6q2kwlda+a8QwOdbB95CrJ
CoHP+V5kSpgZt19GiiGIMB8QQ4a/zjZJim5jLaSIF8+3Ly6FXt2h2rqZ/vrrQFwG
YsgQrqjAuTBveHL9J3GiZx7oc8DaTt0bu3ErIKl2/kKSxF/EcDR2hNehOytPsuG5
md1hsjHbkTPxJEr9eeCwvMANb0r8Q5UCggEBAOhGwGdM24ULcSLGONg2Qz03bdDP
alDteEfq79X3mEuxn2x7N+tu31sBKCgIlrrTlsG6vWgLebFelAF3Vm/T3Hc6ifUL
yDf7/gkvM+X/+f4XYt2Z5r0u+bVOsAITydDQJhakGfar/0it6URknXr9NJca8tRD
DATfrRA5jHCbu+sEoDLb6m2lGXIFnkeD0rc7tz27inues1sxyTLy6lENAB4c6K2n
oFtigO7F22miqUiVOXAAllJo6yVfwtmbtDkEYTjLZ2oQwpEdyff70f/iDm2+uKRO
eF8kNuKxR2Em03slcfOV6M145fN35Eq5IuOI5N/+SiQhvywbjh6j5DRHlTg=
MIIJKAIBAAKCAgEAyNxL6iay1rJz24wE/BDYjEcgSDYYWn7m4uTW/oJRM5GwtpL9
s15FZKZAbmw0cMod3qJkm3cCmJN8s/iKKU++d7XibnkaTD6vQMq//j2ZeGNbRtOC
nI3zrzpbOsz7A3x85bkfExO9OSH+cMGbtwXcMc3bcfU9ETsyBIEbdAMbnHuapIPd
yFjcTqyK/uCwsWH06b6U1zttJc9CLkDZtTqaPT1aFp+z13Tprgs0htoVtQ3Cqksk
D+yJKZQSUtBIaKLyLF2r0pDyibLL0I+92RSAVYCoV7h5jzXa8qWkJArcbKm1XTjp
aIyLamE0wwImncEUFpGIAzkkAhiYj6mFScfqx+DJc8UOp/cdqiHJ3pXzK/lRQxHN
WLx7tVyzIOW9SJg+gobrWFtEYRSdwkFXUEdouJCfE9Q0iWCyEjDg2bsdXGWlKEi/
xJKwuf/DzlmZj/JyVzugOMK2Qxxd9P6lqaPk+T77AOnAAX19Y5HE8TwVxitajmfK
06E8aayds3N87mTcUoDN9p843D1IJ+efTIHZdB0eHOCXk2RrHm1psTFppM//wVeH
lGhh6gqc0UB392CMcrLwwtl3+M9gJZPAJS0V6e/5LGrXcQLcnPsvPjFgnOjdGGyP
c47/nswgakfprtT+U29B3mzxc93TnSKYgt5FPEMjBGoMPLucZYmbOAMcHTcCAwEA
AQKCAgBS1vCESKOXgo/f61ae8v+skyUQQyc2I4Jr739wBiUhRKQCGIuDr4ylHyAR
qpTSM7mv+X/O0n2CmcljnEy3Dwl568zQTSf4bB3xde1LGPKzwR6DDnaexLjM+x9n
F+UqoewM/pV/U7PF3WxH6sGi8UrIS6OG02L1OVm+m9TLuwBnQF8eHLiaiXOLCwRk
bBzTe5f70zslrX+tiVY9J0fiw6GbQjNmg0UzxicePcbTGxy6yEsR2t2rp51GRahs
+TPz28hPXe6gcGFnQxNmF/JvllH7cY18aDvSQZ7kVkZlCwmv0ypWoUM6eESDgkW1
a6yrgVccm7bhxW5BYw2AqqSrMkV0oMcCUjh2rYvex7w6dM374Ok3DD/dXjTHLNV5
+0tHMxXUiCKwe7hVEg+iGD4E1jap5n5c4RzpEtAXsGEK5WUBksHi9qOBv+lubjZn
Kcfbos+BbnmUCU3MmU48EZwyFQIu9djkLXfJV2Cbbg9HmkrIOYgi4tFjoBKeQLE4
6GCucMWnNfMO7Kq/z7c+7sfWOAA55pu0Ojel8VH6US+Y/1mEuSUhQudrJn8GxAmc
4t+C2Ie1Q1bK3iJbd0NUqtlwd9xI9wQgCbaxfQceUmBBjuTUu3YFctZ7Jia7h18I
gZ3wsKfySDhW29XTFvnT3FUpc+AN9Pv4sB7uobm6qOBV8/AdKQKCAQEA1zwIuJki
bSgXxsD4cfKgQsyIk0eMj8bDOlf/A8AFursXliH3rRASoixXNgzWrMhaEIE2BeeT
InE13YCUjNCKoz8oZJqKYpjh3o/diZf1vCo6m/YUSR+4amynWE4FEAa58Og2WCJ3
Nx8/IMpmch2VZ+hSQuNr5uvpH84+eZADQ1GB6ypzqxb5HjIEeryLJecDQGe4ophd
JCo3loezq/K0XJQI8GTBe2GQPjXSmLMZKksyZoWEXAaC1Q+sdJWZvBpm3GfVQbXu
q7wyqTMknVIlEOy0sHxstsbayysSFFQ/fcgKjyQb8f4efOkyQg8mH5vQOZghbHJ+
7I8wVSSBt+bE2wKCAQEA7udRoo2NIoIpJH+2+SPqJJVq1gw/FHMM4oXNZp+AAjR1
hTWcIzIXleMyDATl5ZFzZIY1U2JMifS5u2R7fDZEu9vfZk4e6BJUJn+5/ahjYFU8
m8WV4rFWR6XN0SZxPb43Mn6OO7EoMqr8InRufiN4LwIqnPqDm2D9Fdijb9QFJ2UG
QLKNnIkLTcUfx1RYP4T48CHkeZdxV8Cp49SzSSV8PbhIVBx32bm/yO6nLHoro7Wl
YqXGW0wItf2BUA5a5eYNO0ezVkOkTp2aj/p9i+0rqbsYa480hzlnOzYI5F72Z8V2
iPltUAeQn53Vg1azySa1x8/0Xp5nVsgQSh18CH3p1QKCAQBxZv4pVPXgkXlFjTLZ
xr5Ns7pZ7x7OOiluuiJw9WGPazgYMDlxA8DtlXM11Tneu4lInOu73LGXOhLpa+/Y
6Z/CN2qu5wX2wRpwy1gsQNaGl7FdryAtDvt5h1n8ms7sDL83gQHxGee6MUpvmnSz
t4aawrtk5rJZbv7bdS1Rm2E8vNs47psXD/mdwTi++kxOYhNCgeO0N5cLkPrM4x71
f+ErzguPrWaL/XGkdXNKZULjF8+sWLjOS9fvLlzs6E2h4D9F7addAeCIt5XxtDKc
eUVyT2U8f7I/8zIgTccu0tzJBvcZSCs5K20g3zVNvPGXQd9KGS+zFfht51vN4HhA
TuR1AoIBAGuQBKZeexP1bJa9VeF4dRxBldeHrgMEBeIbgi5ZU+YqPltaltEV5Z6b
q1XUArpIsZ6p+mpvkKxwXgtsI1j6ihnW1g+Wzr2IOxEWYuQ9I3klB2PPIzvswj8B
/NfVKhk1gl6esmVXzxR4/Yp5x6HNUHhBznPdKtITaf+jCXr5B9UD3DvW6IF5Bnje
bv9tD0qSEQ71A4xnTiXHXfZxNsOROA4F4bLVGnUR97J9GRGic/GCgFMY9mT2p9lg
qQ8lV3G5EW4GS01kqR6oQQXgLxSIFSeXUFhlIq5bfwoeuwQvaVuxgTwMqVXmAgyL
oK1ApTPE1QWAsLLFORvOed8UxVqBbn0CggEBALfr/wheXCKLdzFzm03sO1i9qVz2
vnpxzexXW3V/TtM6Dff2ojgkDC+CVximtAiLA/Wj60hXnQxw53g5VVT5rESx0J3c
pq+azbi1eWzFeOrqJvKQhMfYc0nli7YuGnPkKzeepJJtWZHYkAjL4QZAn1jt0RqV
DQmlGPGiOuGP8uh59c23pbjgh4eSJnvhOT2BFKhKZpBdTBYeiQiZBqIyme8rNTFr
NmpBxtUr77tccVTrcWWhhViG36UNpetAP7b5QCHScIXZJXrEqyK5HaePqi5UMH8o
alSz6s2REG/xP7x54574TvRG/3cIamv1AfZAOjin7BwhlSLhPl2eeh4Cgas=
-----END RSA PRIVATE KEY-----

View File

@ -1,31 +1,31 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----

View File

@ -1,29 +0,0 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIE8DCCAtgCAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCAiIwDQYJKoZIhvcN
AQEBBQADggIPADCCAgoCggIBALY5FfOgbclrkfZS/XpzPJgWZrs/W+zakuoBDtke
TeIdVMk2lNZ//oA4g+eYVPnf0DSJoEPvJIOuwjF8b2M3iYR+fwV4iI2NKVEiV546
9qtjkSm7OlvNRMAeWztGm8uXI9wg9MEqVU4SPlpTV7kUE2c/d3jU6ZAjvgBn6sWn
RWG39lBGXecqay6PzbAYhlrGH/OuPZaL4mc6nE1D7/mdBOo3J+6dNQUzB9FhU/BY
55M5c0tSrDGlM9pPE9/p3JXu1dcp95YtZbUCib/NPVnHGEK5s8LfG6RE8kxxUj6b
PjPmyEF+jsgwJb2vdHjOXbwbtsjiWprZ6TrAFfLQWmD9qbsVxvyMlnuzrfPyaREW
hgijBADDGBmcL8k/OFH3LqhmwOETLpGepCV5BbRqD3+tDIQcjjlt1fdJTDu1RuPs
921EdHXaQNzTTPbO9DoNpFY0l6UlHjlz8VlnwuEoehd3NDZc7a/b8X6Ry0Jwuaym
ouUJE9GQrGJRJ3imZkwrhhqxiWItp6HJKgePD38V1tFbifqjiF/LfhqaZ/oaFU5f
3wLbs41BuMOQtEoNsmRCNd2L6BJ++fskqnJfbuw6YRoB7gvoFjyqn5CZuox8ArmO
s/oYk2nior2jBEQI+S0JwVquBDvbvyUnYT+E/mSURUA6kPtHax0kaDZnQijXGc4K
wASpAgMBAAGgZjBkBgkqhkiG9w0BCQ4xVzBVMAkGA1UdEwQCMAAwCwYDVR0PBAQD
AgXgMCoGA1UdJQEB/wQgMB4GCCsGAQUFBwMIBggrBgEFBQcDAQYIKwYBBQUHAwIw
DwYDVR0RBAgwBocEfwAAATANBgkqhkiG9w0BAQUFAAOCAgEAsjhQOckysiSTZaz/
Ck5APYE13ckBQOxvHqrCvDQSRMqq/yb/eWtItQhCs9u3fKGFGKCefPYwtVdUj6v2
g4SpXzBblcXNP8SXEtbcNuG4lPNsTc2YbDxuLWmgvLX8on2nq0f+TcGmtvvmCaLz
tEdLPlQfkzQUlwfaK4kMJ4qzR8eeHxBrhKJyDyzSreZSa/ZXMcKpjJLhXl6oM+ud
cfi0BO/xOKt/MmGHAxTMNrTFV5HcEWzws+r51sCcIV4BwuELA5rZuG0leaj3CDDy
3dPkpLp3HObbX3KV6yyCCfEAN4pyoZQNut8i87FITsYbJJy4ld7/PWTvg/JMk96X
ZACpeI1ERL/Sr3uzFpmlLszwSQ7t/hv5ykFA6d1QLv0u+EX1mL1O/PZ5Lb3moC4t
7ma3CffPqJpEjvvdXtweol62MI4Rr/1sXyZGR+lvkjcoSY5vzv0j7V4w6/e1In3D
nHY4vmpuy65w5gGm/s2y2cXRfCc8P4we0+A+QbNAgt3eicdJmWZGcWwlMQI10Nmq
6Qnp8cpwvFM/iCIajfIAz0fD7G0UEL5ExSFoh6WhFFDOYbTl5MeXUjMaYmemICE2
r3GVfZxHLvDQzftkq/oSXXiZgLkoYveN0R7VJuUfCgyLOlJL5O8WX2lX8odUKINc
DcZ/FpV+R/u7WGm2j0tvRA4y9Qc=
-----END CERTIFICATE REQUEST-----

View File

@ -1,54 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,F332544C4A2552FC
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
-----END RSA PRIVATE KEY-----

View File

@ -1,51 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -165,22 +165,17 @@ func (h *handler) watch(keypath string, index int, closeChan <-chan bool) error
return fmt.Errorf("lock watch lookup error: %s", err.Error())
}
nodes := lockNodes{resp.Node.Nodes}
prevIndex := nodes.PrevIndex(index)
prevIndex, modifiedIndex := nodes.PrevIndex(index)
// If there is no previous index then we have the lock.
if prevIndex == 0 {
return nil
}
// Watch previous index until it's gone.
waitIndex := resp.Node.ModifiedIndex
// Wait from the last modification of the node.
waitIndex := modifiedIndex + 1
// Since event store has only 1000 histories we should use first node's CreatedIndex if available
if firstNode := nodes.First(); firstNode != nil {
waitIndex = firstNode.CreatedIndex
}
_, err = h.client.Watch(path.Join(keypath, strconv.Itoa(prevIndex)), waitIndex, false, nil, stopWatchChan)
resp, err = h.client.Watch(path.Join(keypath, strconv.Itoa(prevIndex)), uint64(waitIndex), false, nil, stopWatchChan)
if err == etcd.ErrWatchStoppedByUser {
return fmt.Errorf("lock watch closed")
} else if err != nil {

View File

@ -41,17 +41,20 @@ func (s lockNodes) FindByValue(value string) (*etcd.Node, int) {
return nil, 0
}
// Retrieves the index that occurs before a given index.
func (s lockNodes) PrevIndex(index int) int {
// Find the node with the largest index in the lockNodes that is smaller than the given index. Also return the lastModified index of that node.
func (s lockNodes) PrevIndex(index int) (int, int) {
sort.Sort(s)
// Iterate over each node to find the given index. We keep track of the
// previous index on each iteration so we can return it when we match the
// index we're looking for.
var prevIndex int
for _, node := range s.Nodes {
idx, _ := strconv.Atoi(path.Base(node.Key))
if index == idx {
return prevIndex
return prevIndex, int(node.ModifiedIndex)
}
prevIndex = idx
}
return 0
return 0, 0
}

View File

@ -3,9 +3,35 @@ package server
import (
"crypto/tls"
"net"
"github.com/coreos/etcd/log"
)
func NewListener(addr string) (net.Listener, error) {
// NewListener creates a net.Listener
// If the given scheme is "https", it will generate TLS configuration based on TLSInfo.
// If any error happens, this function will call log.Fatal
func NewListener(scheme, addr string, tlsInfo *TLSInfo) net.Listener {
if scheme == "https" {
cfg, err := tlsInfo.ServerConfig()
if err != nil {
log.Fatal("TLS info error: ", err)
}
l, err := newTLSListener(addr, cfg)
if err != nil {
log.Fatal("Failed to create TLS listener: ", err)
}
return l
}
l, err := newListener(addr)
if err != nil {
log.Fatal("Failed to create listener: ", err)
}
return l
}
func newListener(addr string) (net.Listener, error) {
if addr == "" {
addr = ":http"
}
@ -16,7 +42,7 @@ func NewListener(addr string) (net.Listener, error) {
return l, nil
}
func NewTLSListener(addr string, cfg *tls.Config) (net.Listener, error) {
func newTLSListener(addr string, cfg *tls.Config) (net.Listener, error) {
if addr == "" {
addr = ":https"
}

View File

@ -231,6 +231,19 @@ func (s *PeerServer) findCluster(discoverURL string, peers []string) {
}
peers = append(peers, prevPeers...)
// Remove its own peer address from the peer list to join
u, err := url.Parse(s.Config.URL)
if err != nil {
log.Fatalf("cannot parse peer address %v: %v", s.Config.URL, err)
}
filteredPeers := make([]string, 0)
for _, v := range peers {
if v != u.Host {
filteredPeers = append(filteredPeers, v)
}
}
peers = filteredPeers
// if there is backup peer lists, use it to find cluster
if len(peers) > 0 {
ok := s.joinCluster(peers)
@ -371,13 +384,12 @@ func (s *PeerServer) startAsFollower(cluster []string) {
// getVersion fetches the peer version of a cluster.
func getVersion(t *transporter, versionURL url.URL) (int, error) {
resp, req, err := t.Get(versionURL.String())
resp, _, err := t.Get(versionURL.String())
if err != nil {
return 0, err
}
defer resp.Body.Close()
t.CancelWhenTimeout(req)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return 0, err
@ -460,10 +472,11 @@ func (s *PeerServer) joinByPeer(server raft.Server, peer string, scheme string)
json.NewEncoder(&b).Encode(c)
joinURL := url.URL{Host: peer, Scheme: scheme, Path: "/v2/admin/machines/" + server.Name()}
log.Debugf("Send Join Request to %s", joinURL.String())
log.Infof("Send Join Request to %s", joinURL.String())
req, _ := http.NewRequest("PUT", joinURL.String(), &b)
resp, err := t.client.Do(req)
for {
if err != nil {
return fmt.Errorf("Unable to join: %v", err)
@ -471,8 +484,7 @@ func (s *PeerServer) joinByPeer(server raft.Server, peer string, scheme string)
if resp != nil {
defer resp.Body.Close()
t.CancelWhenTimeout(req)
log.Infof("»»»» %d", resp.StatusCode)
if resp.StatusCode == http.StatusOK {
var msg joinMessageV2
if err := json.NewDecoder(resp.Body).Decode(&msg); err != nil {
@ -500,7 +512,7 @@ func (s *PeerServer) joinByPeer(server raft.Server, peer string, scheme string)
EtcdURL: s.server.URL(),
}
json.NewEncoder(&b).Encode(c)
resp, req, err = t.Post(address, &b)
resp, _, err = t.Post(address, &b)
} else if resp.StatusCode == http.StatusBadRequest {
log.Debug("Reach max number peers in the cluster")

View File

@ -11,6 +11,11 @@ import (
"github.com/coreos/etcd/log"
"github.com/coreos/etcd/third_party/github.com/goraft/raft"
httpclient "github.com/coreos/etcd/third_party/github.com/mreiferson/go-httpclient"
)
const (
snapshotTimeout = time.Second * 120
)
// Transporter layer for communication between raft nodes
@ -20,8 +25,10 @@ type transporter struct {
serverStats *raftServerStats
registry *Registry
client *http.Client
transport *http.Transport
client *http.Client
transport *httpclient.Transport
snapshotClient *http.Client
snapshotTransport *httpclient.Transport
}
type dialer func(network, addr string) (net.Conn, error)
@ -30,20 +37,38 @@ type dialer func(network, addr string) (net.Conn, error)
// Create http or https transporter based on
// whether the user give the server cert and key
func NewTransporter(followersStats *raftFollowersStats, serverStats *raftServerStats, registry *Registry, dialTimeout, requestTimeout, responseHeaderTimeout time.Duration) *transporter {
tr := &http.Transport{
Dial: func(network, addr string) (net.Conn, error) {
return net.DialTimeout(network, addr, dialTimeout)
},
tr := &httpclient.Transport{
ResponseHeaderTimeout: responseHeaderTimeout,
// This is a workaround for Transport.CancelRequest doesn't work on
// HTTPS connections blocked. The patch for it is in progress,
// and would be available in Go1.3
// More: https://codereview.appspot.com/69280043/
ConnectTimeout: dialTimeout,
RequestTimeout: dialTimeout + responseHeaderTimeout,
ReadWriteTimeout: responseHeaderTimeout,
}
// Sending snapshot might take a long time so we use a different HTTP transporter
// Timeout is set to 120s (Around 100MB if the bandwidth is 10Mbits/s)
// This timeout is not calculated by heartbeat time.
// TODO(xiangl1) we can actually calculate the max bandwidth if we know
// average RTT.
// It should be equal to (TCP max window size/RTT).
sTr := &httpclient.Transport{
ConnectTimeout: dialTimeout,
RequestTimeout: snapshotTimeout,
ReadWriteTimeout: snapshotTimeout,
}
t := transporter{
client: &http.Client{Transport: tr},
transport: tr,
requestTimeout: requestTimeout,
followersStats: followersStats,
serverStats: serverStats,
registry: registry,
client: &http.Client{Transport: tr},
transport: tr,
snapshotClient: &http.Client{Transport: sTr},
snapshotTransport: sTr,
requestTimeout: requestTimeout,
followersStats: followersStats,
serverStats: serverStats,
registry: registry,
}
return &t
@ -52,6 +77,9 @@ func NewTransporter(followersStats *raftFollowersStats, serverStats *raftServerS
func (t *transporter) SetTLSConfig(tlsConf tls.Config) {
t.transport.TLSClientConfig = &tlsConf
t.transport.DisableCompression = true
t.snapshotTransport.TLSClientConfig = &tlsConf
t.snapshotTransport.DisableCompression = true
}
// Sends AppendEntries RPCs to a peer when the server is the leader.
@ -81,7 +109,7 @@ func (t *transporter) SendAppendEntriesRequest(server raft.Server, peer *raft.Pe
start := time.Now()
resp, httpRequest, err := t.Post(fmt.Sprintf("%s/log/append", u), &b)
resp, _, err := t.Post(fmt.Sprintf("%s/log/append", u), &b)
end := time.Now()
@ -100,8 +128,6 @@ func (t *transporter) SendAppendEntriesRequest(server raft.Server, peer *raft.Pe
if resp != nil {
defer resp.Body.Close()
t.CancelWhenTimeout(httpRequest)
aeresp := &raft.AppendEntriesResponse{}
if _, err = aeresp.Decode(resp.Body); err != nil && err != io.EOF {
log.Warn("transporter.ae.decoding.error:", err)
@ -125,7 +151,7 @@ func (t *transporter) SendVoteRequest(server raft.Server, peer *raft.Peer, req *
u, _ := t.registry.PeerURL(peer.Name)
log.Debugf("Send Vote from %s to %s", server.Name(), u)
resp, httpRequest, err := t.Post(fmt.Sprintf("%s/vote", u), &b)
resp, _, err := t.Post(fmt.Sprintf("%s/vote", u), &b)
if err != nil {
log.Debugf("Cannot send VoteRequest to %s : %s", u, err)
@ -134,8 +160,6 @@ func (t *transporter) SendVoteRequest(server raft.Server, peer *raft.Peer, req *
if resp != nil {
defer resp.Body.Close()
t.CancelWhenTimeout(httpRequest)
rvrsp := &raft.RequestVoteResponse{}
if _, err = rvrsp.Decode(resp.Body); err != nil && err != io.EOF {
log.Warn("transporter.vr.decoding.error:", err)
@ -158,7 +182,7 @@ func (t *transporter) SendSnapshotRequest(server raft.Server, peer *raft.Peer, r
u, _ := t.registry.PeerURL(peer.Name)
log.Debugf("Send Snapshot Request from %s to %s", server.Name(), u)
resp, httpRequest, err := t.Post(fmt.Sprintf("%s/snapshot", u), &b)
resp, _, err := t.Post(fmt.Sprintf("%s/snapshot", u), &b)
if err != nil {
log.Debugf("Cannot send Snapshot Request to %s : %s", u, err)
@ -167,8 +191,6 @@ func (t *transporter) SendSnapshotRequest(server raft.Server, peer *raft.Peer, r
if resp != nil {
defer resp.Body.Close()
t.CancelWhenTimeout(httpRequest)
ssrsp := &raft.SnapshotResponse{}
if _, err = ssrsp.Decode(resp.Body); err != nil && err != io.EOF {
log.Warn("transporter.ss.decoding.error:", err)
@ -191,7 +213,7 @@ func (t *transporter) SendSnapshotRecoveryRequest(server raft.Server, peer *raft
u, _ := t.registry.PeerURL(peer.Name)
log.Debugf("Send Snapshot Recovery from %s to %s", server.Name(), u)
resp, httpRequest, err := t.Post(fmt.Sprintf("%s/snapshotRecovery", u), &b)
resp, err := t.PostSnapshot(fmt.Sprintf("%s/snapshotRecovery", u), &b)
if err != nil {
log.Debugf("Cannot send Snapshot Recovery to %s : %s", u, err)
@ -200,8 +222,6 @@ func (t *transporter) SendSnapshotRecoveryRequest(server raft.Server, peer *raft
if resp != nil {
defer resp.Body.Close()
t.CancelWhenTimeout(httpRequest)
ssrrsp := &raft.SnapshotRecoveryResponse{}
if _, err = ssrrsp.Decode(resp.Body); err != nil && err != io.EOF {
log.Warn("transporter.ssr.decoding.error:", err)
@ -227,10 +247,8 @@ func (t *transporter) Get(urlStr string) (*http.Response, *http.Request, error)
return resp, req, err
}
// Cancel the on fly HTTP transaction when timeout happens.
func (t *transporter) CancelWhenTimeout(req *http.Request) {
go func() {
time.Sleep(t.requestTimeout)
t.transport.CancelRequest(req)
}()
// PostSnapshot posts a json format snapshot to the given url
// The underlying HTTP transport has a minute level timeout
func (t *transporter) PostSnapshot(url string, body io.Reader) (*http.Response, error) {
return t.snapshotClient.Post(url, "application/json", body)
}

View File

@ -44,8 +44,8 @@ Peer Communication Options:
-peer-ca-file=<path> Path to the peer CA file.
-peer-cert-file=<path> Path to the peer cert file.
-peer-key-file=<path> Path to the peer key file.
-peer-heartbeat-timeout=<time>
Time (in milliseconds) for a heartbeat to timeout.
-peer-heartbeat-interval=<time>
Time (in milliseconds) of a heartbeat interval.
-peer-election-timeout=<time>
Time (in milliseconds) for an election to timeout.

View File

@ -85,17 +85,15 @@ func TestV1GetKeyDir(t *testing.T) {
//
func TestV1WatchKey(t *testing.T) {
tests.RunServer(func(s *server.Server) {
var body map[string]interface{}
var watchResp *http.Response
c := make(chan bool)
go func() {
resp, _ := tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v1/watch/foo/bar"))
body = tests.ReadBodyJSON(resp)
watchResp, _ = tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v1/watch/foo/bar"))
c <- true
}()
// Make sure response didn't fire early.
time.Sleep(1 * time.Millisecond)
assert.Nil(t, body, "")
// Set a value.
v := url.Values{}
@ -113,6 +111,7 @@ func TestV1WatchKey(t *testing.T) {
t.Fatal("cannot get watch result")
}
body := tests.ReadBodyJSON(watchResp)
assert.NotNil(t, body, "")
assert.Equal(t, body["action"], "set", "")

View File

@ -151,7 +151,7 @@ func TestV1SetKeyCASOnValueFail(t *testing.T) {
body := tests.ReadBodyJSON(resp)
assert.Equal(t, body["errorCode"], 101, "")
assert.Equal(t, body["message"], "Compare failed", "")
assert.Equal(t, body["cause"], "[AAA != XXX] [0 != 2]", "")
assert.Equal(t, body["cause"], "[AAA != XXX]", "")
assert.Equal(t, body["index"], 2, "")
})
}

View File

@ -90,17 +90,15 @@ func TestV2GetKeyRecursively(t *testing.T) {
//
func TestV2WatchKey(t *testing.T) {
tests.RunServer(func(s *server.Server) {
var body map[string]interface{}
var watchResp *http.Response
c := make(chan bool)
go func() {
resp, _ := tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?wait=true"))
body = tests.ReadBodyJSON(resp)
watchResp, _ = tests.Get(fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar?wait=true"))
c <- true
}()
// Make sure response didn't fire early.
time.Sleep(1 * time.Millisecond)
assert.Nil(t, body, "")
// Set a value.
v := url.Values{}
@ -118,6 +116,7 @@ func TestV2WatchKey(t *testing.T) {
t.Fatal("cannot get watch result")
}
body := tests.ReadBodyJSON(watchResp)
assert.NotNil(t, body, "")
assert.Equal(t, body["action"], "set", "")

View File

@ -239,7 +239,7 @@ func TestV2SetKeyCASOnIndexFail(t *testing.T) {
body := tests.ReadBodyJSON(resp)
assert.Equal(t, body["errorCode"], 101, "")
assert.Equal(t, body["message"], "Compare failed", "")
assert.Equal(t, body["cause"], "[ != XXX] [10 != 2]", "")
assert.Equal(t, body["cause"], "[10 != 2]", "")
assert.Equal(t, body["index"], 2, "")
})
}
@ -307,7 +307,7 @@ func TestV2SetKeyCASOnValueFail(t *testing.T) {
body := tests.ReadBodyJSON(resp)
assert.Equal(t, body["errorCode"], 101, "")
assert.Equal(t, body["message"], "Compare failed", "")
assert.Equal(t, body["cause"], "[AAA != XXX] [0 != 2]", "")
assert.Equal(t, body["cause"], "[AAA != XXX]", "")
assert.Equal(t, body["index"], 2, "")
})
}
@ -330,6 +330,84 @@ func TestV2SetKeyCASWithMissingValueFails(t *testing.T) {
})
}
// Ensures that a key is not set if both previous value and index do not match.
//
// $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
// $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=YYY -d prevValue=AAA -d prevIndex=3
//
func TestV2SetKeyCASOnValueAndIndexFail(t *testing.T) {
tests.RunServer(func(s *server.Server) {
v := url.Values{}
v.Set("value", "XXX")
fullURL := fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar")
resp, _ := tests.PutForm(fullURL, v)
assert.Equal(t, resp.StatusCode, http.StatusCreated)
tests.ReadBody(resp)
v.Set("value", "YYY")
v.Set("prevValue", "AAA")
v.Set("prevIndex", "3")
resp, _ = tests.PutForm(fullURL, v)
assert.Equal(t, resp.StatusCode, http.StatusPreconditionFailed)
body := tests.ReadBodyJSON(resp)
assert.Equal(t, body["errorCode"], 101, "")
assert.Equal(t, body["message"], "Compare failed", "")
assert.Equal(t, body["cause"], "[AAA != XXX] [3 != 2]", "")
assert.Equal(t, body["index"], 2, "")
})
}
// Ensures that a key is not set if previous value match but index does not.
//
// $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
// $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=YYY -d prevValue=XXX -d prevIndex=3
//
func TestV2SetKeyCASOnValueMatchAndIndexFail(t *testing.T) {
tests.RunServer(func(s *server.Server) {
v := url.Values{}
v.Set("value", "XXX")
fullURL := fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar")
resp, _ := tests.PutForm(fullURL, v)
assert.Equal(t, resp.StatusCode, http.StatusCreated)
tests.ReadBody(resp)
v.Set("value", "YYY")
v.Set("prevValue", "XXX")
v.Set("prevIndex", "3")
resp, _ = tests.PutForm(fullURL, v)
assert.Equal(t, resp.StatusCode, http.StatusPreconditionFailed)
body := tests.ReadBodyJSON(resp)
assert.Equal(t, body["errorCode"], 101, "")
assert.Equal(t, body["message"], "Compare failed", "")
assert.Equal(t, body["cause"], "[3 != 2]", "")
assert.Equal(t, body["index"], 2, "")
})
}
// Ensures that a key is not set if previous index matches but value does not.
//
// $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=XXX
// $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=YYY -d prevValue=AAA -d prevIndex=2
//
func TestV2SetKeyCASOnIndexMatchAndValueFail(t *testing.T) {
tests.RunServer(func(s *server.Server) {
v := url.Values{}
v.Set("value", "XXX")
fullURL := fmt.Sprintf("%s%s", s.URL(), "/v2/keys/foo/bar")
resp, _ := tests.PutForm(fullURL, v)
assert.Equal(t, resp.StatusCode, http.StatusCreated)
tests.ReadBody(resp)
v.Set("value", "YYY")
v.Set("prevValue", "AAA")
v.Set("prevIndex", "2")
resp, _ = tests.PutForm(fullURL, v)
assert.Equal(t, resp.StatusCode, http.StatusPreconditionFailed)
body := tests.ReadBodyJSON(resp)
assert.Equal(t, body["errorCode"], 101, "")
assert.Equal(t, body["message"], "Compare failed", "")
assert.Equal(t, body["cause"], "[AAA != XXX]", "")
assert.Equal(t, body["index"], 2, "")
})
}
// Ensure that we can set an empty value
//
// $ curl -X PUT localhost:4001/v2/keys/foo/bar -d value=

View File

@ -9,6 +9,14 @@ import (
ustrings "github.com/coreos/etcd/pkg/strings"
)
// explanations of Compare function result
const (
CompareMatch = 0
CompareIndexNotMatch = 1
CompareValueNotMatch = 2
CompareNotMatch = 3
)
var Permanent time.Time
// node is the basic element in the store system.
@ -321,11 +329,23 @@ func (n *node) UpdateTTL(expireTime time.Time) {
}
}
func (n *node) Compare(prevValue string, prevIndex uint64) bool {
compareValue := (prevValue == "" || n.Value == prevValue)
compareIndex := (prevIndex == 0 || n.ModifiedIndex == prevIndex)
return compareValue && compareIndex
// Compare function compares node index and value with provided ones.
// second result value explains result and equals to one of Compare.. constants
func (n *node) Compare(prevValue string, prevIndex uint64) (ok bool, which int) {
indexMatch := (prevIndex == 0 || n.ModifiedIndex == prevIndex)
valueMatch := (prevValue == "" || n.Value == prevValue)
ok = valueMatch && indexMatch
switch {
case valueMatch && indexMatch:
which = CompareMatch
case indexMatch && !valueMatch:
which = CompareValueNotMatch
case valueMatch && !indexMatch:
which = CompareIndexNotMatch
default:
which = CompareNotMatch
}
return
}
// Clone function clone the node recursively and return the new node.

View File

@ -181,6 +181,18 @@ func (s *store) Set(nodePath string, dir bool, value string, expireTime time.Tim
return e, nil
}
// returns user-readable cause of failed comparison
func getCompareFailCause(n *node, which int, prevValue string, prevIndex uint64) string {
switch which {
case CompareIndexNotMatch:
return fmt.Sprintf("[%v != %v]", prevIndex, n.ModifiedIndex)
case CompareValueNotMatch:
return fmt.Sprintf("[%v != %v]", prevValue, n.Value)
default:
return fmt.Sprintf("[%v != %v] [%v != %v]", prevValue, n.Value, prevIndex, n.ModifiedIndex)
}
}
func (s *store) CompareAndSwap(nodePath string, prevValue string, prevIndex uint64,
value string, expireTime time.Time) (*Event, error) {
@ -207,8 +219,8 @@ func (s *store) CompareAndSwap(nodePath string, prevValue string, prevIndex uint
// If both of the prevValue and prevIndex are given, we will test both of them.
// Command will be executed, only if both of the tests are successful.
if !n.Compare(prevValue, prevIndex) {
cause := fmt.Sprintf("[%v != %v] [%v != %v]", prevValue, n.Value, prevIndex, n.ModifiedIndex)
if ok, which := n.Compare(prevValue, prevIndex); !ok {
cause := getCompareFailCause(n, which, prevValue, prevIndex)
s.Stats.Inc(CompareAndSwapFail)
return nil, etcdErr.NewError(etcdErr.EcodeTestFailed, cause, s.CurrentIndex)
}
@ -309,8 +321,8 @@ func (s *store) CompareAndDelete(nodePath string, prevValue string, prevIndex ui
// If both of the prevValue and prevIndex are given, we will test both of them.
// Command will be executed, only if both of the tests are successful.
if !n.Compare(prevValue, prevIndex) {
cause := fmt.Sprintf("[%v != %v] [%v != %v]", prevValue, n.Value, prevIndex, n.ModifiedIndex)
if ok, which := n.Compare(prevValue, prevIndex); !ok {
cause := getCompareFailCause(n, which, prevValue, prevIndex)
s.Stats.Inc(CompareAndDeleteFail)
return nil, etcdErr.NewError(etcdErr.EcodeTestFailed, cause, s.CurrentIndex)
}

View File

@ -117,8 +117,8 @@ func TestTLSUnauthenticatedClient(t *testing.T) {
defer stopServer(proc)
cacertfile := "../../fixtures/ca/ca.crt"
certfile := "../../fixtures/ca/broken/server.crt"
keyfile := "../../fixtures/ca/broken/server.key.insecure"
certfile := "../../fixtures/ca/broken_server.crt"
keyfile := "../../fixtures/ca/broken_server.key.insecure"
cert, err := tls.LoadX509KeyPair(certfile, keyfile)
if err != nil {

View File

@ -14,6 +14,10 @@ func TestMultiNodeKillAllAndRecovery(t *testing.T) {
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
stop := make(chan bool)
leaderChan := make(chan string, 1)
all := make(chan bool, 1)
clusterSize := 5
argGroup, etcds, err := CreateCluster(clusterSize, procAttr, false)
defer DestroyCluster(etcds)
@ -24,9 +28,12 @@ func TestMultiNodeKillAllAndRecovery(t *testing.T) {
c := etcd.NewClient(nil)
c.SyncCluster()
go Monitor(clusterSize, clusterSize, leaderChan, all, stop)
<-all
<-leaderChan
stop <-true
time.Sleep(time.Second)
c.SyncCluster()
// send 10 commands
for i := 0; i < 10; i++ {
@ -44,9 +51,78 @@ func TestMultiNodeKillAllAndRecovery(t *testing.T) {
time.Sleep(time.Second)
stop := make(chan bool)
leaderChan := make(chan string, 1)
all := make(chan bool, 1)
stop = make(chan bool)
leaderChan = make(chan string, 1)
all = make(chan bool, 1)
time.Sleep(time.Second)
for i := 0; i < clusterSize; i++ {
etcds[i], err = os.StartProcess(EtcdBinPath, argGroup[i], procAttr)
}
go Monitor(clusterSize, 1, leaderChan, all, stop)
<-all
<-leaderChan
result, err := c.Set("foo", "bar", 0)
if err != nil {
t.Fatalf("Recovery error: %s", err)
}
if result.Node.ModifiedIndex != 16 {
t.Fatalf("recovery failed! [%d/16]", result.Node.ModifiedIndex)
}
}
// TestTLSMultiNodeKillAllAndRecovery create a five nodes
// then kill all the nodes and restart
func TestTLSMultiNodeKillAllAndRecovery(t *testing.T) {
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
stop := make(chan bool)
leaderChan := make(chan string, 1)
all := make(chan bool, 1)
clusterSize := 5
argGroup, etcds, err := CreateCluster(clusterSize, procAttr, true)
defer DestroyCluster(etcds)
if err != nil {
t.Fatal("cannot create cluster")
}
c := etcd.NewClient(nil)
go Monitor(clusterSize, clusterSize, leaderChan, all, stop)
<-all
<-leaderChan
stop <-true
c.SyncCluster()
// send 10 commands
for i := 0; i < 10; i++ {
// Test Set
_, err := c.Set("foo", "bar", 0)
if err != nil {
panic(err)
}
}
time.Sleep(time.Second)
// kill all
DestroyCluster(etcds)
time.Sleep(time.Second)
stop = make(chan bool)
leaderChan = make(chan string, 1)
all = make(chan bool, 1)
time.Sleep(time.Second)

View File

@ -30,7 +30,7 @@ func ReadBodyJSON(resp *http.Response) map[string]interface{} {
m := make(map[string]interface{})
b := ReadBody(resp)
if err := json.Unmarshal(b, &m); err != nil {
panic(fmt.Sprintf("HTTP body JSON parse error: %v", err))
panic(fmt.Sprintf("HTTP body JSON parse error: %v: %s", err, string(b)))
}
return m
}

View File

@ -15,12 +15,12 @@ import (
)
const (
testName = "ETCDTEST"
testClientURL = "localhost:4401"
testRaftURL = "localhost:7701"
testSnapshotCount = 10000
testHeartbeatTimeout = time.Duration(50) * time.Millisecond
testElectionTimeout = time.Duration(200) * time.Millisecond
testName = "ETCDTEST"
testClientURL = "localhost:4401"
testRaftURL = "localhost:7701"
testSnapshotCount = 10000
testHeartbeatInterval = time.Duration(50) * time.Millisecond
testElectionTimeout = time.Duration(200) * time.Millisecond
)
// Starts a server in a temporary directory.
@ -44,28 +44,22 @@ func RunServer(f func(*server.Server)) {
mb := metrics.NewBucket("")
ps := server.NewPeerServer(psConfig, registry, store, &mb, followersStats, serverStats)
psListener, err := server.NewListener(testRaftURL)
if err != nil {
panic(err)
}
psListener := server.NewListener("http", testRaftURL, nil)
// Create Raft transporter and server
dialTimeout := (3 * testHeartbeatTimeout) + testElectionTimeout
responseHeaderTimeout := (3 * testHeartbeatTimeout) + testElectionTimeout
raftTransporter := server.NewTransporter(followersStats, serverStats, registry, testHeartbeatTimeout, dialTimeout, responseHeaderTimeout)
dialTimeout := (3 * testHeartbeatInterval) + testElectionTimeout
responseHeaderTimeout := (3 * testHeartbeatInterval) + testElectionTimeout
raftTransporter := server.NewTransporter(followersStats, serverStats, registry, testHeartbeatInterval, dialTimeout, responseHeaderTimeout)
raftServer, err := raft.NewServer(testName, path, raftTransporter, store, ps, "")
if err != nil {
panic(err)
}
raftServer.SetElectionTimeout(testElectionTimeout)
raftServer.SetHeartbeatInterval(testHeartbeatTimeout)
raftServer.SetHeartbeatInterval(testHeartbeatInterval)
ps.SetRaftServer(raftServer)
s := server.New(testName, "http://"+testClientURL, ps, registry, store, nil)
sListener, err := server.NewListener(testClientURL)
if err != nil {
panic(err)
}
sListener := server.NewListener("http", testClientURL, nil)
ps.SetServer(s)

View File

@ -0,0 +1,17 @@
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,39 @@
## go-httpclient
**requires Go 1.1+** as of `v0.4.0` the API has been completely re-written for Go 1.1 (for a Go
1.0.x compatible release see [1adef50](https://github.com/mreiferson/go-httpclient/tree/1adef50))
[![Build
Status](https://secure.travis-ci.org/mreiferson/go-httpclient.png?branch=master)](http://travis-ci.org/mreiferson/go-httpclient)
Provides an HTTP Transport that implements the `RoundTripper` interface and
can be used as a built in replacement for the standard library's, providing:
* connection timeouts
* request timeouts
This is a thin wrapper around `http.Transport` that sets dial timeouts and uses
Go's internal timer scheduler to call the Go 1.1+ `CancelRequest()` API.
### Example
```go
transport := &httpclient.Transport{
ConnectTimeout: 1*time.Second,
RequestTimeout: 10*time.Second,
ResponseHeaderTimeout: 5*time.Second,
}
defer transport.Close()
client := &http.Client{Transport: transport}
req, _ := http.NewRequest("GET", "http://127.0.0.1/test", nil)
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
```
### Reference Docs
For API docs see [godoc](http://godoc.org/github.com/mreiferson/go-httpclient).

View File

@ -0,0 +1,210 @@
/*
Provides an HTTP Transport that implements the `RoundTripper` interface and
can be used as a built in replacement for the standard library's, providing:
* connection timeouts
* request timeouts
This is a thin wrapper around `http.Transport` that sets dial timeouts and uses
Go's internal timer scheduler to call the Go 1.1+ `CancelRequest()` API.
*/
package httpclient
import (
"crypto/tls"
"io"
"net"
"net/http"
"net/url"
"sync"
"time"
)
// returns the current version of the package
func Version() string {
return "0.4.1"
}
// Transport implements the RoundTripper interface and can be used as a replacement
// for Go's built in http.Transport implementing end-to-end request timeouts.
//
// transport := &httpclient.Transport{
// ConnectTimeout: 1*time.Second,
// ResponseHeaderTimeout: 5*time.Second,
// RequestTimeout: 10*time.Second,
// }
// defer transport.Close()
//
// client := &http.Client{Transport: transport}
// req, _ := http.NewRequest("GET", "http://127.0.0.1/test", nil)
// resp, err := client.Do(req)
// if err != nil {
// return err
// }
// defer resp.Body.Close()
//
type Transport struct {
// Proxy specifies a function to return a proxy for a given
// *http.Request. If the function returns a non-nil error, the
// request is aborted with the provided error.
// If Proxy is nil or returns a nil *url.URL, no proxy is used.
Proxy func(*http.Request) (*url.URL, error)
// Dial specifies the dial function for creating TCP
// connections. This will override the Transport's ConnectTimeout and
// ReadWriteTimeout settings.
// If Dial is nil, a dialer is generated on demand matching the Transport's
// options.
Dial func(network, addr string) (net.Conn, error)
// TLSClientConfig specifies the TLS configuration to use with
// tls.Client. If nil, the default configuration is used.
TLSClientConfig *tls.Config
// DisableKeepAlives, if true, prevents re-use of TCP connections
// between different HTTP requests.
DisableKeepAlives bool
// DisableCompression, if true, prevents the Transport from
// requesting compression with an "Accept-Encoding: gzip"
// request header when the Request contains no existing
// Accept-Encoding value. If the Transport requests gzip on
// its own and gets a gzipped response, it's transparently
// decoded in the Response.Body. However, if the user
// explicitly requested gzip it is not automatically
// uncompressed.
DisableCompression bool
// MaxIdleConnsPerHost, if non-zero, controls the maximum idle
// (keep-alive) to keep per-host. If zero,
// http.DefaultMaxIdleConnsPerHost is used.
MaxIdleConnsPerHost int
// ConnectTimeout, if non-zero, is the maximum amount of time a dial will wait for
// a connect to complete.
ConnectTimeout time.Duration
// ResponseHeaderTimeout, if non-zero, specifies the amount of
// time to wait for a server's response headers after fully
// writing the request (including its body, if any). This
// time does not include the time to read the response body.
ResponseHeaderTimeout time.Duration
// RequestTimeout, if non-zero, specifies the amount of time for the entire
// request to complete (including all of the above timeouts + entire response body).
// This should never be less than the sum total of the above two timeouts.
RequestTimeout time.Duration
// ReadWriteTimeout, if non-zero, will set a deadline for every Read and
// Write operation on the request connection.
ReadWriteTimeout time.Duration
starter sync.Once
transport *http.Transport
}
// Close cleans up the Transport, currently a no-op
func (t *Transport) Close() error {
return nil
}
func (t *Transport) lazyStart() {
if t.Dial == nil {
t.Dial = func(netw, addr string) (net.Conn, error) {
c, err := net.DialTimeout(netw, addr, t.ConnectTimeout)
if err != nil {
return nil, err
}
if t.ReadWriteTimeout > 0 {
timeoutConn := &rwTimeoutConn{
TCPConn: c.(*net.TCPConn),
rwTimeout: t.ReadWriteTimeout,
}
return timeoutConn, nil
}
return c, nil
}
}
t.transport = &http.Transport{
Dial: t.Dial,
Proxy: t.Proxy,
TLSClientConfig: t.TLSClientConfig,
DisableKeepAlives: t.DisableKeepAlives,
DisableCompression: t.DisableCompression,
MaxIdleConnsPerHost: t.MaxIdleConnsPerHost,
ResponseHeaderTimeout: t.ResponseHeaderTimeout,
}
}
func (t *Transport) CancelRequest(req *http.Request) {
t.starter.Do(t.lazyStart)
t.transport.CancelRequest(req)
}
func (t *Transport) CloseIdleConnections() {
t.starter.Do(t.lazyStart)
t.transport.CloseIdleConnections()
}
func (t *Transport) RegisterProtocol(scheme string, rt http.RoundTripper) {
t.starter.Do(t.lazyStart)
t.transport.RegisterProtocol(scheme, rt)
}
func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
t.starter.Do(t.lazyStart)
if t.RequestTimeout > 0 {
timer := time.AfterFunc(t.RequestTimeout, func() {
t.transport.CancelRequest(req)
})
resp, err = t.transport.RoundTrip(req)
if err != nil {
timer.Stop()
} else {
resp.Body = &bodyCloseInterceptor{ReadCloser: resp.Body, timer: timer}
}
} else {
resp, err = t.transport.RoundTrip(req)
}
return
}
type bodyCloseInterceptor struct {
io.ReadCloser
timer *time.Timer
}
func (bci *bodyCloseInterceptor) Close() error {
bci.timer.Stop()
return bci.ReadCloser.Close()
}
// A net.Conn that sets a deadline for every Read or Write operation
type rwTimeoutConn struct {
*net.TCPConn
rwTimeout time.Duration
}
func (c *rwTimeoutConn) Read(b []byte) (int, error) {
err := c.TCPConn.SetReadDeadline(time.Now().Add(c.rwTimeout))
if err != nil {
return 0, err
}
return c.TCPConn.Read(b)
}
func (c *rwTimeoutConn) Write(b []byte) (int, error) {
err := c.TCPConn.SetWriteDeadline(time.Now().Add(c.rwTimeout))
if err != nil {
return 0, err
}
return c.TCPConn.Write(b)
}

View File

@ -0,0 +1,233 @@
package httpclient
import (
"crypto/tls"
"io"
"io/ioutil"
"net"
"net/http"
"sync"
"testing"
"time"
)
var starter sync.Once
var addr net.Addr
func testHandler(w http.ResponseWriter, req *http.Request) {
time.Sleep(200 * time.Millisecond)
io.WriteString(w, "hello, world!\n")
}
func postHandler(w http.ResponseWriter, req *http.Request) {
ioutil.ReadAll(req.Body)
w.Header().Set("Content-Length", "2")
io.WriteString(w, "OK")
}
func closeHandler(w http.ResponseWriter, req *http.Request) {
hj, _ := w.(http.Hijacker)
conn, bufrw, _ := hj.Hijack()
defer conn.Close()
bufrw.WriteString("HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n")
bufrw.Flush()
}
func redirectHandler(w http.ResponseWriter, req *http.Request) {
ioutil.ReadAll(req.Body)
http.Redirect(w, req, "/post", 302)
}
func redirect2Handler(w http.ResponseWriter, req *http.Request) {
ioutil.ReadAll(req.Body)
http.Redirect(w, req, "/redirect", 302)
}
func slowHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
io.WriteString(w, "START\n")
f := w.(http.Flusher)
f.Flush()
time.Sleep(200 * time.Millisecond)
io.WriteString(w, "WORKING\n")
f.Flush()
time.Sleep(200 * time.Millisecond)
io.WriteString(w, "DONE\n")
return
}
func setupMockServer(t *testing.T) {
http.HandleFunc("/test", testHandler)
http.HandleFunc("/post", postHandler)
http.HandleFunc("/redirect", redirectHandler)
http.HandleFunc("/redirect2", redirect2Handler)
http.HandleFunc("/close", closeHandler)
http.HandleFunc("/slow", slowHandler)
ln, err := net.Listen("tcp", ":0")
if err != nil {
t.Fatalf("failed to listen - %s", err.Error())
}
go func() {
err = http.Serve(ln, nil)
if err != nil {
t.Fatalf("failed to start HTTP server - %s", err.Error())
}
}()
addr = ln.Addr()
}
func TestHttpsConnection(t *testing.T) {
transport := &Transport{
ConnectTimeout: 1 * time.Second,
RequestTimeout: 2 * time.Second,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
defer transport.Close()
client := &http.Client{Transport: transport}
req, _ := http.NewRequest("GET", "https://httpbin.org/ip", nil)
resp, err := client.Do(req)
if err != nil {
t.Fatalf("1st request failed - %s", err.Error())
}
_, err = ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatalf("1st failed to read body - %s", err.Error())
}
resp.Body.Close()
req2, _ := http.NewRequest("GET", "https://httpbin.org/delay/5", nil)
_, err = client.Do(req2)
if err == nil {
t.Fatalf("HTTPS request should have timed out")
}
}
func TestHttpClient(t *testing.T) {
starter.Do(func() { setupMockServer(t) })
transport := &Transport{
ConnectTimeout: 1 * time.Second,
RequestTimeout: 5 * time.Second,
ReadWriteTimeout: 3 * time.Second,
}
client := &http.Client{Transport: transport}
req, _ := http.NewRequest("GET", "http://"+addr.String()+"/test", nil)
resp, err := client.Do(req)
if err != nil {
t.Fatalf("1st request failed - %s", err.Error())
}
_, err = ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatalf("1st failed to read body - %s", err.Error())
}
resp.Body.Close()
transport.Close()
transport = &Transport{
ConnectTimeout: 25 * time.Millisecond,
RequestTimeout: 50 * time.Millisecond,
ReadWriteTimeout: 50 * time.Millisecond,
}
client = &http.Client{Transport: transport}
req2, _ := http.NewRequest("GET", "http://"+addr.String()+"/test", nil)
resp, err = client.Do(req2)
if err == nil {
t.Fatal("2nd request should have timed out")
}
transport.Close()
transport = &Transport{
ConnectTimeout: 25 * time.Millisecond,
RequestTimeout: 250 * time.Millisecond,
ReadWriteTimeout: 250 * time.Millisecond,
}
client = &http.Client{Transport: transport}
req3, _ := http.NewRequest("GET", "http://"+addr.String()+"/test", nil)
resp, err = client.Do(req3)
if err != nil {
t.Fatal("3rd request should not have timed out")
}
resp.Body.Close()
transport.Close()
}
func TestSlowServer(t *testing.T) {
starter.Do(func() { setupMockServer(t) })
transport := &Transport{
ConnectTimeout: 25 * time.Millisecond,
RequestTimeout: 500 * time.Millisecond,
ReadWriteTimeout: 250 * time.Millisecond,
}
client := &http.Client{Transport: transport}
req, _ := http.NewRequest("GET", "http://"+addr.String()+"/slow", nil)
resp, err := client.Do(req)
if err != nil {
t.Fatalf("1st request failed - %s", err)
}
_, err = ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatalf("1st failed to read body - %s", err)
}
resp.Body.Close()
transport.Close()
transport = &Transport{
ConnectTimeout: 25 * time.Millisecond,
RequestTimeout: 500 * time.Millisecond,
ReadWriteTimeout: 100 * time.Millisecond,
}
client = &http.Client{Transport: transport}
req, _ = http.NewRequest("GET", "http://"+addr.String()+"/slow", nil)
resp, err = client.Do(req)
if err != nil {
t.Fatalf("2nd request failed - %s", err)
}
_, err = ioutil.ReadAll(resp.Body)
netErr, ok := err.(net.Error)
if !ok {
t.Fatalf("2nd request dind't return a net.Error - %s", netErr)
}
if !netErr.Timeout() {
t.Fatalf("2nd request should have timed out - %s", netErr)
}
resp.Body.Close()
transport.Close()
}
func TestMultipleRequests(t *testing.T) {
starter.Do(func() { setupMockServer(t) })
transport := &Transport{
ConnectTimeout: 1 * time.Second,
RequestTimeout: 5 * time.Second,
ReadWriteTimeout: 3 * time.Second,
ResponseHeaderTimeout: 400 * time.Millisecond,
}
client := &http.Client{Transport: transport}
req, _ := http.NewRequest("GET", "http://"+addr.String()+"/test", nil)
for i := 0; i < 10; i++ {
resp, err := client.Do(req)
if err != nil {
t.Fatalf("%d request failed - %s", i, err.Error())
}
_, err = ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatalf("%d failed to read body - %s", i, err.Error())
}
resp.Body.Close()
}
transport.Close()
}