]> Cypherpunks repositories - gostls13.git/commitdiff
doc/articles/wiki: fix path handling and clean up test process
authorAndrew Gerrand <adg@golang.org>
Tue, 8 Oct 2013 00:14:35 +0000 (11:14 +1100)
committerAndrew Gerrand <adg@golang.org>
Tue, 8 Oct 2013 00:14:35 +0000 (11:14 +1100)
Fixes #6525.

R=r
CC=golang-dev
https://golang.org/cl/14383043

14 files changed:
doc/articles/wiki/Makefile
doc/articles/wiki/final-noclosure.go
doc/articles/wiki/final-noerror.go
doc/articles/wiki/final-parsetemplate.go
doc/articles/wiki/final-template.go
doc/articles/wiki/final.go
doc/articles/wiki/htmlify.go [deleted file]
doc/articles/wiki/index.html
doc/articles/wiki/notemplate.go
doc/articles/wiki/part2.go
doc/articles/wiki/part3-errorhandling.go
doc/articles/wiki/part3.go
doc/articles/wiki/srcextract.go [deleted file]
doc/articles/wiki/test.bash

index 0cb9071850e48a15ddba2551567e7063c3272c8c..e40b1311ed06938782259f480f76fdcf5b646cc4 100644 (file)
@@ -4,17 +4,7 @@
 
 all: index.html
 
-CLEANFILES:=srcextract.bin htmlify.bin get.bin
-
-index.html: wiki.html srcextract.bin htmlify.bin
-       PATH=.:$$PATH awk '/^!/{system(substr($$0,2)); next} {print}' < wiki.html | tr -d '\r' > index.html
-
-test: get.bin
-       bash ./test.sh
-       rm -f get.6 get.bin
-
-%.bin: %.go
-       go build -o $@ $^
+CLEANFILES:=get.bin final-test.bin a.out
 
 clean:
        rm -f $(CLEANFILES)
index a23cf7a27a858b05ad250fc6a0ba8d9b8006acb2..d72ca805b8793a2603e406e239dfb6289b5cde74 100644 (file)
@@ -83,17 +83,15 @@ func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
        }
 }
 
-const lenPath = len("/view/")
+var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")
 
-var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
-
-func getTitle(w http.ResponseWriter, r *http.Request) (title string, err error) {
-       title = r.URL.Path[lenPath:]
-       if !titleValidator.MatchString(title) {
+func getTitle(w http.ResponseWriter, r *http.Request) (string, error) {
+       m := validPath.FindStringSubmatch(r.URL.Path)
+       if m == nil {
                http.NotFound(w, r)
-               err = errors.New("Invalid Page Title")
+               return "", errors.New("Invalid Page Title")
        }
-       return
+       return m[2], nil // The title is the second subexpression.
 }
 
 func main() {
index e11d268e2faab0ae527c700b014660d81e08ff13..86d8da751f9d5d77e4c602266568f73558b8763a 100644 (file)
@@ -29,10 +29,8 @@ func loadPage(title string) (*Page, error) {
        return &Page{Title: title, Body: body}, nil
 }
 
-const lenPath = len("/view/")
-
 func editHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/edit/"):]
        p, err := loadPage(title)
        if err != nil {
                p = &Page{Title: title}
@@ -42,7 +40,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) {
 }
 
 func viewHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/view/"):]
        p, _ := loadPage(title)
        t, _ := template.ParseFiles("view.html")
        t.Execute(w, p)
index 6234c08f2e3ed0d24776d0090a47c0549bd213f3..5ff8bf60c5b02f9a1abc62973a04ef2c06a9cd1c 100644 (file)
@@ -70,18 +70,16 @@ func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
        }
 }
 
-const lenPath = len("/view/")
-
-var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
+var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")
 
 func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
        return func(w http.ResponseWriter, r *http.Request) {
-               title := r.URL.Path[lenPath:]
-               if !titleValidator.MatchString(title) {
+               m := validPath.FindStringSubmatch(r.URL.Path)
+               if m == nil {
                        http.NotFound(w, r)
                        return
                }
-               fn(w, r, title)
+               fn(w, r, m[2])
        }
 }
 
index f295b9d600087e8b5785e56aa0068e9283de26bc..719157da954bd23b4d4048164ae18694284f9b96 100644 (file)
@@ -29,10 +29,8 @@ func loadPage(title string) (*Page, error) {
        return &Page{Title: title, Body: body}, nil
 }
 
-const lenPath = len("/view/")
-
 func editHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/edit/"):]
        p, err := loadPage(title)
        if err != nil {
                p = &Page{Title: title}
@@ -41,13 +39,13 @@ func editHandler(w http.ResponseWriter, r *http.Request) {
 }
 
 func viewHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/view/"):]
        p, _ := loadPage(title)
        renderTemplate(w, "view", p)
 }
 
 func saveHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/save/"):]
        body := r.FormValue("body")
        p := &Page{Title: title, Body: []byte(body)}
        p.save()
index e93cdee479b7f82db97d26fc8bf2520b553e17ef..f15794d660b70542c19725d13b64e4ba691201c6 100644 (file)
@@ -67,18 +67,16 @@ func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
        }
 }
 
