@@ -25,7 +25,7 @@ var defaultClient = &http.Client{
2525 },
2626}
2727
28- func ProxyHTTP (ctx context.Context , endpoint * Endpoint , req * rpc.Request , timing * servertiming.Header ) (* rpc.Response , * Provider , error ) {
28+ func ProxyHTTP (ctx context.Context , endpoint * Endpoint , req * rpc.BatchRequest , timing * servertiming.Header ) (* rpc.BatchResponse , * Provider , error ) {
2929 providers := endpoint .GetActiveProviders ()
3030
3131 for _ , provider := range providers {
@@ -93,15 +93,15 @@ func SendHTTPRequest(ctx context.Context, provider *Provider, body []byte) ([]by
9393 return b , nil
9494}
9595
96- func SendHTTPRPCRequest (ctx context.Context , p * Provider , rpcreq * rpc.Request ) (* rpc.Response , error ) {
97- req := rpc .SerializeRequest ( rpcreq )
96+ func SendHTTPRPCRequest (ctx context.Context , p * Provider , req * rpc.BatchRequest ) (* rpc.BatchResponse , error ) {
97+ body := rpc .SerializeBatchRequest ( req )
9898
99- b , err := SendHTTPRequest (ctx , p , req )
99+ b , err := SendHTTPRequest (ctx , p , body )
100100 if err != nil {
101101 return nil , err
102102 }
103103
104- response , err := rpc .DecodeResponse (b )
104+ response , err := rpc .DecodeBatchResponse (b )
105105 if err != nil {
106106 return nil , fmt .Errorf ("bad response: %w, raw: %s" , err , string (b ))
107107 }
@@ -127,19 +127,26 @@ func IncomingHttpHandler(ctx context.Context, endpoint *Endpoint, w http.Respons
127127 return
128128 }
129129
130- rpcReq , err := rpc .DecodeRequest (body )
130+ req , err := rpc .DecodeBatchRequest (body )
131131 if err != nil {
132- log .Error ("http: bad request" , "error" , err , "msg " , rpc .FormatRawBody (string (body )))
132+ log .Error ("http: bad request" , "error" , err , "body " , rpc .FormatRawBody (string (body )))
133133 http .Error (w , "bad request" , http .StatusBadRequest )
134134 return
135135 }
136136
137- log = log .With ("rpc_id" , rpc .GetRequestIDString (rpcReq .ID ), "method" , rpcReq .Method )
137+ if req .IsBatch {
138+ rpc .BatchIDCounter ++
139+ log = log .With ("batch_id" , rpc .BatchIDCounter , "size" , len (req .Requests ))
140+ } else {
141+ log = log .With ("rpc_id" , req .Requests [0 ].GetID (), "method" , req .Requests [0 ].Method )
142+ }
138143
139- res , provider , err := ProxyHTTP (ctx , endpoint , rpcReq , timing )
144+ res , provider , err := ProxyHTTP (ctx , endpoint , req , timing )
140145
141146 if err != nil {
142- metrics .RecordRequest (endpoint .Name , provider .Name , "http" , rpcReq .Method , time .Since (start ).Seconds (), true )
147+ for _ , req := range req .Requests {
148+ metrics .RecordFailedRequest (endpoint .Name , provider .Name , "http" , req .Method )
149+ }
143150
144151 if err == ErrNoProvidersAvailable {
145152 log .Error ("no providers available" )
@@ -154,9 +161,41 @@ func IncomingHttpHandler(ctx context.Context, endpoint *Endpoint, w http.Respons
154161
155162 log = log .With ("provider" , provider .Name , "request_time" , time .Since (start ))
156163
157- log .Debug ("request" )
164+ if req .IsBatch {
165+ if len (res .Responses ) != len (req .Requests ) {
166+ log .Error ("batch response size mismatch" , "request size" , len (req .Requests ), "response size" , len (res .Responses ))
167+ http .Error (w , "batch response size mismatch" , http .StatusInternalServerError )
168+ return
169+ }
170+
171+ // batch_id and size is already set
172+ log .Debug ("batch request" )
173+ }
158174
159- metrics .RecordRequest (endpoint .Name , provider .Name , "http" , rpcReq .Method , time .Since (start ).Seconds (), res .IsError ())
175+ for _ , res := range req .Requests {
176+ if req .IsBatch {
177+ log .Debug ("request" , "rpc_id" , res .GetID (), "method" , res .Method )
178+ } else {
179+ // id and method is already set for this single request
180+ log .Debug ("request" )
181+ }
182+ }
183+
184+ for i , res := range res .Responses {
185+ method := req .Requests [i ].Method
186+
187+ if res .IsError () {
188+ metrics .RecordFailedRequest (endpoint .Name , provider .Name , "http" , method )
189+ } else {
190+ metrics .RecordRequest (endpoint .Name , provider .Name , "http" , method , time .Since (start ).Seconds ())
191+ }
192+ }
193+
194+ if endpoint .Headers != nil {
195+ for k , v := range endpoint .Headers {
196+ w .Header ().Set (k , v )
197+ }
198+ }
160199
161200 if ! endpoint .Public {
162201 w .Header ().Set ("X-Provider" , provider .Name )
@@ -168,7 +207,7 @@ func IncomingHttpHandler(ctx context.Context, endpoint *Endpoint, w http.Respons
168207
169208 w .Header ().Set ("Content-Type" , "application/json; charset=utf-8" )
170209
171- _ , err = w .Write (rpc .SerializeResponse (res ))
210+ _ , err = w .Write (rpc .SerializeBatchResponse (res ))
172211 if err != nil {
173212 log .Error ("error writing body" , "error" , err )
174213 return
0 commit comments