update code to latest go
[epoint] / cmd / epoint-server / epoint-server.go
1 package main
2
3 import (
4         "epoint/key"
5         "epoint/server"
6         "fmt"
7         "log"
8         "net/http"
9         "os"
10 )
11
12 const (
13         addr    = ":8080"
14         rootdir = "docroot"
15         seckey  = "./key.sec"
16 )
17
18 // todo: http header limit: 64K, body limit: 64K
19
20 func httpError(w http.ResponseWriter, code int, msg string) {
21         log.Printf("error: %d %s", code, msg)
22         http.Error(w, fmt.Sprintf("%d %s\n\n%s\n", code, http.StatusText(code), msg), code)
23 }
24
25 func httpReq(r *http.Request) string {
26         err := r.ParseForm()
27         form := ""
28         if err != nil {
29                 form = err.Error()
30         } else {
31                 a := []string{}
32                 for k := range r.Form {
33                         a = append(a, k)
34                 }
35                 form = fmt.Sprintf("%v", a)
36         }
37         return fmt.Sprintf("%s %s params:%s", r.Method, r.URL, form)
38 }
39
40 func defaultHandler(w http.ResponseWriter, r *http.Request) {
41         log.Printf("%s %s", r.RemoteAddr, httpReq(r))
42         fmt.Fprintf(w, "not implemented: %s %s\n", r.Method, r.URL)
43 }
44
45 func submitHandler(w http.ResponseWriter, r *http.Request) {
46         log.Printf("%s %s", r.RemoteAddr, httpReq(r))
47         draft := r.FormValue("draft")
48         debit := r.FormValue("debit")
49         key := r.FormValue("key")
50         switch {
51         case draft != "":
52                 cert, err := server.EvalDraft([]byte(draft))
53                 if err != nil {
54                         msg := fmt.Sprintf("eval draft failed: %s", err)
55                         httpError(w, 404, msg)
56                 } else {
57                         w.Write(cert)
58                 }
59         case debit != "":
60                 cert, err := server.EvalDebitCert([]byte(debit))
61                 if err != nil {
62                         msg := fmt.Sprintf("eval debit failed: %s", err)
63                         httpError(w, 404, msg)
64                 } else {
65                         w.Write(cert)
66                 }
67         case key != "":
68                 err := server.AddKeys([]byte(key))
69                 if err != nil {
70                         msg := fmt.Sprintf("add keys failed: %s", err)
71                         httpError(w, 404, msg)
72                 } else {
73                         w.Write([]byte("ok\nTODO: create cert 1 here?"))
74                 }
75         default:
76                 msg := fmt.Sprintf("expected key, draft or debit param, got: %s", httpReq(r))
77                 httpError(w, 404, msg)
78         }
79 }
80
81 func main() {
82         // TODO: serious keygen
83         serverkey, err := key.Server([]byte("secret seed"))
84         if err != nil {
85                 log.Fatal(err)
86         }
87         err = server.Init(rootdir, serverkey)
88         if err != nil {
89                 log.Fatal(err)
90         }
91
92         // TODO: url from key
93         f, err := os.Create(rootdir + "/form.html")
94         if err != nil {
95                 log.Fatal(err)
96         }
97         _, _ = fmt.Fprintf(f, `<html><head><title>epoint-server submit form</title></head><body>
98 <h2>epoint-server submit form</h2>
99 <h3>web form</h3>
100 <p>submit one document at a time
101 <form method="post" action="/submit">
102 <p>key:<br><textarea name="key" rows="5" cols="80"></textarea>
103 <p>draft:<br><textarea name="draft" rows="5" cols="80"></textarea>
104 <p>debit:<br><textarea name="debit" rows="5" cols="80"></textarea>
105 <p><input type="submit">
106 </form>
107 <h3>command line</h3>
108 <pre>
109 curl --data-urlencode name@path/to/file.txt host/submit
110 </pre>
111 where 'name' is 'key', 'draft' or 'debit'.
112 </body></html>
113 `)
114         _ = f.Close()
115
116         // queries
117         http.Handle("/", http.FileServer(http.Dir(rootdir)))
118
119         // actions
120         // withdraw, draw, deposit, process, clear
121         http.HandleFunc("/submit", submitHandler)
122
123         log.Printf("start service on %s, server key id: %s\n", addr, key.Id(serverkey))
124         log.Fatal(http.ListenAndServe(addr, nil))
125 }