diff options
| author | Robert Griesemer <gri@golang.org> | 2009-12-15 15:35:38 -0800 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2009-12-15 15:35:38 -0800 |
| commit | e4bd81f903362d998f7bfc02095935408aff0bc5 (patch) | |
| tree | 05f75a90e239d33be427da4f9c5596d2fcb3dc96 /src/pkg/http/request.go | |
| parent | d9527dd16f72598b54a64550607bf892efa12384 (diff) | |
| download | golang-e4bd81f903362d998f7bfc02095935408aff0bc5.tar.gz | |
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
http://codereview.appspot.com/180048
Diffstat (limited to 'src/pkg/http/request.go')
| -rw-r--r-- | src/pkg/http/request.go | 246 |
1 files changed, 123 insertions, 123 deletions
diff --git a/src/pkg/http/request.go b/src/pkg/http/request.go index 83374a549..bf1e299d7 100644 --- a/src/pkg/http/request.go +++ b/src/pkg/http/request.go @@ -10,50 +10,50 @@ package http import ( - "bufio"; - "bytes"; - "container/vector"; - "fmt"; - "io"; - "io/ioutil"; - "os"; - "strconv"; - "strings"; + "bufio" + "bytes" + "container/vector" + "fmt" + "io" + "io/ioutil" + "os" + "strconv" + "strings" ) const ( - maxLineLength = 1024; // assumed < bufio.DefaultBufSize - maxValueLength = 1024; - maxHeaderLines = 1024; - chunkSize = 4 << 10; // 4 KB chunks + maxLineLength = 1024 // assumed < bufio.DefaultBufSize + maxValueLength = 1024 + maxHeaderLines = 1024 + chunkSize = 4 << 10 // 4 KB chunks ) // HTTP request parsing errors. type ProtocolError struct { - os.ErrorString; + os.ErrorString } var ( - ErrLineTooLong = &ProtocolError{"header line too long"}; - ErrHeaderTooLong = &ProtocolError{"header too long"}; - ErrShortBody = &ProtocolError{"entity body too short"}; + ErrLineTooLong = &ProtocolError{"header line too long"} + ErrHeaderTooLong = &ProtocolError{"header too long"} + ErrShortBody = &ProtocolError{"entity body too short"} ) type badStringError struct { - what string; - str string; + what string + str string } -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) } // A Request represents a parsed HTTP request header. type Request struct { - Method string; // GET, POST, PUT, etc. - RawURL string; // The raw URL given in the request. - URL *URL; // Parsed URL. - Proto string; // "HTTP/1.0" - ProtoMajor int; // 1 - ProtoMinor int; // 0 + Method string // GET, POST, PUT, etc. + RawURL string // The raw URL given in the request. + URL *URL // Parsed URL. + Proto string // "HTTP/1.0" + ProtoMajor int // 1 + ProtoMinor int // 0 // A header mapping request lines to their values. // If the header says @@ -74,18 +74,18 @@ type Request struct { // The request parser implements this by canonicalizing the // name, making the first character and any characters // following a hyphen uppercase and the rest lowercase. - Header map[string]string; + Header map[string]string // The message body. - Body io.Reader; + Body io.Reader // Whether to close the connection after replying to this request. - Close bool; + Close bool // The host on which the URL is sought. // Per RFC 2616, this is either the value of the Host: header // or the host name given in the URL itself. - Host string; + Host string // The referring URL, if sent in the request. // @@ -97,13 +97,13 @@ type Request struct { // can diagnose programs that use the alternate // (correct English) spelling req.Referrer but cannot // diagnose programs that use Header["Referrer"]. - Referer string; + Referer string // The User-Agent: header string, if sent in the request. - UserAgent string; + UserAgent string // The parsed form. Only available after ParseForm is called. - Form map[string][]string; + Form map[string][]string } // ProtoAtLeast returns whether the HTTP protocol used @@ -118,7 +118,7 @@ func valueOrDefault(value, def string) string { if value != "" { return value } - return def; + return def } const defaultUserAgent = "Go http package" @@ -134,14 +134,14 @@ const defaultUserAgent = "Go http package" // // If Body is present, "Transfer-Encoding: chunked" is forced as a header. func (req *Request) Write(w io.Writer) os.Error { - uri := URLEscape(req.URL.Path); + uri := URLEscape(req.URL.Path) if req.URL.RawQuery != "" { uri += "?" + req.URL.RawQuery } - fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), uri); - fmt.Fprintf(w, "Host: %s\r\n", req.URL.Host); - fmt.Fprintf(w, "User-Agent: %s\r\n", valueOrDefault(req.UserAgent, defaultUserAgent)); + fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), uri) + fmt.Fprintf(w, "Host: %s\r\n", req.URL.Host) + fmt.Fprintf(w, "User-Agent: %s\r\n", valueOrDefault(req.UserAgent, defaultUserAgent)) if req.Referer != "" { fmt.Fprintf(w, "Referer: %s\r\n", req.Referer) @@ -163,19 +163,19 @@ func (req *Request) Write(w io.Writer) os.Error { io.WriteString(w, k+": "+v+"\r\n") } - io.WriteString(w, "\r\n"); + io.WriteString(w, "\r\n") if req.Body != nil { - buf := make([]byte, chunkSize); + buf := make([]byte, chunkSize) Loop: for { - var nr, nw int; - var er, ew os.Error; + var nr, nw int + var er, ew os.Error if nr, er = req.Body.Read(buf); nr > 0 { if er == nil || er == os.EOF { - fmt.Fprintf(w, "%x\r\n", nr); - nw, ew = w.Write(buf[0:nr]); - fmt.Fprint(w, "\r\n"); + fmt.Fprintf(w, "%x\r\n", nr) + nw, ew = w.Write(buf[0:nr]) + fmt.Fprint(w, "\r\n") } } switch { @@ -183,7 +183,7 @@ func (req *Request) Write(w io.Writer) os.Error { if er == os.EOF { break Loop } - return er; + return er case ew != nil: return ew case nw < nr: @@ -191,10 +191,10 @@ func (req *Request) Write(w io.Writer) os.Error { } } // last-chunk CRLF - fmt.Fprint(w, "0\r\n\r\n"); + fmt.Fprint(w, "0\r\n\r\n") } - return nil; + return nil } // Read a line of bytes (up to \n) from b. @@ -208,29 +208,29 @@ func readLineBytes(b *bufio.Reader) (p []byte, err os.Error) { if err == os.EOF { err = io.ErrUnexpectedEOF } - return nil, err; + return nil, err } if len(p) >= maxLineLength { return nil, ErrLineTooLong } // Chop off trailing white space. - var i int; + var i int for i = len(p); i > 0; i-- { if c := p[i-1]; c != ' ' && c != '\r' && c != '\t' && c != '\n' { break } } - return p[0:i], nil; + return p[0:i], nil } // readLineBytes, but convert the bytes into a string. func readLine(b *bufio.Reader) (s string, err os.Error) { - p, e := readLineBytes(b); + p, e := readLineBytes(b) if e != nil { return "", e } - return string(p), nil; + return string(p), nil } var colon = []byte{':'} @@ -240,7 +240,7 @@ var colon = []byte{':'} // and the Value can continue on multiple lines if each continuation line // starts with a space. func readKeyValue(b *bufio.Reader) (key, value string, err os.Error) { - line, e := readLineBytes(b); + line, e := readLineBytes(b) if e != nil { return "", "", e } @@ -249,12 +249,12 @@ func readKeyValue(b *bufio.Reader) (key, value string, err os.Error) { } // Scan first line for colon. - i := bytes.Index(line, colon); + i := bytes.Index(line, colon) if i < 0 { goto Malformed } - key = string(line[0:i]); + key = string(line[0:i]) if strings.Index(key, " ") >= 0 { // Key field has space - no good. goto Malformed @@ -266,16 +266,16 @@ func readKeyValue(b *bufio.Reader) (key, value string, err os.Error) { break } } - value = string(line[i:]); + value = string(line[i:]) // Look for extension lines, which must begin with space. for { - c, e := b.ReadByte(); + c, e := b.ReadByte() if c != ' ' { if e != os.EOF { b.UnreadByte() } - break; + break } // Eat leading space. @@ -284,43 +284,43 @@ func readKeyValue(b *bufio.Reader) (key, value string, err os.Error) { if e == os.EOF { e = io.ErrUnexpectedEOF } - return "", "", e; + return "", "", e } } - b.UnreadByte(); + b.UnreadByte() // Read the rest of the line and add to value. if line, e = readLineBytes(b); e != nil { return "", "", e } - value += " " + string(line); + value += " " + string(line) if len(value) >= maxValueLength { return "", "", &badStringError{"value too long for key", key} } } - return key, value, nil; + return key, value, nil Malformed: - return "", "", &badStringError{"malformed header line", string(line)}; + return "", "", &badStringError{"malformed header line", string(line)} } // Convert decimal at s[i:len(s)] to integer, // returning value, string position where the digits stopped, // and whether there was a valid number (digits, not too big). func atoi(s string, i int) (n, i1 int, ok bool) { - const Big = 1000000; + const Big = 1000000 if i >= len(s) || s[i] < '0' || s[i] > '9' { return 0, 0, false } - n = 0; + n = 0 for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ { - n = n*10 + int(s[i]-'0'); + n = n*10 + int(s[i]-'0') if n > Big { return 0, 0, false } } - return n, i, true; + return n, i, true } // Parse HTTP version: "HTTP/1.2" -> (1, 2, true). @@ -328,16 +328,16 @@ func parseHTTPVersion(vers string) (int, int, bool) { if vers[0:5] != "HTTP/" { return 0, 0, false } - major, i, ok := atoi(vers, 5); + major, i, ok := atoi(vers, 5) if !ok || i >= len(vers) || vers[i] != '.' { return 0, 0, false } - var minor int; - minor, i, ok = atoi(vers, i+1); + var minor int + minor, i, ok = atoi(vers, i+1) if !ok || i != len(vers) { return 0, 0, false } - return major, minor, true; + return major, minor, true } var cmap = make(map[string]string) @@ -356,8 +356,8 @@ func CanonicalHeaderKey(s string) string { // and upper case after each dash. // (Host, User-Agent, If-Modified-Since). // HTTP headers are ASCII only, so no Unicode issues. - a := strings.Bytes(s); - upper := true; + a := strings.Bytes(s) + upper := true for i, v := range a { if upper && 'a' <= v && v <= 'z' { a[i] = v + 'A' - 'a' @@ -365,20 +365,20 @@ func CanonicalHeaderKey(s string) string { if !upper && 'A' <= v && v <= 'Z' { a[i] = v + 'a' - 'A' } - upper = false; + upper = false if v == '-' { upper = true } } - t := string(a); - cmap[s] = t; - return t; + t := string(a) + cmap[s] = t + return t } type chunkedReader struct { - r *bufio.Reader; - n uint64; // unread bytes in chunk - err os.Error; + r *bufio.Reader + n uint64 // unread bytes in chunk + err os.Error } func newChunkedReader(r *bufio.Reader) *chunkedReader { @@ -387,19 +387,19 @@ func newChunkedReader(r *bufio.Reader) *chunkedReader { func (cr *chunkedReader) beginChunk() { // chunk-size CRLF - var line string; - line, cr.err = readLine(cr.r); + var line string + line, cr.err = readLine(cr.r) if cr.err != nil { return } - cr.n, cr.err = strconv.Btoui64(line, 16); + cr.n, cr.err = strconv.Btoui64(line, 16) if cr.err != nil { return } if cr.n == 0 { // trailer CRLF for { - line, cr.err = readLine(cr.r); + line, cr.err = readLine(cr.r) if cr.err != nil { return } @@ -407,7 +407,7 @@ func (cr *chunkedReader) beginChunk() { break } } - cr.err = os.EOF; + cr.err = os.EOF } } @@ -416,7 +416,7 @@ func (cr *chunkedReader) Read(b []uint8) (n int, err os.Error) { return 0, cr.err } if cr.n == 0 { - cr.beginChunk(); + cr.beginChunk() if cr.err != nil { return 0, cr.err } @@ -424,36 +424,36 @@ func (cr *chunkedReader) Read(b []uint8) (n int, err os.Error) { if uint64(len(b)) > cr.n { b = b[0:cr.n] } - n, cr.err = cr.r.Read(b); - cr.n -= uint64(n); + n, cr.err = cr.r.Read(b) + cr.n -= uint64(n) if cr.n == 0 && cr.err == nil { // end of chunk (CRLF) - b := make([]byte, 2); + b := make([]byte, 2) if _, cr.err = io.ReadFull(cr.r, b); cr.err == nil { if b[0] != '\r' || b[1] != '\n' { cr.err = os.NewError("malformed chunked encoding") } } } - return n, cr.err; + return n, cr.err } // ReadRequest reads and parses a request from b. func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) { - req = new(Request); + req = new(Request) // First line: GET /index.html HTTP/1.0 - var s string; + var s string if s, err = readLine(b); err != nil { return nil, err } - var f []string; + var f []string if f = strings.Split(s, " ", 3); len(f) < 3 { return nil, &badStringError{"malformed HTTP request", s} } - req.Method, req.RawURL, req.Proto = f[0], f[1], f[2]; - var ok bool; + req.Method, req.RawURL, req.Proto = f[0], f[1], f[2] + var ok bool if req.ProtoMajor, req.ProtoMinor, ok = parseHTTPVersion(req.Proto); !ok { return nil, &badStringError{"malformed HTTP version", req.Proto} } @@ -463,10 +463,10 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) { } // Subsequent lines: Key: value. - nheader := 0; - req.Header = make(map[string]string); + nheader := 0 + req.Header = make(map[string]string) for { - var key, value string; + var key, value string if key, value, err = readKeyValue(b); err != nil { return nil, err } @@ -477,12 +477,12 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) { return nil, ErrHeaderTooLong } - key = CanonicalHeaderKey(key); + key = CanonicalHeaderKey(key) // RFC 2616 says that if you send the same header key // multiple times, it has to be semantically equivalent // to concatenating the values separated by commas. - oldvalue, present := req.Header[key]; + oldvalue, present := req.Header[key] if present { req.Header[key] = oldvalue + "," + value } else { @@ -561,30 +561,30 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) { if v, present := req.Header["Transfer-Encoding"]; present && v == "chunked" { req.Body = newChunkedReader(b) } else if v, present := req.Header["Content-Length"]; present { - length, err := strconv.Btoui64(v, 10); + length, err := strconv.Btoui64(v, 10) if err != nil { return nil, &badStringError{"invalid Content-Length", v} } // TODO: limit the Content-Length. This is an easy DoS vector. - raw := make([]byte, length); - n, err := b.Read(raw); + raw := make([]byte, length) + n, err := b.Read(raw) if err != nil || uint64(n) < length { return nil, ErrShortBody } - req.Body = bytes.NewBuffer(raw); + req.Body = bytes.NewBuffer(raw) } - return req, nil; + return req, nil } func parseForm(m map[string][]string, query string) (err os.Error) { - data := make(map[string]*vector.StringVector); + data := make(map[string]*vector.StringVector) for _, kv := range strings.Split(query, "&", 0) { - kvPair := strings.Split(kv, "=", 2); + kvPair := strings.Split(kv, "=", 2) - var key, value string; - var e os.Error; - key, e = URLUnescape(kvPair[0]); + var key, value string + var e os.Error + key, e = URLUnescape(kvPair[0]) if e == nil && len(kvPair) > 1 { value, e = URLUnescape(kvPair[1]) } @@ -592,19 +592,19 @@ func parseForm(m map[string][]string, query string) (err os.Error) { err = e } - vec, ok := data[key]; + vec, ok := data[key] if !ok { - vec = new(vector.StringVector); - data[key] = vec; + vec = new(vector.StringVector) + data[key] = vec } - vec.Push(value); + vec.Push(value) } for k, vec := range data { m[k] = vec.Data() } - return; + return } // ParseForm parses the request body as a form for POST requests, or the raw query for GET requests. @@ -613,9 +613,9 @@ func (r *Request) ParseForm() (err os.Error) { if r.Form != nil { return } - r.Form = make(map[string][]string); + r.Form = make(map[string][]string) - var query string; + var query string switch r.Method { case "GET": query = r.URL.RawQuery @@ -623,20 +623,20 @@ func (r *Request) ParseForm() (err os.Error) { if r.Body == nil { return os.ErrorString("missing form body") } - ct, _ := r.Header["Content-Type"]; + ct, _ := r.Header["Content-Type"] switch strings.Split(ct, ";", 2)[0] { case "text/plain", "application/x-www-form-urlencoded", "": - var b []byte; + var b []byte if b, err = ioutil.ReadAll(r.Body); err != nil { return err } - query = string(b); + query = string(b) // TODO(dsymonds): Handle multipart/form-data default: return &badStringError{"unknown Content-Type", ct} } } - return parseForm(r.Form, query); + return parseForm(r.Form, query) } // FormValue returns the first value for the named component of the query. @@ -648,5 +648,5 @@ func (r *Request) FormValue(key string) string { if vs, ok := r.Form[key]; ok && len(vs) > 0 { return vs[0] } - return ""; + return "" } |
