The following code used to work in NodeJS 16 (16.20.0 tested), but when trying to use it with NodeJS 18 (or the latest NodeJS 20) there's the following error:
Error:
[http] [Network error]: TypeError: terminated
[http] Error: incorrect header check
[http] at Zlib.zlibOnError [as onerror] (node:zlib:189:17) {
[http] errno: -3,
[http] code: 'Z_DATA_ERROR'
[http] }
This is the file that defines the authentication procedures and the only place I have any control regarding headers.
apollo.ts
let apolloClient: ApolloClient<NormalizedCacheObject> | undefined;
const errorLink = onError(({ graphQLErrors, networkError, response }) => {...);
const authLink = setContext((_, { headers }) => {
const AUTHENTICATION = toBase64(CREDENTIALS);
return {
headers: {
...headers,
authorization: `Basic ${AUTHENTICATION}`
},
};
});
function createApolloClient(headers: IncomingHttpHeaders | null = null) {
// isomorphic fetch for passing the cookies along with each GraphQL request
const enhancedFetch = (url: RequestInfo, init: RequestInit) => {
if (headers) {
init.headers = {
...init.headers,
cookie: headers.cookie ?? '',
};
}
return fetch(url, init);
};
return new ApolloClient({
ssrMode: typeof window === 'undefined',
defaultOptions: {
query: {
errorPolicy: 'all',
},
},
link: from([
errorLink,
authLink,
createUploadLink({
uri: `https://${process.env.NEXT_PUBLIC_API_ENDPOINT}/graphql`,
credentials: 'include',
fetch: enhancedFetch,
// Make sure that CORS and cookies work
// fetch: typeof window !== 'undefined' ? enhancedFetch : undefined,
}),
]),
cache: new InMemoryCache({...}),
connectToDevTools: true,
});
}
type InitialState = NormalizedCacheObject | undefined;
interface IInitializeApollo {
headers?: IncomingHttpHeaders | null;
initialState?: InitialState | null;
}
export function initializeApollo(
{ headers, initialState }: IInitializeApollo = {
headers: null,
initialState: null,
}
): ApolloClient<NormalizedCacheObject> {
const _apolloClient = apolloClient ?? createApolloClient(headers);
// If your page has Next.js data fetching methods that use Apollo Client, the initial state
// get hydrated here
if (initialState) {
// Get existing cache, loaded during client side data fetching
const existingCache = _apolloClient.extract();
// Merge the existing cache into data passed from getStaticProps/getServerSideProps
const data = merge(initialState, existingCache, {
// combine arrays using object equality (like in sets)
arrayMerge: (destinationArray, sourceArray) => [
...sourceArray,
...destinationArray.filter((d) => sourceArray.every((s) => !isEqual(d, s))),
],
});
// Restore the cache with the merged data
_apolloClient.cache.restore(data);
}
// For SSG and SSR always create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient;
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient;
return _apolloClient;
}
export function useApollo(initialState = {}): ApolloClient<NormalizedCacheObject> {
const store = useMemo(() => initializeApollo({ headers: null, initialState }), [initialState]);
return store;
}
I have a login page, that is able to fetch a cookie from the API endpoint, but then a subsequent request within getServerSideProps
(more precisely, apolloClient.query
) triggers the error.
Additional information
Operating System:
Platform: darwin
Arch: x64
Version: Darwin Kernel Version 22.5.0: Mon Apr 24 20:51:50 PDT 2023; root:xnu-8796.121.2~5/RELEASE_X86_64
Binaries:
Node: 18.16.0
npm: 9.5.1
Yarn: N/A
pnpm: N/A
Relevant packages:
next: 13.4.5
eslint-config-next: 13.4.5
react: 18.2.0
react-dom: 18.2.0
typescript: 5.1.3
Example
No response