-const lenPath = len("/view/")
-
-var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
+var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")
 
 func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
        return func(w http.ResponseWriter, r *http.Request) {
-               title := r.URL.Path[lenPath:]
-               if !titleValidator.MatchString(title) {
+               m := validPath.FindStringSubmatch(r.URL.Path)
+               if m == nil {
                        http.NotFound(w, r)
                        return
                }
-               fn(w, r, title)
+               fn(w, r, m[2])
        }
 }
 
diff --git a/doc/articles/wiki/htmlify.go b/doc/articles/wiki/htmlify.go
deleted file mode 100644 (file)
index 2a845a1..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-       "io/ioutil"
-       "os"
-       "text/template"
-)
-
-func main() {
-       b, _ := ioutil.ReadAll(os.Stdin)
-       template.HTMLEscape(os.Stdout, b)
-}
index f57857a7f3dc09e10518eb3e8808b5f51875f131..7bf7213e8817892a1b2383fbcbae0b78be0261ff 100644 (file)
@@ -260,18 +260,15 @@ Let's create a handler, <code>viewHandler</code> that will allow users to
 view a wiki page. It will handle URLs prefixed with "/view/".
 </p>
 
-{{code "doc/articles/wiki/part2.go" `/^const lenPath/`}}
-
 {{code "doc/articles/wiki/part2.go" `/^func viewHandler/` `/^}/`}}
 
 <p>
 First, this function extracts the page title from <code>r.URL.Path</code>,
-the path component of the request URL. The global constant
-<code>lenPath</code> is the length of the leading <code>"/view/"</code>
-component of the request path.
-The <code>Path</code> is re-sliced with <code>[lenPath:]</code> to drop the
-first 6 characters of the string. This is because the path will invariably
-begin with <code>"/view/"</code>, which is not part of the page's title.
+the path component of the request URL.
+The <code>Path</code> is re-sliced with <code>[len("/view/"):]</code> to drop
+the leading <code>"/view/"</code> component of the request path.
+This is because the path will invariably begin with <code>"/view/"</code>,
+which is not part of the page's title.
 </p>
 
 <p>
@@ -431,6 +428,11 @@ to its own function:
 </p>
 
 {{code "doc/articles/wiki/final-template.go" `/^func renderTemplate/` `/^}/`}}
+
+<p>
+And modify the handlers to use that function:
+</p>
+
 {{code "doc/articles/wiki/final-template.go" `/^func viewHandler/` `/^}/`}}
 {{code "doc/articles/wiki/final-template.go" `/^func editHandler/` `/^}/`}}
 
@@ -573,10 +575,11 @@ this, we can write a function to validate the title with a regular expression.
 
 <p>
 First, add <code>"regexp"</code> to the <code>import</code> list.
-Then we can create a global variable to store our validation regexp:
+Then we can create a global variable to store our validation 
+expression:
 </p>
 
-{{code "doc/articles/wiki/final-noclosure.go" `/^var titleValidator/`}}
+{{code "doc/articles/wiki/final-noclosure.go" `/^var validPath/`}}
 
 <p>
 The function <code>regexp.MustCompile</code> will parse and compile the
@@ -587,9 +590,8 @@ an <code>error</code> as a second parameter.
 </p>
 
 <p>
-Now, let's write a function, <code>getTitle</code>, that extracts the title
-string from the request URL, and tests it against our
-<code>TitleValidator</code> expression:
+Now, let's write a function that uses the <code>validPath</code>
+expression to validate path and extract the page title:
 </p>
 
 {{code "doc/articles/wiki/final-noclosure.go" `/func getTitle/` `/^}/`}}
index 33006ac958f1be4e5520214965c4b49a61e535e4..be214d1111d6b6ffed44229f7799c39f2d47601e 100644 (file)
@@ -29,16 +29,14 @@ func loadPage(title string) (*Page, error) {
        return &Page{Title: title, Body: body}, nil
 }
 
-const lenPath = len("/view/")
-
 func viewHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/view/"):]
        p, _ := loadPage(title)
        fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body)
 }
 
 func editHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/edit/"):]
        p, err := loadPage(title)
        if err != nil {
                p = &Page{Title: title}
index dd4365c82242dbb7f6a66815fd3563e7aae3352f..c0231693efbd29373a1a05c2bedd2b2812eadb04 100644 (file)
@@ -29,10 +29,8 @@ func loadPage(title string) (*Page, error) {
        return &Page{Title: title, Body: body}, nil
 }
 
-const lenPath = len("/view/")
-
 func viewHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/view/"):]
        p, _ := loadPage(title)
        fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body)
 }
