@@ -71,32 +71,34 @@ func parseRequests(r *http.Request) (string, []string, []ModifiedRequest, error)
7171 if err != nil {
7272 return "" , nil , nil , fmt .Errorf ("failed to read body: %v" , err )
7373 }
74- type rpcRequest struct {
75- ID json.RawMessage `json:"id"`
76- Method string `json:"method"`
77- Params []json.RawMessage `json:"params"`
74+ methods , res , err = parseMessage (body , ip )
75+ if err != nil {
76+ return "" , nil , nil , err
7877 }
79- if isBatch (body ) {
80- var arr []rpcRequest
81- err = json .Unmarshal (body , & arr )
82- if err != nil {
83- return "" , nil , nil , fmt .Errorf ("failed to parse JSON batch request: %v" , err )
84- }
85- for _ , t := range arr {
86- methods = append (methods , t .Method )
87- res = append (res , ModifiedRequest {
88- ID : t .ID ,
89- Path : t .Method ,
90- RemoteAddr : ip ,
91- Params : t .Params ,
92- })
93- }
94- } else {
95- var t rpcRequest
96- err = json .Unmarshal (body , & t )
97- if err != nil {
98- return "" , nil , nil , fmt .Errorf ("failed to parse JSON request: %v" , err )
99- }
78+ }
79+ if len (res ) == 0 {
80+ methods = append (methods , r .URL .Path )
81+ res = append (res , ModifiedRequest {
82+ Path : r .URL .Path ,
83+ RemoteAddr : ip ,
84+ })
85+ }
86+ return ip , methods , res , nil
87+ }
88+
89+ func parseMessage (body []byte , ip string ) (methods []string , res []ModifiedRequest , err error ) {
90+ type rpcRequest struct {
91+ ID json.RawMessage `json:"id"`
92+ Method string `json:"method"`
93+ Params []json.RawMessage `json:"params"`
94+ }
95+ if isBatch (body ) {
96+ var arr []rpcRequest
97+ err := json .Unmarshal (body , & arr )
98+ if err != nil {
99+ return nil , nil , fmt .Errorf ("failed to parse JSON batch request: %v" , err )
100+ }
101+ for _ , t := range arr {
100102 methods = append (methods , t .Method )
101103 res = append (res , ModifiedRequest {
102104 ID : t .ID ,
@@ -105,15 +107,21 @@ func parseRequests(r *http.Request) (string, []string, []ModifiedRequest, error)
105107 Params : t .Params ,
106108 })
107109 }
108- }
109- if len (res ) == 0 {
110- methods = append (methods , r .URL .Path )
110+ } else {
111+ var t rpcRequest
112+ err := json .Unmarshal (body , & t )
113+ if err != nil {
114+ return nil , nil , fmt .Errorf ("failed to parse JSON request: %v" , err )
115+ }
116+ methods = append (methods , t .Method )
111117 res = append (res , ModifiedRequest {
112- Path : r .URL .Path ,
118+ ID : t .ID ,
119+ Path : t .Method ,
113120 RemoteAddr : ip ,
121+ Params : t .Params ,
114122 })
115123 }
116- return ip , methods , res , nil
124+ return methods , res , nil
117125}
118126
119127const (
@@ -123,16 +131,18 @@ const (
123131 jsonRPCInternal = - 32603
124132)
125133
134+ type ErrResponse struct {
135+ Version string `json:"jsonrpc"`
136+ ID json.RawMessage `json:"id"`
137+ Error struct {
138+ Code int `json:"code"`
139+ Message string `json:"message"`
140+ } `json:"error"`
141+ }
142+
126143func jsonRPCError (id json.RawMessage , jsonCode int , msg string ) interface {} {
127- type errResponse struct {
128- Version string `json:"jsonrpc"`
129- ID json.RawMessage `json:"id"`
130- Error struct {
131- Code int `json:"code"`
132- Message string `json:"message"`
133- } `json:"error"`
134- }
135- resp := errResponse {
144+
145+ resp := ErrResponse {
136146 Version : "2.0" ,
137147 ID : id ,
138148 }
@@ -187,8 +197,13 @@ func (t *myTransport) RoundTrip(req *http.Request) (*http.Response, error) {
187197
188198 ctx = gotils .With (ctx , "remoteIp" , ip )
189199 ctx = gotils .With (ctx , "methods" , methods )
190- if blockResponse := t .block (ctx , parsedRequests ); blockResponse != nil {
191- return blockResponse , nil
200+ errorCode , resp := t .block (ctx , parsedRequests )
201+ if resp != nil {
202+ resp , err := jsonRPCResponse (errorCode , resp )
203+ if err != nil {
204+ gotils .L (ctx ).Error ().Printf ("Failed to construct a response: %v" , err )
205+ }
206+ return resp , nil
192207 }
193208
194209 gotils .L (ctx ).Info ().Print ("Forwarding request" )
@@ -197,71 +212,47 @@ func (t *myTransport) RoundTrip(req *http.Request) (*http.Response, error) {
197212}
198213
199214// block returns a response only if the request should be blocked, otherwise it returns nil if allowed.
200- func (t * myTransport ) block (ctx context.Context , parsedRequests []ModifiedRequest ) * http. Response {
215+ func (t * myTransport ) block (ctx context.Context , parsedRequests []ModifiedRequest ) ( int , interface {}) {
201216 var union * blockRange
202217 for _ , parsedRequest := range parsedRequests {
203218 ctx = gotils .With (ctx , "ip" , parsedRequest .RemoteAddr )
204219 if allowed , added := t .AllowVisitor (parsedRequest ); ! allowed {
205220 gotils .L (ctx ).Info ().Print ("Request blocked: Rate limited" )
206- resp , err := jsonRPCResponse (http .StatusTooManyRequests , jsonRPCLimit (parsedRequest .ID ))
207- if err != nil {
208- gotils .L (ctx ).Error ().Printf ("Failed to construct rate-limit response: %v" , err )
209- }
210- return resp
221+ return http .StatusTooManyRequests , jsonRPCLimit (parsedRequest .ID )
211222 } else if added {
212223 gotils .L (ctx ).Info ().Printf ("Added new visitor, ip: %v" , parsedRequest .RemoteAddr )
213224 }
214225
215226 if ! t .MatchAnyRule (parsedRequest .Path ) {
216227 gotils .L (ctx ).Info ().Print ("Request blocked: Method not allowed" )
217- resp , err := jsonRPCResponse (http .StatusMethodNotAllowed , jsonRPCUnauthorized (parsedRequest .ID , parsedRequest .Path ))
218- if err != nil {
219- gotils .L (ctx ).Error ().Printf ("Failed to construct not-allowed response: %v" , err )
220- }
221- return resp
228+ return http .StatusMethodNotAllowed , jsonRPCUnauthorized (parsedRequest .ID , parsedRequest .Path )
222229 }
223230 if t .blockRangeLimit > 0 && parsedRequest .Path == "eth_getLogs" {
224231 r , invalid , err := t .parseRange (ctx , parsedRequest )
225232 if err != nil {
226- resp , err := jsonRPCResponse (http .StatusInternalServerError , jsonRPCError (parsedRequest .ID , jsonRPCInternal , err .Error ()))
227- if err != nil {
228- gotils .L (ctx ).Error ().Printf ("Failed to construct internal error response: %v" , err )
229- }
230- return resp
233+ return http .StatusInternalServerError , jsonRPCError (parsedRequest .ID , jsonRPCInternal , err .Error ())
231234 } else if invalid != nil {
232235 gotils .L (ctx ).Info ().Printf ("Request blocked: Invalid params: %v" , invalid )
233- resp , err := jsonRPCResponse (http .StatusBadRequest , jsonRPCError (parsedRequest .ID , jsonRPCInvalidParams , invalid .Error ()))
234- if err != nil {
235- gotils .L (ctx ).Error ().Printf ("Failed to construct invalid params response: %v" , err )
236- }
237- return resp
236+ return http .StatusBadRequest , jsonRPCError (parsedRequest .ID , jsonRPCInvalidParams , invalid .Error ())
238237 }
239238 if r != nil {
240239 if l := r .len (); l > t .blockRangeLimit {
241240 gotils .L (ctx ).Info ().Println ("Request blocked: Exceeds block range limit, range:" , l , "limit:" , t .blockRangeLimit )
242- resp , err := jsonRPCResponse (http .StatusBadRequest , jsonRPCBlockRangeLimit (parsedRequest .ID , l , t .blockRangeLimit ))
243- if err != nil {
244- gotils .L (ctx ).Error ().Printf ("Failed to construct block range limit response: %v" , err )
245- }
246- return resp
241+ return http .StatusBadRequest , jsonRPCBlockRangeLimit (parsedRequest .ID , l , t .blockRangeLimit )
247242 }
248243 if union == nil {
249244 union = r
250245 } else {
251246 union .extend (r )
252247 if l := union .len (); l > t .blockRangeLimit {
253248 gotils .L (ctx ).Info ().Println ("Request blocked: Exceeds block range limit, range:" , l , "limit:" , t .blockRangeLimit )
254- resp , err := jsonRPCResponse (http .StatusBadRequest , jsonRPCBlockRangeLimit (parsedRequest .ID , l , t .blockRangeLimit ))
255- if err != nil {
256- gotils .L (ctx ).Error ().Printf ("Failed to construct block range limit response: %v" , err )
257- }
258- return resp
249+ return http .StatusBadRequest , jsonRPCBlockRangeLimit (parsedRequest .ID , l , t .blockRangeLimit )
259250 }
260251 }
261252 }
262253 }
263254 }
264- return nil
255+ return 0 , nil
265256}
266257
267258type blockRange struct { start , end uint64 }
0 commit comments