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
fd9a5d22
Commit
fd9a5d22
authored
Sep 29, 2010
by
Stephen Ma
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
http: revised http Handler interface
R=rsc CC=golang-dev
https://golang.org/cl/1993043
parent
ffdb855b
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
343 additions
and
313 deletions
+343
-313
src/cmd/godoc/codewalk.go
src/cmd/godoc/codewalk.go
+21
-21
src/cmd/godoc/godoc.go
src/cmd/godoc/godoc.go
+41
-41
src/cmd/godoc/main.go
src/cmd/godoc/main.go
+12
-12
src/pkg/expvar/expvar.go
src/pkg/expvar/expvar.go
+6
-6
src/pkg/http/fs.go
src/pkg/http/fs.go
+23
-23
src/pkg/http/pprof/pprof.go
src/pkg/http/pprof/pprof.go
+13
-13
src/pkg/http/server.go
src/pkg/http/server.go
+198
-174
src/pkg/http/status.go
src/pkg/http/status.go
+6
-0
src/pkg/rpc/debug.go
src/pkg/rpc/debug.go
+3
-3
src/pkg/rpc/server.go
src/pkg/rpc/server.go
+6
-6
src/pkg/websocket/server.go
src/pkg/websocket/server.go
+14
-14
No files found.
src/cmd/godoc/codewalk.go
View file @
fd9a5d22
...
...
@@ -31,26 +31,26 @@ import (
// Handler for /doc/codewalk/ and below.
func
codewalk
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
codewalk
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
relpath
:=
r
.
URL
.
Path
[
len
(
"/doc/codewalk/"
)
:
]
abspath
:=
absolutePath
(
r
.
URL
.
Path
[
1
:
],
*
goroot
)
r
.
ParseForm
()
if
f
:=
r
.
FormValue
(
"fileprint"
);
f
!=
""
{
codewalkFileprint
(
c
,
r
,
f
)
codewalkFileprint
(
w
,
r
,
f
)
return
}
// If directory exists, serve list of code walks.
dir
,
err
:=
os
.
Lstat
(
abspath
)
if
err
==
nil
&&
dir
.
IsDirectory
()
{
codewalkDir
(
c
,
r
,
relpath
,
abspath
)
codewalkDir
(
w
,
r
,
relpath
,
abspath
)
return
}
// If file exists, serve using standard file server.
if
err
==
nil
{
serveFile
(
c
,
r
)
serveFile
(
w
,
r
)
return
}
...
...
@@ -59,17 +59,17 @@ func codewalk(c *http.Conn, r *http.Request) {
cw
,
err
:=
loadCodewalk
(
abspath
+
".xml"
)
if
err
!=
nil
{
log
.
Stderr
(
err
)
serveError
(
c
,
r
,
relpath
,
err
)
serveError
(
w
,
r
,
relpath
,
err
)
return
}
// Canonicalize the path and redirect if changed
if
redirect
(
c
,
r
)
{
if
redirect
(
w
,
r
)
{
return
}
b
:=
applyTemplate
(
codewalkHTML
,
"codewalk"
,
cw
)
servePage
(
c
,
"Codewalk: "
+
cw
.
Title
,
""
,
""
,
b
)
servePage
(
w
,
"Codewalk: "
+
cw
.
Title
,
""
,
""
,
b
)
}
...
...
@@ -178,7 +178,7 @@ func loadCodewalk(file string) (*Codewalk, os.Error) {
// codewalkDir serves the codewalk directory listing.
// It scans the directory for subdirectories or files named *.xml
// and prepares a table.
func
codewalkDir
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
relpath
,
abspath
string
)
{
func
codewalkDir
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
relpath
,
abspath
string
)
{
type
elem
struct
{
Name
string
Title
string
...
...
@@ -187,7 +187,7 @@ func codewalkDir(c *http.Conn, r *http.Request, relpath, abspath string) {
dir
,
err
:=
ioutil
.
ReadDir
(
abspath
)
if
err
!=
nil
{
log
.
Stderr
(
err
)
serveError
(
c
,
r
,
relpath
,
err
)
serveError
(
w
,
r
,
relpath
,
err
)
return
}
var
v
vector
.
Vector
...
...
@@ -204,7 +204,7 @@ func codewalkDir(c *http.Conn, r *http.Request, relpath, abspath string) {
}
b
:=
applyTemplate
(
codewalkdirHTML
,
"codewalkdir"
,
v
)
servePage
(
c
,
"Codewalks"
,
""
,
""
,
b
)
servePage
(
w
,
"Codewalks"
,
""
,
""
,
b
)
}
...
...
@@ -214,12 +214,12 @@ func codewalkDir(c *http.Conn, r *http.Request, relpath, abspath string) {
// in the response. This format is used for the middle window pane
// of the codewalk pages. It is a separate iframe and does not get
// the usual godoc HTML wrapper.
func
codewalkFileprint
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
f
string
)
{
func
codewalkFileprint
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
f
string
)
{
abspath
:=
absolutePath
(
f
,
*
goroot
)
data
,
err
:=
ioutil
.
ReadFile
(
abspath
)
if
err
!=
nil
{
log
.
Stderr
(
err
)
serveError
(
c
,
r
,
f
,
err
)
serveError
(
w
,
r
,
f
,
err
)
return
}
lo
,
_
:=
strconv
.
Atoi
(
r
.
FormValue
(
"lo"
))
...
...
@@ -243,17 +243,17 @@ func codewalkFileprint(c *http.Conn, r *http.Request, f string) {
}
}
io
.
WriteString
(
c
,
`<style type="text/css">@import "/doc/codewalk/codewalk.css";</style><pre>`
)
template
.
HTMLEscape
(
c
,
data
[
0
:
mark
])
io
.
WriteString
(
c
,
"<a name='mark'></a>"
)
template
.
HTMLEscape
(
c
,
data
[
mark
:
lo
])
io
.
WriteString
(
w
,
`<style type="text/css">@import "/doc/codewalk/codewalk.css";</style><pre>`
)
template
.
HTMLEscape
(
w
,
data
[
0
:
mark
])
io
.
WriteString
(
w
,
"<a name='mark'></a>"
)
template
.
HTMLEscape
(
w
,
data
[
mark
:
lo
])
if
lo
<
hi
{
io
.
WriteString
(
c
,
"<div class='codewalkhighlight'>"
)
template
.
HTMLEscape
(
c
,
data
[
lo
:
hi
])
io
.
WriteString
(
c
,
"</div>"
)
io
.
WriteString
(
w
,
"<div class='codewalkhighlight'>"
)
template
.
HTMLEscape
(
w
,
data
[
lo
:
hi
])
io
.
WriteString
(
w
,
"</div>"
)
}
template
.
HTMLEscape
(
c
,
data
[
hi
:
])
io
.
WriteString
(
c
,
"</pre>"
)
template
.
HTMLEscape
(
w
,
data
[
hi
:
])
io
.
WriteString
(
w
,
"</pre>"
)
}
...
...
src/cmd/godoc/godoc.go
View file @
fd9a5d22
...
...
@@ -792,7 +792,7 @@ func readTemplates() {
// ----------------------------------------------------------------------------
// Generic HTML wrapper
func
servePage
(
c
*
http
.
Conn
,
title
,
subtitle
,
query
string
,
content
[]
byte
)
{
func
servePage
(
w
http
.
ResponseWriter
,
title
,
subtitle
,
query
string
,
content
[]
byte
)
{
type
Data
struct
{
Title
string
Subtitle
string
...
...
@@ -813,15 +813,15 @@ func servePage(c *http.Conn, title, subtitle, query string, content []byte) {
Content
:
content
,
}
if
err
:=
godocHTML
.
Execute
(
&
d
,
c
);
err
!=
nil
{
if
err
:=
godocHTML
.
Execute
(
&
d
,
w
);
err
!=
nil
{
log
.
Stderrf
(
"godocHTML.Execute: %s"
,
err
)
}
}
func
serveText
(
c
*
http
.
Conn
,
text
[]
byte
)
{
c
.
SetHeader
(
"Content-Type"
,
"text/plain; charset=utf-8"
)
c
.
Write
(
text
)
func
serveText
(
w
http
.
ResponseWriter
,
text
[]
byte
)
{
w
.
SetHeader
(
"Content-Type"
,
"text/plain; charset=utf-8"
)
w
.
Write
(
text
)
}
...
...
@@ -844,19 +844,19 @@ func extractString(src []byte, rx *regexp.Regexp) (s string) {
}
func
serveHTMLDoc
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
abspath
,
relpath
string
)
{
func
serveHTMLDoc
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
abspath
,
relpath
string
)
{
// get HTML body contents
src
,
err
:=
ioutil
.
ReadFile
(
abspath
)
if
err
!=
nil
{
log
.
Stderrf
(
"ioutil.ReadFile: %s"
,
err
)
serveError
(
c
,
r
,
relpath
,
err
)
serveError
(
w
,
r
,
relpath
,
err
)
return
}
// if it begins with "<!DOCTYPE " assume it is standalone
// html that doesn't need the template wrapping.
if
bytes
.
HasPrefix
(
src
,
[]
byte
(
"<!DOCTYPE "
))
{
c
.
Write
(
src
)
w
.
Write
(
src
)
return
}
...
...
@@ -875,7 +875,7 @@ func serveHTMLDoc(c *http.Conn, r *http.Request, abspath, relpath string) {
}
subtitle
:=
extractString
(
src
,
subtitleRx
)
servePage
(
c
,
title
,
subtitle
,
""
,
src
)
servePage
(
w
,
title
,
subtitle
,
""
,
src
)
}
...
...
@@ -888,11 +888,11 @@ func applyTemplate(t *template.Template, name string, data interface{}) []byte {
}
func
serveGoSource
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
abspath
,
relpath
string
)
{
func
serveGoSource
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
abspath
,
relpath
string
)
{
file
,
err
:=
parser
.
ParseFile
(
abspath
,
nil
,
parser
.
ParseComments
)
if
err
!=
nil
{
log
.
Stderrf
(
"parser.ParseFile: %s"
,
err
)
serveError
(
c
,
r
,
relpath
,
err
)
serveError
(
w
,
r
,
relpath
,
err
)
return
}
...
...
@@ -911,13 +911,13 @@ func serveGoSource(c *http.Conn, r *http.Request, abspath, relpath string) {
info
:=
&
SourceInfo
{
styler
.
idList
(),
buf
.
Bytes
()}
contents
:=
applyTemplate
(
sourceHTML
,
"sourceHTML"
,
info
)
servePage
(
c
,
"Source file "
+
relpath
,
""
,
""
,
contents
)
servePage
(
w
,
"Source file "
+
relpath
,
""
,
""
,
contents
)
}
func
redirect
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
(
redirected
bool
)
{
func
redirect
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
redirected
bool
)
{
if
canonical
:=
pathutil
.
Clean
(
r
.
URL
.
Path
)
+
"/"
;
r
.
URL
.
Path
!=
canonical
{
http
.
Redirect
(
c
,
canonical
,
http
.
StatusMovedPermanently
)
http
.
Redirect
(
w
,
r
,
canonical
,
http
.
StatusMovedPermanently
)
redirected
=
true
}
return
...
...
@@ -971,11 +971,11 @@ func isTextFile(path string) bool {
}
func
serveTextFile
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
abspath
,
relpath
string
)
{
func
serveTextFile
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
abspath
,
relpath
string
)
{
src
,
err
:=
ioutil
.
ReadFile
(
abspath
)
if
err
!=
nil
{
log
.
Stderrf
(
"ioutil.ReadFile: %s"
,
err
)
serveError
(
c
,
r
,
relpath
,
err
)
serveError
(
w
,
r
,
relpath
,
err
)
return
}
...
...
@@ -984,19 +984,19 @@ func serveTextFile(c *http.Conn, r *http.Request, abspath, relpath string) {
template
.
HTMLEscape
(
&
buf
,
src
)
fmt
.
Fprintln
(
&
buf
,
"</pre>"
)
servePage
(
c
,
"Text file "
+
relpath
,
""
,
""
,
buf
.
Bytes
())
servePage
(
w
,
"Text file "
+
relpath
,
""
,
""
,
buf
.
Bytes
())
}
func
serveDirectory
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
abspath
,
relpath
string
)
{
if
redirect
(
c
,
r
)
{
func
serveDirectory
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
abspath
,
relpath
string
)
{
if
redirect
(
w
,
r
)
{
return
}
list
,
err
:=
ioutil
.
ReadDir
(
abspath
)
if
err
!=
nil
{
log
.
Stderrf
(
"ioutil.ReadDir: %s"
,
err
)
serveError
(
c
,
r
,
relpath
,
err
)
serveError
(
w
,
r
,
relpath
,
err
)
return
}
...
...
@@ -1007,23 +1007,23 @@ func serveDirectory(c *http.Conn, r *http.Request, abspath, relpath string) {
}
contents
:=
applyTemplate
(
dirlistHTML
,
"dirlistHTML"
,
list
)
servePage
(
c
,
"Directory "
+
relpath
,
""
,
""
,
contents
)
servePage
(
w
,
"Directory "
+
relpath
,
""
,
""
,
contents
)
}
func
serveFile
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
serveFile
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
relpath
:=
r
.
URL
.
Path
[
1
:
]
// serveFile URL paths start with '/'
abspath
:=
absolutePath
(
relpath
,
*
goroot
)
// pick off special cases and hand the rest to the standard file server
switch
r
.
URL
.
Path
{
case
"/"
:
serveHTMLDoc
(
c
,
r
,
pathutil
.
Join
(
*
goroot
,
"doc/root.html"
),
"doc/root.html"
)
serveHTMLDoc
(
w
,
r
,
pathutil
.
Join
(
*
goroot
,
"doc/root.html"
),
"doc/root.html"
)
return
case
"/doc/root.html"
:
// hide landing page from its real name
http
.
Redirect
(
c
,
"/"
,
http
.
StatusMovedPermanently
)
http
.
Redirect
(
w
,
r
,
"/"
,
http
.
StatusMovedPermanently
)
return
}
...
...
@@ -1032,42 +1032,42 @@ func serveFile(c *http.Conn, r *http.Request) {
if
strings
.
HasSuffix
(
abspath
,
"/index.html"
)
{
// We'll show index.html for the directory.
// Use the dir/ version as canonical instead of dir/index.html.
http
.
Redirect
(
c
,
r
.
URL
.
Path
[
0
:
len
(
r
.
URL
.
Path
)
-
len
(
"index.html"
)],
http
.
StatusMovedPermanently
)
http
.
Redirect
(
w
,
r
,
r
.
URL
.
Path
[
0
:
len
(
r
.
URL
.
Path
)
-
len
(
"index.html"
)],
http
.
StatusMovedPermanently
)
return
}
serveHTMLDoc
(
c
,
r
,
abspath
,
relpath
)
serveHTMLDoc
(
w
,
r
,
abspath
,
relpath
)
return
case
".go"
:
serveGoSource
(
c
,
r
,
abspath
,
relpath
)
serveGoSource
(
w
,
r
,
abspath
,
relpath
)
return
}
dir
,
err
:=
os
.
Lstat
(
abspath
)
if
err
!=
nil
{
log
.
Stderr
(
err
)
serveError
(
c
,
r
,
relpath
,
err
)
serveError
(
w
,
r
,
relpath
,
err
)
return
}
if
dir
!=
nil
&&
dir
.
IsDirectory
()
{
if
redirect
(
c
,
r
)
{
if
redirect
(
w
,
r
)
{
return
}
if
index
:=
abspath
+
"/index.html"
;
isTextFile
(
index
)
{
serveHTMLDoc
(
c
,
r
,
index
,
relativePath
(
index
))
serveHTMLDoc
(
w
,
r
,
index
,
relativePath
(
index
))
return
}
serveDirectory
(
c
,
r
,
abspath
,
relpath
)
serveDirectory
(
w
,
r
,
abspath
,
relpath
)
return
}
if
isTextFile
(
abspath
)
{
serveTextFile
(
c
,
r
,
abspath
,
relpath
)
serveTextFile
(
w
,
r
,
abspath
,
relpath
)
return
}
fileServer
.
ServeHTTP
(
c
,
r
)
fileServer
.
ServeHTTP
(
w
,
r
)
}
...
...
@@ -1243,8 +1243,8 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
}
func
(
h
*
httpHandler
)
ServeHTTP
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
if
redirect
(
c
,
r
)
{
func
(
h
*
httpHandler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
redirect
(
w
,
r
)
{
return
}
...
...
@@ -1257,13 +1257,13 @@ func (h *httpHandler) ServeHTTP(c *http.Conn, r *http.Request) {
info
:=
h
.
getPageInfo
(
abspath
,
relpath
,
r
.
FormValue
(
"p"
),
mode
)
if
info
.
Err
!=
nil
{
log
.
Stderr
(
info
.
Err
)
serveError
(
c
,
r
,
relpath
,
info
.
Err
)
serveError
(
w
,
r
,
relpath
,
info
.
Err
)
return
}
if
r
.
FormValue
(
"f"
)
==
"text"
{
contents
:=
applyTemplate
(
packageText
,
"packageText"
,
info
)
serveText
(
c
,
contents
)
serveText
(
w
,
contents
)
return
}
...
...
@@ -1290,7 +1290,7 @@ func (h *httpHandler) ServeHTTP(c *http.Conn, r *http.Request) {
}
contents
:=
applyTemplate
(
packageHTML
,
"packageHTML"
,
info
)
servePage
(
c
,
title
,
subtitle
,
""
,
contents
)
servePage
(
w
,
title
,
subtitle
,
""
,
contents
)
}
...
...
@@ -1319,13 +1319,13 @@ func lookup(query string) (result SearchResult) {
}
func
search
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
search
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
query
:=
strings
.
TrimSpace
(
r
.
FormValue
(
"q"
))
result
:=
lookup
(
query
)
if
r
.
FormValue
(
"f"
)
==
"text"
{
contents
:=
applyTemplate
(
searchText
,
"searchText"
,
result
)
serveText
(
c
,
contents
)
serveText
(
w
,
contents
)
return
}
...
...
@@ -1337,7 +1337,7 @@ func search(c *http.Conn, r *http.Request) {
}
contents
:=
applyTemplate
(
searchHTML
,
"searchHTML"
,
result
)
servePage
(
c
,
title
,
""
,
query
,
contents
)
servePage
(
w
,
title
,
""
,
query
,
contents
)
}
...
...
src/cmd/godoc/main.go
View file @
fd9a5d22
...
...
@@ -64,14 +64,14 @@ var (
)
func
serveError
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
relpath
string
,
err
os
.
Error
)
{
func
serveError
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
relpath
string
,
err
os
.
Error
)
{
contents
:=
applyTemplate
(
errorHTML
,
"errorHTML"
,
err
)
// err may contain an absolute path!
c
.
WriteHeader
(
http
.
StatusNotFound
)
servePage
(
c
,
"File "
+
relpath
,
""
,
""
,
contents
)
w
.
WriteHeader
(
http
.
StatusNotFound
)
servePage
(
w
,
"File "
+
relpath
,
""
,
""
,
contents
)
}
func
exec
(
c
*
http
.
Conn
,
args
[]
string
)
(
status
int
)
{
func
exec
(
rw
http
.
ResponseWriter
,
args
[]
string
)
(
status
int
)
{
r
,
w
,
err
:=
os
.
Pipe
()
if
err
!=
nil
{
log
.
Stderrf
(
"os.Pipe(): %v
\n
"
,
err
)
...
...
@@ -109,18 +109,18 @@ func exec(c *http.Conn, args []string) (status int) {
if
*
verbose
{
os
.
Stderr
.
Write
(
buf
.
Bytes
())
}
if
c
!=
nil
{
c
.
SetHeader
(
"content-type"
,
"text/plain; charset=utf-8"
)
c
.
Write
(
buf
.
Bytes
())
if
rw
!=
nil
{
rw
.
SetHeader
(
"content-type"
,
"text/plain; charset=utf-8"
)
rw
.
Write
(
buf
.
Bytes
())
}
return
}
func
dosync
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
dosync
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
args
:=
[]
string
{
"/bin/sh"
,
"-c"
,
*
syncCmd
}
switch
exec
(
c
,
args
)
{
switch
exec
(
w
,
args
)
{
case
0
:
// sync succeeded and some files have changed;
// update package tree.
...
...
@@ -150,9 +150,9 @@ func usage() {
func
loggingHandler
(
h
http
.
Handler
)
http
.
Handler
{
return
http
.
HandlerFunc
(
func
(
c
*
http
.
Conn
,
req
*
http
.
Request
)
{
log
.
Stderrf
(
"%s
\t
%s"
,
c
.
RemoteAddr
,
req
.
URL
)
h
.
ServeHTTP
(
c
,
req
)
return
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
log
.
Stderrf
(
"%s
\t
%s"
,
w
.
RemoteAddr
()
,
req
.
URL
)
h
.
ServeHTTP
(
w
,
req
)
})
}
...
...
src/pkg/expvar/expvar.go
View file @
fd9a5d22
...
...
@@ -210,18 +210,18 @@ func Iter() <-chan KeyValue {
return
c
}
func
expvarHandler
(
c
*
http
.
Conn
,
req
*
http
.
Request
)
{
c
.
SetHeader
(
"content-type"
,
"application/json; charset=utf-8"
)
fmt
.
Fprintf
(
c
,
"{
\n
"
)
func
expvarHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
SetHeader
(
"content-type"
,
"application/json; charset=utf-8"
)
fmt
.
Fprintf
(
w
,
"{
\n
"
)
first
:=
true
for
name
,
value
:=
range
vars
{
if
!
first
{
fmt
.
Fprintf
(
c
,
",
\n
"
)
fmt
.
Fprintf
(
w
,
",
\n
"
)
}
first
=
false
fmt
.
Fprintf
(
c
,
"%q: %s"
,
name
,
value
)
fmt
.
Fprintf
(
w
,
"%q: %s"
,
name
,
value
)
}
fmt
.
Fprintf
(
c
,
"
\n
}
\n
"
)
fmt
.
Fprintf
(
w
,
"
\n
}
\n
"
)
}
func
memstats
()
string
{
...
...
src/pkg/http/fs.go
View file @
fd9a5d22
...
...
@@ -43,8 +43,8 @@ func isText(b []byte) bool {
return
true
}
func
dirList
(
c
*
Conn
,
f
*
os
.
File
)
{
fmt
.
Fprintf
(
c
,
"<pre>
\n
"
)
func
dirList
(
w
ResponseWriter
,
f
*
os
.
File
)
{
fmt
.
Fprintf
(
w
,
"<pre>
\n
"
)
for
{
dirs
,
err
:=
f
.
Readdir
(
100
)
if
err
!=
nil
||
len
(
dirs
)
==
0
{
...
...
@@ -56,25 +56,25 @@ func dirList(c *Conn, f *os.File) {
name
+=
"/"
}
// TODO htmlescape
fmt
.
Fprintf
(
c
,
"<a href=
\"
%s
\"
>%s</a>
\n
"
,
name
,
name
)
fmt
.
Fprintf
(
w
,
"<a href=
\"
%s
\"
>%s</a>
\n
"
,
name
,
name
)
}
}
fmt
.
Fprintf
(
c
,
"</pre>
\n
"
)
fmt
.
Fprintf
(
w
,
"</pre>
\n
"
)
}
func
serveFile
(
c
*
Conn
,
r
*
Request
,
name
string
,
redirect
bool
)
{
func
serveFile
(
w
ResponseWriter
,
r
*
Request
,
name
string
,
redirect
bool
)
{
const
indexPage
=
"/index.html"
// redirect .../index.html to .../
if
strings
.
HasSuffix
(
r
.
URL
.
Path
,
indexPage
)
{
Redirect
(
c
,
r
.
URL
.
Path
[
0
:
len
(
r
.
URL
.
Path
)
-
len
(
indexPage
)
+
1
],
StatusMovedPermanently
)
Redirect
(
w
,
r
,
r
.
URL
.
Path
[
0
:
len
(
r
.
URL
.
Path
)
-
len
(
indexPage
)
+
1
],
StatusMovedPermanently
)
return
}
f
,
err
:=
os
.
Open
(
name
,
os
.
O_RDONLY
,
0
)
if
err
!=
nil
{
// TODO expose actual error?
NotFound
(
c
,
r
)
NotFound
(
w
,
r
)
return
}
defer
f
.
Close
()
...
...
@@ -82,7 +82,7 @@ func serveFile(c *Conn, r *Request, name string, redirect bool) {
d
,
err1
:=
f
.
Stat
()
if
err1
!=
nil
{
// TODO expose actual error?
NotFound
(
c
,
r
)
NotFound
(
w
,
r
)
return
}
...
...
@@ -92,22 +92,22 @@ func serveFile(c *Conn, r *Request, name string, redirect bool) {
url
:=
r
.
URL
.
Path
if
d
.
IsDirectory
()
{
if
url
[
len
(
url
)
-
1
]
!=
'/'
{
Redirect
(
c
,
url
+
"/"
,
StatusMovedPermanently
)
Redirect
(
w
,
r
,
url
+
"/"
,
StatusMovedPermanently
)
return
}
}
else
{
if
url
[
len
(
url
)
-
1
]
==
'/'
{
Redirect
(
c
,
url
[
0
:
len
(
url
)
-
1
],
StatusMovedPermanently
)
Redirect
(
w
,
r
,
url
[
0
:
len
(
url
)
-
1
],
StatusMovedPermanently
)
return
}
}
}
if
t
,
_
:=
time
.
Parse
(
TimeFormat
,
r
.
Header
[
"If-Modified-Since"
]);
t
!=
nil
&&
d
.
Mtime_ns
/
1e9
<=
t
.
Seconds
()
{
c
.
WriteHeader
(
StatusNotModified
)
w
.
WriteHeader
(
StatusNotModified
)
return
}
c
.
SetHeader
(
"Last-Modified"
,
time
.
SecondsToUTC
(
d
.
Mtime_ns
/
1e9
)
.
Format
(
TimeFormat
))
w
.
SetHeader
(
"Last-Modified"
,
time
.
SecondsToUTC
(
d
.
Mtime_ns
/
1e9
)
.
Format
(
TimeFormat
))
// use contents of index.html for directory, if present
if
d
.
IsDirectory
()
{
...
...
@@ -125,7 +125,7 @@ func serveFile(c *Conn, r *Request, name string, redirect bool) {
}
if
d
.
IsDirectory
()
{
dirList
(
c
,
f
)
dirList
(
w
,
f
)
return
}
...
...
@@ -133,25 +133,25 @@ func serveFile(c *Conn, r *Request, name string, redirect bool) {
// use extension to find content type.
ext
:=
path
.
Ext
(
name
)
if
ctype
:=
mime
.
TypeByExtension
(
ext
);
ctype
!=
""
{
c
.
SetHeader
(
"Content-Type"
,
ctype
)
w
.
SetHeader
(
"Content-Type"
,
ctype
)
}
else
{
// read first chunk to decide between utf-8 text and binary
var
buf
[
1024
]
byte
n
,
_
:=
io
.
ReadFull
(
f
,
buf
[
0
:
])
b
:=
buf
[
0
:
n
]
if
isText
(
b
)
{
c
.
SetHeader
(
"Content-Type"
,
"text-plain; charset=utf-8"
)
w
.
SetHeader
(
"Content-Type"
,
"text-plain; charset=utf-8"
)
}
else
{
c
.
SetHeader
(
"Content-Type"
,
"application/octet-stream"
)
// generic binary
w
.
SetHeader
(
"Content-Type"
,
"application/octet-stream"
)
// generic binary
}
c
.
Write
(
b
)
w
.
Write
(
b
)
}
io
.
Copy
(
c
,
f
)
io
.
Copy
(
w
,
f
)
}
// ServeFile replies to the request with the contents of the named file or directory.
func
ServeFile
(
c
*
Conn
,
r
*
Request
,
name
string
)
{
serveFile
(
c
,
r
,
name
,
false
)
func
ServeFile
(
w
ResponseWriter
,
r
*
Request
,
name
string
)
{
serveFile
(
w
,
r
,
name
,
false
)
}
type
fileHandler
struct
{
...
...
@@ -165,12 +165,12 @@ type fileHandler struct {
// looking up the file name in the file system.
func
FileServer
(
root
,
prefix
string
)
Handler
{
return
&
fileHandler
{
root
,
prefix
}
}
func
(
f
*
fileHandler
)
ServeHTTP
(
c
*
Conn
,
r
*
Request
)
{
func
(
f
*
fileHandler
)
ServeHTTP
(
w
ResponseWriter
,
r
*
Request
)
{
path
:=
r
.
URL
.
Path
if
!
strings
.
HasPrefix
(
path
,
f
.
prefix
)
{
NotFound
(
c
,
r
)
NotFound
(
w
,
r
)
return
}
path
=
path
[
len
(
f
.
prefix
)
:
]
serveFile
(
c
,
r
,
f
.
root
+
"/"
+
path
,
true
)
serveFile
(
w
,
r
,
f
.
root
+
"/"
+
path
,
true
)
}
src/pkg/http/pprof/pprof.go
View file @
fd9a5d22
...
...
@@ -40,28 +40,28 @@ func init() {
// Cmdline responds with the running program's
// command line, with arguments separated by NUL bytes.
// The package initialization registers it as /debug/pprof/cmdline.
func
Cmdline
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
c
.
SetHeader
(
"content-type"
,
"text/plain; charset=utf-8"
)
fmt
.
Fprintf
(
c
,
strings
.
Join
(
os
.
Args
,
"
\x00
"
))
func
Cmdline
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
SetHeader
(
"content-type"
,
"text/plain; charset=utf-8"
)
fmt
.
Fprintf
(
w
,
strings
.
Join
(
os
.
Args
,
"
\x00
"
))
}
// Heap responds with the pprof-formatted heap profile.
// The package initialization registers it as /debug/pprof/heap.
func
Heap
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
c
.
SetHeader
(
"content-type"
,
"text/plain; charset=utf-8"
)
pprof
.
WriteHeapProfile
(
c
)
func
Heap
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
SetHeader
(
"content-type"
,
"text/plain; charset=utf-8"
)
pprof
.
WriteHeapProfile
(
w
)
}
// Symbol looks up the program counters listed in the request,
// responding with a table mapping program counters to function names.
// The package initialization registers it as /debug/pprof/symbol.
func
Symbol
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
c
.
SetHeader
(
"content-type"
,
"text/plain; charset=utf-8"
)
func
Symbol
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
SetHeader
(
"content-type"
,
"text/plain; charset=utf-8"
)
// We don't know how many symbols we have, but we
// do have symbol information. Pprof only cares whether
// this number is 0 (no symbols available) or > 0.
fmt
.
Fprintf
(
c
,
"num_symbols: 1
\n
"
)
fmt
.
Fprintf
(
w
,
"num_symbols: 1
\n
"
)
var
b
*
bufio
.
Reader
if
r
.
Method
==
"POST"
{
...
...
@@ -71,15 +71,15 @@ func Symbol(c *http.Conn, r *http.Request) {
}
for
{
w
,
err
:=
b
.
ReadSlice
(
'+'
)
w
ord
,
err
:=
b
.
ReadSlice
(
'+'
)
if
err
==
nil
{
w
=
w
[
0
:
len
(
w
)
-
1
]
// trim +
w
ord
=
word
[
0
:
len
(
word
)
-
1
]
// trim +
}
pc
,
_
:=
strconv
.
Btoui64
(
string
(
w
),
0
)
pc
,
_
:=
strconv
.
Btoui64
(
string
(
w
ord
),
0
)
if
pc
!=
0
{
f
:=
runtime
.
FuncForPC
(
uintptr
(
pc
))
if
f
!=
nil
{
fmt
.
Fprintf
(
c
,
"%#x %s
\n
"
,
pc
,
f
.
Name
())
fmt
.
Fprintf
(
w
,
"%#x %s
\n
"
,
pc
,
f
.
Name
())
}
}
...
...
src/pkg/http/server.go
View file @
fd9a5d22
This diff is collapsed.
Click to expand it.
src/pkg/http/status.go
View file @
fd9a5d22
...
...
@@ -98,3 +98,9 @@ var statusText = map[int]string{
StatusGatewayTimeout
:
"Gateway Timeout"
,
StatusHTTPVersionNotSupported
:
"HTTP Version Not Supported"
,
}
// StatusText returns a text for the HTTP status code. It returns the empty
// string if the code is unknown.
func
StatusText
(
code
int
)
string
{
return
statusText
[
code
]
}
src/pkg/rpc/debug.go
View file @
fd9a5d22
...
...
@@ -62,7 +62,7 @@ func (m methodArray) Less(i, j int) bool { return m[i].name < m[j].name }
func
(
m
methodArray
)
Swap
(
i
,
j
int
)
{
m
[
i
],
m
[
j
]
=
m
[
j
],
m
[
i
]
}
// Runs at /debug/rpc
func
debugHTTP
(
c
*
http
.
Conn
,
req
*
http
.
Request
)
{
func
debugHTTP
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
// Build a sorted version of the data.
var
services
=
make
(
serviceArray
,
len
(
server
.
serviceMap
))
i
:=
0
...
...
@@ -79,8 +79,8 @@ func debugHTTP(c *http.Conn, req *http.Request) {
}
server
.
Unlock
()
sort
.
Sort
(
services
)
err
:=
debug
.
Execute
(
services
,
c
)
err
:=
debug
.
Execute
(
services
,
w
)
if
err
!=
nil
{
fmt
.
Fprintln
(
c
,
"rpc: error executing template:"
,
err
.
String
())
fmt
.
Fprintln
(
w
,
"rpc: error executing template:"
,
err
.
String
())
}
}
src/pkg/rpc/server.go
View file @
fd9a5d22
...
...
@@ -445,16 +445,16 @@ var rpcPath string = "/_goRPC_"
var
debugPath
string
=
"/debug/rpc"
var
connected
=
"200 Connected to Go RPC"
func
serveHTTP
(
c
*
http
.
Conn
,
req
*
http
.
Request
)
{
func
serveHTTP
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
if
req
.
Method
!=
"CONNECT"
{
c
.
SetHeader
(
"Content-Type"
,
"text/plain; charset=utf-8"
)
c
.
WriteHeader
(
http
.
StatusMethodNotAllowed
)
io
.
WriteString
(
c
,
"405 must CONNECT to "
+
rpcPath
+
"
\n
"
)
w
.
SetHeader
(
"Content-Type"
,
"text/plain; charset=utf-8"
)
w
.
WriteHeader
(
http
.
StatusMethodNotAllowed
)
io
.
WriteString
(
w
,
"405 must CONNECT to "
+
rpcPath
+
"
\n
"
)
return
}
conn
,
_
,
err
:=
c
.
Hijack
()
conn
,
_
,
err
:=
w
.
Hijack
()
if
err
!=
nil
{
log
.
Stderr
(
"rpc hijacking "
,
c
.
RemoteAddr
,
": "
,
err
.
String
())
log
.
Stderr
(
"rpc hijacking "
,
w
.
RemoteAddr
()
,
": "
,
err
.
String
())
return
}
io
.
WriteString
(
conn
,
"HTTP/1.0 "
+
connected
+
"
\n\n
"
)
...
...
src/pkg/websocket/server.go
View file @
fd9a5d22
...
...
@@ -57,8 +57,8 @@ func getKeyNumber(s string) (r uint32) {
}
// ServeHTTP implements the http.Handler interface for a Web Socket
func
(
f
Handler
)
ServeHTTP
(
c
*
http
.
Conn
,
req
*
http
.
Request
)
{
rwc
,
buf
,
err
:=
c
.
Hijack
()
func
(
f
Handler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
rwc
,
buf
,
err
:=
w
.
Hijack
()
if
err
!=
nil
{
panic
(
"Hijack failed: "
+
err
.
String
())
return
...
...
@@ -98,7 +98,7 @@ func (f Handler) ServeHTTP(c *http.Conn, req *http.Request) {
}
var
location
string
if
c
.
UsingTLS
()
{
if
w
.
UsingTLS
()
{
location
=
"wss://"
+
req
.
Host
+
req
.
URL
.
RawPath
}
else
{
location
=
"ws://"
+
req
.
Host
+
req
.
URL
.
RawPath
...
...
@@ -161,30 +161,30 @@ Draft75Handler is an interface to a WebSocket based on the
type
Draft75Handler
func
(
*
Conn
)
// ServeHTTP implements the http.Handler interface for a Web Socket.
func
(
f
Draft75Handler
)
ServeHTTP
(
c
*
http
.
Conn
,
req
*
http
.
Request
)
{
func
(
f
Draft75Handler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
if
req
.
Method
!=
"GET"
||
req
.
Proto
!=
"HTTP/1.1"
{
c
.
WriteHeader
(
http
.
StatusBadRequest
)
io
.
WriteString
(
c
,
"Unexpected request"
)
w
.
WriteHeader
(
http
.
StatusBadRequest
)
io
.
WriteString
(
w
,
"Unexpected request"
)
return
}
if
req
.
Header
[
"Upgrade"
]
!=
"WebSocket"
{
c
.
WriteHeader
(
http
.
StatusBadRequest
)
io
.
WriteString
(
c
,
"missing Upgrade: WebSocket header"
)
w
.
WriteHeader
(
http
.
StatusBadRequest
)
io
.
WriteString
(
w
,
"missing Upgrade: WebSocket header"
)
return
}
if
req
.
Header
[
"Connection"
]
!=
"Upgrade"
{
c
.
WriteHeader
(
http
.
StatusBadRequest
)
io
.
WriteString
(
c
,
"missing Connection: Upgrade header"
)
w
.
WriteHeader
(
http
.
StatusBadRequest
)
io
.
WriteString
(
w
,
"missing Connection: Upgrade header"
)
return
}
origin
,
found
:=
req
.
Header
[
"Origin"
]
if
!
found
{
c
.
WriteHeader
(
http
.
StatusBadRequest
)
io
.
WriteString
(
c
,
"missing Origin header"
)
w
.
WriteHeader
(
http
.
StatusBadRequest
)
io
.
WriteString
(
w
,
"missing Origin header"
)
return
}
rwc
,
buf
,
err
:=
c
.
Hijack
()
rwc
,
buf
,
err
:=
w
.
Hijack
()
if
err
!=
nil
{
panic
(
"Hijack failed: "
+
err
.
String
())
return
...
...
@@ -192,7 +192,7 @@ func (f Draft75Handler) ServeHTTP(c *http.Conn, req *http.Request) {
defer
rwc
.
Close
()
var
location
string
if
c
.
UsingTLS
()
{
if
w
.
UsingTLS
()
{
location
=
"wss://"
+
req
.
Host
+
req
.
URL
.
RawPath
}
else
{
location
=
"ws://"
+
req
.
Host
+
req
.
URL
.
RawPath
...
...
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