Files
B2BCall-dialer/docs/XML_CURL.md
Matheus d2ea83c06a feat: activate mod_xml_curl with b2bcall-fs-config (agente.md secao 26)
- apps/freeswitch-config (b2bcall-fs-config): Fastify service implementing
  the mod_xml_curl HTTP protocol (form-encoded POST -> XML response),
  containerized, no host port published
- reactivated mod_xml_curl in FreeSWITCH, binding restricted to
  directory|dialplan only (configuration was removed after testing showed
  it firing several unnecessary HTTP round-trips at boot for module
  configs we don't need dynamic — matches agente.md's own 'don't put every
  critical config through XML Curl' guidance)
- no extensions/dialplan tables exist yet (next phases), so the service
  always answers 'not found' for now — this phase only proves the wire
  protocol works without breaking the static vanilla config fallback
- verified end-to-end: user/8888 (nowhere) -> SUBSCRIBER_ABSENT via
  fs-config; user/1000 (static vanilla extension) -> USER_NOT_REGISTERED,
  proving FreeSWITCH correctly falls through to static XML when xml_curl
  says not found
- docs/XML_CURL.md, including the not-yet-authenticated endpoint note (fine
  while it only returns not-found; needs gateway-credentials before serving
  real directory/dialplan data)
2026-08-28 07:07:05 -03:00

2.4 KiB

XML Curl

b2bcall-fs-config (apps/freeswitch-config) responde às consultas HTTP que mod_xml_curl faz ao FreeSWITCH pra Directory e Dialplan (agente.md secao 26).

Fluxo

FreeSWITCH → mod_xml_curl → http://fs-config:8080/ → (nesta fase: sempre "not found")

O binding cobre só directory|dialplan (não configuration) — inicialmente incluí configuration também, mas isso disparava várias chamadas HTTP desnecessárias no boot do FreeSWITCH pra configs de módulo que não precisamos controlar dinamicamente (contraria a seção 26: "Não colocar todas as configurações críticas via XML Curl").

Por que "not found" pra tudo, por enquanto

Não existe tabela extensions nem dialplans ainda — essas são as próximas fases (Extensions, Trunks, Dialplan). O objetivo desta fase era só provar o encanamento: FreeSWITCH consegue mesmo chamar nosso serviço e interpretar a resposta corretamente, sem quebrar a config estática vanilla que continua valendo como fallback.

Isso foi verificado assim:

# Usuario inexistente em qualquer lugar -> vai ate o fs-config, recebe "not
# found", FreeSWITCH reporta erro correto:
fs_cli -x "originate user/8888 &park()"    # -ERR SUBSCRIBER_ABSENT

# Usuario 1000 (extensao estatica da config vanilla) -> mod_xml_curl retorna
# "not found", FreeSWITCH cai pro XML estatico e ACHA o usuario (so nao tem
# telefone registrado, que e' o esperado sem SIP real ainda):
fs_cli -x "originate user/1000 &park()"    # -ERR USER_NOT_REGISTERED (nao SUBSCRIBER_ABSENT)

A diferença entre as duas mensagens de erro é a prova de que o fallback pra config estática funciona corretamente.

Segurança

Sem autenticação no endpoint HTTP por enquanto — a única proteção é isolamento de rede (porta não publicada no host, só o FreeSWITCH na mesma rede do Docker Compose alcança). Isso é aceitável enquanto o serviço só responde "not found" (não há nada de valor pra proteger ainda). mod_xml_curl suporta gateway-credentials (HTTP Basic) nativamente — adicionar isso antes deste serviço passar a devolver directory/dialplan reais (fase Extensions/Trunks/Dialplan), já que a partir daí ele vira fonte de verdade para autenticação SIP.

Próxima fase (Extensions)

Quando a tabela extensions existir, o handler section === "directory" passa a consultar o Postgres e devolver o XML real de usuário (senha SIP, context, etc.) em vez de "not found" fixo.