Skip to content

[P1][Correctness] Make HTTP code generators emit executable and semantically faithful requests #329

Description

@baixiangcpp

Summary

The HTTP Request Builder and Curl-to-Code generators currently emit snippets that are syntactically plausible but can be non-executable or change the request semantics.

The highest-confidence defect affects every valid JSON body generated for Python: both generators replace import requests with import json, then still call requests.<method>(...).

Generated output therefore fails immediately with NameError: name 'requests' is not defined.

Confirmed defects

1. Python JSON output drops import requests

Both implementations start with:

import requests

but replace the first line when a JSON payload is parsed:

lines[0] = "import json"

The final snippet still contains:

response = requests.post(...)

Both imports are required.

2. GET/HEAD bodies are emitted

The Fetch generators add a body whenever body text is present, independent of the HTTP method. Browser Fetch rejects GET and HEAD requests with bodies.

The builder UI also allows selecting a body for these methods, so users can generate code that fails at runtime.

3. Form-urlencoded cURL output changes the payload

HTTP Request Builder emits one --data-urlencode argument containing the entire body string:

--data-urlencode 'mode=test&limit=10'

This does not preserve two pre-encoded form fields; it reinterprets/encodes the whole argument and can send a different payload. A raw form body should use an appropriate --data-raw/--data form, or the builder should model individual key/value fields and emit one encoded argument per field.

4. Method-specific convenience APIs are assumed to exist

Curl-to-Code accepts a free-form parsed method, but generated Python and Rust use method-named convenience calls:

requests.<method>(...)
client.<method>(...)

These APIs do not cover every valid/custom HTTP method. The generator should use generic request APIs when the method is not explicitly supported.

5. Response bodies are always parsed as JSON

JavaScript and Python output always call response.json(). Valid 204 responses, text, binary responses, and error pages can therefore make otherwise successful snippets fail after the request completes.

Why this matters

These tools are code-generation utilities. The primary correctness contract is that copied output runs and represents the configured request. A snippet that compiles visually but fails on first execution, or sends a different body, breaks that contract.

Recommended implementation

Create a shared normalized request/code-generation model used by both tools. Each language emitter should:

  • preserve all required imports;
  • enforce method/body compatibility;
  • use generic request APIs for methods without a safe convenience method;
  • preserve raw versus JSON versus form semantics;
  • choose response handling from status/content type or generate a safe text-first default;
  • return structured generation warnings for unsupported combinations.

Where practical, generate source through small typed helpers rather than mutating line positions such as lines[0].

Acceptance criteria

  • Python output with a valid JSON body imports both json and requests and executes without an undefined name.
  • GET and HEAD configurations do not emit a Fetch body; the UI either disables body controls or surfaces a clear warning.
  • Form-urlencoded cURL output preserves the configured fields/body byte semantics.
  • OPTIONS/custom methods use a generic Python/Rust request API when no convenience method exists.
  • Empty, text, JSON, and 204 responses have generated handling that does not unconditionally fail on .json().
  • Shared table-driven tests cover methods, body types, headers, imports, and response modes across both tools.
  • At least one generated snippet per supported language is syntax-checked or compiled in CI where tooling is available.
  • Existing literal/code-injection safety tests continue to pass.

Relevant files

  • src/features/tools/http-request-builder/logic.ts
  • src/features/tools/curl-to-code/logic.ts
  • src/core/codegen/literals.ts
  • tests/unit/http-request-builder-codegen.test.ts
  • tests/unit/curl-to-code-codegen.test.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions