Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Typed parsers and formatters for common HTTP header values

Cerrado
#9,685 0 comentarios 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@effect-bot ya está trabajando en esto.

Desde el 21/10/2026.

  • #9709 de @tim-smart — fusionado

Evaluación

Este issue todavía no se ha evaluado.

Descripción

docker-made-me-do-it enhancement

Problem

effect/http treats header values as plain strings. Each place that needs to understand a value parses it on the spot, and the copies disagree.

Retry-After is parsed in eight places with six different rules. RFC 9110 §10.2.3 allows whole seconds or an HTTP date. For the invalid value -5:

  • HttpClient (http/HttpClient.ts:1461) falls through to Date.parse("-5"), which V8 reads as a date in 2001, so it retries after 1 ms.
  • The OTLP exporter and the Anthropic, OpenAI, OpenRouter and OpenAI-compatible clients return a delay of −5 seconds. These four AI clients also ignore HTTP dates and accept 1e3 and Infinity.
  • GraphQL and Cloudflare return undefined, and the typesafe client returns 0.

Other examples on main:

  • Media types are matched by substring (HttpServerRequest.ts:274, GraphQLProtocol.ts:260, HttpStaticServer.ts:438). The static server treats Accept: text/html;q=0, which means "never send HTML", as asking for HTML.
  • There are three separate Accept-style parsers: compression, McpServer and HttpApi.
  • HTTP dates go through Date.parse, which reads the asctime format in local time. With TZ=America/New_York, Sun Nov 6 08:49:37 1994 comes out five hours off.
  • Etag can format a tag but not parse or compare one. The static server splits If-None-Match on raw commas (HttpStaticServer.ts:448), but a comma is valid inside a tag.
  • There is nothing for Cache-Control, Range, Link, WWW-Authenticate or Structured Fields.

Two related bugs are filed separately: basicAuth encoding (#9678) and multipart filenames (#9679).

Proposal

Add one small module per header family to effect/http. Each one provides:

  • an immutable value;
  • parse, which returns a Result and is forgiving where the RFC allows;
  • format, which always produces the canonical form;
  • an Equivalence;
  • a Schema codec from string, so the value can be used directly in HttpApi headers schemas and in WithHeaders.
Module Standard
MediaType RFC 9110 §8.3.1
Accept, AcceptEncoding, AcceptLanguage, with negotiation RFC 9110 §12.5, RFC 4647
ContentDisposition RFC 6266, RFC 8187
HttpDate, RetryAfter RFC 9110 §5.6.7, §10.2.3
Etag lists and comparison, conditional requests RFC 9110 §8.8.3, §13
Range, ContentRange RFC 9110 §14
CacheControl RFC 9111 §5.2
Link RFC 8288
Authorization, WWW-Authenticate (Basic, Bearer) RFC 9110 §11, RFC 7617, RFC 6750
StructuredField RFC 9651
// names illustrative
RetryAfter.parse("Wed, 21 Oct 2015 07:28:00 GMT")  // Result<RetryAfter, HeaderValueError>
RetryAfter.delay(value, now)                         // Duration, never negative
Etag.parseList(`"a,b", W/"c"`)                       // two tags

HttpApiEndpoint.get("file", "/file", {
  headers: { "if-none-match": Schema.optional(Etag.ListFromString) }
})

Then switch Effect's own call sites over to these modules.

Why in Effect

  • Effect's own code needs these parsers, and today every bug has to be fixed in every copy.
  • Header values are wire data. Schema codecs give HttpApi users typed headers, decode errors and OpenAPI output without writing their own parsers.
  • Other ecosystems provide them too. Go has mime.ParseMediaType, http.ParseTime, and precondition and range handling in http.ServeContent. Rust has the headers and sfv crates. Node has jshttp's content-type, negotiator, range-parser and fresh.

Scope

In scope:

  • The modules above, and switching Effect's own call sites over to them.

Out of scope:

  • An HTTP cache.
  • Cookies and trace context, which already have modules.
  • Forwarded (#9681) and Problem Details (#9686), which have their own issues.
  • Accept-based response selection in HttpApi.

Open questions

  • Should conditional-request evaluation (If-Match, If-None-Match, If-Modified-Since, If-Range) be a public helper that any handler can call? The static server would then use it too.
  • One issue with a checklist, or one PR per module?
Lenguaje dominante
TypeScript
Estrellas
16.7k
Forks
808
Merge medio
11 h 24 min
PR fusionados (30 d)
848

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Effect-TS/effect

Todos los issues de Effect-TS/effect

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.