16 rootdir = flag.String("dir", "docroot", "root dir for storage")
17 seckey = flag.String("key", "", "secret key, empty means generated")
18 addr = flag.String("addr", ":8080", "address to listen on")
21 // todo: http header limit: 64K, body limit: 64K
23 func httpError(w http.ResponseWriter, code int, msg string) {
24 log.Printf("error: %d %s", code, msg)
25 http.Error(w, fmt.Sprintf("%d %s\n\n%s\n", code, http.StatusText(code), msg), code)
28 func httpReq(r *http.Request) string {
35 for k := range r.Form {
38 form = fmt.Sprintf("%v", a)
40 return fmt.Sprintf("%s %s params:%s", r.Method, r.URL, form)
43 func defaultHandler(w http.ResponseWriter, r *http.Request) {
44 log.Printf("%s %s", r.RemoteAddr, httpReq(r))
45 fmt.Fprintf(w, "not implemented: %s %s\n", r.Method, r.URL)
48 func submitHandler(w http.ResponseWriter, r *http.Request) {
49 log.Printf("%s %s", r.RemoteAddr, httpReq(r))
50 draft := r.FormValue("draft")
51 debit := r.FormValue("debit")
52 key := r.FormValue("key")
55 cert, err := server.EvalDraft([]byte(draft))
57 msg := fmt.Sprintf("eval draft failed: %s", err)
58 httpError(w, 404, msg)
63 cert, err := server.EvalDebitCert([]byte(debit))
65 msg := fmt.Sprintf("eval debit failed: %s", err)
66 httpError(w, 404, msg)
71 err := server.AddKeys([]byte(key))
73 msg := fmt.Sprintf("add keys failed: %s", err)
74 httpError(w, 404, msg)
76 w.Write([]byte("ok\n"))
79 msg := fmt.Sprintf("expected key, draft or debit param, got: %s", httpReq(r))
80 httpError(w, 404, msg)
84 func initkey(path string) (sk *openpgp.Entity, err error) {
86 // TODO: serious keygen, server key depends on time
87 return key.Server([]byte("secret seed"))
89 d, err := ioutil.ReadFile(path)
98 serverkey, err := initkey(*seckey)
102 err = server.Init(*rootdir, serverkey)
107 // TODO: url from key
108 f, err := os.Create(*rootdir + "/form.html")
112 _, _ = fmt.Fprintf(f, `<html><head><title>epoint-server submit form</title></head><body>
113 <h2>epoint-server submit form</h2>
115 <p>submit one document at a time
116 <form method="post" action="/submit">
117 <p>key:<br><textarea name="key" rows="5" cols="80"></textarea>
118 <p>draft:<br><textarea name="draft" rows="5" cols="80"></textarea>
119 <p>debit:<br><textarea name="debit" rows="5" cols="80"></textarea>
120 <p><input type="submit">
122 <h3>command line</h3>
124 curl --data-urlencode name@path/to/file.txt host/submit
126 where 'name' is 'key', 'draft' or 'debit'.
132 http.Handle("/", http.FileServer(http.Dir(*rootdir)))
135 // withdraw, draw, deposit, process, clear
136 http.HandleFunc("/submit", submitHandler)
138 log.Printf("start service on %s, server key id: %s\n", *addr, key.Id(serverkey))
139 log.Fatal(http.ListenAndServe(*addr, nil))