-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.go
72 lines (63 loc) · 2.12 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package main
import (
"errors"
"fmt"
"net/http"
)
// Server errors, both to be reported to the admin and to the
// connecting user.
var (
ErrNoID = errors.New("no id presented")
ErrNoData = errors.New("no data field presented")
ErrInvalidData = errors.New("data could not be parsed: %s")
)
func serve(iface, port string) (err error) {
l.Printf("Starting server at %q on %s:%s", *fRoot, iface, port)
http.HandleFunc(*fRoot+"pickup", handlePickup)
http.HandleFunc(*fRoot+"delivery", handleDelivery)
return http.ListenAndServe(iface+":"+port, nil)
}
func handlePickup(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Pickup, gov'ner?"))
}
func handleDelivery(w http.ResponseWriter, r *http.Request) {
// Retrieve the ID from the form, and abort if it's not given.
id := r.FormValue("id")
if len(id) == 0 {
l.Printf("Delivery from %s aborted: %s\n", r.RemoteAddr, ErrNoID)
http.Error(w, ErrNoID.Error(), http.StatusBadRequest)
return
}
// Now retrieve the data, and abort if it's not given.
data := r.FormValue("data")
if len(data) == 0 {
l.Printf("Delivery from %s aborted: %s\n", r.RemoteAddr, ErrNoData)
http.Error(w, ErrNoData.Error(), http.StatusBadRequest)
return
}
// BUG(DuoNoxSol): There is no authentication. This should be
// added. The general idea is that the ID is looked up and matched
// with a password. Then, the hash (probably SHA-256) of the data
// and id are matched with one provided in the request. If they
// don't match, abort.
// Try to create a snapshot from the given information, and report
// if it fails.
s, err := BuildSnapshot(id, r.FormValue("timestamp"), data)
if err != nil {
report := fmt.Errorf(ErrInvalidData.Error(), err)
l.Printf("Delivery from %s aborted: %s\n", r.RemoteAddr,
report)
http.Error(w, report.Error(), http.StatusBadRequest)
return
}
// Finally, register it in the database. If this fails, report it
// both in the log and to the web.
err = Store(s)
if err != nil {
l.Printf("Attempt to store snapshot failed: %s\n", err)
http.Error(w, "Database store failed.",
http.StatusInternalServerError)
return
}
w.Write([]byte("Successful."))
}