@@ -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 {
@@ -66,6 +66,13 @@ func SendHTTPRequest(ctx context.Context, provider *Provider, body []byte) ([]by
6666 }
6767
6868 req .Header = make (http.Header )
69+
70+ if provider .Headers != nil {
71+ for k , v := range provider .Headers {
72+ req .Header .Set (k , v )
73+ }
74+ }
75+
6976 req .Header .Set ("User-Agent" , UserAgent )
7077 req .Header .Set ("Content-Type" , "application/json; charset=utf-8" )
7178
@@ -93,15 +100,15 @@ func SendHTTPRequest(ctx context.Context, provider *Provider, body []byte) ([]by
93100 return b , nil
94101}
95102
96- func SendHTTPRPCRequest (ctx context.Context , p * Provider , rpcreq * rpc.Request ) (* rpc.Response , error ) {
97- req := rpc .SerializeRequest ( rpcreq )
103+ func SendHTTPRPCRequest (ctx context.Context , p * Provider , req * rpc.BatchRequest ) (* rpc.BatchResponse , error ) {
104+ body := rpc .SerializeBatchRequest ( req )
98105
99- b , err := SendHTTPRequest (ctx , p , req )
106+ b , err := SendHTTPRequest (ctx , p , body )
100107 if err != nil {
101108 return nil , err
102109 }
103110
104- response , err := rpc .DecodeResponse (b )
111+ response , err := rpc .DecodeBatchResponse (b )
105112 if err != nil {
106113 return nil , fmt .Errorf ("bad response: %w, raw: %s" , err , string (b ))
107114 }
@@ -127,19 +134,26 @@ func IncomingHttpHandler(ctx context.Context, endpoint *Endpoint, w http.Respons
127134 return
128135 }
129136
130- rpcReq , err := rpc .DecodeRequest (body )
137+ req , err := rpc .DecodeBatchRequest (body )
131138 if err != nil {
132- log .Error ("http: bad request" , "error" , err , "msg " , rpc .FormatRawBody (string (body )))
139+ log .Error ("http: bad request" , "error" , err , "body " , rpc .FormatRawBody (string (body )))
133140 http .Error (w , "bad request" , http .StatusBadRequest )
134141 return
135142 }
136143
137- log = log .With ("rpc_id" , rpc .GetRequestIDString (rpcReq .ID ), "method" , rpcReq .Method )
144+ if req .IsBatch {
145+ rpc .BatchIDCounter ++
146+ log = log .With ("batch_id" , rpc .BatchIDCounter , "batch_size" , len (req .Requests ))
147+ } else {
148+ log = log .With ("rpc_id" , req .Requests [0 ].GetID (), "method" , req .Requests [0 ].Method )
149+ }
138150
139- res , provider , err := ProxyHTTP (ctx , endpoint , rpcReq , timing )
151+ res , provider , err := ProxyHTTP (ctx , endpoint , req , timing )
140152
141153 if err != nil {
142- metrics .RecordRequest (endpoint .Name , provider .Name , "http" , rpcReq .Method , time .Since (start ).Seconds (), true )
154+ for _ , req := range req .Requests {
155+ metrics .RecordFailedRequest (endpoint .Name , provider .Name , "http" , req .Method )
156+ }
143157
144158 if err == ErrNoProvidersAvailable {
145159 log .Error ("no providers available" )
@@ -154,9 +168,33 @@ func IncomingHttpHandler(ctx context.Context, endpoint *Endpoint, w http.Respons
154168
155169 log = log .With ("provider" , provider .Name , "request_time" , time .Since (start ))
156170
157- log .Debug ("request" )
171+ for i , res := range req .Requests {
172+ if req .IsBatch {
173+ log .Debug ("request" , "batch_index" , i , "rpc_id" , res .GetID (), "method" , res .Method )
174+ } else {
175+ // id and method is already set for this single request
176+ log .Debug ("request" )
177+ }
178+ }
158179
159- metrics .RecordRequest (endpoint .Name , provider .Name , "http" , rpcReq .Method , time .Since (start ).Seconds (), res .IsError ())
180+ for i , res := range res .Responses {
181+ method := req .Requests [i ].Method
182+
183+ if res .IsError () {
184+ log .Error ("error" , "error" , res .Error )
185+ metrics .RecordFailedRequest (endpoint .Name , provider .Name , "http" , method )
186+ } else {
187+ metrics .RecordRequest (endpoint .Name , provider .Name , "http" , method , time .Since (start ).Seconds ())
188+ }
189+ }
190+
191+ if req .IsBatch {
192+ if len (res .Responses ) != len (req .Requests ) {
193+ log .Error ("batch response size mismatch" , "request_size" , len (req .Requests ), "response_size" , len (res .Responses ))
194+ http .Error (w , "batch response size mismatch" , http .StatusInternalServerError )
195+ return
196+ }
197+ }
160198
161199 if ! endpoint .Public {
162200 w .Header ().Set ("X-Provider" , provider .Name )
@@ -168,7 +206,7 @@ func IncomingHttpHandler(ctx context.Context, endpoint *Endpoint, w http.Respons
168206
169207 w .Header ().Set ("Content-Type" , "application/json; charset=utf-8" )
170208
171- _ , err = w .Write (rpc .SerializeResponse (res ))
209+ _ , err = w .Write (rpc .SerializeBatchResponse (res ))
172210 if err != nil {
173211 log .Error ("error writing body" , "error" , err )
174212 return
0 commit comments