-
Notifications
You must be signed in to change notification settings - Fork 0
/
handlers.go
141 lines (115 loc) · 4.4 KB
/
handlers.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
133
134
135
136
137
138
139
140
141
package app
import (
"bytes"
"errors"
"net/url"
"strings"
"github.com/MindHunter86/addie/balancer"
"github.com/MindHunter86/addie/utils"
"github.com/gofiber/fiber/v2"
)
var (
errFbApiInvalidMode = errors.New("mode argument is invalid; values soft, hard are permited only")
errFbApiInvalidQuality = errors.New("quality argument is invalid; 480, 720, 1080 values are permited only")
)
func (*App) fbHndApiPreCondErr(ctx *fiber.Ctx) error {
switch ctx.Locals("errors").(appMidError) {
case errMidAppPreHeaderUri:
rlog(ctx).Warn().Msg(errApiPreBadUri.Error())
ctx.Set("X-Error", errApiPreBadUri.Error())
ctx.SendString(errApiPreBadUri.Error())
case errMidAppPreHeaderId:
rlog(ctx).Warn().Msg(errApiPreBadId.Error())
ctx.Set("X-Error", errApiPreBadId.Error())
ctx.SendString(errApiPreBadId.Error())
case errMidAppPreHeaderServer:
rlog(ctx).Warn().Msg(errApiPreBadServer.Error())
ctx.Set("X-Error", errApiPreBadServer.Error())
ctx.SendString(errApiPreBadServer.Error())
case errMidAppPreUriRegexp:
rlog(ctx).Warn().Msg(errApiPreUriRegexp.Error())
ctx.Set("X-Error", errApiPreUriRegexp.Error())
ctx.SendString(errApiPreUriRegexp.Error())
default:
rlog(ctx).Warn().Msg("unknown error")
}
return ctx.SendStatus(fiber.StatusPreconditionFailed)
}
func (m *App) fbHndAppRequestSign(ctx *fiber.Ctx) (e error) {
m.lapRequestTimer(ctx, utils.FbReqTmrReqSign)
rlog(ctx).Trace().Msg("new 'sign request' request")
srv, uri := ctx.Locals("srv").(string), ctx.Locals("uri").(string)
expires, extra := m.getHlpExtra(
ctx,
uri,
srv,
ctx.Locals("uid").(string),
)
var rrl *url.URL
if rrl, e = url.Parse(srv + uri); e != nil {
rlog(ctx).Debug().Str("url_parse", srv+uri).Str("remote_addr", ctx.IP()).
Msg("could not sign request; url.Parse error")
return fiber.NewError(fiber.StatusInternalServerError, e.Error())
}
var rgs = &url.Values{}
rgs.Add("expires", expires)
rgs.Add("extra", extra)
rrl.RawQuery, rrl.Scheme = rgs.Encode(), "https"
rlog(ctx).Debug().Str("computed_request", rrl.String()).Str("remote_addr", ctx.IP()).
Msg("request signing completed")
ctx.Set(apiHeaderLocation, rrl.String())
return ctx.SendStatus(fiber.StatusNoContent)
}
func (m *App) fbHndBlcNodesBalance(ctx *fiber.Ctx) error {
ctx.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
uri := ctx.Locals("uri").(*string)
sub := m.chunkRegexp.FindSubmatch([]byte(*uri))
buf := bytes.NewBuffer(sub[utils.ChunkTitleId])
buf.Write(sub[utils.ChunkEpisodeId])
buf.Write(sub[utils.ChunkQualityLevel])
_, server, e := m.bareBalancer.BalanceByChunk(buf.String(), string(sub[utils.ChunkName]))
if errors.Is(e, balancer.ErrServerUnavailable) {
gLog.Debug().Err(e).Msg("balancer soft error; fallback to random balancing")
return ctx.Next()
} else if e != nil {
gLog.Warn().Err(e).Msg("balancer critical error; fallback to random balancing")
return ctx.Next()
}
srv := strings.ReplaceAll(server.Name, "-node", "") + "." + gCli.String("consul-entries-domain")
ctx.Set("X-Location", srv)
return ctx.SendStatus(fiber.StatusNoContent)
}
func (m *App) fbHndBlcNodesBalanceFallback(ctx *fiber.Ctx) error {
ctx.Type(fiber.MIMETextPlainCharsetUTF8)
server, e := m.getServerFromRandomBalancer(ctx)
if e != nil {
return e
}
srv := strings.ReplaceAll(server.Name, "-node", "") + "." + gCli.String("consul-entries-domain")
ctx.Set("X-Location", srv)
return ctx.SendStatus(fiber.StatusNoContent)
}
func (m *App) getServerFromRandomBalancer(ctx *fiber.Ctx) (server *balancer.BalancerServer, e error) {
reqid := ctx.Locals("requestid").(string)
for fails := 0; fails <= gCli.Int("balancer-server-max-fails"); fails++ {
if fails == gCli.Int("balancer-server-max-fails") {
gLog.Error().Str("req", reqid).Msg("internal balancer error; too many balance errors")
e = fiber.NewError(fiber.StatusInternalServerError, "internal balancer error")
return
}
_, server, e = m.bareBalancer.BalanceRandom()
if errors.Is(e, balancer.ErrServerUnavailable) {
gLog.Trace().Err(e).Int("fails", fails).Str("req", reqid).Msg("trying to roll new server...")
continue
} else if errors.Is(e, balancer.ErrUpstreamUnavailable) {
gLog.Trace().Err(e).Int("fails", fails).Str("req", reqid).Msg("trying to force balancer")
continue
} else if e != nil {
gLog.Error().Err(e).Str("req", reqid).Msg("could not balance the request")
e = fiber.NewError(fiber.StatusInternalServerError, e.Error())
return
}
return
}
return
}