mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-12 05:21:58 +00:00
Update golang.org/x/net to fix godep reproducability problem
We are debugging why in #14677 but basically godep restore is ending up on master and no the commit specified in godeps. (reproducable with just go get, so don't blame godep right off) To unbreak things this updates golang.org/x/net while we continue to dig deeping into the core problem...
This commit is contained in:
parent
7b428d8bcd
commit
17d54f42fe
6
Godeps/Godeps.json
generated
6
Godeps/Godeps.json
generated
@ -578,15 +578,15 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/net/context",
|
"ImportPath": "golang.org/x/net/context",
|
||||||
"Rev": "cbcac7bb8415db9b6cb4d1ebab1dc9afbd688b97"
|
"Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/net/html",
|
"ImportPath": "golang.org/x/net/html",
|
||||||
"Rev": "cbcac7bb8415db9b6cb4d1ebab1dc9afbd688b97"
|
"Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/net/websocket",
|
"ImportPath": "golang.org/x/net/websocket",
|
||||||
"Rev": "cbcac7bb8415db9b6cb4d1ebab1dc9afbd688b97"
|
"Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/oauth2",
|
"ImportPath": "golang.org/x/oauth2",
|
||||||
|
67
Godeps/_workspace/src/golang.org/x/net/context/context.go
generated
vendored
67
Godeps/_workspace/src/golang.org/x/net/context/context.go
generated
vendored
@ -64,18 +64,21 @@ type Context interface {
|
|||||||
//
|
//
|
||||||
// Done is provided for use in select statements:
|
// Done is provided for use in select statements:
|
||||||
//
|
//
|
||||||
// // DoSomething calls DoSomethingSlow and returns as soon as
|
// // Stream generates values with DoSomething and sends them to out
|
||||||
// // it returns or ctx.Done is closed.
|
// // until DoSomething returns an error or ctx.Done is closed.
|
||||||
// func DoSomething(ctx context.Context) (Result, error) {
|
// func Stream(ctx context.Context, out <-chan Value) error {
|
||||||
// c := make(chan Result, 1)
|
// for {
|
||||||
// go func() { c <- DoSomethingSlow(ctx) }()
|
// v, err := DoSomething(ctx)
|
||||||
// select {
|
// if err != nil {
|
||||||
// case res := <-c:
|
// return err
|
||||||
// return res, nil
|
// }
|
||||||
// case <-ctx.Done():
|
// select {
|
||||||
// return nil, ctx.Err()
|
// case <-ctx.Done():
|
||||||
// }
|
// return ctx.Err()
|
||||||
// }
|
// case out <- v:
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
//
|
//
|
||||||
// See http://blog.golang.org/pipelines for more examples of how to use
|
// See http://blog.golang.org/pipelines for more examples of how to use
|
||||||
// a Done channel for cancelation.
|
// a Done channel for cancelation.
|
||||||
@ -202,6 +205,9 @@ type CancelFunc func()
|
|||||||
// WithCancel returns a copy of parent with a new Done channel. The returned
|
// WithCancel returns a copy of parent with a new Done channel. The returned
|
||||||
// context's Done channel is closed when the returned cancel function is called
|
// context's Done channel is closed when the returned cancel function is called
|
||||||
// or when the parent context's Done channel is closed, whichever happens first.
|
// or when the parent context's Done channel is closed, whichever happens first.
|
||||||
|
//
|
||||||
|
// Canceling this context releases resources associated with it, so code should
|
||||||
|
// call cancel as soon as the operations running in this Context complete.
|
||||||
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
|
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
|
||||||
c := newCancelCtx(parent)
|
c := newCancelCtx(parent)
|
||||||
propagateCancel(parent, &c)
|
propagateCancel(parent, &c)
|
||||||
@ -262,6 +268,19 @@ func parentCancelCtx(parent Context) (*cancelCtx, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// removeChild removes a context from its parent.
|
||||||
|
func removeChild(parent Context, child canceler) {
|
||||||
|
p, ok := parentCancelCtx(parent)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.mu.Lock()
|
||||||
|
if p.children != nil {
|
||||||
|
delete(p.children, child)
|
||||||
|
}
|
||||||
|
p.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
// A canceler is a context type that can be canceled directly. The
|
// A canceler is a context type that can be canceled directly. The
|
||||||
// implementations are *cancelCtx and *timerCtx.
|
// implementations are *cancelCtx and *timerCtx.
|
||||||
type canceler interface {
|
type canceler interface {
|
||||||
@ -316,13 +335,7 @@ func (c *cancelCtx) cancel(removeFromParent bool, err error) {
|
|||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
|
|
||||||
if removeFromParent {
|
if removeFromParent {
|
||||||
if p, ok := parentCancelCtx(c.Context); ok {
|
removeChild(c.Context, c)
|
||||||
p.mu.Lock()
|
|
||||||
if p.children != nil {
|
|
||||||
delete(p.children, c)
|
|
||||||
}
|
|
||||||
p.mu.Unlock()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,9 +346,8 @@ func (c *cancelCtx) cancel(removeFromParent bool, err error) {
|
|||||||
// cancel function is called, or when the parent context's Done channel is
|
// cancel function is called, or when the parent context's Done channel is
|
||||||
// closed, whichever happens first.
|
// closed, whichever happens first.
|
||||||
//
|
//
|
||||||
// Canceling this context releases resources associated with the deadline
|
// Canceling this context releases resources associated with it, so code should
|
||||||
// timer, so code should call cancel as soon as the operations running in this
|
// call cancel as soon as the operations running in this Context complete.
|
||||||
// Context complete.
|
|
||||||
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
|
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
|
||||||
if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
|
if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
|
||||||
// The current deadline is already sooner than the new one.
|
// The current deadline is already sooner than the new one.
|
||||||
@ -380,7 +392,11 @@ func (c *timerCtx) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *timerCtx) cancel(removeFromParent bool, err error) {
|
func (c *timerCtx) cancel(removeFromParent bool, err error) {
|
||||||
c.cancelCtx.cancel(removeFromParent, err)
|
c.cancelCtx.cancel(false, err)
|
||||||
|
if removeFromParent {
|
||||||
|
// Remove this timerCtx from its parent cancelCtx's children.
|
||||||
|
removeChild(c.cancelCtx.Context, c)
|
||||||
|
}
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
if c.timer != nil {
|
if c.timer != nil {
|
||||||
c.timer.Stop()
|
c.timer.Stop()
|
||||||
@ -391,9 +407,8 @@ func (c *timerCtx) cancel(removeFromParent bool, err error) {
|
|||||||
|
|
||||||
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
|
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
|
||||||
//
|
//
|
||||||
// Canceling this context releases resources associated with the deadline
|
// Canceling this context releases resources associated with it, so code should
|
||||||
// timer, so code should call cancel as soon as the operations running in this
|
// call cancel as soon as the operations running in this Context complete:
|
||||||
// Context complete:
|
|
||||||
//
|
//
|
||||||
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
||||||
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||||
|
24
Godeps/_workspace/src/golang.org/x/net/context/context_test.go
generated
vendored
24
Godeps/_workspace/src/golang.org/x/net/context/context_test.go
generated
vendored
@ -375,7 +375,7 @@ func TestAllocs(t *testing.T) {
|
|||||||
<-c.Done()
|
<-c.Done()
|
||||||
},
|
},
|
||||||
limit: 8,
|
limit: 8,
|
||||||
gccgoLimit: 13,
|
gccgoLimit: 15,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "WithCancel(bg)",
|
desc: "WithCancel(bg)",
|
||||||
@ -551,3 +551,25 @@ func testLayers(t *testing.T, seed int64, testTimeout bool) {
|
|||||||
checkValues("after cancel")
|
checkValues("after cancel")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCancelRemoves(t *testing.T) {
|
||||||
|
checkChildren := func(when string, ctx Context, want int) {
|
||||||
|
if got := len(ctx.(*cancelCtx).children); got != want {
|
||||||
|
t.Errorf("%s: context has %d children, want %d", when, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, _ := WithCancel(Background())
|
||||||
|
checkChildren("after creation", ctx, 0)
|
||||||
|
_, cancel := WithCancel(ctx)
|
||||||
|
checkChildren("with WithCancel child ", ctx, 1)
|
||||||
|
cancel()
|
||||||
|
checkChildren("after cancelling WithCancel child", ctx, 0)
|
||||||
|
|
||||||
|
ctx, _ = WithCancel(Background())
|
||||||
|
checkChildren("after creation", ctx, 0)
|
||||||
|
_, cancel = WithTimeout(ctx, 60*time.Minute)
|
||||||
|
checkChildren("with WithTimeout child ", ctx, 1)
|
||||||
|
cancel()
|
||||||
|
checkChildren("after cancelling WithTimeout child", ctx, 0)
|
||||||
|
}
|
||||||
|
18
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go
generated
vendored
Normal file
18
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// +build go1.5
|
||||||
|
|
||||||
|
package ctxhttp
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
func canceler(client *http.Client, req *http.Request) func() {
|
||||||
|
ch := make(chan struct{})
|
||||||
|
req.Cancel = ch
|
||||||
|
|
||||||
|
return func() {
|
||||||
|
close(ch)
|
||||||
|
}
|
||||||
|
}
|
23
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go
generated
vendored
Normal file
23
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// +build !go1.5
|
||||||
|
|
||||||
|
package ctxhttp
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
type requestCanceler interface {
|
||||||
|
CancelRequest(*http.Request)
|
||||||
|
}
|
||||||
|
|
||||||
|
func canceler(client *http.Client, req *http.Request) func() {
|
||||||
|
rc, ok := client.Transport.(requestCanceler)
|
||||||
|
if !ok {
|
||||||
|
return func() {}
|
||||||
|
}
|
||||||
|
return func() {
|
||||||
|
rc.CancelRequest(req)
|
||||||
|
}
|
||||||
|
}
|
79
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go
generated
vendored
Normal file
79
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
|
||||||
|
package ctxhttp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Do sends an HTTP request with the provided http.Client and returns an HTTP response.
|
||||||
|
// If the client is nil, http.DefaultClient is used.
|
||||||
|
// If the context is canceled or times out, ctx.Err() will be returned.
|
||||||
|
func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
|
||||||
|
if client == nil {
|
||||||
|
client = http.DefaultClient
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go.
|
||||||
|
cancel := canceler(client, req)
|
||||||
|
|
||||||
|
type responseAndError struct {
|
||||||
|
resp *http.Response
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
result := make(chan responseAndError, 1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
result <- responseAndError{resp, err}
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
cancel()
|
||||||
|
return nil, ctx.Err()
|
||||||
|
case r := <-result:
|
||||||
|
return r.resp, r.err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get issues a GET request via the Do function.
|
||||||
|
func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return Do(ctx, client, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Head issues a HEAD request via the Do function.
|
||||||
|
func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
||||||
|
req, err := http.NewRequest("HEAD", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return Do(ctx, client, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post issues a POST request via the Do function.
|
||||||
|
func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
|
||||||
|
req, err := http.NewRequest("POST", url, body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", bodyType)
|
||||||
|
return Do(ctx, client, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostForm issues a POST request via the Do function.
|
||||||
|
func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
|
||||||
|
return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
|
||||||
|
}
|
72
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp_test.go
generated
vendored
Normal file
72
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp_test.go
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
package ctxhttp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
requestDuration = 100 * time.Millisecond
|
||||||
|
requestBody = "ok"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNoTimeout(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
resp, err := doRequest(ctx)
|
||||||
|
|
||||||
|
if resp == nil || err != nil {
|
||||||
|
t.Fatalf("error received from client: %v %v", err, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func TestCancel(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
go func() {
|
||||||
|
time.Sleep(requestDuration / 2)
|
||||||
|
cancel()
|
||||||
|
}()
|
||||||
|
|
||||||
|
resp, err := doRequest(ctx)
|
||||||
|
|
||||||
|
if resp != nil || err == nil {
|
||||||
|
t.Fatalf("expected error, didn't get one. resp: %v", resp)
|
||||||
|
}
|
||||||
|
if err != ctx.Err() {
|
||||||
|
t.Fatalf("expected error from context but got: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCancelAfterRequest(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
resp, err := doRequest(ctx)
|
||||||
|
|
||||||
|
// Cancel before reading the body.
|
||||||
|
// Request.Body should still be readable after the context is canceled.
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
b, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil || string(b) != requestBody {
|
||||||
|
t.Fatalf("could not read body: %q %v", b, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func doRequest(ctx context.Context) (*http.Response, error) {
|
||||||
|
var okHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
time.Sleep(requestDuration)
|
||||||
|
w.Write([]byte(requestBody))
|
||||||
|
})
|
||||||
|
|
||||||
|
serv := httptest.NewServer(okHandler)
|
||||||
|
defer serv.Close()
|
||||||
|
|
||||||
|
return Get(ctx, nil, serv.URL)
|
||||||
|
}
|
20
Godeps/_workspace/src/golang.org/x/net/html/atom/gen.go
generated
vendored
20
Godeps/_workspace/src/golang.org/x/net/html/atom/gen.go
generated
vendored
@ -284,8 +284,8 @@ func (t *table) push(i uint32, depth int) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The lists of element names and attribute keys were taken from
|
// The lists of element names and attribute keys were taken from
|
||||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/section-index.html
|
// https://html.spec.whatwg.org/multipage/indices.html#index
|
||||||
// as of the "HTML Living Standard - Last Updated 30 May 2012" version.
|
// as of the "HTML Living Standard - Last Updated 21 February 2015" version.
|
||||||
|
|
||||||
var elements = []string{
|
var elements = []string{
|
||||||
"a",
|
"a",
|
||||||
@ -352,6 +352,7 @@ var elements = []string{
|
|||||||
"map",
|
"map",
|
||||||
"mark",
|
"mark",
|
||||||
"menu",
|
"menu",
|
||||||
|
"menuitem",
|
||||||
"meta",
|
"meta",
|
||||||
"meter",
|
"meter",
|
||||||
"nav",
|
"nav",
|
||||||
@ -385,6 +386,7 @@ var elements = []string{
|
|||||||
"table",
|
"table",
|
||||||
"tbody",
|
"tbody",
|
||||||
"td",
|
"td",
|
||||||
|
"template",
|
||||||
"textarea",
|
"textarea",
|
||||||
"tfoot",
|
"tfoot",
|
||||||
"th",
|
"th",
|
||||||
@ -400,7 +402,10 @@ var elements = []string{
|
|||||||
"wbr",
|
"wbr",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/indices.html#attributes-3
|
||||||
|
|
||||||
var attributes = []string{
|
var attributes = []string{
|
||||||
|
"abbr",
|
||||||
"accept",
|
"accept",
|
||||||
"accept-charset",
|
"accept-charset",
|
||||||
"accesskey",
|
"accesskey",
|
||||||
@ -410,7 +415,6 @@ var attributes = []string{
|
|||||||
"autocomplete",
|
"autocomplete",
|
||||||
"autofocus",
|
"autofocus",
|
||||||
"autoplay",
|
"autoplay",
|
||||||
"border",
|
|
||||||
"challenge",
|
"challenge",
|
||||||
"charset",
|
"charset",
|
||||||
"checked",
|
"checked",
|
||||||
@ -452,7 +456,7 @@ var attributes = []string{
|
|||||||
"http-equiv",
|
"http-equiv",
|
||||||
"icon",
|
"icon",
|
||||||
"id",
|
"id",
|
||||||
"inert",
|
"inputmode",
|
||||||
"ismap",
|
"ismap",
|
||||||
"itemid",
|
"itemid",
|
||||||
"itemprop",
|
"itemprop",
|
||||||
@ -473,6 +477,7 @@ var attributes = []string{
|
|||||||
"mediagroup",
|
"mediagroup",
|
||||||
"method",
|
"method",
|
||||||
"min",
|
"min",
|
||||||
|
"minlength",
|
||||||
"multiple",
|
"multiple",
|
||||||
"muted",
|
"muted",
|
||||||
"name",
|
"name",
|
||||||
@ -500,6 +505,8 @@ var attributes = []string{
|
|||||||
"shape",
|
"shape",
|
||||||
"size",
|
"size",
|
||||||
"sizes",
|
"sizes",
|
||||||
|
"sortable",
|
||||||
|
"sorted",
|
||||||
"span",
|
"span",
|
||||||
"src",
|
"src",
|
||||||
"srcdoc",
|
"srcdoc",
|
||||||
@ -521,6 +528,8 @@ var attributes = []string{
|
|||||||
|
|
||||||
var eventHandlers = []string{
|
var eventHandlers = []string{
|
||||||
"onabort",
|
"onabort",
|
||||||
|
"onautocomplete",
|
||||||
|
"onautocompleteerror",
|
||||||
"onafterprint",
|
"onafterprint",
|
||||||
"onbeforeprint",
|
"onbeforeprint",
|
||||||
"onbeforeunload",
|
"onbeforeunload",
|
||||||
@ -552,6 +561,7 @@ var eventHandlers = []string{
|
|||||||
"onkeydown",
|
"onkeydown",
|
||||||
"onkeypress",
|
"onkeypress",
|
||||||
"onkeyup",
|
"onkeyup",
|
||||||
|
"onlanguagechange",
|
||||||
"onload",
|
"onload",
|
||||||
"onloadeddata",
|
"onloadeddata",
|
||||||
"onloadedmetadata",
|
"onloadedmetadata",
|
||||||
@ -580,11 +590,13 @@ var eventHandlers = []string{
|
|||||||
"onseeking",
|
"onseeking",
|
||||||
"onselect",
|
"onselect",
|
||||||
"onshow",
|
"onshow",
|
||||||
|
"onsort",
|
||||||
"onstalled",
|
"onstalled",
|
||||||
"onstorage",
|
"onstorage",
|
||||||
"onsubmit",
|
"onsubmit",
|
||||||
"onsuspend",
|
"onsuspend",
|
||||||
"ontimeupdate",
|
"ontimeupdate",
|
||||||
|
"ontoggle",
|
||||||
"onunload",
|
"onunload",
|
||||||
"onvolumechange",
|
"onvolumechange",
|
||||||
"onwaiting",
|
"onwaiting",
|
||||||
|
1325
Godeps/_workspace/src/golang.org/x/net/html/atom/table.go
generated
vendored
1325
Godeps/_workspace/src/golang.org/x/net/html/atom/table.go
generated
vendored
File diff suppressed because it is too large
Load Diff
14
Godeps/_workspace/src/golang.org/x/net/html/atom/table_test.go
generated
vendored
14
Godeps/_workspace/src/golang.org/x/net/html/atom/table_test.go
generated
vendored
@ -5,6 +5,7 @@ package atom
|
|||||||
var testAtomList = []string{
|
var testAtomList = []string{
|
||||||
"a",
|
"a",
|
||||||
"abbr",
|
"abbr",
|
||||||
|
"abbr",
|
||||||
"accept",
|
"accept",
|
||||||
"accept-charset",
|
"accept-charset",
|
||||||
"accesskey",
|
"accesskey",
|
||||||
@ -33,7 +34,6 @@ var testAtomList = []string{
|
|||||||
"blink",
|
"blink",
|
||||||
"blockquote",
|
"blockquote",
|
||||||
"body",
|
"body",
|
||||||
"border",
|
|
||||||
"br",
|
"br",
|
||||||
"button",
|
"button",
|
||||||
"canvas",
|
"canvas",
|
||||||
@ -125,8 +125,8 @@ var testAtomList = []string{
|
|||||||
"iframe",
|
"iframe",
|
||||||
"image",
|
"image",
|
||||||
"img",
|
"img",
|
||||||
"inert",
|
|
||||||
"input",
|
"input",
|
||||||
|
"inputmode",
|
||||||
"ins",
|
"ins",
|
||||||
"isindex",
|
"isindex",
|
||||||
"ismap",
|
"ismap",
|
||||||
@ -160,12 +160,14 @@ var testAtomList = []string{
|
|||||||
"media",
|
"media",
|
||||||
"mediagroup",
|
"mediagroup",
|
||||||
"menu",
|
"menu",
|
||||||
|
"menuitem",
|
||||||
"meta",
|
"meta",
|
||||||
"meter",
|
"meter",
|
||||||
"method",
|
"method",
|
||||||
"mglyph",
|
"mglyph",
|
||||||
"mi",
|
"mi",
|
||||||
"min",
|
"min",
|
||||||
|
"minlength",
|
||||||
"mn",
|
"mn",
|
||||||
"mo",
|
"mo",
|
||||||
"ms",
|
"ms",
|
||||||
@ -183,6 +185,8 @@ var testAtomList = []string{
|
|||||||
"ol",
|
"ol",
|
||||||
"onabort",
|
"onabort",
|
||||||
"onafterprint",
|
"onafterprint",
|
||||||
|
"onautocomplete",
|
||||||
|
"onautocompleteerror",
|
||||||
"onbeforeprint",
|
"onbeforeprint",
|
||||||
"onbeforeunload",
|
"onbeforeunload",
|
||||||
"onblur",
|
"onblur",
|
||||||
@ -213,6 +217,7 @@ var testAtomList = []string{
|
|||||||
"onkeydown",
|
"onkeydown",
|
||||||
"onkeypress",
|
"onkeypress",
|
||||||
"onkeyup",
|
"onkeyup",
|
||||||
|
"onlanguagechange",
|
||||||
"onload",
|
"onload",
|
||||||
"onloadeddata",
|
"onloadeddata",
|
||||||
"onloadedmetadata",
|
"onloadedmetadata",
|
||||||
@ -241,11 +246,13 @@ var testAtomList = []string{
|
|||||||
"onseeking",
|
"onseeking",
|
||||||
"onselect",
|
"onselect",
|
||||||
"onshow",
|
"onshow",
|
||||||
|
"onsort",
|
||||||
"onstalled",
|
"onstalled",
|
||||||
"onstorage",
|
"onstorage",
|
||||||
"onsubmit",
|
"onsubmit",
|
||||||
"onsuspend",
|
"onsuspend",
|
||||||
"ontimeupdate",
|
"ontimeupdate",
|
||||||
|
"ontoggle",
|
||||||
"onunload",
|
"onunload",
|
||||||
"onvolumechange",
|
"onvolumechange",
|
||||||
"onwaiting",
|
"onwaiting",
|
||||||
@ -291,6 +298,8 @@ var testAtomList = []string{
|
|||||||
"size",
|
"size",
|
||||||
"sizes",
|
"sizes",
|
||||||
"small",
|
"small",
|
||||||
|
"sortable",
|
||||||
|
"sorted",
|
||||||
"source",
|
"source",
|
||||||
"spacer",
|
"spacer",
|
||||||
"span",
|
"span",
|
||||||
@ -315,6 +324,7 @@ var testAtomList = []string{
|
|||||||
"target",
|
"target",
|
||||||
"tbody",
|
"tbody",
|
||||||
"td",
|
"td",
|
||||||
|
"template",
|
||||||
"textarea",
|
"textarea",
|
||||||
"tfoot",
|
"tfoot",
|
||||||
"th",
|
"th",
|
||||||
|
15
Godeps/_workspace/src/golang.org/x/net/html/charset/charset.go
generated
vendored
15
Godeps/_workspace/src/golang.org/x/net/html/charset/charset.go
generated
vendored
@ -5,11 +5,12 @@
|
|||||||
// Package charset provides common text encodings for HTML documents.
|
// Package charset provides common text encodings for HTML documents.
|
||||||
//
|
//
|
||||||
// The mapping from encoding labels to encodings is defined at
|
// The mapping from encoding labels to encodings is defined at
|
||||||
// http://encoding.spec.whatwg.org.
|
// https://encoding.spec.whatwg.org/.
|
||||||
package charset
|
package charset
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
"strings"
|
"strings"
|
||||||
@ -110,6 +111,18 @@ func NewReader(r io.Reader, contentType string) (io.Reader, error) {
|
|||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewReaderLabel returns a reader that converts from the specified charset to
|
||||||
|
// UTF-8. It uses Lookup to find the encoding that corresponds to label, and
|
||||||
|
// returns an error if Lookup returns nil. It is suitable for use as
|
||||||
|
// encoding/xml.Decoder's CharsetReader function.
|
||||||
|
func NewReaderLabel(label string, input io.Reader) (io.Reader, error) {
|
||||||
|
e, _ := Lookup(label)
|
||||||
|
if e == nil {
|
||||||
|
return nil, fmt.Errorf("unsupported charset: %q", label)
|
||||||
|
}
|
||||||
|
return transform.NewReader(input, e.NewDecoder()), nil
|
||||||
|
}
|
||||||
|
|
||||||
func prescan(content []byte) (e encoding.Encoding, name string) {
|
func prescan(content []byte) (e encoding.Encoding, name string) {
|
||||||
z := html.NewTokenizer(bytes.NewReader(content))
|
z := html.NewTokenizer(bytes.NewReader(content))
|
||||||
for {
|
for {
|
||||||
|
21
Godeps/_workspace/src/golang.org/x/net/html/charset/charset_test.go
generated
vendored
21
Godeps/_workspace/src/golang.org/x/net/html/charset/charset_test.go
generated
vendored
@ -6,6 +6,7 @@ package charset
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/xml"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
@ -213,3 +214,23 @@ func TestFromMeta(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestXML(t *testing.T) {
|
||||||
|
const s = "<?xml version=\"1.0\" encoding=\"windows-1252\"?><a><Word>r\xe9sum\xe9</Word></a>"
|
||||||
|
|
||||||
|
d := xml.NewDecoder(strings.NewReader(s))
|
||||||
|
d.CharsetReader = NewReaderLabel
|
||||||
|
|
||||||
|
var a struct {
|
||||||
|
Word string
|
||||||
|
}
|
||||||
|
err := d.Decode(&a)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Decode: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := "résumé"
|
||||||
|
if a.Word != want {
|
||||||
|
t.Errorf("got %q, want %q", a.Word, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
4
Godeps/_workspace/src/golang.org/x/net/html/charset/gen.go
generated
vendored
4
Godeps/_workspace/src/golang.org/x/net/html/charset/gen.go
generated
vendored
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
// Download http://encoding.spec.whatwg.org/encodings.json and use it to
|
// Download https://encoding.spec.whatwg.org/encodings.json and use it to
|
||||||
// generate table.go.
|
// generate table.go.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -27,7 +27,7 @@ type group struct {
|
|||||||
Heading string
|
Heading string
|
||||||
}
|
}
|
||||||
|
|
||||||
const specURL = "http://encoding.spec.whatwg.org/encodings.json"
|
const specURL = "https://encoding.spec.whatwg.org/encodings.json"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
resp, err := http.Get(specURL)
|
resp, err := http.Get(specURL)
|
||||||
|
10
Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/README
generated
vendored
10
Godeps/_workspace/src/golang.org/x/net/html/charset/testdata/README
generated
vendored
@ -1 +1,9 @@
|
|||||||
These test cases come from http://www.w3.org/International/tests/html5/the-input-byte-stream/results-basics
|
These test cases come from
|
||||||
|
http://www.w3.org/International/tests/repository/html5/the-input-byte-stream/results-basics
|
||||||
|
|
||||||
|
Distributed under both the W3C Test Suite License
|
||||||
|
(http://www.w3.org/Consortium/Legal/2008/04-testsuite-license)
|
||||||
|
and the W3C 3-clause BSD License
|
||||||
|
(http://www.w3.org/Consortium/Legal/2008/03-bsd-license).
|
||||||
|
To contribute to a W3C Test Suite, see the policies and contribution
|
||||||
|
forms (http://www.w3.org/2004/10/27-testcases).
|
||||||
|
6
Godeps/_workspace/src/golang.org/x/net/html/const.go
generated
vendored
6
Godeps/_workspace/src/golang.org/x/net/html/const.go
generated
vendored
@ -6,7 +6,7 @@ package html
|
|||||||
|
|
||||||
// Section 12.2.3.2 of the HTML5 specification says "The following elements
|
// Section 12.2.3.2 of the HTML5 specification says "The following elements
|
||||||
// have varying levels of special parsing rules".
|
// have varying levels of special parsing rules".
|
||||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#the-stack-of-open-elements
|
// https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements
|
||||||
var isSpecialElementMap = map[string]bool{
|
var isSpecialElementMap = map[string]bool{
|
||||||
"address": true,
|
"address": true,
|
||||||
"applet": true,
|
"applet": true,
|
||||||
@ -24,7 +24,6 @@ var isSpecialElementMap = map[string]bool{
|
|||||||
"center": true,
|
"center": true,
|
||||||
"col": true,
|
"col": true,
|
||||||
"colgroup": true,
|
"colgroup": true,
|
||||||
"command": true,
|
|
||||||
"dd": true,
|
"dd": true,
|
||||||
"details": true,
|
"details": true,
|
||||||
"dir": true,
|
"dir": true,
|
||||||
@ -73,17 +72,20 @@ var isSpecialElementMap = map[string]bool{
|
|||||||
"script": true,
|
"script": true,
|
||||||
"section": true,
|
"section": true,
|
||||||
"select": true,
|
"select": true,
|
||||||
|
"source": true,
|
||||||
"style": true,
|
"style": true,
|
||||||
"summary": true,
|
"summary": true,
|
||||||
"table": true,
|
"table": true,
|
||||||
"tbody": true,
|
"tbody": true,
|
||||||
"td": true,
|
"td": true,
|
||||||
|
"template": true,
|
||||||
"textarea": true,
|
"textarea": true,
|
||||||
"tfoot": true,
|
"tfoot": true,
|
||||||
"th": true,
|
"th": true,
|
||||||
"thead": true,
|
"thead": true,
|
||||||
"title": true,
|
"title": true,
|
||||||
"tr": true,
|
"tr": true,
|
||||||
|
"track": true,
|
||||||
"ul": true,
|
"ul": true,
|
||||||
"wbr": true,
|
"wbr": true,
|
||||||
"xmp": true,
|
"xmp": true,
|
||||||
|
4
Godeps/_workspace/src/golang.org/x/net/html/doc.go
generated
vendored
4
Godeps/_workspace/src/golang.org/x/net/html/doc.go
generated
vendored
@ -90,8 +90,8 @@ example, to process each anchor node in depth-first order:
|
|||||||
f(doc)
|
f(doc)
|
||||||
|
|
||||||
The relevant specifications include:
|
The relevant specifications include:
|
||||||
http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html and
|
https://html.spec.whatwg.org/multipage/syntax.html and
|
||||||
http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html
|
https://html.spec.whatwg.org/multipage/syntax.html#tokenization
|
||||||
*/
|
*/
|
||||||
package html
|
package html
|
||||||
|
|
||||||
|
2
Godeps/_workspace/src/golang.org/x/net/html/entity.go
generated
vendored
2
Godeps/_workspace/src/golang.org/x/net/html/entity.go
generated
vendored
@ -8,7 +8,7 @@ package html
|
|||||||
const longestEntityWithoutSemicolon = 6
|
const longestEntityWithoutSemicolon = 6
|
||||||
|
|
||||||
// entity is a map from HTML entity names to their values. The semicolon matters:
|
// entity is a map from HTML entity names to their values. The semicolon matters:
|
||||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/named-character-references.html
|
// https://html.spec.whatwg.org/multipage/syntax.html#named-character-references
|
||||||
// lists both "amp" and "amp;" as two separate entries.
|
// lists both "amp" and "amp;" as two separate entries.
|
||||||
//
|
//
|
||||||
// Note that the HTML5 list is larger than the HTML4 list at
|
// Note that the HTML5 list is larger than the HTML4 list at
|
||||||
|
4
Godeps/_workspace/src/golang.org/x/net/html/escape.go
generated
vendored
4
Godeps/_workspace/src/golang.org/x/net/html/escape.go
generated
vendored
@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
// These replacements permit compatibility with old numeric entities that
|
// These replacements permit compatibility with old numeric entities that
|
||||||
// assumed Windows-1252 encoding.
|
// assumed Windows-1252 encoding.
|
||||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#consume-a-character-reference
|
// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference
|
||||||
var replacementTable = [...]rune{
|
var replacementTable = [...]rune{
|
||||||
'\u20AC', // First entry is what 0x80 should be replaced with.
|
'\u20AC', // First entry is what 0x80 should be replaced with.
|
||||||
'\u0081',
|
'\u0081',
|
||||||
@ -55,7 +55,7 @@ var replacementTable = [...]rune{
|
|||||||
// Precondition: b[src] == '&' && dst <= src.
|
// Precondition: b[src] == '&' && dst <= src.
|
||||||
// attribute should be true if parsing an attribute value.
|
// attribute should be true if parsing an attribute value.
|
||||||
func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
|
func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
|
||||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#consume-a-character-reference
|
// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference
|
||||||
|
|
||||||
// i starts at 1 because we already know that s[0] == '&'.
|
// i starts at 1 because we already know that s[0] == '&'.
|
||||||
i, s := 1, b[src:]
|
i, s := 1, b[src:]
|
||||||
|
42
Godeps/_workspace/src/golang.org/x/net/html/parse.go
generated
vendored
42
Godeps/_workspace/src/golang.org/x/net/html/parse.go
generated
vendored
@ -14,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// A parser implements the HTML5 parsing algorithm:
|
// A parser implements the HTML5 parsing algorithm:
|
||||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#tree-construction
|
// https://html.spec.whatwg.org/multipage/syntax.html#tree-construction
|
||||||
type parser struct {
|
type parser struct {
|
||||||
// tokenizer provides the tokens for the parser.
|
// tokenizer provides the tokens for the parser.
|
||||||
tokenizer *Tokenizer
|
tokenizer *Tokenizer
|
||||||
@ -59,7 +59,7 @@ func (p *parser) top() *Node {
|
|||||||
// Stop tags for use in popUntil. These come from section 12.2.3.2.
|
// Stop tags for use in popUntil. These come from section 12.2.3.2.
|
||||||
var (
|
var (
|
||||||
defaultScopeStopTags = map[string][]a.Atom{
|
defaultScopeStopTags = map[string][]a.Atom{
|
||||||
"": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object},
|
"": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template},
|
||||||
"math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext},
|
"math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext},
|
||||||
"svg": {a.Desc, a.ForeignObject, a.Title},
|
"svg": {a.Desc, a.ForeignObject, a.Title},
|
||||||
}
|
}
|
||||||
@ -1037,15 +1037,15 @@ func inBodyIM(p *parser) bool {
|
|||||||
|
|
||||||
func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
|
func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
|
||||||
// This is the "adoption agency" algorithm, described at
|
// This is the "adoption agency" algorithm, described at
|
||||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#adoptionAgency
|
// https://html.spec.whatwg.org/multipage/syntax.html#adoptionAgency
|
||||||
|
|
||||||
// TODO: this is a fairly literal line-by-line translation of that algorithm.
|
// TODO: this is a fairly literal line-by-line translation of that algorithm.
|
||||||
// Once the code successfully parses the comprehensive test suite, we should
|
// Once the code successfully parses the comprehensive test suite, we should
|
||||||
// refactor this code to be more idiomatic.
|
// refactor this code to be more idiomatic.
|
||||||
|
|
||||||
// Steps 1-3. The outer loop.
|
// Steps 1-4. The outer loop.
|
||||||
for i := 0; i < 8; i++ {
|
for i := 0; i < 8; i++ {
|
||||||
// Step 4. Find the formatting element.
|
// Step 5. Find the formatting element.
|
||||||
var formattingElement *Node
|
var formattingElement *Node
|
||||||
for j := len(p.afe) - 1; j >= 0; j-- {
|
for j := len(p.afe) - 1; j >= 0; j-- {
|
||||||
if p.afe[j].Type == scopeMarkerNode {
|
if p.afe[j].Type == scopeMarkerNode {
|
||||||
@ -1070,7 +1070,7 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Steps 5-6. Find the furthest block.
|
// Steps 9-10. Find the furthest block.
|
||||||
var furthestBlock *Node
|
var furthestBlock *Node
|
||||||
for _, e := range p.oe[feIndex:] {
|
for _, e := range p.oe[feIndex:] {
|
||||||
if isSpecialElement(e) {
|
if isSpecialElement(e) {
|
||||||
@ -1087,47 +1087,47 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Steps 7-8. Find the common ancestor and bookmark node.
|
// Steps 11-12. Find the common ancestor and bookmark node.
|
||||||
commonAncestor := p.oe[feIndex-1]
|
commonAncestor := p.oe[feIndex-1]
|
||||||
bookmark := p.afe.index(formattingElement)
|
bookmark := p.afe.index(formattingElement)
|
||||||
|
|
||||||
// Step 9. The inner loop. Find the lastNode to reparent.
|
// Step 13. The inner loop. Find the lastNode to reparent.
|
||||||
lastNode := furthestBlock
|
lastNode := furthestBlock
|
||||||
node := furthestBlock
|
node := furthestBlock
|
||||||
x := p.oe.index(node)
|
x := p.oe.index(node)
|
||||||
// Steps 9.1-9.3.
|
// Steps 13.1-13.2
|
||||||
for j := 0; j < 3; j++ {
|
for j := 0; j < 3; j++ {
|
||||||
// Step 9.4.
|
// Step 13.3.
|
||||||
x--
|
x--
|
||||||
node = p.oe[x]
|
node = p.oe[x]
|
||||||
// Step 9.5.
|
// Step 13.4 - 13.5.
|
||||||
if p.afe.index(node) == -1 {
|
if p.afe.index(node) == -1 {
|
||||||
p.oe.remove(node)
|
p.oe.remove(node)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Step 9.6.
|
// Step 13.6.
|
||||||
if node == formattingElement {
|
if node == formattingElement {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// Step 9.7.
|
// Step 13.7.
|
||||||
clone := node.clone()
|
clone := node.clone()
|
||||||
p.afe[p.afe.index(node)] = clone
|
p.afe[p.afe.index(node)] = clone
|
||||||
p.oe[p.oe.index(node)] = clone
|
p.oe[p.oe.index(node)] = clone
|
||||||
node = clone
|
node = clone
|
||||||
// Step 9.8.
|
// Step 13.8.
|
||||||
if lastNode == furthestBlock {
|
if lastNode == furthestBlock {
|
||||||
bookmark = p.afe.index(node) + 1
|
bookmark = p.afe.index(node) + 1
|
||||||
}
|
}
|
||||||
// Step 9.9.
|
// Step 13.9.
|
||||||
if lastNode.Parent != nil {
|
if lastNode.Parent != nil {
|
||||||
lastNode.Parent.RemoveChild(lastNode)
|
lastNode.Parent.RemoveChild(lastNode)
|
||||||
}
|
}
|
||||||
node.AppendChild(lastNode)
|
node.AppendChild(lastNode)
|
||||||
// Step 9.10.
|
// Step 13.10.
|
||||||
lastNode = node
|
lastNode = node
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 10. Reparent lastNode to the common ancestor,
|
// Step 14. Reparent lastNode to the common ancestor,
|
||||||
// or for misnested table nodes, to the foster parent.
|
// or for misnested table nodes, to the foster parent.
|
||||||
if lastNode.Parent != nil {
|
if lastNode.Parent != nil {
|
||||||
lastNode.Parent.RemoveChild(lastNode)
|
lastNode.Parent.RemoveChild(lastNode)
|
||||||
@ -1139,13 +1139,13 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
|
|||||||
commonAncestor.AppendChild(lastNode)
|
commonAncestor.AppendChild(lastNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Steps 11-13. Reparent nodes from the furthest block's children
|
// Steps 15-17. Reparent nodes from the furthest block's children
|
||||||
// to a clone of the formatting element.
|
// to a clone of the formatting element.
|
||||||
clone := formattingElement.clone()
|
clone := formattingElement.clone()
|
||||||
reparentChildren(clone, furthestBlock)
|
reparentChildren(clone, furthestBlock)
|
||||||
furthestBlock.AppendChild(clone)
|
furthestBlock.AppendChild(clone)
|
||||||
|
|
||||||
// Step 14. Fix up the list of active formatting elements.
|
// Step 18. Fix up the list of active formatting elements.
|
||||||
if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
|
if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
|
||||||
// Move the bookmark with the rest of the list.
|
// Move the bookmark with the rest of the list.
|
||||||
bookmark--
|
bookmark--
|
||||||
@ -1153,13 +1153,15 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
|
|||||||
p.afe.remove(formattingElement)
|
p.afe.remove(formattingElement)
|
||||||
p.afe.insert(bookmark, clone)
|
p.afe.insert(bookmark, clone)
|
||||||
|
|
||||||
// Step 15. Fix up the stack of open elements.
|
// Step 19. Fix up the stack of open elements.
|
||||||
p.oe.remove(formattingElement)
|
p.oe.remove(formattingElement)
|
||||||
p.oe.insert(p.oe.index(furthestBlock)+1, clone)
|
p.oe.insert(p.oe.index(furthestBlock)+1, clone)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM.
|
// inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM.
|
||||||
|
// "Any other end tag" handling from 12.2.5.5 The rules for parsing tokens in foreign content
|
||||||
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inforeign
|
||||||
func (p *parser) inBodyEndTagOther(tagAtom a.Atom) {
|
func (p *parser) inBodyEndTagOther(tagAtom a.Atom) {
|
||||||
for i := len(p.oe) - 1; i >= 0; i-- {
|
for i := len(p.oe) - 1; i >= 0; i-- {
|
||||||
if p.oe[i].DataAtom == tagAtom {
|
if p.oe[i].DataAtom == tagAtom {
|
||||||
|
2
Godeps/_workspace/src/golang.org/x/net/html/render.go
generated
vendored
2
Godeps/_workspace/src/golang.org/x/net/html/render.go
generated
vendored
@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
type writer interface {
|
type writer interface {
|
||||||
io.Writer
|
io.Writer
|
||||||
WriteByte(c byte) error // in Go 1.1, use io.ByteWriter
|
io.ByteWriter
|
||||||
WriteString(string) (int, error)
|
WriteString(string) (int, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
Godeps/_workspace/src/golang.org/x/net/html/token_test.go
generated
vendored
2
Godeps/_workspace/src/golang.org/x/net/html/token_test.go
generated
vendored
@ -392,7 +392,7 @@ var tokenTests = []tokenTest{
|
|||||||
"½",
|
"½",
|
||||||
},
|
},
|
||||||
// Attribute tests:
|
// Attribute tests:
|
||||||
// http://dev.w3.org/html5/spec/Overview.html#attributes-0
|
// http://dev.w3.org/html5/pf-summary/Overview.html#attributes
|
||||||
{
|
{
|
||||||
"Empty attribute",
|
"Empty attribute",
|
||||||
`<input disabled FOO>`,
|
`<input disabled FOO>`,
|
||||||
|
19
Godeps/_workspace/src/golang.org/x/net/websocket/client.go
generated
vendored
19
Godeps/_workspace/src/golang.org/x/net/websocket/client.go
generated
vendored
@ -64,6 +64,20 @@ func Dial(url_, protocol, origin string) (ws *Conn, err error) {
|
|||||||
return DialConfig(config)
|
return DialConfig(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var portMap = map[string]string{
|
||||||
|
"ws": "80",
|
||||||
|
"wss": "443",
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseAuthority(location *url.URL) string {
|
||||||
|
if _, ok := portMap[location.Scheme]; ok {
|
||||||
|
if _, _, err := net.SplitHostPort(location.Host); err != nil {
|
||||||
|
return net.JoinHostPort(location.Host, portMap[location.Scheme])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return location.Host
|
||||||
|
}
|
||||||
|
|
||||||
// DialConfig opens a new client connection to a WebSocket with a config.
|
// DialConfig opens a new client connection to a WebSocket with a config.
|
||||||
func DialConfig(config *Config) (ws *Conn, err error) {
|
func DialConfig(config *Config) (ws *Conn, err error) {
|
||||||
var client net.Conn
|
var client net.Conn
|
||||||
@ -75,10 +89,10 @@ func DialConfig(config *Config) (ws *Conn, err error) {
|
|||||||
}
|
}
|
||||||
switch config.Location.Scheme {
|
switch config.Location.Scheme {
|
||||||
case "ws":
|
case "ws":
|
||||||
client, err = net.Dial("tcp", config.Location.Host)
|
client, err = net.Dial("tcp", parseAuthority(config.Location))
|
||||||
|
|
||||||
case "wss":
|
case "wss":
|
||||||
client, err = tls.Dial("tcp", config.Location.Host, config.TlsConfig)
|
client, err = tls.Dial("tcp", parseAuthority(config.Location), config.TlsConfig)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
err = ErrBadScheme
|
err = ErrBadScheme
|
||||||
@ -89,6 +103,7 @@ func DialConfig(config *Config) (ws *Conn, err error) {
|
|||||||
|
|
||||||
ws, err = NewClient(config, client)
|
ws, err = NewClient(config, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
client.Close()
|
||||||
goto Error
|
goto Error
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
50
Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go
generated
vendored
50
Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go
generated
vendored
@ -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:
|
case PingFrame, PongFrame:
|
||||||
pingMsg := make([]byte, maxControlFramePayloadLength)
|
b := make([]byte, maxControlFramePayloadLength)
|
||||||
n, err := io.ReadFull(frame, pingMsg)
|
n, err := io.ReadFull(frame, b)
|
||||||
if err != nil && err != io.ErrUnexpectedEOF {
|
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 frame.PayloadType() == PingFrame {
|
||||||
if err != nil {
|
if _, err := handler.WritePong(b[:n]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
case PongFrame:
|
|
||||||
return nil, ErrNotImplemented
|
|
||||||
}
|
}
|
||||||
return frame, nil
|
return frame, nil
|
||||||
}
|
}
|
||||||
@ -370,6 +372,23 @@ func generateNonce() (nonce []byte) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// removeZone removes IPv6 zone identifer from host.
|
||||||
|
// E.g., "[fe80::1%en0]:8080" to "[fe80::1]:8080"
|
||||||
|
func removeZone(host string) string {
|
||||||
|
if !strings.HasPrefix(host, "[") {
|
||||||
|
return host
|
||||||
|
}
|
||||||
|
i := strings.LastIndex(host, "]")
|
||||||
|
if i < 0 {
|
||||||
|
return host
|
||||||
|
}
|
||||||
|
j := strings.LastIndex(host[:i], "%")
|
||||||
|
if j < 0 {
|
||||||
|
return host
|
||||||
|
}
|
||||||
|
return host[:j] + host[i:]
|
||||||
|
}
|
||||||
|
|
||||||
// getNonceAccept computes the base64-encoded SHA-1 of the concatenation of
|
// getNonceAccept computes the base64-encoded SHA-1 of the concatenation of
|
||||||
// the nonce ("Sec-WebSocket-Key" value) with the websocket GUID string.
|
// the nonce ("Sec-WebSocket-Key" value) with the websocket GUID string.
|
||||||
func getNonceAccept(nonce []byte) (expected []byte, err error) {
|
func getNonceAccept(nonce []byte) (expected []byte, err error) {
|
||||||
@ -389,7 +408,10 @@ func getNonceAccept(nonce []byte) (expected []byte, err error) {
|
|||||||
func hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (err error) {
|
func hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (err error) {
|
||||||
bw.WriteString("GET " + config.Location.RequestURI() + " HTTP/1.1\r\n")
|
bw.WriteString("GET " + config.Location.RequestURI() + " HTTP/1.1\r\n")
|
||||||
|
|
||||||
bw.WriteString("Host: " + config.Location.Host + "\r\n")
|
// According to RFC 6874, an HTTP client, proxy, or other
|
||||||
|
// intermediary must remove any IPv6 zone identifier attached
|
||||||
|
// to an outgoing URI.
|
||||||
|
bw.WriteString("Host: " + removeZone(config.Location.Host) + "\r\n")
|
||||||
bw.WriteString("Upgrade: websocket\r\n")
|
bw.WriteString("Upgrade: websocket\r\n")
|
||||||
bw.WriteString("Connection: Upgrade\r\n")
|
bw.WriteString("Connection: Upgrade\r\n")
|
||||||
nonce := generateNonce()
|
nonce := generateNonce()
|
||||||
@ -515,15 +537,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".
|
// Origin parses the Origin header in req.
|
||||||
// If origin is "null", returns (nil, nil).
|
// 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)
|
||||||
|
124
Godeps/_workspace/src/golang.org/x/net/websocket/hybi_test.go
generated
vendored
124
Godeps/_workspace/src/golang.org/x/net/websocket/hybi_test.go
generated
vendored
@ -31,63 +31,74 @@ func TestSecWebSocketAccept(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestHybiClientHandshake(t *testing.T) {
|
func TestHybiClientHandshake(t *testing.T) {
|
||||||
b := bytes.NewBuffer([]byte{})
|
type test struct {
|
||||||
bw := bufio.NewWriter(b)
|
url, host string
|
||||||
br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols
|
}
|
||||||
|
tests := []test{
|
||||||
|
{"ws://server.example.com/chat", "server.example.com"},
|
||||||
|
{"ws://127.0.0.1/chat", "127.0.0.1"},
|
||||||
|
}
|
||||||
|
if _, err := url.ParseRequestURI("http://[fe80::1%25lo0]"); err == nil {
|
||||||
|
tests = append(tests, test{"ws://[fe80::1%25lo0]/chat", "[fe80::1]"})
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
var b bytes.Buffer
|
||||||
|
bw := bufio.NewWriter(&b)
|
||||||
|
br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols
|
||||||
Upgrade: websocket
|
Upgrade: websocket
|
||||||
Connection: Upgrade
|
Connection: Upgrade
|
||||||
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
|
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
|
||||||
Sec-WebSocket-Protocol: chat
|
Sec-WebSocket-Protocol: chat
|
||||||
|
|
||||||
`))
|
`))
|
||||||
var err error
|
var err error
|
||||||
config := new(Config)
|
var config Config
|
||||||
config.Location, err = url.ParseRequestURI("ws://server.example.com/chat")
|
config.Location, err = url.ParseRequestURI(tt.url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("location url", err)
|
t.Fatal("location url", err)
|
||||||
}
|
}
|
||||||
config.Origin, err = url.ParseRequestURI("http://example.com")
|
config.Origin, err = url.ParseRequestURI("http://example.com")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("origin url", err)
|
t.Fatal("origin url", err)
|
||||||
}
|
}
|
||||||
config.Protocol = append(config.Protocol, "chat")
|
config.Protocol = append(config.Protocol, "chat")
|
||||||
config.Protocol = append(config.Protocol, "superchat")
|
config.Protocol = append(config.Protocol, "superchat")
|
||||||
config.Version = ProtocolVersionHybi13
|
config.Version = ProtocolVersionHybi13
|
||||||
|
config.handshakeData = map[string]string{
|
||||||
config.handshakeData = map[string]string{
|
"key": "dGhlIHNhbXBsZSBub25jZQ==",
|
||||||
"key": "dGhlIHNhbXBsZSBub25jZQ==",
|
}
|
||||||
}
|
if err := hybiClientHandshake(&config, br, bw); err != nil {
|
||||||
err = hybiClientHandshake(config, br, bw)
|
t.Fatal("handshake", err)
|
||||||
if err != nil {
|
}
|
||||||
t.Errorf("handshake failed: %v", err)
|
req, err := http.ReadRequest(bufio.NewReader(&b))
|
||||||
}
|
if err != nil {
|
||||||
req, err := http.ReadRequest(bufio.NewReader(b))
|
t.Fatal("read request", err)
|
||||||
if err != nil {
|
}
|
||||||
t.Fatalf("read request: %v", err)
|
if req.Method != "GET" {
|
||||||
}
|
t.Errorf("request method expected GET, but got %s", req.Method)
|
||||||
if req.Method != "GET" {
|
}
|
||||||
t.Errorf("request method expected GET, but got %q", req.Method)
|
if req.URL.Path != "/chat" {
|
||||||
}
|
t.Errorf("request path expected /chat, but got %s", req.URL.Path)
|
||||||
if req.URL.Path != "/chat" {
|
}
|
||||||
t.Errorf("request path expected /chat, but got %q", req.URL.Path)
|
if req.Proto != "HTTP/1.1" {
|
||||||
}
|
t.Errorf("request proto expected HTTP/1.1, but got %s", req.Proto)
|
||||||
if req.Proto != "HTTP/1.1" {
|
}
|
||||||
t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
|
if req.Host != tt.host {
|
||||||
}
|
t.Errorf("request host expected %s, but got %s", tt.host, req.Host)
|
||||||
if req.Host != "server.example.com" {
|
}
|
||||||
t.Errorf("request Host expected server.example.com, but got %v", req.Host)
|
var expectedHeader = map[string]string{
|
||||||
}
|
"Connection": "Upgrade",
|
||||||
var expectedHeader = map[string]string{
|
"Upgrade": "websocket",
|
||||||
"Connection": "Upgrade",
|
"Sec-Websocket-Key": config.handshakeData["key"],
|
||||||
"Upgrade": "websocket",
|
"Origin": config.Origin.String(),
|
||||||
"Sec-Websocket-Key": config.handshakeData["key"],
|
"Sec-Websocket-Protocol": "chat, superchat",
|
||||||
"Origin": config.Origin.String(),
|
"Sec-Websocket-Version": fmt.Sprintf("%d", ProtocolVersionHybi13),
|
||||||
"Sec-Websocket-Protocol": "chat, superchat",
|
}
|
||||||
"Sec-Websocket-Version": fmt.Sprintf("%d", ProtocolVersionHybi13),
|
for k, v := range expectedHeader {
|
||||||
}
|
if req.Header.Get(k) != v {
|
||||||
for k, v := range expectedHeader {
|
t.Errorf("%s expected %s, but got %v", k, v, req.Header.Get(k))
|
||||||
if req.Header.Get(k) != v {
|
}
|
||||||
t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -326,7 +337,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 +374,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)
|
||||||
|
5
Godeps/_workspace/src/golang.org/x/net/websocket/server.go
generated
vendored
5
Godeps/_workspace/src/golang.org/x/net/websocket/server.go
generated
vendored
@ -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
|
||||||
@ -95,8 +94,8 @@ func (s Server) serveWebSocket(w http.ResponseWriter, req *http.Request) {
|
|||||||
// You might want to verify websocket.Conn.Config().Origin in the func.
|
// You might want to verify websocket.Conn.Config().Origin in the func.
|
||||||
// If you use Server instead of Handler, you could call websocket.Origin and
|
// If you use Server instead of Handler, you could call websocket.Origin and
|
||||||
// check the origin in your Handshake func. So, if you want to accept
|
// check the origin in your Handshake func. So, if you want to accept
|
||||||
// non-browser client, which doesn't send Origin header, you could use Server
|
// non-browser clients, which do not send an Origin header, set a
|
||||||
//. that doesn't check origin in its Handshake.
|
// Server.Handshake that does not check the origin.
|
||||||
type Handler func(*Conn)
|
type Handler func(*Conn)
|
||||||
|
|
||||||
func checkOrigin(config *Config, req *http.Request) (err error) {
|
func checkOrigin(config *Config, req *http.Request) (err error) {
|
||||||
|
3
Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go
generated
vendored
3
Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go
generated
vendored
@ -216,10 +216,11 @@ func (ws *Conn) Write(msg []byte) (n int, err error) {
|
|||||||
// Close implements the io.Closer interface.
|
// Close implements the io.Closer interface.
|
||||||
func (ws *Conn) Close() error {
|
func (ws *Conn) Close() error {
|
||||||
err := ws.frameHandler.WriteClose(ws.defaultCloseStatus)
|
err := ws.frameHandler.WriteClose(ws.defaultCloseStatus)
|
||||||
|
err1 := ws.rwc.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return ws.rwc.Close()
|
return err1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ws *Conn) IsClientConn() bool { return ws.request == nil }
|
func (ws *Conn) IsClientConn() bool { return ws.request == nil }
|
||||||
|
248
Godeps/_workspace/src/golang.org/x/net/websocket/websocket_test.go
generated
vendored
248
Godeps/_workspace/src/golang.org/x/net/websocket/websocket_test.go
generated
vendored
@ -13,15 +13,21 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
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
|
||||||
@ -29,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)
|
||||||
@ -44,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" {
|
||||||
@ -63,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),
|
||||||
@ -339,3 +396,192 @@ func TestSmallBuffer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
conn.Close()
|
conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var parseAuthorityTests = []struct {
|
||||||
|
in *url.URL
|
||||||
|
out string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
&url.URL{
|
||||||
|
Scheme: "ws",
|
||||||
|
Host: "www.google.com",
|
||||||
|
},
|
||||||
|
"www.google.com:80",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&url.URL{
|
||||||
|
Scheme: "wss",
|
||||||
|
Host: "www.google.com",
|
||||||
|
},
|
||||||
|
"www.google.com:443",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&url.URL{
|
||||||
|
Scheme: "ws",
|
||||||
|
Host: "www.google.com:80",
|
||||||
|
},
|
||||||
|
"www.google.com:80",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&url.URL{
|
||||||
|
Scheme: "wss",
|
||||||
|
Host: "www.google.com:443",
|
||||||
|
},
|
||||||
|
"www.google.com:443",
|
||||||
|
},
|
||||||
|
// some invalid ones for parseAuthority. parseAuthority doesn't
|
||||||
|
// concern itself with the scheme unless it actually knows about it
|
||||||
|
{
|
||||||
|
&url.URL{
|
||||||
|
Scheme: "http",
|
||||||
|
Host: "www.google.com",
|
||||||
|
},
|
||||||
|
"www.google.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&url.URL{
|
||||||
|
Scheme: "http",
|
||||||
|
Host: "www.google.com:80",
|
||||||
|
},
|
||||||
|
"www.google.com:80",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&url.URL{
|
||||||
|
Scheme: "asdf",
|
||||||
|
Host: "127.0.0.1",
|
||||||
|
},
|
||||||
|
"127.0.0.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&url.URL{
|
||||||
|
Scheme: "asdf",
|
||||||
|
Host: "www.google.com",
|
||||||
|
},
|
||||||
|
"www.google.com",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseAuthority(t *testing.T) {
|
||||||
|
for _, tt := range parseAuthorityTests {
|
||||||
|
out := parseAuthority(tt.in)
|
||||||
|
if out != tt.out {
|
||||||
|
t.Errorf("got %v; want %v", out, tt.out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type closerConn struct {
|
||||||
|
net.Conn
|
||||||
|
closed int // count of the number of times Close was called
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *closerConn) Close() error {
|
||||||
|
c.closed++
|
||||||
|
return c.Conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClose(t *testing.T) {
|
||||||
|
if runtime.GOOS == "plan9" {
|
||||||
|
t.Skip("see golang.org/issue/11454")
|
||||||
|
}
|
||||||
|
|
||||||
|
once.Do(startServer)
|
||||||
|
|
||||||
|
conn, err := net.Dial("tcp", serverAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("dialing", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cc := closerConn{Conn: conn}
|
||||||
|
|
||||||
|
client, err := NewClient(newConfig(t, "/echo"), &cc)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("WebSocket handshake: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the deadline to ten minutes ago, which will have expired by the time
|
||||||
|
// client.Close sends the close status frame.
|
||||||
|
conn.SetDeadline(time.Now().Add(-10 * time.Minute))
|
||||||
|
|
||||||
|
if err := client.Close(); err == nil {
|
||||||
|
t.Errorf("ws.Close(): expected error, got %v", err)
|
||||||
|
}
|
||||||
|
if cc.closed < 1 {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user