Merge pull request #327 from garyburd/impl

Improve synopsis text indexing
diff --git a/Dockerfile b/Dockerfile
index 80b1c2f..4d0a4ad 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -19,12 +19,12 @@
 
 # Manually fetch and install gddo-server dependencies (faster than "go get").
 ADD https://github.com/garyburd/redigo/archive/779af66db5668074a96f522d9025cb0a5ef50d89.zip /x/redigo.zip
-ADD https://snappy-go.googlecode.com/archive/12e4b4183793ac4b061921e7980845e750679fd0.tar.gz /x/snappy-go.tar.gz
-RUN unzip /x/redigo.zip -d /x && tar xzvf /x/snappy-go.tar.gz -C /x && \
+ADD https://github.com/golang/snappy/archive/master.zip /x/snappy-go.zip
+RUN unzip /x/redigo.zip -d /x && unzip /x/snappy-go.zip -d /x && \
 	mkdir -p /go/src/github.com/garyburd && \
-	mkdir -p /go/src/code.google.com/p && \
+	mkdir -p /go/src/github.com/golang && \
 	mv /x/redigo-* /go/src/github.com/garyburd/redigo && \
-	mv /x/snappy-go-* /go/src/code.google.com/p/snappy-go && \
+	mv /x/snappy-master /go/src/github.com/golang/snappy && \
 	rm -rf /x
 
 # Build the local gddo files.
diff --git a/gddo-server/assets/templates/pkg.html b/gddo-server/assets/templates/pkg.html
index c98b74d..63ff746 100644
--- a/gddo-server/assets/templates/pkg.html
+++ b/gddo-server/assets/templates/pkg.html
@@ -178,7 +178,7 @@
         <div id="ex-{{.ID}}" class="panel-collapse collapse"><div class="panel-body">
           {{with .Example.Doc}}<p>{{.|comment}}{{end}}
           <p>Code:{{if .Example.Play}}<span class="pull-right"><a href="?play={{.ID}}">play</a>&nbsp;</span>{{end}}
-          <pre>{{code .Example.Code nil}}</pre>
+          {{code .Example.Code nil}}
           {{with .Example.Output}}<p>Output:<pre>{{.}}</pre>{{end}}
         </div></div>
       </div>
diff --git a/gddo-server/main.go b/gddo-server/main.go
index 486addd..eea3e12 100644
--- a/gddo-server/main.go
+++ b/gddo-server/main.go
@@ -18,6 +18,7 @@
 	"html/template"
 	"io"
 	"log"
+	"net"
 	"net/http"
 	"os"
 	"path"
@@ -60,6 +61,7 @@
 	robotRequest
 	queryRequest
 	refreshRequest
+	apiRequest
 )
 
 type crawlResult struct {
@@ -84,7 +86,7 @@
 
 	needsCrawl := false
 	switch requestType {
-	case queryRequest:
+	case queryRequest, apiRequest:
 		needsCrawl = nextCrawl.IsZero() && len(pkgs) == 0
 	case humanRequest:
 		needsCrawl = nextCrawl.Before(time.Now())
@@ -598,7 +600,10 @@
 	var pkgs []database.Package
 
 	if gosrc.IsValidRemotePath(q) || (strings.Contains(q, "/") && gosrc.IsGoRepoPath(q)) {
-		pdoc, _, err := getDoc(q, robotRequest)
+		pdoc, _, err := getDoc(q, apiRequest)
+		if e, ok := err.(gosrc.NotFoundError); ok && e.Redirect != "" {
+			pdoc, _, err = getDoc(e.Redirect, robotRequest)
+		}
 		if err == nil && pdoc != nil {
 			pkgs = []database.Package{{Path: pdoc.ImportPath, Synopsis: pdoc.Synopsis}}
 		}
@@ -760,12 +765,29 @@
 	json.NewEncoder(resp).Encode(&data)
 }
 
-type hostMux []struct {
+type rootHandler []struct {
 	prefix string
 	h      http.Handler
 }
 
-func (m hostMux) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
+func (m rootHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
+	host := req.Host
+	if h, _, err := net.SplitHostPort(host); err == nil {
+		host = h
+	}
+	if host == "godoc.org" {
+		if req.Header.Get("X-Scheme") != "https" {
+			u := *req.URL
+			u.Scheme = "https"
+			u.Host = host
+			http.Redirect(resp, req, u.String(), http.StatusFound)
+			return
+		}
+		// Because https is not used api.godoc.org, the includeSubDomains
+		// parameter is not used here.
+		resp.Header().Add("Strict-Transport-Security", "max-age=631138519; preload")
+	}
+
 	var h http.Handler
 	for _, ph := range m {
 		if strings.HasPrefix(req.Host, ph.prefix) {
@@ -773,6 +795,7 @@
 			break
 		}
 	}
+
 	h.ServeHTTP(resp, req)
 }
 
@@ -898,7 +921,7 @@
 
 	cacheBusters.Handler = mux
 
-	if err := http.ListenAndServe(*httpAddr, hostMux{{"api.", apiMux}, {"", mux}}); err != nil {
+	if err := http.ListenAndServe(*httpAddr, rootHandler{{"api.", apiMux}, {"", mux}}); err != nil {
 		log.Fatal(err)
 	}
 }