-
Notifications
You must be signed in to change notification settings - Fork 166
/
main.go
127 lines (103 loc) · 2.71 KB
/
main.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"encoding/json"
"flag"
"fmt"
"net/http"
"strings"
"time"
"github.com/hugomd/ascii-live/frames"
"github.com/golang/glog"
"github.com/gorilla/mux"
)
var NotFoundMessage = map[string]string{
"error": "Frames not found. Navigate to /list for list of frames. Navigate to https://github.com/hugomd/ascii-live to submit new frames.",
}
var NotCurledMessage = map[string]string{
"error": "You almost ruined a good surprise. Come on, curl it in terminal.",
}
var availableFrames []string
func init() {
for k := range frames.FrameMap {
availableFrames = append(availableFrames, k)
}
}
func writeJson(w http.ResponseWriter, r *http.Request, res interface{}, status int) {
w.Header().Set("Content-Type", "application/json")
data, err := json.Marshal(res)
if err != nil {
return
}
w.WriteHeader(status)
fmt.Fprint(w, string(data))
}
func listHandler(w http.ResponseWriter, r *http.Request) {
writeJson(w, r, map[string][]string{"frames": availableFrames}, http.StatusOK)
}
func notFoundHandler(w http.ResponseWriter, r *http.Request) {
writeJson(w, r, NotFoundMessage, http.StatusNotFound)
}
func notCurledHandler(w http.ResponseWriter, r *http.Request) {
writeJson(w, r, NotCurledMessage, http.StatusExpectationFailed)
}
func handler(w http.ResponseWriter, r *http.Request) {
cn := w.(http.CloseNotifier)
flusher := w.(http.Flusher)
vars := mux.Vars(r)
frameSource := vars["frameSource"]
glog.Infof("Frame source %s", frameSource)
frames, ok := frames.FrameMap[frameSource]
if !ok {
notFoundHandler(w, r)
return
}
userAgent := r.Header.Get("User-Agent")
if !strings.Contains(userAgent, "curl") {
notCurledHandler(w, r)
return
}
w.Header().Set("Transfer-Encoding", "chunked")
w.WriteHeader(http.StatusOK)
i := 0
for {
select {
// Handle client disconnects
case <-cn.CloseNotify():
glog.Infof("Client stopped listening")
return
default:
if i >= frames.GetLength() {
i = 0
}
// Artificially wait between reponses.
time.Sleep(frames.GetSleep())
// Clear screen
clearScreen := "\033[2J\033[H"
newLine := "\n"
// Write frames
fmt.Fprintf(w, clearScreen+frames.GetFrame(i)+newLine)
i++
// Send some data.
flusher.Flush()
}
}
}
// Server.
func main() {
flag.Parse()
// Don't write to /tmp - doesn't work in docker scratch
flag.Set("logtostderr", "true")
r := mux.NewRouter()
r.HandleFunc("/list", listHandler).Methods("GET")
r.HandleFunc("/{frameSource}", handler).Methods("GET")
r.NotFoundHandler = http.HandlerFunc(notFoundHandler)
srv := &http.Server{
Handler: r,
Addr: ":8080",
// Set unlimited read/write timeouts
ReadTimeout: 0,
WriteTimeout: 0,
}
glog.Infof("Serving...")
glog.Fatal(srv.ListenAndServe())
}