-
Notifications
You must be signed in to change notification settings - Fork 0
/
http.go
132 lines (110 loc) · 4.09 KB
/
http.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
128
129
130
131
132
// Copyright 2017 Inca Roads LLC. All rights reserved.
// Use of this source code is governed by licenses granted by the
// copyright holder including that found in the LICENSE file.
// Common support for all HTTP topic handlers
package main
import (
"fmt"
"io"
"net/http"
"net/url"
"strconv"
"strings"
)
// HTTPInboundHandler kicks off inbound messages coming from all sources, then serve HTTP
func HTTPInboundHandler() {
// Spin up functions only available on the monitor role, of which there is only one
if ThisServerIsMonitor {
http.HandleFunc(TTServerTopicGithub, inboundWebGithubHandler)
http.HandleFunc(TTServerTopicSlack, inboundWebSlackHandler)
}
// Spin up TTN
if !TTNMQTTMode {
http.HandleFunc(TTServerTopicTTN, inboundWebTTNHandler)
}
// Spin up misc handlers
http.HandleFunc(TTServerTopicRoot1, inboundWebRootHandler)
http.HandleFunc(TTServerTopicRoot2, inboundWebRootHandler)
http.HandleFunc(TTServerTopicDevices, inboundWebDevicesHandler)
http.HandleFunc(TTServerTopicDeviceLog, inboundWebDeviceLogHandler)
http.HandleFunc(TTServerTopicFile, inboundWebFileHandler)
http.HandleFunc(TTServerTopicDeviceCheck, inboundWebDeviceCheckHandler)
http.HandleFunc(TTServerTopicDeviceStatus, inboundWebDeviceStatusHandler)
http.HandleFunc(TTServerTopicServerLog, inboundWebServerLogHandler)
http.HandleFunc(TTServerTopicServerStatus, inboundWebServerStatusHandler)
http.HandleFunc(TTServerTopicGatewayStatus, inboundWebGatewayStatusHandler)
http.HandleFunc(TTServerTopicGatewayUpdate, inboundWebGatewayUpdateHandler)
http.HandleFunc(TTServerTopicSend, inboundWebSendHandler)
http.HandleFunc(TTServerTopicNote, inboundWebNoteHandler)
http.HandleFunc(TTServerTopicNoteTest, inboundWebNoteHandlerTest)
http.HandleFunc(TTServerTopicRedirect1, inboundWebRedirectHandler)
http.HandleFunc(TTServerTopicRedirect2, inboundWebRedirectHandler)
http.HandleFunc(TTServerTopicID, inboundWebIDHandler)
http.HandleFunc(TTServerTopicMap, inboundWebMapHandler)
http.HandleFunc(TTServerTopicDashboard, inboundWebDashboardHandler)
http.HandleFunc(TTServerTopicProfile, inboundWebProfileHandler)
// Listen on the alternate HTTP port
go func() {
fmt.Printf("Now handling inbound HTTP on %s:%s\n", ThisServerAddressIPv4, TTServerHTTPPortAlternate)
http.ListenAndServe(TTServerHTTPPortAlternate, nil)
}()
// Listen on the primary HTTP port
fmt.Printf("Now handling inbound HTTP on %s:%s\n", ThisServerAddressIPv4, TTServerHTTPPort)
http.ListenAndServe(TTServerHTTPPort, nil)
}
// Handle inbound HTTP requests for root
func inboundWebRootHandler(rw http.ResponseWriter, req *http.Request) {
stats.Count.HTTP++
io.WriteString(rw, fmt.Sprintf("Hello. (%s)\n", ThisServerAddressIPv4))
}
// HTTPArgs parses the request URI and returns interesting things
func HTTPArgs(req *http.Request, topic string) (target string, args map[string]string, err error) {
args = map[string]string{}
// Trim the request URI
target = req.RequestURI[len(topic):]
// If nothing left, there were no args
if len(target) == 0 {
return
}
// Make sure that the prefix is "/", else the pattern matcher is matching something we don't want
target = strings.TrimPrefix(target, "/")
// See if there is a query, and if so process it
str := strings.SplitN(target, "?", 2)
if len(str) == 1 {
return
}
target = str[0]
remainder := str[1]
// See if there is an anchor on the target, and special-case it
str2 := strings.Split(target, "#")
if len(str2) > 1 {
target = str2[0]
args["anchor"] = str2[1]
}
// Now that we know we have args, parse them
values, err2 := url.ParseQuery(remainder)
if err2 != nil {
err = err2
fmt.Printf("can't parse query: %s\n%s\n", err, str[1])
return
}
// Generate the return arg in the format we expect
for k, v := range values {
if len(v) == 1 {
str := v[0]
// Safely unquote the value. This fails if there are NO quotes, so
// only replace the str value if no error occurs
s, err2 := strconv.Unquote(str)
if err2 == nil {
str = s
}
args[k], err = url.PathUnescape(str)
if err != nil {
fmt.Printf("can't unescape: %s\n%s\n", err, str)
return
}
}
}
// Done
return
}