• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender-server / 1978029483

11 Aug 2025 02:15PM UTC coverage: 65.755% (+0.3%) from 65.495%
1978029483

Pull #860

gitlab-ci

kjaskiewiczz
docs(useradm): move API specification to single file

Changelog: Title
Ticket: QA-1094
Signed-off-by: Krzysztof Jaskiewicz <krzysztof.jaskiewicz@northern.tech>
Pull Request #860: docs(useradm): move API specification to single file

29261 of 44500 relevant lines covered (65.76%)

1.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.51
/backend/pkg/routing/routing.go
1
// Copyright 2024 Northern.tech AS
2
//
3
//        Licensed under the Apache License, Version 2.0 (the "License");
4
//        you may not use this file except in compliance with the License.
5
//        You may obtain a copy of the License at
6
//
7
//            http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//        Unless required by applicable law or agreed to in writing, software
10
//        distributed under the License is distributed on an "AS IS" BASIS,
11
//        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//        See the License for the specific language governing permissions and
13
//        limitations under the License.
14
package routing
15

16
import (
17
        "net/http"
18
        "os"
19
        "strings"
20

21
        "github.com/gin-gonic/gin"
22

23
        "github.com/mendersoftware/mender-server/pkg/accesslog"
24
        "github.com/mendersoftware/mender-server/pkg/requestid"
25
        "github.com/mendersoftware/mender-server/pkg/rest.utils"
26
        utils "github.com/mendersoftware/mender-server/pkg/strings"
27
)
28

29
type HttpOptionsGenerator func(methods []string) gin.HandlerFunc
30

31
func AllowHeaderOptionsGenerator(methods []string) gin.HandlerFunc {
2✔
32
        // return a dummy handler for now
2✔
33
        return func(c *gin.Context) {
2✔
34
                for _, m := range methods {
×
35
                        c.Writer.Header().Add("Allow", m)
×
36
                }
×
37
        }
38
}
39

40
func supportsMethod(method string, methods []string) bool {
2✔
41
        return utils.ContainsString(method, methods)
2✔
42
}
2✔
43

44
// Automatically add OPTIONS method support for each defined route,
45
// only if there's no OPTIONS handler for that route yet
46
func AutogenOptionsRoutes(router *gin.Engine, gen HttpOptionsGenerator) {
2✔
47

2✔
48
        routes := router.Routes()
2✔
49
        methodGroups := make(map[string][]string, len(routes))
2✔
50

2✔
51
        for _, route := range routes {
4✔
52
                if strings.HasPrefix(route.Path, "/api/internal") {
2✔
53
                        continue
×
54
                }
55
                methods, ok := methodGroups[route.Path]
2✔
56
                if !ok {
4✔
57
                        methods = make([]string, 0)
2✔
58
                }
2✔
59

60
                methodGroups[route.Path] = append(methods, route.Method)
2✔
61
        }
62

63
        for route, methods := range methodGroups {
4✔
64
                // skip if there's a handler for OPTIONS already
2✔
65
                if !supportsMethod(http.MethodOptions, methods) {
4✔
66
                        router.OPTIONS(route, gen(methods))
2✔
67
                }
2✔
68
        }
69

70
}
71

72
func handleNoRoute(c *gin.Context) {
1✔
73
        c.JSON(http.StatusNotFound, rest.Error{
1✔
74
                Err:       "not found",
1✔
75
                RequestID: requestid.FromContext(c.Request.Context()),
1✔
76
        })
1✔
77
}
1✔
78

79
func handleNoMethod(c *gin.Context) {
×
80
        c.JSON(http.StatusMethodNotAllowed, rest.Error{
×
81
                Err:       "method not allowed",
×
82
                RequestID: requestid.FromContext(c.Request.Context()),
×
83
        })
×
84
}
×
85

86
func SwitchToReleaseMode() {
9✔
87
        if mode := os.Getenv(gin.EnvGinMode); mode != "" {
9✔
88
                gin.SetMode(mode)
×
89
        } else {
9✔
90
                gin.SetMode(gin.ReleaseMode)
9✔
91
        }
9✔
92
        gin.DisableConsoleColor()
9✔
93
}
94

95
func NewGinRouter() *gin.Engine {
8✔
96
        SwitchToReleaseMode()
8✔
97

8✔
98
        router := gin.New()
8✔
99

8✔
100
        router.HandleMethodNotAllowed = true
8✔
101
        router.NoMethod(handleNoMethod)
8✔
102
        router.NoRoute(handleNoRoute)
8✔
103

8✔
104
        router.Use(accesslog.Middleware())
8✔
105
        router.Use(requestid.Middleware())
8✔
106

8✔
107
        return router
8✔
108
}
8✔
109

110
// New Gin router without any middlewares
111
func NewMinimalGinRouter() *gin.Engine {
2✔
112
        SwitchToReleaseMode()
2✔
113

2✔
114
        router := gin.New()
2✔
115

2✔
116
        router.HandleMethodNotAllowed = true
2✔
117
        router.NoMethod(handleNoMethod)
2✔
118
        router.NoRoute(handleNoRoute)
2✔
119

2✔
120
        return router
2✔
121
}
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc