1
- import { type AxiosInstance } from "axios" ;
1
+ import {
2
+ type AxiosResponseHeaders ,
3
+ type AxiosInstance ,
4
+ type AxiosHeaders ,
5
+ type AxiosResponseTransformer ,
6
+ } from "axios" ;
2
7
import { Api } from "coder/site/src/api/api" ;
3
8
import {
4
9
type GetInboxNotificationResponse ,
@@ -23,6 +28,7 @@ import {
23
28
type RequestConfigWithMeta ,
24
29
HttpClientLogLevel ,
25
30
} from "../logging/types" ;
31
+ import { serializeValue , sizeOf } from "../logging/utils" ;
26
32
import { WsLogger } from "../logging/wsLogger" ;
27
33
import {
28
34
OneWayWebSocket ,
@@ -207,7 +213,24 @@ function addLoggingInterceptors(client: AxiosInstance, logger: Logger) {
207
213
( config ) => {
208
214
const configWithMeta = config as RequestConfigWithMeta ;
209
215
configWithMeta . 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
+
211
234
return config ;
212
235
} ,
213
236
( error : unknown ) => {
@@ -228,6 +251,66 @@ function addLoggingInterceptors(client: AxiosInstance, logger: Logger) {
228
251
) ;
229
252
}
230
253
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 estimate the size
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
+ // estimate the size before transforming the response
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
+ const size = sizeOf ( data ) ;
305
+ if ( size !== undefined ) {
306
+ return size ;
307
+ }
308
+
309
+ // Fallback
310
+ const stringified = serializeValue ( data ) ;
311
+ return stringified === null ? undefined : Buffer . byteLength ( stringified ) ;
312
+ }
313
+
231
314
function getLogLevel ( ) : HttpClientLogLevel {
232
315
const logLevelStr = vscode . workspace
233
316
. getConfiguration ( )
0 commit comments