Commit fd9a5d22 authored by Stephen Ma's avatar Stephen Ma

http: revised http Handler interface

R=rsc
CC=golang-dev
https://golang.org/cl/1993043
parent ffdb855b
......@@ -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>")
}
......
......@@ -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)
}
......
......@@ -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)
})
}
......
......@@ -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 {
......
......@@ -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)
}
......@@ -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('+')
word, err := b.ReadSlice('+')
if err == nil {
w = w[0 : len(w)-1] // trim +
word = word[0 : len(word)-1] // trim +
}
pc, _ := strconv.Btoui64(string(w), 0)
pc, _ := strconv.Btoui64(string(word), 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())
}
}
......
This diff is collapsed.
......@@ -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]
}
......@@ -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())
}
}
......@@ -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")
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment