Browse Source

Update godeps

Ask Bjørn Hansen 10 years ago
parent
commit
98a4a773c5

+ 4 - 4
Godeps/Godeps.json

@@ -12,7 +12,7 @@
 		},
 		},
 		{
 		{
 			"ImportPath": "github.com/abh/geoip",
 			"ImportPath": "github.com/abh/geoip",
-			"Rev": "917745c7ac5c2f92c815ed169cc1680474700951"
+			"Rev": "e5f8ea00f476d60a1e539d74211ce24881347d9e"
 		},
 		},
 		{
 		{
 			"ImportPath": "github.com/miekg/dns",
 			"ImportPath": "github.com/miekg/dns",
@@ -20,7 +20,7 @@
 		},
 		},
 		{
 		{
 			"ImportPath": "github.com/rcrowley/go-metrics",
 			"ImportPath": "github.com/rcrowley/go-metrics",
-			"Rev": "a5cfc242a56ba7fa70b785f678d6214837bf93b9"
+			"Rev": "3e5e593311103d49927c8d2b0fd93ccdfe4a525c"
 		},
 		},
 		{
 		{
 			"ImportPath": "github.com/stathat/go",
 			"ImportPath": "github.com/stathat/go",
@@ -28,11 +28,11 @@
 		},
 		},
 		{
 		{
 			"ImportPath": "golang.org/x/net/websocket",
 			"ImportPath": "golang.org/x/net/websocket",
-			"Rev": "e562cdb856bcf26549c3d024ec9c8a3d9493fe91"
+			"Rev": "1bc0720082d79ce7ffc6ef6e523d00d46b0dee45"
 		},
 		},
 		{
 		{
 			"ImportPath": "gopkg.in/check.v1",
 			"ImportPath": "gopkg.in/check.v1",
-			"Rev": "64131543e7896d5bcc6bd5a76287eb75ea96c673"
+			"Rev": "11d3bc7aa68e238947792f30573146a3231fc0f1"
 		},
 		},
 		{
 		{
 			"ImportPath": "gopkg.in/fsnotify.v1",
 			"ImportPath": "gopkg.in/fsnotify.v1",

+ 1 - 2
Godeps/_workspace/src/github.com/abh/geoip/geoip.go

@@ -2,8 +2,7 @@
 package geoip
 package geoip
 
 
 /*
 /*
-#cgo CFLAGS: -I/opt/local/include -I/usr/local/include -I/usr/include
-#cgo LDFLAGS: -lGeoIP -L/opt/local/lib -L/usr/local/lib -L/usr/lib
+#cgo pkg-config: geoip  
 #include <stdio.h>
 #include <stdio.h>
 #include <errno.h>
 #include <errno.h>
 #include <GeoIP.h>
 #include <GeoIP.h>

+ 27 - 6
Godeps/_workspace/src/github.com/rcrowley/go-metrics/README.md

@@ -1,7 +1,9 @@
 go-metrics
 go-metrics
 ==========
 ==========
 
 
-Go port of Coda Hale's Metrics library: <https://github.com/codahale/metrics>.
+![travis build status](https://travis-ci.org/rcrowley/go-metrics.svg?branch=master)
+
+Go port of Coda Hale's Metrics library: <https://github.com/dropwizard/metrics>.
 
 
 Documentation: <http://godoc.org/github.com/rcrowley/go-metrics>.
 Documentation: <http://godoc.org/github.com/rcrowley/go-metrics>.
 
 
@@ -47,15 +49,23 @@ w, _ := syslog.Dial("unixgram", "/dev/log", syslog.LOG_INFO, "metrics")
 go metrics.Syslog(metrics.DefaultRegistry, 60e9, w)
 go metrics.Syslog(metrics.DefaultRegistry, 60e9, w)
 ```
 ```
 
 
-Periodically emit every metric to Graphite:
+Periodically emit every metric to Graphite using the [Graphite client](https://github.com/cyberdelia/go-metrics-graphite):
 
 
 ```go
 ```go
+
+import "github.com/cyberdelia/go-metrics-graphite"
+
 addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:2003")
 addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:2003")
-go metrics.Graphite(metrics.DefaultRegistry, 10e9, "metrics", addr)
+go graphite.Graphite(metrics.DefaultRegistry, 10e9, "metrics", addr)
 ```
 ```
 
 
 Periodically emit every metric into InfluxDB:
 Periodically emit every metric into InfluxDB:
 
 
+**NOTE:** this has been pulled out of the library due to constant fluctuations
+in the InfluxDB API. In fact, all client libraries are on their way out. see
+issues [#121](https://github.com/rcrowley/go-metrics/issues/121) and
+[#124](https://github.com/rcrowley/go-metrics/issues/124) for progress and details.
+
 ```go
 ```go
 import "github.com/rcrowley/go-metrics/influxdb"
 import "github.com/rcrowley/go-metrics/influxdb"
 
 
@@ -67,17 +77,20 @@ go influxdb.Influxdb(metrics.DefaultRegistry, 10e9, &influxdb.Config{
 })
 })
 ```
 ```
 
 
-Periodically upload every metric to Librato:
+Periodically upload every metric to Librato using the [Librato client](https://github.com/mihasya/go-metrics-librato):
+
+**Note**: the client included with this repository under the `librato` package
+has been deprecated and moved to the repository linked above.
 
 
 ```go
 ```go
-import "github.com/rcrowley/go-metrics/librato"
+import "github.com/mihasya/go-metrics-librato"
 
 
 go librato.Librato(metrics.DefaultRegistry,
 go librato.Librato(metrics.DefaultRegistry,
     10e9,                  // interval
     10e9,                  // interval
     "[email protected]", // account owner email address
     "[email protected]", // account owner email address
     "token",               // Librato API token
     "token",               // Librato API token
     "hostname",            // source
     "hostname",            // source
-    []float64{0.95},       // precentiles to send
+    []float64{0.95},       // percentiles to send
     time.Millisecond,      // time unit
     time.Millisecond,      // time unit
 )
 )
 ```
 ```
@@ -102,3 +115,11 @@ StatHat support additionally requires their Go client:
 ```sh
 ```sh
 go get github.com/stathat/go
 go get github.com/stathat/go
 ```
 ```
+
+Publishing Metrics
+------------------
+
+Clients are available for the following destinations:
+
+* Librato - [https://github.com/mihasya/go-metrics-librato](https://github.com/mihasya/go-metrics-librato)
+* Graphite - [https://github.com/cyberdelia/go-metrics-graphite](https://github.com/cyberdelia/go-metrics-graphite)

+ 1 - 1
Godeps/_workspace/src/github.com/rcrowley/go-metrics/ewma.go

@@ -77,7 +77,7 @@ func (NilEWMA) Update(n int64) {}
 // of uncounted events and processes them on each tick.  It uses the
 // of uncounted events and processes them on each tick.  It uses the
 // sync/atomic package to manage uncounted events.
 // sync/atomic package to manage uncounted events.
 type StandardEWMA struct {
 type StandardEWMA struct {
-	uncounted int64		// /!\ this should be the first member to ensure 64-bit alignment
+	uncounted int64 // /!\ this should be the first member to ensure 64-bit alignment
 	alpha     float64
 	alpha     float64
 	rate      float64
 	rate      float64
 	init      bool
 	init      bool

+ 2 - 0
Godeps/_workspace/src/github.com/rcrowley/go-metrics/graphite.go

@@ -38,6 +38,7 @@ func Graphite(r Registry, d time.Duration, prefix string, addr *net.TCPAddr) {
 // GraphiteWithConfig is a blocking exporter function just like Graphite,
 // GraphiteWithConfig is a blocking exporter function just like Graphite,
 // but it takes a GraphiteConfig instead.
 // but it takes a GraphiteConfig instead.
 func GraphiteWithConfig(c GraphiteConfig) {
 func GraphiteWithConfig(c GraphiteConfig) {
+	log.Printf("WARNING: This go-metrics client has been DEPRECATED! It has been moved to https://github.com/cyberdelia/go-metrics-graphite and will be removed from rcrowley/go-metrics on August 12th 2015")
 	for _ = range time.Tick(c.FlushInterval) {
 	for _ = range time.Tick(c.FlushInterval) {
 		if err := graphite(&c); nil != err {
 		if err := graphite(&c); nil != err {
 			log.Println(err)
 			log.Println(err)
@@ -49,6 +50,7 @@ func GraphiteWithConfig(c GraphiteConfig) {
 // non-nil error on failed connections. This can be used in a loop
 // non-nil error on failed connections. This can be used in a loop
 // similar to GraphiteWithConfig for custom error handling.
 // similar to GraphiteWithConfig for custom error handling.
 func GraphiteOnce(c GraphiteConfig) error {
 func GraphiteOnce(c GraphiteConfig) error {
+	log.Printf("WARNING: This go-metrics client has been DEPRECATED! It has been moved to https://github.com/cyberdelia/go-metrics-graphite and will be removed from rcrowley/go-metrics on August 12th 2015")
 	return graphite(&c)
 	return graphite(&c)
 }
 }
 
 

+ 1 - 1
Godeps/_workspace/src/github.com/rcrowley/go-metrics/graphite_test.go

@@ -17,6 +17,6 @@ func ExampleGraphiteWithConfig() {
 		Registry:      DefaultRegistry,
 		Registry:      DefaultRegistry,
 		FlushInterval: 1 * time.Second,
 		FlushInterval: 1 * time.Second,
 		DurationUnit:  time.Millisecond,
 		DurationUnit:  time.Millisecond,
-		Percentiles: []float64{ 0.5, 0.75, 0.99, 0.999 },
+		Percentiles:   []float64{0.5, 0.75, 0.99, 0.999},
 	})
 	})
 }
 }

+ 0 - 114
Godeps/_workspace/src/github.com/rcrowley/go-metrics/influxdb/influxdb.go

@@ -1,114 +0,0 @@
-package influxdb
-
-import (
-	"fmt"
-	"github.com/abh/geodns/Godeps/_workspace/src/github.com/rcrowley/go-metrics"
-	influxClient "github.com/influxdb/influxdb/client"
-	"log"
-	"time"
-)
-
-type Config struct {
-	Host     string
-	Database string
-	Username string
-	Password string
-}
-
-func Influxdb(r metrics.Registry, d time.Duration, config *Config) {
-	client, err := influxClient.NewClient(&influxClient.ClientConfig{
-		Host:     config.Host,
-		Database: config.Database,
-		Username: config.Username,
-		Password: config.Password,
-	})
-	if err != nil {
-		log.Println(err)
-		return
-	}
-
-	for _ = range time.Tick(d) {
-		if err := send(r, client); err != nil {
-			log.Println(err)
-		}
-	}
-}
-
-func send(r metrics.Registry, client *influxClient.Client) error {
-	series := []*influxClient.Series{}
-
-	r.Each(func(name string, i interface{}) {
-		now := getCurrentTime()
-		switch metric := i.(type) {
-		case metrics.Counter:
-			series = append(series, &influxClient.Series{
-				Name:    fmt.Sprintf("%s.count", name),
-				Columns: []string{"time", "count"},
-				Points: [][]interface{}{
-					{now, metric.Count()},
-				},
-			})
-		case metrics.Gauge:
-			series = append(series, &influxClient.Series{
-				Name:    fmt.Sprintf("%s.value", name),
-				Columns: []string{"time", "value"},
-				Points: [][]interface{}{
-					{now, metric.Value()},
-				},
-			})
-		case metrics.GaugeFloat64:
-			series = append(series, &influxClient.Series{
-				Name:    fmt.Sprintf("%s.value", name),
-				Columns: []string{"time", "value"},
-				Points: [][]interface{}{
-					{now, metric.Value()},
-				},
-			})
-		case metrics.Histogram:
-			h := metric.Snapshot()
-			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
-			series = append(series, &influxClient.Series{
-				Name: fmt.Sprintf("%s.histogram", name),
-				Columns: []string{"time", "count", "min", "max", "mean", "std-dev",
-					"50-percentile", "75-percentile", "95-percentile",
-					"99-percentile", "999-percentile"},
-				Points: [][]interface{}{
-					{now, h.Count(), h.Min(), h.Max(), h.Mean(), h.StdDev(),
-						ps[0], ps[1], ps[2], ps[3], ps[4]},
-				},
-			})
-		case metrics.Meter:
-			m := metric.Snapshot()
-			series = append(series, &influxClient.Series{
-				Name: fmt.Sprintf("%s.meter", name),
-				Columns: []string{"count", "one-minute",
-					"five-minute", "fifteen-minute", "mean"},
-				Points: [][]interface{}{
-					{m.Count(), m.Rate1(), m.Rate5(), m.Rate15(), m.RateMean()},
-				},
-			})
-		case metrics.Timer:
-			h := metric.Snapshot()
-			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
-			series = append(series, &influxClient.Series{
-				Name: fmt.Sprintf("%s.timer", name),
-				Columns: []string{"count", "min", "max", "mean", "std-dev",
-					"50-percentile", "75-percentile", "95-percentile",
-					"99-percentile", "999-percentile", "one-minute", "five-minute", "fifteen-minute", "mean-rate"},
-				Points: [][]interface{}{
-					{h.Count(), h.Min(), h.Max(), h.Mean(), h.StdDev(),
-						ps[0], ps[1], ps[2], ps[3], ps[4],
-						h.Rate1(), h.Rate5(), h.Rate15(), h.RateMean()},
-				},
-			})
-		}
-	})
-	if err := client.WriteSeries(series); err != nil {
-		log.Println(err)
-	}
-	return nil
-}
-
-func getCurrentTime() int64 {
-	return time.Now().UnixNano() / 1000000
-}

+ 1 - 1
Godeps/_workspace/src/github.com/rcrowley/go-metrics/json.go

@@ -8,7 +8,7 @@ import (
 
 
 // MarshalJSON returns a byte slice containing a JSON representation of all
 // MarshalJSON returns a byte slice containing a JSON representation of all
 // the metrics in the Registry.
 // the metrics in the Registry.
-func (r StandardRegistry) MarshalJSON() ([]byte, error) {
+func (r *StandardRegistry) MarshalJSON() ([]byte, error) {
 	data := make(map[string]map[string]interface{})
 	data := make(map[string]map[string]interface{})
 	r.Each(func(name string, i interface{}) {
 	r.Each(func(name string, i interface{}) {
 		values := make(map[string]interface{})
 		values := make(map[string]interface{})

+ 1 - 0
Godeps/_workspace/src/github.com/rcrowley/go-metrics/librato/librato.go

@@ -40,6 +40,7 @@ func Librato(r metrics.Registry, d time.Duration, e string, t string, s string,
 }
 }
 
 
 func (self *Reporter) Run() {
 func (self *Reporter) Run() {
+	log.Printf("WARNING: This client has been DEPRECATED! It has been moved to https://github.com/mihasya/go-metrics-librato and will be removed from rcrowley/go-metrics on August 5th 2015")
 	ticker := time.Tick(self.Interval)
 	ticker := time.Tick(self.Interval)
 	metricsApi := &LibratoClient{self.Email, self.Token}
 	metricsApi := &LibratoClient{self.Email, self.Token}
 	for now := range ticker {
 	for now := range ticker {

+ 0 - 1
Godeps/_workspace/src/github.com/rcrowley/go-metrics/opentsdb_test.go

@@ -19,4 +19,3 @@ func ExampleOpenTSDBWithConfig() {
 		DurationUnit:  time.Millisecond,
 		DurationUnit:  time.Millisecond,
 	})
 	})
 }
 }
-

+ 60 - 0
Godeps/_workspace/src/github.com/rcrowley/go-metrics/registry.go

@@ -145,6 +145,58 @@ func (r *StandardRegistry) registered() map[string]interface{} {
 	return metrics
 	return metrics
 }
 }
 
 
+type PrefixedRegistry struct {
+	underlying Registry
+	prefix     string
+}
+
+func NewPrefixedRegistry(prefix string) Registry {
+	return &PrefixedRegistry{
+		underlying: NewRegistry(),
+		prefix:     prefix,
+	}
+}
+
+// Call the given function for each registered metric.
+func (r *PrefixedRegistry) Each(fn func(string, interface{})) {
+	r.underlying.Each(fn)
+}
+
+// Get the metric by the given name or nil if none is registered.
+func (r *PrefixedRegistry) Get(name string) interface{} {
+	return r.underlying.Get(name)
+}
+
+// Gets an existing metric or registers the given one.
+// The interface can be the metric to register if not found in registry,
+// or a function returning the metric for lazy instantiation.
+func (r *PrefixedRegistry) GetOrRegister(name string, metric interface{}) interface{} {
+	realName := r.prefix + name
+	return r.underlying.GetOrRegister(realName, metric)
+}
+
+// Register the given metric under the given name. The name will be prefixed.
+func (r *PrefixedRegistry) Register(name string, metric interface{}) error {
+	realName := r.prefix + name
+	return r.underlying.Register(realName, metric)
+}
+
+// Run all registered healthchecks.
+func (r *PrefixedRegistry) RunHealthchecks() {
+	r.underlying.RunHealthchecks()
+}
+
+// Unregister the metric with the given name. The name will be prefixed.
+func (r *PrefixedRegistry) Unregister(name string) {
+	realName := r.prefix + name
+	r.underlying.Unregister(realName)
+}
+
+// Unregister all metrics.  (Mostly for testing.)
+func (r *PrefixedRegistry) UnregisterAll() {
+	r.underlying.UnregisterAll()
+}
+
 var DefaultRegistry Registry = NewRegistry()
 var DefaultRegistry Registry = NewRegistry()
 
 
 // Call the given function for each registered metric.
 // Call the given function for each registered metric.
@@ -169,6 +221,14 @@ func Register(name string, i interface{}) error {
 	return DefaultRegistry.Register(name, i)
 	return DefaultRegistry.Register(name, i)
 }
 }
 
 
+// Register the given metric under the given name.  Panics if a metric by the
+// given name is already registered.
+func MustRegister(name string, i interface{}) {
+	if err := Register(name, i); err != nil {
+		panic(err)
+	}
+}
+
 // Run all registered healthchecks.
 // Run all registered healthchecks.
 func RunHealthchecks() {
 func RunHealthchecks() {
 	DefaultRegistry.RunHealthchecks()
 	DefaultRegistry.RunHealthchecks()

+ 47 - 0
Godeps/_workspace/src/github.com/rcrowley/go-metrics/registry_test.go

@@ -116,3 +116,50 @@ func TestRegistryGetOrRegisterWithLazyInstantiation(t *testing.T) {
 		t.Fatal(i)
 		t.Fatal(i)
 	}
 	}
 }
 }
+
+func TestPrefixedRegistryGetOrRegister(t *testing.T) {
+	r := NewPrefixedRegistry("prefix.")
+
+	_ = r.GetOrRegister("foo", NewCounter)
+
+	r.Each(func(name string, m interface{}) {
+		if name != "prefix.foo" {
+			t.Fatal(name)
+		}
+	})
+}
+
+func TestPrefixedRegistryRegister(t *testing.T) {
+	r := NewPrefixedRegistry("prefix.")
+
+	_ = r.Register("foo", NewCounter)
+
+	r.Each(func(name string, m interface{}) {
+		if name != "prefix.foo" {
+			t.Fatal(name)
+		}
+	})
+}
+
+func TestPrefixedRegistryUnregister(t *testing.T) {
+	r := NewPrefixedRegistry("prefix.")
+
+	_ = r.Register("foo", NewCounter)
+
+	r.Each(func(name string, m interface{}) {
+		if name != "prefix.foo" {
+			t.Fatal(name)
+		}
+	})
+
+	r.Unregister("foo")
+
+	i := 0
+	r.Each(func(name string, m interface{}) {
+		i++
+	})
+
+	if i != 0 {
+		t.Fatal(i)
+	}
+}

+ 15 - 13
Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go

@@ -157,6 +157,9 @@ func (buf hybiFrameReaderFactory) NewFrameReader() (frame frameReader, err error
 		if err != nil {
 		if err != nil {
 			return
 			return
 		}
 		}
+		if lengthFields == 8 && i == 0 { // MSB must be zero when 7+64 bits
+			b &= 0x7f
+		}
 		header = append(header, b)
 		header = append(header, b)
 		hybiFrame.header.Length = hybiFrame.header.Length*256 + int64(b)
 		hybiFrame.header.Length = hybiFrame.header.Length*256 + int64(b)
 	}
 	}
@@ -264,7 +267,7 @@ type hybiFrameHandler struct {
 	payloadType byte
 	payloadType byte
 }
 }
 
 
-func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (r frameReader, err error) {
+func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (frameReader, error) {
 	if handler.conn.IsServerConn() {
 	if handler.conn.IsServerConn() {
 		// The client MUST mask all frames sent to the server.
 		// The client MUST mask all frames sent to the server.
 		if frame.(*hybiFrameReader).header.MaskingKey == nil {
 		if frame.(*hybiFrameReader).header.MaskingKey == nil {
@@ -288,20 +291,19 @@ func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (r frameReader,
 		handler.payloadType = frame.PayloadType()
 		handler.payloadType = frame.PayloadType()
 	case CloseFrame:
 	case CloseFrame:
 		return nil, io.EOF
 		return nil, io.EOF
-	case PingFrame:
-		pingMsg := make([]byte, maxControlFramePayloadLength)
-		n, err := io.ReadFull(frame, pingMsg)
-		if err != nil && err != io.ErrUnexpectedEOF {
+	case PingFrame, PongFrame:
+		b := make([]byte, maxControlFramePayloadLength)
+		n, err := io.ReadFull(frame, b)
+		if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
 			return nil, err
 			return nil, err
 		}
 		}
 		io.Copy(ioutil.Discard, frame)
 		io.Copy(ioutil.Discard, frame)
-		n, err = handler.WritePong(pingMsg[:n])
-		if err != nil {
-			return nil, err
+		if frame.PayloadType() == PingFrame {
+			if _, err := handler.WritePong(b[:n]); err != nil {
+				return nil, err
+			}
 		}
 		}
 		return nil, nil
 		return nil, nil
-	case PongFrame:
-		return nil, ErrNotImplemented
 	}
 	}
 	return frame, nil
 	return frame, nil
 }
 }
@@ -515,15 +517,15 @@ func (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Reques
 	return http.StatusSwitchingProtocols, nil
 	return http.StatusSwitchingProtocols, nil
 }
 }
 
 
-// Origin parses Origin header in "req".
-// If origin is "null", returns (nil, nil).
+// Origin parses the Origin header in req.
+// If the Origin header is not set, it returns nil and nil.
 func Origin(config *Config, req *http.Request) (*url.URL, error) {
 func Origin(config *Config, req *http.Request) (*url.URL, error) {
 	var origin string
 	var origin string
 	switch config.Version {
 	switch config.Version {
 	case ProtocolVersionHybi13:
 	case ProtocolVersionHybi13:
 		origin = req.Header.Get("Origin")
 		origin = req.Header.Get("Origin")
 	}
 	}
-	if origin == "null" {
+	if origin == "" {
 		return nil, nil
 		return nil, nil
 	}
 	}
 	return url.ParseRequestURI(origin)
 	return url.ParseRequestURI(origin)

+ 9 - 2
Godeps/_workspace/src/golang.org/x/net/websocket/hybi_test.go

@@ -326,7 +326,7 @@ func testHybiFrame(t *testing.T, testHeader, testPayload, testMaskedPayload []by
 	}
 	}
 	payload := make([]byte, len(testPayload))
 	payload := make([]byte, len(testPayload))
 	_, err = r.Read(payload)
 	_, err = r.Read(payload)
-	if err != nil {
+	if err != nil && err != io.EOF {
 		t.Errorf("read %v", err)
 		t.Errorf("read %v", err)
 	}
 	}
 	if !bytes.Equal(testPayload, payload) {
 	if !bytes.Equal(testPayload, payload) {
@@ -363,13 +363,20 @@ func TestHybiShortBinaryFrame(t *testing.T) {
 }
 }
 
 
 func TestHybiControlFrame(t *testing.T) {
 func TestHybiControlFrame(t *testing.T) {
-	frameHeader := &hybiFrameHeader{Fin: true, OpCode: PingFrame}
 	payload := []byte("hello")
 	payload := []byte("hello")
+
+	frameHeader := &hybiFrameHeader{Fin: true, OpCode: PingFrame}
 	testHybiFrame(t, []byte{0x89, 0x05}, payload, payload, frameHeader)
 	testHybiFrame(t, []byte{0x89, 0x05}, payload, payload, frameHeader)
 
 
+	frameHeader = &hybiFrameHeader{Fin: true, OpCode: PingFrame}
+	testHybiFrame(t, []byte{0x89, 0x00}, nil, nil, frameHeader)
+
 	frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame}
 	frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame}
 	testHybiFrame(t, []byte{0x8A, 0x05}, payload, payload, frameHeader)
 	testHybiFrame(t, []byte{0x8A, 0x05}, payload, payload, frameHeader)
 
 
+	frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame}
+	testHybiFrame(t, []byte{0x8A, 0x00}, nil, nil, frameHeader)
+
 	frameHeader = &hybiFrameHeader{Fin: true, OpCode: CloseFrame}
 	frameHeader = &hybiFrameHeader{Fin: true, OpCode: CloseFrame}
 	payload = []byte{0x03, 0xe8} // 1000
 	payload = []byte{0x03, 0xe8} // 1000
 	testHybiFrame(t, []byte{0x88, 0x02}, payload, payload, frameHeader)
 	testHybiFrame(t, []byte{0x88, 0x02}, payload, payload, frameHeader)

+ 0 - 1
Godeps/_workspace/src/golang.org/x/net/websocket/server.go

@@ -74,7 +74,6 @@ func (s Server) serveWebSocket(w http.ResponseWriter, req *http.Request) {
 	rwc, buf, err := w.(http.Hijacker).Hijack()
 	rwc, buf, err := w.(http.Hijacker).Hijack()
 	if err != nil {
 	if err != nil {
 		panic("Hijack failed: " + err.Error())
 		panic("Hijack failed: " + err.Error())
-		return
 	}
 	}
 	// The server should abort the WebSocket connection if it finds
 	// The server should abort the WebSocket connection if it finds
 	// the client did not send a handshake that matches with protocol
 	// the client did not send a handshake that matches with protocol

+ 136 - 1
Godeps/_workspace/src/golang.org/x/net/websocket/websocket_test.go

@@ -13,6 +13,8 @@ import (
 	"net/http"
 	"net/http"
 	"net/http/httptest"
 	"net/http/httptest"
 	"net/url"
 	"net/url"
+	"reflect"
+	"runtime"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 	"testing"
 	"testing"
@@ -22,7 +24,10 @@ import (
 var serverAddr string
 var serverAddr string
 var once sync.Once
 var once sync.Once
 
 
-func echoServer(ws *Conn) { io.Copy(ws, ws) }
+func echoServer(ws *Conn) {
+	defer ws.Close()
+	io.Copy(ws, ws)
+}
 
 
 type Count struct {
 type Count struct {
 	S string
 	S string
@@ -30,6 +35,7 @@ type Count struct {
 }
 }
 
 
 func countServer(ws *Conn) {
 func countServer(ws *Conn) {
+	defer ws.Close()
 	for {
 	for {
 		var count Count
 		var count Count
 		err := JSON.Receive(ws, &count)
 		err := JSON.Receive(ws, &count)
@@ -45,6 +51,55 @@ func countServer(ws *Conn) {
 	}
 	}
 }
 }
 
 
+type testCtrlAndDataHandler struct {
+	hybiFrameHandler
+}
+
+func (h *testCtrlAndDataHandler) WritePing(b []byte) (int, error) {
+	h.hybiFrameHandler.conn.wio.Lock()
+	defer h.hybiFrameHandler.conn.wio.Unlock()
+	w, err := h.hybiFrameHandler.conn.frameWriterFactory.NewFrameWriter(PingFrame)
+	if err != nil {
+		return 0, err
+	}
+	n, err := w.Write(b)
+	w.Close()
+	return n, err
+}
+
+func ctrlAndDataServer(ws *Conn) {
+	defer ws.Close()
+	h := &testCtrlAndDataHandler{hybiFrameHandler: hybiFrameHandler{conn: ws}}
+	ws.frameHandler = h
+
+	go func() {
+		for i := 0; ; i++ {
+			var b []byte
+			if i%2 != 0 { // with or without payload
+				b = []byte(fmt.Sprintf("#%d-CONTROL-FRAME-FROM-SERVER", i))
+			}
+			if _, err := h.WritePing(b); err != nil {
+				break
+			}
+			if _, err := h.WritePong(b); err != nil { // unsolicited pong
+				break
+			}
+			time.Sleep(10 * time.Millisecond)
+		}
+	}()
+
+	b := make([]byte, 128)
+	for {
+		n, err := ws.Read(b)
+		if err != nil {
+			break
+		}
+		if _, err := ws.Write(b[:n]); err != nil {
+			break
+		}
+	}
+}
+
 func subProtocolHandshake(config *Config, req *http.Request) error {
 func subProtocolHandshake(config *Config, req *http.Request) error {
 	for _, proto := range config.Protocol {
 	for _, proto := range config.Protocol {
 		if proto == "chat" {
 		if proto == "chat" {
@@ -64,6 +119,7 @@ func subProtoServer(ws *Conn) {
 func startServer() {
 func startServer() {
 	http.Handle("/echo", Handler(echoServer))
 	http.Handle("/echo", Handler(echoServer))
 	http.Handle("/count", Handler(countServer))
 	http.Handle("/count", Handler(countServer))
+	http.Handle("/ctrldata", Handler(ctrlAndDataServer))
 	subproto := Server{
 	subproto := Server{
 		Handshake: subProtocolHandshake,
 		Handshake: subProtocolHandshake,
 		Handler:   Handler(subProtoServer),
 		Handler:   Handler(subProtoServer),
@@ -425,6 +481,10 @@ func (c *closerConn) Close() error {
 }
 }
 
 
 func TestClose(t *testing.T) {
 func TestClose(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("see golang.org/issue/11454")
+	}
+
 	once.Do(startServer)
 	once.Do(startServer)
 
 
 	conn, err := net.Dial("tcp", serverAddr)
 	conn, err := net.Dial("tcp", serverAddr)
@@ -450,3 +510,78 @@ func TestClose(t *testing.T) {
 		t.Fatalf("ws.Close(): expected underlying ws.rwc.Close to be called > 0 times, got: %v", cc.closed)
 		t.Fatalf("ws.Close(): expected underlying ws.rwc.Close to be called > 0 times, got: %v", cc.closed)
 	}
 	}
 }
 }
+
+var originTests = []struct {
+	req    *http.Request
+	origin *url.URL
+}{
+	{
+		req: &http.Request{
+			Header: http.Header{
+				"Origin": []string{"http://www.example.com"},
+			},
+		},
+		origin: &url.URL{
+			Scheme: "http",
+			Host:   "www.example.com",
+		},
+	},
+	{
+		req: &http.Request{},
+	},
+}
+
+func TestOrigin(t *testing.T) {
+	conf := newConfig(t, "/echo")
+	conf.Version = ProtocolVersionHybi13
+	for i, tt := range originTests {
+		origin, err := Origin(conf, tt.req)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		if !reflect.DeepEqual(origin, tt.origin) {
+			t.Errorf("#%d: got origin %v; want %v", i, origin, tt.origin)
+			continue
+		}
+	}
+}
+
+func TestCtrlAndData(t *testing.T) {
+	once.Do(startServer)
+
+	c, err := net.Dial("tcp", serverAddr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	ws, err := NewClient(newConfig(t, "/ctrldata"), c)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ws.Close()
+
+	h := &testCtrlAndDataHandler{hybiFrameHandler: hybiFrameHandler{conn: ws}}
+	ws.frameHandler = h
+
+	b := make([]byte, 128)
+	for i := 0; i < 2; i++ {
+		data := []byte(fmt.Sprintf("#%d-DATA-FRAME-FROM-CLIENT", i))
+		if _, err := ws.Write(data); err != nil {
+			t.Fatalf("#%d: %v", i, err)
+		}
+		var ctrl []byte
+		if i%2 != 0 { // with or without payload
+			ctrl = []byte(fmt.Sprintf("#%d-CONTROL-FRAME-FROM-CLIENT", i))
+		}
+		if _, err := h.WritePing(ctrl); err != nil {
+			t.Fatalf("#%d: %v", i, err)
+		}
+		n, err := ws.Read(b)
+		if err != nil {
+			t.Fatalf("#%d: %v", i, err)
+		}
+		if !bytes.Equal(b[:n], data) {
+			t.Fatalf("#%d: got %v; want %v", i, b[:n], data)
+		}
+	}
+}

+ 27 - 3
Godeps/_workspace/src/gopkg.in/check.v1/benchmark.go

@@ -1,6 +1,30 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
+// Copyright (c) 2012 The Go Authors. All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// 
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 package check
 package check
 
 

+ 31 - 22
Godeps/_workspace/src/gopkg.in/check.v1/check.go

@@ -21,6 +21,7 @@ import (
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
+	"sync/atomic"
 	"time"
 	"time"
 )
 )
 
 
@@ -43,7 +44,7 @@ const (
 	missedSt
 	missedSt
 )
 )
 
 
-type funcStatus int
+type funcStatus uint32
 
 
 // A method value can't reach its own Method structure.
 // A method value can't reach its own Method structure.
 type methodType struct {
 type methodType struct {
@@ -81,7 +82,7 @@ type C struct {
 	method    *methodType
 	method    *methodType
 	kind      funcKind
 	kind      funcKind
 	testName  string
 	testName  string
-	status    funcStatus
+	_status   funcStatus
 	logb      *logger
 	logb      *logger
 	logw      io.Writer
 	logw      io.Writer
 	done      chan *C
 	done      chan *C
@@ -93,6 +94,14 @@ type C struct {
 	timer
 	timer
 }
 }
 
 
+func (c *C) status() funcStatus {
+	return funcStatus(atomic.LoadUint32((*uint32)(&c._status)))
+}
+
+func (c *C) setStatus(s funcStatus) {
+	atomic.StoreUint32((*uint32)(&c._status), uint32(s))
+}
+
 func (c *C) stopNow() {
 func (c *C) stopNow() {
 	runtime.Goexit()
 	runtime.Goexit()
 }
 }
@@ -326,7 +335,7 @@ func (c *C) logPanic(skip int, value interface{}) {
 			if name == "Value.call" && strings.HasSuffix(path, valueGo) {
 			if name == "Value.call" && strings.HasSuffix(path, valueGo) {
 				continue
 				continue
 			}
 			}
-			if name == "call16" && strings.Contains(path, asmGo) {
+			if (name == "call16" || name == "call32") && strings.Contains(path, asmGo) {
 				continue
 				continue
 			}
 			}
 			c.logf("%s:%d\n  in %s", nicePath(file), line, name)
 			c.logf("%s:%d\n  in %s", nicePath(file), line, name)
@@ -455,7 +464,7 @@ func (tracker *resultTracker) _loopRoutine() {
 				tracker._waiting += 1
 				tracker._waiting += 1
 			case c = <-tracker._doneChan:
 			case c = <-tracker._doneChan:
 				tracker._waiting -= 1
 				tracker._waiting -= 1
-				switch c.status {
+				switch c.status() {
 				case succeededSt:
 				case succeededSt:
 					if c.kind == testKd {
 					if c.kind == testKd {
 						if c.mustFail {
 						if c.mustFail {
@@ -601,15 +610,15 @@ func (runner *suiteRunner) run() *Result {
 		runner.tracker.start()
 		runner.tracker.start()
 		if runner.checkFixtureArgs() {
 		if runner.checkFixtureArgs() {
 			c := runner.runFixture(runner.setUpSuite, "", nil)
 			c := runner.runFixture(runner.setUpSuite, "", nil)
-			if c == nil || c.status == succeededSt {
+			if c == nil || c.status() == succeededSt {
 				for i := 0; i != len(runner.tests); i++ {
 				for i := 0; i != len(runner.tests); i++ {
 					c := runner.runTest(runner.tests[i])
 					c := runner.runTest(runner.tests[i])
-					if c.status == fixturePanickedSt {
+					if c.status() == fixturePanickedSt {
 						runner.skipTests(missedSt, runner.tests[i+1:])
 						runner.skipTests(missedSt, runner.tests[i+1:])
 						break
 						break
 					}
 					}
 				}
 				}
-			} else if c != nil && c.status == skippedSt {
+			} else if c != nil && c.status() == skippedSt {
 				runner.skipTests(skippedSt, runner.tests)
 				runner.skipTests(skippedSt, runner.tests)
 			} else {
 			} else {
 				runner.skipTests(missedSt, runner.tests)
 				runner.skipTests(missedSt, runner.tests)
@@ -674,22 +683,22 @@ func (runner *suiteRunner) callDone(c *C) {
 		switch v := value.(type) {
 		switch v := value.(type) {
 		case *fixturePanic:
 		case *fixturePanic:
 			if v.status == skippedSt {
 			if v.status == skippedSt {
-				c.status = skippedSt
+				c.setStatus(skippedSt)
 			} else {
 			} else {
 				c.logSoftPanic("Fixture has panicked (see related PANIC)")
 				c.logSoftPanic("Fixture has panicked (see related PANIC)")
-				c.status = fixturePanickedSt
+				c.setStatus(fixturePanickedSt)
 			}
 			}
 		default:
 		default:
 			c.logPanic(1, value)
 			c.logPanic(1, value)
-			c.status = panickedSt
+			c.setStatus(panickedSt)
 		}
 		}
 	}
 	}
 	if c.mustFail {
 	if c.mustFail {
-		switch c.status {
+		switch c.status() {
 		case failedSt:
 		case failedSt:
-			c.status = succeededSt
+			c.setStatus(succeededSt)
 		case succeededSt:
 		case succeededSt:
-			c.status = failedSt
+			c.setStatus(failedSt)
 			c.logString("Error: Test succeeded, but was expected to fail")
 			c.logString("Error: Test succeeded, but was expected to fail")
 			c.logString("Reason: " + c.reason)
 			c.logString("Reason: " + c.reason)
 		}
 		}
@@ -724,11 +733,11 @@ func (runner *suiteRunner) runFixtureWithPanic(method *methodType, testName stri
 		return nil
 		return nil
 	}
 	}
 	c := runner.runFixture(method, testName, logb)
 	c := runner.runFixture(method, testName, logb)
-	if c != nil && c.status != succeededSt {
+	if c != nil && c.status() != succeededSt {
 		if skipped != nil {
 		if skipped != nil {
-			*skipped = c.status == skippedSt
+			*skipped = c.status() == skippedSt
 		}
 		}
-		panic(&fixturePanic{c.status, method})
+		panic(&fixturePanic{c.status(), method})
 	}
 	}
 	return c
 	return c
 }
 }
@@ -753,7 +762,7 @@ func (runner *suiteRunner) forkTest(method *methodType) *C {
 			if mt.NumIn() != 1 || mt.In(0) != reflect.TypeOf(c) {
 			if mt.NumIn() != 1 || mt.In(0) != reflect.TypeOf(c) {
 				// Rather than a plain panic, provide a more helpful message when
 				// Rather than a plain panic, provide a more helpful message when
 				// the argument type is incorrect.
 				// the argument type is incorrect.
-				c.status = panickedSt
+				c.setStatus(panickedSt)
 				c.logArgPanic(c.method, "*check.C")
 				c.logArgPanic(c.method, "*check.C")
 				return
 				return
 			}
 			}
@@ -773,7 +782,7 @@ func (runner *suiteRunner) forkTest(method *methodType) *C {
 			c.StartTimer()
 			c.StartTimer()
 			c.method.Call([]reflect.Value{reflect.ValueOf(c)})
 			c.method.Call([]reflect.Value{reflect.ValueOf(c)})
 			c.StopTimer()
 			c.StopTimer()
-			if c.status != succeededSt || c.duration >= c.benchTime || benchN >= 1e9 {
+			if c.status() != succeededSt || c.duration >= c.benchTime || benchN >= 1e9 {
 				return
 				return
 			}
 			}
 			perOpN := int(1e9)
 			perOpN := int(1e9)
@@ -808,7 +817,7 @@ func (runner *suiteRunner) runTest(method *methodType) *C {
 func (runner *suiteRunner) skipTests(status funcStatus, methods []*methodType) {
 func (runner *suiteRunner) skipTests(status funcStatus, methods []*methodType) {
 	for _, method := range methods {
 	for _, method := range methods {
 		runner.runFunc(method, testKd, "", nil, func(c *C) {
 		runner.runFunc(method, testKd, "", nil, func(c *C) {
-			c.status = status
+			c.setStatus(status)
 		})
 		})
 	}
 	}
 }
 }
@@ -825,7 +834,7 @@ func (runner *suiteRunner) checkFixtureArgs() bool {
 				succeeded = false
 				succeeded = false
 				runner.runFunc(method, fixtureKd, "", nil, func(c *C) {
 				runner.runFunc(method, fixtureKd, "", nil, func(c *C) {
 					c.logArgPanic(method, "*check.C")
 					c.logArgPanic(method, "*check.C")
-					c.status = panickedSt
+					c.setStatus(panickedSt)
 				})
 				})
 			}
 			}
 		}
 		}
@@ -839,7 +848,7 @@ func (runner *suiteRunner) reportCallStarted(c *C) {
 
 
 func (runner *suiteRunner) reportCallDone(c *C) {
 func (runner *suiteRunner) reportCallDone(c *C) {
 	runner.tracker.callDone(c)
 	runner.tracker.callDone(c)
-	switch c.status {
+	switch c.status() {
 	case succeededSt:
 	case succeededSt:
 		if c.mustFail {
 		if c.mustFail {
 			runner.output.WriteCallSuccess("FAIL EXPECTED", c)
 			runner.output.WriteCallSuccess("FAIL EXPECTED", c)
@@ -917,7 +926,7 @@ func (ow *outputWriter) WriteCallSuccess(label string, c *C) {
 		if c.reason != "" {
 		if c.reason != "" {
 			suffix = " (" + c.reason + ")"
 			suffix = " (" + c.reason + ")"
 		}
 		}
-		if c.status == succeededSt {
+		if c.status() == succeededSt {
 			suffix += "\t" + c.timerString()
 			suffix += "\t" + c.timerString()
 		}
 		}
 		suffix += "\n"
 		suffix += "\n"

+ 4 - 4
Godeps/_workspace/src/gopkg.in/check.v1/helpers.go

@@ -16,7 +16,7 @@ func (c *C) TestName() string {
 
 
 // Failed returns whether the currently running test has already failed.
 // Failed returns whether the currently running test has already failed.
 func (c *C) Failed() bool {
 func (c *C) Failed() bool {
-	return c.status == failedSt
+	return c.status() == failedSt
 }
 }
 
 
 // Fail marks the currently running test as failed.
 // Fail marks the currently running test as failed.
@@ -25,7 +25,7 @@ func (c *C) Failed() bool {
 // what went wrong. The higher level helper functions will fail the test
 // what went wrong. The higher level helper functions will fail the test
 // and do the logging properly.
 // and do the logging properly.
 func (c *C) Fail() {
 func (c *C) Fail() {
-	c.status = failedSt
+	c.setStatus(failedSt)
 }
 }
 
 
 // FailNow marks the currently running test as failed and stops running it.
 // FailNow marks the currently running test as failed and stops running it.
@@ -40,7 +40,7 @@ func (c *C) FailNow() {
 // Succeed marks the currently running test as succeeded, undoing any
 // Succeed marks the currently running test as succeeded, undoing any
 // previous failures.
 // previous failures.
 func (c *C) Succeed() {
 func (c *C) Succeed() {
-	c.status = succeededSt
+	c.setStatus(succeededSt)
 }
 }
 
 
 // SucceedNow marks the currently running test as succeeded, undoing any
 // SucceedNow marks the currently running test as succeeded, undoing any
@@ -72,7 +72,7 @@ func (c *C) Skip(reason string) {
 		panic("Missing reason why the test is being skipped")
 		panic("Missing reason why the test is being skipped")
 	}
 	}
 	c.reason = reason
 	c.reason = reason
-	c.status = skippedSt
+	c.setStatus(skippedSt)
 	c.stopNow()
 	c.stopNow()
 }
 }