OLD | NEW |
1 package main | 1 package main |
2 | 2 |
3 import ( | 3 import ( |
4 "http" | 4 "http" |
5 "io/ioutil" | 5 "io/ioutil" |
6 "os" | |
7 "regexp" | 6 "regexp" |
8 "template" | 7 "template" |
9 ) | 8 ) |
10 | 9 |
11 type Page struct { | 10 type Page struct { |
12 Title string | 11 Title string |
13 Body []byte | 12 Body []byte |
14 } | 13 } |
15 | 14 |
16 func (p *Page) save() os.Error { | 15 func (p *Page) save() error { |
17 filename := p.Title + ".txt" | 16 filename := p.Title + ".txt" |
18 return ioutil.WriteFile(filename, p.Body, 0600) | 17 return ioutil.WriteFile(filename, p.Body, 0600) |
19 } | 18 } |
20 | 19 |
21 func loadPage(title string) (*Page, os.Error) { | 20 func loadPage(title string) (*Page, error) { |
22 filename := title + ".txt" | 21 filename := title + ".txt" |
23 body, err := ioutil.ReadFile(filename) | 22 body, err := ioutil.ReadFile(filename) |
24 if err != nil { | 23 if err != nil { |
25 return nil, err | 24 return nil, err |
26 } | 25 } |
27 return &Page{Title: title, Body: body}, nil | 26 return &Page{Title: title, Body: body}, nil |
28 } | 27 } |
29 | 28 |
30 func viewHandler(w http.ResponseWriter, r *http.Request, title string) { | 29 func viewHandler(w http.ResponseWriter, r *http.Request, title string) { |
31 p, err := loadPage(title) | 30 p, err := loadPage(title) |
(...skipping 10 matching lines...) Expand all Loading... |
42 p = &Page{Title: title} | 41 p = &Page{Title: title} |
43 } | 42 } |
44 renderTemplate(w, "edit", p) | 43 renderTemplate(w, "edit", p) |
45 } | 44 } |
46 | 45 |
47 func saveHandler(w http.ResponseWriter, r *http.Request, title string) { | 46 func saveHandler(w http.ResponseWriter, r *http.Request, title string) { |
48 body := r.FormValue("body") | 47 body := r.FormValue("body") |
49 p := &Page{Title: title, Body: []byte(body)} | 48 p := &Page{Title: title, Body: []byte(body)} |
50 err := p.save() | 49 err := p.save() |
51 if err != nil { | 50 if err != nil { |
52 » » http.Error(w, err.String(), http.StatusInternalServerError) | 51 » » http.Error(w, err.Error(), http.StatusInternalServerError) |
53 return | 52 return |
54 } | 53 } |
55 http.Redirect(w, r, "/view/"+title, http.StatusFound) | 54 http.Redirect(w, r, "/view/"+title, http.StatusFound) |
56 } | 55 } |
57 | 56 |
58 func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { | 57 func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { |
59 t, err := template.ParseFile(tmpl+".html", nil) | 58 t, err := template.ParseFile(tmpl+".html", nil) |
60 if err != nil { | 59 if err != nil { |
61 » » http.Error(w, err.String(), http.StatusInternalServerError) | 60 » » http.Error(w, err.Error(), http.StatusInternalServerError) |
62 return | 61 return |
63 } | 62 } |
64 err = t.Execute(w, p) | 63 err = t.Execute(w, p) |
65 if err != nil { | 64 if err != nil { |
66 » » http.Error(w, err.String(), http.StatusInternalServerError) | 65 » » http.Error(w, err.Error(), http.StatusInternalServerError) |
67 } | 66 } |
68 } | 67 } |
69 | 68 |
70 const lenPath = len("/view/") | 69 const lenPath = len("/view/") |
71 | 70 |
72 var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$") | 71 var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$") |
73 | 72 |
74 func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.Handl
erFunc { | 73 func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.Handl
erFunc { |
75 return func(w http.ResponseWriter, r *http.Request) { | 74 return func(w http.ResponseWriter, r *http.Request) { |
76 title := r.URL.Path[lenPath:] | 75 title := r.URL.Path[lenPath:] |
77 if !titleValidator.MatchString(title) { | 76 if !titleValidator.MatchString(title) { |
78 http.NotFound(w, r) | 77 http.NotFound(w, r) |
79 return | 78 return |
80 } | 79 } |
81 fn(w, r, title) | 80 fn(w, r, title) |
82 } | 81 } |
83 } | 82 } |
84 | 83 |
85 func main() { | 84 func main() { |
86 http.HandleFunc("/view/", makeHandler(viewHandler)) | 85 http.HandleFunc("/view/", makeHandler(viewHandler)) |
87 http.HandleFunc("/edit/", makeHandler(editHandler)) | 86 http.HandleFunc("/edit/", makeHandler(editHandler)) |
88 http.HandleFunc("/save/", makeHandler(saveHandler)) | 87 http.HandleFunc("/save/", makeHandler(saveHandler)) |
89 http.ListenAndServe(":8080", nil) | 88 http.ListenAndServe(":8080", nil) |
90 } | 89 } |
OLD | NEW |