Skip to content

Commit

Permalink
fix: ensure axios headers are instance of AxiosHeaders via interceptor (
Browse files Browse the repository at this point in the history
  • Loading branch information
B4nan committed Feb 20, 2024
1 parent e81eaf8 commit 1f4633f
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
11 changes: 9 additions & 2 deletions src/http_client.ts
Expand Up @@ -4,7 +4,14 @@ import { APIFY_ENV_VARS } from '@apify/consts';
import { Log } from '@apify/log';
import KeepAliveAgent from 'agentkeepalive';
import retry, { RetryFunction } from 'async-retry';
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, InternalAxiosRequestConfig, AxiosResponse } from 'axios';
import axios, {
AxiosError,
AxiosInstance,
AxiosRequestConfig,
InternalAxiosRequestConfig,
AxiosResponse,
AxiosHeaders,
} from 'axios';

import { ApifyApiError } from './apify_api_error';
import {
Expand Down Expand Up @@ -99,7 +106,7 @@ export class HttpClient {
});

// Clean all default headers because they only make a mess and their merging is difficult to understand and buggy.
this.axios.defaults.headers = {} as any;
this.axios.defaults.headers = new AxiosHeaders() as any;

// If workflow key is available, pass it as a header
if (this.workflowKey) {
Expand Down
12 changes: 10 additions & 2 deletions src/interceptors.ts
@@ -1,4 +1,4 @@
import axios, { AxiosInterceptorManager, AxiosResponse, AxiosRequestTransformer } from 'axios';
import axios, { AxiosInterceptorManager, AxiosResponse, AxiosRequestTransformer, AxiosHeaders } from 'axios';
import contentTypeParser from 'content-type';
import { JsonObject } from 'type-fest';

Expand Down Expand Up @@ -62,6 +62,14 @@ function serializeRequest(config: ApifyRequestConfig): ApifyRequestConfig {
return config;
}

function ensureHeadersPrototype(config: ApifyRequestConfig): ApifyRequestConfig {
if (config.headers && !(config.headers instanceof AxiosHeaders)) {
Object.setPrototypeOf(config.headers, AxiosHeaders.prototype);
}

return config;
}

/**
* JSON.stringify() that serializes functions to string instead
* of replacing them with null or removing them.
Expand Down Expand Up @@ -114,5 +122,5 @@ function parseResponseData(response: ApifyResponse): ApifyResponse {
export type RequestInterceptorFunction = Parameters<AxiosInterceptorManager<ApifyRequestConfig>['use']>[0];
export type ResponseInterceptorFunction = Parameters<AxiosInterceptorManager<ApifyResponse>['use']>[0];

export const requestInterceptors: RequestInterceptorFunction[] = [maybeGzipRequest, serializeRequest];
export const requestInterceptors: RequestInterceptorFunction[] = [maybeGzipRequest, serializeRequest, ensureHeadersPrototype];
export const responseInterceptors: ResponseInterceptorFunction[] = [parseResponseData];
4 changes: 4 additions & 0 deletions test/http_client.test.js
Expand Up @@ -27,6 +27,10 @@ describe('HttpClient', () => {
baseUrl,
timeoutSecs: 1,
maxRetries: 0,
requestInterceptors: [(config) => {
config.headers = {};
return config;
}],
});
});
afterEach(async () => {
Expand Down

0 comments on commit 1f4633f

Please sign in to comment.