mirror of
https://github.com/golang/go
synced 2024-11-22 02:34:40 -07:00
simplify various code using new map index rule
R=r CC=golang-dev https://golang.org/cl/833044
This commit is contained in:
parent
6962e2b754
commit
c7122a3c58
@ -682,8 +682,8 @@ func (x *Index) Size() (nwords int, nspots int) {
|
|||||||
|
|
||||||
|
|
||||||
func (x *Index) LookupWord(w string) (match *LookupResult, alt *AltWords) {
|
func (x *Index) LookupWord(w string) (match *LookupResult, alt *AltWords) {
|
||||||
match, _ = x.words[w]
|
match = x.words[w]
|
||||||
alt, _ = x.alts[canonical(w)]
|
alt = x.alts[canonical(w)]
|
||||||
// remove current spelling from alternatives
|
// remove current spelling from alternatives
|
||||||
// (if there is no match, the alternatives do
|
// (if there is no match, the alternatives do
|
||||||
// not contain the current spelling)
|
// not contain the current spelling)
|
||||||
|
@ -85,7 +85,7 @@ func printDeps(pkg string) {
|
|||||||
// install installs the package named by path, which is needed by parent.
|
// install installs the package named by path, which is needed by parent.
|
||||||
func install(pkg, parent string) {
|
func install(pkg, parent string) {
|
||||||
// Make sure we're not already trying to install pkg.
|
// Make sure we're not already trying to install pkg.
|
||||||
switch v, _ := visit[pkg]; v {
|
switch visit[pkg] {
|
||||||
case done:
|
case done:
|
||||||
return
|
return
|
||||||
case visiting:
|
case visiting:
|
||||||
|
@ -62,20 +62,20 @@ func main() {
|
|||||||
// Make sure we won't be editing files with local pending changes.
|
// Make sure we won't be editing files with local pending changes.
|
||||||
dirtylist, err := hgModified()
|
dirtylist, err := hgModified()
|
||||||
chk(err)
|
chk(err)
|
||||||
dirty := make(map[string]int)
|
dirty := make(map[string]bool)
|
||||||
for _, f := range dirtylist {
|
for _, f := range dirtylist {
|
||||||
dirty[f] = 1
|
dirty[f] = true
|
||||||
}
|
}
|
||||||
conflict := make(map[string]int)
|
conflict := make(map[string]bool)
|
||||||
for _, f := range pset.File {
|
for _, f := range pset.File {
|
||||||
if f.Verb == patch.Delete || f.Verb == patch.Rename {
|
if f.Verb == patch.Delete || f.Verb == patch.Rename {
|
||||||
if _, ok := dirty[f.Src]; ok {
|
if dirty[f.Src] {
|
||||||
conflict[f.Src] = 1
|
conflict[f.Src] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if f.Verb != patch.Delete {
|
if f.Verb != patch.Delete {
|
||||||
if _, ok := dirty[f.Dst]; ok {
|
if dirty[f.Dst] {
|
||||||
conflict[f.Dst] = 1
|
conflict[f.Dst] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,9 +149,9 @@ func TestRemove2(t *testing.T) {
|
|||||||
}
|
}
|
||||||
h.verify(t, 0)
|
h.verify(t, 0)
|
||||||
|
|
||||||
m := make(map[int]int)
|
m := make(map[int]bool)
|
||||||
for h.Len() > 0 {
|
for h.Len() > 0 {
|
||||||
m[Remove(h, (h.Len()-1)/2).(int)] = 1
|
m[Remove(h, (h.Len()-1)/2).(int)] = true
|
||||||
h.verify(t, 0)
|
h.verify(t, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ func TestRemove2(t *testing.T) {
|
|||||||
t.Errorf("len(m) = %d; want %d", len(m), N)
|
t.Errorf("len(m) = %d; want %d", len(m), N)
|
||||||
}
|
}
|
||||||
for i := 0; i < len(m); i++ {
|
for i := 0; i < len(m); i++ {
|
||||||
if _, exists := m[i]; !exists {
|
if !m[i] {
|
||||||
t.Errorf("m[%d] doesn't exist", i)
|
t.Errorf("m[%d] doesn't exist", i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,18 +29,10 @@ func nameToKey(name *x509.Name) string {
|
|||||||
// FindParent attempts to find the certificate in s which signs the given
|
// FindParent attempts to find the certificate in s which signs the given
|
||||||
// certificate. If no such certificate can be found, it returns nil.
|
// certificate. If no such certificate can be found, it returns nil.
|
||||||
func (s *CASet) FindParent(cert *x509.Certificate) (parent *x509.Certificate) {
|
func (s *CASet) FindParent(cert *x509.Certificate) (parent *x509.Certificate) {
|
||||||
var ok bool
|
|
||||||
|
|
||||||
if len(cert.AuthorityKeyId) > 0 {
|
if len(cert.AuthorityKeyId) > 0 {
|
||||||
parent, ok = s.bySubjectKeyId[string(cert.AuthorityKeyId)]
|
return s.bySubjectKeyId[string(cert.AuthorityKeyId)]
|
||||||
} else {
|
|
||||||
parent, ok = s.byName[nameToKey(&cert.Issuer)]
|
|
||||||
}
|
}
|
||||||
|
return s.byName[nameToKey(&cert.Issuer)]
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return parent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFromPEM attempts to parse a series of PEM encoded root certificates. It
|
// SetFromPEM attempts to parse a series of PEM encoded root certificates. It
|
||||||
|
@ -87,7 +87,7 @@ func testTypedefs(t *testing.T, d *Data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if want, ok := typedefTests[t1.Name]; ok {
|
if want, ok := typedefTests[t1.Name]; ok {
|
||||||
if _, ok := seen[t1.Name]; ok {
|
if seen[t1.Name] {
|
||||||
t.Errorf("multiple definitions for %s", t1.Name)
|
t.Errorf("multiple definitions for %s", t1.Name)
|
||||||
}
|
}
|
||||||
seen[t1.Name] = true
|
seen[t1.Name] = true
|
||||||
@ -102,7 +102,7 @@ func testTypedefs(t *testing.T, d *Data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for k := range typedefTests {
|
for k := range typedefTests {
|
||||||
if _, ok := seen[k]; !ok {
|
if !seen[k] {
|
||||||
t.Errorf("missing %s", k)
|
t.Errorf("missing %s", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -845,7 +845,7 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't check the same type twice and avoid loops
|
// Don't check the same type twice and avoid loops
|
||||||
if _, ok := visited[t]; ok {
|
if visited[t] {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
visited[t] = true
|
visited[t] = true
|
||||||
|
@ -119,7 +119,7 @@ nextEnt:
|
|||||||
|
|
||||||
func (m typeArrayMap) Put(key []Type, v interface{}) interface{} {
|
func (m typeArrayMap) Put(key []Type, v interface{}) interface{} {
|
||||||
hash := hashTypeArray(key)
|
hash := hashTypeArray(key)
|
||||||
ent, _ := m[hash]
|
ent := m[hash]
|
||||||
|
|
||||||
new := &typeArrayMapEntry{key, v, ent}
|
new := &typeArrayMapEntry{key, v, ent}
|
||||||
m[hash] = new
|
m[hash] = new
|
||||||
|
@ -539,10 +539,7 @@ type evalMap map[interface{}]Value
|
|||||||
func (m evalMap) Len(t *Thread) int64 { return int64(len(m)) }
|
func (m evalMap) Len(t *Thread) int64 { return int64(len(m)) }
|
||||||
|
|
||||||
func (m evalMap) Elem(t *Thread, key interface{}) Value {
|
func (m evalMap) Elem(t *Thread, key interface{}) Value {
|
||||||
if v, ok := m[key]; ok {
|
return m[key]
|
||||||
return v
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m evalMap) SetElem(t *Thread, key interface{}, val Value) {
|
func (m evalMap) SetElem(t *Thread, key interface{}, val Value) {
|
||||||
|
@ -38,7 +38,7 @@ func newManualType(t eval.Type, arch Arch) *remoteType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the type map for this architecture
|
// Get the type map for this architecture
|
||||||
typeMap, _ := manualTypes[arch]
|
typeMap := manualTypes[arch]
|
||||||
if typeMap == nil {
|
if typeMap == nil {
|
||||||
typeMap = make(map[eval.Type]*remoteType)
|
typeMap = make(map[eval.Type]*remoteType)
|
||||||
manualTypes[arch] = typeMap
|
manualTypes[arch] = typeMap
|
||||||
|
@ -87,10 +87,7 @@ func (v *Map) Init() *Map {
|
|||||||
func (v *Map) Get(key string) Var {
|
func (v *Map) Get(key string) Var {
|
||||||
v.mu.Lock()
|
v.mu.Lock()
|
||||||
defer v.mu.Unlock()
|
defer v.mu.Unlock()
|
||||||
if av, ok := v.m[key]; ok {
|
return v.m[key]
|
||||||
return av
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Map) Set(key string, av Var) {
|
func (v *Map) Set(key string, av Var) {
|
||||||
@ -168,10 +165,7 @@ func Publish(name string, v Var) {
|
|||||||
|
|
||||||
// Get retrieves a named exported variable.
|
// Get retrieves a named exported variable.
|
||||||
func Get(name string) Var {
|
func Get(name string) Var {
|
||||||
if v, ok := vars[name]; ok {
|
return vars[name]
|
||||||
return v
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveAll removes all exported variables.
|
// RemoveAll removes all exported variables.
|
||||||
|
@ -239,11 +239,7 @@ func Visit(fn func(*Flag)) {
|
|||||||
|
|
||||||
// Lookup returns the Flag structure of the named flag, returning nil if none exists.
|
// Lookup returns the Flag structure of the named flag, returning nil if none exists.
|
||||||
func Lookup(name string) *Flag {
|
func Lookup(name string) *Flag {
|
||||||
f, ok := flags.formal[name]
|
return flags.formal[name]
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return f
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set sets the value of the named flag. It returns true if the set succeeded; false if
|
// Set sets the value of the named flag. It returns true if the set succeeded; false if
|
||||||
|
@ -91,8 +91,8 @@ func TestParse4(t *testing.T) {
|
|||||||
if len(pkgs) != 1 {
|
if len(pkgs) != 1 {
|
||||||
t.Errorf("incorrect number of packages: %d", len(pkgs))
|
t.Errorf("incorrect number of packages: %d", len(pkgs))
|
||||||
}
|
}
|
||||||
pkg, found := pkgs["parser"]
|
pkg := pkgs["parser"]
|
||||||
if pkg == nil || !found {
|
if pkg == nil {
|
||||||
t.Errorf(`package "parser" not found`)
|
t.Errorf(`package "parser" not found`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func NewDecoder(r io.Reader) *Decoder {
|
|||||||
|
|
||||||
func (dec *Decoder) recvType(id typeId) {
|
func (dec *Decoder) recvType(id typeId) {
|
||||||
// Have we already seen this type? That's an error
|
// Have we already seen this type? That's an error
|
||||||
if _, alreadySeen := dec.wireType[id]; alreadySeen {
|
if dec.wireType[id] != nil {
|
||||||
dec.state.err = os.ErrorString("gob: duplicate type received")
|
dec.state.err = os.ErrorString("gob: duplicate type received")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -109,8 +109,7 @@ func (dec *Decoder) Decode(e interface{}) os.Error {
|
|||||||
|
|
||||||
// No, it's a value.
|
// No, it's a value.
|
||||||
// Make sure the type has been defined already.
|
// Make sure the type has been defined already.
|
||||||
_, ok := dec.wireType[id]
|
if dec.wireType[id] == nil {
|
||||||
if !ok {
|
|
||||||
dec.state.err = errBadType
|
dec.state.err = errBadType
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ func newArrayType(name string, elem gobType, length int) *arrayType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *arrayType) safeString(seen map[typeId]bool) string {
|
func (a *arrayType) safeString(seen map[typeId]bool) string {
|
||||||
if _, ok := seen[a._id]; ok {
|
if seen[a._id] {
|
||||||
return a.name
|
return a.name
|
||||||
}
|
}
|
||||||
seen[a._id] = true
|
seen[a._id] = true
|
||||||
@ -155,7 +155,7 @@ func newSliceType(name string, elem gobType) *sliceType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *sliceType) safeString(seen map[typeId]bool) string {
|
func (s *sliceType) safeString(seen map[typeId]bool) string {
|
||||||
if _, ok := seen[s._id]; ok {
|
if seen[s._id] {
|
||||||
return s.name
|
return s.name
|
||||||
}
|
}
|
||||||
seen[s._id] = true
|
seen[s._id] = true
|
||||||
|
@ -49,13 +49,13 @@ type badStringError struct {
|
|||||||
|
|
||||||
func (e *badStringError) String() string { return fmt.Sprintf("%s %q", e.what, e.str) }
|
func (e *badStringError) String() string { return fmt.Sprintf("%s %q", e.what, e.str) }
|
||||||
|
|
||||||
var reqExcludeHeader = map[string]int{
|
var reqExcludeHeader = map[string]bool{
|
||||||
"Host": 0,
|
"Host": true,
|
||||||
"User-Agent": 0,
|
"User-Agent": true,
|
||||||
"Referer": 0,
|
"Referer": true,
|
||||||
"Content-Length": 0,
|
"Content-Length": true,
|
||||||
"Transfer-Encoding": 0,
|
"Transfer-Encoding": true,
|
||||||
"Trailer": 0,
|
"Trailer": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Request represents a parsed HTTP request header.
|
// A Request represents a parsed HTTP request header.
|
||||||
@ -518,24 +518,19 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) {
|
|||||||
// Host: doesntmatter
|
// Host: doesntmatter
|
||||||
// the same. In the second case, any Host line is ignored.
|
// the same. In the second case, any Host line is ignored.
|
||||||
req.Host = req.URL.Host
|
req.Host = req.URL.Host
|
||||||
if v, present := req.Header["Host"]; present {
|
if req.Host == "" {
|
||||||
if req.Host == "" {
|
req.Host = req.Header["Host"]
|
||||||
req.Host = v
|
|
||||||
}
|
|
||||||
req.Header["Host"] = "", false
|
|
||||||
}
|
}
|
||||||
|
req.Header["Host"] = "", false
|
||||||
|
|
||||||
fixPragmaCacheControl(req.Header)
|
fixPragmaCacheControl(req.Header)
|
||||||
|
|
||||||
// Pull out useful fields as a convenience to clients.
|
// Pull out useful fields as a convenience to clients.
|
||||||
if v, present := req.Header["Referer"]; present {
|
req.Referer = req.Header["Referer"]
|
||||||
req.Referer = v
|
req.Header["Referer"] = "", false
|
||||||
req.Header["Referer"] = "", false
|
|
||||||
}
|
req.UserAgent = req.Header["User-Agent"]
|
||||||
if v, present := req.Header["User-Agent"]; present {
|
req.Header["User-Agent"] = "", false
|
||||||
req.UserAgent = v
|
|
||||||
req.Header["User-Agent"] = "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Parse specific header values:
|
// TODO: Parse specific header values:
|
||||||
// Accept
|
// Accept
|
||||||
@ -572,7 +567,7 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseQuery(query string) (m map[string][]string, err os.Error) {
|
func ParseQuery(query string) (m map[string][]string, err os.Error) {
|
||||||
data := make(map[string]*vector.StringVector)
|
m = make(map[string][]string)
|
||||||
for _, kv := range strings.Split(query, "&", 0) {
|
for _, kv := range strings.Split(query, "&", 0) {
|
||||||
kvPair := strings.Split(kv, "=", 2)
|
kvPair := strings.Split(kv, "=", 2)
|
||||||
|
|
||||||
@ -586,17 +581,9 @@ func ParseQuery(query string) (m map[string][]string, err os.Error) {
|
|||||||
err = e
|
err = e
|
||||||
}
|
}
|
||||||
|
|
||||||
vec, ok := data[key]
|
vec := vector.StringVector(m[key])
|
||||||
if !ok {
|
|
||||||
vec = new(vector.StringVector)
|
|
||||||
data[key] = vec
|
|
||||||
}
|
|
||||||
vec.Push(value)
|
vec.Push(value)
|
||||||
}
|
m[key] = vec
|
||||||
|
|
||||||
m = make(map[string][]string)
|
|
||||||
for k, vec := range data {
|
|
||||||
m[k] = vec.Data()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@ -618,7 +605,7 @@ func (r *Request) ParseForm() (err os.Error) {
|
|||||||
r.Form = make(map[string][]string)
|
r.Form = make(map[string][]string)
|
||||||
return os.ErrorString("missing form body")
|
return os.ErrorString("missing form body")
|
||||||
}
|
}
|
||||||
ct, _ := r.Header["Content-Type"]
|
ct := r.Header["Content-Type"]
|
||||||
switch strings.Split(ct, ";", 2)[0] {
|
switch strings.Split(ct, ";", 2)[0] {
|
||||||
case "text/plain", "application/x-www-form-urlencoded", "":
|
case "text/plain", "application/x-www-form-urlencoded", "":
|
||||||
var b []byte
|
var b []byte
|
||||||
@ -643,7 +630,7 @@ func (r *Request) FormValue(key string) string {
|
|||||||
if r.Form == nil {
|
if r.Form == nil {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
}
|
}
|
||||||
if vs, ok := r.Form[key]; ok && len(vs) > 0 {
|
if vs := r.Form[key]; len(vs) > 0 {
|
||||||
return vs[0]
|
return vs[0]
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
@ -16,10 +16,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var respExcludeHeader = map[string]int{
|
var respExcludeHeader = map[string]bool{
|
||||||
"Content-Length": 0,
|
"Content-Length": true,
|
||||||
"Transfer-Encoding": 0,
|
"Transfer-Encoding": true,
|
||||||
"Trailer": 0,
|
"Trailer": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Response represents the response from an HTTP request.
|
// Response represents the response from an HTTP request.
|
||||||
@ -133,7 +133,7 @@ func ReadResponse(r *bufio.Reader, requestMethod string) (resp *Response, err os
|
|||||||
// like
|
// like
|
||||||
// Cache-Control: no-cache
|
// Cache-Control: no-cache
|
||||||
func fixPragmaCacheControl(header map[string]string) {
|
func fixPragmaCacheControl(header map[string]string) {
|
||||||
if v, present := header["Pragma"]; present && v == "no-cache" {
|
if header["Pragma"] == "no-cache" {
|
||||||
if _, presentcc := header["Cache-Control"]; !presentcc {
|
if _, presentcc := header["Cache-Control"]; !presentcc {
|
||||||
header["Cache-Control"] = "no-cache"
|
header["Cache-Control"] = "no-cache"
|
||||||
}
|
}
|
||||||
@ -157,8 +157,7 @@ func (r *Response) AddHeader(key, value string) {
|
|||||||
// with a comma delimiter. If there were no response headers with the given
|
// with a comma delimiter. If there were no response headers with the given
|
||||||
// key, GetHeader returns an empty string. Keys are not case sensitive.
|
// key, GetHeader returns an empty string. Keys are not case sensitive.
|
||||||
func (r *Response) GetHeader(key string) (value string) {
|
func (r *Response) GetHeader(key string) (value string) {
|
||||||
value, _ = r.Header[CanonicalHeaderKey(key)]
|
return r.Header[CanonicalHeaderKey(key)]
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProtoAtLeast returns whether the HTTP protocol used
|
// ProtoAtLeast returns whether the HTTP protocol used
|
||||||
@ -228,11 +227,11 @@ func (resp *Response) Write(w io.Writer) os.Error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeSortedKeyValue(w io.Writer, kvm map[string]string, exclude map[string]int) os.Error {
|
func writeSortedKeyValue(w io.Writer, kvm map[string]string, exclude map[string]bool) os.Error {
|
||||||
kva := make([]string, len(kvm))
|
kva := make([]string, len(kvm))
|
||||||
i := 0
|
i := 0
|
||||||
for k, v := range kvm {
|
for k, v := range kvm {
|
||||||
if _, exc := exclude[k]; !exc {
|
if !exclude[k] {
|
||||||
kva[i] = fmt.Sprint(k + ": " + v + "\r\n")
|
kva[i] = fmt.Sprint(k + ": " + v + "\r\n")
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
@ -340,11 +340,8 @@ func fixLength(status int, requestMethod string, header map[string]string, te []
|
|||||||
// Logic based on media type. The purpose of the following code is just
|
// Logic based on media type. The purpose of the following code is just
|
||||||
// to detect whether the unsupported "multipart/byteranges" is being
|
// to detect whether the unsupported "multipart/byteranges" is being
|
||||||
// used. A proper Content-Type parser is needed in the future.
|
// used. A proper Content-Type parser is needed in the future.
|
||||||
if ct, present := header["Content-Type"]; present {
|
if strings.Index(strings.ToLower(header["Content-Type"]), "multipart/byteranges") >= 0 {
|
||||||
ct = strings.ToLower(ct)
|
return -1, ErrNotSupported
|
||||||
if strings.Index(ct, "multipart/byteranges") >= 0 {
|
|
||||||
return -1, ErrNotSupported
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Body-EOF logic based on other methods (like closing, or chunked coding)
|
// Body-EOF logic based on other methods (like closing, or chunked coding)
|
||||||
|
@ -78,6 +78,5 @@ func initMime() {
|
|||||||
// When ext has no associated type, TypeByExtension returns "".
|
// When ext has no associated type, TypeByExtension returns "".
|
||||||
func TypeByExtension(ext string) string {
|
func TypeByExtension(ext string) string {
|
||||||
once.Do(initMime)
|
once.Do(initMime)
|
||||||
typ, _ := mimeTypes[ext]
|
return mimeTypes[ext]
|
||||||
return typ
|
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,7 @@ func readHosts() {
|
|||||||
}
|
}
|
||||||
for i := 1; i < len(f); i++ {
|
for i := 1; i < len(f); i++ {
|
||||||
h := f[i]
|
h := f[i]
|
||||||
old, _ := hs[h]
|
hs[h] = appendHost(hs[h], f[0])
|
||||||
hs[h] = appendHost(old, f[0])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update the data cache.
|
// Update the data cache.
|
||||||
|
@ -38,8 +38,8 @@ var joblock sync.Mutex
|
|||||||
// func each time f runs, and each of those funcs is run once.
|
// func each time f runs, and each of those funcs is run once.
|
||||||
func Do(f func()) {
|
func Do(f func()) {
|
||||||
joblock.Lock()
|
joblock.Lock()
|
||||||
j, present := jobs[f]
|
j := jobs[f]
|
||||||
if !present {
|
if j == nil {
|
||||||
// run it
|
// run it
|
||||||
j = new(job)
|
j = new(job)
|
||||||
j.Lock()
|
j.Lock()
|
||||||
|
@ -45,7 +45,7 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool {
|
|||||||
|
|
||||||
// ... or already seen
|
// ... or already seen
|
||||||
h := 17*addr1 + addr2
|
h := 17*addr1 + addr2
|
||||||
seen, _ := visited[h]
|
seen := visited[h]
|
||||||
typ := v1.Type()
|
typ := v1.Type()
|
||||||
for p := seen; p != nil; p = p.next {
|
for p := seen; p != nil; p = p.next {
|
||||||
if p.a1 == addr1 && p.a2 == addr2 && p.typ == typ {
|
if p.a1 == addr1 && p.a2 == addr2 && p.typ == typ {
|
||||||
|
@ -510,7 +510,7 @@ const inf = 1 << 30 // infinity - no struct has that many nesting levels
|
|||||||
func (t *StructType) fieldByName(name string, mark map[*StructType]bool, depth int) (ff StructField, fd int) {
|
func (t *StructType) fieldByName(name string, mark map[*StructType]bool, depth int) (ff StructField, fd int) {
|
||||||
fd = inf // field depth
|
fd = inf // field depth
|
||||||
|
|
||||||
if _, marked := mark[t]; marked {
|
if mark[t] {
|
||||||
// Struct already seen.
|
// Struct already seen.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,10 @@ type ProtocolError struct {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
ErrBadStatus = &ProtocolError{"bad status"}
|
ErrBadStatus = &ProtocolError{"bad status"}
|
||||||
ErrNoUpgrade = &ProtocolError{"no upgrade"}
|
ErrBadUpgrade = &ProtocolError{"missing or bad upgrade"}
|
||||||
ErrBadUpgrade = &ProtocolError{"bad upgrade"}
|
ErrBadWebSocketOrigin = &ProtocolError{"missing or bad WebSocket-Origin"}
|
||||||
ErrNoWebSocketOrigin = &ProtocolError{"no WebSocket-Origin"}
|
ErrBadWebSocketLocation = &ProtocolError{"missing or bad WebSocket-Location"}
|
||||||
ErrBadWebSocketOrigin = &ProtocolError{"bad WebSocket-Origin"}
|
ErrBadWebSocketProtocol = &ProtocolError{"missing or bad WebSocket-Protocol"}
|
||||||
ErrNoWebSocketLocation = &ProtocolError{"no WebSocket-Location"}
|
|
||||||
ErrBadWebSocketLocation = &ProtocolError{"bad WebSocket-Location"}
|
|
||||||
ErrNoWebSocketProtocol = &ProtocolError{"no WebSocket-Protocol"}
|
|
||||||
ErrBadWebSocketProtocol = &ProtocolError{"bad WebSocket-Protocol"}
|
|
||||||
ErrChallengeResponse = &ProtocolError{"mismatch challange/response"}
|
ErrChallengeResponse = &ProtocolError{"mismatch challange/response"}
|
||||||
secKeyRandomChars [0x30 - 0x21 + 0x7F - 0x3A]byte
|
secKeyRandomChars [0x30 - 0x21 + 0x7F - 0x3A]byte
|
||||||
)
|
)
|
||||||
@ -244,40 +240,21 @@ func handshake(resourceName, host, origin, location, protocol string, br *bufio.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Step 41. check websocket headers.
|
// Step 41. check websocket headers.
|
||||||
upgrade, found := resp.Header["Upgrade"]
|
if resp.Header["Upgrade"] != "WebSocket" ||
|
||||||
if !found {
|
strings.ToLower(resp.Header["Connection"]) != "upgrade" {
|
||||||
return ErrNoUpgrade
|
|
||||||
}
|
|
||||||
if upgrade != "WebSocket" {
|
|
||||||
return ErrBadUpgrade
|
|
||||||
}
|
|
||||||
connection, found := resp.Header["Connection"]
|
|
||||||
if !found || strings.ToLower(connection) != "upgrade" {
|
|
||||||
return ErrBadUpgrade
|
return ErrBadUpgrade
|
||||||
}
|
}
|
||||||
|
|
||||||
s, found := resp.Header["Sec-Websocket-Origin"]
|
if resp.Header["Sec-Websocket-Origin"] != origin {
|
||||||
if !found {
|
|
||||||
return ErrNoWebSocketOrigin
|
|
||||||
}
|
|
||||||
if s != origin {
|
|
||||||
return ErrBadWebSocketOrigin
|
return ErrBadWebSocketOrigin
|
||||||
}
|
}
|
||||||
s, found = resp.Header["Sec-Websocket-Location"]
|
|
||||||
if !found {
|
if resp.Header["Sec-Websocket-Location"] != location {
|
||||||
return ErrNoWebSocketLocation
|
|
||||||
}
|
|
||||||
if s != location {
|
|
||||||
return ErrBadWebSocketLocation
|
return ErrBadWebSocketLocation
|
||||||
}
|
}
|
||||||
if protocol != "" {
|
|
||||||
s, found = resp.Header["Sec-Websocket-Protocol"]
|
if protocol != "" && resp.Header["Sec-Websocket-Protocol"] != protocol {
|
||||||
if !found {
|
return ErrBadWebSocketProtocol
|
||||||
return ErrNoWebSocketProtocol
|
|
||||||
}
|
|
||||||
if s != protocol {
|
|
||||||
return ErrBadWebSocketProtocol
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 42-43. get expected data from challange data.
|
// Step 42-43. get expected data from challange data.
|
||||||
@ -322,40 +299,18 @@ func draft75handshake(resourceName, host, origin, location, protocol string, br
|
|||||||
if resp.Status != "101 Web Socket Protocol Handshake" {
|
if resp.Status != "101 Web Socket Protocol Handshake" {
|
||||||
return ErrBadStatus
|
return ErrBadStatus
|
||||||
}
|
}
|
||||||
upgrade, found := resp.Header["Upgrade"]
|
if resp.Header["Upgrade"] != "WebSocket" ||
|
||||||
if !found {
|
resp.Header["Connection"] != "Upgrade" {
|
||||||
return ErrNoUpgrade
|
|
||||||
}
|
|
||||||
if upgrade != "WebSocket" {
|
|
||||||
return ErrBadUpgrade
|
return ErrBadUpgrade
|
||||||
}
|
}
|
||||||
connection, found := resp.Header["Connection"]
|
if resp.Header["Websocket-Origin"] != origin {
|
||||||
if !found || connection != "Upgrade" {
|
|
||||||
return ErrBadUpgrade
|
|
||||||
}
|
|
||||||
|
|
||||||
ws_origin, found := resp.Header["Websocket-Origin"]
|
|
||||||
if !found {
|
|
||||||
return ErrNoWebSocketOrigin
|
|
||||||
}
|
|
||||||
if ws_origin != origin {
|
|
||||||
return ErrBadWebSocketOrigin
|
return ErrBadWebSocketOrigin
|
||||||
}
|
}
|
||||||
ws_location, found := resp.Header["Websocket-Location"]
|
if resp.Header["Websocket-Location"] != location {
|
||||||
if !found {
|
|
||||||
return ErrNoWebSocketLocation
|
|
||||||
}
|
|
||||||
if ws_location != location {
|
|
||||||
return ErrBadWebSocketLocation
|
return ErrBadWebSocketLocation
|
||||||
}
|
}
|
||||||
if protocol != "" {
|
if protocol != "" && resp.Header["Websocket-Protocol"] != protocol {
|
||||||
ws_protocol, found := resp.Header["Websocket-Protocol"]
|
return ErrBadWebSocketProtocol
|
||||||
if !found {
|
|
||||||
return ErrNoWebSocketProtocol
|
|
||||||
}
|
|
||||||
if ws_protocol != protocol {
|
|
||||||
return ErrBadWebSocketProtocol
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -75,14 +75,11 @@ func (f Handler) ServeHTTP(c *http.Conn, req *http.Request) {
|
|||||||
}
|
}
|
||||||
// HTTP version can be safely ignored.
|
// HTTP version can be safely ignored.
|
||||||
|
|
||||||
if v, found := req.Header["Upgrade"]; !found ||
|
if strings.ToLower(req.Header["Upgrade"]) != "websocket" ||
|
||||||
strings.ToLower(v) != "websocket" {
|
strings.ToLower(req.Header["Connection"]) != "upgrade" {
|
||||||
return
|
|
||||||
}
|
|
||||||
if v, found := req.Header["Connection"]; !found ||
|
|
||||||
strings.ToLower(v) != "upgrade" {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(ukai): check Host
|
// TODO(ukai): check Host
|
||||||
origin, found := req.Header["Origin"]
|
origin, found := req.Header["Origin"]
|
||||||
if !found {
|
if !found {
|
||||||
@ -181,12 +178,12 @@ func (f Draft75Handler) ServeHTTP(c *http.Conn, req *http.Request) {
|
|||||||
io.WriteString(c, "Unexpected request")
|
io.WriteString(c, "Unexpected request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if v, found := req.Header["Upgrade"]; !found || v != "WebSocket" {
|
if req.Header["Upgrade"] != "WebSocket" {
|
||||||
c.WriteHeader(http.StatusBadRequest)
|
c.WriteHeader(http.StatusBadRequest)
|
||||||
io.WriteString(c, "missing Upgrade: WebSocket header")
|
io.WriteString(c, "missing Upgrade: WebSocket header")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if v, found := req.Header["Connection"]; !found || v != "Upgrade" {
|
if req.Header["Connection"] != "Upgrade" {
|
||||||
c.WriteHeader(http.StatusBadRequest)
|
c.WriteHeader(http.StatusBadRequest)
|
||||||
io.WriteString(c, "missing Connection: Upgrade header")
|
io.WriteString(c, "missing Connection: Upgrade header")
|
||||||
return
|
return
|
||||||
|
@ -42,18 +42,18 @@ func TestEcho(t *testing.T) {
|
|||||||
ws, err := newClient("/echo", "localhost", "http://localhost",
|
ws, err := newClient("/echo", "localhost", "http://localhost",
|
||||||
"ws://localhost/echo", "", client, handshake)
|
"ws://localhost/echo", "", client, handshake)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("WebSocket handshake error", err)
|
t.Errorf("WebSocket handshake error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := []byte("hello, world\n")
|
msg := []byte("hello, world\n")
|
||||||
if _, err := ws.Write(msg); err != nil {
|
if _, err := ws.Write(msg); err != nil {
|
||||||
t.Errorf("Write: error %v", err)
|
t.Errorf("Write: %v", err)
|
||||||
}
|
}
|
||||||
var actual_msg = make([]byte, 512)
|
var actual_msg = make([]byte, 512)
|
||||||
n, err := ws.Read(actual_msg)
|
n, err := ws.Read(actual_msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Read: error %v", err)
|
t.Errorf("Read: %v", err)
|
||||||
}
|
}
|
||||||
actual_msg = actual_msg[0:n]
|
actual_msg = actual_msg[0:n]
|
||||||
if !bytes.Equal(msg, actual_msg) {
|
if !bytes.Equal(msg, actual_msg) {
|
||||||
@ -73,7 +73,7 @@ func TestEchoDraft75(t *testing.T) {
|
|||||||
ws, err := newClient("/echoDraft75", "localhost", "http://localhost",
|
ws, err := newClient("/echoDraft75", "localhost", "http://localhost",
|
||||||
"ws://localhost/echoDraft75", "", client, draft75handshake)
|
"ws://localhost/echoDraft75", "", client, draft75handshake)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("WebSocket handshake error", err)
|
t.Errorf("WebSocket handshake: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ func TestWithQuery(t *testing.T) {
|
|||||||
ws, err := newClient("/echo?q=v", "localhost", "http://localhost",
|
ws, err := newClient("/echo?q=v", "localhost", "http://localhost",
|
||||||
"ws://localhost/echo?q=v", "", client, handshake)
|
"ws://localhost/echo?q=v", "", client, handshake)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("WebSocket handshake error", err)
|
t.Errorf("WebSocket handshake: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ws.Close()
|
ws.Close()
|
||||||
|
@ -51,24 +51,15 @@ func count(data string, n int) map[string]int {
|
|||||||
top := len(data) - n
|
top := len(data) - n
|
||||||
for i := 0; i <= top; i++ {
|
for i := 0; i <= top; i++ {
|
||||||
s := data[i : i+n]
|
s := data[i : i+n]
|
||||||
if k, ok := counts[s]; ok {
|
counts[s]++
|
||||||
counts[s] = k + 1
|
|
||||||
} else {
|
|
||||||
counts[s] = 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return counts
|
return counts
|
||||||
}
|
}
|
||||||
|
|
||||||
func countOne(data string, s string) int {
|
func countOne(data string, s string) int {
|
||||||
counts := count(data, len(s))
|
return count(data, len(s))[s]
|
||||||
if i, ok := counts[s]; ok {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type kNuc struct {
|
type kNuc struct {
|
||||||
name string
|
name string
|
||||||
count int
|
count int
|
||||||
|
Loading…
Reference in New Issue
Block a user