]> Cypherpunks repositories - gostls13.git/commitdiff
document http
authorRuss Cox <rsc@golang.org>
Wed, 11 Mar 2009 19:45:53 +0000 (12:45 -0700)
committerRuss Cox <rsc@golang.org>
Wed, 11 Mar 2009 19:45:53 +0000 (12:45 -0700)
R=r
DELTA=84  (63 added, 4 deleted, 17 changed)
OCL=25950
CL=26126

src/lib/http/request.go
src/lib/http/status.go
src/lib/http/url.go

index 5d1fd67d7221a0077e2693283d8b904f9931e434..a2720ff01b1a5ee9cd996be8e9b83244bec224a0 100644 (file)
@@ -4,6 +4,11 @@
 
 // HTTP Request reading and parsing.
 
+// The http package implements parsing of HTTP requests and URLs
+// and provides an extensible HTTP server.
+//
+// In the future it should also implement parsing of HTTP replies
+// and provide methods to fetch URLs via HTTP.
 package http
 
 import (
@@ -20,6 +25,7 @@ const (
        maxHeaderLines = 1024;
 )
 
+// HTTP request parsing errors.
 var (
        LineTooLong = os.NewError("http header line too long");
        ValueTooLong = os.NewError("http header value too long");
@@ -29,29 +35,67 @@ var (
        BadHTTPVersion = os.NewError("unsupported http version");
 )
 
-// HTTP Request
+// A Request represents a parsed HTTP request header.
 type Request struct {
        Method string;          // GET, PUT,etc.
-       RawUrl string;
-       Url *URL;               // URI after GET, PUT etc.
+       RawUrl string;          // The raw URL given in the request.
+       Url *URL;               // URL after GET, PUT etc.
        Proto string;   // "HTTP/1.0"
        ProtoMajor int; // 1
        ProtoMinor int; // 0
 
+       // A header mapping request lines to their values.
+       // If the header says
+       //
+       //      Accept-Language: en-us
+       //      accept-encoding: gzip, deflate
+       //      Connection: keep-alive
+       //
+       // then
+       //
+       //      Header = map[string]string{
+       //              "Accept-Encoding": "en-us",
+       //              "Accept-Language": "gzip, deflate",
+       //              "Connection": "keep-alive"
+       //      }
+       //
+       // HTTP defines that header names are case-insensitive.
+       // 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;
 
+       // Whether to close the connection after replying to this request.
        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;
-       Referer string; // referer [sic]
+
+       // The referring URL, if sent in the request.
+       //
+       // Referer is misspelled as in the request itself,
+       // a mistake from the earliest days of HTTP.
+       // This value can also be fetched from the Header map
+       // as Header["Referer"]; the benefit of making it
+       // available as a structure field is that the compiler
+       // can diagnose programs that use the alternate
+       // (correct English) spelling req.Referrer but cannot
+       // diagnose programs that use Header["Referrer"].
+       Referer string;
+
+       // The User-Agent: header string, if sent in the request.
        UserAgent string;
 }
 
+// ProtoAtLeast returns whether the HTTP protocol used
+// in the request is at least major.minor.
 func (r *Request) ProtoAtLeast(major, minor int) bool {
        return r.ProtoMajor > major ||
                r.ProtoMajor == major && r.ProtoMinor >= minor
 }
 
-
 // Read a line of bytes (up to \n) from b.
 // Give up if the line exceeds maxLineLength.
 // The returned bytes are a pointer into storage in
@@ -188,6 +232,11 @@ func parseHTTPVersion(vers string) (int, int, bool) {
 
 var cmap = make(map[string]string)
 
+// CanonicalHeaderKey returns the canonical format of the
+// HTTP header key s.  The canonicalization converts the first
+// letter and any letter following a hyphen to upper case;
+// the rest are converted to lowercase.  For example, the
+// canonical key for "accept-encoding" is "Accept-Encoding".
 func CanonicalHeaderKey(s string) string {
        if t, ok := cmap[s]; ok {
                return t;
@@ -216,8 +265,7 @@ func CanonicalHeaderKey(s string) string {
        return t;
 }
 
-
-// Read and parse a request from b.
+// ReadRequest reads and parses a request from b.
 func ReadRequest(b *bufio.BufRead) (req *Request, err *os.Error) {
        req = new(Request);
 
index 82a8b214c4625da0560a58054307d76051ae654a..6d1c5ab28ad9098b0a773e4d6bf2173b01e87dc7 100644 (file)
@@ -2,10 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// HTTP status codes.  See RFC 2616.
-
 package http
 
+// HTTP status codes, defined in RFC 2616.
 const (
        StatusContinue = 100;
        StatusSwitchingProtocols = 101;
index f0a94d68bc18a28acdbb638a9f272015bc223f71..0b2e9783ad388598465b486f94dea63de6bb3de0 100644 (file)
@@ -12,6 +12,7 @@ import (
        "strings"
 )
 
+// Errors introduced by ParseURL.
 var (
        BadURL = os.NewError("bad url syntax")
 )
@@ -40,7 +41,10 @@ func unhex(c byte) byte {
        return 0
 }
 
-// Unescape %xx into hex.
+// URLUnescape unescapes a URL-encoded string,
+// converting %AB into the byte 0xAB.
+// It returns a BadURL error if each % is not followed
+// by two hexadecimal digits.
 func URLUnescape(s string) (string, *os.Error) {
        // Count %, check that they're well-formed.
        n := 0;
@@ -76,16 +80,19 @@ func URLUnescape(s string) (string, *os.Error) {
        return string(t), nil;
 }
 
+// A URL represents a parsed URL (technically, a URI reference).
+// The general form represented is:
+//     scheme://[userinfo@]host/path[?query][#fragment]
 type URL struct {
-       Raw string;
-       Scheme string;
-       RawPath string;
-       Authority string;
-       Userinfo string;
-       Host string;
-       Path string;
-       Query string;
-       Fragment string;
+       Raw string;             // the original string
+       Scheme string;          // scheme
+       RawPath string;         // //[userinfo@]host/path[?query][#fragment]
+       Authority string;       // [userinfo@]host
+       Userinfo string;        // userinfo
+       Host string;            // host
+       Path string;            // /path
+       Query string;           // query
+       Fragment string;        // fragment
 }
 
 // Maybe rawurl is of the form scheme:path.
@@ -126,7 +133,12 @@ func split(s string, c byte, cutc bool) (string, string) {
        return s, ""
 }
 
-// Parse rawurl into a URL structure.
+// BUG(rsc): ParseURL should canonicalize the path,
+// removing unnecessary . and .. elements.
+
+// ParseURL parses rawurl into a URL structure.
+// The string rawurl is assumed not to have a #fragment suffix.
+// (Web browsers strip #fragment before sending the URL to a web server.)
 func ParseURL(rawurl string) (url *URL, err *os.Error) {
        if rawurl == "" {
                return nil, BadURL
@@ -171,7 +183,7 @@ func ParseURL(rawurl string) (url *URL, err *os.Error) {
        return url, nil
 }
 
-// A URL reference is a URL with #frag potentially added.  Parse it.
+// ParseURLReference is like ParseURL but allows a trailing #fragment.
 func ParseURLReference(rawurlref string) (url *URL, err *os.Error) {
        // Cut off #frag.
        rawurl, frag := split(rawurlref, '#', true);