-
Notifications
You must be signed in to change notification settings - Fork 129
/
context.go
115 lines (104 loc) · 2.89 KB
/
context.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
// Copyright 2017 NDP Systèmes. All Rights Reserved.
// See LICENSE file for full licensing details.
package server
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"github.com/hexya-erp/hexya/src/tools/exceptions"
"github.com/hexya-erp/hexya/src/tools/hweb"
)
// The Context allows to pass data across controller layers
// and middlewares.
type Context struct {
*gin.Context
}
// RPC serializes the given struct as JSON-RPC into the response body.
func (c *Context) RPC(code int, obj interface{}, err ...error) {
id, ok := c.Get("id")
if !ok {
var req RequestRPC
if err2 := c.BindJSON(&req); err2 != nil {
c.AbortWithError(http.StatusBadRequest, err2)
return
}
id = req.ID
}
if len(err) > 0 && err[0] != nil {
userError, ok2 := err[0].(exceptions.UserError)
if !ok2 {
c.AbortWithError(http.StatusInternalServerError, errors.New("error is of unknown type"))
return
}
respErr := ResponseError{
JsonRPC: "2.0",
ID: id.(int64),
Error: JSONRPCError{
Code: code,
Message: "Hexya Server Error",
Data: JSONRPCErrorData{
Arguments: []string{userError.Message},
ExceptionType: "user_error",
Debug: userError.Debug,
},
},
}
c.JSON(code, respErr)
return
}
resp := ResponseRPC{
JsonRPC: "2.0",
ID: id.(int64),
Result: obj,
}
c.JSON(code, resp)
}
// BindRPCParams binds the RPC parameters to the given data object.
func (c *Context) BindRPCParams(data interface{}) {
var req RequestRPC
if err := c.BindJSON(&req); err != nil {
c.AbortWithError(http.StatusBadRequest, err)
return
}
c.Set("id", req.ID)
if err := json.Unmarshal(req.Params, data); err != nil {
c.AbortWithError(http.StatusBadRequest, err)
return
}
}
// Session returns the current Session instance
func (c *Context) Session() sessions.Session {
return sessions.Default(c.Context)
}
// Super calls the next middleware / handler layer
// It is an alias for Next
func (c *Context) Super() {
c.Next()
}
// HTTPGet makes an http GET request to this server with the context's session cookie
func (c *Context) HTTPGet(uri string) (*http.Response, error) {
scheme := "http"
if c.Request.TLS != nil {
scheme = "https"
}
sanitizedURI, _ := url.ParseRequestURI(uri)
targetUrl := fmt.Sprintf("%s://%s%s", scheme, c.Request.Host, sanitizedURI.RequestURI())
req, _ := http.NewRequest(http.MethodGet, targetUrl, nil)
sessionCookie, _ := c.Cookie("hexya-session")
req.AddCookie(&http.Cookie{
Name: "hexya-session",
Value: sessionCookie,
})
client := http.Client{}
return client.Do(req)
}
// HTML renders the HTTP template specified by its file name.
// It also updates the HTTP code and sets the Content-Type as "text/html".
// See http://golang.org/doc/articles/wiki/
func (c *Context) HTML(code int, name string, context hweb.Context) {
c.Context.HTML(code, name, context)
}