Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
b678c197
Commit
b678c197
authored
Apr 23, 2012
by
Pascal S. de Kloe
Committed by
Brad Fitzpatrick
Apr 23, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
net/http: lex cleanup
R=rsc, bradfitz CC=golang-dev
https://golang.org/cl/6099043
parent
e7e7b1c5
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
97 additions
and
181 deletions
+97
-181
src/pkg/net/http/cookie.go
src/pkg/net/http/cookie.go
+1
-6
src/pkg/net/http/lex.go
src/pkg/net/http/lex.go
+83
-123
src/pkg/net/http/lex_test.go
src/pkg/net/http/lex_test.go
+13
-52
No files found.
src/pkg/net/http/cookie.go
View file @
b678c197
...
@@ -258,10 +258,5 @@ func parseCookieValueUsing(raw string, validByte func(byte) bool) (string, bool)
...
@@ -258,10 +258,5 @@ func parseCookieValueUsing(raw string, validByte func(byte) bool) (string, bool)
}
}
func
isCookieNameValid
(
raw
string
)
bool
{
func
isCookieNameValid
(
raw
string
)
bool
{
for
_
,
c
:=
range
raw
{
return
strings
.
IndexFunc
(
raw
,
isNotToken
)
<
0
if
!
isToken
(
byte
(
c
))
{
return
false
}
}
return
true
}
}
src/pkg/net/http/lex.go
View file @
b678c197
...
@@ -6,131 +6,91 @@ package http
...
@@ -6,131 +6,91 @@ package http
// This file deals with lexical matters of HTTP
// This file deals with lexical matters of HTTP
func
isSeparator
(
c
byte
)
bool
{
var
isTokenTable
=
[
127
]
bool
{
switch
c
{
'!'
:
true
,
case
'('
,
')'
,
'<'
,
'>'
,
'@'
,
','
,
';'
,
':'
,
'\\'
,
'"'
,
'/'
,
'['
,
']'
,
'?'
,
'='
,
'{'
,
'}'
,
' '
,
'\t'
:
'#'
:
true
,
return
true
'$'
:
true
,
}
'%'
:
true
,
return
false
'&'
:
true
,
'\'
'
:
true
,
'*'
:
true
,
'+'
:
true
,
'-'
:
true
,
'.'
:
true
,
'0'
:
true
,
'1'
:
true
,
'2'
:
true
,
'3'
:
true
,
'4'
:
true
,
'5'
:
true
,
'6'
:
true
,
'7'
:
true
,
'8'
:
true
,
'9'
:
true
,
'A'
:
true
,
'B'
:
true
,
'C'
:
true
,
'D'
:
true
,
'E'
:
true
,
'F'
:
true
,
'G'
:
true
,
'H'
:
true
,
'I'
:
true
,
'J'
:
true
,
'K'
:
true
,
'L'
:
true
,
'M'
:
true
,
'N'
:
true
,
'O'
:
true
,
'P'
:
true
,
'Q'
:
true
,
'R'
:
true
,
'S'
:
true
,
'T'
:
true
,
'U'
:
true
,
'W'
:
true
,
'V'
:
true
,
'X'
:
true
,
'Y'
:
true
,
'Z'
:
true
,
'^'
:
true
,
'_'
:
true
,
'`'
:
true
,
'a'
:
true
,
'b'
:
true
,
'c'
:
true
,
'd'
:
true
,
'e'
:
true
,
'f'
:
true
,
'g'
:
true
,
'h'
:
true
,
'i'
:
true
,
'j'
:
true
,
'k'
:
true
,
'l'
:
true
,
'm'
:
true
,
'n'
:
true
,
'o'
:
true
,
'p'
:
true
,
'q'
:
true
,
'r'
:
true
,
's'
:
true
,
't'
:
true
,
'u'
:
true
,
'v'
:
true
,
'w'
:
true
,
'x'
:
true
,
'y'
:
true
,
'z'
:
true
,
'|'
:
true
,
'~'
:
true
,
}
}
func
isCtl
(
c
byte
)
bool
{
return
(
0
<=
c
&&
c
<=
31
)
||
c
==
127
}
func
isToken
(
r
rune
)
bool
{
i
:=
int
(
r
)
func
isChar
(
c
byte
)
bool
{
return
0
<=
c
&&
c
<=
127
}
return
i
<
len
(
isTokenTable
)
&&
isTokenTable
[
i
]
func
isAnyText
(
c
byte
)
bool
{
return
!
isCtl
(
c
)
}
func
isQdText
(
c
byte
)
bool
{
return
isAnyText
(
c
)
&&
c
!=
'"'
}
func
isToken
(
c
byte
)
bool
{
return
isChar
(
c
)
&&
!
isCtl
(
c
)
&&
!
isSeparator
(
c
)
}
// Valid escaped sequences are not specified in RFC 2616, so for now, we assume
// that they coincide with the common sense ones used by GO. Malformed
// characters should probably not be treated as errors by a robust (forgiving)
// parser, so we replace them with the '?' character.
func
httpUnquotePair
(
b
byte
)
byte
{
// skip the first byte, which should always be '\'
switch
b
{
case
'a'
:
return
'\a'
case
'b'
:
return
'\b'
case
'f'
:
return
'\f'
case
'n'
:
return
'\n'
case
'r'
:
return
'\r'
case
't'
:
return
'\t'
case
'v'
:
return
'\v'
case
'\\'
:
return
'\\'
case
'\'
'
:
return
'\'
'
case
'"'
:
return
'"'
}
return
'?'
}
// raw must begin with a valid quoted string. Only the first quoted string is
// parsed and is unquoted in result. eaten is the number of bytes parsed, or -1
// upon failure.
func
httpUnquote
(
raw
[]
byte
)
(
eaten
int
,
result
string
)
{
buf
:=
make
([]
byte
,
len
(
raw
))
if
raw
[
0
]
!=
'"'
{
return
-
1
,
""
}
eaten
=
1
j
:=
0
// # of bytes written in buf
for
i
:=
1
;
i
<
len
(
raw
);
i
++
{
switch
b
:=
raw
[
i
];
b
{
case
'"'
:
eaten
++
buf
=
buf
[
0
:
j
]
return
i
+
1
,
string
(
buf
)
case
'\\'
:
if
len
(
raw
)
<
i
+
2
{
return
-
1
,
""
}
buf
[
j
]
=
httpUnquotePair
(
raw
[
i
+
1
])
eaten
+=
2
j
++
i
++
default
:
if
isQdText
(
b
)
{
buf
[
j
]
=
b
}
else
{
buf
[
j
]
=
'?'
}
eaten
++
j
++
}
}
return
-
1
,
""
}
}
// This is a best effort parse, so errors are not returned, instead not all of
func
isNotToken
(
r
rune
)
bool
{
// the input string might be parsed. result is always non-nil.
return
!
isToken
(
r
)
func
httpSplitFieldValue
(
fv
string
)
(
eaten
int
,
result
[]
string
)
{
result
=
make
([]
string
,
0
,
len
(
fv
))
raw
:=
[]
byte
(
fv
)
i
:=
0
chunk
:=
""
for
i
<
len
(
raw
)
{
b
:=
raw
[
i
]
switch
{
case
b
==
'"'
:
eaten
,
unq
:=
httpUnquote
(
raw
[
i
:
len
(
raw
)])
if
eaten
<
0
{
return
i
,
result
}
else
{
i
+=
eaten
chunk
+=
unq
}
case
isSeparator
(
b
)
:
if
chunk
!=
""
{
result
=
result
[
0
:
len
(
result
)
+
1
]
result
[
len
(
result
)
-
1
]
=
chunk
chunk
=
""
}
i
++
case
isToken
(
b
)
:
chunk
+=
string
(
b
)
i
++
case
b
==
'\n'
||
b
==
'\r'
:
i
++
default
:
chunk
+=
"?"
i
++
}
}
if
chunk
!=
""
{
result
=
result
[
0
:
len
(
result
)
+
1
]
result
[
len
(
result
)
-
1
]
=
chunk
chunk
=
""
}
return
i
,
result
}
}
src/pkg/net/http/lex_test.go
View file @
b678c197
...
@@ -8,63 +8,24 @@ import (
...
@@ -8,63 +8,24 @@ import (
"testing"
"testing"
)
)
type
lexTest
struct
{
func
isChar
(
c
rune
)
bool
{
return
c
<=
127
}
Raw
string
Parsed
int
// # of parsed characters
Result
[]
string
}
var
lexTests
=
[]
lexTest
{
func
isCtl
(
c
rune
)
bool
{
return
c
<=
31
||
c
==
127
}
{
Raw
:
`"abc"def,:ghi`
,
Parsed
:
13
,
Result
:
[]
string
{
"abcdef"
,
"ghi"
},
},
// My understanding of the RFC is that escape sequences outside of
// quotes are not interpreted?
{
Raw
:
`"\t"\t"\t"`
,
Parsed
:
10
,
Result
:
[]
string
{
"
\t
"
,
"t
\t
"
},
},
{
Raw
:
`"\yab"\r\n`
,
Parsed
:
10
,
Result
:
[]
string
{
"?ab"
,
"r"
,
"n"
},
},
{
Raw
:
"ab
\f
"
,
Parsed
:
3
,
Result
:
[]
string
{
"ab?"
},
},
{
Raw
:
"
\"
ab
\"
c,de f, gh, ij
\n\t\r
"
,
Parsed
:
23
,
Result
:
[]
string
{
"ab "
,
"c"
,
"de"
,
"f"
,
"gh"
,
"ij"
},
},
}
func
min
(
x
,
y
int
)
int
{
func
isSeparator
(
c
rune
)
bool
{
if
x
<=
y
{
switch
c
{
return
x
case
'('
,
')'
,
'<'
,
'>'
,
'@'
,
','
,
';'
,
':'
,
'\\'
,
'"'
,
'/'
,
'['
,
']'
,
'?'
,
'='
,
'{'
,
'}'
,
' '
,
'\t'
:
return
true
}
}
return
y
return
false
}
}
func
TestSplitFieldValue
(
t
*
testing
.
T
)
{
func
TestIsToken
(
t
*
testing
.
T
)
{
for
k
,
l
:=
range
lexTests
{
for
i
:=
0
;
i
<=
130
;
i
++
{
parsed
,
result
:=
httpSplitFieldValue
(
l
.
Raw
)
r
:=
rune
(
i
)
if
parsed
!=
l
.
Parsed
{
expected
:=
isChar
(
r
)
&&
!
isCtl
(
r
)
&&
!
isSeparator
(
r
)
t
.
Errorf
(
"#%d: Parsed %d, expected %d"
,
k
,
parsed
,
l
.
Parsed
)
if
isToken
(
r
)
!=
expected
{
}
t
.
Errorf
(
"isToken(0x%x) = %v"
,
r
,
!
expected
)
if
len
(
result
)
!=
len
(
l
.
Result
)
{
t
.
Errorf
(
"#%d: Result len %d, expected %d"
,
k
,
len
(
result
),
len
(
l
.
Result
))
}
for
i
:=
0
;
i
<
min
(
len
(
result
),
len
(
l
.
Result
));
i
++
{
if
result
[
i
]
!=
l
.
Result
[
i
]
{
t
.
Errorf
(
"#%d: %d-th entry mismatch. Have {%s}, expect {%s}"
,
k
,
i
,
result
[
i
],
l
.
Result
[
i
])
}
}
}
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment