)
// The size of an Adler-32 checksum in bytes.
-const Size = 4;
+const Size = 4
// digest represents the partial evaluation of a checksum.
type digest struct {
a += uint32(p[i]);
b += a;
// invariant: a <= b
- if b > (0xffffffff - 255) / 2 {
+ if b > (0xffffffff - 255)/2 {
a %= mod;
b %= mod;
// invariant: a < mod && b < mod
)
// TODO this should be in a mime package somewhere
-var contentByExt = map[string] string {
- ".css": "text/css",
- ".gif": "image/gif",
- ".html": "text/html; charset=utf-8",
- ".jpg": "image/jpeg",
- ".js": "application/x-javascript",
- ".pdf": "application/pdf",
- ".png": "image/png",
+var contentByExt = map[string]string{
+ ".css": "text/css",
+ ".gif": "image/gif",
+ ".html": "text/html; charset=utf-8",
+ ".jpg": "image/jpeg",
+ ".js": "application/x-javascript",
+ ".pdf": "application/pdf",
+ ".png": "image/png",
}
// Heuristic: b is text if it is valid UTF-8 and doesn't
for {
dirs, err := f.Readdir(100);
if err != nil || len(dirs) == 0 {
- break
+ break;
}
for _, d := range dirs {
name := d.Name;
if d.IsDirectory() {
- name += "/"
+ name += "/";
}
// TODO htmlescape
fmt.Fprintf(c, "<a href=\"%s\">%s</a>\n", name, name);
const indexPage = "/index.html";
// redirect to strip off any index.html
- n := len(name) - len(indexPage);
+ n := len(name)-len(indexPage);
if n >= 0 && name[n:len(name)] == indexPage {
- Redirect(c, name[0:n+1], StatusMovedPermanently);
+ Redirect(c, name[0 : n+1], StatusMovedPermanently);
return;
}
url := r.Url.Path;
if d.IsDirectory() {
if url[len(url)-1] != '/' {
- Redirect(c, url + "/", StatusMovedPermanently);
+ Redirect(c, url+"/", StatusMovedPermanently);
return;
}
} else {
if url[len(url)-1] == '/' {
- Redirect(c, url[0:len(url)-1], StatusMovedPermanently);
+ Redirect(c, url[0 : len(url)-1], StatusMovedPermanently);
return;
}
}
}
type fileHandler struct {
- root string;
- prefix string;
+ root string;
+ prefix string;
}
// FileServer returns a handler that serves HTTP requests
path = path[len(f.prefix):len(path)];
serveFileInternal(c, r, f.root + "/" + path, true);
}
-
func TestRedirect(t *testing.T) {
const (
- start = "http://codesearch.google.com/";
- end = "http://www.google.com/codesearch";
+ start = "http://codesearch.google.com/";
+ end = "http://www.google.com/codesearch";
)
r, url, err := Get(start);
if err != nil {
}
r.Body.Close();
if r.StatusCode != 200 || url != end {
- t.Fatalf("Get(%s) got status %d at %s, want 200 at %s", start, r.StatusCode, url, end)
+ t.Fatalf("Get(%s) got status %d at %s, want 200 at %s", start, r.StatusCode, url, end);
}
}
// HTTP status codes, defined in RFC 2616.
const (
- StatusContinue = 100;
- StatusSwitchingProtocols = 101;
+ StatusContinue = 100;
+ StatusSwitchingProtocols = 101;
- StatusOK = 200;
- StatusCreated = 201;
- StatusAccepted = 202;
- StatusNonAuthoritativeInfo = 203;
- StatusNoContent = 204;
- StatusResetContent = 205;
- StatusPartialContent = 206;
+ StatusOK = 200;
+ StatusCreated = 201;
+ StatusAccepted = 202;
+ StatusNonAuthoritativeInfo = 203;
+ StatusNoContent = 204;
+ StatusResetContent = 205;
+ StatusPartialContent = 206;
- StatusMultipleChoices = 300;
- StatusMovedPermanently = 301;
- StatusFound = 302;
- StatusSeeOther = 303;
- StatusNotModified = 304;
- StatusUseProxy = 305;
- StatusTemporaryRedirect = 307;
+ StatusMultipleChoices = 300;
+ StatusMovedPermanently = 301;
+ StatusFound = 302;
+ StatusSeeOther = 303;
+ StatusNotModified = 304;
+ StatusUseProxy = 305;
+ StatusTemporaryRedirect = 307;
- StatusBadRequest = 400;
- StatusUnauthorized = 401;
- StatusPaymentRequired = 402;
- StatusForbidden = 403;
- StatusNotFound = 404;
- StatusMethodNotAllowed = 405;
- StatusNotAcceptable = 406;
- StatusProxyAuthRequired = 407;
- StatusRequestTimeout = 408;
- StatusConflict = 409;
- StatusGone = 410;
- StatusLengthRequired = 411;
- StatusPreconditionFailed = 412;
- StatusRequestEntityTooLarge = 413;
- StatusRequestURITooLong = 414;
- StatusUnsupportedMediaType = 415;
- StatusRequestedRangeNotSatisfiable = 416;
- StatusExpectationFailed = 417;
+ StatusBadRequest = 400;
+ StatusUnauthorized = 401;
+ StatusPaymentRequired = 402;
+ StatusForbidden = 403;
+ StatusNotFound = 404;
+ StatusMethodNotAllowed = 405;
+ StatusNotAcceptable = 406;
+ StatusProxyAuthRequired = 407;
+ StatusRequestTimeout = 408;
+ StatusConflict = 409;
+ StatusGone = 410;
+ StatusLengthRequired = 411;
+ StatusPreconditionFailed = 412;
+ StatusRequestEntityTooLarge = 413;
+ StatusRequestURITooLong = 414;
+ StatusUnsupportedMediaType = 415;
+ StatusRequestedRangeNotSatisfiable = 416;
+ StatusExpectationFailed = 417;
- StatusInternalServerError = 500;
- StatusNotImplemented = 501;
- StatusBadGateway = 502;
- StatusServiceUnavailable = 503;
- StatusGatewayTimeout = 504;
- StatusHTTPVersionNotSupported = 505;
+ StatusInternalServerError = 500;
+ StatusNotImplemented = 501;
+ StatusBadGateway = 502;
+ StatusServiceUnavailable = 503;
+ StatusGatewayTimeout = 504;
+ StatusHTTPVersionNotSupported = 505;
)
-var statusText = map[int]string {
- StatusContinue: "Continue",
- StatusSwitchingProtocols: "Switching Protocols",
+var statusText = map[int]string{
+ StatusContinue: "Continue",
+ StatusSwitchingProtocols: "Switching Protocols",
- StatusOK: "OK",
- StatusCreated: "Created",
- StatusAccepted: "Accepted",
- StatusNonAuthoritativeInfo: "Non-Authoritative Information",
- StatusNoContent: "No Content",
- StatusResetContent: "Reset Content",
- StatusPartialContent: "Partial Content",
+ StatusOK: "OK",
+ StatusCreated: "Created",
+ StatusAccepted: "Accepted",
+ StatusNonAuthoritativeInfo: "Non-Authoritative Information",
+ StatusNoContent: "No Content",
+ StatusResetContent: "Reset Content",
+ StatusPartialContent: "Partial Content",
- StatusMultipleChoices: "Multiple Choices",
- StatusMovedPermanently: "Moved Permanently",
- StatusFound: "Found",
- StatusSeeOther: "See Other",
- StatusNotModified: "Not Modified",
- StatusUseProxy: "Use Proxy",
- StatusTemporaryRedirect: "Temporary Redirect",
+ StatusMultipleChoices: "Multiple Choices",
+ StatusMovedPermanently: "Moved Permanently",
+ StatusFound: "Found",
+ StatusSeeOther: "See Other",
+ StatusNotModified: "Not Modified",
+ StatusUseProxy: "Use Proxy",
+ StatusTemporaryRedirect: "Temporary Redirect",
- StatusBadRequest: "Bad Request",
- StatusUnauthorized: "Unauthorized",
- StatusPaymentRequired: "Payment Required",
- StatusForbidden: "Forbidden",
- StatusNotFound: "Not Found",
- StatusMethodNotAllowed: "Method Not Allowed",
- StatusNotAcceptable: "Not Acceptable",
- StatusProxyAuthRequired: "Proxy Authentication Required",
- StatusRequestTimeout: "Request Timeout",
- StatusConflict: "Conflict",
- StatusGone: "Gone",
- StatusLengthRequired: "Length Required",
- StatusPreconditionFailed: "Precondition Failed",
- StatusRequestEntityTooLarge: "Request Entity Too Large",
- StatusRequestURITooLong: "Request URI Too Long",
- StatusUnsupportedMediaType: "Unsupported Media Type",
- StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable",
- StatusExpectationFailed: "Expectation Failed",
+ StatusBadRequest: "Bad Request",
+ StatusUnauthorized: "Unauthorized",
+ StatusPaymentRequired: "Payment Required",
+ StatusForbidden: "Forbidden",
+ StatusNotFound: "Not Found",
+ StatusMethodNotAllowed: "Method Not Allowed",
+ StatusNotAcceptable: "Not Acceptable",
+ StatusProxyAuthRequired: "Proxy Authentication Required",
+ StatusRequestTimeout: "Request Timeout",
+ StatusConflict: "Conflict",
+ StatusGone: "Gone",
+ StatusLengthRequired: "Length Required",
+ StatusPreconditionFailed: "Precondition Failed",
+ StatusRequestEntityTooLarge: "Request Entity Too Large",
+ StatusRequestURITooLong: "Request URI Too Long",
+ StatusUnsupportedMediaType: "Unsupported Media Type",
+ StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable",
+ StatusExpectationFailed: "Expectation Failed",
- StatusInternalServerError: "Internal Server Error",
- StatusNotImplemented: "Not Implemented",
- StatusBadGateway: "Bad Gateway",
- StatusServiceUnavailable: "Service Unavailable",
- StatusGatewayTimeout: "Gateway Timeout",
- StatusHTTPVersionNotSupported: "HTTP Version Not Supported",
+ StatusInternalServerError: "Internal Server Error",
+ StatusNotImplemented: "Not Implemented",
+ StatusBadGateway: "Bad Gateway",
+ StatusServiceUnavailable: "Service Unavailable",
+ StatusGatewayTimeout: "Gateway Timeout",
+ StatusHTTPVersionNotSupported: "HTTP Version Not Supported",
}
-
// test ParseURL
type URLTest struct {
- in string;
- out *URL;
- roundtrip string; // expected result of reserializing the URL; empty means same as "in".
+ in string;
+ out *URL;
+ roundtrip string; // expected result of reserializing the URL; empty means same as "in".
}
-var urltests = []URLTest {
+var urltests = []URLTest{
// no path
URLTest{
"http://www.google.com",
"http://www.google.com",
"http", "//www.google.com",
"www.google.com", "", "www.google.com",
- "", "", ""
+ "", "", "",
},
- ""
+ "",
},
// path
URLTest{
"http://www.google.com/",
"http", "//www.google.com/",
"www.google.com", "", "www.google.com",
- "/", "", ""
+ "/", "", "",
},
- ""
+ "",
},
// path with hex escaping... note that space roundtrips to +
URLTest{
"http://www.google.com/file%20one%26two",
"http", "//www.google.com/file%20one%26two",
"www.google.com", "", "www.google.com",
- "/file one&two", "", ""
+ "/file one&two", "", "",
},
- "http://www.google.com/file+one%26two"
+ "http://www.google.com/file+one%26two",
},
// user
URLTest{
"ftp://webmaster@www.google.com/",
"ftp", "//webmaster@www.google.com/",
"webmaster@www.google.com", "webmaster", "www.google.com",
- "/", "", ""
+ "/", "", "",
},
- ""
+ "",
},
// escape sequence in username
URLTest{
"ftp://john%20doe@www.google.com/",
"ftp", "//john%20doe@www.google.com/",
"john doe@www.google.com", "john doe", "www.google.com",
- "/", "", ""
+ "/", "", "",
},
- "ftp://john+doe@www.google.com/"
+ "ftp://john+doe@www.google.com/",
},
// query
URLTest{
"http://www.google.com/?q=go+language",
"http", "//www.google.com/?q=go+language",
"www.google.com", "", "www.google.com",
- "/", "q=go+language", ""
+ "/", "q=go+language", "",
},
- ""
+ "",
},
// query with hex escaping: NOT parsed
URLTest{
"http://www.google.com/?q=go%20language",
"http", "//www.google.com/?q=go%20language",
"www.google.com", "", "www.google.com",
- "/", "q=go%20language", ""
+ "/", "q=go%20language", "",
},
- ""
+ "",
},
// path without /, so no query parsing
URLTest{
"http:www.google.com/?q=go+language",
"http", "www.google.com/?q=go+language",
"", "", "",
- "www.google.com/?q=go language", "", ""
+ "www.google.com/?q=go language", "", "",
},
- "http:www.google.com/%3fq%3dgo+language"
+ "http:www.google.com/%3fq%3dgo+language",
},
// non-authority
URLTest{
"mailto:/webmaster@golang.org",
"mailto", "/webmaster@golang.org",
"", "", "",
- "/webmaster@golang.org", "", ""
+ "/webmaster@golang.org", "", "",
},
- ""
+ "",
},
// non-authority
URLTest{
"mailto:webmaster@golang.org",
"mailto", "webmaster@golang.org",
"", "", "",
- "webmaster@golang.org", "", ""
+ "webmaster@golang.org", "", "",
},
- ""
+ "",
},
// unescaped :// in query should not create a scheme
URLTest{
"/foo?query=http://bad",
"", "/foo?query=http://bad",
"", "", "",
- "/foo", "query=http://bad", ""
+ "/foo", "query=http://bad", "",
},
- ""
+ "",
},
}
-var urlnofragtests = []URLTest {
+var urlnofragtests = []URLTest{
URLTest{
"http://www.google.com/?q=go+language#foo",
&URL{
"http://www.google.com/?q=go+language#foo",
"http", "//www.google.com/?q=go+language#foo",
"www.google.com", "", "www.google.com",
- "/", "q=go+language#foo", ""
+ "/", "q=go+language#foo", "",
},
- ""
+ "",
},
}
-var urlfragtests = []URLTest {
+var urlfragtests = []URLTest{
URLTest{
"http://www.google.com/?q=go+language#foo",
&URL{
"http://www.google.com/?q=go+language",
"http", "//www.google.com/?q=go+language",
"www.google.com", "", "www.google.com",
- "/", "q=go+language", "foo"
+ "/", "q=go+language", "foo",
},
- ""
+ "",
},
URLTest{
"http://www.google.com/?q=go+language#foo%26bar",
"http://www.google.com/?q=go+language",
"http", "//www.google.com/?q=go+language",
"www.google.com", "", "www.google.com",
- "/", "q=go+language", "foo&bar"
+ "/", "q=go+language", "foo&bar",
},
- ""
+ "",
},
}
}
type URLEscapeTest struct {
- in string;
- out string;
- err os.Error;
+ in string;
+ out string;
+ err os.Error;
}
-var unescapeTests = []URLEscapeTest {
+var unescapeTests = []URLEscapeTest{
URLEscapeTest{
"",
"",
- nil
+ nil,
},
URLEscapeTest{
"abc",
"abc",
- nil
+ nil,
},
URLEscapeTest{
"1%41",
"1A",
- nil
+ nil,
},
URLEscapeTest{
"1%41%42%43",
"1ABC",
- nil
+ nil,
},
URLEscapeTest{
"%4a",
"J",
- nil
+ nil,
},
URLEscapeTest{
"%6F",
"o",
- nil
+ nil,
},
URLEscapeTest{
- "%", // not enough characters after %
+ "%", // not enough characters after %
"",
URLEscapeError("%"),
},
URLEscapeTest{
- "%a", // not enough characters after %
+ "%a", // not enough characters after %
"",
URLEscapeError("%a"),
},
URLEscapeTest{
- "%1", // not enough characters after %
+ "%1", // not enough characters after %
"",
URLEscapeError("%1"),
},
URLEscapeTest{
- "123%45%6", // not enough characters after %
+ "123%45%6", // not enough characters after %
"",
URLEscapeError("%6"),
},
URLEscapeTest{
- "%zzzzz", // invalid hex digits
+ "%zzzzz", // invalid hex digits
"",
URLEscapeError("%zz"),
},
}
}
-var escapeTests = []URLEscapeTest {
+var escapeTests = []URLEscapeTest{
URLEscapeTest{
"",
"",
- nil
+ nil,
},
URLEscapeTest{
"abc",
"abc",
- nil
+ nil,
},
URLEscapeTest{
"one two",
"one+two",
- nil
+ nil,
},
URLEscapeTest{
"10%",
"10%25",
- nil
+ nil,
},
URLEscapeTest{
" ?&=#+%!",
"+%3f%26%3d%23%2b%25!",
- nil
+ nil,
},
}
}
}
}
-