From f70cc6d2e52cfa43040b77828cff13c594c56c7b Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sat, 12 Mar 2011 12:32:40 -0800 Subject: [PATCH] Updates to latest Go language + library changes. --- lib/go/blobserver/handlers/enumerate.go | 2 +- lib/go/blobserver/handlers/get.go | 6 +- lib/go/client/sync.go | 5 +- server/go/auth/auth.go | 2 +- server/go/httputil/httputil.go | 2 +- website/Makefile | 1 - website/camweb.go | 11 +- website/cgi.go | 187 ------------------------ website/logging.go | 2 +- 9 files changed, 16 insertions(+), 202 deletions(-) delete mode 100644 website/cgi.go diff --git a/lib/go/blobserver/handlers/enumerate.go b/lib/go/blobserver/handlers/enumerate.go index a897324d1..ce5a7596b 100644 --- a/lib/go/blobserver/handlers/enumerate.go +++ b/lib/go/blobserver/handlers/enumerate.go @@ -80,7 +80,7 @@ func handleEnumerateBlobs(conn http.ResponseWriter, req *http.Request, storage b } } - conn.SetHeader("Content-Type", "text/javascript; charset=utf-8") + conn.Header().Set("Content-Type", "text/javascript; charset=utf-8") fmt.Fprintf(conn, "{\n \"blobs\": [\n") blobch := make(chan *blobref.SizedBlobRef, 100) diff --git a/lib/go/blobserver/handlers/get.go b/lib/go/blobserver/handlers/get.go index 45bcffab4..612caedf6 100644 --- a/lib/go/blobserver/handlers/get.go +++ b/lib/go/blobserver/handlers/get.go @@ -131,12 +131,12 @@ func serveBlobRef(conn http.ResponseWriter, req *http.Request, } input = bufReader - conn.SetHeader("Content-Length", strconv.Itoa64(size)) + conn.Header().Set("Content-Length", strconv.Itoa64(size)) } - conn.SetHeader("Content-Type", contentType) + conn.Header().Set("Content-Type", contentType) if !reqRange.IsWholeFile() { - conn.SetHeader("Content-Range", + conn.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", reqRange.SkipBytes(), reqRange.SkipBytes()+remainBytes, size)) diff --git a/lib/go/client/sync.go b/lib/go/client/sync.go index 497a4aa02..85c3ad3f1 100644 --- a/lib/go/client/sync.go +++ b/lib/go/client/sync.go @@ -34,8 +34,9 @@ func (cp *chanPeeker) Peek() *blobref.SizedBlobRef { if cp.peek != nil { return cp.peek } - cp.peek = <-cp.ch - if closed(cp.ch) { + var ok bool + cp.peek, ok = <-cp.ch + if !ok { cp.Closed = true return nil } diff --git a/server/go/auth/auth.go b/server/go/auth/auth.go index 1f904cee9..b76b769f6 100644 --- a/server/go/auth/auth.go +++ b/server/go/auth/auth.go @@ -65,7 +65,7 @@ func RequireAuth(handler func(conn http.ResponseWriter, req *http.Request)) func return func (conn http.ResponseWriter, req *http.Request) { if !IsAuthorized(req) { req.Body.Close() // http://code.google.com/p/go/issues/detail?id=1306 - conn.SetHeader("WWW-Authenticate", "Basic realm=\"camlistored\"") + conn.Header().Set("WWW-Authenticate", "Basic realm=\"camlistored\"") conn.WriteHeader(http.StatusUnauthorized) fmt.Fprintf(conn, "Authentication required.\n") return diff --git a/server/go/httputil/httputil.go b/server/go/httputil/httputil.go index b0a0a0a35..6c63edb2c 100644 --- a/server/go/httputil/httputil.go +++ b/server/go/httputil/httputil.go @@ -36,7 +36,7 @@ func ServerError(conn http.ResponseWriter, err os.Error) { } func ReturnJson(conn http.ResponseWriter, data interface{}) { - conn.SetHeader("Content-Type", "text/javascript") + conn.Header().Set("Content-Type", "text/javascript") bytes, err := json.MarshalIndent(data, "", " ") if err != nil { BadRequestError(conn, fmt.Sprintf( diff --git a/website/Makefile b/website/Makefile index 68ac434a3..e5c042138 100644 --- a/website/Makefile +++ b/website/Makefile @@ -3,7 +3,6 @@ include $(GOROOT)/src/Make.inc TARG=camweb GOFILES=\ camweb.go\ - cgi.go\ logging.go\ include $(GOROOT)/src/Make.cmd diff --git a/website/camweb.go b/website/camweb.go index eac9ad0b0..db36354d1 100644 --- a/website/camweb.go +++ b/website/camweb.go @@ -21,6 +21,7 @@ import ( "flag" "fmt" "http" + "http/cgi" "io" "io/ioutil" "log" @@ -41,7 +42,7 @@ var ( root = flag.String("root", "", "Website root (parent of 'static', 'content', and 'tmpl") gitwebScript = flag.String("gitwebscript", "/usr/lib/cgi-bin/gitweb.cgi", "Path to gitweb.cgi, or blank to disable.") gitwebFiles = flag.String("gitwebfiles", "/usr/share/gitweb", "Path to gitweb's static files.") - logDir = flag.String("logdir", "-", "Directory to write log files to (one per hour), or empty to not log.") + logDir = flag.String("logdir", "", "Directory to write log files to (one per hour), or empty to not log.") logStdout = flag.Bool("logstdout", true, "Write to stdout?") pageHtml, errorHtml *template.Template ) @@ -241,7 +242,7 @@ func main() { mux.Handle("/robots.txt", http.FileServer(path.Join(*root, "static"), "/")) mux.Handle("/static/", http.FileServer(path.Join(*root, "static"), "/static/")) - testCgi := &CgiHandler{ExecutablePath: path.Join(*root, "test.cgi"), + testCgi := &cgi.Handler{Path: path.Join(*root, "test.cgi"), Root: "/test.cgi", } mux.Handle("/test.cgi", testCgi) @@ -253,10 +254,10 @@ func main() { env = append(env, "GITWEB_CONFIG="+path.Join(*root, "gitweb-camli.conf")) env = append(env, "CAMWEB_ROOT="+path.Join(*root)) mux.Handle("/code/", &fixUpGitwebUrls{&gitwebHandler{ - Cgi: &CgiHandler{ - ExecutablePath: *gitwebScript, + Cgi: &cgi.Handler{ + Path: *gitwebScript, Root: "/code/", - Environ: env, + Env: env, }, Static: http.FileServer(*gitwebFiles, "/code/"), }}) diff --git a/website/cgi.go b/website/cgi.go deleted file mode 100644 index 0852bce6e..000000000 --- a/website/cgi.go +++ /dev/null @@ -1,187 +0,0 @@ -/* -Copyright 2011 Google Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -// Package cgi implements a CGI (Common Gateway Interface) HTTP handler as specified -// in RFC 3875. Using CGI isn't usually incredibly efficient and this package -// is intended primarily for compatibility. - -import ( - "encoding/line" - "exec" - "fmt" - "http" - "io" - "log" - "os" - "regexp" - "strconv" - "strings" -) - -var trailingPort = regexp.MustCompile(`:([0-9]+)$`) - -type CgiHandler struct { - ExecutablePath string - Root string // empty is "/"; otherwise must start with "/" - Environ []string - // TODO: custom log.Logger -} - -func (h *CgiHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - pathInfo := req.URL.Path - if strings.HasPrefix(pathInfo, h.Root) { - pathInfo = pathInfo[len(h.Root):] - } - - port := "80" - if matches := trailingPort.FindStringSubmatch(req.Host); len(matches) != 0 { - port = matches[1] - } - - env := []string{ - "SERVER_SOFTWARE=golang", - "SERVER_NAME=" + req.Host, - "HTTP_HOST=" + req.Host, - "GATEWAY_INTERFACE=CGI/1.1", - "REQUEST_METHOD=" + req.Method, - "QUERY_STRING=" + req.URL.RawQuery, - "REQUEST_URI=" + req.URL.RawPath, - "PATH_INFO=" + pathInfo, - "SCRIPT_NAME=" + h.Root, - "SCRIPT_FILENAME=" + h.ExecutablePath, - "REMOTE_ADDR=0.0.0.0", // TODO - "REMOTE_HOST=", // TODO - "SERVER_PORT=" + port, - } - - for k, _ := range req.Header { - k = strings.Map(upperCaseAndUnderscore, k) - env = append(env, "HTTP_"+k+"="+req.Header.Get(k)) - } - - if req.ContentLength > 0 { - env = append(env, fmt.Sprintf("CONTENT_LENGTH=%d", req.ContentLength)) - } - if ctype := req.Header.Get("Content-Type"); ctype != "" { - env = append(env, "CONTENT_TYPE="+ctype) - } - - if h.Environ != nil { - env = append(env, h.Environ...) - } - - cwd := h.ExecutablePath - if slash := strings.LastIndex(cwd, "/"); slash != -1 { - cwd = cwd[0:slash] - } - if !strings.HasPrefix(cwd, "/") { - cwd = "." - } - - cmd, err := exec.Run( - h.ExecutablePath, - []string{h.ExecutablePath}, - env, - cwd, - exec.Pipe, // stdin - exec.Pipe, // stdout - exec.PassThrough, // stderr (for now) - ) - if err != nil { - rw.WriteHeader(http.StatusInternalServerError) - log.Printf("CGI error: %v", err) - return - } - defer func() { - cmd.Stdin.Close() - cmd.Stdout.Close() - cmd.Wait(0) // no zombies - }() - - if req.ContentLength != 0 { - go func() { - io.Copy(cmd.Stdin, req.Body) - }() - } - - linebody := line.NewReader(cmd.Stdout, 1024) - headers := make(map[string]string) - statusCode := http.StatusOK - for { - line, isPrefix, err := linebody.ReadLine() - if isPrefix { - rw.WriteHeader(http.StatusInternalServerError) - log.Printf("CGI: long header line from subprocess.") - return - } - if err == os.EOF { - break - } - if err != nil { - rw.WriteHeader(http.StatusInternalServerError) - log.Printf("CGI: error reading headers: %v", err) - return - } - if len(line) == 0 { - break - } - parts := strings.Split(string(line), ":", 2) - if len(parts) < 2 { - log.Printf("CGI: bogus header line: %s", string(line)) - continue - } - h, v := parts[0], parts[1] - h = strings.TrimSpace(h) - v = strings.TrimSpace(v) - switch { - case h == "Status": - if len(v) < 3 { - log.Printf("CGI: bogus status (short): %q", v) - return - } - code, err := strconv.Atoi(v[0:3]) - if err != nil { - log.Printf("CGI: bogus status: %q", v) - log.Printf("CGI: line was %q", line) - return - } - statusCode = code - default: - headers[h] = v - } - } - for h, v := range headers { - rw.SetHeader(h, v) - } - rw.WriteHeader(statusCode) - - _, err = io.Copy(rw, linebody) - if err != nil { - log.Printf("CGI: copy error: %v", err) - } -} - -func upperCaseAndUnderscore(rune int) int { - switch { - case rune >= 'a' && rune <= 'z': - return rune - ('a' - 'A') - case rune == '-': - return '_' - } - return rune -} diff --git a/website/logging.go b/website/logging.go index c6d4191f0..0b8c8edec 100644 --- a/website/logging.go +++ b/website/logging.go @@ -41,7 +41,7 @@ func NewLoggingHandler(handler http.Handler, dir string, writeStdout bool) http. func (h *logHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) { // Strip port number from address - addr := rw.RemoteAddr() + addr := r.RemoteAddr if colon := strings.LastIndex(addr, ":"); colon != -1 { addr = addr[:colon] }