mirror of
https://github.com/golang/go
synced 2024-11-21 19:14:44 -07:00
doc: update http handler usage for new signature
R=adg, r2 CC=golang-dev https://golang.org/cl/2302041
This commit is contained in:
parent
763cb8ad11
commit
a2332a32b8
@ -27,21 +27,21 @@ func loadPage(title string) (*page, os.Error) {
|
|||||||
return &page{title: title, body: body}, nil
|
return &page{title: title, body: body}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func viewHandler(c *http.Conn, r *http.Request) {
|
func viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title, err := getTitle(c, r)
|
title, err := getTitle(w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Redirect(c, "/edit/"+title, http.StatusFound)
|
http.Redirect(w, r, "/edit/"+title, http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
renderTemplate(c, "view", p)
|
renderTemplate(w, "view", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func editHandler(c *http.Conn, r *http.Request) {
|
func editHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title, err := getTitle(c, r)
|
title, err := getTitle(w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -49,11 +49,11 @@ func editHandler(c *http.Conn, r *http.Request) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
p = &page{title: title}
|
p = &page{title: title}
|
||||||
}
|
}
|
||||||
renderTemplate(c, "edit", p)
|
renderTemplate(w, "edit", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveHandler(c *http.Conn, r *http.Request) {
|
func saveHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title, err := getTitle(c, r)
|
title, err := getTitle(w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -61,21 +61,21 @@ func saveHandler(c *http.Conn, r *http.Request) {
|
|||||||
p := &page{title: title, body: []byte(body)}
|
p := &page{title: title, body: []byte(body)}
|
||||||
err = p.save()
|
err = p.save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(c, "/view/"+title, http.StatusFound)
|
http.Redirect(w, r, "/view/"+title, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(c *http.Conn, tmpl string, p *page) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *page) {
|
||||||
t, err := template.ParseFile(tmpl+".html", nil)
|
t, err := template.ParseFile(tmpl+".html", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = t.Execute(p, c)
|
err = t.Execute(p, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,10 +83,10 @@ const lenPath = len("/view/")
|
|||||||
|
|
||||||
var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
|
var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
|
||||||
|
|
||||||
func getTitle(c *http.Conn, r *http.Request) (title string, err os.Error) {
|
func getTitle(w http.ResponseWriter, r *http.Request) (title string, err os.Error) {
|
||||||
title = r.URL.Path[lenPath:]
|
title = r.URL.Path[lenPath:]
|
||||||
if !titleValidator.MatchString(title) {
|
if !titleValidator.MatchString(title) {
|
||||||
http.NotFound(c, r)
|
http.NotFound(w, r)
|
||||||
err = os.NewError("Invalid Page Title")
|
err = os.NewError("Invalid Page Title")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -28,21 +28,21 @@ func loadPage(title string) (*page, os.Error) {
|
|||||||
|
|
||||||
const lenPath = len("/view/")
|
const lenPath = len("/view/")
|
||||||
|
|
||||||
func editHandler(c *http.Conn, r *http.Request) {
|
func editHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p = &page{title: title}
|
p = &page{title: title}
|
||||||
}
|
}
|
||||||
t, _ := template.ParseFile("edit.html", nil)
|
t, _ := template.ParseFile("edit.html", nil)
|
||||||
t.Execute(p, c)
|
t.Execute(p, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func viewHandler(c *http.Conn, r *http.Request) {
|
func viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, _ := loadPage(title)
|
p, _ := loadPage(title)
|
||||||
t, _ := template.ParseFile("view.html", nil)
|
t, _ := template.ParseFile("view.html", nil)
|
||||||
t.Execute(p, c)
|
t.Execute(p, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -27,43 +27,43 @@ func loadPage(title string) (*page, os.Error) {
|
|||||||
return &page{title: title, body: body}, nil
|
return &page{title: title, body: body}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func viewHandler(c *http.Conn, r *http.Request, title string) {
|
func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Redirect(c, "/edit/"+title, http.StatusFound)
|
http.Redirect(w, r, "/edit/"+title, http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
renderTemplate(c, "view", p)
|
renderTemplate(w, "view", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func editHandler(c *http.Conn, r *http.Request, title string) {
|
func editHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p = &page{title: title}
|
p = &page{title: title}
|
||||||
}
|
}
|
||||||
renderTemplate(c, "edit", p)
|
renderTemplate(w, "edit", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveHandler(c *http.Conn, r *http.Request, title string) {
|
func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||||
body := r.FormValue("body")
|
body := r.FormValue("body")
|
||||||
p := &page{title: title, body: []byte(body)}
|
p := &page{title: title, body: []byte(body)}
|
||||||
err := p.save()
|
err := p.save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(c, "/view/"+title, http.StatusFound)
|
http.Redirect(w, r, "/view/"+title, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(c *http.Conn, tmpl string, p *page) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *page) {
|
||||||
t, err := template.ParseFile(tmpl+".html", nil)
|
t, err := template.ParseFile(tmpl+".html", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = t.Execute(p, c)
|
err = t.Execute(p, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,14 +71,14 @@ const lenPath = len("/view/")
|
|||||||
|
|
||||||
var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
|
var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
|
||||||
|
|
||||||
func makeHandler(fn func(*http.Conn, *http.Request, string)) http.HandlerFunc {
|
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
|
||||||
return func(c *http.Conn, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
if !titleValidator.MatchString(title) {
|
if !titleValidator.MatchString(title) {
|
||||||
http.NotFound(c, r)
|
http.NotFound(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fn(c, r, title)
|
fn(w, r, title)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,32 +28,32 @@ func loadPage(title string) (*page, os.Error) {
|
|||||||
|
|
||||||
const lenPath = len("/view/")
|
const lenPath = len("/view/")
|
||||||
|
|
||||||
func editHandler(c *http.Conn, r *http.Request) {
|
func editHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p = &page{title: title}
|
p = &page{title: title}
|
||||||
}
|
}
|
||||||
renderTemplate(c, "edit", p)
|
renderTemplate(w, "edit", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func viewHandler(c *http.Conn, r *http.Request) {
|
func viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, _ := loadPage(title)
|
p, _ := loadPage(title)
|
||||||
renderTemplate(c, "view", p)
|
renderTemplate(w, "view", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveHandler(c *http.Conn, r *http.Request) {
|
func saveHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
body := r.FormValue("body")
|
body := r.FormValue("body")
|
||||||
p := &page{title: title, body: []byte(body)}
|
p := &page{title: title, body: []byte(body)}
|
||||||
p.save()
|
p.save()
|
||||||
http.Redirect(c, "/view/"+title, http.StatusFound)
|
http.Redirect(w, r, "/view/"+title, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(c *http.Conn, tmpl string, p *page) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *page) {
|
||||||
t, _ := template.ParseFile(tmpl+".html", nil)
|
t, _ := template.ParseFile(tmpl+".html", nil)
|
||||||
t.Execute(p, c)
|
t.Execute(p, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -27,32 +27,32 @@ func loadPage(title string) (*page, os.Error) {
|
|||||||
return &page{title: title, body: body}, nil
|
return &page{title: title, body: body}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func viewHandler(c *http.Conn, r *http.Request, title string) {
|
func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Redirect(c, "/edit/"+title, http.StatusFound)
|
http.Redirect(w, r, "/edit/"+title, http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
renderTemplate(c, "view", p)
|
renderTemplate(w, "view", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func editHandler(c *http.Conn, r *http.Request, title string) {
|
func editHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p = &page{title: title}
|
p = &page{title: title}
|
||||||
}
|
}
|
||||||
renderTemplate(c, "edit", p)
|
renderTemplate(w, "edit", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveHandler(c *http.Conn, r *http.Request, title string) {
|
func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||||
body := r.FormValue("body")
|
body := r.FormValue("body")
|
||||||
p := &page{title: title, body: []byte(body)}
|
p := &page{title: title, body: []byte(body)}
|
||||||
err := p.save()
|
err := p.save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(c, "/view/"+title, http.StatusFound)
|
http.Redirect(w, r, "/view/"+title, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
var templates = make(map[string]*template.Template)
|
var templates = make(map[string]*template.Template)
|
||||||
@ -63,10 +63,10 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(c *http.Conn, tmpl string, p *page) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *page) {
|
||||||
err := templates[tmpl].Execute(p, c)
|
err := templates[tmpl].Execute(p, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,14 +74,14 @@ const lenPath = len("/view/")
|
|||||||
|
|
||||||
var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
|
var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
|
||||||
|
|
||||||
func makeHandler(fn func(*http.Conn, *http.Request, string)) http.HandlerFunc {
|
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
|
||||||
return func(c *http.Conn, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
if !titleValidator.MatchString(title) {
|
if !titleValidator.MatchString(title) {
|
||||||
http.NotFound(c, r)
|
http.NotFound(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fn(c, r, title)
|
fn(w, r, title)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"http"
|
"http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func handler(c *http.Conn, r *http.Request) {
|
func handler(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprintf(c, "Hi there, I love %s!", r.URL.Path[1:])
|
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -240,8 +240,8 @@ import (
|
|||||||
"http"
|
"http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func handler(c *http.Conn, r *http.Request) {
|
func handler(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprintf(c, "Hi there, I love %s!", r.URL.Path[1:])
|
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -266,12 +266,12 @@ This function will block until the program is terminated.
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
The function <code>handler</code> is of the type <code>http.HandlerFunc</code>.
|
The function <code>handler</code> is of the type <code>http.HandlerFunc</code>.
|
||||||
It takes an <code>http.Conn</code> and <code>http.Request</code> as its
|
It takes an <code>http.ResponseWriter</code> and an <code>http.Request</code> as
|
||||||
arguments.
|
its arguments.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
An <code>http.Conn</code> is the server end of an HTTP connection; by writing
|
An <code>http.ResponseWriter</code> value assembles the HTTP server's response; by writing
|
||||||
to it, we send data to the HTTP client.
|
to it, we send data to the HTTP client.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -314,10 +314,10 @@ Let's create a handler to view a wiki page:
|
|||||||
<pre>
|
<pre>
|
||||||
const lenPath = len("/view/")
|
const lenPath = len("/view/")
|
||||||
|
|
||||||
func viewHandler(c *http.Conn, r *http.Request) {
|
func viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, _ := loadPage(title)
|
p, _ := loadPage(title)
|
||||||
fmt.Fprintf(c, "<h1>%s</h1><div>%s</div>", p.title, p.body)
|
fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.title, p.body)
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -333,7 +333,7 @@ begin with <code>"/view/"</code>, which is not part of the page title.
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
The function then loads the page data, formats the page with a string of simple
|
The function then loads the page data, formats the page with a string of simple
|
||||||
HTML, and writes it to <code>c</code>, the <code>http.Conn</code>.
|
HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -406,13 +406,13 @@ and displays an HTML form.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func editHandler(c *http.Conn, r *http.Request) {
|
func editHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p = &page{title: title}
|
p = &page{title: title}
|
||||||
}
|
}
|
||||||
fmt.Fprintf(c, "<h1>Editing %s</h1>"+
|
fmt.Fprintf(w, "<h1>Editing %s</h1>"+
|
||||||
"<form action=\"/save/%s\" method=\"POST\">"+
|
"<form action=\"/save/%s\" method=\"POST\">"+
|
||||||
"<textarea name=\"body\">%s</textarea><br>"+
|
"<textarea name=\"body\">%s</textarea><br>"+
|
||||||
"<input type=\"submit\" value=\"Save\">"+
|
"<input type=\"submit\" value=\"Save\">"+
|
||||||
@ -468,14 +468,14 @@ HTML:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func editHandler(c *http.Conn, r *http.Request) {
|
func editHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p = &page{title: title}
|
p = &page{title: title}
|
||||||
}
|
}
|
||||||
t, _ := template.ParseFile("edit.html", nil)
|
t, _ := template.ParseFile("edit.html", nil)
|
||||||
t.Execute(p, c)
|
t.Execute(p, w)
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -488,7 +488,7 @@ The function <code>template.ParseFile</code> will read the contents of
|
|||||||
The method <code>t.Execute</code> replaces all occurrences of
|
The method <code>t.Execute</code> replaces all occurrences of
|
||||||
<code>{title}</code> and <code>{body}</code> with the values of
|
<code>{title}</code> and <code>{body}</code> with the values of
|
||||||
<code>p.title</code> and <code>p.body</code>, and writes the resultant
|
<code>p.title</code> and <code>p.body</code>, and writes the resultant
|
||||||
HTML to the <code>http.Conn</code>.
|
HTML to the <code>http.ResponseWriter</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -523,11 +523,11 @@ Modify <code>viewHandler</code> accordingly:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func viewHandler(c *http.Conn, r *http.Request) {
|
func viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, _ := loadPage(title)
|
p, _ := loadPage(title)
|
||||||
t, _ := template.ParseFile("view.html", nil)
|
t, _ := template.ParseFile("view.html", nil)
|
||||||
t.Execute(p, c)
|
t.Execute(p, w)
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -538,24 +538,24 @@ to its own function:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func viewHandler(c *http.Conn, r *http.Request) {
|
func viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, _ := loadPage(title)
|
p, _ := loadPage(title)
|
||||||
renderTemplate(c, "view", p)
|
renderTemplate(w, "view", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func editHandler(c *http.Conn, r *http.Request) {
|
func editHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p = &page{title: title}
|
p = &page{title: title}
|
||||||
}
|
}
|
||||||
renderTemplate(c, "edit", p)
|
renderTemplate(w, "edit", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(c *http.Conn, tmpl string, p *page) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *page) {
|
||||||
t, _ := template.ParseFile(tmpl+".html", nil)
|
t, _ := template.ParseFile(tmpl+".html", nil)
|
||||||
t.Execute(p, c)
|
t.Execute(p, w)
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -573,13 +573,13 @@ redirect the client to the edit page so the content may be created:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func viewHandler(c *http.Conn, r *http.Request, title string) {
|
func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Redirect(c, "/edit/"+title, http.StatusFound)
|
http.Redirect(w, r, "/edit/"+title, http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
renderTemplate(c, "view", p)
|
renderTemplate(w, "view", p)
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -596,12 +596,12 @@ The function <code>saveHandler</code> will handle the form submission.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func saveHandler(c *http.Conn, r *http.Request) {
|
func saveHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
body := r.FormValue("body")
|
body := r.FormValue("body")
|
||||||
p := &page{title: title, body: []byte(body)}
|
p := &page{title: title, body: []byte(body)}
|
||||||
p.save()
|
p.save()
|
||||||
http.Redirect(c, "/view/"+title, http.StatusFound)
|
http.Redirect(w, r, "/view/"+title, http.StatusFound)
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -634,15 +634,15 @@ First, let's handle the errors in <code>renderTemplate</code>:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func renderTemplate(c *http.Conn, tmpl string, p *page) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *page) {
|
||||||
t, err := template.ParseFile(tmpl+".html", nil)
|
t, err := template.ParseFile(tmpl+".html", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = t.Execute(p, c)
|
err = t.Execute(p, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
@ -658,15 +658,15 @@ Now let's fix up <code>saveHandler</code>:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func saveHandler(c *http.Conn, r *http.Request, title string) {
|
func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||||
body := r.FormValue("body")
|
body := r.FormValue("body")
|
||||||
p := &page{title: title, body: []byte(body)}
|
p := &page{title: title, body: []byte(body)}
|
||||||
err := p.save()
|
err := p.save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(c, "/view/"+title, http.StatusFound)
|
http.Redirect(w, r, "/view/"+title, http.StatusFound)
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -725,10 +725,10 @@ the <code>Execute</code> method on the appropriate <code>Template</code> from
|
|||||||
<code>templates</code>:
|
<code>templates</code>:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func renderTemplate(c *http.Conn, tmpl string, p *page) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *page) {
|
||||||
err := templates[tmpl].Execute(p, c)
|
err := templates[tmpl].Execute(p, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
@ -765,10 +765,10 @@ URL, and tests it against our <code>titleValidator</code> expression:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func getTitle(c *http.Conn, r *http.Request) (title string, err os.Error) {
|
func getTitle(w http.ResponseWriter, r *http.Request) (title string, err os.Error) {
|
||||||
title = r.URL.Path[lenPath:]
|
title = r.URL.Path[lenPath:]
|
||||||
if !titleValidator.MatchString(title) {
|
if !titleValidator.MatchString(title) {
|
||||||
http.NotFound(c, r)
|
http.NotFound(w, r)
|
||||||
err = os.NewError("Invalid Page Title")
|
err = os.NewError("Invalid Page Title")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -787,21 +787,21 @@ Let's put a call to <code>getTitle</code> in each of the handlers:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func viewHandler(c *http.Conn, r *http.Request) {
|
func viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title, err := getTitle(c, r)
|
title, err := getTitle(w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Redirect(c, "/edit/"+title, http.StatusFound)
|
http.Redirect(w, r, "/edit/"+title, http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
renderTemplate(c, "view", p)
|
renderTemplate(w, "view", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func editHandler(c *http.Conn, r *http.Request) {
|
func editHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title, err := getTitle(c, r)
|
title, err := getTitle(w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -809,11 +809,11 @@ func editHandler(c *http.Conn, r *http.Request) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
p = &page{title: title}
|
p = &page{title: title}
|
||||||
}
|
}
|
||||||
renderTemplate(c, "edit", p)
|
renderTemplate(w, "edit", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveHandler(c *http.Conn, r *http.Request) {
|
func saveHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title, err := getTitle(c, r)
|
title, err := getTitle(w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -821,10 +821,10 @@ func saveHandler(c *http.Conn, r *http.Request) {
|
|||||||
p := &page{title: title, body: []byte(body)}
|
p := &page{title: title, body: []byte(body)}
|
||||||
err = p.save()
|
err = p.save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(c, "/view/"+title, http.StatusFound)
|
http.Redirect(w, r, "/view/"+title, http.StatusFound)
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -845,9 +845,9 @@ a title string:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func viewHandler(c *http.Conn, r *http.Request, title string)
|
func viewHandler(w http.ResponseWriter, r *http.Request, title string)
|
||||||
func editHandler(c *http.Conn, r *http.Request, title string)
|
func editHandler(w http.ResponseWriter, r *http.Request, title string)
|
||||||
func saveHandler(c *http.Conn, r *http.Request, title string)
|
func saveHandler(w http.ResponseWriter, r *http.Request, title string)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -857,8 +857,8 @@ type</i>, and returns a function of type <code>http.HandlerFunc</code>
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func makeHandler(fn func (*http.Conn, *http.Request, string)) http.HandlerFunc {
|
func makeHandler(fn func (http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
|
||||||
return func(c *http.Conn, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
// Here we will extract the page title from the Request,
|
// Here we will extract the page title from the Request,
|
||||||
// and call the provided handler 'fn'
|
// and call the provided handler 'fn'
|
||||||
}
|
}
|
||||||
@ -878,28 +878,28 @@ Now we can take the code from <code>getTitle</code> and use it here
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func makeHandler(fn func(*http.Conn, *http.Request, string)) http.HandlerFunc {
|
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
|
||||||
return func(c *http.Conn, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
if !titleValidator.MatchString(title) {
|
if !titleValidator.MatchString(title) {
|
||||||
http.NotFound(c, r)
|
http.NotFound(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fn(c, r, title)
|
fn(w, r, title)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The closure returned by <code>makeHandler</code> is a function that takes
|
The closure returned by <code>makeHandler</code> is a function that takes
|
||||||
an <code>http.Conn</code> and <code>http.Request</code> (in other words,
|
an <code>http.ResponseWriter</code> and <code>http.Request</code> (in other
|
||||||
an <code>http.HandlerFunc</code>).
|
words, an <code>http.HandlerFunc</code>).
|
||||||
The closure extracts the <code>title</code> from the request path, and
|
The closure extracts the <code>title</code> from the request path, and
|
||||||
validates it with the <code>titleValidator</code> regexp. If the
|
validates it with the <code>titleValidator</code> regexp. If the
|
||||||
<code>title</code> is invalid, an error will be written to the
|
<code>title</code> is invalid, an error will be written to the
|
||||||
<code>Conn</code> using the <code>http.NotFound</code> function.
|
<code>ResponseWriter</code> using the <code>http.NotFound</code> function.
|
||||||
If the <code>title</code> is valid, the enclosed handler function
|
If the <code>title</code> is valid, the enclosed handler function
|
||||||
<code>fn</code> will be called with the <code>Conn</code>,
|
<code>fn</code> will be called with the <code>ResponseWriter</code>,
|
||||||
<code>Request</code>, and <code>title</code> as arguments.
|
<code>Request</code>, and <code>title</code> as arguments.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -924,32 +924,32 @@ making them much simpler:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func viewHandler(c *http.Conn, r *http.Request, title string) {
|
func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Redirect(c, "/edit/"+title, http.StatusFound)
|
http.Redirect(w, r, "/edit/"+title, http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
renderTemplate(c, "view", p)
|
renderTemplate(w, "view", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func editHandler(c *http.Conn, r *http.Request, title string) {
|
func editHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p = &page{title: title}
|
p = &page{title: title}
|
||||||
}
|
}
|
||||||
renderTemplate(c, "edit", p)
|
renderTemplate(w, "edit", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveHandler(c *http.Conn, r *http.Request, title string) {
|
func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
|
||||||
body := r.FormValue("body")
|
body := r.FormValue("body")
|
||||||
p := &page{title: title, body: []byte(body)}
|
p := &page{title: title, body: []byte(body)}
|
||||||
err := p.save()
|
err := p.save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(c, err.String(), http.StatusInternalServerError)
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.Redirect(c, "/view/"+title, http.StatusFound)
|
http.Redirect(w, r, "/view/"+title, http.StatusFound)
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
@ -28,19 +28,19 @@ func loadPage(title string) (*page, os.Error) {
|
|||||||
|
|
||||||
const lenPath = len("/view/")
|
const lenPath = len("/view/")
|
||||||
|
|
||||||
func viewHandler(c *http.Conn, r *http.Request) {
|
func viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, _ := loadPage(title)
|
p, _ := loadPage(title)
|
||||||
fmt.Fprintf(c, "<h1>%s</h1><div>%s</div>", p.title, p.body)
|
fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.title, p.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
func editHandler(c *http.Conn, r *http.Request) {
|
func editHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, err := loadPage(title)
|
p, err := loadPage(title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p = &page{title: title}
|
p = &page{title: title}
|
||||||
}
|
}
|
||||||
fmt.Fprintf(c, "<h1>Editing %s</h1>"+
|
fmt.Fprintf(w, "<h1>Editing %s</h1>"+
|
||||||
"<form action=\"/save/%s\" method=\"POST\">"+
|
"<form action=\"/save/%s\" method=\"POST\">"+
|
||||||
"<textarea name=\"body\">%s</textarea><br>"+
|
"<textarea name=\"body\">%s</textarea><br>"+
|
||||||
"<input type=\"submit\" value=\"Save\">"+
|
"<input type=\"submit\" value=\"Save\">"+
|
||||||
|
@ -28,10 +28,10 @@ func loadPage(title string) (*page, os.Error) {
|
|||||||
|
|
||||||
const lenPath = len("/view/")
|
const lenPath = len("/view/")
|
||||||
|
|
||||||
func viewHandler(c *http.Conn, r *http.Request) {
|
func viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
title := r.URL.Path[lenPath:]
|
title := r.URL.Path[lenPath:]
|
||||||
p, _ := loadPage(title)
|
p, _ := loadPage(title)
|
||||||
fmt.Fprintf(c, "<h1>%s</h1><div>%s</div>", p.title, p.body)
|
fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.title, p.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -230,12 +230,12 @@ This function will block until the program is terminated.
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
The function <code>handler</code> is of the type <code>http.HandlerFunc</code>.
|
The function <code>handler</code> is of the type <code>http.HandlerFunc</code>.
|
||||||
It takes an <code>http.Conn</code> and <code>http.Request</code> as its
|
It takes an <code>http.ResponseWriter</code> and an <code>http.Request</code> as
|
||||||
arguments.
|
its arguments.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
An <code>http.Conn</code> is the server end of an HTTP connection; by writing
|
An <code>http.ResponseWriter</code> value assembles the HTTP server's response; by writing
|
||||||
to it, we send data to the HTTP client.
|
to it, we send data to the HTTP client.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -293,7 +293,7 @@ begin with <code>"/view/"</code>, which is not part of the page title.
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
The function then loads the page data, formats the page with a string of simple
|
The function then loads the page data, formats the page with a string of simple
|
||||||
HTML, and writes it to <code>c</code>, the <code>http.Conn</code>.
|
HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -415,7 +415,7 @@ The function <code>template.ParseFile</code> will read the contents of
|
|||||||
The method <code>t.Execute</code> replaces all occurrences of
|
The method <code>t.Execute</code> replaces all occurrences of
|
||||||
<code>{title}</code> and <code>{body}</code> with the values of
|
<code>{title}</code> and <code>{body}</code> with the values of
|
||||||
<code>p.title</code> and <code>p.body</code>, and writes the resultant
|
<code>p.title</code> and <code>p.body</code>, and writes the resultant
|
||||||
HTML to the <code>http.Conn</code>.
|
HTML to the <code>http.ResponseWriter</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -667,9 +667,9 @@ a title string:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func viewHandler(c *http.Conn, r *http.Request, title string)
|
func viewHandler(w http.ResponseWriter, r *http.Request, title string)
|
||||||
func editHandler(c *http.Conn, r *http.Request, title string)
|
func editHandler(w http.ResponseWriter, r *http.Request, title string)
|
||||||
func saveHandler(c *http.Conn, r *http.Request, title string)
|
func saveHandler(w http.ResponseWriter, r *http.Request, title string)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -679,8 +679,8 @@ type</i>, and returns a function of type <code>http.HandlerFunc</code>
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func makeHandler(fn func (*http.Conn, *http.Request, string)) http.HandlerFunc {
|
func makeHandler(fn func (http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
|
||||||
return func(c *http.Conn, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
// Here we will extract the page title from the Request,
|
// Here we will extract the page title from the Request,
|
||||||
// and call the provided handler 'fn'
|
// and call the provided handler 'fn'
|
||||||
}
|
}
|
||||||
@ -705,14 +705,14 @@ Now we can take the code from <code>getTitle</code> and use it here
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
The closure returned by <code>makeHandler</code> is a function that takes
|
The closure returned by <code>makeHandler</code> is a function that takes
|
||||||
an <code>http.Conn</code> and <code>http.Request</code> (in other words,
|
an <code>http.ResponseWriter</code> and <code>http.Request</code> (in other
|
||||||
an <code>http.HandlerFunc</code>).
|
words, an <code>http.HandlerFunc</code>).
|
||||||
The closure extracts the <code>title</code> from the request path, and
|
The closure extracts the <code>title</code> from the request path, and
|
||||||
validates it with the <code>titleValidator</code> regexp. If the
|
validates it with the <code>titleValidator</code> regexp. If the
|
||||||
<code>title</code> is invalid, an error will be written to the
|
<code>title</code> is invalid, an error will be written to the
|
||||||
<code>Conn</code> using the <code>http.NotFound</code> function.
|
<code>ResponseWriter</code> using the <code>http.NotFound</code> function.
|
||||||
If the <code>title</code> is valid, the enclosed handler function
|
If the <code>title</code> is valid, the enclosed handler function
|
||||||
<code>fn</code> will be called with the <code>Conn</code>,
|
<code>fn</code> will be called with the <code>ResponseWriter</code>,
|
||||||
<code>Request</code>, and <code>title</code> as arguments.
|
<code>Request</code>, and <code>title</code> as arguments.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user