-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhelpers.go
106 lines (86 loc) · 2.79 KB
/
helpers.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
package jrpc2server
import (
"errors"
"github.com/pquerna/ffjson/ffjson"
"github.com/riftbit/jrpc2errors"
"github.com/valyala/fasthttp"
)
// ReadRequestParams getting request parametrs
func ReadRequestParams(request *ServerRequest, args interface{}) error {
if request.Params != nil {
// Note: if c.request.Params is nil it's not an error, it's an optional member.
// JSON params structured object. Unmarshal to the args object.
if err := ffjson.Unmarshal(*request.Params, args); err != nil {
// Clearly JSON params is not a structured object,
// fallback and attempt an unmarshal with JSON params as
// array value and RPC params is struct. Unmarshal into
// array containing the request struct.
params := [1]interface{}{args}
if err = ffjson.Unmarshal(*request.Params, ¶ms); err != nil {
return err
}
}
}
return nil
}
// WriteResponse write response to client with status code and server response struct
func WriteResponse(ctx *fasthttp.RequestCtx, status int, resp *ServerResponse) {
body, _ := ffjson.Marshal(resp)
ctx.SetBody(body)
ffjson.Pool(body)
ctx.Response.Header.Set("x-content-type-options", "nosniff")
ctx.SetContentType("application/json; charset=utf-8")
ctx.SetStatusCode(status)
}
// PrepareDataHandler process basic data to context values PrepareDataHandlerRequestErr.(error) and PrepareDataHandlerRequest.(*ServerRequest) and PrepareDataHandlerRequestRun.(int)
func PrepareDataHandler(ctx *fasthttp.RequestCtx) {
var err error
ctx.SetUserValue("PrepareDataHandlerRequestErr", err)
ctx.SetUserValue("PrepareDataHandlerRequestRun", 1)
if string(ctx.Method()) != "POST" {
err = &jrpc2errors.Error{
Code: jrpc2errors.ParseError,
Message: errors.New("api: POST method required, received " + string(ctx.Method())).Error(),
}
resp := &ServerResponse{
Version: Version,
Error: err.(*jrpc2errors.Error),
}
ctx.SetUserValue("PrepareDataHandlerRequestErr", err)
WriteResponse(ctx, 405, resp)
return
}
req := new(ServerRequest)
err = ffjson.Unmarshal(ctx.Request.Body(), req)
if err != nil {
err = &jrpc2errors.Error{
Code: jrpc2errors.ParseError,
Message: err.Error(),
Data: req,
}
resp := &ServerResponse{
Version: Version,
ID: req.ID,
Error: err.(*jrpc2errors.Error),
}
ctx.SetUserValue("PrepareDataHandlerRequestErr", err)
WriteResponse(ctx, 400, resp)
return
}
ctx.SetUserValue("PrepareDataHandlerRequest", req)
if req.Version != Version {
err = &jrpc2errors.Error{
Code: jrpc2errors.InvalidRequestError,
Message: "jsonrpc must be " + Version,
Data: req,
}
resp := &ServerResponse{
Version: Version,
ID: req.ID,
Error: err.(*jrpc2errors.Error),
}
ctx.SetUserValue("PrepareDataHandlerRequestErr", err)
WriteResponse(ctx, 400, resp)
return
}
}