Продолжение обсуждения: Подключение к API через IPv6 против IPv4 — поддержка — Discourse Meta
Недавно я обновил Node.js с версии 18 до 20, и мое приложение внезапно перестало получать ответы от API Discourse. Мне потребовалось некоторое время, чтобы понять, что проблема связана с вышеупомянутой темой. Я подтвердил это, установив соединение только через IPv4, например:
import {Agent} from 'node:https'
import axios from 'axios'
import {env} from 'node:process'
export const axiosDiscourse = axios.create({
baseURL: 'https://<discourse-url>',
headers: {
'api-key': env['DISCOURSE_KEY'],
'api-username': env['DISCOURSE_USERNAME']
},
httpsAgent: new Agent({
family: 4
})
})
Ключевой момент здесь — указание HTTP-агента; ранее я использовал его без этого параметра. Теперь всё работает, но я пытался отказаться от Axios, чтобы использовать другие библиотеки на основе fetch, такие как Wretch (в первую очередь для уменьшения размера пакета, так как планирую использовать его также на стороне клиента): elbywan/wretch: Обёртка над fetch с интуитивно понятным синтаксисом.
(github.com). Однако в fetch нет возможности явно указать использование IPv4 или IPv6. Поэтому я решил, что мне нужно либо:
- Принудительно использовать только IPv4, но, несмотря на все мои попытки, это пока не удалось.
- Связаться с поддержкой Discourse, чтобы узнать, как настроить работу через IPv6.
Мое приложение подключается к различным другим API, и ни у одного из них нет такой проблемы — отказывается работать только соединение с Discourse.
Вот ошибка, которую я получаю (надеюсь, это поможет):
Error: connect ETIMEDOUT 184.105.99.43:443
at createConnectionError (node:net:1634:14)
at Timeout.internalConnectMultipleTimeout (node:net:1685:38)
at listOnTimeout (node:internal/timers:575:11)
at processTimers (node:internal/timers:514:7) {
errno: -110,
code: 'ETIMEDOUT',
syscall: 'connect',
address: '184.105.99.43',
port: 443
},
Error: connect ENETUNREACH 2602:fd3f:3:ff01::2b:443 - Local (:::0)
at internalConnectMultiple (node:net:1176:40)
at Timeout.internalConnectMultipleTimeout (node:net:1687:3)
at listOnTimeout (node:internal/timers:575:11)
at processTimers (node:internal/timers:514:7) {
errno: -101,
code: 'ENETUNREACH',
syscall: 'connect',
address: '2602:fd3f:3:ff01::2b',
port: 443
}
Что интересно, в отличие от упомянутой выше темы, я не получаю ответ даже после долгого ожидания. Мой запрос сразу же завершается с этой ошибкой. Вызов API работает корректно в браузере, через curl и любые другие инструменты, которые я могу протестировать.
Способ отправки запроса к API не имеет значения, пока запрос выполняется из моего приложения. Он просто не работает и функционирует только при использовании опции family, как указано выше. В связанной теме я вижу следующее упоминание:
Вам нужно разобраться, почему соединения через IPv6 не работают в вашей сети.
У меня есть два возражения по этому поводу:
- Я не знаю, как именно это проверить.
- Не понимаю, почему это проблема возникает только с Discourse и только в моём приложении.
