summaryrefslogtreecommitdiff
path: root/src/pkg/http/request.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
commite4bd81f903362d998f7bfc02095935408aff0bc5 (patch)
tree05f75a90e239d33be427da4f9c5596d2fcb3dc96 /src/pkg/http/request.go
parentd9527dd16f72598b54a64550607bf892efa12384 (diff)
downloadgolang-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.go246
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 ""
}