This repository was archived by the owner on May 14, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
138 lines (123 loc) · 4.76 KB
/
main.go
File metadata and controls
138 lines (123 loc) · 4.76 KB
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
133
134
135
136
137
138
//go:generate go run -tags=dev assets_generate.go
package main
import (
"context"
"expvar"
"flag"
"io/ioutil"
"net/http"
"os"
"os/signal"
"regexp"
"time"
"github.com/mdigger/app-info"
"github.com/mdigger/mx-http-proxy/mx"
"github.com/mdigger/log"
"github.com/mdigger/rest"
)
var (
appName = "MX-HTTP-Proxy"
version string // версия приложения
commit string // идентификатор коммита git
date string // дата сборки
mxhost = app.Env("MX", "") // адрес сервера MX
)
func main() {
// разбираем параметры сервиса
flag.StringVar(&mxhost, "mx", mxhost, "mx server `host`")
var httphost = flag.String("port", app.Env("PORT", ":8000"),
"http server `port`")
flag.Parse()
// выводим в лог информацию о версии сервиса
app.Parse(appName, version, commit, date)
log.Info("service", app.LogInfo())
var mxlogger = log.New("mx")
mx.Logger = mxlogger.StdLog(log.TRACE) // настраиваем вывод лога MX
// проверяем доступность сервера MX
if _, err := mx.Connect(mxhost, nil); err != nil {
mxlogger.Error("mx server unavailable", "host", mxhost, err)
os.Exit(2)
}
mxlogger.Info("using mx server", "host", mxhost)
mhost.Set(mxhost)
var conns = new(Conns) // инициализируем список подключений к MX
defer conns.Close() // закрываем все соединения по окончании
// разбираем имя хоста и порт, на котором будет слушать веб-сервер
port, err := app.Port(*httphost)
if err != nil {
log.Error("http host parse error", err)
os.Exit(2)
}
// инициализируем обработку HTTP запросов
var httplogger = log.New("http")
var mux = &rest.ServeMux{
Headers: map[string]string{
"Server": app.Agent,
"Access-Control-Allow-Origin": "*",
},
Logger: httplogger,
}
// обработчики команд
mux.Handle("POST", "/login", conns.Login)
mux.Handle("POST", "/logout", conns.Logout)
mux.Handle("POST", "/:cmd", conns.Commands)
mux.Handle("GET", "/events", conns.Events)
// добавляем обработку отдачи документации и дополнительных статических
// файлов через веб-сервер
mux.Handle("GET", "/*file", rest.HTTPFiles(assets, "index.html"))
// проверяем, что вывод осуществляется из "живого" каталога, а не из
// внедренных в исполняемый файл данных
if assets, ok := assets.(http.Dir); ok {
httplogger.Warn("live http assets", "folder", assets)
}
// добавляем версию документации
if file, err := assets.Open("openapi.yaml"); err == nil {
if data, err := ioutil.ReadAll(file); err == nil {
var v = regexp.MustCompile(`version:\s(.+)`).FindSubmatch(data)
if len(v) == 2 {
var ver = string(v[1])
httplogger.Info("api docs", "version", ver)
mux.Headers["X-API-Version"] = ver // добавляем версию API
}
}
file.Close()
} else {
// документация недоступна ни в виде отдельного каталога, ни в виде
// встроенных в исполняемый файл данных
httplogger.Warn("no http documentation")
}
// добавляем в статистику
mux.Handle("GET", "/debug/vars", rest.HTTPHandler(expvar.Handler()))
// инициализируем и запускаем сервер HTTP
var server = http.Server{
Addr: port,
Handler: mux,
IdleTimeout: 10 * time.Minute,
ReadHeaderTimeout: 5 * time.Second,
ErrorLog: httplogger.StdLog(log.ERROR),
}
// отслеживаем сигнал о прерывании и останавливаем по нему сервер
go func() {
var sigint = make(chan os.Signal, 1)
signal.Notify(sigint, os.Interrupt)
<-sigint
if err := server.Shutdown(context.Background()); err != nil {
httplogger.Error("server shutdown", err)
}
}()
// добавляем в статистику и выводим в лог информацию о запущенном сервере
if server.TLSConfig != nil {
// добавляем заголовок с обязательством использования защищенного
// соединения в ближайший час
mux.Headers["Strict-Transport-Security"] = "max-age=3600"
}
httplogger.Info("server",
"listen", server.Addr,
"tls", server.TLSConfig != nil,
)
if err = server.ListenAndServe(); err != http.ErrServerClosed {
httplogger.Error("server", err)
} else {
httplogger.Info("server stopped")
}
}