1- import { type AxiosInstance } from "axios" ;
1+ import {
2+ type AxiosResponseHeaders ,
3+ type AxiosInstance ,
4+ type AxiosHeaders ,
5+ type AxiosResponseTransformer ,
6+ } from "axios" ;
27import { Api } from "coder/site/src/api/api" ;
38import {
49type GetInboxNotificationResponse ,
@@ -23,6 +28,7 @@ import {
2328type RequestConfigWithMeta ,
2429HttpClientLogLevel ,
2530} from "../logging/types" ;
31+ import { sizeOf } from "../logging/utils" ;
2632import { WsLogger } from "../logging/wsLogger" ;
2733import {
2834OneWayWebSocket ,
@@ -207,7 +213,24 @@ function addLoggingInterceptors(client: AxiosInstance, logger: Logger) {
207213( config ) => {
208214const configWithMeta = config as RequestConfigWithMeta ;
209215configWithMeta . metadata = createRequestMeta ( ) ;
210- logRequest ( logger , configWithMeta , getLogLevel ( ) ) ;
216+
217+ config . transformRequest = [
218+ ...wrapRequestTransform (
219+ config . transformRequest || client . defaults . transformRequest || [ ] ,
220+ configWithMeta ,
221+ ) ,
222+ ( data ) => {
223+ // Log after setting the raw request size
224+ logRequest ( logger , configWithMeta , getLogLevel ( ) ) ;
225+ return data ;
226+ } ,
227+ ] ;
228+
229+ config . transformResponse = wrapResponseTransform (
230+ config . transformResponse || client . defaults . transformResponse || [ ] ,
231+ configWithMeta ,
232+ ) ;
233+
211234return config ;
212235} ,
213236( error :unknown ) => {
@@ -228,6 +251,59 @@ function addLoggingInterceptors(client: AxiosInstance, logger: Logger) {
228251) ;
229252}
230253
254+ function wrapRequestTransform (
255+ transformer :AxiosResponseTransformer | AxiosResponseTransformer [ ] ,
256+ config :RequestConfigWithMeta ,
257+ ) :AxiosResponseTransformer [ ] {
258+ return [
259+ ( data :unknown , headers :AxiosHeaders ) => {
260+ const transformerArray = Array . isArray ( transformer )
261+ ?transformer
262+ :[ transformer ] ;
263+
264+ // Transform the request first then get the size (measure what's sent over the wire)
265+ const result = transformerArray . reduce (
266+ ( d , fn ) => fn . call ( config , d , headers ) ,
267+ data ,
268+ ) ;
269+
270+ config . rawRequestSize = getSize ( config . headers , result ) ;
271+
272+ return result ;
273+ } ,
274+ ] ;
275+ }
276+
277+ function wrapResponseTransform (
278+ transformer :AxiosResponseTransformer | AxiosResponseTransformer [ ] ,
279+ config :RequestConfigWithMeta ,
280+ ) :AxiosResponseTransformer [ ] {
281+ return [
282+ ( data :unknown , headers :AxiosResponseHeaders , status ?:number ) => {
283+ // Get the size before transforming the response (measure what's sent over the wire)
284+ config . rawResponseSize = getSize ( headers , data ) ;
285+
286+ const transformerArray = Array . isArray ( transformer )
287+ ?transformer
288+ :[ transformer ] ;
289+
290+ return transformerArray . reduce (
291+ ( d , fn ) => fn . call ( config , d , headers , status ) ,
292+ data ,
293+ ) ;
294+ } ,
295+ ] ;
296+ }
297+
298+ function getSize ( headers :AxiosHeaders , data :unknown ) :number | undefined {
299+ const contentLength = headers [ "content-length" ] ;
300+ if ( contentLength !== undefined ) {
301+ return parseInt ( contentLength , 10 ) ;
302+ }
303+
304+ return sizeOf ( data ) ;
305+ }
306+
231307function getLogLevel ( ) :HttpClientLogLevel {
232308const logLevelStr = vscode . workspace
233309. getConfiguration ( )