aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/http/server.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2009-12-15 15:35:38 -0800
committerRobert Griesemer <gri@golang.org>2009-12-15 15:35:38 -0800
commita3d1045fb7b34355c9859aea2781e0d77004cc82 (patch)
treea24912cd4769ba851226128e42eebf00deabbf30 /src/pkg/http/server.go
parent5a1d3323fe2032beb0b429f44b9356e8ca43fdf7 (diff)
downloadgo-a3d1045fb7b34355c9859aea2781e0d77004cc82.tar.xz
1) Change default gofmt default settings for
parsing and printing to new syntax. Use -oldparser to parse the old syntax, use -oldprinter to print the old syntax. 2) Change default gofmt formatting settings to use tabs for indentation only and to use spaces for alignment. This will make the code alignment insensitive to an editor's tabwidth. Use -spaces=false to use tabs for alignment. 3) Manually changed src/exp/parser/parser_test.go so that it doesn't try to parse the parser's source files using the old syntax (they have new syntax now). 4) gofmt -w src misc test/bench 3rd set of files. R=rsc CC=golang-dev https://golang.org/cl/180048
Diffstat (limited to 'src/pkg/http/server.go')
-rw-r--r--src/pkg/http/server.go254
1 files changed, 127 insertions, 127 deletions
diff --git a/src/pkg/http/server.go b/src/pkg/http/server.go
index 9178d5438c..f9771f9b41 100644
--- a/src/pkg/http/server.go
+++ b/src/pkg/http/server.go
@@ -12,61 +12,61 @@
package http
import (
- "bufio";
- "fmt";
- "io";
- "log";
- "net";
- "os";
- "path";
- "strconv";
- "strings";
+ "bufio"
+ "fmt"
+ "io"
+ "log"
+ "net"
+ "os"
+ "path"
+ "strconv"
+ "strings"
)
// Errors introduced by the HTTP server.
var (
- ErrWriteAfterFlush = os.NewError("Conn.Write called after Flush");
- ErrHijacked = os.NewError("Conn has been hijacked");
+ ErrWriteAfterFlush = os.NewError("Conn.Write called after Flush")
+ ErrHijacked = os.NewError("Conn has been hijacked")
)
// Objects implementing the Handler interface can be
// registered to serve a particular path or subtree
// in the HTTP server.
type Handler interface {
- ServeHTTP(*Conn, *Request);
+ ServeHTTP(*Conn, *Request)
}
// A Conn represents the server side of a single active HTTP connection.
type Conn struct {
- RemoteAddr string; // network address of remote side
- Req *Request; // current HTTP request
+ RemoteAddr string // network address of remote side
+ Req *Request // current HTTP request
- rwc io.ReadWriteCloser; // i/o connection
- buf *bufio.ReadWriter; // buffered rwc
- handler Handler; // request handler
- hijacked bool; // connection has been hijacked by handler
+ rwc io.ReadWriteCloser // i/o connection
+ buf *bufio.ReadWriter // buffered rwc
+ handler Handler // request handler
+ hijacked bool // connection has been hijacked by handler
// state for the current reply
- closeAfterReply bool; // close connection after this reply
- chunking bool; // using chunked transfer encoding for reply body
- wroteHeader bool; // reply header has been written
- header map[string]string; // reply header parameters
- written int64; // number of bytes written in body
- status int; // status code passed to WriteHeader
+ closeAfterReply bool // close connection after this reply
+ chunking bool // using chunked transfer encoding for reply body
+ wroteHeader bool // reply header has been written
+ header map[string]string // reply header parameters
+ written int64 // number of bytes written in body
+ status int // status code passed to WriteHeader
}
// Create new connection from rwc.
func newConn(rwc net.Conn, handler Handler) (c *Conn, err os.Error) {
- c = new(Conn);
+ c = new(Conn)
if a := rwc.RemoteAddr(); a != nil {
c.RemoteAddr = a.String()
}
- c.handler = handler;
- c.rwc = rwc;
- br := bufio.NewReader(rwc);
- bw := bufio.NewWriter(rwc);
- c.buf = bufio.NewReadWriter(br, bw);
- return c, nil;
+ c.handler = handler
+ c.rwc = rwc
+ br := bufio.NewReader(rwc)
+ bw := bufio.NewWriter(rwc)
+ c.buf = bufio.NewReadWriter(br, bw)
+ return c, nil
}
// Read next request from connection.
@@ -79,18 +79,18 @@ func (c *Conn) readRequest() (req *Request, err os.Error) {
}
// Reset per-request connection state.
- c.header = make(map[string]string);
- c.wroteHeader = false;
- c.Req = req;
+ c.header = make(map[string]string)
+ c.wroteHeader = false
+ c.Req = req
// Default output is HTML encoded in UTF-8.
- c.SetHeader("Content-Type", "text/html; charset=utf-8");
+ c.SetHeader("Content-Type", "text/html; charset=utf-8")
if req.ProtoAtLeast(1, 1) {
// HTTP/1.1 or greater: use chunked transfer encoding
// to avoid closing the connection at EOF.
- c.chunking = true;
- c.SetHeader("Transfer-Encoding", "chunked");
+ c.chunking = true
+ c.SetHeader("Transfer-Encoding", "chunked")
} else {
// HTTP version < 1.1: cannot do chunked transfer
// encoding, so signal EOF by closing connection.
@@ -98,11 +98,11 @@ func (c *Conn) readRequest() (req *Request, err os.Error) {
// a Content-Length: header in the response,
// but everyone who expects persistent connections
// does HTTP/1.1 now.
- c.closeAfterReply = true;
- c.chunking = false;
+ c.closeAfterReply = true
+ c.chunking = false
}
- return req, nil;
+ return req, nil
}
// SetHeader sets a header line in the eventual reply.
@@ -115,7 +115,7 @@ func (c *Conn) readRequest() (req *Request, err os.Error) {
// Content-Type in this library, so users need not make that
// particular call. Calls to SetHeader after WriteHeader (or Write)
// are ignored.
-func (c *Conn) SetHeader(hdr, val string) { c.header[CanonicalHeaderKey(hdr)] = val }
+func (c *Conn) SetHeader(hdr, val string) { c.header[CanonicalHeaderKey(hdr)] = val }
// WriteHeader sends an HTTP response header with status code.
// If WriteHeader is not called explicitly, the first call to Write
@@ -124,33 +124,33 @@ func (c *Conn) SetHeader(hdr, val string) { c.header[CanonicalHeaderKey(hdr)] =
// send error codes.
func (c *Conn) WriteHeader(code int) {
if c.hijacked {
- log.Stderr("http: Conn.WriteHeader on hijacked connection");
- return;
+ log.Stderr("http: Conn.WriteHeader on hijacked connection")
+ return
}
if c.wroteHeader {
- log.Stderr("http: multiple Conn.WriteHeader calls");
- return;
+ log.Stderr("http: multiple Conn.WriteHeader calls")
+ return
}
- c.wroteHeader = true;
- c.status = code;
- c.written = 0;
+ c.wroteHeader = true
+ c.status = code
+ c.written = 0
if !c.Req.ProtoAtLeast(1, 0) {
return
}
- proto := "HTTP/1.0";
+ proto := "HTTP/1.0"
if c.Req.ProtoAtLeast(1, 1) {
proto = "HTTP/1.1"
}
- codestring := strconv.Itoa(code);
- text, ok := statusText[code];
+ codestring := strconv.Itoa(code)
+ text, ok := statusText[code]
if !ok {
text = "status code " + codestring
}
- io.WriteString(c.buf, proto+" "+codestring+" "+text+"\r\n");
+ io.WriteString(c.buf, proto+" "+codestring+" "+text+"\r\n")
for k, v := range c.header {
io.WriteString(c.buf, k+": "+v+"\r\n")
}
- io.WriteString(c.buf, "\r\n");
+ io.WriteString(c.buf, "\r\n")
}
// Write writes the data to the connection as part of an HTTP reply.
@@ -158,8 +158,8 @@ func (c *Conn) WriteHeader(code int) {
// before writing the data.
func (c *Conn) Write(data []byte) (n int, err os.Error) {
if c.hijacked {
- log.Stderr("http: Conn.Write on hijacked connection");
- return 0, ErrHijacked;
+ log.Stderr("http: Conn.Write on hijacked connection")
+ return 0, ErrHijacked
}
if !c.wroteHeader {
c.WriteHeader(StatusOK)
@@ -168,15 +168,15 @@ func (c *Conn) Write(data []byte) (n int, err os.Error) {
return 0, nil
}
- c.written += int64(len(data)); // ignoring errors, for errorKludge
+ c.written += int64(len(data)) // ignoring errors, for errorKludge
// TODO(rsc): if chunking happened after the buffering,
// then there would be fewer chunk headers.
// On the other hand, it would make hijacking more difficult.
if c.chunking {
- fmt.Fprintf(c.buf, "%x\r\n", len(data)) // TODO(rsc): use strconv not fmt
+ fmt.Fprintf(c.buf, "%x\r\n", len(data)) // TODO(rsc): use strconv not fmt
}
- n, err = c.buf.Write(data);
+ n, err = c.buf.Write(data)
if err == nil && c.chunking {
if n != len(data) {
err = io.ErrShortWrite
@@ -186,7 +186,7 @@ func (c *Conn) Write(data []byte) (n int, err os.Error) {
}
}
- return n, err;
+ return n, err
}
// If this is an error reply (4xx or 5xx)
@@ -197,7 +197,7 @@ func (c *Conn) Write(data []byte) (n int, err os.Error) {
// browsers are in the 256-512 range.
// Pad to 1024 bytes.
func errorKludge(c *Conn, req *Request) {
- const min = 1024;
+ const min = 1024
// Is this an error?
if kind := c.status / 100; kind != 4 && kind != 5 {
@@ -210,7 +210,7 @@ func errorKludge(c *Conn, req *Request) {
}
// Is it a broken browser?
- var msg string;
+ var msg string
switch agent := req.UserAgent; {
case strings.Index(agent, "MSIE") >= 0:
msg = "Internet Explorer"
@@ -219,19 +219,19 @@ func errorKludge(c *Conn, req *Request) {
default:
return
}
- msg += " would ignore this error page if this text weren't here.\n";
+ msg += " would ignore this error page if this text weren't here.\n"
// Is it text? ("Content-Type" is always in the map)
- baseType := strings.Split(c.header["Content-Type"], ";", 2)[0];
+ baseType := strings.Split(c.header["Content-Type"], ";", 2)[0]
switch baseType {
case "text/html":
- io.WriteString(c, "<!-- ");
+ io.WriteString(c, "<!-- ")
for c.written < min {
io.WriteString(c, msg)
}
- io.WriteString(c, " -->");
+ io.WriteString(c, " -->")
case "text/plain":
- io.WriteString(c, "\n");
+ io.WriteString(c, "\n")
for c.written < min {
io.WriteString(c, msg)
}
@@ -242,13 +242,13 @@ func (c *Conn) finishRequest() {
if !c.wroteHeader {
c.WriteHeader(StatusOK)
}
- errorKludge(c, c.Req);
+ errorKludge(c, c.Req)
if c.chunking {
- io.WriteString(c.buf, "0\r\n");
+ io.WriteString(c.buf, "0\r\n")
// trailer key/value pairs, followed by blank line
- io.WriteString(c.buf, "\r\n");
+ io.WriteString(c.buf, "\r\n")
}
- c.buf.Flush();
+ c.buf.Flush()
}
// Flush sends any buffered data to the client.
@@ -256,41 +256,41 @@ func (c *Conn) Flush() {
if !c.wroteHeader {
c.WriteHeader(StatusOK)
}
- c.buf.Flush();
+ c.buf.Flush()
}
// Close the connection.
func (c *Conn) close() {
if c.buf != nil {
- c.buf.Flush();
- c.buf = nil;
+ c.buf.Flush()
+ c.buf = nil
}
if c.rwc != nil {
- c.rwc.Close();
- c.rwc = nil;
+ c.rwc.Close()
+ c.rwc = nil
}
}
// Serve a new connection.
func (c *Conn) serve() {
for {
- req, err := c.readRequest();
+ req, err := c.readRequest()
if err != nil {
break
}
// HTTP cannot have multiple simultaneous active requests.
// Until the server replies to this request, it can't read another,
// so we might as well run the handler in this goroutine.
- c.handler.ServeHTTP(c, req);
+ c.handler.ServeHTTP(c, req)
if c.hijacked {
return
}
- c.finishRequest();
+ c.finishRequest()
if c.closeAfterReply {
break
}
}
- c.close();
+ c.close()
}
// Hijack lets the caller take over the connection.
@@ -302,12 +302,12 @@ func (c *Conn) Hijack() (rwc io.ReadWriteCloser, buf *bufio.ReadWriter, err os.E
if c.hijacked {
return nil, nil, ErrHijacked
}
- c.hijacked = true;
- rwc = c.rwc;
- buf = c.buf;
- c.rwc = nil;
- c.buf = nil;
- return;
+ c.hijacked = true
+ rwc = c.rwc
+ buf = c.buf
+ c.rwc = nil
+ c.buf = nil
+ return
}
// The HandlerFunc type is an adapter to allow the use of
@@ -325,26 +325,26 @@ func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
// NotFound replies to the request with an HTTP 404 not found error.
func NotFound(c *Conn, req *Request) {
- c.SetHeader("Content-Type", "text/plain; charset=utf-8");
- c.WriteHeader(StatusNotFound);
- io.WriteString(c, "404 page not found\n");
+ c.SetHeader("Content-Type", "text/plain; charset=utf-8")
+ c.WriteHeader(StatusNotFound)
+ io.WriteString(c, "404 page not found\n")
}
// NotFoundHandler returns a simple request handler
// that replies to each request with a ``404 page not found'' reply.
-func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
+func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
// Redirect replies to the request with a redirect to url,
// which may be a path relative to the request path.
func Redirect(c *Conn, url string, code int) {
// RFC2616 recommends that a short note "SHOULD" be included in the
// response because older user agents may not understand 301/307.
- note := "<a href=\"%v\">" + statusText[code] + "</a>.\n";
+ note := "<a href=\"%v\">" + statusText[code] + "</a>.\n"
if c.Req.Method == "POST" {
note = ""
}
- u, err := ParseURL(url);
+ u, err := ParseURL(url)
if err != nil {
goto finish
}
@@ -365,36 +365,36 @@ func Redirect(c *Conn, url string, code int) {
// Because of this problem, no one pays attention
// to the RFC; they all send back just a new path.
// So do we.
- oldpath := c.Req.URL.Path;
- if oldpath == "" { // should not happen, but avoid a crash if it does
+ oldpath := c.Req.URL.Path
+ if oldpath == "" { // should not happen, but avoid a crash if it does
oldpath = "/"
}
if u.Scheme == "" {
// no leading http://server
if url == "" || url[0] != '/' {
// make relative path absolute
- olddir, _ := path.Split(oldpath);
- url = olddir + url;
+ olddir, _ := path.Split(oldpath)
+ url = olddir + url
}
// clean up but preserve trailing slash
- trailing := url[len(url)-1] == '/';
- url = path.Clean(url);
+ trailing := url[len(url)-1] == '/'
+ url = path.Clean(url)
if trailing && url[len(url)-1] != '/' {
url += "/"
}
}
finish:
- c.SetHeader("Location", url);
- c.WriteHeader(code);
- fmt.Fprintf(c, note, url);
+ c.SetHeader("Location", url)
+ c.WriteHeader(code)
+ fmt.Fprintf(c, note, url)
}
// Redirect to a fixed URL
type redirectHandler struct {
- url string;
- code int;
+ url string
+ code int
}
func (rh *redirectHandler) ServeHTTP(c *Conn, req *Request) {
@@ -433,11 +433,11 @@ func RedirectHandler(url string, code int) Handler {
// redirecting any request containing . or .. elements to an
// equivalent .- and ..-free URL.
type ServeMux struct {
- m map[string]Handler;
+ m map[string]Handler
}
// NewServeMux allocates and returns a new ServeMux.
-func NewServeMux() *ServeMux { return &ServeMux{make(map[string]Handler)} }
+func NewServeMux() *ServeMux { return &ServeMux{make(map[string]Handler)} }
// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = NewServeMux()
@@ -448,11 +448,11 @@ func pathMatch(pattern, path string) bool {
// should not happen
return false
}
- n := len(pattern);
+ n := len(pattern)
if pattern[n-1] != '/' {
return pattern == path
}
- return len(path) >= n && path[0:n] == pattern;
+ return len(path) >= n && path[0:n] == pattern
}
// Return the canonical path for p, eliminating . and .. elements.
@@ -463,13 +463,13 @@ func cleanPath(p string) string {
if p[0] != '/' {
p = "/" + p
}
- np := path.Clean(p);
+ np := path.Clean(p)
// path.Clean removes trailing slash except for root;
// put the trailing slash back if necessary.
if p[len(p)-1] == '/' && np != "/" {
np += "/"
}
- return np;
+ return np
}
// ServeHTTP dispatches the request to the handler whose
@@ -477,27 +477,27 @@ func cleanPath(p string) string {
func (mux *ServeMux) ServeHTTP(c *Conn, req *Request) {
// Clean path to canonical form and redirect.
if p := cleanPath(req.URL.Path); p != req.URL.Path {
- c.SetHeader("Location", p);
- c.WriteHeader(StatusMovedPermanently);
- return;
+ c.SetHeader("Location", p)
+ c.WriteHeader(StatusMovedPermanently)
+ return
}
// Most-specific (longest) pattern wins.
- var h Handler;
- var n = 0;
+ var h Handler
+ var n = 0
for k, v := range mux.m {
if !pathMatch(k, req.URL.Path) {
continue
}
if h == nil || len(k) > n {
- n = len(k);
- h = v;
+ n = len(k)
+ h = v
}
}
if h == nil {
h = NotFoundHandler()
}
- h.ServeHTTP(c, req);
+ h.ServeHTTP(c, req)
}
// Handle registers the handler for the given pattern.
@@ -506,11 +506,11 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) {
panicln("http: invalid pattern", pattern)
}
- mux.m[pattern] = handler;
+ mux.m[pattern] = handler
// Helpful behavior:
// If pattern is /tree/, insert permanent redirect for /tree.
- n := len(pattern);
+ n := len(pattern)
if n > 0 && pattern[n-1] == '/' {
mux.m[pattern[0:n-1]] = RedirectHandler(pattern, StatusMovedPermanently)
}
@@ -518,7 +518,7 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) {
// Handle registers the handler for the given pattern
// in the DefaultServeMux.
-func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
+func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
// Serve accepts incoming HTTP connections on the listener l,
// creating a new service thread for each. The service threads
@@ -529,17 +529,17 @@ func Serve(l net.Listener, handler Handler) os.Error {
handler = DefaultServeMux
}
for {
- rw, e := l.Accept();
+ rw, e := l.Accept()
if e != nil {
return e
}
- c, err := newConn(rw, handler);
+ c, err := newConn(rw, handler)
if err != nil {
continue
}
- go c.serve();
+ go c.serve()
}
- panic("not reached");
+ panic("not reached")
}
// ListenAndServe listens on the TCP network address addr
@@ -569,11 +569,11 @@ func Serve(l net.Listener, handler Handler) os.Error {
// }
// }
func ListenAndServe(addr string, handler Handler) os.Error {
- l, e := net.Listen("tcp", addr);
+ l, e := net.Listen("tcp", addr)
if e != nil {
return e
}
- e = Serve(l, handler);
- l.Close();
- return e;
+ e = Serve(l, handler)
+ l.Close()
+ return e
}