index 945aa1e391df887e5b0326bb10c0c521c996aee9..bb4ecda84bb90d3015a97d70f333587a77160454 100644 (file)
@@ -29,15 +29,13 @@ func loadPage(title string) (*Page, error) {
        return &Page{Title: title, Body: body}, nil
 }
 
-const lenPath = len("/view/")
-
 func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
        t, _ := template.ParseFiles(tmpl + ".html")
        t.Execute(w, p)
 }
 
 func viewHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/view/"):]
        p, err := loadPage(title)
        if err != nil {
                http.Redirect(w, r, "/edit/"+title, http.StatusFound)
@@ -47,7 +45,7 @@ func viewHandler(w http.ResponseWriter, r *http.Request) {
 }
 
 func editHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/edit/"):]
        p, err := loadPage(title)
        if err != nil {
                p = &Page{Title: title}
@@ -56,7 +54,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) {
 }
 
 func saveHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/save/"):]
        body := r.FormValue("body")
        p := &Page{Title: title, Body: []byte(body)}
        err := p.save()
index 7fe4351af9214a993365f8234264a4a350d0868b..174f3abcd76fa94c7979a7c63aca2e1729660d61 100644 (file)
@@ -29,21 +29,19 @@ func loadPage(title string) (*Page, error) {
        return &Page{Title: title, Body: body}, nil
 }
 
-const lenPath = len("/view/")
-
 func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
        t, _ := template.ParseFiles(tmpl + ".html")
        t.Execute(w, p)
 }
 
 func viewHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/view/"):]
        p, _ := loadPage(title)
        renderTemplate(w, "view", p)
 }
 
 func editHandler(w http.ResponseWriter, r *http.Request) {
-       title := r.URL.Path[lenPath:]
+       title := r.URL.Path[len("/edit/"):]
        p, err := loadPage(title)
        if err != nil {
                p = &Page{Title: title}
diff --git a/doc/articles/wiki/srcextract.go b/doc/articles/wiki/srcextract.go
deleted file mode 100644 (file)
index 813e252..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-       "bytes"
-       "flag"
-       "go/ast"
-       "go/parser"
-       "go/printer"
-       "go/token"
-       "log"
-       "os"
-       "text/template"
-)
-
-var (
-       srcFn   = flag.String("src", "", "source filename")
-       getName = flag.String("name", "", "func/type name to output")
-       html    = flag.Bool("html", true, "output HTML")
-       showPkg = flag.Bool("pkg", false, "show package in output")
-)
-
-func main() {
-       // handle input
-       flag.Parse()
-       if *srcFn == "" || *getName == "" {
-               flag.Usage()
-               os.Exit(2)
-       }
-       // load file
-       fs := token.NewFileSet()
-       file, err := parser.ParseFile(fs, *srcFn, nil, 0)
-       if err != nil {
-               log.Fatal(err)
-       }
-       // create filter
-       filter := func(name string) bool {
-               return name == *getName
-       }
-       // filter
-       if !ast.FilterFile(file, filter) {
-               os.Exit(1)
-       }
-       // print the AST
-       var b bytes.Buffer
-       printer.Fprint(&b, fs, file)
-       // drop package declaration
-       if !*showPkg {
-               for {
-                       c, err := b.ReadByte()
-                       if c == '\n' || err != nil {
-                               break
-                       }
-               }
-       }
-       // drop leading newlines
-       for {
-               b, err := b.ReadByte()
-               if err != nil {
-                       break
-               }
-               if b != '\n' {
-                       os.Stdout.Write([]byte{b})
-                       break
-               }
-       }
-       // output
-       if *html {
-               template.HTMLEscape(os.Stdout, b.Bytes())
-       } else {
-               b.WriteTo(os.Stdout)
-       }
-}
index 02ed1894a529caa5ad233bbc015ff4ece5464da8..54a632c308a64f665243c103295c431ea1484008 100755 (executable)
@@ -7,10 +7,17 @@ set -e
 wiki_pid=
 cleanup() {
        kill $wiki_pid
-       rm -f test_*.out Test.txt final-test.bin final-test.go
+       rm -f test_*.out Test.txt final-test.bin final-test.go a.out get.bin
 }
 trap cleanup 0 INT
 
+# If called with -all, check that all code snippets compile.
+if [ "$1" == "-all" ]; then
+       for fn in *.go; do
+               go build -o a.out $fn
+       done
+fi
+
 go build -o get.bin get.go
 addr=$(./get.bin -addr)
 sed s/:8080/$addr/ < final.go > final-test.go