-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
110 lines (93 loc) · 3.26 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
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"log/syslog"
"net/http"
"regexp"
)
type URLMapping struct {
RedirectPath string `json:"redirectPath"`
DestinationURL string `json:"destinationURL"`
RegexPattern string `json:"regexPattern,omitempty"`
}
var (
urlMappings []URLMapping
sysLogger *syslog.Writer
err error
)
func initLogger() {
// Setup syslog for logging.
sysLogger, err = syslog.New(syslog.LOG_INFO|syslog.LOG_LOCAL7, "urlsnip")
if err != nil {
log.Fatalf("Failed to initialize syslog: %v", err)
}
}
func loadConfig(filePath string) {
data, err := ioutil.ReadFile(filePath)
if err != nil {
logMessage := fmt.Sprintf("Failed to read config file: %v", err)
log.Fatal(logMessage)
sysLogger.Err(logMessage)
}
err = json.Unmarshal(data, &urlMappings)
if err != nil {
logMessage := fmt.Sprintf("Failed to parse config file: %v", err)
log.Fatal(logMessage)
sysLogger.Err(logMessage)
}
log.Println("Configuration file loaded successfully")
sysLogger.Info("Configuration file loaded successfully")
}
func redirectHandler(w http.ResponseWriter, r *http.Request) {
requestedURL := r.URL.Path[1:]
for _, mapping := range urlMappings {
if mapping.RedirectPath == requestedURL {
http.Redirect(w, r, mapping.DestinationURL, http.StatusFound)
logMessage := fmt.Sprintf("Redirected '%s' to '%s'", requestedURL, mapping.DestinationURL)
log.Println(logMessage)
sysLogger.Info(logMessage)
return
}
if mapping.RegexPattern != "" {
matched, regexErr := regexp.MatchString(mapping.RegexPattern, requestedURL)
if regexErr != nil {
logMessage := fmt.Sprintf("Regex error for pattern '%s': %v", mapping.RegexPattern, regexErr)
log.Println(logMessage)
sysLogger.Err(logMessage)
continue
}
if matched {
http.Redirect(w, r, mapping.DestinationURL, http.StatusFound)
logMessage := fmt.Sprintf("Redirected via route '%s' to '%s' using pattern '%s'", requestedURL, mapping.DestinationURL, mapping.RegexPattern)
log.Println(logMessage)
sysLogger.Info(logMessage)
return
}
}
}
logMessage := fmt.Sprintf("No redirect mapping found for url '%s'", requestedURL)
log.Println(logMessage)
sysLogger.Warning(logMessage)
http.NotFound(w, r)
}
func main() {
configFilePath := flag.String("config", "config.json", "Path to the configuration file")
port := flag.Int("port", 8080, "Port on which the server will run")
flag.Parse()
initLogger()
defer sysLogger.Close()
loadConfig(*configFilePath)
http.HandleFunc("/", redirectHandler)
serverAddress := fmt.Sprintf(":%d", *port)
log.Printf("Server starting on %s", serverAddress)
sysLogger.Info(fmt.Sprintf("Server starting on %s", serverAddress))
err = http.ListenAndServe(serverAddress, nil)
if err != nil {
sysLogger.Err(fmt.Sprintf("Server failed to start: %v", err))
log.Fatalf("Server failed to start: %v", err)
}
}