Funciones implementadas, registradas en registry.db via fn index, tests locales (11 cases, 27 assertions) en verde. Cierra el gap detectado: patron curl-popen inline duplicado en services_monitor / dag_engine_ui / data_factory ahora promovido al registry. Sigue habilitando issue 0111 (apps/process_explorer http_client) cuando arranque — usara http_request_cpp_core directamente.
4.9 KiB
id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
| id | title | status | type | domain | scope | priority | depends | blocks | related | created | updated | tags | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0110 | Gap registry: helper HTTP cliente C++ (curl/popen) reutilizable | pendiente | feature |
|
registry | media |
|
|
2026-05-18 | 2026-05-18 |
|
0110 — Helper HTTP cliente C++ en el registry
Problema
Hoy no existe funcion HTTP cliente reutilizable en cpp/functions/. Cada app C++ que necesita
golpear un endpoint reinventa la capa:
| App | Fichero | Tecnica | LOC aprox |
|---|---|---|---|
apps/services_monitor/ |
http_client.cpp |
cURL popen/WinHTTP segun plataforma | ~150 |
apps/dag_engine_ui/ |
inline en main.cpp |
curl CLI via popen + parse | ~80 |
apps/data_factory/ |
inline | popen curl | ~60 |
cpp/functions/core/llm_anthropic.cpp |
propio | cURL popen — solo Anthropic | — |
apps/process_explorer/ (issue 0111) |
http_client.cpp local |
pendiente — clonara services_monitor | ~150 esperados |
El patron ya supera el umbral >2x que dispara la regla de promocion (CLAUDE.md
"Si patron se repite >2x → propose nueva funcion via fn-constructor"). Cada app duplica:
- Detection de plataforma (Linux:
popen("curl -s ..."), Win:WinHTTPOpen/popen) - Manejo de basicAuth / Bearer tokens
- Timeouts
- Captura de body + status code
- Manejo de errores transitorios (DNS, conexion rechazada)
Decision
Anadir al registry dos funciones C++ en dominio core (o infra):
http_request_cpp_core (impure)
namespace fn_http {
struct Request {
std::string method; // "GET", "POST", "PUT", "DELETE"
std::string url;
std::vector<std::pair<std::string,std::string>> headers;
std::string body; // raw bytes (JSON, etc.)
int timeout_ms = 5000;
std::string bearer_token; // shortcut: anade Authorization: Bearer <token>
std::string basic_user; // shortcut: anade Authorization: Basic base64(user:pass)
std::string basic_pass;
};
struct Response {
int status = 0; // 0 = error de transporte
std::string body;
std::vector<std::pair<std::string,std::string>> headers;
std::string error; // vacio si OK
int64_t duration_ms = 0;
};
Response request(const Request& req);
}
Implementacion: cURL via popen (portable WSL+Win+Linux, igual que llm_anthropic).
Si en el futuro queremos rendimiento real, swap a libcurl linkado estaticamente
o WinHTTP via #ifdef _WIN32 — interfaz Request/Response no cambia.
http_get_json_cpp_core (impure, pure wrapper)
Helper que envuelve http_request + parse JSON (via nlohmann::json o similar
ya disponible en el repo) para los casos comunes:
namespace fn_http {
// Devuelve parsed JSON o lanza si status != 2xx
nlohmann::json get_json(const std::string& url,
const std::string& bearer_token = "",
int timeout_ms = 5000);
}
Plan de migracion
Tras crear las funciones, abrir issue separado por cada consumer para migrar:
apps/services_monitor/http_client.cpp-> usarfn_http::requestapps/dag_engine_ui/main.cpp(inline)apps/data_factory/(inline)cpp/functions/core/llm_anthropic.cpp— refactor para usarfn_http::requestpor debajo (mantiene API publica)apps/process_explorer/(issue 0111) — nace ya usando el helper
Criterios de aceptacion
cpp/functions/core/http_request.{cpp,h,md}registrado enregistry.dbcpp/functions/core/http_get_json.{cpp,h,md}idem- Tests visuales o de integracion contra
httpbin.org(200/404/timeout/auth) - Frontmatter completo (
params/output/tags/example) .mdcumple contrato self-doc (## Ejemplo,## Cuando usarla,## Gotchas)- Al menos 1 consumer migrado para validar API (recomendado
services_monitor) fn doctor uses-functionslimpio
Gotchas conocidos
- cURL popen en Windows necesita
curl.exeen PATH — todos los WSL/Win lo tienen, pero documentar en## Gotchas. - Bodies binarios: popen complica el escape; primera version solo string bodies.
- TLS verify: por defecto on; permitir
req.insecure = truesolo para testing. - Timeouts: cURL
--max-timecubre handshake+transfer; documentar diferencia con read-timeout puro.
Por que no usar libcurl linkado
popen("curl ...")no requiere anadir libcurl al toolchain MinGW cross-compile (que ya costo configurar).llm_anthropiclleva meses funcionando asi.- Cuando aparezca un caso real de latencia (>10 req/s sostenido), abrimos issue separado para swap a libcurl.
Out of scope (no en este issue)
- WebSocket / SSE — cliente WS C++ es otro gap; abrir issue propio cuando aplique.
- Cliente gRPC.
- Streaming responses (SSE chunk-by-chunk) — usar caso de
dag_engine_uipara decidir cuando.