A batteries included HTTP/1.1 client in OCaml

trim

-11212
-166
third_party/bash-shell/ain.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "bash-shell/ain", 5 - "source_language": "Go", 6 - "criticality": "high", 7 - "change_type": "enhancement", 8 - "title": "Enhanced error context with line numbers and surrounding context", 9 - "description": "Ain provides rich error messages showing the original input line with the error, line numbers, surrounding context (1 line before/after), and an 'Expanded context' section showing variable/executable substitutions. This two-stage error reporting (raw + expanded) helps users debug template issues quickly. The OCaml library currently provides basic error messages without showing the context of where in a configuration file an error occurred.", 10 - "affected_files": [ 11 - "lib/error.ml", 12 - "lib/requests.ml", 13 - "lib/timeout.ml", 14 - "lib/retry.ml" 15 - ], 16 - "rationale": "When users configure the OCaml HTTP client (e.g., via configuration files, environment variables, or Cmdliner terms), errors should show exactly where the problem occurred with surrounding context. This is especially valuable for complex configurations with many parameters. The enhanced error messages would significantly improve developer experience and reduce debugging time." 17 - }, 18 - { 19 - "source_repo": "bash-shell/ain", 20 - "source_language": "Go", 21 - "criticality": "medium", 22 - "change_type": "feature", 23 - "title": "Global timeout covering entire operation lifecycle", 24 - "description": "Ain implements a global timeout that covers environment variable substitution, executable invocation, AND the backend HTTP call. The OCaml library has granular timeouts (connect, read, total) but the 'total' timeout only applies to the HTTP request itself, not to any pre-request setup operations or hooks that might be added in the future.", 25 - "affected_files": [ 26 - "lib/timeout.ml", 27 - "lib/requests.ml", 28 - "lib/one.ml" 29 - ], 30 - "rationale": "For production systems, it's critical to have an upper bound on the entire operation duration, not just the network I/O. If the library adds features like pre-request hooks, credential fetching, or configuration loading, these could hang indefinitely without a global timeout. Adding a 'global' timeout option that wraps the entire request lifecycle would provide better production safety guarantees." 31 - }, 32 - { 33 - "source_repo": "bash-shell/ain", 34 - "source_language": "Go", 35 - "criticality": "medium", 36 - "change_type": "enhancement", 37 - "title": "Typo suggestions using Levenshtein distance for configuration errors", 38 - "description": "Ain implements Levenshtein distance calculation to suggest similar variable names when an environment variable is not found. For example, if 'PORT' is undefined but 'PROT' exists, it suggests the correct name. This dramatically improves user experience when debugging configuration issues.", 39 - "affected_files": [ 40 - "lib/error.ml", 41 - "lib/requests.ml" 42 - ], 43 - "rationale": "When users mistype configuration parameter names (environment variables, header names, etc.), providing suggestions based on string similarity would help them quickly identify the mistake. This is particularly useful for CLI applications built with the library where users might set environment variables with typos. Implementation could use a simple edit distance algorithm to find the closest 2-3 matches from available options." 44 - }, 45 - { 46 - "source_repo": "bash-shell/ain", 47 - "source_language": "Go", 48 - "criticality": "medium", 49 - "change_type": "enhancement", 50 - "title": "Print/dry-run mode for debugging without executing requests", 51 - "description": "Ain has a '-p' flag that prints the exact command it would execute (curl/wget/httpie) instead of running it. This allows users to inspect, share, and manually test the generated command. The printed command is fully executable and includes all headers, body files, and options. This is invaluable for debugging and understanding what the tool is actually doing.", 52 - "affected_files": [ 53 - "lib/requests.mli", 54 - "lib/requests.ml", 55 - "lib/one.mli", 56 - "lib/one.ml" 57 - ], 58 - "rationale": "Adding a debug/dry-run mode that returns a structured representation of the HTTP request (method, URL, headers, body preview) without executing it would help users debug issues, validate configurations, and understand what the library will send. This could be implemented as an optional parameter that returns a request description instead of a response. Particularly useful for CLI tools and testing." 59 - }, 60 - { 61 - "source_repo": "bash-shell/ain", 62 - "source_language": "Go", 63 - "criticality": "medium", 64 - "change_type": "enhancement", 65 - "title": "Intelligent URL encoding that preserves existing encoded sequences", 66 - "description": "Ain's URL encoder intelligently handles mixed encoded/unencoded input by detecting already-encoded sequences (%XX format) and preserving them while encoding unencoded characters. It also handles space encoding differently for paths (%20) vs query strings (+). This allows users to mix encoded and unencoded text without double-encoding issues.", 67 - "affected_files": [ 68 - "lib/requests.ml", 69 - "lib/one.ml" 70 - ], 71 - "rationale": "The current OCaml library relies on Uri module's encoding, which may double-encode already-encoded sequences or not handle mixed input well. Implementing smarter URL encoding that detects and preserves existing percent-encoded sequences would prevent common bugs where URLs are encoded multiple times, leading to malformed requests. This is especially important when composing URLs from multiple sources or when receiving URLs that may already be partially encoded." 72 - }, 73 - { 74 - "source_repo": "bash-shell/ain", 75 - "source_language": "Go", 76 - "criticality": "low", 77 - "change_type": "enhancement", 78 - "title": "Parallel execution of independent operations", 79 - "description": "Ain executes all executable substitutions in parallel using goroutines and sync.WaitGroup, only waiting for all to complete before proceeding. This significantly reduces latency when multiple independent operations need to be performed (e.g., fetching multiple auth tokens or configuration values).", 80 - "affected_files": [ 81 - "lib/requests.ml", 82 - "lib/one.ml" 83 - ], 84 - "rationale": "While the OCaml library uses Eio for structured concurrency, it could benefit from explicitly parallelizing independent operations like: (1) DNS resolution for multiple redirect targets, (2) loading cookies from multiple domains in parallel, (3) future extensibility for pre-request hooks that could run concurrently. Adding explicit parallel execution patterns for independent operations would reduce latency, especially for complex request scenarios." 85 - }, 86 - { 87 - "source_repo": "bash-shell/ain", 88 - "source_language": "Go", 89 - "criticality": "low", 90 - "change_type": "enhancement", 91 - "title": "Accumulated error reporting (collect all errors before failing)", 92 - "description": "Ain accumulates multiple fatal errors from template parsing and reports them all at once, allowing users to fix multiple issues in a single iteration rather than fixing one error at a time. This is implemented via an errors slice that collects all issues before reporting.", 93 - "affected_files": [ 94 - "lib/error.ml", 95 - "lib/requests.ml" 96 - ], 97 - "rationale": "When validating request configurations (especially from configuration files or complex programmatic setups), collecting and reporting all validation errors at once saves users time by not forcing them to fix errors one-by-one. This could be implemented for configuration validation, header validation, and other pre-flight checks. Return a list of errors instead of failing on the first one." 98 - }, 99 - { 100 - "source_repo": "bash-shell/ain", 101 - "source_language": "Go", 102 - "criticality": "low", 103 - "change_type": "enhancement", 104 - "title": "Template/configuration file composition with override semantics", 105 - "description": "Ain allows composing multiple template files where some sections append (headers, query params) and others overwrite (method, body). This enables hierarchical organization like 'base.ain' with common settings + 'endpoint.ain' with specific details. The append vs overwrite semantics are well-defined per section type.", 106 - "affected_files": [ 107 - "lib/requests.mli", 108 - "lib/requests.ml" 109 - ], 110 - "rationale": "While the OCaml library has programmatic configuration, adding support for configuration file composition would be valuable for CLI tools and applications needing declarative configuration. Users could define base configurations (auth, common headers, timeouts) and compose them with endpoint-specific configurations. This could be implemented as a separate module that loads and merges configuration from multiple sources with clear override semantics." 111 - }, 112 - { 113 - "source_repo": "bash-shell/ain", 114 - "source_language": "Go", 115 - "criticality": "low", 116 - "change_type": "enhancement", 117 - "title": "Exit code and signal handling with proper propagation", 118 - "description": "Ain carefully propagates backend exit codes as its own exit code, handles SIGINT/SIGTERM with context cancellation, and calculates proper exit codes for signals (128 + signal number) for bash compatibility. This ensures clean shutdown and proper integration with shell scripts and CI/CD pipelines.", 119 - "affected_files": [ 120 - "lib/requests.ml", 121 - "lib/one.ml" 122 - ], 123 - "rationale": "For CLI tools built with the OCaml library, providing utilities or examples for proper signal handling and exit code management would improve production reliability. While Eio provides cancellation contexts, documenting best practices for signal handling patterns and providing helper functions for CLI applications would help users build robust tools. This is particularly important for long-running operations that need graceful shutdown." 124 - }, 125 - { 126 - "source_repo": "bash-shell/ain", 127 - "source_language": "Go", 128 - "criticality": "medium", 129 - "change_type": "enhancement", 130 - "title": "Interactive editing with VISUAL/EDITOR integration", 131 - "description": "Ain supports an exclamation mark suffix on filenames (template.ain!) that opens the file in $VISUAL or $EDITOR (falling back to vim) for one-time edits. It waits for the editor to exit before proceeding, supporting both terminal editors and GUI editors with --wait flags. This enables quick iteration without modifying source files.", 132 - "affected_files": [ 133 - "lib/requests.mli", 134 - "lib/requests.ml" 135 - ], 136 - "rationale": "For CLI HTTP client tools built with the library, adding a helper module for interactive editing of request templates or bodies would significantly improve developer experience. Users could edit complex JSON payloads or headers in their preferred editor before sending. This is particularly valuable for exploratory API testing. Implementation would involve temporary file creation, spawning editor process, and reading the modified content." 137 - }, 138 - { 139 - "source_repo": "bash-shell/ain", 140 - "source_language": "Go", 141 - "criticality": "low", 142 - "change_type": "enhancement", 143 - "title": "Backend abstraction pattern for pluggable execution strategies", 144 - "description": "Ain implements a backend interface that allows pluggable implementations (curl, wget, httpie) with a common interface (getAsCmd, getAsString). Each backend translates the abstract request representation into backend-specific command-line arguments. This abstraction enables supporting multiple HTTP clients through a unified interface.", 145 - "affected_files": [ 146 - "lib/http_client.ml", 147 - "lib/requests.ml" 148 - ], 149 - "rationale": "The OCaml library currently has a single HTTP/1.1 implementation. Adding a backend abstraction would enable: (1) pluggable HTTP/2 and HTTP/3 support via different backends, (2) mocking/testing with fake backends, (3) specialized backends for specific use cases (e.g., low-latency vs high-throughput). This would improve extensibility without breaking the core API. The abstraction should define a common interface for making requests that different implementations can fulfill." 150 - }, 151 - { 152 - "source_repo": "bash-shell/ain", 153 - "source_language": "Go", 154 - "criticality": "high", 155 - "change_type": "enhancement", 156 - "title": "Comprehensive end-to-end testing with declarative test format", 157 - "description": "Ain uses a declarative YAML-in-comments test format for end-to-end tests. Each .ain template file can include test directives (env vars, args, expected stdout/stderr, exit code) as YAML in comments. A single test runner parses these directives and validates all aspects of execution. Tests are actual template files that also serve as examples. This approach provides high test coverage with minimal boilerplate.", 158 - "affected_files": [ 159 - "test/", 160 - "test/test_simple.ml", 161 - "test/httpbin.t" 162 - ], 163 - "rationale": "The OCaml library currently uses Alcotest and expect tests. Adding more declarative, end-to-end test cases that validate the complete request/response cycle (including edge cases like redirects, retries, timeouts, various auth schemes) would improve confidence. Tests should cover: (1) all authentication methods including digest auth challenges, (2) retry behavior with Retry-After headers, (3) redirect handling including cross-origin security, (4) timeout scenarios at different stages, (5) error conditions. More comprehensive E2E tests would catch integration issues early." 164 - } 165 - ] 166 - }
-278
third_party/bash-shell/aria2.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "aria2", 5 - "source_language": "C++", 6 - "criticality": "high", 7 - "change_type": "feature", 8 - "title": "Add HTTP Range Request Support for Resumable Downloads", 9 - "description": "aria2 implements segmented downloading with HTTP Range requests, allowing downloads to be split across multiple connections and resumed after interruption. The OCaml library should support Range headers for partial content requests and Accept-Ranges detection.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/one.ml", 13 - "lib/headers.ml", 14 - "lib/response.ml" 15 - ], 16 - "rationale": "aria2's HttpRequest.cc uses Range headers extensively for parallel chunk downloads and resume capability. This is a critical feature for download managers and large file transfers. The OCaml library currently lacks explicit Range request helpers and resumption logic. Adding this would enable: (1) Resuming interrupted downloads by requesting byte ranges, (2) Parallel chunk downloads for faster speeds, (3) Checking Accept-Ranges header to determine if server supports partial requests. Implementation should add Range header builder in Headers module and resume helpers in Requests/One modules." 17 - }, 18 - { 19 - "source_repo": "aria2", 20 - "source_language": "C++", 21 - "criticality": "medium", 22 - "change_type": "enhancement", 23 - "title": "Implement Persistent Connection Statistics and Server Performance Tracking", 24 - "description": "aria2 tracks per-server statistics (PeerStat, ServerStat) including download speeds, connection success/failure rates, and latency. This enables intelligent connection reuse and server selection for mirror fallback scenarios.", 25 - "affected_files": [ 26 - "lib/requests.ml", 27 - "lib/conpool.ml" 28 - ], 29 - "rationale": "aria2's AbstractCommand.cc and SegmentMan.h maintain detailed statistics about server performance, allowing the download engine to prefer faster servers and detect slow/failing servers. The OCaml library uses connection pooling but doesn't track performance metrics. Adding statistics would enable: (1) Preferring faster mirrors automatically, (2) Adaptive timeout adjustment based on server latency, (3) Identifying problematic servers for blacklisting. Implementation could add a ServerStats module tracking response times, error rates, and throughput per endpoint." 30 - }, 31 - { 32 - "source_repo": "aria2", 33 - "source_language": "C++", 34 - "criticality": "medium", 35 - "change_type": "feature", 36 - "title": "Add Netrc File Support for Automatic Authentication", 37 - "description": "aria2 supports .netrc file parsing for automatic credential lookup based on hostname. When credentials are stripped during cross-origin redirects, netrc allows re-acquiring appropriate credentials for the new host.", 38 - "affected_files": [ 39 - "lib/auth.ml", 40 - "lib/requests.ml" 41 - ], 42 - "rationale": "aria2's AuthConfigFactory includes netrc support, enabling automatic authentication without exposing credentials in code or URLs. The OCaml library correctly strips Authorization headers on cross-origin redirects (per requests.ml:244 TODO comment) but has no mechanism to re-acquire credentials. Adding netrc support would: (1) Enable automatic authentication for multiple hosts, (2) Support secure credential storage following Unix conventions, (3) Allow credential re-acquisition after cross-origin redirects. Implementation should parse ~/.netrc with permission checks (must be 600) and add Auth.from_netrc function." 43 - }, 44 - { 45 - "source_repo": "aria2", 46 - "source_language": "C++", 47 - "criticality": "low", 48 - "change_type": "enhancement", 49 - "title": "Add Download Progress Callbacks and Streaming Progress Monitoring", 50 - "description": "aria2 provides real-time progress tracking through callbacks that report bytes downloaded, download speed, and ETA. This enables progress bars, bandwidth monitoring, and user feedback during long downloads.", 51 - "affected_files": [ 52 - "lib/requests.ml", 53 - "lib/one.ml", 54 - "lib/response.ml" 55 - ], 56 - "rationale": "aria2's DownloadEngine calculates statistics continuously and reports progress through various interfaces. The OCaml library returns responses with body streams but provides no mechanism to monitor download progress. Adding progress callbacks would enable: (1) Progress bars for downloads, (2) Bandwidth throttling based on current speed, (3) Cancellation after detecting slow downloads. Implementation could add optional progress callback to request functions that receives (bytes_downloaded, total_bytes, speed_bps) updates during streaming." 57 - }, 58 - { 59 - "source_repo": "aria2", 60 - "source_language": "C++", 61 - "criticality": "low", 62 - "change_type": "feature", 63 - "title": "Implement HTTP Pipelining Support for Sequential Requests", 64 - "description": "aria2 supports HTTP/1.1 pipelining, sending multiple requests over a single connection without waiting for responses. This reduces latency for sequential requests to the same server.", 65 - "affected_files": [ 66 - "lib/http_client.ml", 67 - "lib/requests.ml" 68 - ], 69 - "rationale": "aria2's HttpConnection.cc implements request pipelining with outstanding request tracking (outstandingHttpRequests_). The OCaml library uses connection pooling but sends requests sequentially. While HTTP/2 multiplexing is better, HTTP/1.1 pipelining can reduce latency for servers that support it. Implementation would require tracking multiple in-flight requests per connection and matching responses to requests. However, pipelining has compatibility issues and is disabled in most browsers, so this is low priority unless HTTP/2 is added." 70 - }, 71 - { 72 - "source_repo": "aria2", 73 - "source_language": "C++", 74 - "criticality": "medium", 75 - "change_type": "enhancement", 76 - "title": "Add Configurable User-Agent with Application/Version Information", 77 - "description": "aria2 sends a detailed User-Agent header including version, platform, and enabled features. Allowing configurable User-Agent with sensible defaults helps with debugging, analytics, and server compatibility.", 78 - "affected_files": [ 79 - "lib/requests.ml", 80 - "lib/headers.ml" 81 - ], 82 - "rationale": "aria2 constructs User-Agent strings like 'aria2/1.37.0 libaria2/1.37.0' with platform details. The OCaml library can set User-Agent via default headers but has no built-in User-Agent. Adding a default User-Agent would: (1) Help server administrators identify the client, (2) Enable version-specific bug tracking, (3) Improve compatibility with servers that require User-Agent. Implementation should add a default like 'ocaml-requests/VERSION (OCaml; Eio)' that can be overridden." 83 - }, 84 - { 85 - "source_repo": "aria2", 86 - "source_language": "C++", 87 - "criticality": "low", 88 - "change_type": "feature", 89 - "title": "Add Mirror/Fallback URL Support with Automatic Failover", 90 - "description": "aria2 supports multiple mirror URLs for the same resource, automatically trying alternatives when one fails. This is implemented via Metalink protocol but the core concept applies to any download with backup URLs.", 91 - "affected_files": [ 92 - "lib/requests.ml", 93 - "lib/one.ml" 94 - ], 95 - "rationale": "aria2's RequestGroup manages multiple mirror URIs and automatically switches when encountering errors (via useFasterRequest in AbstractCommand.cc). The OCaml library has retry logic but no built-in mirror support. Adding mirror fallback would: (1) Improve reliability by trying alternative servers, (2) Automatically select fastest mirror, (3) Work around server failures transparently. Implementation could add optional mirror_urls parameter to request functions that tries URLs in sequence on connection/server errors." 96 - }, 97 - { 98 - "source_repo": "aria2", 99 - "source_language": "C++", 100 - "criticality": "high", 101 - "change_type": "enhancement", 102 - "title": "Improve Retry Logic with Exponential Backoff Per Server", 103 - "description": "aria2 implements sophisticated retry logic with per-server backoff, avoiding retry storms when a server is overloaded. The backoff state is maintained separately for each endpoint rather than globally.", 104 - "affected_files": [ 105 - "lib/retry.ml", 106 - "lib/requests.ml" 107 - ], 108 - "rationale": "aria2's AbstractCommand.cc implements prepareForRetry with timers and per-request retry counts. The OCaml library's retry.ml uses global backoff without considering which server failed. Per-server backoff prevents: (1) Hammering a failing server while allowing retries to healthy servers, (2) Retry storms that can amplify outages, (3) Unfair resource usage. Implementation should track retry state (attempt count, next retry time) per endpoint in a retry state map." 109 - }, 110 - { 111 - "source_repo": "aria2", 112 - "source_language": "C++", 113 - "criticality": "medium", 114 - "change_type": "security", 115 - "title": "Add Configurable Maximum Concurrent Connections Per Host", 116 - "description": "aria2 limits concurrent connections per host to avoid overwhelming servers and being rate-limited or banned. This is both a performance and security best practice.", 117 - "affected_files": [ 118 - "lib/requests.ml" 119 - ], 120 - "rationale": "aria2 limits connections via max_connections_per_endpoint configuration (SegmentMan). The OCaml library has max_connections_per_host in Requests.create (default 10) which configures the connection pool. However, there's no documentation or enforcement at the request level. Adding explicit limits would: (1) Prevent accidental DoS of target servers, (2) Avoid rate limiting and bans, (3) Ensure fair resource usage. The current implementation via conpool is correct, but should be documented as a security feature." 121 - }, 122 - { 123 - "source_repo": "aria2", 124 - "source_language": "C++", 125 - "criticality": "medium", 126 - "change_type": "enhancement", 127 - "title": "Add Bandwidth Throttling and Rate Limiting", 128 - "description": "aria2 supports configurable download and upload speed limits, enabling bandwidth management and preventing network saturation.", 129 - "affected_files": [ 130 - "lib/requests.ml", 131 - "lib/response.ml" 132 - ], 133 - "rationale": "aria2 implements bandwidth throttling at the engine level, controlling how fast data is read from sockets. The OCaml library streams responses but has no rate limiting. Adding throttling would enable: (1) Limiting bandwidth usage to avoid network saturation, (2) Background downloads that don't impact interactive traffic, (3) Fairness across multiple concurrent downloads. Implementation could add optional max_bytes_per_second parameter that uses Eio.Time.sleep to throttle streaming reads." 134 - }, 135 - { 136 - "source_repo": "aria2", 137 - "source_language": "C++", 138 - "criticality": "low", 139 - "change_type": "enhancement", 140 - "title": "Add Support for HTTP Trailers", 141 - "description": "aria2 parses HTTP trailers (headers sent after chunked body), which can contain checksums, signatures, or metadata determined during transfer.", 142 - "affected_files": [ 143 - "lib/http_read.ml", 144 - "lib/response.ml" 145 - ], 146 - "rationale": "aria2's HttpHeaderProcessor handles both headers and trailers in chunked encoding. HTTP trailers are defined in RFC 9110 Section 6.5 and used for integrity checks (e.g., Content-MD5 calculated during streaming). The OCaml library's http_read.ml parses chunked encoding but may not expose trailers. Adding trailer support would enable: (1) Integrity verification without requiring Content-Length, (2) Dynamic metadata (generation time, server ID), (3) RFC 9110 compliance. Implementation should parse trailers after chunked body and add them to response headers." 147 - }, 148 - { 149 - "source_repo": "aria2", 150 - "source_language": "C++", 151 - "criticality": "low", 152 - "change_type": "feature", 153 - "title": "Add DNS Caching with TTL Awareness", 154 - "description": "aria2 maintains a DNS cache (DNSCache) to avoid repeated lookups for the same hostname, improving performance and reducing DNS server load.", 155 - "affected_files": [ 156 - "lib/requests.ml" 157 - ], 158 - "rationale": "aria2's DownloadEngine includes a DNS cache (DownloadEngine.cc line 107). The OCaml library relies on OS-level DNS caching through getaddrinfo. Adding application-level DNS caching would: (1) Reduce latency for repeated requests, (2) Avoid DNS lookup failures during temporary DNS issues, (3) Respect DNS TTL for cache invalidation. Implementation could add optional DNS cache using a TTL-aware map of hostname -> (ip_addresses, expiry_time)." 159 - }, 160 - { 161 - "source_repo": "aria2", 162 - "source_language": "C++", 163 - "criticality": "medium", 164 - "change_type": "enhancement", 165 - "title": "Improve Connection Timeout Handling with Separate DNS and TCP Phases", 166 - "description": "aria2 separates DNS resolution timeout from TCP connection timeout, allowing fine-grained control and better error diagnostics.", 167 - "affected_files": [ 168 - "lib/timeout.ml", 169 - "lib/error.ml", 170 - "lib/requests.ml" 171 - ], 172 - "rationale": "aria2's AbstractCommand tracks async DNS resolution and TCP connection separately with different timeout values. The OCaml library has connect_timeout in timeout.ml but applies it to the entire connection process. Separating phases would enable: (1) Different timeout values for DNS (usually faster) vs TCP (may need longer), (2) Better error messages distinguishing DNS failures from connection refusal, (3) Retry DNS only vs full reconnection. Implementation should add dns_timeout to Timeout.t and separate error tracking." 173 - }, 174 - { 175 - "source_repo": "aria2", 176 - "source_language": "C++", 177 - "criticality": "low", 178 - "change_type": "enhancement", 179 - "title": "Add Request/Response Logging with Sanitization", 180 - "description": "aria2 logs full HTTP requests and responses with automatic sanitization of sensitive headers (Authorization, Cookie, etc.), which the OCaml library already implements partially.", 181 - "affected_files": [ 182 - "lib/requests.ml", 183 - "lib/http_client.ml" 184 - ], 185 - "rationale": "aria2's HttpConnection.cc has eraseConfidentialInfo function (lines 99-123) that redacts Authorization, Proxy-Authorization, Cookie, and Set-Cookie headers in logs. The OCaml library's error.ml already sanitizes errors (lines 63-83) but doesn't log full requests/responses. The current implementation is good for errors; adding optional debug logging of full HTTP transactions would help debugging. This is already well-handled, but could be extended to log full requests at Debug level." 186 - }, 187 - { 188 - "source_repo": "aria2", 189 - "source_language": "C++", 190 - "criticality": "medium", 191 - "change_type": "feature", 192 - "title": "Add Proxy Support (HTTP, SOCKS) with Authentication", 193 - "description": "aria2 supports HTTP and SOCKS proxies with authentication, enabling use in corporate environments and privacy scenarios.", 194 - "affected_files": [ 195 - "lib/requests.ml", 196 - "lib/auth.ml", 197 - "lib/one.ml" 198 - ], 199 - "rationale": "aria2 implements proxy support throughout (HttpConnection.cc has sendProxyRequest, supports Proxy-Authorization header). The OCaml library currently has no proxy support. Adding proxies would enable: (1) Corporate environment compatibility, (2) Privacy through SOCKS proxies (Tor, etc.), (3) HTTP CONNECT for HTTPS through proxies. Implementation should add proxy configuration to Requests.create with HTTP_PROXY/HTTPS_PROXY environment variables, and add Proxy-Authorization handling in auth.ml." 200 - }, 201 - { 202 - "source_repo": "aria2", 203 - "source_language": "C++", 204 - "criticality": "low", 205 - "change_type": "enhancement", 206 - "title": "Add Idle Connection Reaping and Keepalive Management", 207 - "description": "aria2 actively manages connection lifecycle, closing idle connections and respecting keepalive timeouts to avoid resource exhaustion.", 208 - "affected_files": [ 209 - "lib/requests.ml" 210 - ], 211 - "rationale": "aria2's connection management includes idle timeout tracking and proper cleanup. The OCaml library uses conpool which has max_idle_time and max_connection_lifetime parameters (requests.ml:88-89), so this is already implemented. However, the defaults should be documented as best practices: connection_idle_timeout=60s and connection_lifetime=300s are reasonable values that match aria2's approach." 212 - }, 213 - { 214 - "source_repo": "aria2", 215 - "source_language": "C++", 216 - "criticality": "medium", 217 - "change_type": "enhancement", 218 - "title": "Add Checksum Verification Support", 219 - "description": "aria2 verifies downloads using checksums (MD5, SHA-1, SHA-256, SHA-512) to ensure integrity, especially important for large files and mirrors.", 220 - "affected_files": [ 221 - "lib/response.ml", 222 - "lib/requests.ml", 223 - "lib/one.ml" 224 - ], 225 - "rationale": "aria2's ChecksumCheckIntegrityEntry verifies piece-level and file-level checksums. The OCaml library has no built-in checksum verification. Adding this would enable: (1) Integrity verification for downloads, (2) Detection of corrupted transfers, (3) Validation against provided checksums (Content-MD5 header or external checksums). Implementation could add optional expected_checksum parameter with algorithm and value, verifying after download completes." 226 - }, 227 - { 228 - "source_repo": "aria2", 229 - "source_language": "C++", 230 - "criticality": "low", 231 - "change_type": "feature", 232 - "title": "Add WebSocket Support for Real-Time Communication", 233 - "description": "aria2 implements WebSocket support for its RPC interface, enabling real-time bidirectional communication. This could be useful for the OCaml library's feature set.", 234 - "affected_files": [ 235 - "lib/requests.ml" 236 - ], 237 - "rationale": "aria2 has WebSocketSession and WebSocketSessionMan for RPC communication over WebSockets. While the OCaml library focuses on HTTP requests, WebSocket support would enable: (1) Real-time APIs and notifications, (2) Bidirectional communication patterns, (3) GraphQL subscriptions and similar protocols. However, this is low priority as WebSockets are fundamentally different from HTTP requests. If needed, this should be a separate library building on the HTTP upgrade mechanism." 238 - }, 239 - { 240 - "source_repo": "aria2", 241 - "source_language": "C++", 242 - "criticality": "high", 243 - "change_type": "bug", 244 - "title": "Fix Digest Authentication Implementation", 245 - "description": "The TODO.md mentions 'Auth.Digest seems incomplete'. Review and fix digest authentication to ensure RFC 7616 compliance and handle all edge cases.", 246 - "affected_files": [ 247 - "lib/auth.ml" 248 - ], 249 - "rationale": "aria2's AuthConfig implements full digest authentication including qop, nonce, cnonce, and multiple algorithms. The OCaml library has digest auth in auth.ml (line 280 in requests.ml shows digest auth usage) but TODO.md flags it as incomplete. Digest auth has many subtle requirements (nonce counting, qop handling, multiple algorithm support). Implementation should verify: (1) All RFC 7616 parameters are handled, (2) Nonce counting for qop=auth, (3) Multiple algorithms (MD5, SHA-256, SHA-512-256), (4) Proper response hash calculation." 250 - }, 251 - { 252 - "source_repo": "aria2", 253 - "source_language": "C++", 254 - "criticality": "low", 255 - "change_type": "enhancement", 256 - "title": "Add MIME Type Detection and Content-Type Helpers", 257 - "description": "Enhance MIME type detection for request bodies and add helpers for common content types, as indicated by the 'Body MIME guessing could be enhanced' TODO.", 258 - "affected_files": [ 259 - "lib/body.ml", 260 - "lib/mime.ml" 261 - ], 262 - "rationale": "aria2 determines Content-Type based on file extensions and response analysis. The TODO.md mentions MIME guessing needs work. The library has mime.ml but may lack comprehensive type detection. Adding better MIME support would: (1) Automatically set correct Content-Type for file uploads, (2) Provide helpers for JSON, XML, form data, (3) Guess types from file extensions using magic numbers. Implementation could add MIME database and auto-detection for Body.file and Body.stream variants." 263 - }, 264 - { 265 - "source_repo": "aria2", 266 - "source_language": "C++", 267 - "criticality": "medium", 268 - "change_type": "enhancement", 269 - "title": "Add HTTP/2 Support", 270 - "description": "While aria2 is HTTP/1.1 only, modern HTTP clients should support HTTP/2 for improved performance with multiplexing, header compression, and server push.", 271 - "affected_files": [ 272 - "lib/http_client.ml", 273 - "lib/requests.ml" 274 - ], 275 - "rationale": "aria2 predates widespread HTTP/2 adoption, but HTTP/2 offers significant advantages: (1) Multiplexing eliminates head-of-line blocking, (2) Header compression reduces overhead, (3) Single connection per host reduces overhead. The OCaml library is HTTP/1.1 only. Adding HTTP/2 would enable better performance but requires significant work (ALPN negotiation, HPACK compression, frame parsing). This is medium priority as HTTP/1.1 works but HTTP/2 is now standard. Consider using h2-eio if available." 276 - } 277 - ] 278 - }
-297
third_party/bash-shell/curl.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/bash-shell/curl", 5 - "source_language": "C", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add TCP keepalive configuration support", 9 - "description": "Curl provides TCP keepalive configuration (CURLOPT_TCP_KEEPALIVE, CURLOPT_TCP_KEEPIDLE, CURLOPT_TCP_KEEPINTVL) to prevent idle connections from being dropped by intermediary routers/firewalls. This is particularly useful for long-lived connections in connection pools. The OCaml library should expose TCP keepalive settings at the connection pool or request level to ensure persistent connections remain healthy.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/requests.mli", 13 - "lib/one.ml", 14 - "lib/one.mli" 15 - ], 16 - "rationale": "Connection pools benefit significantly from TCP keepalive to detect dead connections and prevent timeout issues on long-lived HTTP connections. Curl's extensive deployment has proven the value of configurable keepalive parameters. This would improve reliability for applications maintaining persistent connections to APIs." 17 - }, 18 - { 19 - "source_repo": "third_party/bash-shell/curl", 20 - "source_language": "C", 21 - "criticality": "medium", 22 - "change_type": "feature", 23 - "title": "Implement HSTS (HTTP Strict Transport Security) support", 24 - "description": "Curl implements RFC 6797 HSTS which automatically upgrades HTTP requests to HTTPS for domains that have previously sent a Strict-Transport-Security header. This prevents SSL stripping attacks and improves security. The library should parse HSTS headers, maintain an HSTS cache (similar to the cookie jar), and automatically upgrade matching requests from http:// to https://.", 25 - "affected_files": [ 26 - "lib/requests.ml", 27 - "lib/requests.mli", 28 - "lib/headers.ml", 29 - "lib/headers.mli" 30 - ], 31 - "rationale": "HSTS is a critical security feature standardized in RFC 6797. Implementing HSTS prevents downgrade attacks where attackers intercept HTTP requests before they can be upgraded to HTTPS. With XDG directory support already in place for cookie persistence, HSTS cache storage follows the same pattern. This significantly improves security for users of the library." 32 - }, 33 - { 34 - "source_repo": "third_party/bash-shell/curl", 35 - "source_language": "C", 36 - "criticality": "low", 37 - "change_type": "enhancement", 38 - "title": "Add TLS session caching for connection reuse", 39 - "description": "Curl's vtls layer implements TLS session caching (vtls_scache.c) which stores and reuses TLS session data across connections to the same host. This provides significant performance improvements by eliminating the expensive TLS handshake on subsequent connections. The OCaml library should cache TLS session tickets/IDs when using tls-eio and attempt to resume sessions when reconnecting to the same host.", 40 - "affected_files": [ 41 - "lib/requests.ml", 42 - "lib/http_client.ml", 43 - "lib/one.ml" 44 - ], 45 - "rationale": "TLS handshakes are computationally expensive (especially with modern cipher suites). Session resumption can reduce latency by 50-100ms per connection. While Eio's connection pooling already reduces the frequency of new connections, TLS session caching further optimizes the reconnection case when pools are cleared or connections expire. This is a standard optimization in mature HTTP clients." 46 - }, 47 - { 48 - "source_repo": "third_party/bash-shell/curl", 49 - "source_language": "C", 50 - "criticality": "medium", 51 - "change_type": "feature", 52 - "title": "Add comprehensive proxy support with authentication", 53 - "description": "Curl provides extensive proxy support including HTTP/HTTPS/SOCKS4/SOCKS5 proxies with separate authentication credentials and TLS configuration for HTTPS proxies (CURLOPT_PROXY, CURLOPT_PROXYUSERPWD, CURLOPT_PROXY_SSL_*, etc.). The OCaml library currently lacks proxy support. Implement HTTP/HTTPS proxy support with separate authentication, environment variable support (HTTP_PROXY, HTTPS_PROXY, NO_PROXY), and configurable proxy TLS settings.", 54 - "affected_files": [ 55 - "lib/requests.ml", 56 - "lib/requests.mli", 57 - "lib/one.ml", 58 - "lib/one.mli", 59 - "lib/http_client.ml", 60 - "lib/error.ml", 61 - "lib/error.mli" 62 - ], 63 - "rationale": "Proxy support is essential for enterprise environments and corporate networks where direct internet access is restricted. Many organizations require HTTP clients to respect proxy environment variables. The existing Proxy_error variant in error.ml suggests this was planned. This feature would make the library usable in enterprise settings." 64 - }, 65 - { 66 - "source_repo": "third_party/bash-shell/curl", 67 - "source_language": "C", 68 - "criticality": "low", 69 - "change_type": "enhancement", 70 - "title": "Add server response timeout separate from read timeout", 71 - "description": "Curl distinguishes between read timeout (time between bytes) and server response timeout (time waiting for the server to start responding after sending the request). CURLOPT_SERVER_RESPONSE_TIMEOUT defaults to 60s and prevents hanging on servers that accept connections but never respond. The OCaml library's read timeout (default: 30s) applies per-read operation. Add a separate server_response_timeout to Timeout.t to catch unresponsive servers.", 72 - "affected_files": [ 73 - "lib/timeout.ml", 74 - "lib/timeout.mli", 75 - "lib/http_client.ml" 76 - ], 77 - "rationale": "The distinction between 'no data flowing' and 'server never responding' is important for debugging and retry logic. A server might be overwhelmed and never send the first byte, but a properly configured server might legitimately have slow reads for large responses. This separate timeout helps distinguish these cases and provides better timeout granularity." 78 - }, 79 - { 80 - "source_repo": "third_party/bash-shell/curl", 81 - "source_language": "C", 82 - "criticality": "low", 83 - "change_type": "enhancement", 84 - "title": "Add Happy Eyeballs IPv4/IPv6 dual-stack support", 85 - "description": "Curl implements Happy Eyeballs (RFC 8305) via CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS which attempts both IPv4 and IPv6 connections in parallel with a small delay (default: 200ms). This significantly improves connection reliability and latency when one protocol stack has connectivity issues. Implement parallel connection attempts with configurable delay when a hostname resolves to both IPv4 and IPv6 addresses.", 86 - "affected_files": [ 87 - "lib/http_client.ml", 88 - "lib/timeout.ml", 89 - "lib/timeout.mli" 90 - ], 91 - "rationale": "As IPv6 adoption increases, many hosts have both A and AAAA DNS records. Network configurations sometimes have broken IPv6 (or IPv4), leading to connection failures or long timeouts. Happy Eyeballs ensures the client automatically uses whichever protocol works, improving reliability and user experience. This is now a best practice for modern network clients (RFC 8305)." 92 - }, 93 - { 94 - "source_repo": "third_party/bash-shell/curl", 95 - "source_language": "C", 96 - "criticality": "low", 97 - "change_type": "enhancement", 98 - "title": "Add bandwidth rate limiting for uploads and downloads", 99 - "description": "Curl provides CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE to limit bandwidth consumption. This is useful for background transfers, testing under constrained networks, or being a good network citizen. Implement rate limiting in the upload/download streaming functions using Eio's flow control, with configurable bytes-per-second limits.", 100 - "affected_files": [ 101 - "lib/one.ml", 102 - "lib/one.mli", 103 - "lib/requests.ml", 104 - "lib/requests.mli" 105 - ], 106 - "rationale": "While the library has ratelimit.ml visible in the curl implementation, rate limiting is useful for background transfers, testing, and preventing a single transfer from saturating network bandwidth. The existing progress callback infrastructure in One.upload/download makes this a natural extension. This would be particularly useful for applications doing large file transfers." 107 - }, 108 - { 109 - "source_repo": "third_party/bash-shell/curl", 110 - "source_language": "C", 111 - "criticality": "low", 112 - "change_type": "enhancement", 113 - "title": "Add low-speed detection with configurable abort threshold", 114 - "description": "Curl provides CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME which abort transfers if the speed drops below a threshold for a sustained period (e.g., below 1KB/s for 30 seconds). This prevents hanging on stalled connections that would otherwise respect the read timeout. Implement speed tracking in streaming operations with configurable minimum speed and duration thresholds.", 115 - "affected_files": [ 116 - "lib/one.ml", 117 - "lib/one.mli", 118 - "lib/timeout.ml", 119 - "lib/timeout.mli", 120 - "lib/error.ml" 121 - ], 122 - "rationale": "Stalled transfers are a common problem - the connection stays alive but throughput becomes unusable. Traditional timeouts don't catch this because data is still trickling through. Low-speed detection provides a quality-of-service guarantee and prevents wasting time on effectively dead connections. This is especially important for large file transfers over unreliable networks." 123 - }, 124 - { 125 - "source_repo": "third_party/bash-shell/curl", 126 - "source_language": "C", 127 - "criticality": "medium", 128 - "change_type": "feature", 129 - "title": "Add NTLM and Negotiate/Kerberos authentication support", 130 - "description": "Curl supports NTLM (lib/vauth/ntlm.c) and Negotiate/SPNEGO/Kerberos authentication (lib/vauth/spnego_gssapi.c) which are widely used in enterprise environments, particularly with Microsoft services. While complex to implement, adding at least NTLM support would enable the library to work with Windows-based APIs and enterprise services. Consider integrating with existing OCaml Kerberos or NTLM libraries if available.", 131 - "affected_files": [ 132 - "lib/auth.ml", 133 - "lib/auth.mli", 134 - "lib/http_client.ml" 135 - ], 136 - "rationale": "The library already supports Basic, Bearer, and Digest authentication. NTLM and Kerberos/Negotiate are critical for enterprise Windows environments and services like SharePoint, Exchange, and Active Directory. While implementation complexity is high, this would significantly expand the library's applicability in enterprise settings. Even documenting a custom authentication path for these schemes would be valuable." 137 - }, 138 - { 139 - "source_repo": "third_party/bash-shell/curl", 140 - "source_language": "C", 141 - "criticality": "medium", 142 - "change_type": "enhancement", 143 - "title": "Add DNS caching with configurable TTL", 144 - "description": "Curl implements DNS result caching with CURLOPT_DNS_CACHE_TIMEOUT (default: 60 seconds) to avoid redundant DNS lookups. While Eio's network stack may handle some DNS caching, implementing application-level DNS caching ensures consistent behavior and reduces latency for applications making many requests to the same hosts. Add a simple hostname->IP cache with TTL-based expiration.", 145 - "affected_files": [ 146 - "lib/requests.ml", 147 - "lib/http_client.ml" 148 - ], 149 - "rationale": "DNS lookups add 10-100ms of latency per request. For applications making frequent requests to the same hosts (API clients, web scrapers), DNS caching provides significant performance improvements. While connection pooling reduces this impact, DNS caching benefits the initial connection and reconnections after pool expiration. The library's session-oriented design makes this a natural optimization." 150 - }, 151 - { 152 - "source_repo": "third_party/bash-shell/curl", 153 - "source_language": "C", 154 - "criticality": "low", 155 - "change_type": "feature", 156 - "title": "Add certificate pinning support for enhanced security", 157 - "description": "Curl supports public key pinning via CURLOPT_PINNEDPUBLICKEY which allows applications to validate that the server's certificate matches a known public key hash. This provides protection against compromised certificate authorities. Add support for certificate/public key pinning in the TLS configuration, allowing users to specify expected certificate hashes or public keys.", 158 - "affected_files": [ 159 - "lib/requests.ml", 160 - "lib/requests.mli", 161 - "lib/one.ml", 162 - "lib/one.mli", 163 - "lib/error.ml" 164 - ], 165 - "rationale": "Certificate pinning provides defense-in-depth against certificate authority compromise and man-in-the-middle attacks. While not needed for most applications, it's critical for high-security applications (banking, cryptocurrency, healthcare). The tls-eio library should support custom certificate validation, making this a configuration layer addition. This is a standard security feature in modern HTTP clients." 166 - }, 167 - { 168 - "source_repo": "third_party/bash-shell/curl", 169 - "source_language": "C", 170 - "criticality": "low", 171 - "change_type": "enhancement", 172 - "title": "Add support for multiple authentication methods with automatic fallback", 173 - "description": "Curl supports automatic authentication method negotiation - trying multiple methods (Negotiate, NTLM, Digest, Basic) in priority order until one succeeds. The OCaml library currently requires users to specify exactly one auth method. Implement authentication method negotiation based on WWW-Authenticate header challenges, with configurable priority order and automatic fallback.", 174 - "affected_files": [ 175 - "lib/auth.ml", 176 - "lib/auth.mli", 177 - "lib/http_client.ml", 178 - "lib/requests.ml" 179 - ], 180 - "rationale": "Many servers support multiple authentication methods, and the preferred method may not be known in advance. Automatic negotiation improves usability and robustness. The library already has Digest authentication with 401 retry logic, making this a natural extension. This would reduce configuration burden and improve compatibility with diverse server environments." 181 - }, 182 - { 183 - "source_repo": "third_party/bash-shell/curl", 184 - "source_language": "C", 185 - "criticality": "low", 186 - "change_type": "enhancement", 187 - "title": "Add custom CA certificate bundle support", 188 - "description": "Curl allows users to specify custom CA certificate bundles via CURLOPT_CAINFO and CURLOPT_CAPATH for validating server certificates. While the library uses ca-certs package for system certificates, add explicit support for custom CA bundles to handle self-signed certificates, internal CAs, and testing scenarios. Extend the TLS configuration to accept custom certificate files or directories.", 189 - "affected_files": [ 190 - "lib/requests.ml", 191 - "lib/requests.mli", 192 - "lib/one.ml", 193 - "lib/one.mli" 194 - ], 195 - "rationale": "Many internal corporate services use private certificate authorities or self-signed certificates. Development and testing environments often use non-public CAs. While the library allows disabling verification, providing custom CA support enables secure connections to these services. This is a common requirement for enterprise HTTP clients and testing scenarios." 196 - }, 197 - { 198 - "source_repo": "third_party/bash-shell/curl", 199 - "source_language": "C", 200 - "criticality": "low", 201 - "change_type": "enhancement", 202 - "title": "Add connection timeout separate from other timeout types", 203 - "description": "The library currently has connect timeout (default: 10s) in Timeout.t. Curl additionally provides millisecond precision for all timeouts (CURLOPT_CONNECTTIMEOUT_MS, CURLOPT_TIMEOUT_MS) and distinguishes DNS resolution timeout from TCP connection timeout. Consider adding millisecond precision to all timeout values and potentially separating DNS resolution timeout from TCP connection timeout for finer-grained control.", 204 - "affected_files": [ 205 - "lib/timeout.ml", 206 - "lib/timeout.mli", 207 - "lib/http_client.ml" 208 - ], 209 - "rationale": "While second-precision timeouts are sufficient for most use cases, some applications need millisecond-level control (real-time systems, high-frequency trading, performance testing). The Eio time primitives already support subsecond precision. Separating DNS timeout from TCP timeout helps distinguish DNS infrastructure issues from server availability issues. This provides more precise timeout control." 210 - }, 211 - { 212 - "source_repo": "third_party/bash-shell/curl", 213 - "source_language": "C", 214 - "criticality": "low", 215 - "change_type": "enhancement", 216 - "title": "Add support for Unix domain socket connections", 217 - "description": "Curl supports connecting to HTTP servers over Unix domain sockets via CURLOPT_UNIX_SOCKET_PATH, commonly used for Docker daemon, Podman, and local service communication. Eio supports Unix domain sockets through its network abstraction. Add support for unix:// URLs or an explicit unix_socket_path parameter to enable local socket-based HTTP communication.", 218 - "affected_files": [ 219 - "lib/http_client.ml", 220 - "lib/requests.ml", 221 - "lib/one.ml" 222 - ], 223 - "rationale": "Unix domain sockets are commonly used for local service communication (Docker API, systemd services, local databases). They provide better performance and security than TCP for local communication. Eio's network abstraction already supports Unix sockets, making this primarily a URL parsing and connection establishment change. This would enable the library to communicate with local containerized services." 224 - }, 225 - { 226 - "source_repo": "third_party/bash-shell/curl", 227 - "source_language": "C", 228 - "criticality": "low", 229 - "change_type": "enhancement", 230 - "title": "Add interface/source IP binding support", 231 - "description": "Curl supports binding to specific network interfaces or source IP addresses via CURLOPT_INTERFACE, useful for multi-homed systems or VPN scenarios. Add optional parameters to specify the source interface or local IP address for outbound connections, leveraging Eio's network binding capabilities.", 232 - "affected_files": [ 233 - "lib/http_client.ml", 234 - "lib/requests.ml", 235 - "lib/one.ml" 236 - ], 237 - "rationale": "Multi-homed systems (multiple network interfaces) and VPN users need to control which interface is used for connections. This is also useful for testing and network troubleshooting. While not commonly needed, this is a straightforward addition given Eio's network abstraction and provides advanced routing control for specialized use cases." 238 - }, 239 - { 240 - "source_repo": "third_party/bash-shell/curl", 241 - "source_language": "C", 242 - "criticality": "medium", 243 - "change_type": "enhancement", 244 - "title": "Enhance retry logic with exponential backoff ceiling and jitter improvements", 245 - "description": "The library has excellent retry support with exponential backoff and jitter. Curl's approach includes per-error-type retry strategies and more sophisticated backoff calculations. Consider adding: (1) configurable backoff ceiling (already present as backoff_max), (2) different backoff strategies (linear, exponential, fibonacci), (3) per-error-type retry configuration (different retries for DNS vs timeout vs 503), and (4) circuit breaker pattern to stop retrying a failing service.", 246 - "affected_files": [ 247 - "lib/retry.ml", 248 - "lib/retry.mli", 249 - "lib/error.ml" 250 - ], 251 - "rationale": "The current retry implementation is solid but could benefit from more sophisticated strategies seen in production systems. Circuit breaker pattern prevents cascading failures when a service is down. Per-error-type configuration allows fine-tuning (retry DNS failures more than auth failures). Different backoff strategies suit different failure modes. These enhancements would improve the library's production readiness." 252 - }, 253 - { 254 - "source_repo": "third_party/bash-shell/curl", 255 - "source_language": "C", 256 - "criticality": "low", 257 - "change_type": "enhancement", 258 - "title": "Add detailed connection metrics and timing information", 259 - "description": "Curl provides detailed timing information via CURLINFO_* constants (DNS lookup time, TLS handshake time, time to first byte, total time, etc.). Add a metrics/timing module that tracks and exposes: DNS resolution duration, TCP connection duration, TLS handshake duration, time to first byte, transfer duration, and total request duration. Include this in Response.t or a separate Metrics.t type.", 260 - "affected_files": [ 261 - "lib/response.ml", 262 - "lib/response.mli", 263 - "lib/http_client.ml" 264 - ], 265 - "rationale": "Performance monitoring and debugging require detailed timing breakdowns. Knowing whether slowness is in DNS, TLS handshake, or server processing is critical for optimization. Many production systems track these metrics for monitoring and alerting. The library already uses Eio's time primitives, making timing capture straightforward. This would significantly improve observability for production deployments." 266 - }, 267 - { 268 - "source_repo": "third_party/bash-shell/curl", 269 - "source_language": "C", 270 - "criticality": "low", 271 - "change_type": "enhancement", 272 - "title": "Add HTTP/2 server push support", 273 - "description": "While HTTP/2 implementation is complex, curl's HTTP/2 support includes server push handling (lib/http2.c). If/when the library adds HTTP/2 support via an OCaml HTTP/2 library, ensure server push frames are properly handled. Document how pushed resources can be accessed or cached for subsequent requests.", 274 - "affected_files": [ 275 - "lib/http_client.ml", 276 - "lib/requests.ml", 277 - "lib/response.ml" 278 - ], 279 - "rationale": "HTTP/2 server push can significantly improve page load times by proactively sending resources. While HTTP/2 support is a major feature addition, documenting the intended approach for server push ensures the architecture can accommodate it. This is forward-looking but important for planning HTTP/2 integration. Note: This is lower priority until HTTP/2 support itself is implemented." 280 - }, 281 - { 282 - "source_repo": "third_party/bash-shell/curl", 283 - "source_language": "C", 284 - "criticality": "low", 285 - "change_type": "enhancement", 286 - "title": "Add support for HTTP trailers in chunked encoding", 287 - "description": "Curl supports HTTP trailers (headers sent after the chunked body). Trailers are used for checksums, signatures, or metadata computed during transfer. Ensure Http_read.chunked_body correctly parses trailers after the final chunk and exposes them via Response. Consider adding Response.trailers to access these post-body headers.", 288 - "affected_files": [ 289 - "lib/http_read.ml", 290 - "lib/http_read.mli", 291 - "lib/response.ml", 292 - "lib/response.mli" 293 - ], 294 - "rationale": "HTTP trailers are part of the HTTP/1.1 specification (RFC 9110) and used by some APIs for integrity checks (content digests, signatures computed over the body). While uncommon, proper trailer support ensures full HTTP/1.1 compliance. The chunked encoding parser should already encounter trailers, making this primarily an exposure issue. This improves standards compliance." 295 - } 296 - ] 297 - }
-268
third_party/bash-shell/http-prompt.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/bash-shell/http-prompt", 5 - "source_language": "Python", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add session persistence and context save/load functionality", 9 - "description": "Implement the ability to save and restore HTTP session state (URL, headers, cookies, auth, timeout config) to/from disk. HTTP-prompt automatically persists context to XDG data directory after each mutation, allowing users to resume sessions across CLI invocations. The OCaml library has cookie persistence but lacks comprehensive session state persistence.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/requests.mli" 13 - ], 14 - "rationale": "HTTP-prompt's contextio.py automatically saves session context (headers, query params, body params, options) to ~/.local/share/http-prompt/context.hp and reloads on startup. This enables workflow continuity across sessions. The OCaml library already has XDG support and cookie persistence via Cookeio, but lacks API for saving/loading full session configuration. Adding save_session() and load_session() functions would improve developer experience for long-running API testing and debugging workflows." 15 - }, 16 - { 17 - "source_repo": "third_party/bash-shell/http-prompt", 18 - "source_language": "Python", 19 - "criticality": "low", 20 - "change_type": "enhancement", 21 - "title": "Add configurable cookie handling modes (auto/ask/off)", 22 - "description": "HTTP-prompt supports three cookie modes: 'auto' (automatically set cookies from responses), 'ask' (prompt user), and 'off' (ignore). The OCaml library currently has binary persist_cookies flag but always auto-sets cookies when enabled. Add an enum to control cookie acceptance behavior.", 23 - "affected_files": [ 24 - "lib/requests.ml", 25 - "lib/requests.mli" 26 - ], 27 - "rationale": "HTTP-prompt's ExecutionListener (cli.py:59-70) implements configurable cookie handling with set_cookies preference. Users can control whether cookies are automatically set, require confirmation, or ignored entirely. This is useful for security-sensitive workflows where automatic cookie acceptance may be undesirable. The OCaml library's current binary approach (persist_cookies: bool) doesn't allow fine-grained control. Adding a cookie_policy type with variants Auto | Manual | Off would enhance security and user control." 28 - }, 29 - { 30 - "source_repo": "third_party/bash-shell/http-prompt", 31 - "source_language": "Python", 32 - "criticality": "medium", 33 - "change_type": "feature", 34 - "title": "Add request/response event hooks or listeners", 35 - "description": "HTTP-prompt uses an ExecutionListener pattern (cli.py:50-70) with callbacks for context_changed and response_returned events. This enables extensibility for logging, metrics collection, response processing, and cookie handling. Add similar hooks to the OCaml library to allow users to inject custom behavior at request/response lifecycle events.", 36 - "affected_files": [ 37 - "lib/requests.ml", 38 - "lib/requests.mli" 39 - ], 40 - "rationale": "HTTP-prompt's listener pattern decouples concerns like cookie extraction, context persistence, and response handling from core HTTP logic. The pattern allows users to hook into request/response lifecycle without modifying library internals. The OCaml library lacks extensibility points - all behavior is hardcoded. Adding optional callbacks (e.g., ~on_request_start, ~on_response_received, ~on_retry_attempt) would enable metrics collection, custom logging, response caching, and automated testing without forking the library." 41 - }, 42 - { 43 - "source_repo": "third_party/bash-shell/http-prompt", 44 - "source_language": "Python", 45 - "criticality": "low", 46 - "change_type": "enhancement", 47 - "title": "Add URL auto-correction and normalization helpers", 48 - "description": "HTTP-prompt includes fix_incomplete_url() (cli.py:33-40) that auto-corrects common URL mistakes: 's://' -> 'https://', '://' -> 'http://', '//' -> 'http://', and missing protocol. Add similar normalization to the OCaml library to improve ergonomics.", 49 - "affected_files": [ 50 - "lib/requests.ml", 51 - "lib/one.ml" 52 - ], 53 - "rationale": "HTTP-prompt's URL normalization (cli.py:33-40) handles common user errors gracefully, reducing friction in interactive usage. For example, 'example.com' becomes 'http://example.com', '//api.github.com' becomes 'http://api.github.com'. The OCaml library currently requires fully-formed URLs or fails with Uri parsing errors. Adding a normalize_url() helper function would improve API ergonomics, especially for CLI tools and REPL-style usage, while maintaining strict validation for security-critical contexts." 54 - }, 55 - { 56 - "source_repo": "third_party/bash-shell/http-prompt", 57 - "source_language": "Python", 58 - "criticality": "medium", 59 - "change_type": "enhancement", 60 - "title": "Improve error messages with request context and suggestions", 61 - "description": "HTTP-prompt provides detailed parse errors with context (execution.py:551-556) showing 'near N chars' and uses colored output (red for errors, yellow for warnings). Enhance the OCaml library's error messages to include more diagnostic context like the partial request that was being constructed, suggestions for fixes, and formatted output.", 62 - "affected_files": [ 63 - "lib/error.ml", 64 - "lib/error.mli" 65 - ], 66 - "rationale": "HTTP-prompt's error handling (execution.py:551-581) differentiates error types (ParseError, VisitationError, CalledProcessError) and provides context-specific messages with colored output for visual distinction. The OCaml library has comprehensive error types in Error.ml but messages could be more helpful with diagnostic context. For instance, URL parsing errors could suggest corrections, timeout errors could indicate which operation timed out with duration, and authentication errors could explain what credentials are needed. Adding error_hints field to error types would improve debuggability." 67 - }, 68 - { 69 - "source_repo": "third_party/bash-shell/http-prompt", 70 - "source_language": "Python", 71 - "criticality": "low", 72 - "change_type": "enhancement", 73 - "title": "Add support for loading environment/configuration files", 74 - "description": "HTTP-prompt supports --env flag (cli.py:84, 143-144) to preload context from a file, enabling environment-specific configurations (dev/staging/prod). The library could provide a function to load request configuration from files (JSON, S-expressions, or OCaml format).", 75 - "affected_files": [ 76 - "lib/requests.ml", 77 - "lib/requests.mli" 78 - ], 79 - "rationale": "HTTP-prompt's env file support (cli.py:143-147) allows users to maintain environment-specific configurations (different base URLs, auth tokens, headers for dev/staging/prod). The OCaml library lacks configuration file support - users must hardcode settings or manually construct session objects. Adding load_config_from_file() that parses JSON/YAML/S-expressions into session configuration would support environment-based workflows common in modern API development. This pairs well with the session persistence feature." 80 - }, 81 - { 82 - "source_repo": "third_party/bash-shell/http-prompt", 83 - "source_language": "Python", 84 - "criticality": "low", 85 - "change_type": "feature", 86 - "title": "Add OpenAPI/Swagger spec support for validation and completion", 87 - "description": "HTTP-prompt supports loading OpenAPI/Swagger specs (cli.py:103-117) to populate URL base paths, extract endpoints, parse parameters, and enable intelligent completion. The OCaml library could validate requests against OpenAPI specs or generate client functions from specs.", 88 - "affected_files": [ 89 - "lib/requests.ml", 90 - "lib/requests.mli" 91 - ], 92 - "rationale": "HTTP-prompt's OpenAPI support (cli.py:103-117, context/__init__.py:6-72) parses spec files (JSON/YAML) to build a tree of endpoints and parameters, enabling context-aware completions and validation. The OCaml library has no schema validation or spec-based client generation. While full OpenAPI support may be out of scope for a low-level HTTP library, providing hooks or utilities for spec validation (e.g., validate_against_spec()) would benefit users building API clients. This could be a separate library that depends on ocaml-requests." 93 - }, 94 - { 95 - "source_repo": "third_party/bash-shell/http-prompt", 96 - "source_language": "Python", 97 - "criticality": "medium", 98 - "change_type": "enhancement", 99 - "title": "Add output redirection and streaming helpers", 100 - "description": "HTTP-prompt supports output redirection to files (>, >>), piping to shell commands (|), and pagination. The OCaml library has streaming via Body.of_stream and progress callbacks, but lacks high-level helpers for common output patterns like writing responses to files with progress indication.", 101 - "affected_files": [ 102 - "lib/response.ml", 103 - "lib/response.mli", 104 - "lib/one.ml" 105 - ], 106 - "rationale": "HTTP-prompt's output handling (output.py, execution.py:57) provides Printer wrapper for pagination and TextWriter for file I/O, supporting redirection patterns (>, >>, |) familiar to shell users. The OCaml library has low-level streaming (Body.of_stream, progress callbacks in one.ml:336-370) but lacks high-level convenience functions. Adding Response.to_file ~path ~mode:[`Write|`Append] ~progress and Response.pipe_to ~command would improve ergonomics for CLI tools and download use cases, matching the shell-like UX that http-prompt users expect." 107 - }, 108 - { 109 - "source_repo": "third_party/bash-shell/http-prompt", 110 - "source_language": "Python", 111 - "criticality": "low", 112 - "change_type": "enhancement", 113 - "title": "Add request/response format export utilities", 114 - "description": "HTTP-prompt can export context to different formats: HTTPie commands, HTTP Prompt format, and cURL commands (context/transform.py). The OCaml library could provide utilities to convert Request/Response objects to cURL, HTTPie, or raw HTTP format for debugging and documentation.", 115 - "affected_files": [ 116 - "lib/requests.ml", 117 - "lib/response.ml" 118 - ], 119 - "rationale": "HTTP-prompt's transform module (context/transform.py) provides format_to_httpie(), format_to_http_prompt(), and format_to_curl() for converting session context to executable commands. This is invaluable for debugging, documentation generation, and sharing reproducible test cases. The OCaml library lacks export utilities - users must manually reconstruct requests. Adding Request.to_curl() and Request.to_http() formatters would aid debugging and enable copy-paste reproduction of requests in different tools, improving developer experience." 120 - }, 121 - { 122 - "source_repo": "third_party/bash-shell/http-prompt", 123 - "source_language": "Python", 124 - "criticality": "low", 125 - "change_type": "enhancement", 126 - "title": "Add default User-Agent with library version", 127 - "description": "While the OCaml library supports custom User-Agent headers (headers.ml:116, requests.ml:713), it doesn't set a default identifying string like 'ocaml-requests/0.1.0'. HTTP clients typically identify themselves to aid server-side debugging and analytics.", 128 - "affected_files": [ 129 - "lib/headers.ml", 130 - "lib/requests.ml" 131 - ], 132 - "rationale": "HTTP-prompt delegates to HTTPie which sets a User-Agent like 'HTTPie/3.2.2'. Most HTTP libraries set identifying User-Agent headers by default (e.g., Python requests uses 'python-requests/2.28.1'). The OCaml library has User-Agent support (headers.ml:116) and Cmdliner argument (requests.ml:766) but no default value, sending requests without identification. Adding a default like 'ocaml-requests/0.1.0 (Eio; OCaml)' would help server operators identify clients, aid debugging, and follow HTTP best practices. Users can still override via default_headers or per-request." 133 - }, 134 - { 135 - "source_repo": "third_party/bash-shell/http-prompt", 136 - "source_language": "Python", 137 - "criticality": "medium", 138 - "change_type": "enhancement", 139 - "title": "Add request history tracking and replay", 140 - "description": "HTTP-prompt uses prompt_toolkit's FileHistory (cli.py:128) to persist command history across sessions. The OCaml library could track request history in-memory (and optionally persist) to enable request replay, debugging, and testing workflows.", 141 - "affected_files": [ 142 - "lib/requests.ml", 143 - "lib/requests.mli" 144 - ], 145 - "rationale": "HTTP-prompt's history integration (cli.py:128) allows users to recall and replay previous requests with arrow keys, improving interactive workflows. The OCaml library session (Requests.t) tracks basic statistics (requests_made, total_time, retries_count in requests.ml:69-71) but doesn't maintain request/response history. Adding optional history tracking (e.g., ~max_history:int parameter, get_history() function returning (Request.t * Response.t) list) would enable debugging, request replay, and audit logging. History could be in-memory by default with optional persistence via XDG." 146 - }, 147 - { 148 - "source_repo": "third_party/bash-shell/http-prompt", 149 - "source_language": "Python", 150 - "criticality": "low", 151 - "change_type": "enhancement", 152 - "title": "Add mutation tracking and context diff capabilities", 153 - "description": "HTTP-prompt tracks context mutations (headers, params, options) and can show what changed. The OCaml library could provide utilities to compare two session states or track changes to configuration over the session lifetime.", 154 - "affected_files": [ 155 - "lib/requests.ml", 156 - "lib/requests.mli" 157 - ], 158 - "rationale": "HTTP-prompt's context model (context/__init__.py:76-104) implements copy(), update(), and equality checking, enabling state tracking and diff visualization. The library persists changes after mutations (contextio.py:33-38). The OCaml library's Requests.t is immutable (returns new sessions on configuration changes) but lacks comparison utilities. Adding Session.diff : t -> t -> changes that returns a structured representation of differences would help debugging configuration issues and understanding how session state evolved, especially useful for CLI tools and testing frameworks." 159 - }, 160 - { 161 - "source_repo": "third_party/bash-shell/http-prompt", 162 - "source_language": "Python", 163 - "criticality": "low", 164 - "change_type": "enhancement", 165 - "title": "Add request builder with method chaining", 166 - "description": "While the OCaml library has excellent functional composition via labeled arguments, adding an explicit Request builder type with method chaining (e.g., Request.create() |> with_header |> with_timeout |> with_body) could improve ergonomics for complex requests.", 167 - "affected_files": [ 168 - "lib/requests.ml", 169 - "lib/requests.mli" 170 - ], 171 - "rationale": "HTTP-prompt builds requests incrementally via mutations (execution.py:190-200, context/__init__.py:95-104), accumulating headers, params, and options before execution. The OCaml library uses labeled arguments which is idiomatic but can be verbose for complex requests with many parameters. Adding a Request.t builder type (separate from execution) with chainable functions would improve readability for multi-step request construction, similar to how HTTP-prompt accumulates context. This could complement, not replace, the existing API." 172 - }, 173 - { 174 - "source_repo": "third_party/bash-shell/http-prompt", 175 - "source_language": "Python", 176 - "criticality": "high", 177 - "change_type": "security", 178 - "title": "Add request size limits and validation", 179 - "description": "HTTP-prompt inherits HTTPie's request size handling. The OCaml library has response limits (Response_limits.t) but no corresponding request size limits. Add validation for maximum request header size, header count, and body size to prevent client-side resource exhaustion and detect configuration errors.", 180 - "affected_files": [ 181 - "lib/requests.ml", 182 - "lib/headers.ml", 183 - "lib/body.ml" 184 - ], 185 - "rationale": "The OCaml library has comprehensive response limits (Response_limits.t with max_body_size, max_header_size, max_headers) to prevent DoS attacks from malicious servers, but lacks corresponding request limits. Large request bodies or excessive headers could exhaust client memory or violate server limits. Adding request_limits configuration (max_request_body_size, max_request_headers) would prevent accidental resource exhaustion, especially important for applications that construct requests from user input. This mirrors the defensive approach already present for responses." 186 - }, 187 - { 188 - "source_repo": "third_party/bash-shell/http-prompt", 189 - "source_language": "Python", 190 - "criticality": "medium", 191 - "change_type": "enhancement", 192 - "title": "Add URL query parameter helpers with proper encoding", 193 - "description": "HTTP-prompt has sophisticated query parameter handling (context/__init__.py:9, execution.py with == operator). The OCaml library uses ~params:(string * string) list but lacks helpers for URL encoding, array parameters, or nested objects. Add utility functions for common query param patterns.", 194 - "affected_files": [ 195 - "lib/requests.ml", 196 - "lib/requests.mli" 197 - ], 198 - "rationale": "HTTP-prompt supports querystring_params dictionary with proper URL encoding. The OCaml library's ~params accepts pre-encoded string tuples but provides no encoding helpers or support for array parameters (e.g., ids[]=1&ids[]=2) or nested objects common in modern APIs. Adding Params module with functions like encode_array, encode_nested, to_query_string would reduce boilerplate and prevent encoding errors. The library uses Uri which has query support, but exposing higher-level helpers would improve ergonomics." 199 - }, 200 - { 201 - "source_repo": "third_party/bash-shell/http-prompt", 202 - "source_language": "Python", 203 - "criticality": "low", 204 - "change_type": "enhancement", 205 - "title": "Add request method override support (X-HTTP-Method-Override)", 206 - "description": "Some APIs and proxies require method override headers for PUT/PATCH/DELETE requests sent as POST with X-HTTP-Method-Override header. Add helper or automatic support for this pattern.", 207 - "affected_files": [ 208 - "lib/requests.ml", 209 - "lib/headers.ml" 210 - ], 211 - "rationale": "HTTP-prompt can set any header including X-HTTP-Method-Override, but doesn't provide special handling. Some HTTP libraries (like Python requests) have dedicated support for method override patterns used by Rails, Django, and corporate proxies that block certain methods. While the OCaml library can set this header manually, adding Request.with_method_override : Method.t -> t -> t that automatically sets the header and changes method to POST would improve ergonomics for APIs that require this pattern, improving compatibility with legacy systems." 212 - }, 213 - { 214 - "source_repo": "third_party/bash-shell/http-prompt", 215 - "source_language": "Python", 216 - "criticality": "low", 217 - "change_type": "enhancement", 218 - "title": "Add support for .netrc authentication", 219 - "description": "HTTP-prompt and many HTTP clients support .netrc files for storing credentials per host. The OCaml library has a TODO comment (one.ml:14) about .netrc support. Implement automatic credential lookup from ~/.netrc for matching hosts.", 220 - "affected_files": [ 221 - "lib/auth.ml", 222 - "lib/requests.ml", 223 - "lib/one.ml" 224 - ], 225 - "rationale": "The OCaml library has a TODO comment about .netrc support (one.ml:14) in the context of re-acquiring auth credentials after redirects. .netrc is a standard Unix mechanism for storing machine-specific credentials, supported by curl, HTTPie, and many HTTP libraries. Adding automatic .netrc lookup would improve ergonomics for authenticated requests without hardcoding credentials, especially useful for CLI tools. Implementation could use ocaml-netrc library or custom parser, with opt-in via ~use_netrc:bool parameter to avoid surprise credential leakage." 226 - }, 227 - { 228 - "source_repo": "third_party/bash-shell/http-prompt", 229 - "source_language": "Python", 230 - "criticality": "medium", 231 - "change_type": "enhancement", 232 - "title": "Add idempotency key generation for safe retries", 233 - "description": "For POST/PATCH requests with retry enabled, automatically generate and include an Idempotency-Key header to prevent duplicate operations when requests are retried. This is crucial for financial/e-commerce APIs.", 234 - "affected_files": [ 235 - "lib/retry.ml", 236 - "lib/headers.ml", 237 - "lib/requests.ml" 238 - ], 239 - "rationale": "HTTP-prompt's retry logic (inherited from HTTPie/requests) retries on configured status codes but doesn't handle idempotency for non-idempotent methods. The OCaml library's retry config excludes POST by default (retry.ml:24) to avoid duplicate operations, but this prevents useful retry scenarios. Many modern APIs support Idempotency-Key headers (Stripe, GitHub, etc.) to safely retry POST/PATCH. Adding ~generate_idempotency_key:bool parameter that auto-generates and attaches unique UUIDs for retried non-idempotent requests would enable safe retry without API-level duplicate risk, expanding retry applicability." 240 - }, 241 - { 242 - "source_repo": "third_party/bash-shell/http-prompt", 243 - "source_language": "Python", 244 - "criticality": "low", 245 - "change_type": "feature", 246 - "title": "Add request/response interceptor chain", 247 - "description": "Beyond simple lifecycle hooks, implement a full interceptor chain pattern where multiple interceptors can modify requests before sending and responses after receiving, enabling middleware-like functionality (logging, auth injection, response transformation).", 248 - "affected_files": [ 249 - "lib/requests.ml", 250 - "lib/requests.mli" 251 - ], 252 - "rationale": "HTTP-prompt's ExecutionListener provides basic hooks but HTTP-prompt's architecture doesn't have full middleware chains. However, many HTTP libraries (Axios, OkHttp) implement interceptor patterns for cross-cutting concerns. The OCaml library could benefit from interceptor chains that transform Request.t -> Request.t before sending and Response.t -> Response.t after receiving. This would enable: automatic auth token refresh, request signing, response caching, custom error handling, metrics collection, and request/response logging - all without modifying core library code. Implemented as optional ~interceptors:(interceptor list) parameter." 253 - }, 254 - { 255 - "source_repo": "third_party/bash-shell/http-prompt", 256 - "source_language": "Python", 257 - "criticality": "medium", 258 - "change_type": "enhancement", 259 - "title": "Add response content sniffing and auto-parsing", 260 - "description": "HTTP-prompt uses HTTPie which auto-detects JSON responses even without proper Content-Type headers. The OCaml library's Response.json() requires proper headers or fails. Add lenient parsing mode that attempts JSON/XML detection via content sniffing when Content-Type is missing or incorrect.", 261 - "affected_files": [ 262 - "lib/response.ml", 263 - "lib/mime.ml" 264 - ], 265 - "rationale": "HTTP-prompt benefits from HTTPie's lenient content-type handling which attempts JSON parsing even when servers send incorrect Content-Type (e.g., 'text/plain' for JSON). The OCaml library's Response.json() strictly uses Content-Type header (response.ml:209-220). Many APIs have incorrect Content-Type headers. Adding Response.json_lenient() that attempts parsing regardless of headers, or ~strict:bool parameter to existing json(), would improve robustness when dealing with misconfigured servers. Content sniffing could check for leading '{' or '[' characters as simple heuristic." 266 - } 267 - ] 268 - }
-271
third_party/bash-shell/httpie.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/bash-shell/httpie", 5 - "source_language": "Python", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add download progress tracking with resume capability", 9 - "description": "HTTPie implements sophisticated download features including: (1) Progress display with rich console UI showing download speed and ETA, (2) Resume capability using Range headers with Content-Range validation, (3) Automatic filename extraction from Content-Disposition headers, (4) Unique filename generation to prevent overwrites. The OCaml library currently lacks these download-specific features.", 10 - "affected_files": [ 11 - "lib/one.mli", 12 - "lib/one.ml", 13 - "lib/http_client.ml" 14 - ], 15 - "rationale": "HTTPie's downloads.py (lines 162-305) demonstrates a complete download workflow: it validates Content-Range headers, tracks download progress, handles resume with byte-range requests, and manages partial downloads. This is valuable for CLI tools and applications downloading large files. The OCaml library has One.download but lacks progress callbacks, resume capability, and Content-Range parsing. Adding these features would enable users to build robust download tools similar to wget/curl." 16 - }, 17 - { 18 - "source_repo": "third_party/bash-shell/httpie", 19 - "source_language": "Python", 20 - "criticality": "low", 21 - "change_type": "feature", 22 - "title": "Add offline mode for request building without sending", 23 - "description": "HTTPie supports an --offline flag that builds and displays the complete HTTP request without actually sending it. This is valuable for debugging request construction, validating authentication headers, and understanding what will be sent to the server.", 24 - "affected_files": [ 25 - "lib/requests.mli", 26 - "lib/requests.ml", 27 - "lib/one.mli", 28 - "lib/one.ml" 29 - ], 30 - "rationale": "HTTPie's offline mode (definition.py line 709-713) allows users to inspect the exact HTTP request that would be sent, including all headers, authentication, and body content. This is particularly useful for debugging API integrations and validating request construction. The OCaml library could add a 'dry_run' or 'prepare_request' function that returns a representation of the request without executing it, enabling similar debugging workflows." 31 - }, 32 - { 33 - "source_repo": "third_party/bash-shell/httpie", 34 - "source_language": "Python", 35 - "criticality": "medium", 36 - "change_type": "enhancement", 37 - "title": "Add configurable SSL cipher suite selection", 38 - "description": "HTTPie allows users to specify custom SSL cipher suites via --ciphers flag for security hardening or compatibility with specific servers. It also provides introspection to show the default cipher list being used.", 39 - "affected_files": [ 40 - "lib/requests.mli", 41 - "lib/requests.ml" 42 - ], 43 - "rationale": "HTTPie's ssl_.py (lines 88-109) exposes cipher configuration and provides get_default_ciphers_names() for transparency. The OCaml library uses Tls.Config.client which supports cipher configuration, but doesn't expose a convenient API for users to specify cipher suites. Adding a ~ciphers parameter to the create function (accepting a list of TLS cipher suites) would enable users to: (1) Enforce strong ciphers for security, (2) Enable weak ciphers for legacy systems, (3) Debug TLS handshake issues. This is particularly valuable in enterprise environments with specific security requirements." 44 - }, 45 - { 46 - "source_repo": "third_party/bash-shell/httpie", 47 - "source_language": "Python", 48 - "criticality": "medium", 49 - "change_type": "feature", 50 - "title": "Add encrypted private key passphrase support for client certificates", 51 - "description": "HTTPie detects encrypted private keys and prompts for passphrases interactively. It includes _is_key_file_encrypted() to check for 'ENCRYPTED' markers in PEM files and supports the --cert-key-pass flag.", 52 - "affected_files": [ 53 - "lib/requests.mli", 54 - "lib/requests.ml" 55 - ], 56 - "rationale": "HTTPie's ssl_.py (lines 92-103, 886-896) demonstrates handling encrypted private keys by: (1) Detecting encryption via PEM file inspection, (2) Prompting for passphrases interactively, (3) Passing key_password to the SSL context. The OCaml library's TLS configuration supports client certificates but doesn't expose passphrase handling. Users with encrypted private keys currently cannot use client certificate authentication. Adding support would involve: (1) Accepting an optional ~cert_key_password parameter, (2) Passing it through to the TLS configuration, (3) Potentially adding automatic detection and prompting for CLI tools." 57 - }, 58 - { 59 - "source_repo": "third_party/bash-shell/httpie", 60 - "source_language": "Python", 61 - "criticality": "medium", 62 - "change_type": "enhancement", 63 - "title": "Add session file ignored header prefixes configuration", 64 - "description": "HTTPie automatically excludes request-specific headers from session persistence using SESSION_IGNORED_HEADER_PREFIXES = ['Content-', 'If-']. This prevents Content-Length, Content-Type, If-Modified-Since, and other request-specific headers from being persisted and reused inappropriately.", 65 - "affected_files": [ 66 - "lib/requests.ml" 67 - ], 68 - "rationale": "HTTPie's sessions.py (lines 32-35, 222-226) demonstrates careful header filtering to avoid session pollution. Headers like Content-Length and Content-Type are request-specific and should not be reused across different requests. The OCaml library persists cookies and could persist headers, but doesn't document or implement header filtering. While the library currently doesn't persist headers to disk by default, if this feature is added in the future, implementing ignored prefixes would prevent subtle bugs where request-specific headers contaminate subsequent requests." 69 - }, 70 - { 71 - "source_repo": "third_party/bash-shell/httpie", 72 - "source_language": "Python", 73 - "criticality": "low", 74 - "change_type": "enhancement", 75 - "title": "Add localhost special handling for secure cookies", 76 - "description": "HTTPie implements HTTPieCookiePolicy that treats 'localhost' and '.localhost' as secure contexts, allowing secure cookies to be set and sent to localhost during development. This aligns with modern browser behavior.", 77 - "affected_files": [ 78 - "lib/requests.ml" 79 - ], 80 - "rationale": "HTTPie's cookies.py demonstrates treating localhost as a secure context for cookie handling, which is important for local development with HTTPS APIs. The OCaml library uses Cookeio for cookie management but doesn't implement special localhost handling. This means secure cookies won't work with localhost HTTPS development servers. While this is a niche use case, it significantly improves developer experience when testing HTTPS-only APIs locally. The fix would involve customizing the cookie policy in Cookeio or wrapping it with localhost-aware logic." 81 - }, 82 - { 83 - "source_repo": "third_party/bash-shell/httpie", 84 - "source_language": "Python", 85 - "criticality": "medium", 86 - "change_type": "feature", 87 - "title": "Add max response header count and size limits", 88 - "description": "HTTPie supports --max-headers flag to limit the number of response headers before giving up, providing DoS protection against header bomb attacks. This complements existing response body size limits.", 89 - "affected_files": [ 90 - "lib/response_limits.mli", 91 - "lib/response_limits.ml", 92 - "lib/http_read.ml" 93 - ], 94 - "rationale": "HTTPie's definition.py (lines 747-755) allows users to configure maximum header count (default 0 = unlimited) to protect against malicious servers sending excessive headers. The OCaml library has Response_limits with max_header_size and max_header_count, but the implementation may not enforce max_header_count during HTTP parsing. HTTPie's approach of failing fast when header count exceeds limits prevents memory exhaustion. The OCaml library should ensure http_read.ml actually enforces max_header_count by counting headers during parsing and raising an error if exceeded, similar to how it handles max_header_size." 95 - }, 96 - { 97 - "source_repo": "third_party/bash-shell/httpie", 98 - "source_language": "Python", 99 - "criticality": "low", 100 - "change_type": "enhancement", 101 - "title": "Add --path-as-is flag to bypass URL path normalization", 102 - "description": "HTTPie supports --path-as-is flag to bypass dot segment (/../ or /./) URL squashing, allowing exact URL paths to be sent as specified. This is useful for testing servers with unusual path handling or exploiting path traversal issues in authorized penetration testing.", 103 - "affected_files": [ 104 - "lib/requests.mli", 105 - "lib/requests.ml", 106 - "lib/one.mli", 107 - "lib/one.ml" 108 - ], 109 - "rationale": "HTTPie's definition.py (lines 791-795) and client.py demonstrate optional path normalization control. Most HTTP clients normalize paths for security (/../ → /), but this can prevent testing certain edge cases. The OCaml library uses Uri for URL parsing which normalizes paths by default. Adding a ~normalize_path:bool parameter (default true) would enable users to: (1) Test servers with non-normalized paths, (2) Conduct authorized security testing, (3) Interact with non-compliant servers. This would require either using Uri.of_string with normalization disabled or manually preserving the original path." 110 - }, 111 - { 112 - "source_repo": "third_party/bash-shell/httpie", 113 - "source_language": "Python", 114 - "criticality": "medium", 115 - "change_type": "feature", 116 - "title": "Add request compression with automatic skip for negative compression ratio", 117 - "description": "HTTPie supports --compress/-x flag to compress request bodies with Deflate, automatically skipping compression if it would increase size. Repeated flag forces compression even if ratio is negative.", 118 - "affected_files": [ 119 - "lib/body.mli", 120 - "lib/body.ml", 121 - "lib/requests.mli" 122 - ], 123 - "rationale": "HTTPie's definition.py (lines 228-240) implements request compression with smart defaults. The OCaml library automatically decompresses responses but doesn't compress requests. Request compression is valuable for uploading large text data (JSON, XML, logs) to save bandwidth. HTTPie's approach of checking compression ratio and skipping if negative is elegant - it prevents wasting CPU on incompressible data. Implementation would involve: (1) Adding Body.compressed() constructor, (2) Detecting Content-Type to skip binary data, (3) Comparing compressed vs uncompressed size, (4) Setting Content-Encoding: deflate header." 124 - }, 125 - { 126 - "source_repo": "third_party/bash-shell/httpie", 127 - "source_language": "Python", 128 - "criticality": "low", 129 - "change_type": "enhancement", 130 - "title": "Add --check-status flag for CLI tools to exit with HTTP status-based error codes", 131 - "description": "HTTPie's --check-status flag makes the CLI exit with different codes based on HTTP status: 0 for success, 3 for 3xx redirects without --follow, 4 for 4xx errors, 5 for 5xx errors. This enables better shell scripting with HTTP clients.", 132 - "affected_files": [ 133 - "lib/requests.mli" 134 - ], 135 - "rationale": "HTTPie's definition.py (lines 774-788) and status.py demonstrate status-code-based exit codes for shell integration. The OCaml library is designed as a library, not a CLI tool, but applications built on it (like a hypothetical 'oreq' CLI) would benefit from a helper function to map Response.t to exit codes. Adding Response.to_exit_code : t -> int would enable CLI tools to: (1) Exit with appropriate codes for shell scripting, (2) Integrate with CI/CD pipelines, (3) Match curl/httpie behavior. This is low priority since it's primarily a CLI concern, but valuable for ecosystem completeness." 136 - }, 137 - { 138 - "source_repo": "third_party/bash-shell/httpie", 139 - "source_language": "Python", 140 - "criticality": "low", 141 - "change_type": "feature", 142 - "title": "Add verbose output modes for request/response inspection", 143 - "description": "HTTPie supports granular output control with --verbose/-v flag (levels 1-2) and --print/-p flag to control which parts are displayed: request headers (H), request body (B), response headers (h), response body (b), response metadata (m). This enables debugging and logging workflows.", 144 - "affected_files": [ 145 - "lib/requests.mli", 146 - "lib/response.mli" 147 - ], 148 - "rationale": "HTTPie's definition.py (lines 407-495) implements sophisticated output control for debugging. The OCaml library provides programmatic access to all request/response data but doesn't offer built-in verbose logging modes. While this is primarily a CLI feature, adding optional logging callbacks would enable: (1) Request/response logging for debugging, (2) Integration with application logging systems, (3) Audit trails for API calls. Low priority but useful for applications needing HTTP traffic visibility. Could be implemented via ~on_request and ~on_response callbacks." 149 - }, 150 - { 151 - "source_repo": "third_party/bash-shell/httpie", 152 - "source_language": "Python", 153 - "criticality": "low", 154 - "change_type": "enhancement", 155 - "title": "Add default scheme configuration for URL parsing", 156 - "description": "HTTPie supports --default-scheme to control whether URLs without schemes default to 'http' or 'https'. This is useful for security-conscious applications that want to default to HTTPS.", 157 - "affected_files": [ 158 - "lib/requests.mli", 159 - "lib/requests.ml", 160 - "lib/one.mli", 161 - "lib/one.ml" 162 - ], 163 - "rationale": "HTTPie's definition.py (lines 935-938) allows configuring the default scheme. The OCaml library uses Uri.of_string which may not add a scheme if missing, potentially causing errors. Adding a ~default_scheme parameter (or automatically defaulting to HTTPS for security) would: (1) Improve security by defaulting to HTTPS, (2) Reduce user error from forgetting scheme, (3) Match modern browser behavior. Implementation would check if Uri.scheme is None and add the default scheme before making the request." 164 - }, 165 - { 166 - "source_repo": "third_party/bash-shell/httpie", 167 - "source_language": "Python", 168 - "criticality": "medium", 169 - "change_type": "feature", 170 - "title": "Add localhost shorthand notation support", 171 - "description": "HTTPie supports convenient localhost shorthands: ':3000' expands to 'http://localhost:3000' and ':/foo' expands to 'http://localhost/foo'. This significantly improves developer ergonomics for local API testing.", 172 - "affected_files": [ 173 - "lib/requests.ml", 174 - "lib/one.ml" 175 - ], 176 - "rationale": "HTTPie's definition.py (lines 82-86) demonstrates localhost shorthand parsing that saves significant typing during development. When testing local APIs, developers frequently interact with localhost endpoints. The OCaml library could add URL preprocessing that detects ':port' or ':/path' patterns and expands them to 'http://localhost:port' or 'http://localhost/path'. This is particularly valuable for CLI tools and REPL usage. Implementation would involve a simple regex check before Uri.of_string parsing: if the URL starts with ':' followed by a digit or '/', prepend 'http://localhost'." 177 - }, 178 - { 179 - "source_repo": "third_party/bash-shell/httpie", 180 - "source_language": "Python", 181 - "criticality": "medium", 182 - "change_type": "enhancement", 183 - "title": "Improve error messages with DNS-specific guidance", 184 - "description": "HTTPie provides contextual error messages for DNS failures, distinguishing between EAI_AGAIN (DNS server unreachable, suggests checking connection) and EAI_NONAME (hostname doesn't exist, suggests checking URL). This helps users quickly diagnose common networking issues.", 185 - "affected_files": [ 186 - "lib/error.ml", 187 - "lib/http_client.ml" 188 - ], 189 - "rationale": "HTTPie's core.py (lines 124-137) demonstrates granular DNS error handling with user-friendly messages. The OCaml library has Error.Dns_resolution_failed but doesn't distinguish between different DNS failure modes. Enhancing the error variant to include a reason field and providing specific guidance would improve user experience: 'DNS server unreachable - check your internet connection' vs 'Hostname not found - check the URL'. This would involve catching and classifying Eio.Net exceptions during DNS resolution and mapping them to specific error messages." 190 - }, 191 - { 192 - "source_repo": "third_party/bash-shell/httpie", 193 - "source_language": "Python", 194 - "criticality": "low", 195 - "change_type": "feature", 196 - "title": "Add support for reading request body from stdin", 197 - "description": "HTTPie automatically reads request body from stdin when data is piped in, enabling workflows like 'cat data.json | http POST api.example.com'. It also supports --ignore-stdin to disable this behavior when needed.", 198 - "affected_files": [ 199 - "lib/body.mli", 200 - "lib/body.ml" 201 - ], 202 - "rationale": "HTTPie's stdin handling enables powerful Unix pipeline integration: 'jq . data.json | http POST api.example.com'. While the OCaml library is primarily a library (not CLI), adding Body.of_stdin() or Body.of_flow(Eio.stdin) would enable CLI tools built on this library to support similar workflows. This is low priority since it's a CLI-specific feature, but valuable for ecosystem completeness. Implementation would simply wrap stdin as a flow source with chunked encoding." 203 - }, 204 - { 205 - "source_repo": "third_party/bash-shell/httpie", 206 - "source_language": "Python", 207 - "criticality": "high", 208 - "change_type": "security", 209 - "title": "Add protection against gzip/deflate decompression bombs in chunked responses", 210 - "description": "HTTPie and the OCaml library both handle decompression, but the OCaml library's decompression bomb protection (max_compression_ratio in Response_limits) may not be enforced for chunked transfer encoding where Content-Length is unknown. Need to track decompressed size during streaming.", 211 - "affected_files": [ 212 - "lib/http_read.ml", 213 - "lib/response_limits.ml" 214 - ], 215 - "rationale": "Decompression bombs are a serious security risk where a small compressed payload expands to gigabytes of data, causing DoS. The OCaml library has Response_limits.max_compression_ratio (default 100:1) but this protection relies on knowing Content-Length upfront. For chunked responses without Content-Length, the library needs to track decompressed bytes during streaming and abort if the ratio exceeds limits. HTTPie faces similar challenges. The fix would involve: (1) Tracking compressed bytes read and decompressed bytes written during streaming, (2) Computing the ratio incrementally, (3) Raising Error.Decompression_bomb when ratio exceeds max_compression_ratio, even for chunked responses." 216 - }, 217 - { 218 - "source_repo": "third_party/bash-shell/httpie", 219 - "source_language": "Python", 220 - "criticality": "low", 221 - "change_type": "enhancement", 222 - "title": "Add custom multipart boundary support", 223 - "description": "HTTPie supports --boundary flag to specify custom multipart form-data boundaries. This is useful for testing server implementations, reproducing specific bugs, or matching requests from other clients.", 224 - "affected_files": [ 225 - "lib/body.mli", 226 - "lib/body.ml" 227 - ], 228 - "rationale": "HTTPie's definition.py (lines 194-199) allows custom boundary specification for multipart requests. The OCaml library generates random boundaries internally. While auto-generated boundaries are sufficient for normal use, custom boundaries are valuable for: (1) Reproducing exact requests for debugging, (2) Testing server boundary parsing edge cases, (3) Matching requests from other systems. Adding an optional ~boundary parameter to Body.multipart would enable these use cases. Implementation would pass the custom boundary to the multipart encoder instead of generating one." 229 - }, 230 - { 231 - "source_repo": "third_party/bash-shell/httpie", 232 - "source_language": "Python", 233 - "criticality": "medium", 234 - "change_type": "enhancement", 235 - "title": "Add response charset override for terminal display", 236 - "description": "HTTPie supports --response-charset and --response-mime flags to override detected encoding/MIME type for display purposes. This helps when servers send incorrect Content-Type headers or encoding is detected incorrectly.", 237 - "affected_files": [ 238 - "lib/response.mli", 239 - "lib/response.ml" 240 - ], 241 - "rationale": "HTTPie's definition.py (lines 350-374) demonstrates charset/MIME overrides for handling broken server responses. Servers sometimes send incorrect Content-Type headers (e.g., 'text/plain' for JSON, wrong charset). The OCaml library relies on headers but doesn't provide override mechanisms. While the library correctly passes raw bytes to users, adding optional Response.text_with_encoding : encoding:string -> t -> string would help handle broken servers. This is particularly useful for CLI tools and applications scraping data from poorly-configured servers. Implementation would override charset detection when calling Response.text." 242 - }, 243 - { 244 - "source_repo": "third_party/bash-shell/httpie", 245 - "source_language": "Python", 246 - "criticality": "low", 247 - "change_type": "feature", 248 - "title": "Add HTTP/2 upgrade support and protocol version inspection", 249 - "description": "HTTPie supports HTTP/2 and provides visibility into the protocol version being used. This is increasingly important as HTTP/2 and HTTP/3 adoption grows.", 250 - "affected_files": [ 251 - "lib/response.mli", 252 - "lib/response.ml", 253 - "lib/http_client.ml" 254 - ], 255 - "rationale": "Modern HTTP clients should support HTTP/2 for performance benefits (multiplexing, header compression, server push). HTTPie uses the requests library which supports HTTP/2 via httpx backend. The OCaml library uses HTTP/1.1 over Eio sockets. Adding HTTP/2 support would involve: (1) Integrating h2 or ocaml-h2 library, (2) Negotiating protocol via ALPN during TLS handshake, (3) Exposing Response.http_version to show which protocol was used. This is lower priority but increasingly important for modern APIs. Some servers (especially Google APIs) perform significantly better with HTTP/2." 256 - }, 257 - { 258 - "source_repo": "third_party/bash-shell/httpie", 259 - "source_language": "Python", 260 - "criticality": "low", 261 - "change_type": "enhancement", 262 - "title": "Add plugin architecture for extensible authentication and formatters", 263 - "description": "HTTPie supports a plugin system allowing third-party authentication schemes, transport protocols, data converters, and output formatters. This enables ecosystem growth without modifying the core library.", 264 - "affected_files": [ 265 - "lib/requests.mli", 266 - "lib/auth.mli" 267 - ], 268 - "rationale": "HTTPie's plugins/ directory demonstrates a clean plugin architecture with AuthPlugin, TransportPlugin, ConverterPlugin, and FormatterPlugin base classes. The OCaml library has Auth.custom for custom authentication, but doesn't provide a formal plugin system. While OCaml's module system enables extensions without a plugin framework, providing a documented extension API would encourage ecosystem growth. This could involve: (1) Documenting Auth.custom as the extension point, (2) Providing example plugins (AWS SigV4, OAuth 2.0 client credentials), (3) Creating an opam package registry tag for requests plugins. Low priority but valuable for long-term ecosystem health." 269 - } 270 - ] 271 - }
-163
third_party/bash-shell/resty.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "resty", 5 - "source_language": "bash", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add persistent configuration storage per-host", 9 - "description": "Resty stores per-host default options in `~/.resty/<domain>` and global defaults in `~/.resty/resty`, allowing users to set authentication, headers, and curl options once and have them automatically applied to all requests to that host. The OCaml library should add a similar XDG-compliant configuration system for storing per-host defaults like auth, headers, and timeout settings.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/requests.mli" 13 - ], 14 - "rationale": "Resty's per-host configuration (lines 76-101) significantly improves ergonomics for users working with multiple APIs. The OCaml library currently requires passing auth/headers on every request or setting them globally on the session. A per-host configuration file (e.g., `~/.config/requests/hosts/<domain>.json`) would enable patterns like: configure GitHub auth once, then all github.com requests automatically include it. This reduces boilerplate and improves developer experience, especially in CLI tools. The library already has Xdge support and cookie persistence, so extending to host-specific configs is a natural fit." 15 - }, 16 - { 17 - "source_repo": "resty", 18 - "source_language": "bash", 19 - "criticality": "low", 20 - "change_type": "enhancement", 21 - "title": "Add query parameter builder functions", 22 - "description": "Resty provides explicit query string handling with `-q` flag for automatic URL encoding and `-Q` for raw paths (lines 159-168, 176-178). The OCaml library should add helper functions like `Headers.query_params : (string * string) list -> string` and `Uri.add_query_params : Uri.t -> (string * string) list -> Uri.t` to make query parameter construction more ergonomic.", 23 - "affected_files": [ 24 - "lib/headers.ml", 25 - "lib/headers.mli" 26 - ], 27 - "rationale": "While the OCaml library has `?params:(string * string) list` in the `get` function (requests.mli:390), there's no clear documentation or helper for query encoding patterns. Resty's distinction between encoded (-q) and raw (-Q) queries is useful. Adding utility functions would improve API discoverability and reduce errors from manual URI construction. This is low priority since Uri library already handles this, but explicit helpers improve ergonomics." 28 - }, 29 - { 30 - "source_repo": "resty", 31 - "source_language": "bash", 32 - "criticality": "low", 33 - "change_type": "feature", 34 - "title": "Add dry-run mode for debugging requests", 35 - "description": "Resty includes a `--dry-run` flag (lines 169, 219-222) that prints the full curl command without executing it, useful for debugging. The OCaml library should add a similar capability: either a logging mode that shows the exact HTTP request being sent, or a dry-run function that returns the request components without executing.", 36 - "affected_files": [ 37 - "lib/requests.ml", 38 - "lib/requests.mli", 39 - "lib/one.ml", 40 - "lib/one.mli" 41 - ], 42 - "rationale": "Debugging HTTP requests is critical for development. Resty's dry-run (line 219-222) lets users verify the exact request being sent. The OCaml library has verbose HTTP logging via `--verbose-http` (requests.mli:512-517), but this requires setting up Logs infrastructure and may not show the exact request structure clearly. Adding either: (1) a `pp_request` pretty-printer, (2) a `to_curl_command` function, or (3) a dry-run mode that builds the request but doesn't send it would significantly improve debugging. Low criticality since verbose logging exists, but explicit dry-run is more user-friendly." 43 - }, 44 - { 45 - "source_repo": "resty", 46 - "source_language": "bash", 47 - "criticality": "medium", 48 - "change_type": "enhancement", 49 - "title": "Improve error output to distinguish success vs failure clearly", 50 - "description": "Resty has excellent error handling: 2xx responses go to stdout with exit 0, non-2xx go to stderr with exit code = first digit of status (lines 229-266). The OCaml library should follow similar patterns: add a Response.raise_for_status function that raises an exception for non-2xx status codes, making error handling more explicit and consistent.", 51 - "affected_files": [ 52 - "lib/response.ml", 53 - "lib/response.mli", 54 - "lib/error.ml" 55 - ], 56 - "rationale": "The OCaml library explicitly does NOT raise exceptions for HTTP error codes (requests.mli:98-113), requiring users to manually check Response.ok. While this is documented, Resty's approach (lines 261-267: 2xx→stdout+exit0, non-2xx→stderr+exit!=0) provides clearer semantics. Adding a Response.raise_for_status() function (like Python requests) would give users choice: check status manually OR call raise_for_status for automatic error handling. This improves ergonomics for common cases where 4xx/5xx should abort execution. The retry config already has status_forcelist, so the infrastructure exists." 57 - }, 58 - { 59 - "source_repo": "resty", 60 - "source_language": "bash", 61 - "criticality": "low", 62 - "change_type": "enhancement", 63 - "title": "Add convenience method for TRACE requests", 64 - "description": "Resty supports the TRACE HTTP method as a first-class function (lines 130, 209, 311-313). The OCaml library supports TRACE via the generic `request` function but doesn't expose a dedicated `trace` function like it does for get/post/put/delete/patch/head/options.", 65 - "affected_files": [ 66 - "lib/requests.ml", 67 - "lib/requests.mli" 68 - ], 69 - "rationale": "While TRACE is rarely used, completeness matters for an HTTP library. Resty treats TRACE as first-class (lines 311-313), and the OCaml library already has Method.`TRACE in method.ml. Adding a `val trace` function alongside the existing head/options functions (requests.mli:434-450) takes minimal effort and provides API consistency. Low priority since users can call `request ~method_:`TRACE`, but explicit functions improve discoverability." 70 - }, 71 - { 72 - "source_repo": "resty", 73 - "source_language": "bash", 74 - "criticality": "medium", 75 - "change_type": "enhancement", 76 - "title": "Add automatic Content-Type detection for request bodies", 77 - "description": "Resty provides `--json` and `--xml` flags (lines 170-171) that automatically set both Accept and Content-Type headers. The OCaml library should add convenience functions or auto-detection: when using Body.json, automatically set Content-Type to application/json unless explicitly overridden.", 78 - "affected_files": [ 79 - "lib/body.ml", 80 - "lib/body.mli", 81 - "lib/requests.ml" 82 - ], 83 - "rationale": "Resty's --json flag sets both Accept and Content-Type (line 170), reducing boilerplate. The OCaml library has Body.json but requires manual header setting (README.md:30-36). Auto-setting Content-Type when using Body.json/Body.form/Body.multipart would reduce errors and improve ergonomics. This should be opt-out (can override with explicit headers) following the principle of sensible defaults. The Headers module already has content_type function, so integration is straightforward." 84 - }, 85 - { 86 - "source_repo": "resty", 87 - "source_language": "bash", 88 - "criticality": "low", 89 - "change_type": "feature", 90 - "title": "Add path memory/sticky path feature", 91 - "description": "Resty implements 'path memory' where the last used path is remembered and reused if no path is specified (lines 182-187, environment variable _RESTY_PATH). This allows users to omit the path on subsequent requests. Consider adding an optional similar feature to the OCaml library's session type.", 92 - "affected_files": [ 93 - "lib/requests.ml", 94 - "lib/requests.mli" 95 - ], 96 - "rationale": "Resty's path preservation (lines 182-187) enables workflow: GET /users/123, then PUT (reuses /users/123). This is useful for interactive/REPL usage but less relevant for programmatic APIs. For OCaml, this would be most useful in a REPL-like tool built on the library. Since the OCaml library is primarily for programmatic use (not interactive shell), this is low priority. However, if building a CLI tool on top of the library, maintaining last-used URL in session state could improve UX. Implement as optional behavior (default off) via config flag." 97 - }, 98 - { 99 - "source_repo": "resty", 100 - "source_language": "bash", 101 - "criticality": "low", 102 - "change_type": "enhancement", 103 - "title": "Add raw output mode to bypass response processing", 104 - "description": "Resty has a `-Z` flag (lines 165, 209-212, 237-240) that disables all response processing like HTML-to-text conversion. The OCaml library should add a similar flag to bypass auto-decompression and other response transformations when raw bytes are needed.", 105 - "affected_files": [ 106 - "lib/requests.ml", 107 - "lib/requests.mli" 108 - ], 109 - "rationale": "Resty's -Z flag (lines 165, 237-240) prevents HTML rendering transformations. The OCaml library has `?auto_decompress:bool` (requests.mli:240) which is similar but only covers compression. Consider adding `?raw_response:bool` to bypass all transformations (decompression, charset conversion, etc.) when users need exact byte-for-byte response. This is useful for binary downloads or when debugging response encoding issues. Low priority since auto_decompress=false covers the main use case, but a unified raw mode would be clearer." 110 - }, 111 - { 112 - "source_repo": "resty", 113 - "source_language": "bash", 114 - "criticality": "high", 115 - "change_type": "security", 116 - "title": "Add request history sanitization warnings", 117 - "description": "Resty has a `-W` flag (lines 18, 166, 338) to prevent writing sensitive requests to shell history. The OCaml library should add logging warnings when credentials are used with persist_cookies or in contexts where they might be logged/cached.", 118 - "affected_files": [ 119 - "lib/auth.ml", 120 - "lib/requests.ml" 121 - ], 122 - "rationale": "Resty's -W flag (line 338: --W prevents history writes) addresses credential leakage to shell history. The OCaml library doesn't have this exact risk, but similar concerns exist: (1) credentials in debug logs, (2) credentials in cached responses, (3) credentials in error messages. The library already sanitizes URLs in errors (error.ml:63-68) and redacts sensitive headers (error.ml:70-83). However, there's no warning when users enable persist_cookies with auth enabled, which could persist Authorization headers to disk. Add: (1) Log warning when auth+persist_cookies are both enabled, (2) Ensure cached responses (if caching is re-enabled) never persist auth headers. High criticality for security best practices." 123 - }, 124 - { 125 - "source_repo": "resty", 126 - "source_language": "bash", 127 - "criticality": "medium", 128 - "change_type": "enhancement", 129 - "title": "Add support for stdin/pipe as request body source", 130 - "description": "Resty automatically reads from stdin when no body is provided for POST/PUT/PATCH (lines 192-198). The OCaml library should make it easier to stream from stdin or other Eio flows as request bodies.", 131 - "affected_files": [ 132 - "lib/body.ml", 133 - "lib/body.mli" 134 - ], 135 - "rationale": "Resty's stdin detection (lines 192-198: if stdin is not a TTY, read body from it) enables Unix pipeline workflows. The OCaml library has Body.stream for custom flows, but no explicit Body.stdin helper. Adding Body.from_flow : Eio.Flow.source_ty Eio.Resource.t -> t would make it trivial to pipe data: `cat data.json | ocurl POST /api`. This improves CLI tool ergonomics. Medium priority since Body.stream exists, but an explicit helper improves discoverability and reduces boilerplate for common CLI patterns." 136 - }, 137 - { 138 - "source_repo": "resty", 139 - "source_language": "bash", 140 - "criticality": "low", 141 - "change_type": "feature", 142 - "title": "Add environment variable support for base URL", 143 - "description": "Resty persists the base host in a file that can be reloaded across shell sessions (lines 57, 64-65, 125, 180). Consider adding environment variable support for default base URLs, similar to HTTP_PROXY.", 144 - "affected_files": [ 145 - "lib/requests.ml" 146 - ], 147 - "rationale": "Resty saves host to ~/.resty/host file (lines 57, 180) for persistence across sessions. The OCaml library could support REQUESTS_BASE_URL or app-specific env vars for default base URL. This is useful for CLI tools that always talk to one API. The library already uses app-specific env vars via Cmdliner integration (requests.mli:598-618). Adding base URL to Cmd.config_term would enable: `MYAPP_BASE_URL=https://api.prod.com myapp get /users`. Low priority since users can set this in application code, but env var support is a common CLI convention." 148 - }, 149 - { 150 - "source_repo": "resty", 151 - "source_language": "bash", 152 - "criticality": "low", 153 - "change_type": "enhancement", 154 - "title": "Document HTTP method safety and idempotency for retry decisions", 155 - "description": "Resty explicitly encodes which HTTP methods can have bodies (lines 130) and which should be retried. The OCaml library has retry allowed_methods but should better document the rationale (safety/idempotency) in the retry module.", 156 - "affected_files": [ 157 - "lib/retry.ml", 158 - "lib/retry.mli" 159 - ], 160 - "rationale": "Resty hardcodes 'POST PUT TRACE PATCH DELETE' as methods with bodies (line 130). The OCaml retry.ml has allowed_methods = [GET; HEAD; PUT; DELETE; OPTIONS; TRACE] (line 24), excluding POST and PATCH by default. This is correct (POST/PATCH are not idempotent), but the rationale isn't documented. Adding documentation about HTTP method safety (RFC 9110 Section 9.2.1: GET/HEAD/OPTIONS/TRACE are safe; PUT/DELETE are idempotent) would help users understand retry config. Also clarify why POST/PATCH are excluded by default but can be added if the user's API is idempotent. Low priority: improves understanding but doesn't change functionality." 161 - } 162 - ] 163 - }
-277
third_party/c++/cpp-httplib.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "cpp-httplib", 5 - "source_language": "C++", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add progress callbacks for upload and download operations", 9 - "description": "cpp-httplib provides progress callbacks that report bytes transferred during upload and download. This is useful for implementing progress bars, monitoring large transfers, and providing user feedback. The OCaml library should add similar functionality through optional callback parameters.", 10 - "affected_files": [ 11 - "lib/one.ml", 12 - "lib/one.mli", 13 - "lib/requests.ml", 14 - "lib/requests.mli", 15 - "lib/body.ml" 16 - ], 17 - "rationale": "Progress monitoring is essential for user-facing applications that handle large file uploads/downloads. cpp-httplib implements this via UploadProgress and DownloadProgress callbacks that receive (current_bytes, total_bytes) and can cancel operations by returning false. The OCaml library currently streams data but doesn't provide progress hooks, making it difficult to build responsive UIs." 18 - }, 19 - { 20 - "source_repo": "cpp-httplib", 21 - "source_language": "C++", 22 - "criticality": "low", 23 - "change_type": "feature", 24 - "title": "Support for multipart form data streaming with content receivers", 25 - "description": "cpp-httplib allows streaming processing of multipart form data fields as they arrive, rather than buffering everything in memory. This is critical for handling large file uploads efficiently. The OCaml library should add similar streaming support for multipart data.", 26 - "affected_files": [ 27 - "lib/body.ml", 28 - "lib/body.mli", 29 - "lib/http_read.ml" 30 - ], 31 - "rationale": "cpp-httplib's HandlerWithContentReader allows processing multipart form data incrementally using callbacks for each field and its content. This prevents memory exhaustion when receiving large files. The OCaml library currently has Body.multipart for sending but lacks efficient streaming reception." 32 - }, 33 - { 34 - "source_repo": "cpp-httplib", 35 - "source_language": "C++", 36 - "criticality": "medium", 37 - "change_type": "feature", 38 - "title": "Add support for HTTP Range requests (byte ranges)", 39 - "description": "cpp-httplib provides make_range_header() helper and automatic Range header handling for partial content requests. This enables resumable downloads and seeking in large files. The OCaml library should add Range request support with helpers for common range patterns.", 40 - "affected_files": [ 41 - "lib/headers.ml", 42 - "lib/headers.mli", 43 - "lib/response.ml", 44 - "lib/response.mli" 45 - ], 46 - "rationale": "Range requests (RFC 7233) are essential for resumable downloads, video streaming, and large file access. cpp-httplib supports multi-range requests like 'bytes=1-10,20-30' via make_range_header. The OCaml library currently has no built-in Range support, forcing users to manually construct headers and parse 206 Partial Content responses." 47 - }, 48 - { 49 - "source_repo": "cpp-httplib", 50 - "source_language": "C++", 51 - "criticality": "high", 52 - "change_type": "enhancement", 53 - "title": "Add dedicated error types for socket/file descriptor exhaustion", 54 - "description": "cpp-httplib has specific error codes for ResourceExhaustion and ExceedMaxSocketDescriptorCount. These help diagnose resource limit issues vs network failures. The OCaml library should add similar granular resource error types.", 55 - "affected_files": [ 56 - "lib/error.ml", 57 - "lib/error.mli" 58 - ], 59 - "rationale": "cpp-httplib distinguishes between ResourceExhaustion (general resource issues) and ExceedMaxSocketDescriptorCount (too many file descriptors). The OCaml Error module has granular connection errors but no specific resource exhaustion types. This makes it harder to diagnose and handle resource limit errors differently from network failures." 60 - }, 61 - { 62 - "source_repo": "cpp-httplib", 63 - "source_language": "C++", 64 - "criticality": "medium", 65 - "change_type": "enhancement", 66 - "title": "Implement separate read and write timeout tracking", 67 - "description": "cpp-httplib tracks read and write timeouts independently with microsecond precision, allowing fine-grained control over slow reads vs slow writes. The OCaml library should split timeout configuration to distinguish read/write operations.", 68 - "affected_files": [ 69 - "lib/timeout.ml", 70 - "lib/timeout.mli", 71 - "lib/http_client.ml" 72 - ], 73 - "rationale": "cpp-httplib provides separate CLIENT_READ_TIMEOUT and CLIENT_WRITE_TIMEOUT defaults (300s and 5s respectively), recognizing that reads (waiting for server) often need longer timeouts than writes. The OCaml Timeout module already has connect/read/total fields but could benefit from separating write timeout, especially for large uploads." 74 - }, 75 - { 76 - "source_repo": "cpp-httplib", 77 - "source_language": "C++", 78 - "criticality": "low", 79 - "change_type": "feature", 80 - "title": "Add support for Server-Sent Events (SSE) streaming", 81 - "description": "cpp-httplib has examples demonstrating SSE support for real-time server-to-client event streaming. The OCaml library should add helpers for SSE format parsing and event stream handling.", 82 - "affected_files": [ 83 - "lib/response.ml", 84 - "lib/response.mli" 85 - ], 86 - "rationale": "Server-Sent Events (text/event-stream) is a standard for server push over HTTP. cpp-httplib's examples show SSE server and client implementations. The OCaml library could add SSE parsing helpers to make it easier to consume event streams from APIs like OpenAI, Anthropic, etc." 87 - }, 88 - { 89 - "source_repo": "cpp-httplib", 90 - "source_language": "C++", 91 - "criticality": "medium", 92 - "change_type": "enhancement", 93 - "title": "Add configurable limits for URI length and header count", 94 - "description": "cpp-httplib enforces REQUEST_URI_MAX_LENGTH (8192) and HEADER_MAX_COUNT (100) to prevent attacks. The OCaml library should make these limits configurable rather than using only max_header_size.", 95 - "affected_files": [ 96 - "lib/response_limits.ml", 97 - "lib/response_limits.mli", 98 - "lib/http_read.ml" 99 - ], 100 - "rationale": "cpp-httplib defines separate limits for URI length (8192), header count (100), and header size (8192) as defense against malicious requests. The OCaml Response_limits module has max_header_size and max_header_count but doesn't enforce URI length limits. Adding URI length validation prevents memory exhaustion from pathologically long URLs." 101 - }, 102 - { 103 - "source_repo": "cpp-httplib", 104 - "source_language": "C++", 105 - "criticality": "low", 106 - "change_type": "feature", 107 - "title": "Add automatic path encoding for URL special characters", 108 - "description": "cpp-httplib provides set_path_encode() to automatically encode special characters in URL paths (spaces, plus signs, etc.). The OCaml library should add similar automatic encoding with a toggle.", 109 - "affected_files": [ 110 - "lib/requests.ml", 111 - "lib/requests.mli" 112 - ], 113 - "rationale": "cpp-httplib's set_path_encode(true) automatically encodes spaces and special characters in URL paths, with set_path_encode(false) for pre-encoded paths. This prevents common bugs from unencoded URLs. The OCaml library relies on Uri module encoding but doesn't provide a convenience toggle for automatic path encoding." 114 - }, 115 - { 116 - "source_repo": "cpp-httplib", 117 - "source_language": "C++", 118 - "criticality": "high", 119 - "change_type": "security", 120 - "title": "Add support for trusted proxy headers (X-Forwarded-For validation)", 121 - "description": "cpp-httplib provides set_trusted_proxies() to validate X-Forwarded-For headers and prevent IP spoofing. The OCaml library should add proxy trust configuration for secure header handling.", 122 - "affected_files": [ 123 - "lib/requests.ml", 124 - "lib/requests.mli", 125 - "lib/headers.ml" 126 - ], 127 - "rationale": "cpp-httplib's set_trusted_proxies() prevents IP spoofing by validating which proxies can set X-Forwarded-For/X-Real-IP headers. Without this, malicious clients can forge their IP address. The OCaml library currently has no proxy trust mechanism, making it unsafe to rely on forwarded headers for security decisions." 128 - }, 129 - { 130 - "source_repo": "cpp-httplib", 131 - "source_language": "C++", 132 - "criticality": "medium", 133 - "change_type": "enhancement", 134 - "title": "Add structured logging with separate access and error loggers", 135 - "description": "cpp-httplib separates set_logger() for successful requests from set_error_logger() for failures, following nginx/Apache patterns. The OCaml library should provide separate logging callbacks for success vs error paths.", 136 - "affected_files": [ 137 - "lib/requests.ml", 138 - "lib/requests.mli", 139 - "lib/one.ml" 140 - ], 141 - "rationale": "cpp-httplib provides three logger types: access logger (successful requests), pre-compression logger (before compression), and error logger (failures with different signature taking Error+Request). This separation allows different log destinations and formats. The OCaml library uses Logs module but doesn't provide structured callback hooks for request/response logging." 142 - }, 143 - { 144 - "source_repo": "cpp-httplib", 145 - "source_language": "C++", 146 - "criticality": "low", 147 - "change_type": "feature", 148 - "title": "Add support for connection state polling during long requests", 149 - "description": "cpp-httplib provides Request.is_connection_closed() to check if client disconnected during long-running operations. The OCaml library should add connection state checking for long operations.", 150 - "affected_files": [ 151 - "lib/http_client.ml", 152 - "lib/requests.ml" 153 - ], 154 - "rationale": "cpp-httplib allows checking req.is_connection_closed() in handler loops to detect client disconnection and abort expensive operations early. This prevents wasted work when clients disconnect. The OCaml library could expose connection state through the Eio flow abstraction." 155 - }, 156 - { 157 - "source_repo": "cpp-httplib", 158 - "source_language": "C++", 159 - "criticality": "medium", 160 - "change_type": "enhancement", 161 - "title": "Add configurable idle interval for request processing", 162 - "description": "cpp-httplib provides set_idle_interval() to control polling interval during request processing. The OCaml library should add similar tuning for CPU usage vs responsiveness trade-off.", 163 - "affected_files": [ 164 - "lib/requests.ml", 165 - "lib/requests.mli" 166 - ], 167 - "rationale": "cpp-httplib's IDLE_INTERVAL_USECOND (1000μs on Windows, 0 on Unix) controls polling frequency during I/O operations, balancing CPU usage and responsiveness. The OCaml library relies on Eio's scheduler but doesn't expose idle interval tuning, which could be useful for embedded or high-frequency scenarios." 168 - }, 169 - { 170 - "source_repo": "cpp-httplib", 171 - "source_language": "C++", 172 - "criticality": "low", 173 - "change_type": "enhancement", 174 - "title": "Add default User-Agent header with library version", 175 - "description": "Many HTTP libraries set a default User-Agent identifying the library and version. The OCaml library should add a default User-Agent like 'ocaml-requests/VERSION' that can be overridden.", 176 - "affected_files": [ 177 - "lib/requests.ml", 178 - "lib/headers.ml" 179 - ], 180 - "rationale": "cpp-httplib doesn't enforce User-Agent but most HTTP clients provide defaults (e.g., 'python-requests/2.31.0'). This helps server operators identify clients and debug issues. The OCaml library currently requires users to set User-Agent manually. Adding a default like 'ocaml-requests/0.1.0' with easy override would follow HTTP best practices." 181 - }, 182 - { 183 - "source_repo": "cpp-httplib", 184 - "source_language": "C++", 185 - "criticality": "medium", 186 - "change_type": "feature", 187 - "title": "Add support for custom socket options via callback", 188 - "description": "cpp-httplib provides set_socket_options() callback for custom socket configuration (SO_SNDBUF, SO_RCVBUF, etc.). The OCaml library should expose similar low-level socket tuning.", 189 - "affected_files": [ 190 - "lib/requests.ml", 191 - "lib/requests.mli" 192 - ], 193 - "rationale": "cpp-httplib's set_socket_options(SocketOptions) allows configuring TCP_NODELAY, buffer sizes, keepalive, etc. This is critical for performance tuning and embedded systems. The OCaml library currently doesn't expose socket-level configuration, relying on Eio defaults. Adding optional socket options callback would enable performance tuning." 194 - }, 195 - { 196 - "source_repo": "cpp-httplib", 197 - "source_language": "C++", 198 - "criticality": "high", 199 - "change_type": "security", 200 - "title": "Add validation for form-urlencoded payload size limits", 201 - "description": "cpp-httplib enforces FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH (8192) separate from general payload limits to prevent hash collision attacks. The OCaml library should add similar form-specific limits.", 202 - "affected_files": [ 203 - "lib/response_limits.ml", 204 - "lib/body.ml", 205 - "lib/http_read.ml" 206 - ], 207 - "rationale": "cpp-httplib limits form-urlencoded payloads to 8KB by default, recognizing that parsing form data into hash tables is vulnerable to collision attacks. The OCaml Response_limits module has max_response_body_size but no separate form data limit. This leaves the library vulnerable to hash collision DoS on form parsing." 208 - }, 209 - { 210 - "source_repo": "cpp-httplib", 211 - "source_language": "C++", 212 - "criticality": "medium", 213 - "change_type": "feature", 214 - "title": "Add support for Unix domain socket connections", 215 - "description": "cpp-httplib supports Unix domain sockets via set_address_family(AF_UNIX) for IPC. The OCaml library should add Unix socket support for local service communication.", 216 - "affected_files": [ 217 - "lib/one.ml", 218 - "lib/requests.ml", 219 - "lib/http_client.ml" 220 - ], 221 - "rationale": "cpp-httplib supports Unix domain sockets on Linux/macOS via set_address_family(AF_UNIX) and abstract sockets. This is useful for Docker, systemd, and local IPC. The OCaml library could leverage Eio.Net's Unix socket support to enable HTTP over Unix sockets for container/local scenarios." 222 - }, 223 - { 224 - "source_repo": "cpp-httplib", 225 - "source_language": "C++", 226 - "criticality": "low", 227 - "change_type": "enhancement", 228 - "title": "Add support for pre-compression logging hooks", 229 - "description": "cpp-httplib provides set_pre_compression_logger() to log request/response before compression is applied. This helps debug compression issues. The OCaml library should add similar pre/post compression hooks.", 230 - "affected_files": [ 231 - "lib/requests.ml", 232 - "lib/response.ml" 233 - ], 234 - "rationale": "cpp-httplib's set_pre_compression_logger() captures data before compression, showing original content and allowing inspection of compression decisions. This is valuable for debugging compression issues (e.g., when compressed response is malformed). The OCaml library has auto_decompress but no hooks for debugging compression." 235 - }, 236 - { 237 - "source_repo": "cpp-httplib", 238 - "source_language": "C++", 239 - "criticality": "low", 240 - "change_type": "feature", 241 - "title": "Add convenience helpers for URI encoding/decoding", 242 - "description": "cpp-httplib provides encode_uri(), decode_uri(), encode_uri_component(), and decode_uri_component() as utility functions. The OCaml library should expose similar helpers.", 243 - "affected_files": [ 244 - "lib/requests.ml", 245 - "lib/requests.mli" 246 - ], 247 - "rationale": "cpp-httplib provides httplib::encode_uri() for full URLs (preserves :/?&=) and httplib::encode_uri_component() for query params (encodes all reserved chars). While OCaml has Uri module, exposing convenience functions like Requests.encode_query_param would improve ergonomics and reduce Uri module dependency." 248 - }, 249 - { 250 - "source_repo": "cpp-httplib", 251 - "source_language": "C++", 252 - "criticality": "medium", 253 - "change_type": "enhancement", 254 - "title": "Add maximum redirect count enforcement at protocol level", 255 - "description": "cpp-httplib enforces REDIRECT_MAX_COUNT at the protocol level (default 20). The OCaml library has redirect limits but should ensure they're checked before network I/O to prevent redirect-based DoS.", 256 - "affected_files": [ 257 - "lib/requests.ml", 258 - "lib/http_client.ml" 259 - ], 260 - "rationale": "cpp-httplib has built-in REDIRECT_MAX_COUNT constant and ExceedRedirectCount error. While the OCaml library has max_redirects parameter and Too_many_redirects error, ensuring the check happens early (before attempting connection) prevents redirect-based resource exhaustion. The implementation should short-circuit at max_redirects without network overhead." 261 - }, 262 - { 263 - "source_repo": "cpp-httplib", 264 - "source_language": "C++", 265 - "criticality": "low", 266 - "change_type": "feature", 267 - "title": "Add support for custom HTTP version specification", 268 - "description": "cpp-httplib allows specifying HTTP version (1.0, 1.1) per request. The OCaml library should add version control for compatibility with legacy servers.", 269 - "affected_files": [ 270 - "lib/requests.ml", 271 - "lib/http_client.ml", 272 - "lib/http_write.ml" 273 - ], 274 - "rationale": "cpp-httplib allows forcing HTTP/1.0 vs HTTP/1.1 for compatibility. While HTTP/1.1 is standard, some legacy servers/proxies only support 1.0, or require it to avoid chunked encoding. The OCaml library currently hardcodes HTTP/1.1. Adding version control would improve compatibility." 275 - } 276 - ] 277 - }
-387
third_party/c++/cpp-netlib.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "cpp-netlib", 5 - "source_language": "C++", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add DNS resolution caching capability", 9 - "description": "cpp-netlib provides a `cache_resolved` option (line 77-83 in client/options.hpp) that caches DNS resolution results to avoid repeated lookups for the same hostname. This reduces latency for repeated requests to the same domain and minimizes DNS query overhead.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/requests.mli", 13 - "lib/http_client.ml" 14 - ], 15 - "rationale": "The OCaml library currently performs DNS resolution on every connection attempt. Adding an optional DNS cache with configurable TTL would improve performance for applications making multiple requests to the same domains, especially in high-throughput scenarios. This is particularly valuable when connection pooling is not used or when pools are exhausted." 16 - }, 17 - { 18 - "source_repo": "cpp-netlib", 19 - "source_language": "C++", 20 - "criticality": "low", 21 - "change_type": "enhancement", 22 - "title": "Add automatic EOF retry for stale connections", 23 - "description": "cpp-netlib's pooled_connection policy (lines 115-125 in pooled_connection.hpp) implements automatic retry when EOF is encountered on first read, recognizing that pooled connections may have been closed by the server. The connection is re-established and the request retried once automatically.", 24 - "affected_files": [ 25 - "lib/http_client.ml", 26 - "lib/retry.ml" 27 - ], 28 - "rationale": "The OCaml library's connection pool may encounter stale connections that were closed by the server between requests. While the current retry mechanism handles many error cases, adding specific handling for EOF on first read would improve reliability for long-lived connection pools without requiring full retry configuration. This should be a silent, single automatic retry before falling back to the configured retry policy." 29 - }, 30 - { 31 - "source_repo": "cpp-netlib", 32 - "source_language": "C++", 33 - "criticality": "medium", 34 - "change_type": "feature", 35 - "title": "Add configurable OpenSSL/TLS options for advanced TLS configuration", 36 - "description": "cpp-netlib exposes `openssl_options` (line 134-137 in options.hpp) allowing users to pass raw OpenSSL flags for fine-grained TLS control (e.g., SSL_OP_NO_SSLv2, SSL_OP_CIPHER_SERVER_PREFERENCE). This enables advanced security hardening and compatibility tuning.", 37 - "affected_files": [ 38 - "lib/requests.ml", 39 - "lib/requests.mli" 40 - ], 41 - "rationale": "The OCaml library currently uses OCaml-TLS which has different configuration patterns than OpenSSL, but the principle remains valuable. Exposing low-level TLS configuration options (e.g., specific cipher ordering, session resumption control, ALPN protocol selection) would enable security-conscious users to harden their TLS configuration beyond the current `tls_version` setting. This could be achieved by allowing custom `Tls.Config.client` instances to be passed directly." 42 - }, 43 - { 44 - "source_repo": "cpp-netlib", 45 - "source_language": "C++", 46 - "criticality": "low", 47 - "change_type": "feature", 48 - "title": "Add streaming response body callback for memory-efficient processing", 49 - "description": "cpp-netlib provides a `body_callback_function_type` (lines 37-39 in pooled_connection.hpp) that processes response body chunks as they arrive, avoiding full materialization in memory. This is demonstrated in client_get_streaming_test.cpp (lines 15-24) with a body_handler that appends chunks incrementally.", 50 - "affected_files": [ 51 - "lib/response.ml", 52 - "lib/response.mli", 53 - "lib/http_client.ml" 54 - ], 55 - "rationale": "The OCaml library already supports streaming via `Response.body` returning an `Eio.Flow.source`, which is superior to callbacks in functional programming. However, adding convenience methods like `Response.iter_chunks ~chunk_size ~f:(fun chunk -> ...)` or `Response.fold_chunks` would provide ergonomic alternatives to manual flow reading for common streaming patterns. This enhancement would improve discoverability and reduce boilerplate." 56 - }, 57 - { 58 - "source_repo": "cpp-netlib", 59 - "source_language": "C++", 60 - "criticality": "high", 61 - "change_type": "enhancement", 62 - "title": "Add comprehensive timeout testing similar to cpp-netlib test suite", 63 - "description": "cpp-netlib includes dedicated timeout tests (client_get_timeout_test.cpp) that verify timeout behavior for both connection and request timeouts, including HTTPS-specific timeout tests. Tests use a local sleep endpoint to reliably trigger timeouts.", 64 - "affected_files": [ 65 - "test/test_simple.ml", 66 - "test/test_localhost.ml" 67 - ], 68 - "rationale": "The OCaml library has timeout configuration (lib/timeout.ml) but the test suite (test/) appears to lack comprehensive timeout testing. Adding tests that verify connect timeout, read timeout, total timeout, and expect_100_continue timeout behavior would prevent regressions and ensure timeout mechanisms work correctly. This is high criticality because timeout bugs can cause production hangs." 69 - }, 70 - { 71 - "source_repo": "cpp-netlib", 72 - "source_language": "C++", 73 - "criticality": "medium", 74 - "change_type": "enhancement", 75 - "title": "Add test coverage for streaming request bodies with generators", 76 - "description": "cpp-netlib supports `body_generator_function_type` (line 40 in pooled_connection.hpp) allowing incremental body generation during request transmission. This enables uploading large files or data without loading everything into memory first.", 77 - "affected_files": [ 78 - "lib/body.ml", 79 - "lib/body.mli", 80 - "test/test_simple.ml" 81 - ], 82 - "rationale": "The OCaml library supports streaming request bodies via `Body.of_stream` and `Body.of_file`, but test coverage appears limited (based on test/httpbin.t). Adding tests for large file uploads, chunked encoding, and stream-based bodies would ensure this critical feature works correctly under various conditions. Testing should verify memory efficiency and proper handling of stream errors." 83 - }, 84 - { 85 - "source_repo": "cpp-netlib", 86 - "source_language": "C++", 87 - "criticality": "low", 88 - "change_type": "feature", 89 - "title": "Expose configuration for chunk marker removal in chunked encoding", 90 - "description": "cpp-netlib provides `remove_chunk_markers` option (lines 161-164 in options.hpp, line 38 in client_get_streaming_test.cpp) allowing users to control whether chunk encoding markers are removed from the body or preserved for manual processing.", 91 - "affected_files": [ 92 - "lib/http_client.ml", 93 - "lib/http_read.ml", 94 - "lib/requests.ml" 95 - ], 96 - "rationale": "The OCaml library likely handles chunked transfer encoding automatically in http_read.ml, but doesn't expose this as a configuration option. While automatic handling is correct for 99% of use cases, advanced users implementing custom HTTP proxies or debugging tools may want access to raw chunked data. Adding an optional `preserve_chunk_markers` flag would enable these specialized use cases without complicating the common path." 97 - }, 98 - { 99 - "source_repo": "cpp-netlib", 100 - "source_language": "C++", 101 - "criticality": "medium", 102 - "change_type": "enhancement", 103 - "title": "Add explicit HTTP version negotiation configuration", 104 - "description": "cpp-netlib is templated on HTTP version (version_major, version_minor in pooled_connection.hpp line 28) and handles version-specific behavior like connection keep-alive (lines 137-143). Different behavior for HTTP/1.0 vs HTTP/1.1 is explicitly coded.", 105 - "affected_files": [ 106 - "lib/http_write.ml", 107 - "lib/http_client.ml", 108 - "lib/requests.ml" 109 - ], 110 - "rationale": "The OCaml library appears to implement HTTP/1.1 by default but doesn't expose HTTP version as a configuration option. Adding the ability to specify HTTP/1.0 for compatibility with legacy servers, or prepare for HTTP/2 support, would improve flexibility. Configuration should control Connection header behavior (close for HTTP/1.0, keep-alive for HTTP/1.1) and chunk encoding availability." 111 - }, 112 - { 113 - "source_repo": "cpp-netlib", 114 - "source_language": "C++", 115 - "criticality": "high", 116 - "change_type": "bug", 117 - "title": "Verify and test redirect location header handling for missing or malformed Location", 118 - "description": "cpp-netlib explicitly handles missing Location headers in redirect responses (lines 145-164 in pooled_connection.hpp), throwing a descriptive error 'Location header not defined in redirect response' rather than failing silently or with a cryptic error.", 119 - "affected_files": [ 120 - "lib/requests.ml", 121 - "lib/http_client.ml", 122 - "lib/error.ml" 123 - ], 124 - "rationale": "The OCaml library should verify it properly handles redirect responses (3xx) that are missing Location headers or have malformed Location values. This is a common server misconfiguration that should produce a clear error (Invalid_redirect) rather than causing a URI parsing exception or infinite loop. Review the redirect handling code and add test cases for: missing Location header, empty Location header, and relative vs absolute Location URLs." 125 - }, 126 - { 127 - "source_repo": "cpp-netlib", 128 - "source_language": "C++", 129 - "criticality": "medium", 130 - "change_type": "enhancement", 131 - "title": "Add granular error types for redirect failures", 132 - "description": "cpp-netlib distinguishes between exceeding maximum redirect count (line 101-102) and missing Location headers (lines 161-163) with different error messages, enabling smarter error handling and debugging.", 133 - "affected_files": [ 134 - "lib/error.ml", 135 - "lib/error.mli" 136 - ], 137 - "rationale": "The OCaml library already has `Too_many_redirects` and `Invalid_redirect` error types (error.ml lines 21-22), which is good. Ensure that the redirect handling code in requests.ml uses both appropriately: `Too_many_redirects` when count exceeded, `Invalid_redirect` for missing/malformed Location headers. This allows users to distinguish between configuration issues (max_redirects too low) and server errors (bad Location header)." 138 - }, 139 - { 140 - "source_repo": "cpp-netlib", 141 - "source_language": "C++", 142 - "criticality": "low", 143 - "change_type": "enhancement", 144 - "title": "Add test infrastructure with local HTTP test server", 145 - "description": "cpp-netlib uses a custom `http_test_server` class (client_get_timeout_test.cpp lines 14-30) that provides a local server for reliable, fast testing without external dependencies. Server lifecycle is managed through Google Test's Environment setup/teardown.", 146 - "affected_files": [ 147 - "test/test_localhost.ml", 148 - "test/dune" 149 - ], 150 - "rationale": "The OCaml test suite uses httpbin.org for integration tests (test/httpbin.t) which requires internet connectivity and is subject to external service availability. While test_localhost.ml exists, expanding it with a more comprehensive local test server (similar to http_test_server) would enable offline testing, faster test execution, and more controlled test scenarios (timeouts, specific error conditions, malformed responses). Consider using a library like cohttp-eio or a minimal TCP server." 151 - }, 152 - { 153 - "source_repo": "cpp-netlib", 154 - "source_language": "C++", 155 - "criticality": "medium", 156 - "change_type": "enhancement", 157 - "title": "Add connection socket status checking to avoid sending on closed connections", 158 - "description": "cpp-netlib checks `pimpl->is_open()` (line 106 in pooled_connection.hpp) before attempting to send a request, and initializes a new socket if the connection was closed. This prevents errors from attempting to write to closed sockets.", 159 - "affected_files": [ 160 - "lib/http_client.ml" 161 - ], 162 - "rationale": "The OCaml library should verify that connection pool connections check socket status before use. While the pool likely handles this, explicitly checking socket state before sending HTTP requests would prevent errors when connections are closed by the server between pool acquisitions. This is especially important for pools with long-lived connections or when servers have aggressive idle timeout policies." 163 - }, 164 - { 165 - "source_repo": "cpp-netlib", 166 - "source_language": "C++", 167 - "criticality": "low", 168 - "change_type": "feature", 169 - "title": "Add cipher suite configuration for TLS connections", 170 - "description": "cpp-netlib exposes `openssl_ciphers` option (lines 122-125 in options.hpp) allowing users to specify custom cipher suite preferences for TLS negotiation, enabling security hardening by disabling weak ciphers.", 171 - "affected_files": [ 172 - "lib/requests.ml", 173 - "lib/requests.mli" 174 - ], 175 - "rationale": "The OCaml library uses OCaml-TLS which has its own cipher configuration system. Exposing cipher suite configuration would allow security-conscious applications to restrict to specific cipher suites, disable weak ciphers, or prefer forward secrecy. This could be achieved by accepting a custom `Tls.Config.client` or adding a `ciphers` parameter that constructs appropriate OCaml-TLS configuration. This is lower priority as OCaml-TLS has secure defaults." 176 - }, 177 - { 178 - "source_repo": "cpp-netlib", 179 - "source_language": "C++", 180 - "criticality": "medium", 181 - "change_type": "enhancement", 182 - "title": "Add SNI (Server Name Indication) hostname configuration", 183 - "description": "cpp-netlib provides `openssl_sni_hostname` option (lines 127-131 in options.hpp) to override the SNI hostname sent during TLS handshake, useful for connecting via IP addresses or when the DNS name differs from the certificate name.", 184 - "affected_files": [ 185 - "lib/requests.ml" 186 - ], 187 - "rationale": "The OCaml library should verify that OCaml-TLS correctly extracts and sends SNI hostname from the request URI. For advanced use cases, adding explicit SNI hostname override would enable connecting to servers via IP address while presenting the correct hostname for certificate validation, or implementing virtual hosting scenarios. This is likely already handled correctly by OCaml-TLS, but should be tested and documented." 188 - }, 189 - { 190 - "source_repo": "cpp-netlib", 191 - "source_language": "C++", 192 - "criticality": "high", 193 - "change_type": "enhancement", 194 - "title": "Add test coverage for connection close behavior on HTTP/1.0 and Connection: close header", 195 - "description": "cpp-netlib explicitly handles connection closure based on HTTP version and Connection header (lines 135-143 in pooled_connection.hpp). HTTP/1.1 connections with 'Connection: close' are closed, and all HTTP/1.0 connections are closed after each request.", 196 - "affected_files": [ 197 - "lib/http_client.ml", 198 - "test/test_simple.ml" 199 - ], 200 - "rationale": "The OCaml library should have test coverage ensuring proper connection lifecycle management based on HTTP version and Connection header. Tests should verify: HTTP/1.1 with 'Connection: close' closes the connection, HTTP/1.1 without the header keeps it alive for pooling, and proper handling of server-initiated connection closure. This prevents connection pool corruption and resource leaks." 201 - }, 202 - { 203 - "source_repo": "cpp-netlib", 204 - "source_language": "C++", 205 - "criticality": "medium", 206 - "change_type": "enhancement", 207 - "title": "Add client certificate authentication support", 208 - "description": "cpp-netlib supports client certificate authentication via `openssl_certificate_file` and `openssl_private_key_file` options (lines 107-119 in options.hpp), enabling mutual TLS authentication.", 209 - "affected_files": [ 210 - "lib/requests.ml", 211 - "lib/requests.mli" 212 - ], 213 - "rationale": "The OCaml library appears to support TLS but may not expose client certificate configuration for mutual TLS (mTLS). Adding support for client certificates would enable authentication with services requiring mTLS, common in microservices, B2B APIs, and high-security environments. This requires accepting client certificate and private key paths, passing them to the OCaml-TLS configuration via `Tls.Config.client ~certificates:... ()`. This is medium priority as mTLS is required for certain enterprise use cases." 214 - }, 215 - { 216 - "source_repo": "cpp-netlib", 217 - "source_language": "C++", 218 - "criticality": "low", 219 - "change_type": "enhancement", 220 - "title": "Add custom CA certificate path/directory configuration", 221 - "description": "cpp-netlib provides both `openssl_certificate` and `openssl_verify_path` options (lines 96-105 in options.hpp) for specifying custom CA certificates or CA certificate directories for TLS verification.", 222 - "affected_files": [ 223 - "lib/requests.ml", 224 - "lib/requests.mli" 225 - ], 226 - "rationale": "The OCaml library uses the ca-certs library which loads system CA certificates. Adding the ability to specify custom CA certificate files or directories would support environments with internal CAs, air-gapped systems, or specific compliance requirements. This could be implemented by accepting CA certificate paths and constructing appropriate authenticators for OCaml-TLS. Since ca-certs handles common cases well, this is low priority unless enterprise use cases require it." 227 - }, 228 - { 229 - "source_repo": "cpp-netlib", 230 - "source_language": "C++", 231 - "criticality": "medium", 232 - "change_type": "feature", 233 - "title": "Add configurable response body exclusion for certain status codes", 234 - "description": "cpp-netlib skips reading response body for specific status codes (lines 129-133 in pooled_connection.hpp): 304 Not Modified, 204 No Content, and 1xx informational responses. This avoids wasting bandwidth and processing time for responses that should not have bodies.", 235 - "affected_files": [ 236 - "lib/http_read.ml", 237 - "lib/http_client.ml" 238 - ], 239 - "rationale": "The OCaml library should verify it correctly handles responses that must not have bodies according to RFC 9110. Attempting to read bodies from 204, 304, or 1xx responses wastes resources and may cause protocol errors. Review http_read.ml to ensure body reading is skipped for these status codes. Also verify correct handling of HEAD responses (status code check, not method check, is insufficient). Add tests for these edge cases." 240 - }, 241 - { 242 - "source_repo": "cpp-netlib", 243 - "source_language": "C++", 244 - "criticality": "low", 245 - "change_type": "enhancement", 246 - "title": "Add typed test infrastructure for testing multiple client configurations", 247 - "description": "cpp-netlib uses Google Test's TYPED_TEST_CASE pattern (client_get_timeout_test.cpp line 36) to run the same test suite across multiple client configurations (sync vs async, different tag types), ensuring behavioral consistency.", 248 - "affected_files": [ 249 - "test/test_simple.ml", 250 - "test/dune" 251 - ], 252 - "rationale": "The OCaml test suite could benefit from parameterized testing across different configurations: with/without connection pooling, different timeout settings, HTTP/1.0 vs HTTP/1.1, different retry configurations. This ensures behavior is consistent across configurations and prevents configuration-specific bugs. OCaml testing frameworks like Alcotest support test generators for this purpose. This would improve test coverage without duplicating test code." 253 - }, 254 - { 255 - "source_repo": "cpp-netlib", 256 - "source_language": "C++", 257 - "criticality": "high", 258 - "change_type": "security", 259 - "title": "Verify default TLS peer verification behavior matches cpp-netlib's secure default", 260 - "description": "cpp-netlib defaults `always_verify_peer` to true (line 36 in options.hpp), ensuring certificate verification is enabled by default and must be explicitly disabled. This security-by-default approach prevents accidental MITM vulnerabilities.", 261 - "affected_files": [ 262 - "lib/requests.ml", 263 - "lib/requests.mli" 264 - ], 265 - "rationale": "The OCaml library should verify that TLS certificate verification is enabled by default and requires explicit opt-out via `verify_tls:false`. Review the current default value for the verify_tls parameter and ensure it defaults to true if not specified. This is critical for security - users who don't explicitly configure TLS should get secure defaults. Add documentation warning about the security implications of disabling verification." 266 - }, 267 - { 268 - "source_repo": "cpp-netlib", 269 - "source_language": "C++", 270 - "criticality": "low", 271 - "change_type": "feature", 272 - "title": "Add shared I/O service configuration for resource pooling", 273 - "description": "cpp-netlib allows passing a shared `boost::asio::io_service` (lines 139-143 in options.hpp) enabling multiple clients to share the same event loop and thread pool, improving resource efficiency in applications with many client instances.", 274 - "affected_files": [ 275 - "lib/requests.ml" 276 - ], 277 - "rationale": "The OCaml library uses Eio which has a different concurrency model than ASIO. However, the concept of sharing resources across multiple request instances is valuable. The library already supports this through shared connection pools via the `http_pool` and `https_pool` parameters in `Requests.create`. Ensure this is well-documented with examples showing how to share pools across multiple request instances for maximum efficiency." 278 - }, 279 - { 280 - "source_repo": "cpp-netlib", 281 - "source_language": "C++", 282 - "criticality": "medium", 283 - "change_type": "enhancement", 284 - "title": "Add Base64 encoding utilities for authentication header generation", 285 - "description": "cpp-netlib includes base64 encoding utilities (utils/base64/encode.hpp, tested in utils_base64_test.cpp) specifically for authentication, as Basic auth requires Base64 encoding of credentials.", 286 - "affected_files": [ 287 - "lib/auth.ml", 288 - "lib/headers.ml" 289 - ], 290 - "rationale": "The OCaml library likely already uses the base64 library for Basic authentication (referenced in dune dependencies). Verify that the Base64 encoding for Basic auth headers is correct and includes the 'Basic ' prefix. Add test coverage specifically for authentication header generation with various special characters in username/password (colons, Unicode, etc.) to ensure correct encoding. This is medium priority as authentication is security-critical." 291 - }, 292 - { 293 - "source_repo": "cpp-netlib", 294 - "source_language": "C++", 295 - "criticality": "medium", 296 - "change_type": "feature", 297 - "title": "Add request and response parser incremental testing", 298 - "description": "cpp-netlib includes comprehensive tests for incremental parsing (request_incremental_parser_test.cpp, response_incremental_parser_test.cpp) ensuring the parser correctly handles partial reads, chunked delivery, and edge cases.", 299 - "affected_files": [ 300 - "lib/http_read.ml", 301 - "lib/http_write.ml", 302 - "test/" 303 - ], 304 - "rationale": "The OCaml library uses Eio's Buf_read and Buf_write for parsing, which likely handles incremental reads correctly. However, adding explicit tests for parsing under adverse conditions (single-byte reads, split headers, partial chunk markers, interrupted streams) would ensure robustness. These tests prevent bugs when network conditions cause fragmented HTTP messages. Create unit tests that feed HTTP responses/requests byte-by-byte to the parser." 305 - }, 306 - { 307 - "source_repo": "cpp-netlib", 308 - "source_language": "C++", 309 - "criticality": "low", 310 - "change_type": "feature", 311 - "title": "Add request and response message linearization for debugging", 312 - "description": "cpp-netlib includes tests for message linearization (request_linearize_test.cpp) - serializing the request/response object back to wire format for debugging, logging, or proxying.", 313 - "affected_files": [ 314 - "lib/http_write.ml", 315 - "lib/http_read.ml", 316 - "lib/requests.ml" 317 - ], 318 - "rationale": "The OCaml library has http_write.ml for request serialization but may not expose this as a debugging utility. Adding a function like `Request.to_string` or `Response.to_string` that produces the wire format would be valuable for debugging, logging (at debug level), and implementing HTTP proxies. This should be opt-in and respect the logging configuration to avoid exposing sensitive data by default. Low priority but useful for troubleshooting." 319 - }, 320 - { 321 - "source_repo": "cpp-netlib", 322 - "source_language": "C++", 323 - "criticality": "medium", 324 - "change_type": "enhancement", 325 - "title": "Add comprehensive response header parser testing with edge cases", 326 - "description": "cpp-netlib includes server_header_parser_test.cpp and response_incremental_parser_test.cpp with extensive edge case testing for header parsing: continuation lines, whitespace handling, case sensitivity, duplicate headers, etc.", 327 - "affected_files": [ 328 - "lib/http_read.ml", 329 - "test/" 330 - ], 331 - "rationale": "HTTP header parsing is security-sensitive and must handle malformed input gracefully. The OCaml library should have comprehensive tests for header parsing edge cases: headers with no values, headers with trailing whitespace, duplicate header names (should combine or take last?), extremely long headers (should respect limits), headers with special characters, and case sensitivity. These tests prevent request smuggling and other HTTP parsing vulnerabilities." 332 - }, 333 - { 334 - "source_repo": "cpp-netlib", 335 - "source_language": "C++", 336 - "criticality": "medium", 337 - "change_type": "enhancement", 338 - "title": "Add SSL/HTTPS-specific test infrastructure and coverage", 339 - "description": "cpp-netlib conditionally compiles HTTPS tests (client_localhost_ssl_test.cpp, lines 61-74 in client_get_timeout_test.cpp) when BOOST_NETWORK_ENABLE_HTTPS is defined, ensuring TLS-specific functionality is tested separately.", 340 - "affected_files": [ 341 - "test/test_localhost.ml", 342 - "test/dune" 343 - ], 344 - "rationale": "The OCaml library should have dedicated HTTPS test coverage including: certificate validation, TLS handshake failures, certificate chain verification, hostname verification, expired certificates, self-signed certificate handling, and TLS timeout scenarios. These tests should use a local test server with generated certificates. This ensures TLS implementation is secure and handles error cases correctly. Create a test fixture that sets up local HTTPS server with various certificate configurations." 345 - }, 346 - { 347 - "source_repo": "cpp-netlib", 348 - "source_language": "C++", 349 - "criticality": "low", 350 - "change_type": "enhancement", 351 - "title": "Add async/promise-based request testing patterns", 352 - "description": "cpp-netlib tests both synchronous and asynchronous client implementations, with async tests verifying that response futures resolve correctly (message_async_ready_test.cpp, client_get_ready_test.cpp).", 353 - "affected_files": [ 354 - "test/test_simple.ml", 355 - "test/test_one.ml" 356 - ], 357 - "rationale": "The OCaml library uses Eio fibers for concurrency, which is different from C++ futures but serves the same purpose. Test coverage should verify concurrent request patterns work correctly: multiple concurrent requests via Fiber.both/all, promise-based communication between fibers, cancellation behavior, and timeout propagation in concurrent scenarios. This ensures the library's concurrency model is sound and free of race conditions." 358 - }, 359 - { 360 - "source_repo": "cpp-netlib", 361 - "source_language": "C++", 362 - "criticality": "medium", 363 - "change_type": "enhancement", 364 - "title": "Add test coverage for different port numbers and non-standard ports", 365 - "description": "cpp-netlib includes client_get_different_port_test.cpp specifically testing requests to non-standard HTTP ports (8000, 8080, etc.), ensuring port handling in URLs and Host headers is correct.", 366 - "affected_files": [ 367 - "test/test_simple.ml", 368 - "test/httpbin.t" 369 - ], 370 - "rationale": "The OCaml library should have explicit test coverage for non-standard ports: port in URL vs default ports (80 for HTTP, 443 for HTTPS), Host header generation with port numbers, connection pooling with same host but different ports, and URL parsing edge cases (missing port, port 0, port > 65535). This ensures URL and connection handling is robust across different deployment scenarios." 371 - }, 372 - { 373 - "source_repo": "cpp-netlib", 374 - "source_language": "C++", 375 - "criticality": "low", 376 - "change_type": "feature", 377 - "title": "Add convenience constructors for common client configurations", 378 - "description": "cpp-netlib includes client_constructor_test.cpp and server_constructor_test.cpp testing various constructor patterns and configuration combinations, emphasizing API ergonomics.", 379 - "affected_files": [ 380 - "lib/requests.ml", 381 - "lib/requests.mli", 382 - "lib/one.ml" 383 - ], 384 - "rationale": "The OCaml library has `Requests.create` and `One.create` but could benefit from convenience constructors for common patterns: `create_with_retry`, `create_with_auth`, `create_for_json_api` (with JSON content-type defaults), etc. These would reduce boilerplate for common use cases while maintaining the flexible base API. Alternatively, consider a builder pattern via `Requests.create |> with_auth ... |> with_retry ...`. Low priority as current API is already clean." 385 - } 386 - ] 387 - }
-165
third_party/c++/nfhttp.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/c++/nfhttp", 5 - "source_language": "C++", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Implement request/response modifier hooks (middleware pattern)", 9 - "description": "Add a middleware/interceptor pattern allowing users to transform requests before sending and responses before returning. NFHTTP implements this via REQUEST_MODIFIER_FUNCTION and RESPONSE_MODIFIER_FUNCTION, enabling authentication injection, URL modification, logging, and custom retry logic. This pattern provides extensibility without modifying core library code.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/requests.mli", 13 - "lib/one.ml", 14 - "lib/one.mli" 15 - ], 16 - "rationale": "The OCaml library currently requires auth to be configured upfront and lacks hooks for request/response transformation. NFHTTP's modifier pattern allows dynamic request modification (e.g., refreshing OAuth tokens), response inspection before caching, and custom retry logic. This would enable use cases like: (1) JWT token refresh on 401 responses, (2) automatic request signing, (3) request/response logging middleware, (4) custom retry decisions based on response inspection. Implementation approach: Add optional ~request_modifier:(Headers.t -> Uri.t -> Method.t -> Headers.t * Uri.t) and ~response_modifier:(Response.t -> (Response.t * [`Retry | `Continue])) functions to session configuration." 17 - }, 18 - { 19 - "source_repo": "third_party/c++/nfhttp", 20 - "source_language": "C++", 21 - "criticality": "high", 22 - "change_type": "feature", 23 - "title": "Implement HTTP response caching with disk backend", 24 - "description": "Implement RFC 9111-compliant HTTP caching with persistent storage. NFHTTP provides SQLite-backed caching with cache validation (ETag/If-None-Match, Last-Modified/If-Modified-Since), automatic 304 Not Modified handling, cache pinning for offline access, and background cache pruning. The OCaml library already has Cache-Control parsing (lib/cache_control.ml) but no storage backend.", 25 - "affected_files": [ 26 - "lib/cache.ml", 27 - "lib/cache.mli", 28 - "lib/requests.ml", 29 - "lib/response.ml" 30 - ], 31 - "rationale": "NFHTTP's caching implementation demonstrates production-ready patterns: (1) Automatic cache key generation via request hashing with SHA-256, (2) Respect for Cache-Control directives (no-store, no-cache, must-revalidate), (3) Conditional request headers (If-None-Match, If-Modified-Since) added automatically when serving from stale cache, (4) 304 Not Modified handling to refresh cache metadata without re-downloading body, (5) Cache pinning API for offline-first applications. The OCaml library has comprehensive Cache_control.parse_response/parse_request functions already implemented but unused. Implementation approach: Create a Caching_client module wrapping the existing client, using Eio.Path for file storage (headers in SQLite, bodies in separate files like NFHTTP). Add ~cache_location parameter to Requests.create. Benefits: reduced bandwidth, improved offline support, faster response times for cacheable resources." 32 - }, 33 - { 34 - "source_repo": "third_party/c++/nfhttp", 35 - "source_language": "C++", 36 - "criticality": "medium", 37 - "change_type": "feature", 38 - "title": "Add request deduplication to prevent redundant concurrent identical requests", 39 - "description": "Implement automatic deduplication of concurrent identical requests. NFHTTP's ClientMultiRequestImplementation tracks in-flight requests by hash and multicasts a single network response to multiple waiting callbacks. When multiple identical requests are made concurrently, only one network request is performed and all callers receive the same response.", 40 - "affected_files": [ 41 - "lib/requests.ml", 42 - "lib/http_client.ml" 43 - ], 44 - "rationale": "NFHTTP demonstrates this in ClientMultiRequestImplementation.cpp lines 40-75: requests are hashed, duplicate in-flight requests register additional callbacks in a vector, and the single response is delivered to all waiting callbacks with a 'multicasted' metadata flag. This prevents thundering herd issues and wasted bandwidth when multiple concurrent operations request the same resource (common in UI applications). For the OCaml library, this would particularly benefit scenarios like: (1) Multiple UI components fetching the same user profile, (2) Parallel pagination requests that overlap, (3) Race conditions in concurrent code. Implementation: Add a hash table in the session tracking in-flight requests by (method, URL, headers) hash, queue callbacks for duplicates, broadcast response to all waiters. Use Eio.Promise for coordination." 45 - }, 46 - { 47 - "source_repo": "third_party/c++/nfhttp", 48 - "source_language": "C++", 49 - "criticality": "medium", 50 - "change_type": "enhancement", 51 - "title": "Enhance retry mechanism to support response-based retry decisions", 52 - "description": "Extend the retry mechanism to allow retry decisions based on response inspection, not just exceptions. NFHTTP's response modifier returns a (response, bool retry) tuple, enabling application-specific retry logic based on response headers, body content, or business logic (e.g., retry on specific error codes or custom error responses).", 53 - "affected_files": [ 54 - "lib/retry.ml", 55 - "lib/retry.mli", 56 - "lib/requests.ml" 57 - ], 58 - "rationale": "The current OCaml retry implementation (lib/retry.ml) only retries on exceptions and specific HTTP status codes configured in status_forcelist. NFHTTP's ClientModifierImplementation.cpp lines 56-74 shows a response_modifier_function that receives the response and returns a bool retry flag. This enables: (1) Retrying on custom application error indicators in response body (e.g., JSON error codes), (2) Conditional retry based on response headers (e.g., X-Retry-Required), (3) Different retry strategies per endpoint, (4) Retry after token refresh on 401. Implementation: Add an optional ~should_retry_response:(Response.t -> bool) parameter to Retry.config, check this alongside status_forcelist. This maintains backward compatibility while enabling advanced use cases." 59 - }, 60 - { 61 - "source_repo": "third_party/c++/nfhttp", 62 - "source_language": "C++", 63 - "criticality": "low", 64 - "change_type": "feature", 65 - "title": "Add offline pinning API for critical resources", 66 - "description": "Implement cache pinning to mark specific responses for offline access. NFHTTP provides pinResponse/unpinResponse/pinnedResponsesForIdentifier APIs allowing applications to explicitly preserve critical resources (user profile, essential config) that should survive cache eviction and be available offline.", 67 - "affected_files": [ 68 - "lib/cache.ml", 69 - "lib/cache.mli", 70 - "lib/requests.ml" 71 - ], 72 - "rationale": "NFHTTP's Client.h lines 56-65 shows cache pinning APIs: pinResponse(response, pin_identifier) marks a response as pinned with a logical identifier, unpinResponse removes the pin, removePinnedResponseForIdentifier deletes all responses for an identifier, and pinnedResponsesForIdentifier retrieves all pinned responses. This is implemented in CachingClient.cpp lines 173-211 using database flags. Use cases: (1) Progressive Web Apps keeping critical resources available offline, (2) Mobile apps caching user profiles/settings that must survive cache cleanup, (3) Debugging/testing by pinning specific request/response pairs. Implementation: Extend the proposed cache implementation with pin_id column in SQLite, exclude pinned items from LRU eviction, add Requests.pin_response / Requests.unpin_response / Requests.pinned_responses functions." 73 - }, 74 - { 75 - "source_repo": "third_party/c++/nfhttp", 76 - "source_language": "C++", 77 - "criticality": "low", 78 - "change_type": "enhancement", 79 - "title": "Add response metadata/context dictionary for internal tracking", 80 - "description": "Add a string->string metadata dictionary to Response.t for internal library use and user extensions. NFHTTP's Response includes setMetadata/metadata methods used to track 'cached' flag (whether from cache) and 'multicasted' flag (whether response was shared across duplicate requests).", 81 - "affected_files": [ 82 - "lib/response.ml", 83 - "lib/response.mli" 84 - ], 85 - "rationale": "NFHTTP demonstrates this pattern throughout: CachingClient.cpp line 243 sets 'cached=1' metadata, ClientMultiRequestImplementation.cpp lines 57-58 set 'multicasted' metadata. This enables: (1) Debugging by inspecting response provenance (cache vs network, deduplication status), (2) Metrics collection (cache hit rate, deduplication efficiency), (3) Conditional behavior based on response source, (4) User extensions without modifying Response.t structure. The OCaml library currently has no way to distinguish cached vs fresh responses or track internal processing flags. Implementation: Add a (string, string) Hashtbl.t field to Response.t, expose Response.set_metadata / Response.get_metadata / Response.has_metadata functions. Use for cache hit tracking and future features." 86 - }, 87 - { 88 - "source_repo": "third_party/c++/nfhttp", 89 - "source_language": "C++", 90 - "criticality": "medium", 91 - "change_type": "enhancement", 92 - "title": "Implement automatic cache revalidation with conditional requests", 93 - "description": "Automatically add If-None-Match (ETag) and If-Modified-Since (Last-Modified) headers when serving potentially stale cached responses for validation. NFHTTP's CachingClient.cpp lines 143-159 demonstrates this: when cache entry is expired or must-revalidate is set, it automatically adds validation headers before making the request and handles 304 Not Modified by serving the cached body with refreshed metadata.", 94 - "affected_files": [ 95 - "lib/cache.ml", 96 - "lib/response.ml" 97 - ], 98 - "rationale": "Cache revalidation is critical for efficient HTTP caching per RFC 9111. NFHTTP shows the pattern: (1) Store ETag and Last-Modified from original response in cache database, (2) On cache expiry or must-revalidate directive, add If-None-Match: <etag> or If-Modified-Since: <date> to revalidation request, (3) If server returns 304 Not Modified (no body), serve cached body but update cache metadata (headers, expiry time) from 304 response, (4) If server returns 200 OK, replace cached entry. This dramatically reduces bandwidth for resources that haven't changed. The OCaml library has Response.etag and Response.last_modified helpers but doesn't use them for revalidation. Implementation: When serving from cache with expired freshness_lifetime, automatically inject conditional headers, detect 304 status, merge cached body with new headers." 99 - }, 100 - { 101 - "source_repo": "third_party/c++/nfhttp", 102 - "source_language": "C++", 103 - "criticality": "low", 104 - "change_type": "enhancement", 105 - "title": "Add background cache pruning/cleanup thread", 106 - "description": "Implement periodic background cleanup of expired cache entries and enforcement of cache size limits. NFHTTP implements this via a dedicated pruning thread (CachingClient.cpp lines 213-222) that runs database.prune() every 50 seconds to remove expired entries and enforce storage quotas.", 107 - "affected_files": [ 108 - "lib/cache.ml" 109 - ], 110 - "rationale": "NFHTTP's pruneThread runs in the background, waking periodically to call database.prune() which removes expired cache entries and enforces size limits. This prevents unbounded cache growth and ensures expired content is eventually removed even if never requested again. For the OCaml library with Eio, this would be a Fiber spawned with Eio.Fiber.fork that periodically: (1) Removes cache entries past their expiry time, (2) Enforces max cache size via LRU eviction (respecting pinned items), (3) Cleans up orphaned cache files. Implementation: Add ~cache_max_size and ~cache_prune_interval parameters to Requests.create, spawn a background fiber that sleeps and prunes. Use Eio.Switch to ensure cleanup on session shutdown. This maintains cache hygiene without manual intervention." 111 - }, 112 - { 113 - "source_repo": "third_party/c++/nfhttp", 114 - "source_language": "C++", 115 - "criticality": "low", 116 - "change_type": "enhancement", 117 - "title": "Support cacheability of POST/PUT/DELETE based on Cache-Control headers", 118 - "description": "Allow caching of non-GET/HEAD requests when explicit Cache-Control directives permit it. NFHTTP's CachingClient.cpp lines 248-260 shows shouldCacheRequest rejecting POST/PUT/DELETE unconditionally, but RFC 9110 allows caching these methods with explicit directives. Consider supporting this for idempotent operations.", 119 - "affected_files": [ 120 - "lib/cache.ml" 121 - ], 122 - "rationale": "NFHTTP conservatively disables caching for POST/PUT/DELETE (lines 249-252), but RFC 9110 Section 9.1 allows caching responses to these methods if Cache-Control permits it and the response includes explicit freshness information. This can be useful for: (1) Idempotent PUT operations (e.g., uploading same file repeatedly), (2) POST requests used for safe operations (anti-pattern but exists), (3) GraphQL POST queries that are semantically GET. The OCaml library should follow NFHTTP's conservative default but consider allowing opt-in caching of non-safe methods when max-age/Expires headers are present. Implementation: Add a ~cache_unsafe_methods:bool parameter (default false), check response Cache-Control for explicit caching directives, validate that response includes max-age or Expires before caching POST/PUT/DELETE." 123 - }, 124 - { 125 - "source_repo": "third_party/c++/nfhttp", 126 - "source_language": "C++", 127 - "criticality": "high", 128 - "change_type": "security", 129 - "title": "Review and enhance TLS certificate verification configuration", 130 - "description": "NFHTTP disables SSL certificate verification on Apple and Android platforms (CURLOPT_SSL_VERIFYPEER=false, CURLOPT_SSL_VERIFYHOST=false in ClientCurl.cpp lines 291-294). The OCaml library correctly enables verification by default with ca-certs. Ensure this is well-documented and consider adding certificate pinning support.", 131 - "affected_files": [ 132 - "lib/requests.ml", 133 - "lib/requests.mli", 134 - "README.md" 135 - ], 136 - "rationale": "NFHTTP's security tradeoff (disabling SSL verification on mobile platforms) is a significant vulnerability that the OCaml library correctly avoids. The OCaml implementation properly uses ca-certs for verification and enforces minimum TLS versions (requests.ml lines 108-143). However, the library could improve by: (1) Documenting the security implications of verify_tls:false parameter, (2) Adding certificate pinning for high-security applications (compare cert fingerprints), (3) Supporting custom CA certificate bundles, (4) Adding OCSP stapling validation. The ~verify_tls parameter exists but lacks documentation about when/why to disable it. Implementation: Add documentation warnings about verify_tls:false, add optional ~pinned_certificates:(string list) for cert fingerprint pinning, consider ~ca_cert_file parameter for custom CA bundles." 137 - }, 138 - { 139 - "source_repo": "third_party/c++/nfhttp", 140 - "source_language": "C++", 141 - "criticality": "medium", 142 - "change_type": "enhancement", 143 - "title": "Add synchronous request API for simple use cases", 144 - "description": "NFHTTP provides performRequestSynchronously (Client.cpp lines 54-66) alongside the async API. The OCaml library has Requests.One for stateless requests but might benefit from a more explicit synchronous variant of the main session API for blocking operations.", 145 - "affected_files": [ 146 - "lib/requests.ml", 147 - "lib/requests.mli" 148 - ], 149 - "rationale": "NFHTTP recognizes that some use cases benefit from a synchronous blocking API rather than callback-based async. While Eio is async by nature, the library could provide a convenience function like Requests.get_sync that wraps the promise-style API for simple scripts or REPL usage. However, since OCaml with Eio handles this more naturally than C++ callbacks (you can simply await the promise inline), this is lower priority. The existing Requests.get returns immediately and can be used synchronously. Consider adding documentation examples showing synchronous patterns with Eio rather than a separate API. The Requests.One module already serves this purpose for one-shot requests. Priority: Low unless user feedback indicates confusion." 150 - }, 151 - { 152 - "source_repo": "third_party/c++/nfhttp", 153 - "source_language": "C++", 154 - "criticality": "low", 155 - "change_type": "enhancement", 156 - "title": "Add platform-specific HTTP client backend abstraction", 157 - "description": "NFHTTP uses a layered architecture with platform-specific backends (ClientCurl for Linux, ClientNSURLSession for iOS/macOS, ClientCpprestsdk for Windows). While not directly applicable to OCaml, consider abstracting the HTTP transport to support multiple backends (currently hardcoded to Eio.Net).", 158 - "affected_files": [ 159 - "lib/http_client.ml", 160 - "lib/requests.ml" 161 - ], 162 - "rationale": "NFHTTP's architecture separates protocol handling from platform-specific network I/O, allowing native platform APIs for better battery life and OS integration. For OCaml, this pattern could enable: (1) Testing backend using in-memory request/response pairs (VCR pattern), (2) Proxy/tunnel backend for debugging, (3) HTTP/2 backend via different library when available, (4) Mock backend for unit tests without network. Currently Http_client.ml directly uses Eio.Net and Conpool. Implementation: Define a Backend module type with perform_request signature, make Http_client parameterized by backend, provide Eio_backend (default) and Mock_backend (testing). This would significantly improve testability and future extensibility. However, this is a significant refactoring with unclear immediate benefit." 163 - } 164 - ] 165 - }
-271
third_party/c++/proxygen.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/c++/proxygen", 5 - "source_language": "C++", 6 - "criticality": "high", 7 - "change_type": "feature", 8 - "title": "Add HTTP/2 Support with Multiplexing", 9 - "description": "Proxygen supports HTTP/2 with multiplexing, allowing multiple concurrent request/response pairs over a single connection. The OCaml library currently only supports HTTP/1.1. Adding HTTP/2 support would significantly improve performance for applications making many requests to the same server by reducing connection overhead, supporting server push, and enabling header compression (HPACK).", 10 - "affected_files": [ 11 - "lib/http_client.ml", 12 - "lib/requests.ml", 13 - "ocaml-conpool/lib/conpool.ml", 14 - "lib/one.ml" 15 - ], 16 - "rationale": "HTTP/2 is now widely supported and provides substantial performance improvements through multiplexing, header compression, and binary framing. Proxygen's HTTPSession abstraction shows how to manage multiple concurrent transactions over a single connection. This would reduce latency and improve throughput for API clients making many requests." 17 - }, 18 - { 19 - "source_repo": "third_party/c++/proxygen", 20 - "source_language": "C++", 21 - "criticality": "medium", 22 - "change_type": "enhancement", 23 - "title": "Implement Per-Transaction Flow Control", 24 - "description": "Proxygen implements sophisticated flow control at both the session and transaction level using Window management. The OCaml library currently lacks explicit flow control mechanisms. Adding flow control would prevent memory exhaustion when dealing with fast senders and slow receivers, allowing backpressure to be communicated properly.", 25 - "affected_files": [ 26 - "lib/http_client.ml", 27 - "lib/response.ml", 28 - "lib/body.ml" 29 - ], 30 - "rationale": "Proxygen's Window class manages flow control windows for HTTP/2 streams. While the OCaml library uses Eio's streaming capabilities, it doesn't have explicit flow control to pause/resume reading based on downstream consumption. This could lead to memory issues with large responses when the consumer is slower than the producer." 31 - }, 32 - { 33 - "source_repo": "third_party/c++/proxygen", 34 - "source_language": "C++", 35 - "criticality": "medium", 36 - "change_type": "feature", 37 - "title": "Add Request Priority Support", 38 - "description": "Proxygen supports HTTP/2 priority trees (HTTP2PriorityQueue) allowing requests to be prioritized. The OCaml library has no concept of request priority. Adding priority support would enable applications to ensure critical requests are processed before less important ones, improving user experience.", 39 - "affected_files": [ 40 - "lib/requests.ml", 41 - "lib/one.ml", 42 - "lib/http_client.ml" 43 - ], 44 - "rationale": "Proxygen's priority system allows applications to specify dependencies and weights for requests. This is particularly useful for web applications where HTML should be fetched before CSS/JS, or for API clients where certain requests are more time-sensitive. This would map well to Eio's fiber priorities." 45 - }, 46 - { 47 - "source_repo": "third_party/c++/proxygen", 48 - "source_language": "C++", 49 - "criticality": "low", 50 - "change_type": "enhancement", 51 - "title": "Add Connection Drain Support for Graceful Shutdown", 52 - "description": "Proxygen implements connection draining mechanisms (drainAllSessions, drain timeout) for graceful shutdowns. The OCaml library relies entirely on Eio's switch cleanup. Adding explicit drain support would allow in-flight requests to complete before shutdown while preventing new requests.", 53 - "affected_files": [ 54 - "ocaml-conpool/lib/conpool.ml", 55 - "lib/requests.ml" 56 - ], 57 - "rationale": "Proxygen's SessionPool has drainAllSessions() to gracefully close connections. While Eio switches handle cleanup, explicit draining would allow better control over shutdown behavior, especially for long-lived services that need to handle SIGTERM gracefully without dropping in-flight requests." 58 - }, 59 - { 60 - "source_repo": "third_party/c++/proxygen", 61 - "source_language": "C++", 62 - "criticality": "high", 63 - "change_type": "security", 64 - "title": "Implement Frame Size Limits for DoS Prevention", 65 - "description": "Proxygen enforces frame size limits to prevent denial-of-service attacks via oversized frames. While the OCaml library has Response_limits for body/header size, it lacks granular frame-level limits. Adding frame size validation would provide defense-in-depth against malicious servers.", 66 - "affected_files": [ 67 - "lib/response_limits.ml", 68 - "lib/http_read.ml" 69 - ], 70 - "rationale": "Proxygen's RateLimitFilter and frame size checks prevent attackers from sending extremely large frames that could exhaust memory or CPU. The OCaml library has max_header_size and max_response_body_size, but doesn't limit individual chunks in chunked encoding or validate frame sizes during parsing, creating a potential DoS vector." 71 - }, 72 - { 73 - "source_repo": "third_party/c++/proxygen", 74 - "source_language": "C++", 75 - "criticality": "medium", 76 - "change_type": "enhancement", 77 - "title": "Add Connection Age-Based Eviction", 78 - "description": "Proxygen's SessionPool implements max age-based eviction (maxAge parameter), discarding connections that have existed too long regardless of activity. The OCaml conpool has max_connection_lifetime, but this is already implemented. However, Proxygen also has idle connection eviction with LRU ordering that could be enhanced.", 79 - "affected_files": [ 80 - "ocaml-conpool/lib/endpoint.ml" 81 - ], 82 - "rationale": "Proxygen uses LRU ordering for idle connection eviction, ensuring the oldest idle connections are removed first. The OCaml conpool has idle timeout and lifetime limits but could benefit from more sophisticated eviction strategies like LRU to better manage connection churn and avoid keeping stale connections." 83 - }, 84 - { 85 - "source_repo": "third_party/c++/proxygen", 86 - "source_language": "C++", 87 - "criticality": "low", 88 - "change_type": "enhancement", 89 - "title": "Add Byte Event Tracking for Observability", 90 - "description": "Proxygen tracks detailed byte-level events (ByteEventTracker) including when specific bytes are written, acknowledged, and transmitted. The OCaml library has basic statistics (bytes read/written) but lacks fine-grained event tracking. Adding byte event tracking would improve observability and debugging.", 91 - "affected_files": [ 92 - "ocaml-conpool/lib/stats.ml", 93 - "lib/requests.ml" 94 - ], 95 - "rationale": "Proxygen's ByteEventTracker allows applications to track when specific bytes reach certain milestones (enqueued, transmitted, ACKed). This is valuable for performance monitoring, latency analysis, and debugging network issues. The OCaml library currently only tracks total bytes transferred." 96 - }, 97 - { 98 - "source_repo": "third_party/c++/proxygen", 99 - "source_language": "C++", 100 - "criticality": "medium", 101 - "change_type": "enhancement", 102 - "title": "Implement Idle Connection Timeout per Transaction", 103 - "description": "Proxygen has both session-level idle timeout and per-transaction timeout tracking with HHWheelTimer. The OCaml library has connection-level idle timeout in conpool and request timeouts, but lacks per-stream idle timeout tracking. This would enable more granular timeout control.", 104 - "affected_files": [ 105 - "lib/timeout.ml", 106 - "lib/http_client.ml" 107 - ], 108 - "rationale": "Proxygen's HHWheelTimer provides efficient timeout tracking per transaction, allowing different requests on the same connection to have different timeout characteristics. The OCaml library has global connect/read/total timeouts but could benefit from per-request idle timeout tracking for HTTP/2 multiplexing." 109 - }, 110 - { 111 - "source_repo": "third_party/c++/proxygen", 112 - "source_language": "C++", 113 - "criticality": "low", 114 - "change_type": "enhancement", 115 - "title": "Add Transaction Abort Support", 116 - "description": "Proxygen's HTTPTransaction has sendAbort() to immediately terminate a request/response without waiting for normal completion. The OCaml library can cancel via switch cancellation but lacks explicit abort semantics. Adding abort would allow more graceful cancellation with proper protocol signaling.", 117 - "affected_files": [ 118 - "lib/http_client.ml", 119 - "lib/requests.ml", 120 - "lib/one.ml" 121 - ], 122 - "rationale": "Proxygen's sendAbort() sends a proper protocol-level abort signal (e.g., RST_STREAM in HTTP/2), allowing the server to stop processing and release resources. Eio's switch cancellation works but doesn't send protocol-level signals. Explicit abort would be cleaner for HTTP/2." 123 - }, 124 - { 125 - "source_repo": "third_party/c++/proxygen", 126 - "source_language": "C++", 127 - "criticality": "medium", 128 - "change_type": "feature", 129 - "title": "Add WebSocket and WebTransport Support", 130 - "description": "Proxygen supports WebSocket upgrade and WebTransport for bidirectional streaming. The OCaml library is HTTP-only. Adding WebSocket support would enable real-time applications, server-sent events, and bidirectional streaming use cases that are common in modern web applications.", 131 - "affected_files": [ 132 - "lib/requests.ml", 133 - "lib/one.ml", 134 - "lib/http_client.ml" 135 - ], 136 - "rationale": "Proxygen's HTTPTransaction supports WebSocket upgrade and WebTransport streams. Many modern APIs use WebSockets for real-time features (chat, notifications, live updates). Adding WebSocket support would expand the library's use cases significantly, leveraging Eio's bidirectional flow capabilities." 137 - }, 138 - { 139 - "source_repo": "third_party/c++/proxygen", 140 - "source_language": "C++", 141 - "criticality": "low", 142 - "change_type": "enhancement", 143 - "title": "Add Egress Rate Limiting", 144 - "description": "Proxygen implements egress rate limiting to control the rate of outgoing data. The OCaml library has no rate limiting capabilities. Adding egress rate limiting would prevent overwhelming servers and enable better bandwidth management in client applications.", 145 - "affected_files": [ 146 - "lib/http_client.ml", 147 - "lib/body.ml" 148 - ], 149 - "rationale": "Proxygen's egress rate limiting prevents clients from overwhelming servers with requests. This is useful for batch processing, bulk uploads, or being a good citizen when making many requests. The OCaml library could implement this using Eio's timer and flow control primitives." 150 - }, 151 - { 152 - "source_repo": "third_party/c++/proxygen", 153 - "source_language": "C++", 154 - "criticality": "high", 155 - "change_type": "security", 156 - "title": "Add TLS Session Resumption Support", 157 - "description": "Proxygen supports TLS session resumption and session tickets for performance. The OCaml library uses tls-eio but doesn't explicitly manage session caching. Adding session resumption would reduce latency and CPU usage for repeated connections to the same server.", 158 - "affected_files": [ 159 - "ocaml-conpool/lib/conpool.ml", 160 - "lib/requests.ml" 161 - ], 162 - "rationale": "Proxygen's SSL session caching and resumption significantly reduce TLS handshake overhead for repeated connections. The tls library supports this, but the OCaml library doesn't maintain a session cache across connection pool instances. Implementing this could reduce latency by 1 RTT per reconnection." 163 - }, 164 - { 165 - "source_repo": "third_party/c++/proxygen", 166 - "source_language": "C++", 167 - "criticality": "low", 168 - "change_type": "enhancement", 169 - "title": "Add Secondary Authentication Support (HTTP/2 Post-Handshake Auth)", 170 - "description": "Proxygen implements secondary authentication for HTTP/2 (SecondaryAuthManagerBase) allowing post-handshake certificate requests. The OCaml library has pre-request auth only. Adding secondary auth would support advanced enterprise security scenarios requiring re-authentication.", 171 - "affected_files": [ 172 - "lib/auth.ml", 173 - "lib/http_client.ml" 174 - ], 175 - "rationale": "Proxygen's secondary authentication allows servers to request additional authentication after the initial handshake. While rarely used, this is required for some enterprise scenarios with strict security requirements. This would primarily be useful once HTTP/2 support is added." 176 - }, 177 - { 178 - "source_repo": "third_party/c++/proxygen", 179 - "source_language": "C++", 180 - "criticality": "medium", 181 - "change_type": "enhancement", 182 - "title": "Implement Replay Safety Callbacks for 0-RTT", 183 - "description": "Proxygen has isReplaySafe() and addWaitingForReplaySafety() to handle TLS 1.3 0-RTT (early data) safely. The OCaml library doesn't handle 0-RTT early data. Adding replay safety would enable safe use of TLS 1.3 0-RTT for reduced latency on repeated connections.", 184 - "affected_files": [ 185 - "ocaml-conpool/lib/conpool.ml", 186 - "lib/requests.ml" 187 - ], 188 - "rationale": "Proxygen's replay safety mechanisms prevent non-idempotent requests from being sent as 0-RTT early data, which could be replayed by attackers. TLS 1.3 0-RTT can reduce latency by 1 RTT but requires careful handling. The tls library supports this, but the HTTP client needs application-level replay safety logic." 189 - }, 190 - { 191 - "source_repo": "third_party/c++/proxygen", 192 - "source_language": "C++", 193 - "criticality": "medium", 194 - "change_type": "enhancement", 195 - "title": "Add Detailed Error Classification System", 196 - "description": "Proxygen's HTTPException has multiple error code types (httpStatusCode, codecStatusCode, http3ErrorCode) and direction information (INGRESS/EGRESS). The OCaml library has granular error types but lacks direction and multi-layer error classification. Enhancing error classification would improve debugging.", 197 - "affected_files": [ 198 - "lib/error.ml", 199 - "lib/error.mli" 200 - ], 201 - "rationale": "Proxygen's multi-layer error system distinguishes between application errors, protocol errors, and transport errors, with direction indicating if the error was in receiving or sending. The OCaml library has good error types but could add direction and layer information to help developers understand where failures occur." 202 - }, 203 - { 204 - "source_repo": "third_party/c++/proxygen", 205 - "source_language": "C++", 206 - "criticality": "low", 207 - "change_type": "enhancement", 208 - "title": "Add Connection Pool Tiering (Idle/Partial/Full)", 209 - "description": "Proxygen's SessionPool uses three-tier connection management (idle, partially filled, full) based on transaction capacity. The OCaml conpool has a simpler active/idle model. Adding tiered management would enable better connection reuse for HTTP/2 multiplexing.", 210 - "affected_files": [ 211 - "ocaml-conpool/lib/endpoint.ml", 212 - "ocaml-conpool/lib/conpool.ml" 213 - ], 214 - "rationale": "Proxygen's three-tier system optimizes for HTTP/2 where connections can handle multiple concurrent requests. Connections move between tiers based on transaction count. This would be valuable once HTTP/2 support is added, enabling better load distribution across connections." 215 - }, 216 - { 217 - "source_repo": "third_party/c++/proxygen", 218 - "source_language": "C++", 219 - "criticality": "low", 220 - "change_type": "enhancement", 221 - "title": "Add Mock Objects for Testing", 222 - "description": "Proxygen provides comprehensive mock objects (HTTPSessionMocks, HTTPTransactionMocks, MockHTTPCodec) for testing. The OCaml library has integration tests but lacks mock objects for unit testing. Adding mocks would enable faster, more reliable unit tests.", 223 - "affected_files": [ 224 - "test/test_simple.ml", 225 - "test/mocks.ml" 226 - ], 227 - "rationale": "Proxygen's mock-based testing infrastructure allows unit testing of individual components without network I/O. The OCaml library primarily uses integration tests with real HTTP servers. Adding Eio-compatible mocks would enable faster unit tests and better test coverage of error conditions." 228 - }, 229 - { 230 - "source_repo": "third_party/c++/proxygen", 231 - "source_language": "C++", 232 - "criticality": "medium", 233 - "change_type": "enhancement", 234 - "title": "Add ALPN (Application-Layer Protocol Negotiation) Support", 235 - "description": "Proxygen uses ALPN during TLS handshake to negotiate HTTP protocol version (h2, http/1.1). The OCaml library doesn't use ALPN. Adding ALPN would enable automatic protocol selection and is required for proper HTTP/2 support over TLS.", 236 - "affected_files": [ 237 - "ocaml-conpool/lib/conpool.ml", 238 - "lib/requests.ml" 239 - ], 240 - "rationale": "Proxygen negotiates HTTP/2 vs HTTP/1.1 using ALPN during the TLS handshake. The tls library supports ALPN, but the OCaml HTTP client doesn't configure it. This is essential for HTTP/2 support and allows servers to indicate their preferred protocol version." 241 - }, 242 - { 243 - "source_repo": "third_party/c++/proxygen", 244 - "source_language": "C++", 245 - "criticality": "low", 246 - "change_type": "enhancement", 247 - "title": "Add Request/Response Trailer Support", 248 - "description": "Proxygen supports HTTP trailers (headers sent after the body in chunked encoding). The OCaml library doesn't handle trailers. Adding trailer support would enable use cases like streaming signatures, final checksums, and dynamic metadata.", 249 - "affected_files": [ 250 - "lib/http_read.ml", 251 - "lib/http_write.ml", 252 - "lib/response.ml", 253 - "lib/headers.ml" 254 - ], 255 - "rationale": "Proxygen's HTTPTransaction supports sending and receiving trailers, which are headers sent after the message body. Trailers are useful for checksums, signatures, or metadata that can only be computed after streaming the body. The OCaml library currently ignores trailers." 256 - }, 257 - { 258 - "source_repo": "third_party/c++/proxygen", 259 - "source_language": "C++", 260 - "criticality": "medium", 261 - "change_type": "feature", 262 - "title": "Add Connection Health Check Callbacks", 263 - "description": "Proxygen allows custom connection validation beyond basic age/idle checks. The OCaml conpool has an optional health_check function but it's not well documented or used. Improving health check capabilities would reduce errors from stale connections.", 264 - "affected_files": [ 265 - "ocaml-conpool/lib/config.ml", 266 - "ocaml-conpool/lib/endpoint.ml" 267 - ], 268 - "rationale": "Proxygen validates connections before reuse. The OCaml conpool has health_check in config but it's minimally used. Enhancing this with common checks (TCP keepalive, application-level ping for HTTP/2, TLS session validity) would prevent failures from reusing dead connections that passed basic validation." 269 - } 270 - ] 271 - }
-286
third_party/c++/webcc.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "webcc", 5 - "source_language": "C++", 6 - "criticality": "medium", 7 - "change_type": "enhancement", 8 - "title": "Subsequent Read Timeout for Streaming Responses", 9 - "description": "Add a separate timeout for subsequent reads during response body streaming, distinct from the initial read timeout. This prevents hangs when receiving large responses over slow connections where the initial connection succeeds but individual chunks arrive slowly.", 10 - "affected_files": [ 11 - "lib/timeout.mli", 12 - "lib/timeout.ml", 13 - "lib/http_client.ml", 14 - "lib/requests.mli", 15 - "lib/requests.ml" 16 - ], 17 - "rationale": "Webcc implements three separate timeout mechanisms: connect_timeout (TCP connection), read_timeout (initial read), and subsequent_read_timeout (per-chunk during streaming, default 10s). The OCaml library currently has connect, read, and total timeouts, but no subsequent_read_timeout. This means that when streaming a large response, a single slow chunk could cause the entire request to hang for the full read_timeout duration. A subsequent_read_timeout allows fine-grained control over chunk-by-chunk streaming, preventing indefinite hangs while still allowing long total response times for large files." 18 - }, 19 - { 20 - "source_repo": "webcc", 21 - "source_language": "C++", 22 - "criticality": "low", 23 - "change_type": "feature", 24 - "title": "Progress Callback for Upload/Download Tracking", 25 - "description": "Add optional progress callback functionality to track upload and download progress, useful for implementing progress bars or monitoring large file transfers. Callback should receive: bytes_transferred, total_bytes (or None for chunked), and direction (upload vs download).", 26 - "affected_files": [ 27 - "lib/requests.mli", 28 - "lib/requests.ml", 29 - "lib/one.mli", 30 - "lib/one.ml", 31 - "lib/http_client.ml" 32 - ], 33 - "rationale": "Webcc provides ProgressCallback = function<void(current, total, is_read)> that allows applications to monitor transfer progress. This is particularly valuable for: (1) implementing progress bars in CLI tools or GUIs, (2) detecting stalled transfers, (3) logging transfer statistics. The OCaml library has no equivalent mechanism. Since the library already uses Eio flows for streaming, callbacks could be implemented by wrapping flows with a progress-tracking layer that invokes user callbacks periodically." 34 - }, 35 - { 36 - "source_repo": "webcc", 37 - "source_language": "C++", 38 - "criticality": "medium", 39 - "change_type": "enhancement", 40 - "title": "Configurable Buffer Size for Socket Operations", 41 - "description": "Expose buffer_size configuration (default 1024 bytes) to allow users to tune performance for different use cases. Larger buffers can significantly improve throughput for high-bandwidth connections, while smaller buffers reduce memory usage for many concurrent connections.", 42 - "affected_files": [ 43 - "lib/http_client.ml", 44 - "lib/requests.mli", 45 - "lib/requests.ml", 46 - "lib/one.mli", 47 - "lib/one.ml" 48 - ], 49 - "rationale": "Webcc allows configuring buffer_size via set_buffer_size() (default 1KB). The OCaml library appears to use fixed buffer sizes in Eio operations. Different workloads benefit from different buffer sizes: (1) High-bandwidth connections benefit from larger buffers (4KB-64KB) to reduce syscall overhead, (2) Many concurrent connections benefit from smaller buffers to reduce memory pressure, (3) Streaming large files benefits from larger buffers. Exposing this as a tunable parameter improves performance flexibility without changing defaults." 50 - }, 51 - { 52 - "source_repo": "webcc", 53 - "source_language": "C++", 54 - "criticality": "low", 55 - "change_type": "enhancement", 56 - "title": "Explicit Connection Keep-Alive Control", 57 - "description": "Add explicit API to enable/disable HTTP keep-alive (persistent connections) on a per-session or per-request basis. Currently keep-alive is implicitly managed by the connection pool, but users may want to force connection closure for specific scenarios.", 58 - "affected_files": [ 59 - "lib/requests.mli", 60 - "lib/requests.ml", 61 - "lib/headers.mli", 62 - "lib/headers.ml" 63 - ], 64 - "rationale": "Webcc provides ClientSession::KeepAlive(bool) to control the Connection header (Keep-Alive vs Close). The OCaml library automatically manages keep-alive through connection pooling but doesn't expose explicit control. Use cases for disabling keep-alive: (1) Testing connection establishment logic, (2) Working with servers that mishandle keep-alive, (3) Ensuring fresh connections for security-sensitive operations. This could be implemented by adding Headers.connection_close/connection_keep_alive functions and a ~keep_alive parameter to request functions." 65 - }, 66 - { 67 - "source_repo": "webcc", 68 - "source_language": "C++", 69 - "criticality": "medium", 70 - "change_type": "enhancement", 71 - "title": "Content-Type and Charset Convenience Setters", 72 - "description": "Add session-level default Content-Type and charset configuration that applies to all requests with bodies (unless explicitly overridden). This reduces boilerplate when an application consistently uses the same content type (e.g., always sending JSON).", 73 - "affected_files": [ 74 - "lib/requests.mli", 75 - "lib/requests.ml" 76 - ], 77 - "rationale": "Webcc provides ClientSession::SetContentType(media_type, charset) to set default Content-Type that applies when requests have bodies but no explicit Content-Type. This is a quality-of-life improvement that reduces repetitive header setting. Example use case: A REST API client that always sends JSON can set this once on the session rather than on every request. The OCaml library requires setting Content-Type per-request or per-default-header, but default-header always applies even to GET requests. A smarter default that only applies to requests with bodies would be more intuitive." 78 - }, 79 - { 80 - "source_repo": "webcc", 81 - "source_language": "C++", 82 - "criticality": "low", 83 - "change_type": "enhancement", 84 - "title": "Accept Header Convenience Setter", 85 - "description": "Add a dedicated Accept header convenience function at the session level (in addition to the existing Headers.accept function) to set default accepted content types for all requests in a session.", 86 - "affected_files": [ 87 - "lib/requests.mli", 88 - "lib/requests.ml" 89 - ], 90 - "rationale": "Webcc provides ClientSession::Accept(content_types) as a session-level convenience method. While the OCaml library has Headers.accept for per-request use, a session-level setter would improve ergonomics for API clients that always accept the same content types. This complements the Content-Type enhancement and provides a consistent pattern for session-level header defaults. Implementation would use the existing set_default_header mechanism internally." 91 - }, 92 - { 93 - "source_repo": "webcc", 94 - "source_language": "C++", 95 - "criticality": "low", 96 - "change_type": "enhancement", 97 - "title": "Separate SSL Shutdown Timeout", 98 - "description": "Add a dedicated ssl_shutdown_timeout configuration option (separate from read timeout) to control how long to wait for graceful SSL/TLS connection shutdown. This prevents hangs during cleanup when servers don't respond promptly to shutdown notifications.", 99 - "affected_files": [ 100 - "lib/timeout.mli", 101 - "lib/timeout.ml", 102 - "lib/one.ml" 103 - ], 104 - "rationale": "Webcc implements set_ssl_shutdown_timeout() to control SSL/TLS shutdown duration (default varies). SSL/TLS shutdown is a separate phase from the main request/response cycle and may require different timeout characteristics. Servers sometimes ignore SSL shutdown packets, causing hangs during cleanup. A dedicated short timeout (e.g., 5-10s) for this phase prevents resource leaks and improves responsiveness during application shutdown, while allowing longer timeouts for actual data transfer." 105 - }, 106 - { 107 - "source_repo": "webcc", 108 - "source_language": "C++", 109 - "criticality": "medium", 110 - "change_type": "enhancement", 111 - "title": "Connection Cancellation API", 112 - "description": "Add a Cancel() method to abort in-progress requests (connecting, reading, or writing) without closing the entire session. This enables responsive cancellation for long-running operations, particularly useful in interactive applications or when implementing request timeouts externally.", 113 - "affected_files": [ 114 - "lib/requests.mli", 115 - "lib/requests.ml", 116 - "lib/http_client.ml" 117 - ], 118 - "rationale": "Webcc provides ClientSession::Cancel() which is thread-safe and cancels any in-progress operations by closing active client connections. The OCaml library relies on Eio's switch mechanism for cancellation, which works well for structured concurrency but doesn't provide a direct 'cancel this specific request' API. Use cases: (1) User clicking 'Cancel' button in UI, (2) Application-level timeout enforcement, (3) Graceful shutdown when some requests should be abandoned. This could be implemented by storing cancellation tokens in the request state and providing a cancel function that triggers them." 119 - }, 120 - { 121 - "source_repo": "webcc", 122 - "source_language": "C++", 123 - "criticality": "low", 124 - "change_type": "enhancement", 125 - "title": "Error Code Enumeration for Programmatic Handling", 126 - "description": "Add numeric error codes to the Error module to enable more efficient error categorization without string matching or pattern matching on error variants. This allows fast error filtering in performance-sensitive retry logic.", 127 - "affected_files": [ 128 - "lib/error.mli", 129 - "lib/error.ml" 130 - ], 131 - "rationale": "Webcc defines error_codes namespace with constants (kOK=0, kStateError=1, kResolveError=3, kConnectError=4, etc.) that enable numeric error categorization. While the OCaml library has excellent typed error variants and query functions (is_timeout, is_retryable, etc.), adding optional numeric error codes could provide: (1) More efficient error filtering in hot paths, (2) Easier interop with systems expecting numeric error codes, (3) Stable error identifiers across versions. This would be a supplementary feature, not a replacement for the existing error types." 132 - }, 133 - { 134 - "source_repo": "webcc", 135 - "source_language": "C++", 136 - "criticality": "low", 137 - "change_type": "enhancement", 138 - "title": "Maximum Response Body Size Logging", 139 - "description": "Add configuration to limit the amount of response body data included in error messages and logs (similar to webcc's kMaxDumpSize=2048 bytes). Currently the library previews error response bodies but doesn't document a size limit.", 140 - "affected_files": [ 141 - "lib/error.ml", 142 - "lib/response_limits.mli", 143 - "lib/response_limits.ml" 144 - ], 145 - "rationale": "Webcc defines kMaxDumpSize=2048 to truncate large responses in logs/errors, preventing log spam and memory issues when servers return huge error pages. The OCaml library's Error module includes body_preview fields but should document and enforce a maximum preview size. This prevents: (1) Massive error messages filling logs, (2) Memory pressure from storing large error bodies, (3) Sensitive data leakage from large error responses. Recommend documenting current behavior and potentially adding it to Response_limits configuration." 146 - }, 147 - { 148 - "source_repo": "webcc", 149 - "source_language": "C++", 150 - "criticality": "low", 151 - "change_type": "feature", 152 - "title": "Media Type from File Extension Utility", 153 - "description": "Add a utility function to infer MIME type from file extensions, expanding beyond the current implementation. Webcc provides a comprehensive media_types::FromExtension() function for common file types.", 154 - "affected_files": [ 155 - "lib/mime.mli", 156 - "lib/mime.ml" 157 - ], 158 - "rationale": "Webcc includes media_types::FromExtension() to determine MIME types from file extensions. The OCaml library's Body.of_file does infer MIME types but this utility could be exposed publicly for other use cases like: (1) Setting correct Accept headers based on expected file type, (2) Validating downloaded file types, (3) Building multipart uploads with correct content types. This is a convenience feature that improves API ergonomics and reduces the need for external MIME type libraries." 159 - }, 160 - { 161 - "source_repo": "webcc", 162 - "source_language": "C++", 163 - "criticality": "low", 164 - "change_type": "enhancement", 165 - "title": "Gzip Compression Threshold Configuration", 166 - "description": "Add configuration for the minimum body size that triggers automatic compression (currently appears to be implicit). Webcc uses kGzipThreshold=1400 bytes based on TCP packet size optimization.", 167 - "affected_files": [ 168 - "lib/requests.mli", 169 - "lib/requests.ml", 170 - "lib/body.ml" 171 - ], 172 - "rationale": "Webcc defines kGzipThreshold=1400 bytes, chosen because smaller payloads may not benefit from compression (compression overhead can exceed size savings for small payloads, and they often fit in a single TCP packet anyway). The OCaml library supports automatic decompression but if it adds automatic compression in the future, it should use a similar threshold. This constant is based on the principle that payloads under ~1400 bytes (typical MTU minus headers) fit in one packet and benefit less from compression. Documenting this rationale helps users understand performance characteristics." 173 - }, 174 - { 175 - "source_repo": "webcc", 176 - "source_language": "C++", 177 - "criticality": "low", 178 - "change_type": "enhancement", 179 - "title": "CONNECT and TRACE Method Support", 180 - "description": "Add support for the CONNECT and TRACE HTTP methods, which are currently missing from the Method module. While rarely used, these methods are part of the HTTP specification and may be needed for proxy functionality or debugging.", 181 - "affected_files": [ 182 - "lib/method.mli", 183 - "lib/method.ml", 184 - "lib/requests.mli", 185 - "lib/requests.ml" 186 - ], 187 - "rationale": "Webcc supports all standard HTTP methods including CONNECT (for establishing tunnels through proxies) and TRACE (for diagnostic loop-back testing). The OCaml library supports GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS but not CONNECT or TRACE. While these methods are rarely used in typical API clients, they are: (1) Part of the HTTP/1.1 specification (RFC 7231), (2) Required for implementing HTTP proxy functionality, (3) Useful for advanced debugging scenarios. Adding them improves spec compliance and future-proofs the library." 188 - }, 189 - { 190 - "source_repo": "webcc", 191 - "source_language": "C++", 192 - "criticality": "high", 193 - "change_type": "security", 194 - "title": "Content-MD5 Integrity Verification", 195 - "description": "Add support for Content-MD5 header verification to detect corrupted or tampered response bodies. When a server provides a Content-MD5 header, the client should optionally verify the MD5 hash of the received body matches.", 196 - "affected_files": [ 197 - "lib/response.mli", 198 - "lib/response.ml", 199 - "lib/http_read.ml", 200 - "lib/headers.mli" 201 - ], 202 - "rationale": "Webcc defines headers::kContentMD5 constant, acknowledging this security header. While MD5 is cryptographically broken for collision resistance, it's still useful for detecting accidental corruption during transmission. The OCaml library could add: (1) Headers.content_md5 setter/getter, (2) Optional response body verification (opt-in due to MD5 weakness), (3) Error variant for Content_md5_mismatch. This provides defense-in-depth against corrupted downloads, particularly useful for large file transfers where bit-flips during transmission are possible. Modern alternatives like SHA-256 could be supported alongside MD5." 203 - }, 204 - { 205 - "source_repo": "webcc", 206 - "source_language": "C++", 207 - "criticality": "medium", 208 - "change_type": "enhancement", 209 - "title": "Connection State Introspection", 210 - "description": "Add API to query connection state, such as whether a connection is currently established, the number of active connections, or connection pool statistics. This helps with debugging, monitoring, and implementing graceful shutdown.", 211 - "affected_files": [ 212 - "lib/requests.mli", 213 - "lib/requests.ml", 214 - "lib/http_client.ml" 215 - ], 216 - "rationale": "Webcc provides ClientBase::connected() to check connection state and Close() to explicitly close connections. The OCaml library manages connections transparently through the pool but doesn't expose introspection. Use cases: (1) Health checks to verify connectivity, (2) Monitoring connection pool utilization, (3) Debugging connection reuse behavior, (4) Implementing graceful shutdown by draining active connections. This could be implemented by adding functions like: connection_count, pool_stats, is_connected, etc." 217 - }, 218 - { 219 - "source_repo": "webcc", 220 - "source_language": "C++", 221 - "criticality": "low", 222 - "change_type": "enhancement", 223 - "title": "Request/Response Access from Error Objects", 224 - "description": "Add ability to access the original request details and partial response (if any) from error exceptions. This helps with debugging, retry logic, and logging by providing full context about what failed.", 225 - "affected_files": [ 226 - "lib/error.mli", 227 - "lib/error.ml" 228 - ], 229 - "rationale": "Webcc's Error class and ClientBase provide access to both request() and response() objects, allowing error handlers to inspect what was sent and what (if anything) was received. The OCaml library's error types include some context (URL, status, headers for HTTP errors) but not full request/response access. Enhanced error context would enable: (1) Better logging with full request details, (2) Smart retry decisions based on request characteristics, (3) Debugging by inspecting exact headers sent/received. This could be added as optional fields in error variants." 230 - }, 231 - { 232 - "source_repo": "webcc", 233 - "source_language": "C++", 234 - "criticality": "low", 235 - "change_type": "enhancement", 236 - "title": "User-Agent Default Value", 237 - "description": "Set a default User-Agent header identifying the library (e.g., 'OCaml-Requests/1.0') if the user doesn't specify one. This improves debugging and helps server operators identify client types in logs.", 238 - "affected_files": [ 239 - "lib/requests.ml", 240 - "lib/one.ml" 241 - ], 242 - "rationale": "Webcc automatically sets a User-Agent header through InitHeaders(). The OCaml library doesn't appear to set a default User-Agent, meaning requests may be sent without one. Benefits of a default User-Agent: (1) Server logs can identify the client library, (2) Server operators can contact users if their client is misbehaving, (3) Some servers may block requests without User-Agent as potential bot traffic. The default should be overridable. Suggested format: 'ocaml-requests/<version> eio/<version> ocaml/<version>'." 243 - }, 244 - { 245 - "source_repo": "webcc", 246 - "source_language": "C++", 247 - "criticality": "medium", 248 - "change_type": "enhancement", 249 - "title": "Asynchronous DNS Resolution Timeout", 250 - "description": "Ensure DNS resolution has a separate timeout (potentially part of connect_timeout or as a distinct dns_timeout) to prevent hangs during name resolution. DNS lookups can sometimes hang indefinitely.", 251 - "affected_files": [ 252 - "lib/timeout.mli", 253 - "lib/timeout.ml", 254 - "lib/http_client.ml" 255 - ], 256 - "rationale": "Webcc implements async DNS resolution with timeout control via deadline timers in AsyncResolve()/OnResolve(). The OCaml library should ensure DNS resolution is subject to timeout constraints. DNS resolution can hang due to: (1) Unresponsive DNS servers, (2) Network issues between client and DNS server, (3) DNS amplification attacks causing DNS server overload. This timeout should likely be part of the connect_timeout budget, but the implementation should explicitly handle DNS resolution timeout as a distinct phase (raising Dns_resolution_failed error rather than generic timeout)." 257 - }, 258 - { 259 - "source_repo": "webcc", 260 - "source_language": "C++", 261 - "criticality": "low", 262 - "change_type": "enhancement", 263 - "title": "Deadline Timer Abstraction for Timeout Implementation", 264 - "description": "Document or refactor timeout implementation to use deadline-based timers rather than duration-based timers. This ensures timeouts are absolute rather than cumulative across retry attempts.", 265 - "affected_files": [ 266 - "lib/timeout.ml", 267 - "lib/retry.ml", 268 - "lib/http_client.ml" 269 - ], 270 - "rationale": "Webcc uses boost::asio::steady_timer with deadline semantics (AsyncWaitDeadlineTimer, OnDeadlineTimer, StopDeadlineTimer). This ensures that total_timeout is an absolute deadline, not reset on each retry. The OCaml library's retry logic respects total timeout, but the implementation should ensure that the total timeout is a hard deadline computed at the start of the first attempt, not a per-attempt duration. This prevents the total request time from exceeding total_timeout even with retries. Review the current implementation to ensure it uses deadline semantics correctly." 271 - }, 272 - { 273 - "source_repo": "webcc", 274 - "source_language": "C++", 275 - "criticality": "low", 276 - "change_type": "enhancement", 277 - "title": "Server-Side Features Documentation", 278 - "description": "Add documentation noting that the library is client-focused and does not implement server functionality (unlike webcc which includes both client and server). This manages user expectations and prevents confusion.", 279 - "affected_files": [ 280 - "README.md", 281 - "lib/requests.mli" 282 - ], 283 - "rationale": "Webcc is a client AND server library with full HTTP server support (routing, views, connection pooling, request handling). The OCaml requests library is client-only. While this is clear from the API, explicit documentation prevents users from searching for non-existent server features. Recommended addition: A clear statement in the README and main module documentation that this is an HTTP client library only, and pointing to alternative OCaml HTTP server libraries (Dream, Cohttp server, httpaf, etc.) for server functionality." 284 - } 285 - ] 286 - }
-368
third_party/go/req.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/go/req", 5 - "source_language": "Go", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add Request/Response Middleware System", 9 - "description": "Implement a middleware/hook system that allows users to intercept and modify requests before they are sent and responses after they are received. This enables centralized logging, request signing, response transformation, and custom error handling across all requests without modifying individual request calls.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/requests.mli", 13 - "lib/one.ml", 14 - "lib/one.mli", 15 - "lib/http_client.ml" 16 - ], 17 - "rationale": "The Go req library provides RequestMiddleware (called before request sent) and ResponseMiddleware (called after response received) that execute in a chain. This pattern is extremely valuable for cross-cutting concerns like authentication token refresh, custom logging, request signing, response transformation, and centralized error handling. OCaml could implement this using a list of functions with signatures like `type request_middleware = t -> Request.t -> (Request.t, Error.t) result` and `type response_middleware = t -> Response.t -> (Response.t, Error.t) result`. This would allow users to inject custom behavior without library modification." 18 - }, 19 - { 20 - "source_repo": "third_party/go/req", 21 - "source_language": "Go", 22 - "criticality": "low", 23 - "change_type": "enhancement", 24 - "title": "Add Request/Response Dump Capability for Debugging", 25 - "description": "Add structured dumping capabilities to inspect full HTTP request/response details including headers, body, and timing information. This should support selective dumping (headers only, body only, request only, response only) and output to different destinations (stdout, file, custom writer).", 26 - "affected_files": [ 27 - "lib/response.ml", 28 - "lib/response.mli", 29 - "lib/requests.ml", 30 - "lib/requests.mli", 31 - "lib/one.ml" 32 - ], 33 - "rationale": "The Go req library has comprehensive dump functionality with DumpOptions allowing fine-grained control over what gets dumped (request headers/body, response headers/body) and where (different io.Writers). OCaml could add `Response.dump : ?headers:bool -> ?body:bool -> ?out:Eio.Flow.sink -> Response.t -> unit` and similar configuration at the client level. This is invaluable for debugging production issues and understanding exactly what's being sent/received." 34 - }, 35 - { 36 - "source_repo": "third_party/go/req", 37 - "source_language": "Go", 38 - "criticality": "low", 39 - "change_type": "feature", 40 - "title": "Add Automatic Response Body Unmarshalling with Success/Error Types", 41 - "description": "Implement automatic unmarshalling of response bodies into user-defined success and error types based on HTTP status codes. Allow users to register type mappers that automatically parse JSON responses into the appropriate OCaml types based on whether the response indicates success (2xx) or error (4xx/5xx).", 42 - "affected_files": [ 43 - "lib/response.ml", 44 - "lib/response.mli", 45 - "lib/requests.ml", 46 - "lib/requests.mli" 47 - ], 48 - "rationale": "The Go req library's SetSuccessResult/SetErrorResult pattern with automatic unmarshalling based on ResultState greatly simplifies API client code. Instead of manually checking status codes and parsing JSON, users can call `SetSuccessResult(&user)` and get the response automatically unmarshalled. OCaml could implement this with `set_success_decoder : (Jsont.json -> 'a) -> t` and `set_error_decoder : (Jsont.json -> 'e) -> t`, then provide `Response.result : Response.t -> ('a, 'e) result` that automatically applies the appropriate decoder based on status." 49 - }, 50 - { 51 - "source_repo": "third_party/go/req", 52 - "source_language": "Go", 53 - "criticality": "medium", 54 - "change_type": "feature", 55 - "title": "Add Upload/Download Progress Callbacks", 56 - "description": "Implement progress tracking for file uploads and downloads via user-provided callback functions. Callbacks should report bytes transferred, total size, and be rate-limited to avoid excessive overhead.", 57 - "affected_files": [ 58 - "lib/body.ml", 59 - "lib/body.mli", 60 - "lib/one.ml", 61 - "lib/one.mli", 62 - "lib/requests.ml" 63 - ], 64 - "rationale": "The Go req library provides SetUploadCallback and SetDownloadCallback with configurable intervals, enabling progress bars and transfer monitoring. This is critical for user-facing applications uploading/downloading large files. OCaml could implement this using `Body.of_file_with_progress : ~callback:(int64 -> int64 -> unit) -> ~interval:float -> Eio.Path.t -> Body.t` where callback receives (bytes_transferred, total_size). Similar support needed for downloads via a wrapper around the response body flow." 65 - }, 66 - { 67 - "source_repo": "third_party/go/req", 68 - "source_language": "Go", 69 - "criticality": "low", 70 - "change_type": "enhancement", 71 - "title": "Add Base URL Support with Relative Path Resolution", 72 - "description": "Add a base_url field to the session that automatically prepends to relative URLs, allowing simpler API client code that doesn't repeat the host/scheme for every request.", 73 - "affected_files": [ 74 - "lib/requests.ml", 75 - "lib/requests.mli" 76 - ], 77 - "rationale": "The Go req library's BaseURL field allows setting `c.BaseURL = \"https://api.github.com\"` then making requests with relative paths like `c.Get(\"/user\")`. This significantly reduces repetition in API client code. OCaml should add `?base_url:string` to `create` and intelligently merge it with request URLs: if request URL is absolute, use it; if relative, prepend base_url. Implementation can use `Uri.resolve` for proper URL joining." 78 - }, 79 - { 80 - "source_repo": "third_party/go/req", 81 - "source_language": "Go", 82 - "criticality": "medium", 83 - "change_type": "feature", 84 - "title": "Add Path Parameter Substitution", 85 - "description": "Support templated URLs with placeholder substitution like `/users/{id}/posts/{post_id}` where placeholders are replaced from a parameter map. This enables cleaner REST API client code.", 86 - "affected_files": [ 87 - "lib/requests.ml", 88 - "lib/requests.mli", 89 - "lib/one.ml", 90 - "lib/one.mli" 91 - ], 92 - "rationale": "The Go req library's SetPathParam/SetPathParams allows templated URLs: `Get(\"/users/{username}\").SetPathParam(\"username\", \"alice\")`. This is cleaner than manual string concatenation and safer than Printf-style formatting. OCaml could add `?path_params:(string * string) list` to request methods and use `Str.global_replace` or similar to substitute `{key}` patterns with URL-encoded values from the params list." 93 - }, 94 - { 95 - "source_repo": "third_party/go/req", 96 - "source_language": "Go", 97 - "criticality": "medium", 98 - "change_type": "enhancement", 99 - "title": "Add Response Body Transformer Hook", 100 - "description": "Add a hook that allows transforming response bodies before they are returned to the caller. This enables automatic character encoding conversion, decryption, or custom transformations without modifying application code.", 101 - "affected_files": [ 102 - "lib/requests.ml", 103 - "lib/requests.mli", 104 - "lib/http_client.ml" 105 - ], 106 - "rationale": "The Go req library's SetResponseBodyTransformer allows automatic charset conversion to UTF-8, body decryption, or other transformations. OCaml could add `?body_transformer:(string -> (string, Error.t) result)` to session configuration. This would be called after decompression but before returning the body to the user, enabling centralized handling of non-UTF-8 encodings or encrypted responses." 107 - }, 108 - { 109 - "source_repo": "third_party/go/req", 110 - "source_language": "Go", 111 - "criticality": "low", 112 - "change_type": "enhancement", 113 - "title": "Add Ordered Form Data Support", 114 - "description": "Support preserving the order of form fields when building application/x-www-form-urlencoded request bodies. Some legacy APIs require specific field ordering for signatures or compatibility.", 115 - "affected_files": [ 116 - "lib/body.ml", 117 - "lib/body.mli" 118 - ], 119 - "rationale": "The Go req library has SetOrderedFormData which preserves field order (important for request signing in OAuth 1.0a and some legacy APIs). OCaml's current `Body.form : (string * string) list` uses an association list which maintains order, so this may already be supported. Verify that `Body.form` preserves order during URL encoding, and document this guarantee in the interface." 120 - }, 121 - { 122 - "source_repo": "third_party/go/req", 123 - "source_language": "Go", 124 - "criticality": "low", 125 - "change_type": "enhancement", 126 - "title": "Add Query Parameter Builder from Records", 127 - "description": "Support automatic conversion of OCaml records to query parameters using field names as keys, similar to Go's struct tags. This reduces boilerplate when building API requests with many optional query parameters.", 128 - "affected_files": [ 129 - "lib/requests.ml", 130 - "lib/requests.mli" 131 - ], 132 - "rationale": "The Go req library's SetQueryParamsFromStruct uses struct field tags to build query strings automatically. OCaml could use ppx_deriving to generate `to_query_params : t -> (string * string) list` functions for records. Alternatively, provide a helper that uses reflection (if available) or require manual conversion. This would simplify API clients with many optional filters/parameters." 133 - }, 134 - { 135 - "source_repo": "third_party/go/req", 136 - "source_language": "Go", 137 - "criticality": "low", 138 - "change_type": "enhancement", 139 - "title": "Add AllowGetMethodPayload Configuration", 140 - "description": "Add configuration flag to explicitly allow GET requests with request bodies, which while discouraged by HTTP specs, is required by some APIs (notably Elasticsearch).", 141 - "affected_files": [ 142 - "lib/requests.ml", 143 - "lib/requests.mli", 144 - "lib/one.ml" 145 - ], 146 - "rationale": "The Go req library has AllowGetMethodPayload flag to enable GET with body for Elasticsearch and similar APIs. OCaml currently may reject or ignore bodies on GET requests. Add `?allow_get_body:bool` parameter (default: false) and document this is a spec violation needed for certain APIs. Implementation should check this flag before discarding GET request bodies." 147 - }, 148 - { 149 - "source_repo": "third_party/go/req", 150 - "source_language": "Go", 151 - "criticality": "high", 152 - "change_type": "security", 153 - "title": "Add Retry-After Header Handling with Maximum Backoff", 154 - "description": "Enhance retry logic to parse and respect the Retry-After header from server responses, but cap the maximum wait time to prevent denial-of-service where a malicious server sends extremely long retry delays.", 155 - "affected_files": [ 156 - "lib/retry.ml", 157 - "lib/retry.mli" 158 - ], 159 - "rationale": "The Go req library respects Retry-After headers and has backoff_max (default: 120s) to cap wait times. OCaml's retry.ml already parses Retry-After (lines 73-92) but should ensure it never exceeds backoff_max. Add a check: `let delay = min (Option.value retry_after ~default:calculated_backoff) config.backoff_max` to prevent malicious servers from forcing multi-hour delays that could DOS the client." 160 - }, 161 - { 162 - "source_repo": "third_party/go/req", 163 - "source_language": "Go", 164 - "criticality": "medium", 165 - "change_type": "enhancement", 166 - "title": "Add Custom Retry Condition Function", 167 - "description": "Allow users to provide custom logic to determine whether a specific request/response should be retried beyond the default status code list. This enables application-specific retry logic for transient errors.", 168 - "affected_files": [ 169 - "lib/retry.ml", 170 - "lib/retry.mli", 171 - "lib/requests.ml" 172 - ], 173 - "rationale": "The Go req library's AddRetryCondition/SetRetryCondition allows custom retry logic beyond status codes. OCaml could add `?retry_condition:(Response.t option -> exn option -> bool)` to retry config. This function receives either a response (for HTTP errors) or exception (for network errors) and returns whether to retry. Combine with existing status_forcelist using logical OR. Enables retrying on specific error messages, custom headers, or application-level error codes." 174 - }, 175 - { 176 - "source_repo": "third_party/go/req", 177 - "source_language": "Go", 178 - "criticality": "low", 179 - "change_type": "enhancement", 180 - "title": "Add Retry Hook for Logging and Metrics", 181 - "description": "Add a hook function that gets called before each retry attempt, allowing users to log retry attempts, update metrics, or perform cleanup actions between retries.", 182 - "affected_files": [ 183 - "lib/retry.ml", 184 - "lib/retry.mli" 185 - ], 186 - "rationale": "The Go req library's AddRetryHook/SetRetryHook allows logging and metrics collection on retries. OCaml could add `?retry_hook:(attempt:int -> delay:float -> Response.t option -> exn option -> unit)` to retry config. Call this before sleeping in `with_retry`. Enables production monitoring of retry patterns, alerting on excessive retries, or implementing circuit breakers at the application level." 187 - }, 188 - { 189 - "source_repo": "third_party/go/req", 190 - "source_language": "Go", 191 - "criticality": "low", 192 - "change_type": "feature", 193 - "title": "Add Global Error Hook", 194 - "description": "Add a client-level error callback that gets invoked for all request errors, enabling centralized error logging, metrics collection, and error reporting without wrapping every request in try-catch blocks.", 195 - "affected_files": [ 196 - "lib/requests.ml", 197 - "lib/requests.mli", 198 - "lib/http_client.ml" 199 - ], 200 - "rationale": "The Go req library's OnError hook (type: `func(client *Client, req *Request, resp *Response, err error)`) provides centralized error handling. OCaml could add `?on_error:(Request.t option -> Response.t option -> Error.error -> unit)` to client creation. This would be called whenever an error occurs, before propagating the exception. Useful for sending errors to monitoring services like Sentry, logging to centralized systems, or updating error metrics without modifying application code." 201 - }, 202 - { 203 - "source_repo": "third_party/go/req", 204 - "source_language": "Go", 205 - "criticality": "medium", 206 - "change_type": "feature", 207 - "title": "Add Customizable JSON/XML Marshallers", 208 - "description": "Allow users to override the default JSON encoder/decoder to use custom libraries or handle special encoding requirements. This enables better performance with alternative JSON libraries or custom serialization logic.", 209 - "affected_files": [ 210 - "lib/response.ml", 211 - "lib/response.mli", 212 - "lib/body.ml", 213 - "lib/body.mli", 214 - "lib/requests.ml" 215 - ], 216 - "rationale": "The Go req library allows SetJsonMarshal/SetJsonUnmarshal to override default encoding. OCaml could add `?json_encoder:(Jsont.json -> string)` and `?json_decoder:(string -> Jsont.json)` to client config. This enables using different JSON libraries (yojson, ezjsonm) for performance or feature reasons, implementing custom encoding (e.g., preserving number precision, custom date formats), or integrating with GraphQL or other JSON-based protocols with special requirements." 217 - }, 218 - { 219 - "source_repo": "third_party/go/req", 220 - "source_language": "Go", 221 - "criticality": "low", 222 - "change_type": "enhancement", 223 - "title": "Add DevMode for Enhanced Debugging Output", 224 - "description": "Add a developer mode that enables comprehensive debugging including full request/response dumps, timing information, and detailed error messages. This should be easy to enable for development and disabled in production.", 225 - "affected_files": [ 226 - "lib/requests.ml", 227 - "lib/requests.mli" 228 - ], 229 - "rationale": "The Go req library's DevMode() enables debug logging, request/response dumps, and detailed traces in one call. OCaml could add `?dev_mode:bool` to client creation that sets: log level to Debug, enables request/response dumping, includes full error context, and possibly enables TLS debug logging. This provides a single flag for maximum verbosity during development without requiring multiple configuration options." 230 - }, 231 - { 232 - "source_repo": "third_party/go/req", 233 - "source_language": "Go", 234 - "criticality": "low", 235 - "change_type": "enhancement", 236 - "title": "Add Transport Wrapper for Advanced Customization", 237 - "description": "Provide a mechanism to wrap the underlying HTTP transport layer for advanced use cases like custom connection pooling, socket options, or protocol-level modifications.", 238 - "affected_files": [ 239 - "lib/http_client.ml", 240 - "lib/requests.ml" 241 - ], 242 - "rationale": "The Go req library's WrapRoundTripFunc allows wrapping the transport layer for custom connection handling, protocol switching, or injecting custom behavior at the transport level. OCaml could add a callback that wraps the connection flow, though this may be complex with Eio's architecture. A simpler alternative is providing hooks at connection establishment time for socket configuration or custom TLS setup." 243 - }, 244 - { 245 - "source_repo": "third_party/go/req", 246 - "source_language": "Go", 247 - "criticality": "medium", 248 - "change_type": "enhancement", 249 - "title": "Add Detailed Timing/Trace Information", 250 - "description": "Provide detailed timing breakdown for each request including DNS lookup time, TCP connection time, TLS handshake time, time to first byte, and total request time. This enables performance analysis and debugging.", 251 - "affected_files": [ 252 - "lib/response.ml", 253 - "lib/response.mli", 254 - "lib/http_client.ml" 255 - ], 256 - "rationale": "The Go req library's Trace information provides detailed timing breakdown (DNS, TCP connect, TLS handshake, TTFB, total) and includes a Blame() method to identify bottlenecks. OCaml could add a `timing` field to Response.t with a record type containing optional timing values for each phase. This requires instrumenting http_client.ml to measure each phase. Include helpers like `Response.slowest_phase : Response.t -> (string * float) option` to identify bottlenecks." 257 - }, 258 - { 259 - "source_repo": "third_party/go/req", 260 - "source_language": "Go", 261 - "criticality": "low", 262 - "change_type": "enhancement", 263 - "title": "Add Connection Reuse Tracking", 264 - "description": "Track and report whether each request reused an existing connection or established a new one. This helps diagnose connection pool issues and optimize performance.", 265 - "affected_files": [ 266 - "lib/response.ml", 267 - "lib/response.mli", 268 - "lib/http_client.ml" 269 - ], 270 - "rationale": "The Go req library's Trace includes IsConnReused and RemoteAddr fields showing connection reuse. OCaml should add `connection_reused : bool option` and `remote_addr : string option` to Response.t or a new timing/trace record. This requires connection pool (Conpool) to track whether connections are fresh or reused and pass this information through to the response. Useful for verifying connection pooling is working and diagnosing connection issues." 271 - }, 272 - { 273 - "source_repo": "third_party/go/req", 274 - "source_language": "Go", 275 - "criticality": "low", 276 - "change_type": "feature", 277 - "title": "Add Output Directory for Automatic File Downloads", 278 - "description": "Support automatically saving response bodies to files in a designated directory without explicit file handling. Useful for bulk download operations.", 279 - "affected_files": [ 280 - "lib/requests.ml", 281 - "lib/requests.mli", 282 - "lib/one.ml" 283 - ], 284 - "rationale": "The Go req library's SetOutputDirectory + SetOutput(filename) automatically saves responses to files. OCaml could add `?output_directory:Eio.Path.t` to client config and `?output_file:string` to request methods. When both are set, automatically stream response body to `output_directory / output_file`. Implementation uses `One.download`-style streaming to the file sink. This simplifies bulk download scripts." 285 - }, 286 - { 287 - "source_repo": "third_party/go/req", 288 - "source_language": "Go", 289 - "criticality": "medium", 290 - "change_type": "feature", 291 - "title": "Add Custom Result State Checker", 292 - "description": "Allow users to define custom logic for determining whether a response represents success, error, or unknown state based on application-specific criteria beyond HTTP status codes.", 293 - "affected_files": [ 294 - "lib/response.ml", 295 - "lib/response.mli", 296 - "lib/requests.ml" 297 - ], 298 - "rationale": "The Go req library's SetResultStateCheckFunc allows custom success/error determination beyond status codes. Some APIs return 200 with error details in the body. OCaml could add `?result_state_checker:(Response.t -> [`Success | `Error | `Unknown])` to client config. Use this to override default status-code-based checking. When combined with automatic unmarshalling (recommendation #3), this enables handling APIs that signal errors in the response body rather than status codes." 299 - }, 300 - { 301 - "source_repo": "third_party/go/req", 302 - "source_language": "Go", 303 - "criticality": "low", 304 - "change_type": "enhancement", 305 - "title": "Add Multipart Boundary Customization", 306 - "description": "Allow customization of multipart form boundary generation for compatibility with servers that have specific boundary requirements or for testing purposes.", 307 - "affected_files": [ 308 - "lib/body.ml", 309 - "lib/body.mli" 310 - ], 311 - "rationale": "The Go req library's SetMultipartBoundaryFunc allows custom boundary generation for multipart requests. While most servers don't care about the boundary value, some legacy systems or testing scenarios require specific formats. OCaml could add `?boundary_generator:(unit -> string)` to `Body.multipart` that defaults to a secure random generator. Boundary must not appear in the content and should be reasonably unique." 312 - }, 313 - { 314 - "source_repo": "third_party/go/req", 315 - "source_language": "Go", 316 - "criticality": "low", 317 - "change_type": "enhancement", 318 - "title": "Add Auto-Decode Support for Character Encodings", 319 - "description": "Automatically detect and convert non-UTF-8 response bodies to UTF-8 based on Content-Type charset parameter or auto-detection. This simplifies handling international content.", 320 - "affected_files": [ 321 - "lib/http_client.ml", 322 - "lib/response.ml" 323 - ], 324 - "rationale": "The Go req library's auto-decode feature detects character encoding and converts to UTF-8 automatically. OCaml could add `?auto_decode:bool` (default: true) that examines `Content-Type: text/html; charset=ISO-8859-1` and converts the body to UTF-8. Requires a character encoding library like `uutf` or `camomile`. Falls back to leaving body unchanged if charset is unknown or conversion fails. Include logging when conversion occurs." 325 - }, 326 - { 327 - "source_repo": "third_party/go/req", 328 - "source_language": "Go", 329 - "criticality": "low", 330 - "change_type": "enhancement", 331 - "title": "Add Convenience Methods for Common HTTP Methods", 332 - "description": "Add convenience methods that combine method selection and URL in one call, reducing boilerplate for simple requests. Support chainable configuration for headers, auth, and body.", 333 - "affected_files": [ 334 - "lib/requests.ml", 335 - "lib/requests.mli" 336 - ], 337 - "rationale": "The Go req library provides both `R().SetXxx().Get(url)` and `Get(url).SetXxx()` patterns. OCaml already has `get`, `post`, etc. methods that accept URL and optional parameters. This recommendation is largely already satisfied. Consider documenting the convenience of optional parameters and potentially adding a builder pattern if future enhancements make request construction more complex." 338 - }, 339 - { 340 - "source_repo": "third_party/go/req", 341 - "source_language": "Go", 342 - "criticality": "low", 343 - "change_type": "feature", 344 - "title": "Add Disable Auto-Read Response Option", 345 - "description": "Add option to disable automatic reading of response bodies, allowing manual control over body consumption for streaming applications or when the body is not needed.", 346 - "affected_files": [ 347 - "lib/requests.ml", 348 - "lib/requests.mli", 349 - "lib/http_client.ml" 350 - ], 351 - "rationale": "The Go req library's DisableAutoReadResponse allows manual control over response body reading. OCaml's current design already provides streaming via `Response.body : Response.t -> Eio.Flow.source_ty Resource.t`, so users can choose to read fully via `text`/`json` or stream manually. This recommendation is already satisfied. Document that `Response.body` provides a stream and users control when/how to consume it." 352 - }, 353 - { 354 - "source_repo": "third_party/go/req", 355 - "source_language": "Go", 356 - "criticality": "low", 357 - "change_type": "enhancement", 358 - "title": "Add Redirect Policy Customization", 359 - "description": "Provide more granular control over redirect behavior including custom redirect validation, header preservation across redirects, and method preservation for 307/308 redirects.", 360 - "affected_files": [ 361 - "lib/http_client.ml", 362 - "lib/requests.ml", 363 - "lib/requests.mli" 364 - ], 365 - "rationale": "The Go req library's SetRedirectPolicy allows custom redirect logic. OCaml currently has basic follow_redirects and max_redirects but could enhance with: `?redirect_policy:((Request.t -> Response.t -> Uri.t -> bool) option)` that receives the original request, redirect response, and target URL, returning whether to follow. This enables checking redirect targets against allowlists, preventing redirects to different domains, or implementing custom redirect limits per domain." 366 - } 367 - ] 368 - }
-212
third_party/go/requests.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/go/requests", 5 - "source_language": "Go", 6 - "criticality": "high", 7 - "change_type": "security", 8 - "title": "Fix proxy TLS verification security vulnerability", 9 - "description": "The Go library demonstrates a critical security flaw when implementing proxy support: it sets `TLSClientConfig: &tls.Config{InsecureSkipVerify: true}` which completely disables certificate validation. When implementing proxy support in the OCaml library, ensure TLS verification remains enabled by default and only allow disabling it through an explicit opt-in configuration parameter (e.g., `~verify_tls:false`). The current OCaml codebase has a Proxy_error type defined in error.ml but no proxy implementation - when this is added, it must not repeat this security mistake.", 10 - "affected_files": [ 11 - "lib/one.ml", 12 - "lib/requests.ml", 13 - "lib/http_client.ml" 14 - ], 15 - "rationale": "Disabling TLS verification in proxy connections exposes users to man-in-the-middle attacks. The Go library's Proxy() function at line 248-251 shows what NOT to do. The OCaml library currently has better security practices (requiring explicit TLS config), and this must be maintained when adding proxy support." 16 - }, 17 - { 18 - "source_repo": "third_party/go/requests", 19 - "source_language": "Go", 20 - "criticality": "high", 21 - "change_type": "feature", 22 - "title": "Implement .netrc credential lookup for authentication", 23 - "description": "The OCaml library has TODO comments at lib/one.ml:14 and lib/requests.ml:244 noting '.netrc support' is needed. The Go library lacks this feature entirely, but it's a standard feature in mature HTTP clients like curl and Python requests. Implement parsing of ~/.netrc files to automatically supply credentials for hosts. When a request encounters a 401 response or requires authentication for a host listed in .netrc, automatically apply those credentials. This should respect the standard .netrc format (machine/login/password) and only read credentials for the specific host being accessed.", 24 - "affected_files": [ 25 - "lib/auth.ml", 26 - "lib/auth.mli", 27 - "lib/one.ml", 28 - "lib/requests.ml" 29 - ], 30 - "rationale": "This is explicitly marked as TODO in the codebase and is a standard feature for HTTP clients. It improves usability by allowing users to configure credentials once in a standard location rather than hardcoding them. Python requests and curl both support this, making it expected functionality." 31 - }, 32 - { 33 - "source_repo": "third_party/go/requests", 34 - "source_language": "Go", 35 - "criticality": "medium", 36 - "change_type": "enhancement", 37 - "title": "Add debug mode for request/response inspection", 38 - "description": "The Go library implements a simple but effective debug mode via a `Debug int` field (requests.go:41) that prints request/response details when set to 1. The OCaml library uses structured logging with the Logs library but lacks a simple 'debug mode' toggle. Add a `~debug:bool` parameter to the main API that, when enabled, logs full request/response details at the Info level, including headers (with sensitive values redacted per existing sanitization in error.ml:71-83), URL, method, status code, and timing. This makes troubleshooting easier for users without requiring them to configure logging infrastructure.", 39 - "affected_files": [ 40 - "lib/requests.ml", 41 - "lib/requests.mli", 42 - "lib/one.ml", 43 - "lib/one.mli", 44 - "lib/http_client.ml" 45 - ], 46 - "rationale": "The Go library's tests extensively use `req.Debug = 1` (requests_test.go:72, 80, 90, etc.) showing this is a frequently used feature during development. The OCaml library has excellent logging infrastructure but could benefit from a simple toggle that developers can easily enable during debugging sessions." 47 - }, 48 - { 49 - "source_repo": "third_party/go/requests", 50 - "source_language": "Go", 51 - "criticality": "medium", 52 - "change_type": "enhancement", 53 - "title": "Improve error handling consistency for file operations", 54 - "description": "The Go library has inconsistent error handling: some operations panic (file uploads at requests.go:538-545), others return nil without context (requests.go:286, 293), and others print to stdout (requests.go:140-142). The OCaml library has much better structured error handling through the Error module, but should ensure that file operations in Body.ml consistently raise descriptive errors rather than letting OS errors bubble up. Wrap file I/O operations with try-catch blocks that convert IO errors into appropriate Error types (e.g., Invalid_request with file-specific context).", 55 - "affected_files": [ 56 - "lib/body.ml", 57 - "lib/response.ml" 58 - ], 59 - "rationale": "The Go library shows common pitfalls in error handling that the OCaml library has mostly avoided. However, ensuring consistency in file operation error handling will improve the developer experience by providing clear, actionable error messages with proper context." 60 - }, 61 - { 62 - "source_repo": "third_party/go/requests", 63 - "source_language": "Go", 64 - "criticality": "medium", 65 - "change_type": "feature", 66 - "title": "Add response content caching similar to Response.Content()", 67 - "description": "The Go library caches response bodies after first read (requests.go:277-279, 296) allowing multiple calls to Content() or Text() without re-reading. The OCaml library uses Eio streams which are consumed once. Add an optional response body caching mechanism: `Response.to_string : t -> string` and `Response.to_bytes : t -> bytes` that cache the result internally. Add `Response.text_cached : t -> string` that reads the entire body once and stores it, allowing repeated access. This is useful when users need to process the same response body multiple times (e.g., parse as JSON and also log the raw content).", 68 - "affected_files": [ 69 - "lib/response.ml", 70 - "lib/response.mli" 71 - ], 72 - "rationale": "The Go library's caching pattern (checking `len(resp.content) > 0` before reading) is used frequently in its implementation. While streaming is more memory-efficient, there are legitimate cases where caching is valuable. The OCaml library should provide both streaming and cached access patterns." 73 - }, 74 - { 75 - "source_repo": "third_party/go/requests", 76 - "source_language": "Go", 77 - "criticality": "low", 78 - "change_type": "enhancement", 79 - "title": "Add convenience Response.save_file method", 80 - "description": "The Go library provides Response.SaveFile(filename) (requests.go:307-321) as a convenience method that reads the response body and writes it to a file in one call. The OCaml library requires users to manually copy from the response body stream to a file sink. Add `Response.save_file : t -> _ Eio.Path.t -> unit` that handles the stream-to-file copy internally, with proper error handling and atomic write semantics (write to temp file then rename).", 81 - "affected_files": [ 82 - "lib/response.ml", 83 - "lib/response.mli" 84 - ], 85 - "rationale": "This is a common operation that benefits from a convenience wrapper. The Go library's SaveFile method is used in tests (requests_test.go:52 commented out), indicating user demand. An OCaml implementation can improve on this by making it atomic and handling errors more gracefully." 86 - }, 87 - { 88 - "source_repo": "third_party/go/requests", 89 - "source_language": "Go", 90 - "criticality": "low", 91 - "change_type": "enhancement", 92 - "title": "Add builder-style header setting methods", 93 - "description": "The Go library allows setting headers via `req.Header.Set(key, value)` directly on the request object (requests_test.go:16, 57). While the OCaml library has excellent Headers module, the API requires creating headers separately then passing them. Add optional builder-style methods to the stateful Requests API: methods that return the modified request object to allow chaining. For example: `Requests.with_header : t -> string -> string -> unit` that modifies the session's default headers. This complements the existing functional Headers API.", 94 - "affected_files": [ 95 - "lib/requests.ml", 96 - "lib/requests.mli" 97 - ], 98 - "rationale": "The Go library's imperative header setting is convenient for interactive development and testing. The OCaml library's functional approach is better for safety, but adding imperative convenience methods to the stateful session API (not the one-shot API) would improve ergonomics for users who prefer that style." 99 - }, 100 - { 101 - "source_repo": "third_party/go/requests", 102 - "source_language": "Go", 103 - "criticality": "low", 104 - "change_type": "feature", 105 - "title": "Add manual cookie manipulation API", 106 - "description": "The Go library provides Request.SetCookie and Request.ClearCookies (requests.go:211-227) for manual cookie management beyond automatic cookie jar handling. The OCaml library has automatic cookie management via cookeio.jar but lacks explicit manual cookie manipulation in the public API. Expose methods: `Requests.set_cookie : t -> Cookeio.Cookie.t -> unit` and `Requests.clear_cookies : t -> unit` to allow manual cookie injection and clearing. This is useful for testing, debugging, and scenarios where cookies need to be set before the first request.", 107 - "affected_files": [ 108 - "lib/requests.ml", 109 - "lib/requests.mli" 110 - ], 111 - "rationale": "The Go library's tests use manual cookie manipulation (requests_test.go:102-107), showing this is needed beyond automatic handling. The OCaml library uses the cookeio library which has cookie types, but doesn't expose manual manipulation methods in the Requests module public API." 112 - }, 113 - { 114 - "source_repo": "third_party/go/requests", 115 - "source_language": "Go", 116 - "criticality": "low", 117 - "change_type": "enhancement", 118 - "title": "Add configurable default User-Agent header", 119 - "description": "The Go library sets a default User-Agent of 'Go-Requests 0.8' (requests.go:72) and allows overriding it. The OCaml library should expose a way to configure the default User-Agent for a session. Add an optional `~user_agent:string` parameter to Requests.create that sets a default User-Agent header for all requests in that session. If not specified, use a default like 'ocaml-requests/VERSION' where VERSION comes from the package version. Individual requests can still override it via custom headers.", 120 - "affected_files": [ 121 - "lib/requests.ml", 122 - "lib/requests.mli", 123 - "lib/one.ml", 124 - "lib/one.mli" 125 - ], 126 - "rationale": "Many APIs track clients by User-Agent, and having a recognizable default helps with debugging and server-side analytics. The Go library shows this is standard practice. The OCaml library should identify itself properly while allowing customization." 127 - }, 128 - { 129 - "source_repo": "third_party/go/requests", 130 - "source_language": "Go", 131 - "criticality": "medium", 132 - "change_type": "enhancement", 133 - "title": "Add HTTP method support for HEAD request optimization", 134 - "description": "While the OCaml library supports HEAD method via Method.t, the tests and examples don't demonstrate optimized HEAD request handling that skips body processing. The Go library shows that HEAD requests should be handled specially. Ensure that when using HEAD method, the HTTP client properly handles responses by not attempting to read the response body (servers send Content-Length but no actual body for HEAD). Add explicit documentation and test coverage for HEAD request behavior to ensure body stream is empty/closed immediately.", 135 - "affected_files": [ 136 - "lib/http_client.ml", 137 - "lib/response.ml", 138 - "test/test_simple_head.ml" 139 - ], 140 - "rationale": "HEAD requests are used to check resource existence and metadata without downloading the body. The test file test_simple_head.ml exists but proper optimization and documentation of HEAD behavior ensures efficient resource usage. The Go library handles all methods uniformly, but best practice is to optimize HEAD." 141 - }, 142 - { 143 - "source_repo": "third_party/go/requests", 144 - "source_language": "Go", 145 - "criticality": "low", 146 - "change_type": "enhancement", 147 - "title": "Add package-level convenience functions for common operations", 148 - "description": "The Go library provides package-level functions like `requests.Get(url)` and `requests.Post(url, ...)` (requests.go:87-93, 342-356) that wrap the stateful API for simple one-off requests. The OCaml library separates these into the One module. Consider adding package-level convenience functions in the main Requests module that create a temporary session and execute a single request, combining the ergonomics of the Go library with OCaml's explicit resource management. For example: `Requests.quick_get : env:_ -> url:string -> string` that handles session creation and cleanup internally.", 149 - "affected_files": [ 150 - "lib/requests.ml", 151 - "lib/requests.mli" 152 - ], 153 - "rationale": "The Go library's package-level functions make simple scripts very concise. While OCaml's explicit resource management is better for complex applications, providing 'quick' variants for simple scripts and REPLs improves the developer experience for simple use cases." 154 - }, 155 - { 156 - "source_repo": "third_party/go/requests", 157 - "source_language": "Go", 158 - "criticality": "medium", 159 - "change_type": "enhancement", 160 - "title": "Improve Retry-After header parsing and integration", 161 - "description": "The OCaml library has excellent Retry-After parsing in retry.ml:73-92 supporting both integer seconds and HTTP dates. However, this parsing is not integrated into the actual retry logic in with_retry function. The Go library lacks this entirely. Enhance the OCaml retry implementation to actually use parsed Retry-After values by: 1) Extracting Retry-After from HTTP error responses, 2) Using the parsed delay instead of exponential backoff when server provides it (if respect_retry_after=true in config), 3) Logging when server-specified delays are used. This requires passing response headers into the retry decision logic.", 162 - "affected_files": [ 163 - "lib/retry.ml", 164 - "lib/http_client.ml", 165 - "lib/requests.ml" 166 - ], 167 - "rationale": "The OCaml library has parse_retry_after but it's not actually used in with_retry (retry.ml:94-122). The Go library shows that most HTTP clients don't implement this correctly. Proper Retry-After support improves behavior with rate-limited APIs and shows respect for server guidance." 168 - }, 169 - { 170 - "source_repo": "third_party/go/requests", 171 - "source_language": "Go", 172 - "criticality": "high", 173 - "change_type": "feature", 174 - "title": "Implement HTTP/HTTPS/SOCKS5 proxy support", 175 - "description": "The Go library implements basic proxy support via the Proxy() method (requests.go:240-253) using Go's built-in http.Transport.Proxy. The OCaml library has Proxy_error defined in error.ml:54 but no actual proxy implementation. Add comprehensive proxy support including: 1) HTTP CONNECT proxies for HTTPS requests, 2) HTTP proxies for HTTP requests, 3) SOCKS5 proxy support via a SOCKS library, 4) Proxy authentication (Basic auth for HTTP proxies), 5) Environment variable support (HTTP_PROXY, HTTPS_PROXY, NO_PROXY), 6) Per-request proxy configuration via optional ~proxy parameter. This is a critical feature for enterprise users.", 176 - "affected_files": [ 177 - "lib/http_client.ml", 178 - "lib/requests.ml", 179 - "lib/requests.mli", 180 - "lib/one.ml", 181 - "lib/one.mli" 182 - ], 183 - "rationale": "This is one of the most significant gaps in the OCaml library. The Go library shows basic implementation, but the OCaml version should be more complete. Proxy support is essential for corporate environments, testing, and privacy-conscious users. The error type exists but the feature doesn't." 184 - }, 185 - { 186 - "source_repo": "third_party/go/requests", 187 - "source_language": "Go", 188 - "criticality": "low", 189 - "change_type": "enhancement", 190 - "title": "Add variadic parameter style API as alternative to labeled parameters", 191 - "description": "The Go library uses variadic parameters with type switching (requests.go:107-123) to allow flexible argument passing: `Get(url, Header{...}, Params{...}, Auth{...})` in any order. While OCaml's labeled parameters are more type-safe, consider adding a 'request builder' pattern as an alternative API style that allows chaining: create a request_builder type with methods like `with_headers`, `with_params`, `with_auth` that return the builder, then `execute` to run it. This provides a familiar API for users coming from other HTTP libraries while maintaining OCaml's type safety.", 192 - "affected_files": [ 193 - "lib/requests.ml", 194 - "lib/requests.mli" 195 - ], 196 - "rationale": "The Go library's flexible parameter style is popular because it's concise and order-independent. OCaml's labeled parameters provide similar benefits with better type safety, but a builder pattern could offer an even more fluent API for complex requests, especially in interactive environments." 197 - }, 198 - { 199 - "source_repo": "third_party/go/requests", 200 - "source_language": "Go", 201 - "criticality": "low", 202 - "change_type": "enhancement", 203 - "title": "Add Response.cookies() method for accessing response cookies", 204 - "description": "The Go library provides Response.Cookies() (requests.go:330-337) that returns cookies set by the server in the response. The OCaml library automatically stores cookies in the jar but doesn't provide easy access to view which cookies were set by a specific response. Add `Response.cookies : t -> Cookeio.Cookie.t list` that returns the Set-Cookie headers parsed into cookie objects for inspection. This is useful for debugging and validation.", 205 - "affected_files": [ 206 - "lib/response.ml", 207 - "lib/response.mli" 208 - ], 209 - "rationale": "The Go library's test code uses resp.Cookies() to verify cookie handling (requests_test.go:117-122). While automatic cookie management is good, users sometimes need to inspect what cookies were actually set by the server, especially during testing and debugging." 210 - } 211 - ] 212 - }
-295
third_party/go/resty.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/go/resty", 5 - "source_language": "Go", 6 - "criticality": "medium", 7 - "change_type": "enhancement", 8 - "title": "Implement retry hooks/callbacks for observability", 9 - "description": "Resty provides RetryHookFunc callbacks that execute on each retry attempt, allowing users to log, emit metrics, or perform side effects. The OCaml library's retry mechanism only logs internally via the Logs library but doesn't expose hooks for user-defined actions on retry events.", 10 - "affected_files": [ 11 - "lib/retry.ml", 12 - "lib/retry.mli", 13 - "lib/requests.ml" 14 - ], 15 - "rationale": "Retry hooks enable better observability and integration with monitoring systems. Users can track retry patterns, emit custom metrics, or implement circuit breaker logic. This is particularly valuable in production environments where understanding retry behavior is critical for debugging and capacity planning. Resty's implementation shows this pattern is widely useful in HTTP clients." 16 - }, 17 - { 18 - "source_repo": "third_party/go/resty", 19 - "source_language": "Go", 20 - "criticality": "low", 21 - "change_type": "enhancement", 22 - "title": "Add request attempt counter to response metadata", 23 - "description": "Resty tracks the number of attempts (initial request + retries) in the Request.Attempt field and includes it in trace information. The OCaml library retries internally but doesn't expose attempt count to users, making it harder to understand retry behavior for specific requests.", 24 - "affected_files": [ 25 - "lib/response.ml", 26 - "lib/response.mli", 27 - "lib/requests.ml" 28 - ], 29 - "rationale": "Exposing the attempt counter helps users understand whether a request succeeded on first try or required retries. This aids debugging, performance analysis, and SLA tracking. Combined with trace information, it provides complete visibility into request execution. The implementation is straightforward - increment a counter in the retry loop and include it in the response metadata." 30 - }, 31 - { 32 - "source_repo": "third_party/go/resty", 33 - "source_language": "Go", 34 - "criticality": "low", 35 - "change_type": "enhancement", 36 - "title": "Add trace ID for retry sequences", 37 - "description": "Resty generates a GUID (RetryTraceID) when retries occur, allowing all retry attempts of the same original request to be correlated in logs and distributed traces. The OCaml library doesn't provide request correlation IDs for retry sequences.", 38 - "affected_files": [ 39 - "lib/retry.ml", 40 - "lib/retry.mli", 41 - "lib/requests.ml" 42 - ], 43 - "rationale": "A retry trace ID enables correlation of all retry attempts for a single logical request across distributed systems and log aggregators. This is crucial for debugging intermittent failures and understanding retry patterns. In microservices architectures, this ID can be propagated in headers (X-Request-ID or X-Trace-ID) to correlate requests across service boundaries. Implementation involves generating a UUID on first retry and passing it through all subsequent attempts." 44 - }, 45 - { 46 - "source_repo": "third_party/go/resty", 47 - "source_language": "Go", 48 - "criticality": "medium", 49 - "change_type": "enhancement", 50 - "title": "Support request and response middleware/hooks", 51 - "description": "Resty provides RequestMiddleware and ResponseMiddleware callbacks that execute before request sending and after response receipt. It also has ErrorHook, SuccessHook, PanicHook, and InvalidHook for different request lifecycle events. The OCaml library lacks a general middleware/hook system for request/response manipulation.", 52 - "affected_files": [ 53 - "lib/requests.ml", 54 - "lib/requests.mli", 55 - "lib/http_client.ml" 56 - ], 57 - "rationale": "Middleware enables cross-cutting concerns like authentication token refresh, request signing, response validation, metrics collection, and custom logging without modifying core library code. This is a fundamental extensibility pattern. Hooks allow users to react to request lifecycle events, enabling patterns like automatic retry backoff adjustment, circuit breaker implementation, and custom error handling. The pattern is widely adopted in HTTP clients across languages." 58 - }, 59 - { 60 - "source_repo": "third_party/go/resty", 61 - "source_language": "Go", 62 - "criticality": "medium", 63 - "change_type": "feature", 64 - "title": "Add request tracing with timing breakdowns", 65 - "description": "Resty provides detailed TraceInfo with timing breakdowns: DNSLookup, TCPConnTime, TLSHandshake, ServerTime (time to first byte), ResponseTime, TotalTime, plus metadata like IsConnReused, IsConnWasIdle, ConnIdleTime. The OCaml library only tracks total elapsed time and doesn't expose connection pool statistics or timing breakdowns.", 66 - "affected_files": [ 67 - "lib/http_client.ml", 68 - "lib/requests.ml", 69 - "lib/response.ml", 70 - "lib/response.mli" 71 - ], 72 - "rationale": "Detailed timing breakdowns help diagnose performance bottlenecks. DNS issues, TLS handshake overhead, slow servers, and network latency can all be distinguished. Connection reuse information helps validate pool efficiency. This is invaluable for performance debugging and capacity planning. The OCaml implementation would need to track timestamps at each phase using Eio.Time.now and calculate deltas. Connection pool statistics (reuse, idle time) are already tracked in Conpool and could be exposed." 73 - }, 74 - { 75 - "source_repo": "third_party/go/resty", 76 - "source_language": "Go", 77 - "criticality": "low", 78 - "change_type": "enhancement", 79 - "title": "Add custom retry strategy support", 80 - "description": "Resty allows users to provide custom RetryStrategyFunc callbacks that compute wait duration based on response and error context. The OCaml library only supports exponential backoff with jitter using fixed configuration parameters, with no way to implement custom strategies.", 81 - "affected_files": [ 82 - "lib/retry.ml", 83 - "lib/retry.mli", 84 - "lib/requests.ml" 85 - ], 86 - "rationale": "Custom retry strategies enable business-logic-specific backoff algorithms. Examples include: consulting external rate limit APIs, implementing token bucket algorithms, adaptive backoff based on response headers beyond Retry-After, or domain-specific failure classification. The functional nature of OCaml makes this particularly elegant - users can provide a function (attempt -> response option -> exn option -> float) to compute wait time." 87 - }, 88 - { 89 - "source_repo": "third_party/go/resty", 90 - "source_language": "Go", 91 - "criticality": "low", 92 - "change_type": "enhancement", 93 - "title": "Allow custom retry condition predicates", 94 - "description": "Resty enables users to add custom RetryConditionFunc predicates that determine retry eligibility based on response or error. Multiple conditions can be composed. The OCaml library's should_retry is hardcoded to check method and status against fixed lists, with no extensibility for custom business logic.", 95 - "affected_files": [ 96 - "lib/retry.ml", 97 - "lib/retry.mli", 98 - "lib/requests.ml" 99 - ], 100 - "rationale": "Different applications have different retry requirements. Examples: retrying on specific error messages, checking custom response headers, domain-specific temporary failure detection, rate limit header inspection beyond Retry-After. Resty's approach of composable retry conditions (default conditions + user conditions) provides flexibility while maintaining safe defaults. In OCaml, this could be expressed as (exn -> bool) or (Response.t option -> exn option -> bool) predicate functions." 101 - }, 102 - { 103 - "source_repo": "third_party/go/resty", 104 - "source_language": "Go", 105 - "criticality": "medium", 106 - "change_type": "feature", 107 - "title": "Implement circuit breaker pattern", 108 - "description": "Resty includes a built-in CircuitBreaker with three states (Closed, Open, Half-Open), configurable failure/success thresholds, timeout, and customizable policies. The OCaml library has no circuit breaker support, potentially leading to cascading failures when downstream services fail.", 109 - "affected_files": [ 110 - "lib/requests.ml", 111 - "lib/requests.mli" 112 - ], 113 - "rationale": "Circuit breakers prevent cascading failures by failing fast when a service is unhealthy, giving it time to recover. This is critical for building resilient distributed systems. Resty's implementation provides a proven design: track consecutive failures, open circuit after threshold, allow a test request after timeout, close on success. The pattern is widely adopted in microservices. OCaml's module system would allow clean encapsulation, and Eio's structured concurrency fits well with circuit breaker state management." 114 - }, 115 - { 116 - "source_repo": "third_party/go/resty", 117 - "source_language": "Go", 118 - "criticality": "low", 119 - "change_type": "enhancement", 120 - "title": "Add debug mode with detailed logging and cURL command generation", 121 - "description": "Resty provides a comprehensive debug mode that logs request/response details, generates equivalent cURL commands for reproduction, and supports custom debug formatters (string, JSON). The OCaml library relies on the Logs library but doesn't provide structured debug output or cURL generation.", 122 - "affected_files": [ 123 - "lib/requests.ml", 124 - "lib/requests.mli", 125 - "lib/http_client.ml" 126 - ], 127 - "rationale": "Debug mode significantly improves developer experience and troubleshooting. cURL command generation allows developers to reproduce issues outside the application, share with support teams, or test with different tools. Structured debug output (JSON format) enables log parsing and automated analysis. Custom formatters allow integration with different logging backends. The feature is particularly valuable during development and debugging production issues." 128 - }, 129 - { 130 - "source_repo": "third_party/go/resty", 131 - "source_language": "Go", 132 - "criticality": "low", 133 - "change_type": "enhancement", 134 - "title": "Add path parameter templating", 135 - "description": "Resty supports path parameter substitution via template syntax (e.g., '/users/{id}/posts/{post_id}') with a PathParams map. The OCaml library requires users to manually construct URLs with parameters, which is error-prone and verbose for complex paths.", 136 - "affected_files": [ 137 - "lib/requests.ml", 138 - "lib/requests.mli" 139 - ], 140 - "rationale": "Path templating reduces boilerplate and prevents URL construction errors. It's especially useful for REST APIs with multiple path segments. The pattern separates URL structure from dynamic values, making code more readable and maintainable. Implementation involves scanning for {param} patterns and substituting from a string map, with proper URL encoding of values. This is a common convenience feature in HTTP clients across languages." 141 - }, 142 - { 143 - "source_repo": "third_party/go/resty", 144 - "source_language": "Go", 145 - "criticality": "medium", 146 - "change_type": "feature", 147 - "title": "Add load balancer support for multiple endpoints", 148 - "description": "Resty includes a LoadBalancer abstraction with strategies (Round-Robin, Weighted Round-Robin) and health tracking for distributing requests across multiple backend hosts. The OCaml library only supports single endpoint connections via connection pooling.", 149 - "affected_files": [ 150 - "lib/requests.ml", 151 - "lib/requests.mli" 152 - ], 153 - "rationale": "Client-side load balancing enables fault tolerance and horizontal scaling without external load balancers. This is valuable for direct service-to-service communication in microservices. Resty's approach tracks host health, marks failed hosts inactive, and automatically recovers them after timeout. Combined with circuit breakers, this provides robust failure handling. OCaml implementation could integrate with existing connection pool, selecting endpoints before pool lookup. The feature is particularly useful in containerized environments." 154 - }, 155 - { 156 - "source_repo": "third_party/go/resty", 157 - "source_language": "Go", 158 - "criticality": "low", 159 - "change_type": "enhancement", 160 - "title": "Add response body size limiting with configurable threshold", 161 - "description": "Resty allows setting ResponseBodyLimit at client and request levels to prevent memory exhaustion from unexpectedly large responses. The OCaml library has Response_limits.max_body_size but it's less prominently exposed and not configurable per-request.", 162 - "affected_files": [ 163 - "lib/response_limits.ml", 164 - "lib/response_limits.mli", 165 - "lib/requests.ml", 166 - "lib/requests.mli" 167 - ], 168 - "rationale": "Per-request body size limits provide fine-grained control over memory usage. Different endpoints may have different expected response sizes (e.g., thumbnails vs full images, summaries vs full documents). Resty's approach allows overriding client-level defaults on specific requests. While the OCaml library has the infrastructure, making it more accessible and prominently documented would improve safety. This is a defense-in-depth security measure against memory exhaustion attacks." 169 - }, 170 - { 171 - "source_repo": "third_party/go/resty", 172 - "source_language": "Go", 173 - "criticality": "low", 174 - "change_type": "enhancement", 175 - "title": "Support disabling connection keep-alive per request", 176 - "description": "Resty allows disabling keep-alive via CloseConnection flag at request level, forcing connection closure after response. The OCaml library manages connections exclusively through the pool without per-request control over connection lifecycle.", 177 - "affected_files": [ 178 - "lib/requests.ml", 179 - "lib/requests.mli", 180 - "lib/http_client.ml" 181 - ], 182 - "rationale": "Some scenarios benefit from explicit connection closure: one-time requests, requests to unreliable servers, connection leak debugging, or compliance with server requirements. While connection pooling is generally beneficial, per-request override provides flexibility for edge cases. This could be implemented by passing a flag to Http_client that sets Connection: close header and bypasses pool return. The feature is low-risk and rarely used but valuable when needed." 183 - }, 184 - { 185 - "source_repo": "third_party/go/resty", 186 - "source_language": "Go", 187 - "criticality": "medium", 188 - "change_type": "enhancement", 189 - "title": "Add support for request-level timeout overrides", 190 - "description": "Resty allows setting timeout at request level that overrides client default. The OCaml library supports timeouts in the session configuration but doesn't clearly expose per-request timeout overrides in the API.", 191 - "affected_files": [ 192 - "lib/requests.ml", 193 - "lib/requests.mli" 194 - ], 195 - "rationale": "Different requests have different timeout requirements. Downloads/uploads need longer timeouts than simple API calls. Background tasks can tolerate longer waits than user-facing requests. Per-request timeouts provide necessary flexibility while maintaining reasonable defaults. The OCaml library may have the underlying capability but should expose it more prominently in the API. This is a common pattern across HTTP client libraries." 196 - }, 197 - { 198 - "source_repo": "third_party/go/resty", 199 - "source_language": "Go", 200 - "criticality": "low", 201 - "change_type": "enhancement", 202 - "title": "Support automatic Content-Length calculation and setting", 203 - "description": "Resty automatically calculates and sets Content-Length header for known body types. The OCaml library handles Content-Length for some body types but could be more comprehensive and automatic.", 204 - "affected_files": [ 205 - "lib/body.ml", 206 - "lib/body.mli", 207 - "lib/http_write.ml" 208 - ], 209 - "rationale": "Automatic Content-Length calculation reduces errors and improves server compatibility. Some servers require Content-Length for non-chunked requests. The library can calculate length for string bodies, byte buffers, and files, while using chunked encoding for streams. This improves user experience by handling common cases automatically while allowing manual override for edge cases. The OCaml library already has much of this infrastructure but could enhance the automation." 210 - }, 211 - { 212 - "source_repo": "third_party/go/resty", 213 - "source_language": "Go", 214 - "criticality": "low", 215 - "change_type": "feature", 216 - "title": "Add Server-Sent Events (SSE) client support", 217 - "description": "Resty includes full SSE (Server-Sent Events) client implementation with event parsing, automatic reconnection, and callback-based processing. The OCaml library has no built-in SSE support for handling streaming events.", 218 - "affected_files": [ 219 - "lib/requests.ml", 220 - "lib/requests.mli" 221 - ], 222 - "rationale": "SSE is widely used for real-time notifications, live updates, and streaming responses (chat, monitoring, progress updates). While less common than standard HTTP, SSE support significantly expands the library's use cases. The implementation involves parsing text/event-stream format, handling reconnection with Last-Event-ID, and providing an event callback API. Eio's structured concurrency and streaming support make OCaml well-suited for SSE. This would be a valuable addition for real-time applications." 223 - }, 224 - { 225 - "source_repo": "third_party/go/resty", 226 - "source_language": "Go", 227 - "criticality": "low", 228 - "change_type": "enhancement", 229 - "title": "Allow configurable User-Agent header with sensible default", 230 - "description": "Resty sets a default User-Agent ('go-resty/VERSION (https://resty.dev)') but allows override. The OCaml library doesn't set a default User-Agent, which may cause issues with servers that expect it or use it for analytics.", 231 - "affected_files": [ 232 - "lib/headers.ml", 233 - "lib/headers.mli", 234 - "lib/requests.ml" 235 - ], 236 - "rationale": "Many servers expect User-Agent headers for analytics, bot detection, or compatibility. Some APIs require it or provide different behavior based on it. Setting a sensible default (e.g., 'ocaml-requests/VERSION') while allowing override is good HTTP citizenship. This is straightforward to implement - add default User-Agent to default_headers if not explicitly set. The pattern is standard across HTTP client libraries." 237 - }, 238 - { 239 - "source_repo": "third_party/go/resty", 240 - "source_language": "Go", 241 - "criticality": "low", 242 - "change_type": "enhancement", 243 - "title": "Support response unmarshaling to custom types", 244 - "description": "Resty's Request.Result field allows automatic unmarshaling of response body to user-defined types (JSON/XML), with Request.Error for error responses. The OCaml library provides json_body() but doesn't support automatic unmarshaling to user types or separate success/error response handling.", 245 - "affected_files": [ 246 - "lib/response.ml", 247 - "lib/response.mli", 248 - "lib/requests.ml" 249 - ], 250 - "rationale": "Automatic unmarshaling reduces boilerplate and improves type safety. Separate Result/Error fields enable different types for success vs error responses, reflecting real API designs. This could leverage OCaml's type system for compile-time safety. While JSON parsing is available, integrating it more seamlessly with response handling would improve developer experience. The pattern of having typed result and error fields is common in typed languages' HTTP clients." 251 - }, 252 - { 253 - "source_repo": "third_party/go/resty", 254 - "source_language": "Go", 255 - "criticality": "medium", 256 - "change_type": "enhancement", 257 - "title": "Add granular TLS configuration options", 258 - "description": "Resty exposes comprehensive TLS configuration including cipher suites, TLS version negotiation, client certificates, custom certificate pools, and certificate reloading via watcher. The OCaml library supports basic TLS config (min version, verification) but doesn't expose all TLS options available in the underlying tls-eio library.", 259 - "affected_files": [ 260 - "lib/requests.ml", 261 - "lib/requests.mli" 262 - ], 263 - "rationale": "Advanced TLS configuration is needed for enterprise scenarios: client certificate authentication (mTLS), custom CA certificates for internal PKI, cipher suite restrictions for compliance, certificate rotation without restarts. While basic TLS works for most cases, exposing full tls-eio configuration enables production deployments with strict security requirements. The OCaml library already depends on tls-eio - this is about exposing existing capabilities through the API." 264 - }, 265 - { 266 - "source_repo": "third_party/go/resty", 267 - "source_language": "Go", 268 - "criticality": "low", 269 - "change_type": "enhancement", 270 - "title": "Support custom content encoders and decoders", 271 - "description": "Resty allows registering custom ContentTypeEncoder and ContentTypeDecoder functions for handling arbitrary content types beyond built-in JSON/XML. The OCaml library supports JSON and form data but doesn't provide an extensibility mechanism for custom serialization formats.", 272 - "affected_files": [ 273 - "lib/body.ml", 274 - "lib/body.mli", 275 - "lib/response.ml", 276 - "lib/response.mli" 277 - ], 278 - "rationale": "Different APIs use different serialization formats: Protocol Buffers, MessagePack, CBOR, custom binary formats, etc. An encoder/decoder registry enables supporting these without modifying the core library. This aligns with OCaml's philosophy of extensibility. Implementation would store a map of content-type to encoder/decoder functions. While most users use JSON, the extensibility is valuable for specialized use cases and makes the library more general-purpose." 279 - }, 280 - { 281 - "source_repo": "third_party/go/resty", 282 - "source_language": "Go", 283 - "criticality": "low", 284 - "change_type": "enhancement", 285 - "title": "Add multipart field ordering and progress callbacks", 286 - "description": "Resty supports ordered multipart fields and per-field progress callbacks for tracking upload progress. The OCaml library supports multipart forms but doesn't preserve field order or provide upload progress feedback.", 287 - "affected_files": [ 288 - "lib/body.ml", 289 - "lib/body.mli", 290 - "lib/http_write.ml" 291 - ], 292 - "rationale": "Field ordering matters for some APIs that process fields sequentially. Progress callbacks enable UI updates for long uploads, improving user experience. While not common, these features are valuable when needed. Progress tracking could integrate with Eio's streaming by invoking callbacks at intervals during write operations. Field ordering could be maintained by using a list instead of a map for multipart fields. These enhancements would make the library suitable for interactive applications." 293 - } 294 - ] 295 - }
-169
third_party/go/sling.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/go/sling", 5 - "source_language": "Go", 6 - "criticality": "medium", 7 - "change_type": "enhancement", 8 - "title": "Add fluent/builder pattern for request construction", 9 - "description": "Sling uses a fluent builder pattern where all configuration methods return the modified object, enabling method chaining like `sling.Get(url).QueryStruct(params).Add(\"header\", \"value\").Receive(success, failure)`. The OCaml library requires separate function calls. Implement a builder pattern that allows chaining operations before final execution, improving API ergonomics and discoverability.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/one.ml" 13 - ], 14 - "rationale": "The current OCaml API uses separate function parameters for configuration. A builder pattern would provide better discoverability through IDE autocomplete, allow gradual request construction, and match the ergonomics users expect from libraries like Python requests. This could be implemented using a RequestBuilder module that accumulates configuration before calling a final .execute() method." 15 - }, 16 - { 17 - "source_repo": "third_party/go/sling", 18 - "source_language": "Go", 19 - "criticality": "low", 20 - "change_type": "enhancement", 21 - "title": "Implement parent-child session inheritance pattern", 22 - "description": "Sling's New() method creates a copy of the parent Sling with all configuration (headers, base URL, auth, etc.) inherited but independently modifiable. This allows creating a base session for an API with common config, then deriving endpoint-specific sessions. The OCaml library doesn't provide this pattern - sessions would need manual duplication of all configuration parameters.", 23 - "affected_files": [ 24 - "lib/requests.ml" 25 - ], 26 - "rationale": "Sling demonstrates this pattern: `base := sling.New().Base(apiURL).Client(authClient); repos := base.New().Get(\"repos\"); issues := base.New().Get(\"issues\")`. Each child inherits but can override parent config. The OCaml library could add a `derive : t -> ?headers:... -> ?auth:... -> t` function that copies configuration with selective overrides, enabling cleaner API client implementations." 27 - }, 28 - { 29 - "source_repo": "third_party/go/sling", 30 - "source_language": "Go", 31 - "criticality": "medium", 32 - "change_type": "feature", 33 - "title": "Add dual success/failure response decoding", 34 - "description": "Sling's Receive(successV, failureV) allows passing two different decode targets - one for 2XX responses (success) and one for non-2XX (failure). This enables structured error handling where API error responses are automatically parsed into typed error structs. The OCaml library only returns a single Response.t regardless of status code.", 35 - "affected_files": [ 36 - "lib/requests.ml", 37 - "lib/response.ml", 38 - "lib/one.ml" 39 - ], 40 - "rationale": "Many REST APIs return structured JSON error responses (e.g., {\"error\": {\"code\": 400, \"message\": \"...\"}}). Currently users must manually check status and parse errors. Add optional `?on_success:(Response.t -> 'a)` and `?on_error:(Response.t -> 'b)` callbacks that are invoked based on status code, with the overall function returning `('a, 'b) result`. This matches Sling's pattern while being idiomatic OCaml." 41 - }, 42 - { 43 - "source_repo": "third_party/go/sling", 44 - "source_language": "Go", 45 - "criticality": "low", 46 - "change_type": "enhancement", 47 - "title": "Support struct-tagged query parameter encoding", 48 - "description": "Sling uses QueryStruct() to encode Go structs with url tags into query parameters, allowing type-safe parameter passing. Multiple QueryStruct calls are cumulative. The OCaml library only supports list-based params. Add support for encoding OCaml records/objects into query parameters using a similar tagging mechanism or deriving approach.", 49 - "affected_files": [ 50 - "lib/requests.ml", 51 - "lib/one.ml" 52 - ], 53 - "rationale": "Sling shows the value of type-safe parameter encoding: `type Params struct { Limit int \\`url:\"limit\"\\`; Offset int \\`url:\"offset\"\\` }` then `QueryStruct(&Params{Limit: 10, Offset: 20})`. OCaml could leverage PPX derivers (e.g., `[@@deriving url]`) or manual encoding interfaces. This would prevent typos in query parameter names and enable better API documentation through types." 54 - }, 55 - { 56 - "source_repo": "third_party/go/sling", 57 - "source_language": "Go", 58 - "criticality": "medium", 59 - "change_type": "enhancement", 60 - "title": "Add pluggable response decoder interface", 61 - "description": "Sling provides a ResponseDecoder interface that allows custom response decoding (e.g., XML, Protocol Buffers, MessagePack). The default is JSON but users can call ResponseDecoder() to set alternatives. The OCaml library hardcodes JSON parsing in Response.json and lacks extensibility for other formats.", 62 - "affected_files": [ 63 - "lib/response.ml" 64 - ], 65 - "rationale": "Sling demonstrates this with xmlDecoder example. The OCaml library should add a `type decoder = Response.t -> 'a` type and `decode : decoder:'a decoder -> Response.t -> 'a` function. Built-in decoders for common formats (JSON, XML, MessagePack) would be provided. This is especially important for APIs that use formats like Protobuf or custom serialization." 66 - }, 67 - { 68 - "source_repo": "third_party/go/sling", 69 - "source_language": "Go", 70 - "criticality": "high", 71 - "change_type": "bug", 72 - "title": "Ensure response body is always consumed for connection reuse", 73 - "description": "Sling's Do() method includes `defer io.Copy(io.Discard, resp.Body)` with comment: 'The default HTTP client's Transport may not reuse HTTP/1.x keep-alive TCP connections if the Body is not read to completion and closed.' This ensures connection pooling works correctly even when response body isn't fully read. Verify the OCaml implementation handles this properly.", 74 - "affected_files": [ 75 - "lib/http_client.ml", 76 - "lib/http_read.ml" 77 - ], 78 - "rationale": "This is a subtle but critical detail for HTTP/1.1 connection reuse. If response bodies aren't fully consumed, connection pools can leak or connections may not be reused. Review http_read.ml to ensure all code paths (including errors, early returns, and HEAD requests) fully drain response bodies before returning connections to the pool. This is especially important with chunked encoding and large responses." 79 - }, 80 - { 81 - "source_repo": "third_party/go/sling", 82 - "source_language": "Go", 83 - "criticality": "medium", 84 - "change_type": "enhancement", 85 - "title": "Skip decoding for 204 No Content and zero Content-Length responses", 86 - "description": "Sling's Do() explicitly checks `if resp.StatusCode == http.StatusNoContent || resp.ContentLength == 0` and skips decoding. This prevents parse errors on responses that legitimately have no body. The OCaml library should implement similar logic before attempting to parse JSON/other formats.", 87 - "affected_files": [ 88 - "lib/response.ml" 89 - ], 90 - "rationale": "Many APIs return 204 No Content for successful DELETE/PUT operations or cache validation. Attempting to parse empty bodies as JSON will fail. Add checks in Response.json and other parsing functions: if status is 204 or Content-Length is 0, return None or appropriate empty value rather than attempting to parse. This prevents unnecessary errors and matches HTTP semantics." 91 - }, 92 - { 93 - "source_repo": "third_party/go/sling", 94 - "source_language": "Go", 95 - "criticality": "low", 96 - "change_type": "enhancement", 97 - "title": "Provide separate Request() and Do() methods for testing", 98 - "description": "Sling separates request building (Request() returns *http.Request) from execution (Do() sends the request). This enables unit testing of request construction without making network calls. The OCaml library tightly couples building and sending. Add a `build_request : ... -> http_request` function that returns a request representation without executing.", 99 - "affected_files": [ 100 - "lib/requests.ml", 101 - "lib/one.ml" 102 - ], 103 - "rationale": "Sling's pattern: `req, err := sling.Request()` builds without sending, `resp, err := sling.Do(req, success, failure)` executes. This enables testing request structure (headers, URL, body) without mocking network. Add `type request_spec = { method_: Method.t; url: string; headers: Headers.t; body: Body.t }` and `prepare : ... -> request_spec` function. Users can inspect request_spec in tests before calling `execute : t -> request_spec -> Response.t`." 104 - }, 105 - { 106 - "source_repo": "third_party/go/sling", 107 - "source_language": "Go", 108 - "criticality": "low", 109 - "change_type": "enhancement", 110 - "title": "Add base URL path extension with proper URL resolution", 111 - "description": "Sling's Path() method properly resolves paths against base URLs using url.Parse().ResolveReference(), handling trailing slashes, absolute paths, and relative paths correctly. The OCaml library should ensure similar robust path joining logic when constructing request URLs from components.", 112 - "affected_files": [ 113 - "lib/requests.ml" 114 - ], 115 - "rationale": "Sling tests show edge cases: base=\"http://a.io/foo\" + path=\"bar\" = \"http://a.io/bar\" (not foo/bar because no trailing slash). The OCaml library should use Uri.resolve for proper RFC 3986 reference resolution. This prevents common bugs like double slashes (http://api//endpoint) or missing slashes (http://apiendpoint). Add helper: `resolve_path : base:string -> path:string -> string`." 116 - }, 117 - { 118 - "source_repo": "third_party/go/sling", 119 - "source_language": "Go", 120 - "criticality": "medium", 121 - "change_type": "enhancement", 122 - "title": "Catch encoding errors early during request building", 123 - "description": "Sling's Request() method returns errors for JSON encoding failures (e.g., json.Marshal of math.Inf returns error). These are caught before the network request is attempted. The OCaml library should validate body encoding similarly to provide early error feedback.", 124 - "affected_files": [ 125 - "lib/body.ml", 126 - "lib/requests.ml" 127 - ], 128 - "rationale": "Sling tests show: `New().BodyJSON(FakeModel{Temperature: math.Inf(1)})` returns encoding error immediately. This provides better debugging than discovering encoding failures after establishing a connection. The OCaml library already uses Body.json which can raise Json_encode_error, but should document that encoding happens eagerly. Consider adding `validate : Body.t -> (unit, Error.error) result` for pre-flight validation." 129 - }, 130 - { 131 - "source_repo": "third_party/go/sling", 132 - "source_language": "Go", 133 - "criticality": "low", 134 - "change_type": "enhancement", 135 - "title": "Support custom Doer/middleware pattern for request interception", 136 - "description": "Sling's Doer interface allows wrapping the HTTP client with middleware layers for logging, metrics, retries, circuit breakers, etc. The OCaml library embeds retry logic directly but doesn't expose a general middleware mechanism. Add an interceptor pattern for extensibility.", 137 - "affected_files": [ 138 - "lib/requests.ml" 139 - ], 140 - "rationale": "Sling shows: `type Doer interface { Do(req *http.Request) (*http.Response, error) }` enables composable middleware. OCaml could add `type interceptor = request_spec -> (request_spec -> Response.t) -> Response.t` where interceptors can modify requests, responses, or implement cross-cutting concerns. Register via `add_interceptor : t -> interceptor -> t`. This enables plugins for auth refresh, request signing, distributed tracing, etc." 141 - }, 142 - { 143 - "source_repo": "third_party/go/sling", 144 - "source_language": "Go", 145 - "criticality": "high", 146 - "change_type": "bug", 147 - "title": "Validate JSON encoding errors happen at Body() call time", 148 - "description": "In Sling, JSON encoding errors (like math.Inf which cannot be represented in JSON) are detected when Body() is called during Request() construction, not when setting BodyJSON(). The OCaml library uses Body.json which encodes eagerly. Ensure all encoding errors surface before network I/O begins.", 149 - "affected_files": [ 150 - "lib/body.ml" 151 - ], 152 - "rationale": "Sling's jsonBodyProvider.Body() calls json.Encoder.Encode() which can fail. The OCaml Body.json function already encodes immediately (via Jsont_bytesrw.encode_string'), which is good - it fails fast. However, Body.json_stream uses lazy encoding via Json_stream_source. Verify json_stream_source_create also validates encoding eagerly by attempting to encode at creation time, or document that encoding errors may occur during transmission." 153 - }, 154 - { 155 - "source_repo": "third_party/go/sling", 156 - "source_language": "Go", 157 - "criticality": "medium", 158 - "change_type": "enhancement", 159 - "title": "Add comprehensive test coverage for edge cases", 160 - "description": "Sling's test suite (34KB) extensively covers edge cases: empty base URLs, empty paths, URL resolution precedence, header copying in child slings, query struct list copying, multiple Path extensions, nil value handling, Content-Length 0, status code handling, custom decoders, encoding errors (math.Inf), and mock servers. Expand OCaml test coverage to match this thoroughness.", 161 - "affected_files": [ 162 - "test/test_simple.ml", 163 - "test/test_one.ml", 164 - "test/httpbin.t" 165 - ], 166 - "rationale": "The OCaml tests (httpbin.t at 14KB) focus on integration testing with httpbin. Add unit tests for: URL resolution edge cases (empty strings, trailing slashes, absolute path extensions), header inheritance when deriving sessions, body encoding error cases, 204/0-length response handling, query parameter encoding with special characters, multipart boundary generation uniqueness, cookie domain/path matching edge cases, redirect cycle detection, and TLS version negotiation." 167 - } 168 - ] 169 - }
-297
third_party/haskell/http-client.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "haskell/http-client", 5 - "source_language": "Haskell", 6 - "criticality": "high", 7 - "change_type": "bug", 8 - "title": "Add Connection Reuse Detection and Automatic Retry", 9 - "description": "http-client detects when a reused connection was closed by the server between requests (NoResponseDataReceived, IncompleteHeaders exceptions) and automatically retries the request with a fresh connection. The OCaml library lacks this critical reliability feature, which can cause intermittent failures when servers close keep-alive connections.", 10 - "affected_files": [ 11 - "lib/http_client.ml", 12 - "lib/error.ml", 13 - "lib/error.mli", 14 - "lib/one.ml" 15 - ], 16 - "rationale": "In http-client/Network/HTTP/Client/Core.hs:147-149, when a connection is reused (managedReused mconn) and throws a retryable exception (mRetryableException), the library automatically retries with a fresh connection. This handles the common case where a server closes a keep-alive connection between requests. Without this, clients experience random failures on connection reuse. The OCaml library currently doesn't track whether a connection was reused from the pool or detect this specific failure mode." 17 - }, 18 - { 19 - "source_repo": "haskell/http-client", 20 - "source_language": "Haskell", 21 - "criticality": "medium", 22 - "change_type": "enhancement", 23 - "title": "Add Request/Response Modification Hooks", 24 - "description": "http-client provides managerModifyRequest and managerModifyResponse hooks that allow intercepting and modifying all requests/responses before they're processed. This enables cross-cutting concerns like logging, metrics, request signing, response caching, and testing/mocking without modifying application code.", 25 - "affected_files": [ 26 - "lib/requests.ml", 27 - "lib/requests.mli", 28 - "lib/one.ml", 29 - "lib/one.mli" 30 - ], 31 - "rationale": "http-client/Network/HTTP/Client/Types.hs:800-814 defines managerModifyRequest and managerModifyResponse hooks. These are called for every request (Core.hs:198) and response (Core.hs:863), enabling powerful middleware-like functionality for logging, metrics, authentication, and testing. The OCaml library could add optional ~on_request:(Request.t -> Request.t) and ~on_response:(Response.t -> Response.t) parameters to the session creation and potentially support response interception for caching." 32 - }, 33 - { 34 - "source_repo": "haskell/http-client", 35 - "source_language": "Haskell", 36 - "criticality": "medium", 37 - "change_type": "feature", 38 - "title": "Add Configurable Header Size and Count Limits Per Manager", 39 - "description": "http-client allows configuring MaxHeaderLength (default 4KB) and MaxNumberHeaders (default 100) at the Manager level to protect against header bomb DoS attacks. These limits are enforced during response parsing. The OCaml library has similar limits but they appear to be hardcoded rather than configurable per session.", 40 - "affected_files": [ 41 - "lib/response_limits.ml", 42 - "lib/response_limits.mli", 43 - "lib/requests.ml", 44 - "lib/requests.mli" 45 - ], 46 - "rationale": "http-client/Network/HTTP/Client/Types.hs:827-838 defines configurable MaxHeaderLength (default 4096 bytes) and MaxNumberHeaders (default 100), set at manager creation and enforced during parsing (Headers.hs). The OCaml library has Response_limits.max_header_size and max_header_count, but they should be made easily configurable per Requests.t instance to allow different security profiles for different services (e.g., stricter for untrusted sources)." 47 - }, 48 - { 49 - "source_repo": "haskell/http-client", 50 - "source_language": "Haskell", 51 - "criticality": "high", 52 - "change_type": "security", 53 - "title": "Strip Proxy-Authorization Header on Secure HTTPS Connections", 54 - "description": "http-client automatically strips the Proxy-Authorization header when making secure (HTTPS) requests through a proxy using CONNECT method. This prevents leaking proxy credentials to the destination server. The OCaml library should implement similar protection.", 55 - "affected_files": [ 56 - "lib/one.ml", 57 - "lib/headers.ml", 58 - "lib/headers.mli" 59 - ], 60 - "rationale": "http-client/Network/HTTP/Client/Manager.hs:195-203 implements dropProxyAuthSecure which removes Proxy-Authorization headers for secure connections to prevent credential leakage to the destination server (only the proxy should see these credentials). The Core.hs:141 calls this before sending requests. The OCaml library should implement similar header stripping logic when using proxies with HTTPS." 61 - }, 62 - { 63 - "source_repo": "haskell/http-client", 64 - "source_language": "Haskell", 65 - "criticality": "low", 66 - "change_type": "feature", 67 - "title": "Add HTTP Early Hints (103) Support", 68 - "description": "http-client supports HTTP 103 Early Hints responses via an earlyHintHeadersReceived callback that's invoked when the server sends hints before the final response. This allows applications to preload resources while waiting for the full response.", 69 - "affected_files": [ 70 - "lib/http_read.ml", 71 - "lib/http_read.mli", 72 - "lib/response.ml", 73 - "lib/response.mli", 74 - "lib/requests.ml" 75 - ], 76 - "rationale": "http-client/Network/HTTP/Client/Types.hs:642-645 defines earlyHintHeadersReceived callback for HTTP 103 Early Hints (RFC 8297). The response parsing (Headers.hs) collects these early hints and invokes the callback. The Response type (Types.hs:727-731) includes responseEarlyHints field. This is a modern HTTP optimization that could benefit the OCaml library for improved performance with servers that support it." 77 - }, 78 - { 79 - "source_repo": "haskell/http-client", 80 - "source_language": "Haskell", 81 - "criticality": "medium", 82 - "change_type": "enhancement", 83 - "title": "Add URL and Header Credential Extraction from URIs", 84 - "description": "http-client automatically extracts basic auth credentials from URLs (http://user:pass@host/path) via extractBasicAuthInfo and applies them to requests. This provides convenient authentication for URLs with embedded credentials.", 85 - "affected_files": [ 86 - "lib/auth.ml", 87 - "lib/auth.mli", 88 - "lib/one.ml" 89 - ], 90 - "rationale": "http-client/Network/HTTP/Client/Request.hs:214-229 implements extractBasicAuthInfo and applyAnyUriBasedAuth to automatically extract username:password from URI userinfo and apply it as Basic Auth. This is called during setUri (Request.hs:246). The OCaml library could add Auth.from_uri : Uri.t -> Auth.t option to extract credentials and automatically apply them during request parsing." 91 - }, 92 - { 93 - "source_repo": "haskell/http-client", 94 - "source_language": "Haskell", 95 - "criticality": "low", 96 - "change_type": "enhancement", 97 - "title": "Add Configurable Redirect Header Stripping Behavior", 98 - "description": "http-client provides shouldStripHeaderOnRedirect (a function to decide per-header) and shouldStripHeaderOnRedirectIfOnDifferentHostOnly (strip only on cross-origin) for fine-grained control over which headers to preserve during redirects. The OCaml library has basic header stripping but less flexibility.", 99 - "affected_files": [ 100 - "lib/one.ml", 101 - "lib/headers.ml" 102 - ], 103 - "rationale": "http-client/Network/HTTP/Client/Types.hs:617-628 defines configurable redirect header stripping: shouldStripHeaderOnRedirect (per-header function) and shouldStripHeaderOnRedirectIfOnDifferentHostOnly flag. Response.hs:76-105 implements complex logic to handle same-origin vs cross-origin redirects and selectively strip/restore headers. The OCaml library currently has hardcoded stripping logic; making it configurable would support custom policies." 104 - }, 105 - { 106 - "source_repo": "haskell/http-client", 107 - "source_language": "Haskell", 108 - "criticality": "medium", 109 - "change_type": "feature", 110 - "title": "Add Support for RequestBodyIO for Lazy Body Construction", 111 - "description": "http-client supports RequestBodyIO which allows creating request bodies lazily inside the IO monad. This enables dynamic body generation based on runtime state, easier API ergonomics, and deferred resource allocation until the request is actually sent.", 112 - "affected_files": [ 113 - "lib/body.ml", 114 - "lib/body.mli" 115 - ], 116 - "rationale": "http-client/Network/HTTP/Client/Types.hs:380-384 defines RequestBodyIO which allows wrapping IO actions that produce RequestBody. This is evaluated lazily when the request is sent (Request.hs:481). This pattern enables cleaner APIs (like setRequestBodyFile) and deferred decisions. The OCaml library could add Body.lazy_t : (unit -> Body.t) variant for similar benefits, though Eio's structured concurrency may require careful handling." 117 - }, 118 - { 119 - "source_repo": "haskell/http-client", 120 - "source_language": "Haskell", 121 - "criticality": "medium", 122 - "change_type": "enhancement", 123 - "title": "Track and Expose Original Request in Response", 124 - "description": "http-client stores the original Request (with body cleared) in every Response via responseOriginalRequest field, accessible via getOriginalRequest. This enables response handlers to access request context without explicit threading.", 125 - "affected_files": [ 126 - "lib/response.ml", 127 - "lib/response.mli" 128 - ], 129 - "rationale": "http-client/Network/HTTP/Client/Types.hs:721-726 stores responseOriginalRequest (with empty body to save memory) in every Response. This is populated in Response.hs:165 and accessible via getOriginalRequest (Response.hs:183). This is valuable for logging, debugging, and response handlers that need request context (URL, headers, method). The OCaml library currently only stores the final URL; storing more request metadata would be beneficial." 130 - }, 131 - { 132 - "source_repo": "haskell/http-client", 133 - "source_language": "Haskell", 134 - "criticality": "low", 135 - "change_type": "enhancement", 136 - "title": "Add Configurable Accept-Encoding Header Logic", 137 - "description": "http-client automatically adds 'Accept-Encoding: gzip' unless the header is explicitly set. It supports three modes: not set (add gzip), empty string (remove header entirely), or custom value (use as-is). This provides fine control over compression negotiation.", 138 - "affected_files": [ 139 - "lib/headers.ml", 140 - "lib/headers.mli", 141 - "lib/one.ml" 142 - ], 143 - "rationale": "http-client/Network/HTTP/Client/Request.hs:532-536 implements smart Accept-Encoding handling: if not set, add 'gzip'; if set to empty string, remove it; otherwise use the provided value. This gives fine control: auto-compression (default), no compression (empty), or custom encoding (set explicitly). The OCaml library's auto_decompress flag is less flexible - it could support similar tri-state logic." 144 - }, 145 - { 146 - "source_repo": "haskell/http-client", 147 - "source_language": "Haskell", 148 - "criticality": "medium", 149 - "change_type": "feature", 150 - "title": "Add Support for Proxy Environment Variable Detection", 151 - "description": "http-client automatically detects and uses http_proxy/https_proxy environment variables via ProxyEnvironment functions, with configurable fallback behavior. This enables system-wide proxy configuration without code changes.", 152 - "affected_files": [ 153 - "lib/one.ml", 154 - "lib/one.mli", 155 - "lib/requests.ml" 156 - ], 157 - "rationale": "http-client/Network/HTTP/Client/Manager.hs:313-334 implements proxyEnvironment and proxyEnvironmentNamed to automatically detect http_proxy/https_proxy environment variables with configurable fallback. This is the default behavior (defaultProxy, Manager.hs:332-334). The OCaml library could add similar environment-based proxy detection to match system-level configuration (common in CI/CD, corporate networks)." 158 - }, 159 - { 160 - "source_repo": "haskell/http-client", 161 - "source_language": "Haskell", 162 - "criticality": "low", 163 - "change_type": "enhancement", 164 - "title": "Add Redactable Headers List for Safe Request Logging", 165 - "description": "http-client maintains a redactHeaders Set that specifies which headers to redact when showing/logging requests (default: Authorization). The Show instance for Request uses redactSensitiveHeader to replace sensitive values with <REDACTED>. This prevents credential leakage in logs.", 166 - "affected_files": [ 167 - "lib/headers.ml", 168 - "lib/headers.mli", 169 - "lib/error.ml" 170 - ], 171 - "rationale": "http-client/Network/HTTP/Client/Types.hs:637-640 defines redactHeaders Set (default: Authorization) and Types.hs:683-687 implements redactSensitiveHeader for safe logging. The Request Show instance (Types.hs:669) uses this to redact sensitive headers. The OCaml library has sanitize_headers in Error module but could formalize this as a configurable set of redactable header names for consistent safe logging." 172 - }, 173 - { 174 - "source_repo": "haskell/http-client", 175 - "source_language": "Haskell", 176 - "criticality": "medium", 177 - "change_type": "enhancement", 178 - "title": "Add WrongRequestBodyStreamSize Validation", 179 - "description": "http-client validates that streaming request bodies with declared Content-Length actually send the expected number of bytes, raising WrongRequestBodyStreamSize if there's a mismatch. This catches body truncation bugs early.", 180 - "affected_files": [ 181 - "lib/body.ml", 182 - "lib/http_write.ml", 183 - "lib/error.ml" 184 - ], 185 - "rationale": "http-client/Network/HTTP/Client/Types.hs:213-218 defines WrongRequestBodyStreamSize exception, and Request.hs:493 validates that stream bodies with declared length actually send that many bytes. This catches programming errors where the stream ends early or produces too much data. The OCaml library's Body.stream type could add similar validation to catch body length mismatches." 186 - }, 187 - { 188 - "source_repo": "haskell/http-client", 189 - "source_language": "Haskell", 190 - "criticality": "medium", 191 - "change_type": "enhancement", 192 - "title": "Add ResponseBodyTooShort Detection and Error", 193 - "description": "http-client detects when a response body is shorter than the declared Content-Length and raises ResponseBodyTooShort with expected and actual sizes. This catches premature connection closes and server bugs.", 194 - "affected_files": [ 195 - "lib/http_read.ml", 196 - "lib/error.ml", 197 - "lib/error.mli" 198 - ], 199 - "rationale": "http-client/Network/HTTP/Client/Types.hs:219-222 defines ResponseBodyTooShort exception. The body readers validate that the actual bytes received match Content-Length and raise this error on mismatch. This is critical for detecting truncated responses due to network issues or server bugs. The OCaml library has Content_length_mismatch but should ensure it's consistently enforced during streaming." 200 - }, 201 - { 202 - "source_repo": "haskell/http-client", 203 - "source_language": "Haskell", 204 - "criticality": "high", 205 - "change_type": "bug", 206 - "title": "Add NoResponseDataReceived Error for Connection Reuse Detection", 207 - "description": "http-client raises NoResponseDataReceived when reading from a connection returns empty data immediately, which typically indicates the connection was closed by the server. This is marked as retryable so stale connections from the pool are automatically replaced.", 208 - "affected_files": [ 209 - "lib/error.ml", 210 - "lib/error.mli", 211 - "lib/http_read.ml" 212 - ], 213 - "rationale": "http-client/Network/HTTP/Client/Types.hs:198-205 defines NoResponseDataReceived, raised in Headers.hs:68 when reading returns empty. This is specifically marked as retryable in Manager.hs:81 to handle stale pooled connections. The OCaml library should add this specific error case and mark it retryable in error.ml:is_retryable to support automatic retry on connection reuse (relates to Recommendation #1)." 214 - }, 215 - { 216 - "source_repo": "haskell/http-client", 217 - "source_language": "Haskell", 218 - "criticality": "low", 219 - "change_type": "enhancement", 220 - "title": "Add onRequestBodyException Handler for Body Streaming Errors", 221 - "description": "http-client provides onRequestBodyException callback to customize handling of exceptions thrown while streaming the request body. The default ignores IOExceptions but rethrows others. This allows graceful handling of network errors during uploads.", 222 - "affected_files": [ 223 - "lib/http_write.ml", 224 - "lib/one.ml", 225 - "lib/error.ml" 226 - ], 227 - "rationale": "http-client/Network/HTTP/Client/Types.hs:603-608 defines onRequestBodyException which handles exceptions during body streaming (Request.hs:445-446). Default behavior (Request.hs:300-303) ignores IOExceptions but rethrows others. This allows customizing recovery for upload errors. The OCaml library could add optional ~on_body_exception parameter to control error handling during body streaming." 228 - }, 229 - { 230 - "source_repo": "haskell/http-client", 231 - "source_language": "Haskell", 232 - "criticality": "low", 233 - "change_type": "feature", 234 - "title": "Add rawBody Mode to Skip Decompression and Dechunking", 235 - "description": "http-client supports rawBody flag which disables automatic decompression and dechunking, useful for proxying or when the application needs to handle encoding itself. The OCaml library only has auto_decompress for compression.", 236 - "affected_files": [ 237 - "lib/one.ml", 238 - "lib/one.mli", 239 - "lib/http_client.ml" 240 - ], 241 - "rationale": "http-client/Network/HTTP/Client/Types.hs:556-560 defines rawBody flag which disables both decompression (Request.hs:418) and dechunking (Response.hs:148-149). This is essential for HTTP proxies and cases where the application needs raw encoded data. The OCaml library has auto_decompress for gzip but could add a more comprehensive ~raw_body flag for both." 242 - }, 243 - { 244 - "source_repo": "haskell/http-client", 245 - "source_language": "Haskell", 246 - "criticality": "low", 247 - "change_type": "enhancement", 248 - "title": "Add decompress Predicate for Content-Type-Based Decompression Control", 249 - "description": "http-client uses a decompress predicate function (ByteString -> Bool) that decides whether to decompress based on MIME type. Default browserDecompress skips decompression for 'application/x-tar'. This prevents corrupting already-compressed archives.", 250 - "affected_files": [ 251 - "lib/one.ml", 252 - "lib/http_client.ml" 253 - ], 254 - "rationale": "http-client/Network/HTTP/Client/Types.hs:561-567 defines decompress predicate taking content-type and returning Bool. Request.hs:324-326 provides browserDecompress which skips tar files. Request.hs:420 checks this before decompressing. The OCaml library's auto_decompress is boolean; a predicate ~should_decompress:(Mime.t -> bool) would allow skipping decompression for tar and other pre-compressed formats." 255 - }, 256 - { 257 - "source_repo": "haskell/http-client", 258 - "source_language": "Haskell", 259 - "criticality": "medium", 260 - "change_type": "feature", 261 - "title": "Add hostAddress Field for Pre-Resolved IP Addresses", 262 - "description": "http-client supports optional hostAddress field to use a pre-resolved IP address, bypassing DNS resolution. This is useful for testing, performance optimization with cached DNS, or connecting to hosts with DNS issues.", 263 - "affected_files": [ 264 - "lib/one.ml", 265 - "lib/one.mli" 266 - ], 267 - "rationale": "http-client/Network/HTTP/Client/Types.hs:552-555 defines optional hostAddress field. Manager.hs:243-246 uses it to skip DNS when provided. This enables: testing against specific IPs, caching DNS results, working around DNS issues, and implementing custom DNS logic. The OCaml library could add optional ~host_address parameter to One.request for similar functionality." 268 - }, 269 - { 270 - "source_repo": "haskell/http-client", 271 - "source_language": "Haskell", 272 - "criticality": "low", 273 - "change_type": "enhancement", 274 - "title": "Add InvalidChunkHeaders Error for Malformed Chunked Encoding", 275 - "description": "http-client has a specific InvalidChunkHeaders exception for malformed chunked transfer encoding headers, distinct from general parsing errors. This helps diagnose server bugs and protocol violations.", 276 - "affected_files": [ 277 - "lib/error.ml", 278 - "lib/error.mli", 279 - "lib/http_read.ml" 280 - ], 281 - "rationale": "http-client/Network/HTTP/Client/Types.hs:224-227 defines InvalidChunkHeaders for chunked encoding parsing errors. This is more specific than generic parse errors and helps users diagnose whether the issue is in chunked encoding vs other HTTP parsing. The OCaml library could add this to error.ml as a distinct error case when parsing chunked bodies fails." 282 - }, 283 - { 284 - "source_repo": "haskell/http-client", 285 - "source_language": "Haskell", 286 - "criticality": "low", 287 - "change_type": "feature", 288 - "title": "Add ProxySecureMode for TLS Offloading to Proxy", 289 - "description": "http-client supports ProxySecureWithoutConnect mode which sends HTTPS requests directly to the proxy in plaintext rather than using CONNECT tunnel. This allows TLS offloading to a trusted local proxy (e.g., for monitoring).", 290 - "affected_files": [ 291 - "lib/one.ml", 292 - "lib/one.mli" 293 - ], 294 - "rationale": "http-client/Network/HTTP/Client/Types.hs:357-363 defines ProxySecureMode: WithConnect (tunnel) or WithoutConnect (offload TLS). Request.hs:380-381 and Manager.hs:232-234, 302-305 implement this. This is useful for trusted local proxies that terminate TLS for monitoring/caching. The OCaml library currently only supports CONNECT; adding ~proxy_secure_mode parameter would enable TLS offloading." 295 - } 296 - ] 297 - }
-271
third_party/haskell/http-streams.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/haskell/http-streams", 5 - "source_language": "Haskell", 6 - "criticality": "medium", 7 - "change_type": "enhancement", 8 - "title": "Add Unix domain socket support for local service communication", 9 - "description": "The Haskell library provides openConnectionUnix for connecting to Unix domain sockets (e.g., Docker daemon at /var/run/docker.sock). This enables efficient local IPC without TCP overhead. The OCaml library currently only supports TCP and TLS connections.", 10 - "affected_files": [ 11 - "lib/http_client.ml", 12 - "lib/requests.ml", 13 - "lib/one.ml" 14 - ], 15 - "rationale": "Unix domain sockets are commonly used for local service communication (Docker, systemd, local APIs). Adding this capability would enable the library to communicate with these services efficiently. The implementation would add a new connection type alongside HTTP and HTTPS pools, using Eio's Unix socket support." 16 - }, 17 - { 18 - "source_repo": "third_party/haskell/http-streams", 19 - "source_language": "Haskell", 20 - "criticality": "low", 21 - "change_type": "enhancement", 22 - "title": "Add streaming request body support from InputStream", 23 - "description": "The Haskell library provides inputStreamBody to stream request data from an existing InputStream without loading it into memory. While the OCaml library has Body.stream, it could be enhanced to accept arbitrary Eio.Flow sources for maximum flexibility.", 24 - "affected_files": [ 25 - "lib/body.ml", 26 - "lib/body.mli" 27 - ], 28 - "rationale": "The current streaming support is good but could be made more flexible by accepting any Eio.Flow.source_ty, allowing users to pipe data from arbitrary sources (network streams, compression streams, etc.) directly into the request body without intermediate buffering." 29 - }, 30 - { 31 - "source_repo": "third_party/haskell/http-streams", 32 - "source_language": "Haskell", 33 - "criticality": "medium", 34 - "change_type": "enhancement", 35 - "title": "Add explicit pipelining support and documentation", 36 - "description": "The Haskell library explicitly supports HTTP/1.1 pipelining through persistent connections, with clear documentation about matching request/response counts. The OCaml library has connection pooling but doesn't explicitly document pipelining capabilities or provide APIs to control it.", 37 - "affected_files": [ 38 - "lib/requests.mli", 39 - "lib/http_client.ml", 40 - "README.md" 41 - ], 42 - "rationale": "HTTP/1.1 pipelining can significantly improve performance for multiple requests to the same server by reducing round-trip latency. While the connection pool may enable this implicitly, explicit support with documentation would help users leverage this feature safely. This requires careful API design to ensure proper request/response ordering." 43 - }, 44 - { 45 - "source_repo": "third_party/haskell/http-streams", 46 - "source_language": "Haskell", 47 - "criticality": "low", 48 - "change_type": "enhancement", 49 - "title": "Add OAuth 2.0 Bearer token helper to Auth module", 50 - "description": "While the OCaml library already supports Bearer tokens via Auth.bearer, the Haskell library's approach of having simple wrapper functions for common patterns could inspire additional helpers for OAuth 2.0 flows (token refresh, authorization code exchange, etc.).", 51 - "affected_files": [ 52 - "lib/auth.ml", 53 - "lib/auth.mli" 54 - ], 55 - "rationale": "OAuth 2.0 is ubiquitous in modern APIs. While basic bearer token support exists, adding helpers for common OAuth flows (client credentials, authorization code with PKCE, token refresh) would reduce boilerplate for users. This is a convenience enhancement that doesn't change core functionality." 56 - }, 57 - { 58 - "source_repo": "third_party/haskell/http-streams", 59 - "source_language": "Haskell", 60 - "criticality": "medium", 61 - "change_type": "feature", 62 - "title": "Add response body size limit validation during streaming", 63 - "description": "The Haskell library's readFixedLengthBody terminates the stream after the requested number of bytes (via Streams.takeBytes), preventing over-reading. The OCaml library has Response_limits.max_response_body_size but should ensure this limit is enforced during streaming, not just for fixed-length bodies.", 64 - "affected_files": [ 65 - "lib/http_read.ml", 66 - "lib/response.ml" 67 - ], 68 - "rationale": "While the OCaml library has comprehensive DoS limits, verifying that max_response_body_size is enforced during chunked transfer encoding and unlimited bodies (HTTP/1.0 style) would prevent memory exhaustion attacks. The limit should cause the stream to terminate cleanly when exceeded." 69 - }, 70 - { 71 - "source_repo": "third_party/haskell/http-streams", 72 - "source_language": "Haskell", 73 - "criticality": "low", 74 - "change_type": "enhancement", 75 - "title": "Add builder-based request body construction for efficiency", 76 - "description": "The Haskell library uses Blaze.Builder for efficient incremental construction of request bodies without intermediate allocations. The OCaml library could benefit from using a similar builder pattern (e.g., Faraday or Buffer-based builders) for constructing multipart forms and encoded data.", 77 - "affected_files": [ 78 - "lib/body.ml", 79 - "lib/http_write.ml" 80 - ], 81 - "rationale": "Builder patterns avoid intermediate string allocations when constructing complex request bodies. For multipart forms with many fields or URL-encoded data, this can significantly reduce memory pressure and improve performance. This is an optimization that maintains API compatibility." 82 - }, 83 - { 84 - "source_repo": "third_party/haskell/http-streams", 85 - "source_language": "Haskell", 86 - "criticality": "high", 87 - "change_type": "security", 88 - "title": "Enhance TLS certificate validation documentation and warnings", 89 - "description": "The Haskell library's baselineContextSSL has platform-specific behavior where macOS and Windows default to VerifyNone (no certificate validation). The OCaml library should prominently document that verify_tls=false is dangerous and should never be used in production, similar to how the Haskell library documents its platform limitations.", 90 - "affected_files": [ 91 - "lib/requests.mli", 92 - "README.md", 93 - "examples/README.md" 94 - ], 95 - "rationale": "Security-critical settings like TLS verification deserve clear, prominent documentation with warnings. The Haskell library's platform-specific approach highlights the importance of making TLS verification explicit. The OCaml library should emphasize that verify_tls=true is the only safe production setting and document what certificate authorities are used." 96 - }, 97 - { 98 - "source_repo": "third_party/haskell/http-streams", 99 - "source_language": "Haskell", 100 - "criticality": "medium", 101 - "change_type": "enhancement", 102 - "title": "Add receiveResponseRaw equivalent for accessing compressed data", 103 - "description": "The Haskell library provides receiveResponseRaw to explicitly access raw gzipped content without automatic decompression. The OCaml library's auto_decompress flag is global; adding a per-request override would enable use cases where raw compressed data is needed (integrity verification, re-compression, etc.).", 104 - "affected_files": [ 105 - "lib/requests.ml", 106 - "lib/one.ml", 107 - "lib/http_client.ml" 108 - ], 109 - "rationale": "Some use cases require access to the raw compressed response (e.g., caching gzipped content, verifying compression ratios, or re-serving compressed data). While auto_decompress can be disabled globally, a per-request option would be more flexible without requiring session reconfiguration." 110 - }, 111 - { 112 - "source_repo": "third_party/haskell/http-streams", 113 - "source_language": "Haskell", 114 - "criticality": "low", 115 - "change_type": "enhancement", 116 - "title": "Add convenience handler for ignoring response body", 117 - "description": "The Haskell library's pattern of providing pre-built handlers (debugHandler, simpleHandler, jsonHandler) is useful. Adding a handler that simply discards the response body (useful for HEAD requests or when only headers matter) would be a nice convenience.", 118 - "affected_files": [ 119 - "lib/response.ml", 120 - "lib/response.mli" 121 - ], 122 - "rationale": "For HEAD requests or cases where only response headers matter (checking if a resource exists, getting metadata), users shouldn't need to manually consume the body stream. A Response.ignore_body or Response.discard_body helper would make this clearer and avoid common mistakes." 123 - }, 124 - { 125 - "source_repo": "third_party/haskell/http-streams", 126 - "source_language": "Haskell", 127 - "criticality": "medium", 128 - "change_type": "enhancement", 129 - "title": "Add explicit response body consumption guarantees for connection reuse", 130 - "description": "The Haskell library's receiveResponse explicitly drains the response body (Streams.skipToEof) to maintain HTTP protocol invariants for pipelining/connection reuse. The OCaml library should document whether this happens automatically or if users must fully consume responses to enable connection reuse.", 131 - "affected_files": [ 132 - "lib/http_client.ml", 133 - "lib/requests.mli", 134 - "lib/one.mli" 135 - ], 136 - "rationale": "Connection pooling requires that response bodies are fully consumed before returning connections to the pool. The Haskell library explicitly handles this with skipToEof. The OCaml library should document this requirement and potentially add automatic draining (or at least clear warnings) to prevent connection pool corruption." 137 - }, 138 - { 139 - "source_repo": "third_party/haskell/http-streams", 140 - "source_language": "Haskell", 141 - "criticality": "low", 142 - "change_type": "refactor", 143 - "title": "Consider separating convenience API into distinct module", 144 - "description": "The Haskell library separates its low-level API (Network.Http.Connection) from convenience functions (Network.Http.Inconvenience). The OCaml library combines these in Requests and One modules. A clearer separation might improve discoverability and reduce API surface for advanced users.", 145 - "affected_files": [ 146 - "lib/requests.ml", 147 - "lib/requests.mli" 148 - ], 149 - "rationale": "The Haskell library's separation of concerns makes it clear when you're using 'training wheels' (Inconvenience) vs. the full API. While the OCaml library's current structure works, some users might appreciate a clearer distinction between simple use cases (One module) and full session management (Requests module)." 150 - }, 151 - { 152 - "source_repo": "third_party/haskell/http-streams", 153 - "source_language": "Haskell", 154 - "criticality": "medium", 155 - "change_type": "enhancement", 156 - "title": "Add request/response interceptor hooks for observability", 157 - "description": "The Haskell library's handler pattern enables inspection of all responses. Adding explicit interceptor/middleware hooks in the OCaml library would enable observability features (metrics collection, distributed tracing, request/response logging) without modifying core code.", 158 - "affected_files": [ 159 - "lib/requests.ml", 160 - "lib/http_client.ml" 161 - ], 162 - "rationale": "Modern applications need observability hooks for metrics, tracing, and logging. While users can wrap the API, built-in interceptor support (before_request, after_response, on_error hooks) would standardize this pattern and make the library more enterprise-friendly. This enables OpenTelemetry integration, custom metrics, etc." 163 - }, 164 - { 165 - "source_repo": "third_party/haskell/http-streams", 166 - "source_language": "Haskell", 167 - "criticality": "low", 168 - "change_type": "enhancement", 169 - "title": "Add URL type and parser module for better ergonomics", 170 - "description": "The Haskell library defines a URL type (ByteString) and provides parseURL with escaping support. While the OCaml library uses Uri, adding URL builder helpers specifically for HTTP requests (with automatic encoding of query parameters, path segments) would improve ergonomics.", 171 - "affected_files": [ 172 - "lib/requests.ml", 173 - "lib/one.ml" 174 - ], 175 - "rationale": "Building URLs with query parameters is common but error-prone (escaping, encoding). While Uri exists, adding HTTP-specific helpers (add_query_param, build_path) similar to Python requests or the Haskell library's URL encoding would reduce errors and boilerplate. This is a convenience layer over Uri." 176 - }, 177 - { 178 - "source_repo": "third_party/haskell/http-streams", 179 - "source_language": "Haskell", 180 - "criticality": "medium", 181 - "change_type": "feature", 182 - "title": "Add automatic handling of 100-Continue rejection", 183 - "description": "The Haskell library's sendRequest handles 100-Continue by checking for non-100 responses and 'putting the response back' (Streams.unRead) to be processed by receiveResponse. The OCaml library should document how it handles servers that reject 100-Continue requests (sending error status instead of 100).", 184 - "affected_files": [ 185 - "lib/http_client.ml", 186 - "lib/expect_continue.ml" 187 - ], 188 - "rationale": "When using Expect: 100-continue, servers may respond with error status codes (e.g., 401 Unauthorized) instead of 100 Continue. The implementation should handle this by not sending the body and processing the error response normally. The Haskell library's unRead approach is one solution; documenting or improving this behavior would prevent surprises." 189 - }, 190 - { 191 - "source_repo": "third_party/haskell/http-streams", 192 - "source_language": "Haskell", 193 - "criticality": "low", 194 - "change_type": "enhancement", 195 - "title": "Add content-type based response helpers", 196 - "description": "The Haskell library provides jsonHandler that automatically parses JSON responses. The OCaml library has Response.json but could add more content-type-aware helpers (xml, html, csv) or a generic handler that dispatches based on Content-Type header.", 197 - "affected_files": [ 198 - "lib/response.ml", 199 - "lib/response.mli" 200 - ], 201 - "rationale": "While JSON is covered, APIs return various content types. Adding helpers for common types (or a dispatch mechanism based on Content-Type) would reduce boilerplate. However, this requires additional dependencies (XML parser, CSV parser), so it might be better as optional extensions or examples rather than core features." 202 - }, 203 - { 204 - "source_repo": "third_party/haskell/http-streams", 205 - "source_language": "Haskell", 206 - "criticality": "medium", 207 - "change_type": "enhancement", 208 - "title": "Add support for PATCH method in convenience APIs", 209 - "description": "The Haskell library mentions PATCH in documentation but focuses on GET/POST/PUT. The OCaml library supports PATCH in Method.t but should ensure it's consistently available in all convenience functions and properly documented.", 210 - "affected_files": [ 211 - "lib/requests.ml", 212 - "lib/one.ml", 213 - "lib/requests.mli", 214 - "lib/one.mli" 215 - ], 216 - "rationale": "PATCH is a standard HTTP method (RFC 5789) commonly used in REST APIs for partial updates. While the OCaml library supports it in the low-level API, ensuring it has convenience wrappers (session.patch, One.patch) with the same ergonomics as post and put would improve completeness." 217 - }, 218 - { 219 - "source_repo": "third_party/haskell/http-streams", 220 - "source_language": "Haskell", 221 - "criticality": "high", 222 - "change_type": "bug", 223 - "title": "Verify Content-Length handling with chunked encoding", 224 - "description": "The Haskell library's response parser explicitly handles the precedence of Transfer-Encoding: chunked over Content-Length (chunked takes priority). The OCaml library should verify its implementation matches RFC 9112 Section 6.3, which mandates ignoring Content-Length when Transfer-Encoding is present.", 225 - "affected_files": [ 226 - "lib/http_read.ml" 227 - ], 228 - "rationale": "RFC 9112 Section 6.3 specifies that if both Transfer-Encoding and Content-Length are present, Content-Length MUST be ignored. This is a security issue (HTTP request smuggling) if handled incorrectly. The Haskell library's parser explicitly encodes this precedence; the OCaml implementation should be audited to ensure it follows the same logic." 229 - }, 230 - { 231 - "source_repo": "third_party/haskell/http-streams", 232 - "source_language": "Haskell", 233 - "criticality": "medium", 234 - "change_type": "enhancement", 235 - "title": "Add support for handling 1xx informational responses", 236 - "description": "The Haskell library explicitly handles 100 Continue in expect-continue flow. The OCaml library should document its handling of other 1xx responses (101 Switching Protocols, 102 Processing, 103 Early Hints) per RFC 9110, particularly whether they're exposed to users or handled transparently.", 237 - "affected_files": [ 238 - "lib/http_read.ml", 239 - "lib/http_client.ml" 240 - ], 241 - "rationale": "1xx status codes are informational and can appear before final responses. While 100 Continue is handled, other 1xx codes (especially 103 Early Hints for resource hints) may appear in real-world scenarios. The implementation should either transparently skip them or expose them to users for advanced use cases like HTTP/2 push." 242 - }, 243 - { 244 - "source_repo": "third_party/haskell/http-streams", 245 - "source_language": "Haskell", 246 - "criticality": "low", 247 - "change_type": "enhancement", 248 - "title": "Add automatic Host header handling documentation", 249 - "description": "The Haskell library explicitly documents that the Host header is automatically set from the connection hostname and port (getHostname function). The OCaml library should clearly document this behavior and whether users can override it (for proxy scenarios or virtual hosting).", 250 - "affected_files": [ 251 - "lib/http_write.ml", 252 - "lib/http_write.mli", 253 - "README.md" 254 - ], 255 - "rationale": "The Host header is mandatory in HTTP/1.1 and affects virtual hosting and routing. Documenting when it's automatically set, how port numbers are handled (:80 vs :443 omission), and whether users can override it for proxy/tunneling scenarios would prevent confusion and support advanced use cases." 256 - }, 257 - { 258 - "source_repo": "third_party/haskell/http-streams", 259 - "source_language": "Haskell", 260 - "criticality": "low", 261 - "change_type": "enhancement", 262 - "title": "Add pretty-printing for Request objects", 263 - "description": "The Haskell library has instance Show Connection that prints connection details. The OCaml library could add Format.t pretty-printers for Request and Connection types to aid debugging, similar to the existing Response.pp and Response.pp_detailed.", 264 - "affected_files": [ 265 - "lib/http_client.ml", 266 - "lib/requests.ml" 267 - ], 268 - "rationale": "Debugging HTTP requests is easier with readable representations. Adding Format-based pretty-printers for Request objects (method, URL, headers) and Connection state would improve developer experience. This is especially useful in REPL sessions and when logging requests." 269 - } 270 - ] 271 - }
-217
third_party/haskell/req.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/haskell/req", 5 - "source_language": "Haskell", 6 - "criticality": "medium", 7 - "change_type": "enhancement", 8 - "title": "Add response body preview to HTTP error exceptions", 9 - "description": "The Haskell req library includes the first 1024 bytes of the response body in error exceptions via httpConfigBodyPreviewLength. This significantly improves debugging by allowing developers to see error messages from the server without consuming the response body. The OCaml library's Http_error variant includes body_preview but it's not consistently populated with actual response data during error handling.", 10 - "affected_files": [ 11 - "lib/error.ml", 12 - "lib/error.mli", 13 - "lib/one.ml", 14 - "lib/requests.ml" 15 - ], 16 - "rationale": "When HTTP requests fail with non-2xx status codes, developers often need to see the error response body to understand what went wrong. The Haskell library's approach of capturing a configurable preview (default 1024 bytes) before deciding whether to throw an exception allows for better error messages without the overhead of always consuming the full body. This is particularly valuable for API errors that return JSON error details. The OCaml library should ensure that the body_preview field in Http_error is consistently populated during error handling, with a configurable preview size similar to Haskell's httpConfigBodyPreviewLength." 17 - }, 18 - { 19 - "source_repo": "third_party/haskell/req", 20 - "source_language": "Haskell", 21 - "criticality": "medium", 22 - "change_type": "enhancement", 23 - "title": "Implement response checking before body consumption", 24 - "description": "The Haskell req library performs response validation immediately after receiving status and headers, before streaming the body (via httpConfigCheckResponse). This allows early rejection of error responses without the cost of reading the entire body. The OCaml library currently reads the full response before checking status codes.", 25 - "affected_files": [ 26 - "lib/http_client.ml", 27 - "lib/http_read.ml", 28 - "lib/requests.ml", 29 - "lib/one.ml" 30 - ], 31 - "rationale": "Checking the response status and headers before consuming the body is more efficient, especially for large error responses. The Haskell library's httpConfigCheckResponse is called with the status, headers, and a small body preview, allowing it to throw an exception and short-circuit processing before streaming gigabytes of error response. This pattern also enables proper retry logic: if a response fails validation, the library can retry without having consumed the full body. The OCaml library should add a validation hook that runs after headers are parsed but before the body is streamed, similar to Haskell's approach." 32 - }, 33 - { 34 - "source_repo": "third_party/haskell/req", 35 - "source_language": "Haskell", 36 - "criticality": "low", 37 - "change_type": "enhancement", 38 - "title": "Add OAuth 1.0 authentication support", 39 - "description": "The Haskell req library provides built-in OAuth 1.0 signature support via the oAuth1 function, which handles request signing with consumer token, consumer secret, access token, and token secret. The OCaml library currently only supports Basic, Bearer, and Digest authentication.", 40 - "affected_files": [ 41 - "lib/auth.ml", 42 - "lib/auth.mli" 43 - ], 44 - "rationale": "While OAuth 2.0 (Bearer tokens) is more common, OAuth 1.0 is still used by several major APIs including Twitter (X), Tumblr, and some financial services APIs. The Haskell library's implementation applies OAuth 1.0 signing as a request finalizer, which ensures the signature is computed after all other request modifications (URL, headers, body) are complete. This is the correct approach for OAuth 1.0 as the signature must cover the final request. The OCaml library could add similar support using an external OAuth library or implementing RFC 5849 directly, applying the signature in the custom auth handler pattern that already exists." 45 - }, 46 - { 47 - "source_repo": "third_party/haskell/req", 48 - "source_language": "Haskell", 49 - "criticality": "low", 50 - "change_type": "enhancement", 51 - "title": "Support queryFlag for valueless query parameters", 52 - "description": "The Haskell req library distinguishes between query parameters with values (=:) and flags/valueless parameters (queryFlag). For example, in 'https://example.com?debug&format=json', 'debug' is a flag. The OCaml library's current query parameter API doesn't explicitly support flags, only key-value pairs.", 53 - "affected_files": [ 54 - "lib/requests.ml", 55 - "lib/requests.mli", 56 - "lib/one.ml", 57 - "lib/one.mli" 58 - ], 59 - "rationale": "Some APIs use valueless query parameters (flags) with specific semantics different from empty-value parameters. For example, '?debug' vs '?debug=' can have different meanings in certain APIs. The Haskell library's QueryParam typeclass provides both '=:' for valued parameters and 'queryFlag' for flags, with a unified interface that works for both URL query strings and form-encoded bodies. The OCaml library could add support for valueless parameters by accepting (string * string option) list for query params, where None indicates a flag." 60 - }, 61 - { 62 - "source_repo": "third_party/haskell/req", 63 - "source_language": "Haskell", 64 - "criticality": "medium", 65 - "change_type": "enhancement", 66 - "title": "Add configurable retry policy with separate exception and response judges", 67 - "description": "The Haskell req library separates retry logic into httpConfigRetryJudge (for responses) and httpConfigRetryJudgeException (for exceptions), both using the retry library's RetryStatus. The OCaml library has a single retry configuration but doesn't distinguish between response-based and exception-based retry decisions with separate configurable predicates.", 68 - "affected_files": [ 69 - "lib/retry.ml", 70 - "lib/retry.mli", 71 - "lib/requests.ml" 72 - ], 73 - "rationale": "Different retry strategies are appropriate for exceptions vs. HTTP responses. For example, you might want to retry all connection timeouts (exceptions) but only retry specific HTTP status codes like 429 or 503 (responses). The Haskell library provides httpConfigRetryJudge for deciding based on response status and httpConfigRetryJudgeException for deciding based on exceptions. Both receive a RetryStatus that includes the attempt number and cumulative delay, enabling sophisticated retry logic. The OCaml library should expose separate configurable predicates: should_retry_response : (config -> response -> retry_status -> bool) and should_retry_exception : (config -> exn -> retry_status -> bool), along with a retry_status record containing attempt and cumulative delay information." 74 - }, 75 - { 76 - "source_repo": "third_party/haskell/req", 77 - "source_language": "Haskell", 78 - "criticality": "low", 79 - "change_type": "enhancement", 80 - "title": "Add custom Accept header based on response type", 81 - "description": "The Haskell req library's HttpResponse typeclass includes an acceptHeader method that allows response types to specify their preferred Accept header. For example, jsonResponse automatically sets 'Accept: application/json'. The OCaml library doesn't automatically set Accept headers based on expected response parsing.", 82 - "affected_files": [ 83 - "lib/requests.ml", 84 - "lib/one.ml", 85 - "lib/response.ml" 86 - ], 87 - "rationale": "Setting the Accept header based on the expected response type is a best practice for content negotiation. When you're expecting JSON, sending 'Accept: application/json' helps servers return the right format and can prevent issues with APIs that support multiple response types. The Haskell library's approach allows the response parser to specify what it expects, and this is automatically added to the request (but can be overridden). The OCaml library could add an optional accept parameter to request functions, or provide helper functions like get_json that automatically set the appropriate Accept header." 88 - }, 89 - { 90 - "source_repo": "third_party/haskell/req", 91 - "source_language": "Haskell", 92 - "criticality": "high", 93 - "change_type": "security", 94 - "title": "Add HTTPS-only enforcement for sensitive authentication methods", 95 - "description": "The Haskell req library uses phantom types (Option 'Https vs Option scheme) to enforce at compile-time that sensitive auth methods like basicAuth, oAuth2Bearer, and oAuth2Token can only be used with HTTPS URLs. The library provides *Unsafe variants for cases where HTTP is needed. The OCaml library has no such compile-time or runtime enforcement.", 96 - "affected_files": [ 97 - "lib/auth.ml", 98 - "lib/auth.mli", 99 - "lib/requests.ml", 100 - "lib/one.ml" 101 - ], 102 - "rationale": "Sending credentials over unencrypted HTTP connections is a critical security vulnerability that exposes usernames, passwords, and tokens to network eavesdropping. The Haskell library's type system prevents this at compile time - you literally cannot compile code that sends basicAuth over an HTTP URL unless you explicitly use basicAuthUnsafe. While OCaml can't achieve the same compile-time guarantee without phantom types, it should add runtime checks that raise Invalid_request or Security_error when attempting to use Basic, Bearer, or Digest auth with a non-HTTPS URL. This should be configurable with an allow_insecure_auth flag for testing environments, but should be strict by default." 103 - }, 104 - { 105 - "source_repo": "third_party/haskell/req", 106 - "source_language": "Haskell", 107 - "criticality": "medium", 108 - "change_type": "enhancement", 109 - "title": "Add URL construction helpers with automatic encoding", 110 - "description": "The Haskell req library provides operators (/~) and (/:) for building URLs with automatic percent-encoding of path segments. This ensures URLs are correct-by-construction and prevents injection attacks. The OCaml library accepts URL strings directly without providing path construction helpers.", 111 - "affected_files": [ 112 - "lib/requests.ml", 113 - "lib/requests.mli", 114 - "lib/one.ml", 115 - "lib/one.mli" 116 - ], 117 - "rationale": "Building URLs by string concatenation is error-prone and can lead to injection vulnerabilities if user input is included without proper encoding. The Haskell library's approach (https 'httpbin.org' /: 'bytes' /~ n) ensures each path segment is properly percent-encoded. While the OCaml library accepts Uri.t which handles encoding, it doesn't provide ergonomic helpers for building paths. Adding a URL builder module with functions like Url.make ~scheme:Https ~host:\"api.example.com\" |> Url.add_path \"users\" |> Url.add_path user_id would improve safety and ergonomics. Alternatively, enhance the existing API to accept path segments separately from the base URL." 118 - }, 119 - { 120 - "source_repo": "third_party/haskell/req", 121 - "source_language": "Haskell", 122 - "criticality": "low", 123 - "change_type": "enhancement", 124 - "title": "Add req' and reqBr variants for custom request handling", 125 - "description": "The Haskell req library provides req' for custom request handling that bypasses automatic retry/checking, and reqBr for consuming Response BodyReader manually. These give users full control when needed. The OCaml library doesn't expose similar low-level escape hatches.", 126 - "affected_files": [ 127 - "lib/requests.ml", 128 - "lib/requests.mli", 129 - "lib/one.ml", 130 - "lib/one.mli" 131 - ], 132 - "rationale": "While high-level APIs are great for common cases, advanced users sometimes need full control over request execution. The Haskell library's req' function allows users to provide a custom handler (L.Request -> L.Manager -> m a) that receives the prepared request and connection manager, bypassing retry logic and response checking. Similarly, reqBr allows manual consumption of the response stream. The OCaml library could add request_raw and request_with_handler variants that expose the underlying HTTP/1.1 connection and parsed response without automatic retry or validation, giving users an escape hatch for advanced use cases while still benefiting from connection pooling and TLS setup." 133 - }, 134 - { 135 - "source_repo": "third_party/haskell/req", 136 - "source_language": "Haskell", 137 - "criticality": "low", 138 - "change_type": "enhancement", 139 - "title": "Add MonadHttp typeclass pattern for flexible execution contexts", 140 - "description": "The Haskell req library defines a MonadHttp typeclass that abstracts over the execution environment, with instances for IO, ReaderT, ExceptT, StateT, and all common monad transformers. This allows req to work in any monad stack. The OCaml library is hardcoded to Eio effects.", 141 - "affected_files": [ 142 - "lib/requests.ml", 143 - "lib/requests.mli" 144 - ], 145 - "rationale": "While the MonadHttp abstraction is a Haskell-specific pattern that relies on monad transformers, the underlying principle is valuable: separating the request execution logic from how errors are handled. The OCaml library is tightly coupled to Eio exceptions. A more flexible design would accept error handlers as parameters or provide a with_error_handler combinator that allows users to specify whether errors should raise exceptions, return Result types, or integrate with other error handling patterns. This is particularly useful for libraries that want to use Requests internally but have their own error handling conventions." 146 - }, 147 - { 148 - "source_repo": "third_party/haskell/req", 149 - "source_language": "Haskell", 150 - "criticality": "medium", 151 - "change_type": "enhancement", 152 - "title": "Add isStatusCodeException helper for error inspection", 153 - "description": "The Haskell req library provides isStatusCodeException to extract L.Response () from HttpException when it's a status code error. This allows pattern matching on status codes in error handlers. The OCaml library's error type includes status but doesn't provide structured extraction helpers.", 154 - "affected_files": [ 155 - "lib/error.ml", 156 - "lib/error.mli" 157 - ], 158 - "rationale": "When handling HTTP errors, it's common to want to inspect the status code and make decisions (e.g., retry on 429, fail permanently on 404). The Haskell library's isStatusCodeException function returns Maybe (Response ()) which can be inspected for status code, headers, etc. The OCaml library already has get_http_status but could benefit from more granular extractors: get_response_headers : error -> (string * string) list option, get_response_body_preview : error -> string option. These would make error handling more ergonomic and reduce the need for pattern matching on the full error variant." 159 - }, 160 - { 161 - "source_repo": "third_party/haskell/req", 162 - "source_language": "Haskell", 163 - "criticality": "low", 164 - "change_type": "feature", 165 - "title": "Add form URL-encoding support that works like query parameters", 166 - "description": "The Haskell req library's FormUrlEncodedParam type uses the same =: and queryFlag operators as query parameters, providing a unified API. The ReqBodyUrlEnc constructor wraps these params for use as request body. The OCaml library has Body.form but the API for constructing form data is different from query parameters.", 167 - "affected_files": [ 168 - "lib/body.ml", 169 - "lib/body.mli", 170 - "lib/requests.ml" 171 - ], 172 - "rationale": "Form URL-encoded bodies are essentially query parameters in the request body instead of the URL. Having a consistent API for both use cases reduces cognitive load. The Haskell library's approach (let params = 'foo' =: 'bar' <> queryFlag 'baz') works for both query strings and form bodies. The OCaml library could provide a unified Params module with functions like Params.empty |> Params.add 'key' (Some 'value') |> Params.add_flag 'debug' that can be used with both ?params for URL query strings and ~body:(Body.form params) for request bodies." 173 - }, 174 - { 175 - "source_repo": "third_party/haskell/req", 176 - "source_language": "Haskell", 177 - "criticality": "low", 178 - "change_type": "enhancement", 179 - "title": "Add property-based testing for URL construction and request building", 180 - "description": "The Haskell req library uses QuickCheck for property-based testing of URL construction, header handling, and request modifications (pure-tests/Network/HTTP/ReqSpec.hs). This catches edge cases in URL encoding and request building. The OCaml library uses example-based tests.", 181 - "affected_files": [ 182 - "test/", 183 - "dune" 184 - ], 185 - "rationale": "Property-based testing is particularly valuable for HTTP client libraries because of the complexity of URL encoding, header parsing, and request construction. The Haskell tests verify properties like 'URL encoding roundtrips correctly', 'Headers are case-insensitive', 'Request modifications compose correctly'. These catch edge cases that example-based tests miss. The OCaml library should add QCheck-based property tests for: URL encoding/decoding with arbitrary strings, header name case-insensitivity, query parameter encoding with special characters, multipart boundary generation uniqueness, and retry backoff calculation bounds. This would improve robustness and catch regressions." 186 - }, 187 - { 188 - "source_repo": "third_party/haskell/req", 189 - "source_language": "Haskell", 190 - "criticality": "medium", 191 - "change_type": "enhancement", 192 - "title": "Add configurable redirect count to HttpConfig", 193 - "description": "The Haskell req library's HttpConfig includes httpConfigRedirectCount (default 10) that's passed directly to the underlying HTTP client. This allows per-request or per-session configuration of max redirects. The OCaml library has max_redirects but it's not clear if it's configurable per-request.", 194 - "affected_files": [ 195 - "lib/requests.ml", 196 - "lib/requests.mli", 197 - "lib/one.ml", 198 - "lib/one.mli" 199 - ], 200 - "rationale": "Different APIs have different redirect behaviors, and sometimes you need to override the default. The Haskell library allows configuring redirect count via HttpConfig which can be set globally or per-request. Looking at the OCaml library's interface, max_redirects is available in create but it's not clear if individual request methods support overriding it. The request function signature should include an optional ?max_redirects parameter that overrides the session default, similar to how ?timeout and ?auth already work. This gives users fine-grained control when needed without forcing them to create a new session." 201 - }, 202 - { 203 - "source_repo": "third_party/haskell/req", 204 - "source_language": "Haskell", 205 - "criticality": "low", 206 - "change_type": "refactor", 207 - "title": "Add request finalizers for post-construction modifications", 208 - "description": "The Haskell req library uses request finalizers (Maybe (L.Request -> IO L.Request)) in the Option type for modifications that must happen after all other request building is complete. This is used for OAuth 1.0 signing which must sign the final request. The OCaml library applies auth directly to headers.", 209 - "affected_files": [ 210 - "lib/auth.ml", 211 - "lib/requests.ml", 212 - "lib/one.ml" 213 - ], 214 - "rationale": "Some authentication schemes (OAuth 1.0, AWS SigV4, custom HMAC) must sign the complete request including URL, headers, and body. Applying these transformations too early means they sign incomplete data. The Haskell library's Option type includes a finalizer field that's applied after all other modifications. The OCaml library's current auth system applies authentication to headers, which works for Basic/Bearer but wouldn't work for request-signing schemes. Adding a request finalizer mechanism (type finalizer = Headers.t -> Body.t option -> string -> Method.t -> Headers.t) would enable proper support for signing-based auth. The custom auth handler could specify whether it's a header modifier or a finalizer." 215 - } 216 - ] 217 - }
-210
third_party/java/http-request.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/java/http-request", 5 - "source_language": "Java", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add upload progress callback support", 9 - "description": "The Java library provides an UploadProgress callback interface that allows tracking upload progress with onUpload(uploaded, total) callbacks. This enables progress bars and bandwidth monitoring for large file uploads. The OCaml library lacks this feature.", 10 - "affected_files": [ 11 - "lib/body.mli", 12 - "lib/body.ml", 13 - "lib/http_write.ml" 14 - ], 15 - "rationale": "Progress tracking is essential for user experience when uploading large files. The Java library demonstrates this with UploadProgress.onUpload(long uploaded, long total) callback. In OCaml, this could be implemented using optional callback parameters in Body.multipart and Body.of_stream, accepting a function of type (int64 -> int64 -> unit). This would integrate cleanly with the existing streaming architecture." 16 - }, 17 - { 18 - "source_repo": "third_party/java/http-request", 19 - "source_language": "Java", 20 - "criticality": "low", 21 - "change_type": "feature", 22 - "title": "Add convenience methods for checking specific HTTP status codes", 23 - "description": "The Java library provides convenience methods like ok(), created(), badRequest(), notFound(), serverError() to check for specific status codes without manually comparing integers. The OCaml library only has Response.ok for 2xx status checks.", 24 - "affected_files": [ 25 - "lib/response.mli", 26 - "lib/response.ml" 27 - ], 28 - "rationale": "The Java library shows that developers frequently check for specific status codes (created/201, notModified/304, badRequest/400, notFound/404, serverError/500). Adding Response.created, Response.not_modified, Response.bad_request, Response.not_found, Response.server_error would improve API ergonomics. These are simple boolean functions that map to Status.is_* predicates but provide better discoverability at the Response level." 29 - }, 30 - { 31 - "source_repo": "third_party/java/http-request", 32 - "source_language": "Java", 33 - "criticality": "medium", 34 - "change_type": "enhancement", 35 - "title": "Support configurable buffer sizes for streaming operations", 36 - "description": "The Java library allows setting buffer size with bufferSize(int) method (default 8192 bytes). The OCaml library uses fixed buffer sizes in various streaming operations without user control.", 37 - "affected_files": [ 38 - "lib/requests.mli", 39 - "lib/requests.ml", 40 - "lib/one.mli", 41 - "lib/one.ml", 42 - "lib/http_write.ml", 43 - "lib/http_read.ml" 44 - ], 45 - "rationale": "Different use cases benefit from different buffer sizes. Small buffers (4KB) reduce memory for many small requests; large buffers (64KB+) improve throughput for large file transfers. The Java library defaults to 8KB but allows customization. Add buffer_size parameter to create() and One.create() functions, stored in the client config and used by streaming operations. This enables performance tuning for specific workloads." 46 - }, 47 - { 48 - "source_repo": "third_party/java/http-request", 49 - "source_language": "Java", 50 - "criticality": "low", 51 - "change_type": "feature", 52 - "title": "Add URL encoding utility functions", 53 - "description": "The Java library provides static encode(CharSequence url) and append(url, params) methods for URL encoding and query parameter construction. The OCaml library requires users to manually construct URLs with query parameters.", 54 - "affected_files": [ 55 - "lib/requests.mli", 56 - "lib/requests.ml" 57 - ], 58 - "rationale": "The Java library's HttpRequest.encode() and HttpRequest.append(baseUrl, params) show common patterns: encoding special characters in URLs and building query strings from key-value pairs. While the OCaml library supports ?params in get(), adding Requests.encode_url and Requests.build_url utility functions would help users constructing complex URLs. These could use Uri library internally for proper encoding." 59 - }, 60 - { 61 - "source_repo": "third_party/java/http-request", 62 - "source_language": "Java", 63 - "criticality": "high", 64 - "change_type": "security", 65 - "title": "Add option to disable automatic redirect following for specific status codes", 66 - "description": "The Java library provides followRedirects(boolean) for fine-grained control. While the OCaml library has follow_redirects and max_redirects, it doesn't allow specifying which redirect status codes to follow (301 vs 302 vs 303 vs 307 vs 308).", 67 - "affected_files": [ 68 - "lib/requests.mli", 69 - "lib/requests.ml", 70 - "lib/one.mli", 71 - "lib/one.ml" 72 - ], 73 - "rationale": "Different redirect status codes have different semantics per RFC 9110. 301/302 may change POST to GET; 307/308 preserve the method. Security-conscious applications need control over which redirects to follow automatically. The Java library demonstrates this need by exposing redirect control. Add allowed_redirect_codes parameter to create() accepting int list, defaulting to [301; 302; 303; 307; 308]. This prevents unexpected method changes and improves security for sensitive operations." 74 - }, 75 - { 76 - "source_repo": "third_party/java/http-request", 77 - "source_language": "Java", 78 - "criticality": "low", 79 - "change_type": "enhancement", 80 - "title": "Support reading response headers before consuming body", 81 - "description": "The Java library allows accessing headers (via header(), headers(), contentType()) before reading the response body. The OCaml library's Response type already supports this, but documentation should emphasize that headers are immediately available without reading the body.", 82 - "affected_files": [ 83 - "lib/response.mli" 84 - ], 85 - "rationale": "The Java library pattern shows developers often check Content-Type, Content-Length, or custom headers before deciding whether to read the body. The OCaml Response.headers, Response.content_type, and Response.content_length already support this, but the documentation doesn't emphasize this capability. Add a documentation section 'Lazy Body Consumption' explaining that headers are available immediately and body reading is deferred until Response.text/Response.json/Response.body is called." 86 - }, 87 - { 88 - "source_repo": "third_party/java/http-request", 89 - "source_language": "Java", 90 - "criticality": "medium", 91 - "change_type": "feature", 92 - "title": "Add method to receive response directly to file (download helper)", 93 - "description": "The Java library provides receive(File) and receive(OutputStream) methods that stream response directly to a file without loading into memory. The OCaml library requires manual streaming using Response.body and Eio.Flow.copy.", 94 - "affected_files": [ 95 - "lib/response.mli", 96 - "lib/response.ml", 97 - "lib/one.mli", 98 - "lib/one.ml" 99 - ], 100 - "rationale": "The Java library's receive(File) method is a common pattern for downloading files. While the OCaml library supports this via Eio.Flow.copy(Response.body r, sink), adding Response.save_to_file : t -> _ Eio.Path.t -> unit and One.download : url:string -> sink:_ Eio.Path.t -> unit convenience functions would improve ergonomics. These would handle opening the file, copying the stream, and ensuring proper resource cleanup." 101 - }, 102 - { 103 - "source_repo": "third_party/java/http-request", 104 - "source_language": "Java", 105 - "criticality": "medium", 106 - "change_type": "enhancement", 107 - "title": "Add support for custom connection factories", 108 - "description": "The Java library allows setting a custom ConnectionFactory to control how connections are created. This enables integration with custom socket implementations, connection pooling strategies, or network libraries. The OCaml library's connection pooling is not user-extensible.", 109 - "affected_files": [ 110 - "lib/requests.mli", 111 - "lib/requests.ml" 112 - ], 113 - "rationale": "The Java library's setConnectionFactory(ConnectionFactory) demonstrates the need for customizable connection creation. While the OCaml library uses Conpool for pooling, users cannot customize connection establishment. Adding a connection_factory parameter to create() accepting type (string -> int -> Eio.Net.Sockaddr.stream -> Eio.Flow.two_way_ty Eio.Resource.t) would enable custom connection logic, proxy protocols, or alternative network backends. This maintains the existing Conpool integration while allowing extension points." 114 - }, 115 - { 116 - "source_repo": "third_party/java/http-request", 117 - "source_language": "Java", 118 - "criticality": "low", 119 - "change_type": "feature", 120 - "title": "Add method to check if response body was decompressed", 121 - "description": "The Java library tracks whether uncompress(true) was called and provides visibility into whether gzip decompression occurred. The OCaml library's auto_decompress feature doesn't expose whether decompression happened.", 122 - "affected_files": [ 123 - "lib/response.mli", 124 - "lib/response.ml" 125 - ], 126 - "rationale": "The Java library's uncompress flag shows that applications sometimes need to know if decompression occurred (for logging, debugging, or bandwidth accounting). Adding Response.was_decompressed : t -> bool would expose this information. This requires storing a decompressed flag in the Response.t type during response construction in http_read.ml when Content-Encoding: gzip is detected and auto_decompress is enabled." 127 - }, 128 - { 129 - "source_repo": "third_party/java/http-request", 130 - "source_language": "Java", 131 - "criticality": "high", 132 - "change_type": "security", 133 - "title": "Add total request size limits to prevent resource exhaustion", 134 - "description": "The Java library tracks totalSize and totalWritten to monitor upload sizes. The OCaml library has Response_limits for response bodies but lacks request body size limits.", 135 - "affected_files": [ 136 - "lib/body.mli", 137 - "lib/body.ml", 138 - "lib/requests.mli", 139 - "lib/requests.ml" 140 - ], 141 - "rationale": "The Java library's totalSize tracking demonstrates awareness of upload size limits. While the OCaml library has Response_limits.max_body_size for responses, there's no corresponding limit for request bodies to prevent accidental or malicious large uploads. Add max_request_body_size parameter to create() and validation in Body construction. When exceeded, raise Error.Body_too_large. This prevents resource exhaustion from unbounded file uploads or stream bodies." 142 - }, 143 - { 144 - "source_repo": "third_party/java/http-request", 145 - "source_language": "Java", 146 - "criticality": "low", 147 - "change_type": "enhancement", 148 - "title": "Support for Server header access", 149 - "description": "The Java library provides server() method to access the Server response header. The OCaml library requires using Response.header \"Server\".", 150 - "affected_files": [ 151 - "lib/response.mli", 152 - "lib/response.ml" 153 - ], 154 - "rationale": "The Java library includes a dedicated server() method for the Server header constant (HEADER_SERVER). This is a common header for logging, debugging, and compatibility checks. Adding Response.server : t -> string option would improve discoverability alongside existing helpers like Response.content_type and Response.location. Implementation is trivial: Response.header \"Server\" r." 155 - }, 156 - { 157 - "source_repo": "third_party/java/http-request", 158 - "source_language": "Java", 159 - "criticality": "medium", 160 - "change_type": "feature", 161 - "title": "Add support for Referer header", 162 - "description": "The Java library provides referer(String) method to set the Referer header. The OCaml library requires using Headers.set \"Referer\" value.", 163 - "affected_files": [ 164 - "lib/headers.mli", 165 - "lib/headers.ml" 166 - ], 167 - "rationale": "The Java library includes HEADER_REFERER constant and referer() setter, showing this is a commonly used header. Many APIs require or log the Referer header for security and analytics. Adding Headers.referer : string -> t -> t would improve API consistency alongside existing helpers like Headers.user_agent. This is especially useful for web scraping and API clients that simulate browser behavior." 168 - }, 169 - { 170 - "source_repo": "third_party/java/http-request", 171 - "source_language": "Java", 172 - "criticality": "medium", 173 - "change_type": "enhancement", 174 - "title": "Add response charset detection and handling", 175 - "description": "The Java library supports charset(String) configuration and defaults to UTF-8. The OCaml library doesn't explicitly handle response charset detection from Content-Type header.", 176 - "affected_files": [ 177 - "lib/response.mli", 178 - "lib/response.ml" 179 - ], 180 - "rationale": "The Java library's CHARSET_UTF8 constant and charset handling show that character encoding is important for text responses. The OCaml library's Response.text assumes UTF-8. Adding Response.charset : t -> string option to parse the charset parameter from Content-Type header would enable proper text decoding. For example, 'Content-Type: text/html; charset=iso-8859-1' should return Some \"iso-8859-1\". This could integrate with uutf library for proper decoding." 181 - }, 182 - { 183 - "source_repo": "third_party/java/http-request", 184 - "source_language": "Java", 185 - "criticality": "low", 186 - "change_type": "enhancement", 187 - "title": "Add Accept-Charset header support", 188 - "description": "The Java library provides acceptCharset(String) method and HEADER_ACCEPT_CHARSET constant. The OCaml library lacks a convenience method for this header.", 189 - "affected_files": [ 190 - "lib/headers.mli", 191 - "lib/headers.ml" 192 - ], 193 - "rationale": "The Java library's HEADER_ACCEPT_CHARSET shows this header is used to negotiate character encoding with servers. While less common than Accept, it's still part of HTTP content negotiation. Adding Headers.accept_charset : string -> t -> t would complete the content negotiation API alongside Headers.accept. Implementation is straightforward: set \"Accept-Charset\" value." 194 - }, 195 - { 196 - "source_repo": "third_party/java/http-request", 197 - "source_language": "Java", 198 - "criticality": "low", 199 - "change_type": "feature", 200 - "title": "Add ignoreCloseExceptions option for cleanup robustness", 201 - "description": "The Java library has ignoreCloseExceptions flag (default true) to continue execution even if closing streams fails. The OCaml library using Eio's structured concurrency may propagate close errors unexpectedly.", 202 - "affected_files": [ 203 - "lib/requests.mli", 204 - "lib/requests.ml", 205 - "lib/response.ml" 206 - ], 207 - "rationale": "The Java library's ignoreCloseExceptions (default true) shows that close errors during cleanup often shouldn't fail the overall operation. In Eio, switch cleanup can propagate exceptions. Adding ignore_cleanup_errors parameter to create() (default true) would suppress non-critical errors during resource cleanup. This could be implemented using Eio.Switch.on_release with exception handling that logs errors but doesn't re-raise them when the flag is true." 208 - } 209 - ] 210 - }
-279
third_party/java/okhttp.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "okhttp", 5 - "source_language": "Kotlin/Java", 6 - "criticality": "high", 7 - "change_type": "security", 8 - "title": "Add Certificate Pinning Support", 9 - "description": "OkHttp provides comprehensive certificate pinning functionality that pins Subject Public Key Info (SPKI) hashes using SHA-256 or SHA-1. This defends against certificate authority compromises and MITM attacks. The OCaml library currently lacks certificate pinning capabilities, leaving applications vulnerable to CA-based attacks.", 10 - "affected_files": [ 11 - "lib/requests.mli", 12 - "lib/requests.ml" 13 - ], 14 - "rationale": "Certificate pinning is a critical security feature for high-security applications. OkHttp's implementation supports wildcard patterns (*.example.com, **.example.com), per-hostname configuration, and provides helpful error messages showing actual vs expected certificate hashes. This should be added as an optional configuration in the OCaml library's TLS setup, exposed through the session creation API." 15 - }, 16 - { 17 - "source_repo": "okhttp", 18 - "source_language": "Kotlin/Java", 19 - "criticality": "medium", 20 - "change_type": "enhancement", 21 - "title": "Add EventListener/Observability Hooks", 22 - "description": "OkHttp provides a comprehensive EventListener system that emits events at every stage of the HTTP call lifecycle: DNS resolution start/end, connection establishment, TLS handshake, request/response headers, body transmission, etc. This enables detailed monitoring, metrics collection, and debugging without modifying core library code.", 23 - "affected_files": [ 24 - "lib/requests.mli", 25 - "lib/requests.ml", 26 - "ocaml-conpool/lib/conpool.mli", 27 - "ocaml-conpool/lib/conpool.ml" 28 - ], 29 - "rationale": "The OCaml library has basic logging via the Logs library but lacks structured event hooks for application-level monitoring. Adding an event listener pattern would allow users to track metrics (request duration, DNS time, connection reuse rate), implement distributed tracing, collect analytics, and debug production issues. This is especially valuable for understanding connection pool behavior and retry patterns." 30 - }, 31 - { 32 - "source_repo": "okhttp", 33 - "source_language": "Kotlin/Java", 34 - "criticality": "medium", 35 - "change_type": "enhancement", 36 - "title": "Implement Automatic Retry on 408 Request Timeout", 37 - "description": "OkHttp automatically retries HTTP 408 (Request Timeout) responses, which are rare but used by servers like HAProxy to indicate temporary unavailability. The retry is automatic unless the request body is one-shot or retryOnConnectionFailure is disabled. The OCaml library includes 408 in the default status_forcelist but doesn't handle the special semantics of avoiding retry loops.", 38 - "affected_files": [ 39 - "lib/retry.ml", 40 - "lib/requests.ml" 41 - ], 42 - "rationale": "OkHttp prevents infinite retry loops on 408 by checking if the prior response was also a 408 and giving up in that case (lines 243-246 in RetryAndFollowUpInterceptor.kt). The OCaml library should implement similar protection: check the priorResponse status before retrying 408 to prevent cascading timeouts from causing infinite loops." 43 - }, 44 - { 45 - "source_repo": "okhttp", 46 - "source_language": "Kotlin/Java", 47 - "criticality": "medium", 48 - "change_type": "enhancement", 49 - "title": "Add Support for HTTP 421 Misdirected Request", 50 - "description": "OkHttp handles HTTP 421 (Misdirected Request) which occurs when HTTP/2 connection coalescing is used but the server rejects a request meant for a different hostname. The library automatically retries on a new connection with connection coalescing disabled for that route.", 51 - "affected_files": [ 52 - "lib/requests.ml", 53 - "lib/retry.ml" 54 - ], 55 - "rationale": "While the OCaml library doesn't currently support HTTP/2, this is important groundwork for future HTTP/2 support. When connection coalescing is implemented, 421 responses need special handling: mark the connection as not eligible for coalescing and retry the request on a fresh connection. This is handled in lines 271-286 of RetryAndFollowUpInterceptor.kt." 56 - }, 57 - { 58 - "source_repo": "okhttp", 59 - "source_language": "Kotlin/Java", 60 - "criticality": "medium", 61 - "change_type": "enhancement", 62 - "title": "Improve Redirect Handling - Drop Authorization on Host Change", 63 - "description": "OkHttp automatically removes the Authorization header when a redirect crosses host boundaries (lines 328-333 in RetryAndFollowUpInterceptor.kt). This prevents credential leakage to third-party servers during redirects. The OCaml library needs to verify it implements this security measure.", 64 - "affected_files": [ 65 - "lib/requests.ml" 66 - ], 67 - "rationale": "Credentials should never be sent to a different host than originally intended. This is a security best practice that prevents accidental credential exposure. The implementation should check if the redirect URL's host differs from the original request's host and remove Authorization, Proxy-Authorization, and Cookie headers if so." 68 - }, 69 - { 70 - "source_repo": "okhttp", 71 - "source_language": "Kotlin/Java", 72 - "criticality": "high", 73 - "change_type": "security", 74 - "title": "Add Preemptive Proxy Authentication", 75 - "description": "OkHttp supports preemptive proxy authentication by calling the proxy authenticator before establishing CONNECT tunnels for HTTPS over HTTP proxies. This is done with a synthetic 407 response containing 'Proxy-Authenticate: OkHttp-Preemptive' (lines 22-51 in Authenticator.kt).", 76 - "affected_files": [ 77 - "lib/auth.mli", 78 - "lib/auth.ml", 79 - "lib/requests.ml" 80 - ], 81 - "rationale": "HTTPS tunneling through HTTP proxies requires authentication before the TLS handshake can occur. Without preemptive authentication, the CONNECT request fails. OkHttp's approach of synthesizing a preemptive challenge allows the same authenticator interface to handle both preemptive and reactive authentication. The OCaml library should implement similar support for proxy authentication scenarios." 82 - }, 83 - { 84 - "source_repo": "okhttp", 85 - "source_language": "Kotlin/Java", 86 - "criticality": "low", 87 - "change_type": "enhancement", 88 - "title": "Track Prior Responses for Retry Decision Intelligence", 89 - "description": "OkHttp maintains a chain of prior responses (via priorResponse field) that allows sophisticated retry logic. The authenticator can count authentication attempts to prevent infinite loops (lines 98-111 in Authenticator.kt), and retry logic can detect retry loops for specific status codes.", 90 - "affected_files": [ 91 - "lib/response.mli", 92 - "lib/response.ml", 93 - "lib/retry.ml" 94 - ], 95 - "rationale": "Currently the OCaml library's retry logic doesn't track the full response chain. Adding a priorResponse reference to Response.t would enable smarter retry decisions: preventing authentication retry loops, detecting server-side retry loops, and providing better debugging context. This is especially useful for preventing infinite redirects and authentication challenges." 96 - }, 97 - { 98 - "source_repo": "okhttp", 99 - "source_language": "Kotlin/Java", 100 - "criticality": "medium", 101 - "change_type": "enhancement", 102 - "title": "Add Transparent Gzip Decompression with Proper Header Handling", 103 - "description": "OkHttp's BridgeInterceptor automatically adds 'Accept-Encoding: gzip' unless the user explicitly set Accept-Encoding or Range headers (lines 69-73). It then transparently decompresses gzip responses and removes Content-Encoding/Content-Length headers to present clean, decompressed data to the application.", 104 - "affected_files": [ 105 - "lib/requests.ml", 106 - "lib/response.ml" 107 - ], 108 - "rationale": "The OCaml library has auto_decompress support but should verify it implements the same header management: (1) Don't add Accept-Encoding if user set it or if Range is present (partial content), (2) Remove Content-Encoding and Content-Length from decompressed responses since they no longer apply. This prevents confusion when applications check Content-Length expecting the decompressed size." 109 - }, 110 - { 111 - "source_repo": "okhttp", 112 - "source_language": "Kotlin/Java", 113 - "criticality": "low", 114 - "change_type": "enhancement", 115 - "title": "Add Default User-Agent Header", 116 - "description": "OkHttp automatically adds a User-Agent header identifying the library and version unless one is already set (line 80-82 in BridgeInterceptor.kt). This helps with server-side debugging and allows servers to work around client bugs in specific versions.", 117 - "affected_files": [ 118 - "lib/requests.ml" 119 - ], 120 - "rationale": "User-Agent is considered a good practice for HTTP clients. The OCaml library should add a default User-Agent like 'ocaml-requests/VERSION' unless the user specifies one in default_headers. This aids in debugging, allows servers to track client distribution, and follows HTTP best practices. It's also useful for detecting abuse patterns." 121 - }, 122 - { 123 - "source_repo": "okhttp", 124 - "source_language": "Kotlin/Java", 125 - "criticality": "medium", 126 - "change_type": "enhancement", 127 - "title": "Implement Granular Connection Failure Classification", 128 - "description": "OkHttp classifies connection failures into categories with different retry semantics: ProtocolException (don't retry), CertificateException (don't retry), SSLPeerUnverifiedException (don't retry for cert pinning), SocketTimeoutException during connect (retry with new route), InterruptedIOException after send started (don't retry). See isRecoverable() in RetryAndFollowUpInterceptor.kt lines 167-199.", 129 - "affected_files": [ 130 - "lib/error.ml", 131 - "lib/retry.ml" 132 - ], 133 - "rationale": "The OCaml library has good error granularity (Dns_resolution_failed, Tcp_connect_failed, Tls_handshake_failed) and query functions (is_retryable, is_connection, is_tls) but should refine retry logic based on error type. For example: TLS certificate errors should not be retried (they won't succeed), but DNS failures and TCP connection failures should be retried with exponential backoff. Protocol errors indicate bugs and shouldn't be retried." 134 - }, 135 - { 136 - "source_repo": "okhttp", 137 - "source_language": "Kotlin/Java", 138 - "criticality": "low", 139 - "change_type": "enhancement", 140 - "title": "Suppress Prior Errors in Retry Exception Chains", 141 - "description": "OkHttp collects all prior exceptions during retries and attaches them as suppressed exceptions to the final thrown exception using withSuppressed() (lines 76-84 in RetryAndFollowUpInterceptor.kt). This provides complete failure context for debugging.", 142 - "affected_files": [ 143 - "lib/retry.ml", 144 - "lib/error.ml" 145 - ], 146 - "rationale": "When a request fails after multiple retries, seeing only the final error loses important context. OkHttp's approach of collecting all intermediate failures helps debugging: you can see if DNS failed, then TCP failed, then TLS failed, showing the full failure progression. The OCaml library should maintain a list of prior errors and include them in the final exception or error message." 147 - }, 148 - { 149 - "source_repo": "okhttp", 150 - "source_language": "Kotlin/Java", 151 - "criticality": "medium", 152 - "change_type": "feature", 153 - "title": "Add Request Tagging/Metadata Support", 154 - "description": "OkHttp allows attaching arbitrary metadata to requests via a type-safe tag system (lines 127-150 in RealCall.kt). Tags can be accessed during request processing, in interceptors, and in event listeners. This enables per-request configuration, tracing context propagation, and custom retry policies.", 155 - "affected_files": [ 156 - "lib/requests.mli", 157 - "lib/requests.ml" 158 - ], 159 - "rationale": "Request tags enable powerful patterns: attaching distributed tracing IDs, per-request retry configuration, request-specific metrics collection, or custom authentication context. The OCaml library could implement this as a (string * string) list or heterogeneous map. This is particularly useful for middleware patterns and observability integration." 160 - }, 161 - { 162 - "source_repo": "okhttp", 163 - "source_language": "Kotlin/Java", 164 - "criticality": "high", 165 - "change_type": "bug", 166 - "title": "Handle ConnectionShutdownException Specially", 167 - "description": "OkHttp treats ConnectionShutdownException (HTTP/2 GOAWAY frame) specially - it indicates the request was never sent, so it's always safe to retry even for non-idempotent methods (line 140 in RetryAndFollowUpInterceptor.kt). This exception means the server proactively closed a connection that was about to be reused.", 168 - "affected_files": [ 169 - "lib/error.ml", 170 - "lib/retry.ml", 171 - "ocaml-conpool/lib/conpool.ml" 172 - ], 173 - "rationale": "When a pooled connection is reused but the server has sent GOAWAY (HTTP/2) or closed the socket (HTTP/1.1), the request definitely wasn't transmitted. The OCaml library should detect stale connection errors (connection closed by peer before write) and treat them as always retryable, even for POST requests. This requires distinguishing 'connection closed before request sent' from 'connection closed mid-request'." 174 - }, 175 - { 176 - "source_repo": "okhttp", 177 - "source_language": "Kotlin/Java", 178 - "criticality": "medium", 179 - "change_type": "enhancement", 180 - "title": "Add Async Call Support with Dispatcher", 181 - "description": "OkHttp provides both synchronous (execute()) and asynchronous (enqueue()) call modes. The async mode uses a Dispatcher with configurable thread pools and concurrency limits (maxRequests, maxRequestsPerHost) as seen in RealCall.kt lines 193-197.", 182 - "affected_files": [ 183 - "lib/requests.mli", 184 - "lib/requests.ml" 185 - ], 186 - "rationale": "While Eio provides structured concurrency via fibers, the OCaml library could benefit from a higher-level async API that manages concurrency automatically. This could be implemented as a request queue with configurable parallelism, preventing resource exhaustion when making many concurrent requests. The Dispatcher pattern ensures fair resource allocation across different hosts." 187 - }, 188 - { 189 - "source_repo": "okhttp", 190 - "source_language": "Kotlin/Java", 191 - "criticality": "medium", 192 - "change_type": "enhancement", 193 - "title": "Add Call Cancellation Support", 194 - "description": "OkHttp provides comprehensive cancellation via cancel() method (lines 166-176 in RealCall.kt) that immediately terminates in-flight requests by closing sockets, canceling exchanges, and notifying event listeners. Cancellation is thread-safe and idempotent.", 195 - "affected_files": [ 196 - "lib/requests.mli", 197 - "lib/requests.ml" 198 - ], 199 - "rationale": "The OCaml library uses Eio's structured concurrency (switches) for cancellation, but doesn't expose explicit cancel() on requests. Adding a cancel function that closes the underlying connection would enable use cases like timeout implementation, user-triggered cancellation, or canceling slow requests when a faster mirror responds. This requires storing the active connection/exchange in the request context." 200 - }, 201 - { 202 - "source_repo": "okhttp", 203 - "source_language": "Kotlin/Java", 204 - "criticality": "low", 205 - "change_type": "enhancement", 206 - "title": "Implement Redirect Method Transformation Rules", 207 - "description": "OkHttp implements precise HTTP redirect semantics: 301/302/303 change POST to GET, 307/308 preserve method and body (lines 292-326 in RetryAndFollowUpInterceptor.kt). It also removes Content-Type, Content-Length, and Transfer-Encoding headers when stripping the body on method change.", 208 - "affected_files": [ 209 - "lib/requests.ml" 210 - ], 211 - "rationale": "HTTP redirect semantics are complex and often misimplemented. The OCaml library should verify its redirect handling matches RFC 9110: (1) 301/302/303 with POST/PUT → GET without body, (2) 307/308 preserve method and body, (3) Remove body-related headers when changing to GET, (4) Never follow redirects for one-shot request bodies. This ensures correct behavior with real-world servers." 212 - }, 213 - { 214 - "source_repo": "okhttp", 215 - "source_language": "Kotlin/Java", 216 - "criticality": "medium", 217 - "change_type": "enhancement", 218 - "title": "Add HTTP/2 Support with Stream Multiplexing", 219 - "description": "OkHttp has comprehensive HTTP/2 support with multiplexed streams, HPACK header compression, flow control, server push, and connection coalescing. This significantly improves performance for multiple requests to the same origin.", 220 - "affected_files": [ 221 - "lib/http_client.ml", 222 - "lib/requests.ml", 223 - "ocaml-conpool/lib/conpool.ml" 224 - ], 225 - "rationale": "HTTP/2 provides substantial performance benefits: multiplexing eliminates head-of-line blocking, header compression reduces overhead, and connection reuse is more efficient. The OCaml library currently only supports HTTP/1.1. Adding HTTP/2 support via libraries like h2 or ocaml-h2 would modernize the client and improve performance for API-heavy workloads. This is a significant undertaking but high value." 226 - }, 227 - { 228 - "source_repo": "okhttp", 229 - "source_language": "Kotlin/Java", 230 - "criticality": "low", 231 - "change_type": "enhancement", 232 - "title": "Add Connection: Keep-Alive Header by Default", 233 - "description": "OkHttp adds 'Connection: Keep-Alive' header by default unless already set (lines 63-65 in BridgeInterceptor.kt). This signals to HTTP/1.0 servers that connection reuse is desired.", 234 - "affected_files": [ 235 - "lib/requests.ml" 236 - ], 237 - "rationale": "While HTTP/1.1 defaults to persistent connections, explicitly setting Connection: Keep-Alive improves compatibility with HTTP/1.0 servers and older proxies. The OCaml library should add this header by default (only if not already set by user) to maximize connection reuse and performance." 238 - }, 239 - { 240 - "source_repo": "okhttp", 241 - "source_language": "Kotlin/Java", 242 - "criticality": "low", 243 - "change_type": "enhancement", 244 - "title": "Implement Retry-After Header Immediate Retry", 245 - "description": "OkHttp has special handling for 503 Service Unavailable responses with 'Retry-After: 0' - it immediately retries without delay (lines 256-269 in RetryAndFollowUpInterceptor.kt). This is different from other Retry-After values which prevent retry.", 246 - "affected_files": [ 247 - "lib/retry.ml", 248 - "lib/requests.ml" 249 - ], 250 - "rationale": "When a server sends '503 Service Unavailable' with 'Retry-After: 0', it's explicitly telling the client to retry immediately - likely because it just finished warming up or a load balancer just detected the server is healthy. The OCaml library correctly parses Retry-After but should implement this special case: delay=0 means immediate retry, delay>0 means wait and retry, no header means don't retry 503." 251 - }, 252 - { 253 - "source_repo": "okhttp", 254 - "source_language": "Kotlin/Java", 255 - "criticality": "medium", 256 - "change_type": "refactor", 257 - "title": "Implement Interceptor Chain Pattern", 258 - "description": "OkHttp uses an interceptor chain pattern where each interceptor can modify the request, call the next interceptor, then modify the response. The chain order is: Application Interceptors → RetryAndFollowUp → Bridge → Cache → Network Interceptors → Connect → CallServer. This provides clean separation of concerns.", 259 - "affected_files": [ 260 - "lib/requests.ml", 261 - "lib/requests.mli" 262 - ], 263 - "rationale": "The OCaml library handles retry, authentication, redirects, and other concerns directly in the main request flow, making it harder to extend and test. Adopting an interceptor chain pattern would allow users to inject custom behavior at various stages (logging, metrics, request signing, custom caching). Each concern becomes a separate, testable interceptor. This is a significant refactoring but greatly improves extensibility." 264 - }, 265 - { 266 - "source_repo": "okhttp", 267 - "source_language": "Kotlin/Java", 268 - "criticality": "low", 269 - "change_type": "enhancement", 270 - "title": "Add Built-in MockWebServer for Testing", 271 - "description": "OkHttp provides MockWebServer, a scriptable web server for testing HTTP clients. It allows configuring mock responses, delays, errors, and inspecting received requests. This is essential for reliable testing without external dependencies.", 272 - "affected_files": [ 273 - "test/", 274 - "ocaml-requests.opam" 275 - ], 276 - "rationale": "The OCaml library's tests currently use httpbin.org (external dependency) and local servers. A MockWebServer equivalent would enable faster, more reliable tests that can simulate edge cases (slow responses, connection drops, malformed responses). This could be a separate ocaml-requests-testing package. Consider using existing OCaml HTTP servers (Cohttp, Dream) in test mode or building a minimal test server." 277 - } 278 - ] 279 - }
-225
third_party/javascript/axios.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/javascript/axios", 5 - "source_language": "JavaScript", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add request/response interceptor mechanism", 9 - "description": "Axios provides a powerful interceptor system (InterceptorManager) that allows users to transform requests before they are sent and responses before they are handled. This enables cross-cutting concerns like logging, auth token refresh, error transformation, and retry logic at the application level. The OCaml library currently lacks this capability.", 10 - "affected_files": [ 11 - "lib/requests.mli", 12 - "lib/requests.ml", 13 - "lib/http_client.ml" 14 - ], 15 - "rationale": "Interceptors provide a clean separation of concerns and enable users to add custom behavior (auth token refresh, request signing, response transformation, metrics collection) without modifying core library code. This is particularly valuable for enterprise applications with complex authentication flows. Implementation would use a chain-of-responsibility pattern compatible with Eio's structured concurrency." 16 - }, 17 - { 18 - "source_repo": "third_party/javascript/axios", 19 - "source_language": "JavaScript", 20 - "criticality": "high", 21 - "change_type": "security", 22 - "title": "Add XSRF/CSRF token protection", 23 - "description": "Axios provides built-in XSRF (Cross-Site Request Forgery) protection by automatically reading a token from a cookie (default: XSRF-TOKEN) and adding it to request headers (default: X-XSRF-TOKEN) for same-origin requests. This can be configured with xsrfCookieName, xsrfHeaderName, and withXSRFToken options. The OCaml library currently has no CSRF protection mechanism.", 24 - "affected_files": [ 25 - "lib/requests.mli", 26 - "lib/requests.ml", 27 - "lib/headers.ml" 28 - ], 29 - "rationale": "CSRF is a common web vulnerability (OWASP Top 10). Many web frameworks (Laravel, Django, Rails) use double-submit cookie patterns that require the client to read a cookie and include it in headers. Without built-in support, users must manually implement this for every request, which is error-prone. Adding automatic XSRF token handling would significantly improve security for web applications using the library." 30 - }, 31 - { 32 - "source_repo": "third_party/javascript/axios", 33 - "source_language": "JavaScript", 34 - "criticality": "medium", 35 - "change_type": "feature", 36 - "title": "Add request/response transformation hooks", 37 - "description": "Axios supports configurable transformRequest and transformResponse functions that allow users to transform data before sending and after receiving. The default transformRequest automatically serializes objects to JSON, FormData, or URLEncoded based on Content-Type. The default transformResponse automatically parses JSON responses. Users can override or chain these transformations.", 38 - "affected_files": [ 39 - "lib/body.mli", 40 - "lib/body.ml", 41 - "lib/response.mli", 42 - "lib/response.ml" 43 - ], 44 - "rationale": "Transformation hooks enable users to customize serialization/deserialization without subclassing or wrapping the client. Common use cases include: custom JSON encoding (dates as strings vs timestamps), automatic encryption/decryption, compression, data normalization, and protocol buffer serialization. This is more flexible than the current approach where users must manually convert data before/after requests." 45 - }, 46 - { 47 - "source_repo": "third_party/javascript/axios", 48 - "source_language": "JavaScript", 49 - "criticality": "low", 50 - "change_type": "feature", 51 - "title": "Add validateStatus configuration option", 52 - "description": "Axios allows users to configure which HTTP status codes should be treated as successful via the validateStatus function. The default treats 2xx as success. Users can customize this (e.g., to treat 404 as success when checking resource existence, or to handle 3xx redirects manually). The OCaml library currently doesn't raise exceptions for non-2xx by default, which differs from axios's approach of rejecting non-2xx promises.", 53 - "affected_files": [ 54 - "lib/requests.mli", 55 - "lib/requests.ml", 56 - "lib/response.ml" 57 - ], 58 - "rationale": "Different applications have different requirements for what constitutes an error. Some APIs use 404 to indicate 'not found' as a valid state rather than an error. Others may want to handle specific status codes (429 rate limit) differently. Providing a configurable validateStatus function gives users fine-grained control over error handling behavior while maintaining sensible defaults." 59 - }, 60 - { 61 - "source_repo": "third_party/javascript/axios", 62 - "source_language": "JavaScript", 63 - "criticality": "high", 64 - "change_type": "security", 65 - "title": "Add maxContentLength and maxBodyLength limits", 66 - "description": "Axios provides maxContentLength (response size limit) and maxBodyLength (request size limit) configuration options to prevent DoS attacks from extremely large payloads. The default is -1 (unlimited), but users can set limits in bytes. When exceeded, axios rejects with ERR_BAD_RESPONSE or ERR_BAD_REQUEST errors. The OCaml library has Response_limits but it's not clearly integrated into the main API.", 67 - "affected_files": [ 68 - "lib/requests.mli", 69 - "lib/requests.ml", 70 - "lib/response_limits.mli" 71 - ], 72 - "rationale": "Without size limits, malicious servers can send multi-gigabyte responses that exhaust client memory (decompression bomb attack). Similarly, bugs in client code could accidentally create huge request bodies. Axios's approach of making this configurable at the client level with clear error messages is superior to the current OCaml Response_limits module which requires manual integration." 73 - }, 74 - { 75 - "source_repo": "third_party/javascript/axios", 76 - "source_language": "JavaScript", 77 - "criticality": "medium", 78 - "change_type": "enhancement", 79 - "title": "Improve error serialization with toJSON method", 80 - "description": "Axios's AxiosError class provides a toJSON() method that serializes errors to a plain object including message, name, code, status, config, stack, and platform-specific fields. This makes errors easy to log, transmit over the network, or persist. The OCaml Error module provides to_string but not a structured representation.", 81 - "affected_files": [ 82 - "lib/error.mli", 83 - "lib/error.ml" 84 - ], 85 - "rationale": "Structured error representation is valuable for logging, monitoring, and debugging. Applications often need to send errors to logging services (Sentry, DataDog) which expect structured data. The toJSON approach also makes it easy to include sanitized request config for debugging while excluding sensitive headers. Adding a to_json function that returns Jsont.json would improve observability." 86 - }, 87 - { 88 - "source_repo": "third_party/javascript/axios", 89 - "source_language": "JavaScript", 90 - "criticality": "low", 91 - "change_type": "feature", 92 - "title": "Add baseURL configuration option", 93 - "description": "Axios supports a baseURL configuration option that is prepended to relative URLs. This is particularly useful when creating client instances for specific APIs (e.g., baseURL='https://api.github.com' allows requests like get('/user') instead of get('https://api.github.com/user')). The OCaml library requires full URLs for every request.", 94 - "affected_files": [ 95 - "lib/requests.mli", 96 - "lib/requests.ml", 97 - "lib/one.mli" 98 - ], 99 - "rationale": "BaseURL reduces duplication and makes code more maintainable. When an API changes domains or moves to a different base path, users only need to update one configuration value instead of every request call. This is especially valuable for creating reusable API client libraries. Implementation would join baseURL with relative paths, with validation to prevent path traversal." 100 - }, 101 - { 102 - "source_repo": "third_party/javascript/axios", 103 - "source_language": "JavaScript", 104 - "criticality": "medium", 105 - "change_type": "feature", 106 - "title": "Add HTTP proxy support", 107 - "description": "Axios has built-in HTTP/HTTPS proxy support via the proxy configuration option (protocol, host, port, auth) and automatic detection from HTTP_PROXY/HTTPS_PROXY environment variables via the proxy-from-env library. The OCaml library currently has no proxy support.", 108 - "affected_files": [ 109 - "lib/requests.mli", 110 - "lib/requests.ml", 111 - "lib/http_client.ml" 112 - ], 113 - "rationale": "Proxy support is essential for enterprise environments where direct internet access is restricted. Many corporate networks require all HTTP traffic to go through authenticated proxies. Environment variable support (HTTP_PROXY, HTTPS_PROXY, NO_PROXY) is standard across HTTP clients. Implementation would use HTTP CONNECT for HTTPS proxies and add Proxy-Authorization headers for authenticated proxies." 114 - }, 115 - { 116 - "source_repo": "third_party/javascript/axios", 117 - "source_language": "JavaScript", 118 - "criticality": "low", 119 - "change_type": "enhancement", 120 - "title": "Add progress event callbacks", 121 - "description": "Axios provides onUploadProgress and onDownloadProgress callbacks that receive progress events (loaded bytes, total bytes, progress percentage, transfer rate, time remaining). These callbacks are throttled to 3 events per second to avoid performance issues. The OCaml library has no progress reporting mechanism.", 122 - "affected_files": [ 123 - "lib/requests.mli", 124 - "lib/one.mli", 125 - "lib/body.ml", 126 - "lib/response.ml" 127 - ], 128 - "rationale": "Progress reporting is valuable for user experience when uploading or downloading large files. Users can display progress bars, estimate completion times, or implement bandwidth-aware throttling. The Eio architecture makes this straightforward to implement using Fiber.fork to report progress while the main fiber handles the transfer. Throttling prevents UI flooding." 129 - }, 130 - { 131 - "source_repo": "third_party/javascript/axios", 132 - "source_language": "JavaScript", 133 - "criticality": "medium", 134 - "change_type": "feature", 135 - "title": "Add beforeRedirect hook", 136 - "description": "Axios provides a beforeRedirect hook that is called before following each redirect, allowing users to inspect/modify request options, examine response headers, or cancel the redirect by throwing an error. This enables advanced use cases like handling auth challenges during redirects or limiting redirects to same-origin.", 137 - "affected_files": [ 138 - "lib/requests.mli", 139 - "lib/requests.ml", 140 - "lib/http_client.ml" 141 - ], 142 - "rationale": "Redirect handling is security-sensitive. Applications may need to strip authentication headers when redirecting to different domains, modify request options based on redirect location, or reject suspicious redirect chains. A beforeRedirect hook provides the flexibility to handle these cases without requiring users to disable redirects and implement their own logic." 143 - }, 144 - { 145 - "source_repo": "third_party/javascript/axios", 146 - "source_language": "JavaScript", 147 - "criticality": "low", 148 - "change_type": "enhancement", 149 - "title": "Add transitional error handling options", 150 - "description": "Axios provides transitional options (silentJSONParsing, forcedJSONParsing, clarifyTimeoutError) to control error handling behavior during breaking changes. For example, silentJSONParsing=true sets response.data to null on JSON parse failure rather than throwing, while clarifyTimeoutError=true distinguishes ETIMEDOUT from ECONNABORTED errors.", 151 - "affected_files": [ 152 - "lib/error.mli", 153 - "lib/response.ml" 154 - ], 155 - "rationale": "Providing transitional options allows the library to evolve behavior while maintaining backward compatibility. Applications can opt into stricter error handling gradually. The OCaml library could use this pattern when introducing breaking changes, though the current exception-based approach is already quite strict. This is lower priority but shows good API evolution practices." 156 - }, 157 - { 158 - "source_repo": "third_party/javascript/axios", 159 - "source_language": "JavaScript", 160 - "criticality": "low", 161 - "change_type": "enhancement", 162 - "title": "Add config order of precedence documentation and merging", 163 - "description": "Axios has a clear config merging strategy: library defaults < instance defaults < request config. The mergeConfig module handles this with different merge strategies per option (defaultToConfig2, mergeDirectKeys, etc.). The OCaml library's config merging behavior is less clearly documented.", 164 - "affected_files": [ 165 - "lib/requests.mli", 166 - "lib/requests.ml" 167 - ], 168 - "rationale": "Clear config precedence rules make the library more predictable and easier to use. Users should understand which config values override others when creating instances and making requests. Documenting the merge strategy and ensuring consistent behavior across all configuration options improves developer experience. The OCaml library should document how request-level options (timeout, auth) interact with instance defaults." 169 - }, 170 - { 171 - "source_repo": "third_party/javascript/axios", 172 - "source_language": "JavaScript", 173 - "criticality": "high", 174 - "change_type": "security", 175 - "title": "Add request/response body decompression bomb protection", 176 - "description": "Axios automatically decompresses gzip/deflate responses (decompress: true by default). However, it doesn't have specific decompression bomb protection. The OCaml library has auto_decompress but should add compression ratio limits to detect decompression bombs (e.g., 10MB compressed expanding to 1GB).", 177 - "affected_files": [ 178 - "lib/requests.mli", 179 - "lib/response_limits.mli", 180 - "lib/http_read.ml" 181 - ], 182 - "rationale": "Decompression bombs are a DoS attack where small compressed payloads expand to huge sizes, exhausting memory. The OCaml Error module already defines Decompression_bomb error but it should be actively enforced during response reading. Implementation should track compressed vs decompressed bytes and enforce a configurable ratio limit (e.g., 100:1)." 183 - }, 184 - { 185 - "source_repo": "third_party/javascript/axios", 186 - "source_language": "JavaScript", 187 - "criticality": "medium", 188 - "change_type": "feature", 189 - "title": "Add rate limiting for uploads and downloads", 190 - "description": "Axios's http adapter supports maxRate configuration to limit upload/download speeds in bytes per second (e.g., maxRate: [100*1024, 100*1024] for 100KB/s). This is useful for bandwidth-constrained environments or implementing fair-use policies. The OCaml library has no rate limiting.", 191 - "affected_files": [ 192 - "lib/requests.mli", 193 - "lib/http_client.ml", 194 - "lib/body.ml" 195 - ], 196 - "rationale": "Rate limiting is valuable for mobile applications (conserve cellular data), multi-tenant systems (prevent one user from saturating bandwidth), and testing (simulate slow connections). Implementation would use a token bucket algorithm with Eio's time primitives to throttle reads/writes. This is lower priority but useful for specific use cases." 197 - }, 198 - { 199 - "source_repo": "third_party/javascript/axios", 200 - "source_language": "JavaScript", 201 - "criticality": "low", 202 - "change_type": "enhancement", 203 - "title": "Add explicit error codes like ERR_NETWORK, ERR_CANCELED", 204 - "description": "Axios defines explicit error codes (ERR_NETWORK, ERR_CANCELED, ERR_BAD_REQUEST, ERR_BAD_RESPONSE, ERR_DEPRECATED, etc.) as static properties on AxiosError. This makes error handling more robust than string matching. The OCaml library uses typed error variants which is actually superior, but could add code strings for logging/monitoring.", 205 - "affected_files": [ 206 - "lib/error.mli", 207 - "lib/error.ml" 208 - ], 209 - "rationale": "Error codes make errors easier to categorize in monitoring systems and logs. While OCaml's typed variants are better for pattern matching, adding a to_code function that returns string codes ('TIMEOUT', 'DNS_FAILURE', etc.) would help with logging, metrics, and interop with monitoring systems that expect error codes. This is low priority since the typed approach is already good." 210 - }, 211 - { 212 - "source_repo": "third_party/javascript/axios", 213 - "source_language": "JavaScript", 214 - "criticality": "medium", 215 - "change_type": "enhancement", 216 - "title": "Add request cancellation with AbortController pattern", 217 - "description": "Axios supports request cancellation via AbortController signal (modern approach) and deprecated CancelToken. Users can pass a signal to abort requests, which is useful for debouncing, timeouts, and component unmounting. The OCaml library uses Eio's Switch for cancellation but could expose a more explicit cancellation API.", 218 - "affected_files": [ 219 - "lib/requests.mli", 220 - "lib/one.mli" 221 - ], 222 - "rationale": "While Eio's Switch provides cancellation, users may want to cancel individual requests without canceling the entire switch. Axios's approach allows fine-grained cancellation of specific requests. The OCaml library could provide a cancel_token type that integrates with Eio's cancellation system, allowing users to cancel in-flight requests (useful for autocomplete, race conditions, manual user cancellation)." 223 - } 224 - ] 225 - }
-282
third_party/javascript/got.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/javascript/got", 5 - "source_language": "JavaScript/TypeScript", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add granular timeout configuration for different request phases", 9 - "description": "Got provides fine-grained timeout control for specific phases (lookup, connect, secureConnect, send, response, read, socket, request). The OCaml library only has connect, read, total, and expect_100_continue timeouts. Adding phase-specific timeouts would enable better control over request lifecycle and more precise timeout error handling.", 10 - "affected_files": [ 11 - "lib/timeout.ml", 12 - "lib/timeout.mli", 13 - "lib/http_client.ml", 14 - "lib/one.ml", 15 - "lib/error.ml" 16 - ], 17 - "rationale": "Got's granular timeout model (lookup, connect, secureConnect, send, response, read) allows users to identify exactly which phase of the request timed out, making debugging much easier. The OCaml library currently has generic timeout errors. Adding fields like 'send' (time to upload request body) and 'response' (time to receive first response byte) would improve diagnostics and allow users to tune timeouts for specific bottlenecks in their application." 18 - }, 19 - { 20 - "source_repo": "third_party/javascript/got", 21 - "source_language": "JavaScript/TypeScript", 22 - "criticality": "high", 23 - "change_type": "feature", 24 - "title": "Implement request/response lifecycle hooks system", 25 - "description": "Got provides a comprehensive hooks system (init, beforeRequest, beforeRedirect, beforeRetry, beforeError, afterResponse) that allows users to intercept and modify requests at various lifecycle stages. This enables powerful patterns like automatic token refresh on 401, custom caching, request signing, and error transformation. The OCaml library lacks any hook mechanism.", 26 - "affected_files": [ 27 - "lib/requests.ml", 28 - "lib/requests.mli", 29 - "lib/one.ml", 30 - "lib/one.mli" 31 - ], 32 - "rationale": "Hooks are one of Got's most powerful features. The afterResponse hook is particularly valuable for automatic token refresh (detect 401, refresh token, retry with new credentials). The beforeRequest hook enables request signing for AWS or OAuth. The beforeError hook allows custom error handling and transformation. In OCaml, this could be implemented as optional callback functions in the session configuration: type hooks = { before_request: (Headers.t -> Headers.t) option; after_response: (Response.t -> (Response.t, retry_options) result) option; before_retry: (int -> Error.error -> unit) option }. This would unlock advanced use cases without requiring users to fork the library." 33 - }, 34 - { 35 - "source_repo": "third_party/javascript/got", 36 - "source_language": "JavaScript/TypeScript", 37 - "criticality": "medium", 38 - "change_type": "feature", 39 - "title": "Add request cancellation/abort capability", 40 - "description": "Got supports request cancellation via promise.cancel() and AbortController/AbortSignal integration. The OCaml library using Eio has built-in cancellation via switch cancellation, but there's no way to programmatically cancel an in-flight request from user code without canceling the entire switch.", 41 - "affected_files": [ 42 - "lib/requests.ml", 43 - "lib/requests.mli", 44 - "lib/one.ml", 45 - "lib/one.mli", 46 - "lib/error.ml" 47 - ], 48 - "rationale": "Users may need to cancel requests based on application logic (user navigated away, timeout exceeded, found cached result). Got's PCancelable promise allows calling promise.cancel() to abort the request. In OCaml with Eio, the library could return a (Response.t * (unit -> unit)) tuple where the second element is a cancellation function that triggers switch cancellation for that specific request fiber. Alternatively, accept an optional Eio.Cancel.t token that the library monitors. This would enable use cases like racing multiple requests and canceling losers, or implementing custom timeout logic." 49 - }, 50 - { 51 - "source_repo": "third_party/javascript/got", 52 - "source_language": "JavaScript/TypeScript", 53 - "criticality": "low", 54 - "change_type": "enhancement", 55 - "title": "Add uploadProgress and downloadProgress events/callbacks", 56 - "description": "Got provides progress tracking for both uploads and downloads through events that report {transferred, total, percent}. The OCaml library has progress callbacks in One.upload/download but not in the main session API, and the progress information is less detailed.", 57 - "affected_files": [ 58 - "lib/requests.ml", 59 - "lib/requests.mli", 60 - "lib/one.ml", 61 - "lib/one.mli" 62 - ], 63 - "rationale": "Progress callbacks are essential for user-facing applications that need to show upload/download progress bars. Got provides this through events on both the promise and stream APIs. The OCaml One.upload/download functions have progress callbacks but they only provide bytes transferred, not total or percent. The main Requests API has no progress support at all. Adding optional progress callbacks that provide (transferred: int64, total: int64 option, percent: float option) would enable better UX in client applications. This should be available for both request body uploads and response downloads." 64 - }, 65 - { 66 - "source_repo": "third_party/javascript/got", 67 - "source_language": "JavaScript/TypeScript", 68 - "criticality": "medium", 69 - "change_type": "enhancement", 70 - "title": "Enhance retry logic with error code matching", 71 - "description": "Got's retry mechanism includes an 'errorCodes' list (ETIMEDOUT, ECONNRESET, EADDRINUSE, ECONNREFUSED, EPIPE, ENOTFOUND, ENETUNREACH, EAI_AGAIN) to automatically retry on network errors. The OCaml library's retry logic only checks HTTP status codes and has basic error type checking through Error.is_retryable but doesn't provide user-configurable error matching.", 72 - "affected_files": [ 73 - "lib/retry.ml", 74 - "lib/retry.mli", 75 - "lib/error.ml" 76 - ], 77 - "rationale": "Network errors like DNS resolution failures, connection resets, and temporary network issues are transient and should be retried. Got's errorCodes list provides a battle-tested set of retryable error conditions. The OCaml library's Error.is_retryable function hardcodes which errors are retryable. Adding a configurable error predicate to Retry.config (error_predicate: Error.error -> bool) would allow users to customize retry behavior. The default could match Got's behavior: retry on DNS failures, TCP connection failures, TLS handshake failures, and specific HTTP status codes." 78 - }, 79 - { 80 - "source_repo": "third_party/javascript/got", 81 - "source_language": "JavaScript/TypeScript", 82 - "criticality": "low", 83 - "change_type": "enhancement", 84 - "title": "Add detailed timing information to responses", 85 - "description": "Got includes comprehensive timing data in responses (timings.phases: {wait, dns, tcp, tls, request, firstByte, download, total}) which helps with performance debugging. The OCaml library only tracks total elapsed time in Response.elapsed.", 86 - "affected_files": [ 87 - "lib/response.ml", 88 - "lib/response.mli", 89 - "lib/http_client.ml" 90 - ], 91 - "rationale": "Detailed timing breakdowns are invaluable for performance debugging. Got tracks: socket assignment time, DNS lookup time, TCP connection time, TLS handshake time, request send time, time to first byte, download time, and total time. This helps identify whether slowness is due to DNS, network latency, TLS negotiation, server processing, or data transfer. The OCaml library could add a timing record type: type timings = { dns: float option; connect: float; tls: float option; send: float; first_byte: float; download: float; total: float }. This would require instrumenting http_client.ml to capture timestamps at each phase." 92 - }, 93 - { 94 - "source_repo": "third_party/javascript/got", 95 - "source_language": "JavaScript/TypeScript", 96 - "criticality": "low", 97 - "change_type": "feature", 98 - "title": "Implement built-in pagination support", 99 - "description": "Got provides a pagination API (got.paginate, got.paginate.all) with customizable pagination logic through transform, shouldContinue, filter, and paginate functions. The OCaml library has no built-in pagination support.", 100 - "affected_files": [ 101 - "lib/requests.ml", 102 - "lib/requests.mli" 103 - ], 104 - "rationale": "Many APIs use pagination (GitHub, Twitter, REST APIs with page/offset). Got's pagination support handles common patterns: extracting items from responses, following 'next' links, and assembling complete result sets. While this can be implemented in user code, providing a pagination helper reduces boilerplate. In OCaml, this could be implemented as an async sequence: val paginate : t -> url:string -> ?initial_params:(string * string) list -> extract_items:(Response.t -> 'a list) -> next_url:(Response.t -> string option) -> 'a Seq.t. This returns a lazy sequence that fetches pages on-demand." 105 - }, 106 - { 107 - "source_repo": "third_party/javascript/got", 108 - "source_language": "JavaScript/TypeScript", 109 - "criticality": "medium", 110 - "change_type": "enhancement", 111 - "title": "Add resolveBodyOnly option for cleaner response access", 112 - "description": "Got provides a resolveBodyOnly option that makes requests return just the parsed body instead of the full response object, reducing boilerplate for common cases. The OCaml library always returns the full Response.t and users must call Response.text, Response.json, etc.", 113 - "affected_files": [ 114 - "lib/requests.ml", 115 - "lib/requests.mli", 116 - "lib/one.ml", 117 - "lib/one.mli" 118 - ], 119 - "rationale": "In many cases, users only care about the response body and don't need headers, status, etc. Got's resolveBodyOnly option combined with responseType allows writing: const data = await got(url, {responseType: 'json', resolveBodyOnly: true}) instead of const response = await got(url); const data = await response.json(). In OCaml, this could be method variants: val get_json : t -> string -> Jsont.json (returns parsed JSON directly), val get_text : t -> string -> string (returns body string directly). This provides convenience while keeping the full Response.t API available when needed." 120 - }, 121 - { 122 - "source_repo": "third_party/javascript/got", 123 - "source_language": "JavaScript/TypeScript", 124 - "criticality": "low", 125 - "change_type": "enhancement", 126 - "title": "Add context object for request-scoped user data", 127 - "description": "Got provides a context object that allows users to attach arbitrary data to requests, which is accessible in hooks and persists across retries/redirects. The OCaml library has no equivalent mechanism for request-scoped metadata.", 128 - "affected_files": [ 129 - "lib/requests.ml", 130 - "lib/requests.mli", 131 - "lib/one.ml" 132 - ], 133 - "rationale": "The context object is useful for passing request-specific metadata through the request lifecycle without polluting headers or global state. Use cases include: tracking request IDs for logging, storing authentication state for hooks, passing application-specific data to custom retry logic. In OCaml, this could be implemented as a string map parameter: type context = (string * Jsont.json) list, available in requests and hooks. Alternatively, use a heterogeneous map (type-indexed map) to allow typed storage. This would be particularly useful when hooks are implemented, as hooks could read/write context data." 134 - }, 135 - { 136 - "source_repo": "third_party/javascript/got", 137 - "source_language": "JavaScript/TypeScript", 138 - "criticality": "high", 139 - "change_type": "security", 140 - "title": "Add automatic header filtering on redirects for security", 141 - "description": "Got automatically removes sensitive headers (Authorization, Cookie, etc.) when redirecting to a different host to prevent credential leakage. The OCaml library's redirect handling should implement this security feature.", 142 - "affected_files": [ 143 - "lib/requests.ml", 144 - "lib/one.ml" 145 - ], 146 - "rationale": "This is a critical security feature. When a request is redirected from https://api.example.com to https://evil.com, the Authorization header should NOT be sent to the new host. Got filters out authorization and cookie headers when the redirect changes the hostname (unless explicitly configured otherwise). The OCaml library should implement similar logic: when following a redirect, compare the original hostname with the redirect hostname, and if they differ, remove headers from the sensitive_header_names list (Authorization, Cookie, Proxy-Authorization, etc.). This prevents accidental credential disclosure during cross-origin redirects." 147 - }, 148 - { 149 - "source_repo": "third_party/javascript/got", 150 - "source_language": "JavaScript/TypeScript", 151 - "criticality": "medium", 152 - "change_type": "enhancement", 153 - "title": "Add DNS caching for connection reuse optimization", 154 - "description": "Got uses the cacheable-lookup package to cache DNS resolutions, reducing latency and DNS query load. The OCaml library relies on the system DNS resolver without caching.", 155 - "affected_files": [ 156 - "lib/requests.ml", 157 - "lib/http_client.ml" 158 - ], 159 - "rationale": "DNS lookups can add significant latency, especially for high-volume applications. Got caches DNS resolutions to avoid repeated queries for the same hostname. While Eio and the OS may provide some DNS caching, application-level caching gives more control and consistency. The OCaml library could implement a simple DNS cache: type dns_cache = (string, Unix.inet_addr * float) Hashtbl.t where the float is the expiration time. Cache entries could have a configurable TTL (default 60 seconds). This would integrate with the connection pool to reuse both DNS resolutions and TCP connections." 160 - }, 161 - { 162 - "source_repo": "third_party/javascript/got", 163 - "source_language": "JavaScript/TypeScript", 164 - "criticality": "low", 165 - "change_type": "enhancement", 166 - "title": "Add beforeCache hook for fine-grained cache control", 167 - "description": "Got provides a beforeCache hook that allows users to modify responses before caching or prevent caching by returning false. The OCaml library has response caching headers parsed but no caching implementation or hooks.", 168 - "affected_files": [ 169 - "lib/requests.ml", 170 - "lib/response.ml" 171 - ], 172 - "rationale": "While the OCaml library parses Cache-Control headers and provides Response.is_cacheable, it doesn't implement actual response caching. If response caching is added, a beforeCache hook would allow users to: 1) modify responses before caching (remove sensitive data), 2) prevent caching for specific responses (even if headers allow it), 3) add custom caching logic (cache longer for certain resources). This would be implemented as an optional callback in the session config: before_cache: (Response.t -> (Response.t, [`No_cache]) result) option." 173 - }, 174 - { 175 - "source_repo": "third_party/javascript/got", 176 - "source_language": "JavaScript/TypeScript", 177 - "criticality": "low", 178 - "change_type": "feature", 179 - "title": "Add HTTP/2 support with protocol upgrade", 180 - "description": "Got supports HTTP/2 through the http2-wrapper package with automatic protocol negotiation via ALPN. The OCaml library only supports HTTP/1.1.", 181 - "affected_files": [ 182 - "lib/http_client.ml", 183 - "lib/requests.ml" 184 - ], 185 - "rationale": "HTTP/2 provides significant benefits: multiplexing (multiple requests over one connection), header compression, server push. Got auto-negotiates HTTP/2 via ALPN during TLS handshake and falls back to HTTP/1.1. OCaml has HTTP/2 libraries (h2, httpun-eio-h2) that could be integrated. Adding HTTP/2 support would require: 1) ALPN negotiation in TLS config, 2) protocol detection based on ALPN result, 3) separate HTTP/2 client implementation, 4) unified API that works with both protocols. This is a larger enhancement but would improve performance for modern APIs." 186 - }, 187 - { 188 - "source_repo": "third_party/javascript/got", 189 - "source_language": "JavaScript/TypeScript", 190 - "criticality": "medium", 191 - "change_type": "enhancement", 192 - "title": "Add automatic Retry-After header handling with configurable limits", 193 - "description": "Got respects Retry-After headers and provides maxRetryAfter option to cap the wait time. The OCaml library parses Retry-After but doesn't enforce maximum retry delays in the retry configuration.", 194 - "affected_files": [ 195 - "lib/retry.ml", 196 - "lib/retry.mli" 197 - ], 198 - "rationale": "The OCaml library's Retry module parses Retry-After headers correctly (both integer seconds and HTTP dates), but there's no way to cap the maximum retry delay. If a server sends 'Retry-After: 86400' (24 hours), the library would wait that long. Got provides a maxRetryAfter option (part of retry config) that caps the maximum wait time. Adding this to Retry.config would prevent indefinite waiting: type config = { ... ; max_retry_after: float option (* cap for Retry-After header, in seconds *) }. The calculate_backoff function would then check: if retry_after > max_retry_after then return 0 (don't retry)." 199 - }, 200 - { 201 - "source_repo": "third_party/javascript/got", 202 - "source_language": "JavaScript/TypeScript", 203 - "criticality": "low", 204 - "change_type": "enhancement", 205 - "title": "Add Link header parsing for pagination and resource discovery", 206 - "description": "Got includes a Link header parser (parse-link-header) that extracts relation types and URLs. This is commonly used for REST API pagination. The OCaml library has no Link header parsing utilities.", 207 - "affected_files": [ 208 - "lib/headers.ml", 209 - "lib/headers.mli", 210 - "lib/response.ml" 211 - ], 212 - "rationale": "The Link header (RFC 8288) is widely used for pagination in REST APIs (GitHub, GitLab, etc.). Format: Link: <https://api.example.com/page2>; rel=\"next\", <https://api.example.com/last>; rel=\"last\". Got parses this into a structured object. The OCaml library could add: type link_rel = { url: string; rel: string; params: (string * string) list } and val parse_link : string -> link_rel list in the Headers module. Response.ml could then provide: val links : t -> link_rel list and val next_url : t -> string option. This would enable easy pagination without manual header parsing." 213 - }, 214 - { 215 - "source_repo": "third_party/javascript/got", 216 - "source_language": "JavaScript/TypeScript", 217 - "criticality": "medium", 218 - "change_type": "enhancement", 219 - "title": "Add custom JSON parser/stringifier configuration", 220 - "description": "Got allows users to override JSON parsing and stringification (parseJson and stringifyJson options) to use custom JSON libraries or add transformations. The OCaml library hardcodes Jsont for JSON operations.", 221 - "affected_files": [ 222 - "lib/requests.ml", 223 - "lib/body.ml", 224 - "lib/response.ml" 225 - ], 226 - "rationale": "Different applications have different JSON needs: some need strict RFC compliance, others need to handle invalid JSON gracefully, some need custom number parsing. Got allows overriding the JSON parser/stringifier. In OCaml, there are multiple JSON libraries (Yojson, Ezjsonm, Jsont) with different tradeoffs. Currently the library hardcodes Jsont. Adding optional json_encode and json_decode functions to the session config would allow users to plug in their preferred JSON library: type json_codec = { encode: Jsont.json -> string; decode: string -> (Jsont.json, string) result }. This could be made polymorphic to support any JSON type." 227 - }, 228 - { 229 - "source_repo": "third_party/javascript/got", 230 - "source_language": "JavaScript/TypeScript", 231 - "criticality": "low", 232 - "change_type": "enhancement", 233 - "title": "Add method-specific convenience functions", 234 - "description": "Got provides method shortcuts like got.post(), got.put(), got.delete() in addition to got(url, {method: 'POST'}). The OCaml library has Requests.get, Requests.post but not all methods.", 235 - "affected_files": [ 236 - "lib/requests.ml", 237 - "lib/requests.mli", 238 - "lib/one.ml", 239 - "lib/one.mli" 240 - ], 241 - "rationale": "The OCaml library provides Requests.get and Requests.post but is missing convenience functions for PUT, PATCH, DELETE, HEAD, OPTIONS. Got provides shortcuts for all common methods. Adding val put, val patch, val delete, val head, val options functions would make the API more consistent and convenient. These would be simple wrappers that call the main request function with the appropriate method. This is a low-effort enhancement that improves API ergonomics." 242 - }, 243 - { 244 - "source_repo": "third_party/javascript/got", 245 - "source_language": "JavaScript/TypeScript", 246 - "criticality": "low", 247 - "change_type": "enhancement", 248 - "title": "Add prefixUrl for baseURL functionality", 249 - "description": "Got provides a prefixUrl option that automatically prepends a base URL to all requests, making relative URLs work correctly. The OCaml library requires full URLs for every request.", 250 - "affected_files": [ 251 - "lib/requests.ml", 252 - "lib/requests.mli" 253 - ], 254 - "rationale": "When working with a single API, repeating the base URL is tedious and error-prone. Got's prefixUrl option lets you write: const api = got.extend({prefixUrl: 'https://api.example.com'}); await api.get('users/123') instead of got.get('https://api.example.com/users/123'). The OCaml library could add an optional base_url field to the session config. When set, URLs that don't start with http:// or https:// would be treated as relative and concatenated with base_url. Implementation: if not (String.starts_with ~prefix:\"http\" url) then Uri.to_string (Uri.resolve \"\" (Uri.of_string base_url) (Uri.of_string url))." 255 - }, 256 - { 257 - "source_repo": "third_party/javascript/got", 258 - "source_language": "JavaScript/TypeScript", 259 - "criticality": "medium", 260 - "change_type": "enhancement", 261 - "title": "Add mutable defaults for runtime configuration updates", 262 - "description": "Got's got.extend() supports mutableDefaults option that allows updating configuration after instance creation, useful for token refresh scenarios. The OCaml library's session type is immutable except for statistics.", 263 - "affected_files": [ 264 - "lib/requests.ml", 265 - "lib/requests.mli" 266 - ], 267 - "rationale": "OAuth token refresh is a common use case where you need to update the session's authentication token without creating a new session (which would lose connection pools, statistics, etc.). Got's mutableDefaults allows updating options after creation. In OCaml, the library could provide update functions: val update_auth : t -> Auth.t -> unit, val update_headers : t -> Headers.t -> unit. These would use mutable fields (like statistics currently does) to allow runtime updates. This is particularly important for long-lived sessions that need to refresh credentials." 268 - }, 269 - { 270 - "source_repo": "third_party/javascript/got", 271 - "source_language": "JavaScript/TypeScript", 272 - "criticality": "low", 273 - "change_type": "enhancement", 274 - "title": "Add decompression for Brotli and Zstandard encodings", 275 - "description": "Got supports decompression for gzip, deflate, brotli, and zstd (via decompress-response). The OCaml library only supports gzip, deflate, and zlib decompression.", 276 - "affected_files": [ 277 - "lib/http_client.ml" 278 - ], 279 - "rationale": "Modern web servers increasingly use Brotli and Zstandard compression for better compression ratios. The OCaml library supports gzip/deflate/zlib but not brotli or zstd. OCaml has libraries for these: decompress for brotli, ocaml-zstd for zstandard. Adding support would require: 1) recognize 'br' and 'zstd' content-encoding headers, 2) decompress using appropriate library, 3) add to Accept-Encoding header when auto_decompress is true. This would enable better compression for modern APIs and reduce bandwidth usage." 280 - } 281 - ] 282 - }
-281
third_party/javascript/needle.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "needle (JavaScript)", 5 - "source_language": "JavaScript", 6 - "criticality": "medium", 7 - "change_type": "enhancement", 8 - "title": "Add request cancellation/abort capability via Eio.Cancel", 9 - "description": "Needle supports request cancellation via AbortSignal (lines 789-795 in needle.js), allowing users to cancel in-flight requests. The OCaml library should expose Eio's cancellation mechanisms to allow aborting requests programmatically, especially useful for timeouts controlled by the caller or concurrent request racing.", 10 - "affected_files": [ 11 - "lib/requests.mli", 12 - "lib/requests.ml", 13 - "lib/one.mli", 14 - "lib/one.ml" 15 - ], 16 - "rationale": "Request cancellation is essential for: (1) implementing custom timeout strategies beyond fixed timeouts, (2) racing multiple requests and canceling losers, (3) user-initiated cancellation in interactive applications, (4) graceful shutdown scenarios. Needle's AbortSignal support (lines 789-795) demonstrates this is a common requirement. Eio already has cancellation built-in via switches and Cancel module, but it's not exposed in the public API. Adding explicit abort() methods or documenting cancellation patterns would improve usability." 17 - }, 18 - { 19 - "source_repo": "needle (JavaScript)", 20 - "source_language": "JavaScript", 21 - "criticality": "low", 22 - "change_type": "enhancement", 23 - "title": "Add informative default User-Agent with version and platform info", 24 - "description": "Needle sets a descriptive default User-Agent: 'Needle/3.3.0 (Node.js v16.0.0; linux x64)' (lines 26-28 in needle.js). The OCaml library should set a similar default User-Agent identifying the library, version, OCaml version, and platform, rather than having no default User-Agent.", 25 - "affected_files": [ 26 - "lib/requests.ml", 27 - "lib/one.ml", 28 - "dune" 29 - ], 30 - "rationale": "A descriptive User-Agent header helps with: (1) server-side analytics and debugging, (2) identifying the HTTP client library for support purposes, (3) API providers tracking usage by client library, (4) compliance with HTTP best practices (RFC 7231 recommends User-Agent). The current implementation only sets User-Agent if explicitly provided. Adding a default like 'ocaml-requests/0.1.0 (OCaml 5.1.0; linux)' would improve observability while still allowing override." 31 - }, 32 - { 33 - "source_repo": "needle (JavaScript)", 34 - "source_language": "JavaScript", 35 - "criticality": "medium", 36 - "change_type": "enhancement", 37 - "title": "Emit progress events for streaming requests", 38 - "description": "Needle emits granular events throughout the request lifecycle: 'header', 'headers', 'redirect', 'timeout', 'err', 'done' (lines 481-488 in needle.js). These events allow users to monitor request progress in streaming mode. The OCaml library could provide similar observability via callback hooks or event channels for monitoring long-running requests.", 39 - "affected_files": [ 40 - "lib/requests.mli", 41 - "lib/requests.ml", 42 - "lib/response.mli", 43 - "lib/response.ml" 44 - ], 45 - "rationale": "Progress monitoring is valuable for: (1) implementing progress bars for file uploads/downloads, (2) logging and debugging long-running requests, (3) early response header inspection before body download, (4) custom timeout or cancellation logic based on progress. While OCaml's approach uses Eio streams which are pull-based rather than event-driven, providing optional callbacks (e.g., on_headers, on_redirect) would enable similar observability without breaking the current API design." 46 - }, 47 - { 48 - "source_repo": "needle (JavaScript)", 49 - "source_language": "JavaScript", 50 - "criticality": "medium", 51 - "change_type": "enhancement", 52 - "title": "Add URI modifier hook for dynamic URL transformation", 53 - "description": "Needle provides a uri_modifier option (line 320 in README.md) - a function that can transform the request URI before each request or redirect. This is useful for adding signatures, timestamps, or other dynamic URL modifications. The OCaml library could provide similar functionality via a ~uri_modifier callback.", 54 - "affected_files": [ 55 - "lib/requests.mli", 56 - "lib/requests.ml", 57 - "lib/one.mli", 58 - "lib/one.ml" 59 - ], 60 - "rationale": "URI modification hooks enable: (1) AWS-style request signing where signatures are added to query parameters, (2) adding dynamic authentication tokens or timestamps to URLs, (3) URL rewriting for testing/mocking without changing application code, (4) adding tracking parameters. This pattern is common in API clients that need to sign requests. Implementation would be straightforward: add optional ~uri_modifier:(Uri.t -> Uri.t) parameter that's called before each request." 61 - }, 62 - { 63 - "source_repo": "needle (JavaScript)", 64 - "source_language": "JavaScript", 65 - "criticality": "low", 66 - "change_type": "enhancement", 67 - "title": "Add granular redirect control options", 68 - "description": "Needle provides fine-grained redirect control: follow_if_same_host, follow_if_same_protocol, follow_if_same_location, follow_keep_method, follow_set_referer (lines 365-370 in README.md). The OCaml library only has follow_redirects and max_redirects flags. Adding similar granular options would improve security and flexibility.", 69 - "affected_files": [ 70 - "lib/requests.mli", 71 - "lib/requests.ml" 72 - ], 73 - "rationale": "Granular redirect control improves: (1) Security by preventing cross-domain redirects that could leak credentials or cookies, (2) Correct behavior by allowing POST/PUT to remain as-is on redirect (follow_keep_method), (3) Analytics by setting Referer header on redirects (follow_set_referer), (4) Testing by preventing redirect loops (follow_if_same_location). The current implementation at lines 266-281 validates redirect schemes but doesn't check host/protocol. Adding these options would prevent common security issues like open redirect exploitation." 74 - }, 75 - { 76 - "source_repo": "needle (JavaScript)", 77 - "source_language": "JavaScript", 78 - "criticality": "low", 79 - "change_type": "enhancement", 80 - "title": "Support automatic Content-Length detection for streams", 81 - "description": "Needle's stream_length option (line 318 in README.md) allows setting Content-Length to 0 to auto-detect stream length, preventing ECONNRESET errors on servers that require Content-Length. The OCaml library requires manual length specification for streams.", 82 - "affected_files": [ 83 - "lib/body.mli", 84 - "lib/body.ml", 85 - "lib/http_write.ml" 86 - ], 87 - "rationale": "Automatic Content-Length detection improves: (1) Compatibility with servers that reject chunked encoding, (2) Better performance by avoiding chunked overhead, (3) Reduced user error by eliminating manual length calculation. For Eio file streams, length can be determined via stat. For other streams, the current behavior (chunked encoding without length) is appropriate. Adding ~auto_length:bool parameter to Body.of_stream would enable this feature when the stream source supports length queries." 88 - }, 89 - { 90 - "source_repo": "needle (JavaScript)", 91 - "source_language": "JavaScript", 92 - "criticality": "low", 93 - "change_type": "enhancement", 94 - "title": "Add response output-to-file option", 95 - "description": "Needle supports dumping response bodies directly to files via the 'output' option (lines 328, 640-649 in needle.js), which occurs after decompression/parsing. This is convenient for downloading files without manually managing streams.", 96 - "affected_files": [ 97 - "lib/requests.mli", 98 - "lib/requests.ml", 99 - "lib/one.mli", 100 - "lib/one.ml" 101 - ], 102 - "rationale": "Direct file output simplifies common use cases: (1) Downloading files without stream management boilerplate, (2) Ensuring proper cleanup even on errors, (3) Automatic decompression before writing to disk. While users can currently achieve this by piping Response.body to a file sink, providing ~output:(Eio.Path.t) parameter would be more convenient and ensure consistent error handling. Implementation would wrap the response body in automatic file writing with proper switch-based cleanup." 103 - }, 104 - { 105 - "source_repo": "needle (JavaScript)", 106 - "source_language": "JavaScript", 107 - "criticality": "high", 108 - "change_type": "bug", 109 - "title": "Prevent double-callback/double-done execution", 110 - "description": "Needle protects against calling the done() callback multiple times using a 'returned' counter (lines 469-471 in needle.js). This prevents errors, timeouts, and normal completion from triggering multiple callbacks. The OCaml library should ensure similar protection against duplicate error/completion handling.", 111 - "affected_files": [ 112 - "lib/http_client.ml", 113 - "lib/requests.ml", 114 - "lib/one.ml" 115 - ], 116 - "rationale": "Double-completion bugs can cause: (1) Resource leaks (cleaning up twice), (2) User confusion (callback called with different values), (3) Race conditions in application logic, (4) Corruption if resources are already released. This is particularly important in error handling paths where both timeout and connection errors might fire. The OCaml implementation should verify that: (a) cleanup code is idempotent or protected, (b) only one of error/success path executes, (c) Eio's structured concurrency doesn't allow multiple completion paths. Review http_client.ml for potential double-completion scenarios." 117 - }, 118 - { 119 - "source_repo": "needle (JavaScript)", 120 - "source_language": "JavaScript", 121 - "criticality": "medium", 122 - "change_type": "enhancement", 123 - "title": "Add socket-level and response-level timeout distinction", 124 - "description": "Needle distinguishes between open_timeout (connection), response_timeout (waiting for headers after connection), and read_timeout (data transfer after headers) at lines 94-96 and 755-774. The OCaml library has connect_timeout and read_timeout but lacks response_timeout (time to first byte after connection).", 125 - "affected_files": [ 126 - "lib/timeout.mli", 127 - "lib/timeout.ml", 128 - "lib/http_client.ml" 129 - ], 130 - "rationale": "Response timeout is crucial for: (1) Detecting slow/stalled servers that accept connections but don't send headers, (2) Distinguishing between connection issues and application-level delays, (3) More granular timeout strategies (fast connect, slow headers, fast data). The distinction matters because a server might accept TCP connections quickly but take time to process requests. Adding response_timeout would improve timeout precision and debugging. Implementation would start the timer after socket connection (analogous to Needle lines 766-774)." 131 - }, 132 - { 133 - "source_repo": "needle (JavaScript)", 134 - "source_language": "JavaScript", 135 - "criticality": "medium", 136 - "change_type": "enhancement", 137 - "title": "Add 'parse_response' option to control automatic parsing", 138 - "description": "Needle's parse_response option (line 327 in README.md) allows disabling auto-parsing or restricting it to specific types ('json', 'xml', 'all'). The OCaml library always attempts JSON parsing when requested. Adding finer control would prevent unwanted parsing overhead.", 139 - "affected_files": [ 140 - "lib/response.mli", 141 - "lib/response.ml", 142 - "lib/requests.mli", 143 - "lib/requests.ml" 144 - ], 145 - "rationale": "Parsing control is valuable for: (1) Performance when raw body access is needed, (2) Custom parsing logic (e.g., streaming JSON parsers), (3) Security by avoiding parser bugs on untrusted input, (4) Handling broken servers that send wrong Content-Type headers. Currently, users must skip Response.json and manually parse. Adding ~parse:[ `All | `Json | `None ] option would give users control without breaking existing API. Needle's approach (lines 604-618) only parses when explicitly requested and content-type matches." 146 - }, 147 - { 148 - "source_repo": "needle (JavaScript)", 149 - "source_language": "JavaScript", 150 - "criticality": "low", 151 - "change_type": "enhancement", 152 - "title": "Support cookie persistence to disk with better isolation", 153 - "description": "The OCaml library has basic cookie persistence via persist_cookies flag, but Needle demonstrates more sophisticated cookie handling with per-request cookie merging (lines 550-558). Consider enhancing cookie isolation and providing finer control over cookie behavior.", 154 - "affected_files": [ 155 - "lib/requests.ml", 156 - "lib/requests.mli" 157 - ], 158 - "rationale": "Better cookie handling enables: (1) Testing with isolated cookie jars, (2) Per-domain or per-session cookie isolation, (3) Explicit cookie merging/clearing between requests, (4) Debugging by inspecting cookie state. The current implementation uses Cookeio_jar with XDG persistence but doesn't expose cookie inspection or manual manipulation. Adding methods like get_cookies, set_cookies, clear_cookies would improve testability and debugging. Needle's approach of merging request cookies with response cookies (lines 550-558) shows the importance of granular cookie control." 159 - }, 160 - { 161 - "source_repo": "needle (JavaScript)", 162 - "source_language": "JavaScript", 163 - "criticality": "medium", 164 - "change_type": "enhancement", 165 - "title": "Add charset decoding for non-UTF8 text responses", 166 - "description": "Needle automatically detects and decodes non-UTF8 charsets from Content-Type headers using iconv-lite (lines 622-624 in needle.js). The OCaml library doesn't perform automatic charset conversion, which could lead to mojibake when handling responses with different encodings.", 167 - "affected_files": [ 168 - "lib/response.mli", 169 - "lib/response.ml", 170 - "lib/http_read.ml" 171 - ], 172 - "rationale": "Charset decoding is important for: (1) International content where servers use ISO-8859-1, Windows-1252, or other legacy encodings, (2) Correctness when displaying or processing text, (3) Compatibility with older servers that don't use UTF-8. The issue manifests when parsing responses from legacy systems or international servers. Adding optional ~decode:bool parameter (default: true) with uutf/uucp for charset conversion would improve compatibility. Implementation should: (a) parse charset from Content-Type header, (b) detect common encodings, (c) convert to UTF-8 before returning text." 173 - }, 174 - { 175 - "source_repo": "needle (JavaScript)", 176 - "source_language": "JavaScript", 177 - "criticality": "low", 178 - "change_type": "enhancement", 179 - "title": "Add convenience option aliases for better ergonomics", 180 - "description": "Needle provides option aliases like 'timeout' for 'open_timeout', 'follow' for 'follow_max', 'parse' for 'parse_response' (lines 115-123 in needle.js). This improves API ergonomics by allowing both concise and explicit parameter names.", 181 - "affected_files": [ 182 - "lib/timeout.mli", 183 - "lib/requests.mli" 184 - ], 185 - "rationale": "Option aliases improve: (1) Discoverability - users can guess 'timeout' even if formal name is 'open_timeout', (2) Migration - old code continues working when formal names change, (3) Conciseness - 'follow:5' is cleaner than 'follow_max:5'. In OCaml, this is less critical due to labeled arguments, but providing both forms could improve usability. For example, accepting both ~timeout and ~open_timeout, or ~follow and ~max_redirects. Implementation via optional parameters that map to the same internal field." 186 - }, 187 - { 188 - "source_repo": "needle (JavaScript)", 189 - "source_language": "JavaScript", 190 - "criticality": "medium", 191 - "change_type": "enhancement", 192 - "title": "Add URL-embedded authentication support", 193 - "description": "Needle extracts credentials from URLs like 'https://user:pass@host.com' (lines 447-452 in README.md) for basic authentication. The OCaml library requires explicit auth parameter. Supporting URL-embedded credentials would improve compatibility with existing URLs.", 194 - "affected_files": [ 195 - "lib/requests.ml", 196 - "lib/one.ml", 197 - "lib/auth.ml" 198 - ], 199 - "rationale": "URL-embedded authentication enables: (1) Compatibility with RFC-1738 basic auth URLs, (2) Simplified testing by pasting URLs directly, (3) Integration with tools that output URLs with credentials. The security risk (credentials in URLs can leak via logs/Referer) is mitigated by the existing sanitize_url function in error.ml. Implementation: (a) parse URI.userinfo, (b) extract username and optional password, (c) apply as Basic auth if no explicit auth provided, (d) remove userinfo from URL before making request. Should be opt-in via ~extract_url_auth:bool flag." 200 - }, 201 - { 202 - "source_repo": "needle (JavaScript)", 203 - "source_language": "JavaScript", 204 - "criticality": "low", 205 - "change_type": "enhancement", 206 - "title": "Add brotli compression support alongside gzip/deflate", 207 - "description": "Needle supports brotli compression ('br' encoding) on Node.js 10.16+ (lines 70-72 in needle.js, line 112 in README.md). The OCaml library uses decompress library which supports gzip/deflate/zlib but may not support brotli. Adding brotli would improve bandwidth efficiency.", 208 - "affected_files": [ 209 - "lib/http_read.ml", 210 - "dune" 211 - ], 212 - "rationale": "Brotli compression offers: (1) 15-25% better compression than gzip for text, (2) Widespread support in modern browsers and CDNs, (3) Standard HTTP encoding (RFC 7932). Many modern APIs and CDNs prefer brotli for efficiency. The decompress library may already support brotli, but if not, consider adding the 'decompress-br' or similar OCaml library. Implementation would: (a) add 'br' to Accept-Encoding when auto_decompress=true, (b) detect 'br' content-encoding in responses, (c) pipe through brotli decompressor. Check if current decompress version supports brotli before implementing." 213 - }, 214 - { 215 - "source_repo": "needle (JavaScript)", 216 - "source_language": "JavaScript", 217 - "criticality": "low", 218 - "change_type": "enhancement", 219 - "title": "Support XML parsing alongside JSON", 220 - "description": "Needle automatically parses XML responses based on content-type using a SAX parser (lib/parsers.js). The OCaml library only supports JSON parsing. Adding XML parsing would improve compatibility with XML APIs (SOAP, RSS, Atom feeds).", 221 - "affected_files": [ 222 - "lib/response.mli", 223 - "lib/response.ml", 224 - "dune" 225 - ], 226 - "rationale": "XML parsing enables: (1) Consuming XML APIs without external dependencies, (2) Processing RSS/Atom feeds, (3) SOAP web service integration, (4) Legacy API compatibility. While JSON is dominant, many services still use XML (AWS APIs, RSS feeds, SOAP services). Adding ~xml:unit -> Response.t or Response.xml method using markup, ezxmlm, or xmlm library would provide parity. Implementation should: (a) detect XML content-types (text/xml, application/xml, etc.), (b) parse to structured representation, (c) handle parse errors gracefully by returning raw body." 227 - }, 228 - { 229 - "source_repo": "needle (JavaScript)", 230 - "source_language": "JavaScript", 231 - "criticality": "high", 232 - "change_type": "bug", 233 - "title": "Ensure proper cleanup on 'write after end' stream errors", 234 - "description": "Needle explicitly handles 'write after end' errors (lines 635-636 in needle.js) by destroying the request to prevent dangling sockets. This addresses a specific error case in Node.js v8+. The OCaml library should verify similar error conditions don't cause resource leaks.", 235 - "affected_files": [ 236 - "lib/http_write.ml", 237 - "lib/http_client.ml" 238 - ], 239 - "rationale": "Stream error handling prevents: (1) Socket leaks when pipelines fail mid-stream, (2) Connection pool exhaustion from leaked sockets, (3) Hanging requests that never complete. This is critical for long-running services. The issue occurs when the receiving end closes but the sender continues writing. Eio's structured concurrency should prevent this, but verify: (a) all stream errors properly propagate to cleanup code, (b) sockets are closed even when body writing fails, (c) connection pool resources are released on stream errors. Test by closing response stream mid-read." 240 - }, 241 - { 242 - "source_repo": "needle (JavaScript)", 243 - "source_language": "JavaScript", 244 - "criticality": "medium", 245 - "change_type": "enhancement", 246 - "title": "Add graceful parsing failure with fallback to raw body", 247 - "description": "Needle gracefully handles JSON/XML parsing errors by returning the original raw body instead of throwing (lines 60-64 in stream_events_spec.js, line 116 in README.md). The OCaml library may throw exceptions on parse errors. Providing graceful fallback would improve robustness.", 248 - "affected_files": [ 249 - "lib/response.ml" 250 - ], 251 - "rationale": "Graceful parse failure enables: (1) Handling broken APIs that send wrong Content-Type headers, (2) Partial content consumption even when parsing fails, (3) Better error messages with preview of actual content, (4) Fallback to manual parsing when auto-parsing fails. Current Response.json likely raises exception on invalid JSON. Providing Response.json_opt : t -> Jsont.json option that returns None on parse failure would give users choice. Also consider returning parse errors in the response structure rather than raising, following Eio's philosophy of explicit error handling." 252 - }, 253 - { 254 - "source_repo": "needle (JavaScript)", 255 - "source_language": "JavaScript", 256 - "criticality": "medium", 257 - "change_type": "enhancement", 258 - "title": "Add streaming request body support from arbitrary sources", 259 - "description": "Needle detects and handles stream bodies specially (lines 776-780) using a pump_streams utility, properly handling backpressure and errors. The OCaml library supports streaming via Body.of_stream but verify backpressure handling is correct.", 260 - "affected_files": [ 261 - "lib/body.ml", 262 - "lib/http_write.ml" 263 - ], 264 - "rationale": "Proper streaming enables: (1) Uploading large files without loading into memory, (2) Streaming generated content (e.g., database exports), (3) Efficient memory usage for multi-GB uploads, (4) Proper flow control and backpressure. Verify the current implementation: (a) respects backpressure from socket, (b) handles stream errors properly, (c) doesn't buffer entire stream. Eio's Flow abstraction should handle this correctly, but verify with tests for: large file uploads, slow network conditions, mid-stream errors. Needle's approach shows importance of proper stream error handling." 265 - }, 266 - { 267 - "source_repo": "needle (JavaScript)", 268 - "source_language": "JavaScript", 269 - "criticality": "low", 270 - "change_type": "feature", 271 - "title": "Add ability to set local IP address for outbound requests", 272 - "description": "Needle supports localAddress option (line 319 in README.md) to specify which local network interface to use for the request. This is useful for multi-homed systems. Consider adding similar capability to the OCaml library.", 273 - "affected_files": [ 274 - "lib/http_client.ml", 275 - "lib/one.mli", 276 - "lib/requests.mli" 277 - ], 278 - "rationale": "Local address binding enables: (1) Multi-homed servers using specific NICs, (2) Testing with specific network interfaces, (3) IPv4/IPv6 selection on dual-stack systems, (4) Source address selection for firewall rules. While less common than other features, this is valuable for network engineers and testing. Eio's Net module may already support this via connection options. Check if Eio.Net.connect supports source address binding and expose it via ~local_address:string parameter." 279 - } 280 - ] 281 - }
-253
third_party/javascript/node-fetch.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/javascript/node-fetch", 5 - "source_language": "javascript", 6 - "criticality": "high", 7 - "change_type": "security", 8 - "title": "Implement POST-to-GET redirect conversion for 301/302 status codes", 9 - "description": "Node-fetch converts POST requests to GET when following 301/302 redirects (per HTTP spec RFC 9110). The OCaml library currently preserves the original method for all redirects, which can cause issues with POST body re-submission and violates standard redirect semantics.", 10 - "affected_files": [ 11 - "lib/requests.ml" 12 - ], 13 - "rationale": "In node-fetch (index.js:223-227), POST requests are converted to GET for 301/302 redirects, and the body/content-length are removed. This prevents accidental re-submission of sensitive POST data and follows HTTP spec requirements. The OCaml library should implement similar logic: convert POST/PUT/PATCH to GET for 301/302 (but not 303 which already requires GET, or 307/308 which preserve method)." 14 - }, 15 - { 16 - "source_repo": "third_party/javascript/node-fetch", 17 - "source_language": "javascript", 18 - "criticality": "high", 19 - "change_type": "security", 20 - "title": "Add protocol downgrade detection in redirect security checks", 21 - "description": "Node-fetch strips sensitive headers when redirecting from HTTPS to HTTP (protocol downgrade). The OCaml library's same_origin check should also verify protocol matching to prevent credential leakage over unencrypted connections.", 22 - "affected_files": [ 23 - "lib/requests.ml" 24 - ], 25 - "rationale": "Node-fetch's isDomainOrSubdomain and isSameProtocol checks (index.js:209, is.js:68-87) prevent both cross-domain AND cross-protocol credential leakage. The OCaml code at requests.ml:487-492 only checks domain/subdomain matching. A redirect from https://api.example.com to http://api.example.com would preserve Authorization headers, exposing credentials in plaintext. Add protocol comparison to same_origin function." 26 - }, 27 - { 28 - "source_repo": "third_party/javascript/node-fetch", 29 - "source_language": "javascript", 30 - "criticality": "medium", 31 - "change_type": "security", 32 - "title": "Expand sensitive header stripping to include WWW-Authenticate and Cookie2", 33 - "description": "Node-fetch strips 'authorization', 'www-authenticate', 'cookie', and 'cookie2' headers on cross-origin redirects. The OCaml library should strip the same complete set of sensitive headers.", 34 - "affected_files": [ 35 - "lib/requests.ml" 36 - ], 37 - "rationale": "Node-fetch strips 4 headers on untrusted redirects (index.js:210-212): authorization, www-authenticate, cookie, cookie2. The OCaml strip_sensitive_headers function should be verified to include all these headers. WWW-Authenticate can leak authentication schemes and realms; Cookie2 (deprecated but still used) can leak session data." 38 - }, 39 - { 40 - "source_repo": "third_party/javascript/node-fetch", 41 - "source_language": "javascript", 42 - "criticality": "medium", 43 - "change_type": "feature", 44 - "title": "Add bodyUsed/bodyConsumed tracking to prevent double-consumption bugs", 45 - "description": "Node-fetch tracks whether a response body has been consumed via the 'bodyUsed' property (body.js:96-97) and prevents double-consumption. The OCaml Response type should track consumption state and raise an error if body methods are called multiple times.", 46 - "affected_files": [ 47 - "lib/response.ml" 48 - ], 49 - "rationale": "Node-fetch's Body mixin tracks 'disturbed' state (body.js:77) and checks it before consumption (body.js:195-199). This prevents bugs where code tries to read response.text() after response.json(). OCaml's Response.text/json/body functions should set a mutable 'consumed' flag and raise Error.Invalid_request if called twice, preventing subtle resource/parsing bugs." 50 - }, 51 - { 52 - "source_repo": "third_party/javascript/node-fetch", 53 - "source_language": "javascript", 54 - "criticality": "medium", 55 - "change_type": "enhancement", 56 - "title": "Add redirect mode configuration (follow/error/manual)", 57 - "description": "Node-fetch supports three redirect modes: 'follow' (default), 'error' (reject on redirect), and 'manual' (return redirect response without following). The OCaml library only has a boolean follow_redirects flag.", 58 - "affected_files": [ 59 - "lib/requests.ml", 60 - "lib/requests.mli" 61 - ], 62 - "rationale": "Node-fetch's redirect mode (index.js:163-243) allows fine-grained control: 'error' mode rejects redirects with FetchError, 'manual' mode returns 3xx responses for application handling, 'follow' follows automatically. This is useful for applications that need to detect redirects, extract redirect chains, or implement custom redirect logic. Replace follow_redirects:bool with redirect_mode variant type." 63 - }, 64 - { 65 - "source_repo": "third_party/javascript/node-fetch", 66 - "source_language": "javascript", 67 - "criticality": "low", 68 - "change_type": "enhancement", 69 - "title": "Validate redirect Location header before following", 70 - "description": "Node-fetch validates that redirect Location headers contain valid URLs and rejects invalid redirects with a specific error type. The OCaml library should add similar validation.", 71 - "affected_files": [ 72 - "lib/requests.ml" 73 - ], 74 - "rationale": "Node-fetch wraps URL parsing in try-catch (index.js:150-160) and raises 'invalid-redirect' FetchError for malformed Location headers. This prevents crashes from malicious/broken servers returning invalid redirects. The OCaml code at requests.ml:468 calls validate_redirect_url but should also handle URL parsing failures and raise Error.Invalid_redirect with details." 75 - }, 76 - { 77 - "source_repo": "third_party/javascript/node-fetch", 78 - "source_language": "javascript", 79 - "criticality": "low", 80 - "change_type": "enhancement", 81 - "title": "Add unsupported-redirect error for stream body redirects", 82 - "description": "Node-fetch prevents following redirects when the request body is a readable stream (except for 303 redirects), raising 'unsupported-redirect' error. This prevents data loss and resource leaks.", 83 - "affected_files": [ 84 - "lib/requests.ml", 85 - "lib/error.ml" 86 - ], 87 - "rationale": "Node-fetch checks if request body is a Stream.Readable (index.js:216-220) and rejects non-303 redirects with this body type. Streams cannot be rewound/replayed, so following redirects would lose data. The OCaml library's Body.Stream type should trigger similar validation: prevent redirects (except 303) when body is Body.Stream or Body.File without length, or add Error.Unsupported_redirect variant." 88 - }, 89 - { 90 - "source_repo": "third_party/javascript/node-fetch", 91 - "source_language": "javascript", 92 - "criticality": "medium", 93 - "change_type": "enhancement", 94 - "title": "Add referrer policy parsing and update on redirects", 95 - "description": "Node-fetch parses Referrer-Policy from response headers and updates the policy for subsequent redirects. The OCaml library lacks referrer policy support.", 96 - "affected_files": [ 97 - "lib/requests.ml", 98 - "lib/headers.ml" 99 - ], 100 - "rationale": "Node-fetch parses Referrer-Policy header (index.js:230-233) and updates referrerPolicy for the next redirect, implementing W3C Referrer Policy spec. While less critical for server-side clients, this is important for privacy-conscious applications. Add optional referrer_policy field to Requests.t and parse/apply it per the spec (see node-fetch/src/utils/referrer.js for 8 policy types)." 101 - }, 102 - { 103 - "source_repo": "third_party/javascript/node-fetch", 104 - "source_language": "javascript", 105 - "criticality": "low", 106 - "change_type": "enhancement", 107 - "title": "Support data: URI scheme for embedded content", 108 - "description": "Node-fetch supports data: URIs, allowing inline content without network requests. This is useful for testing and embedding small resources.", 109 - "affected_files": [ 110 - "lib/requests.ml", 111 - "lib/one.ml" 112 - ], 113 - "rationale": "Node-fetch handles data: URIs specially (index.js:57-62), parsing them with data-uri-to-buffer and returning a Response without network I/O. This is useful for testing, demos, and apps that embed small resources. Add data URI support using existing OCaml base64 libraries, detecting data: scheme and parsing format 'data:[<mediatype>][;base64],<data>'." 114 - }, 115 - { 116 - "source_repo": "third_party/javascript/node-fetch", 117 - "source_language": "javascript", 118 - "criticality": "medium", 119 - "change_type": "bug", 120 - "title": "Add GET/HEAD with body validation", 121 - "description": "Node-fetch explicitly rejects GET and HEAD requests with non-null bodies, as per HTTP spec. The OCaml library should add similar validation.", 122 - "affected_files": [ 123 - "lib/requests.ml", 124 - "lib/one.ml" 125 - ], 126 - "rationale": "Node-fetch throws TypeError for GET/HEAD with body (request.js:73-76), enforcing RFC 9110 semantics (GET/HEAD MUST NOT have message body). This prevents accidental misuse and ensures spec compliance. Add validation in make_request_internal: if method is GET/HEAD and body is not Body.Empty, raise Error.Invalid_request with clear message." 127 - }, 128 - { 129 - "source_repo": "third_party/javascript/node-fetch", 130 - "source_language": "javascript", 131 - "criticality": "medium", 132 - "change_type": "security", 133 - "title": "Reject URLs with embedded credentials in HTTP Basic Auth format", 134 - "description": "Node-fetch explicitly rejects URLs containing username:password@ credentials to prevent accidental credential exposure. The OCaml library should add this validation.", 135 - "affected_files": [ 136 - "lib/requests.ml", 137 - "lib/one.ml" 138 - ], 139 - "rationale": "Node-fetch checks parsedURL.username/password (request.js:59-61) and throws TypeError for URLs like 'https://user:pass@example.com'. This prevents credentials from appearing in logs, error messages, and proxy headers. While the OCaml library has Auth module for proper credential handling, URLs with embedded auth should be rejected with Error.Invalid_url to prevent security mistakes." 140 - }, 141 - { 142 - "source_repo": "third_party/javascript/node-fetch", 143 - "source_language": "javascript", 144 - "criticality": "low", 145 - "change_type": "enhancement", 146 - "title": "Add automatic Content-Type detection for request bodies", 147 - "description": "Node-fetch automatically sets Content-Type header based on body type (URLSearchParams, FormData, Blob) if not explicitly provided. The OCaml library should enhance this for Body.form and Body.multipart.", 148 - "affected_files": [ 149 - "lib/body.ml", 150 - "lib/requests.ml" 151 - ], 152 - "rationale": "Node-fetch's extractContentType function (body.js:91-94, request.js:90-95) automatically sets Content-Type for various body types. The OCaml library already does this for Body.multipart (generates boundary) and Body.json (sets application/json), but should verify Body.form sets 'application/x-www-form-urlencoded' automatically and document this behavior clearly." 153 - }, 154 - { 155 - "source_repo": "third_party/javascript/node-fetch", 156 - "source_language": "javascript", 157 - "criticality": "low", 158 - "change_type": "enhancement", 159 - "title": "Add response.clone() capability for multiple body consumptions", 160 - "description": "Node-fetch supports response.clone() to create independent copies, allowing multiple consumption of the response body. This is useful for caching, logging, and retry scenarios.", 161 - "affected_files": [ 162 - "lib/response.ml" 163 - ], 164 - "rationale": "Node-fetch's clone() method (body.js:266) creates an independent copy of the Response with a cloned body stream. While OCaml's current architecture (buffering full response body) makes this less critical than Node's streaming approach, adding Response.clone that duplicates the body flow/string would enable use cases like: logging full response while also parsing it, caching responses for later use, implementing custom retry logic." 165 - }, 166 - { 167 - "source_repo": "third_party/javascript/node-fetch", 168 - "source_language": "javascript", 169 - "criticality": "medium", 170 - "change_type": "feature", 171 - "title": "Add compressed request body support", 172 - "description": "While node-fetch focuses on response decompression, mature HTTP clients support request body compression (Content-Encoding: gzip). The OCaml library could add this for large uploads.", 173 - "affected_files": [ 174 - "lib/body.ml", 175 - "lib/http_write.ml" 176 - ], 177 - "rationale": "Node-fetch only decompresses responses, but Python requests and curl support compressing request bodies for large POST/PUT operations. This reduces bandwidth for large JSON/text uploads. Add Body.compressed variant that wraps String/Stream bodies with gzip compression, automatically sets Content-Encoding header. Useful for APIs that accept compressed uploads (many REST APIs support this)." 178 - }, 179 - { 180 - "source_repo": "third_party/javascript/node-fetch", 181 - "source_language": "javascript", 182 - "criticality": "low", 183 - "change_type": "enhancement", 184 - "title": "Add support for brotli decompression (Content-Encoding: br)", 185 - "description": "Node-fetch supports gzip, deflate, and brotli decompression. The OCaml library only supports gzip and deflate. Brotli offers better compression ratios and is increasingly common.", 186 - "affected_files": [ 187 - "lib/http_client.ml" 188 - ], 189 - "rationale": "Node-fetch decompresses brotli responses (test files show brotli support). The OCaml library's http_client.ml:28-83 only handles gzip and deflate (zlib). Add brotli support using the 'decompress' library's brotli backend (if available) or add it as optional dependency. Update Accept-Encoding header at requests.ml:321 to include 'br' when brotli is available." 190 - }, 191 - { 192 - "source_repo": "third_party/javascript/node-fetch", 193 - "source_language": "javascript", 194 - "criticality": "low", 195 - "change_type": "enhancement", 196 - "title": "Add highWaterMark/buffer size configuration for streaming", 197 - "description": "Node-fetch exposes highWaterMark option to control internal buffer size for streams. The OCaml library could expose similar Eio buffer configuration for large file handling.", 198 - "affected_files": [ 199 - "lib/requests.ml", 200 - "lib/http_client.ml" 201 - ], 202 - "rationale": "Node-fetch's highWaterMark option (default: 16384 bytes) controls stream buffering for memory/performance tuning. The OCaml library uses Eio's Buf_read/Buf_write with fixed buffer sizes. For applications handling very large files or memory-constrained environments, exposing buffer_size option in Requests.create and Http_client functions would allow tuning. Lower values reduce memory, higher values improve throughput." 203 - }, 204 - { 205 - "source_repo": "third_party/javascript/node-fetch", 206 - "source_language": "javascript", 207 - "criticality": "medium", 208 - "change_type": "feature", 209 - "title": "Add Response.redirect() static method for manual redirect creation", 210 - "description": "Node-fetch provides Response.redirect(url, status) static method to programmatically create redirect responses. Useful for testing and middleware.", 211 - "affected_files": [ 212 - "lib/response.ml" 213 - ], 214 - "rationale": "Node-fetch's Response.redirect() static method allows creating valid redirect responses with Location header. While primarily useful for server-side (not typical HTTP client use), this would be valuable for: testing redirect handling, creating mock servers, implementing custom redirect logic, building HTTP proxies. Add Response.make_redirect : url:string -> ?status:int -> unit -> t that creates 3xx response with Location header." 215 - }, 216 - { 217 - "source_repo": "third_party/javascript/node-fetch", 218 - "source_language": "javascript", 219 - "criticality": "low", 220 - "change_type": "enhancement", 221 - "title": "Add Response.error() static method for error response creation", 222 - "description": "Node-fetch provides Response.error() to create network error responses. Useful for testing error handling paths.", 223 - "affected_files": [ 224 - "lib/response.ml" 225 - ], 226 - "rationale": "Node-fetch's Response.error() creates a network error response (type 'error', status 0, null body). This is useful for testing network failure handling without actual network failures. Add Response.make_error : unit -> t that creates a synthetic error response, making it easier to write tests for error handling code paths without mocking network layer." 227 - }, 228 - { 229 - "source_repo": "third_party/javascript/node-fetch", 230 - "source_language": "javascript", 231 - "criticality": "low", 232 - "change_type": "enhancement", 233 - "title": "Improve error context with machine-readable error codes", 234 - "description": "Node-fetch's FetchError includes 'type' field ('system', 'invalid-redirect', 'max-redirect', 'max-size', 'unsupported-redirect') for programmatic error handling. The OCaml error variants could expose this more explicitly.", 235 - "affected_files": [ 236 - "lib/error.ml" 237 - ], 238 - "rationale": "Node-fetch's error.type field (fetch-error.js:11-25) allows pattern matching on error categories without parsing messages. While OCaml's Error module uses variants (which is better than JS), adding Error.error_type : error -> string function that returns machine-readable codes like 'timeout', 'redirect', 'http', 'security', etc. would help with logging, metrics, and cross-language error code compatibility." 239 - }, 240 - { 241 - "source_repo": "third_party/javascript/node-fetch", 242 - "source_language": "javascript", 243 - "criticality": "low", 244 - "change_type": "enhancement", 245 - "title": "Add system error code preservation in network errors", 246 - "description": "Node-fetch preserves system error codes (ECONNREFUSED, ETIMEDOUT, etc.) and syscall information in FetchError. The OCaml library should preserve and expose these for debugging.", 247 - "affected_files": [ 248 - "lib/error.ml" 249 - ], 250 - "rationale": "Node-fetch's FetchError constructor (fetch-error.js:17-24) captures systemError.code, systemError.errno, and systemError.syscall from Node.js errors. This is invaluable for debugging (distinguishing ECONNREFUSED from ETIMEDOUT from EHOSTUNREACH). The OCaml Error.Tcp_connect_failed and similar should capture and expose the underlying Eio exception details (error code, syscall) in structured fields, not just 'reason' string." 251 - } 252 - ] 253 - }
-255
third_party/javascript/superagent.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/javascript/superagent", 5 - "source_language": "JavaScript", 6 - "criticality": "medium", 7 - "change_type": "enhancement", 8 - "title": "Add granular timeout types (response, upload, deadline)", 9 - "description": "SuperAgent provides three distinct timeout types: (1) response timeout - time from request sent to first byte received, (2) upload timeout - time between data chunks during upload, (3) deadline timeout - total time for entire request. OCaml library only has connect, read, and total timeouts. Adding response and upload timeouts would provide better control over slow server scenarios and large file uploads.", 10 - "affected_files": [ 11 - "lib/timeout.mli", 12 - "lib/timeout.ml", 13 - "lib/http_client.ml" 14 - ], 15 - "rationale": "SuperAgent's timeout model at request-base.js:89-129 provides more granular control. Response timeout catches slow-to-start servers (different from read timeout which is per-operation). Upload timeout helps detect stalled uploads. This would improve reliability for applications dealing with large payloads or unreliable servers. Implementation would extend the Timeout.t type with optional response_timeout and upload_timeout fields, and modify HTTP client logic to enforce these timeouts at appropriate points in the request lifecycle." 16 - }, 17 - { 18 - "source_repo": "third_party/javascript/superagent", 19 - "source_language": "JavaScript", 20 - "criticality": "low", 21 - "change_type": "enhancement", 22 - "title": "Add custom retry callback for dynamic retry decisions", 23 - "description": "SuperAgent allows users to provide a custom retry callback function that can override default retry logic on a per-error basis (request-base.js:194-203). The callback receives the error and response, and can return true (force retry), false (prevent retry), or undefined (use defaults). OCaml library has static retry configuration based on status codes and methods only.", 24 - "affected_files": [ 25 - "lib/retry.mli", 26 - "lib/retry.ml" 27 - ], 28 - "rationale": "Dynamic retry decisions enable more sophisticated retry strategies. For example, a user might want to retry only if a specific error message appears in the response body, or retry based on custom headers, or implement different backoff for different error types. Implementation could add an optional 'retry_callback: (exn -> Response.t option -> [`Retry | `No_retry | `Use_default])' field to the retry config, allowing users to inspect both the exception and partial response (if available) to make informed retry decisions." 29 - }, 30 - { 31 - "source_repo": "third_party/javascript/superagent", 32 - "source_language": "JavaScript", 33 - "criticality": "medium", 34 - "change_type": "enhancement", 35 - "title": "Add abort/cancellation support for in-flight requests", 36 - "description": "SuperAgent provides explicit request abortion via the .abort() method (request-base.js:474-488), which cancels in-flight requests, clears timeouts, emits an 'abort' event, and returns immediately. OCaml library relies on switch cancellation but doesn't provide explicit request-level cancellation API.", 37 - "affected_files": [ 38 - "lib/requests.mli", 39 - "lib/one.mli", 40 - "lib/http_client.ml" 41 - ], 42 - "rationale": "Request abortion is critical for responsive applications. Users may need to cancel requests when user navigates away, search queries change, or resource constraints require cleanup. While Eio switches provide cancellation, a request-level abort API would be more ergonomic and provide better control. Implementation could return a cancellation handle from request functions, allowing users to call 'cancel handle' to abort specific requests without canceling the entire switch. This would be implemented using Eio.Cancel.sub to create a sub-cancellation context for each request." 43 - }, 44 - { 45 - "source_repo": "third_party/javascript/superagent", 46 - "source_language": "JavaScript", 47 - "criticality": "low", 48 - "change_type": "enhancement", 49 - "title": "Add Link header parsing utility", 50 - "description": "SuperAgent includes a parseLinks utility (utils.js:41-51 and response-base.js) that automatically parses RFC 8288 Link headers into a structured object mapping relation types to URLs. This is commonly used for pagination (next/prev/first/last links) in REST APIs. OCaml library has no Link header parsing support.", 51 - "affected_files": [ 52 - "lib/response.mli", 53 - "lib/response.ml", 54 - "lib/headers.mli", 55 - "lib/headers.ml" 56 - ], 57 - "rationale": "Link header parsing is a common need for REST API clients, especially for paginated resources. GitHub, GitLab, and many other APIs use Link headers for pagination. Implementation would add 'val links : t -> (string * string) list' to Response module, returning a list of (rel, url) pairs parsed from the Link header. This eliminates the need for every user to parse Link headers manually and reduces the risk of parsing errors." 58 - }, 59 - { 60 - "source_repo": "third_party/javascript/superagent", 61 - "source_language": "JavaScript", 62 - "criticality": "high", 63 - "change_type": "security", 64 - "title": "Implement cross-origin header sanitization on redirects", 65 - "description": "SuperAgent automatically removes sensitive headers (Authorization, Cookie) when a redirect changes origin (utils.js:61-73, node/index.js:514-520). It also removes Content-Type, Content-Length, and Transfer-Encoding headers. OCaml library should verify it implements similar security measures to prevent credential leakage across domains during redirects.", 66 - "affected_files": [ 67 - "lib/requests.ml", 68 - "lib/one.ml", 69 - "lib/http_client.ml" 70 - ], 71 - "rationale": "This is a critical security issue. Without cross-origin header sanitization, authentication credentials and cookies could be leaked to untrusted domains during redirects. For example, if example.com redirects to malicious.com, the Authorization header should not be forwarded. Implementation should detect origin changes during redirects (comparing host and port) and strip sensitive headers (Authorization, Cookie, Set-Cookie, X-API-Key, api-key, Proxy-Authorization) plus content-related headers when origin changes. The OCaml library already has header sanitization in Error module but needs to verify it's applied during redirects." 72 - }, 73 - { 74 - "source_repo": "third_party/javascript/superagent", 75 - "source_language": "JavaScript", 76 - "criticality": "medium", 77 - "change_type": "enhancement", 78 - "title": "Add custom OK callback for response validation", 79 - "description": "SuperAgent provides a .ok(callback) method (request-base.js:306-322) that allows users to customize what constitutes a successful response beyond the default 2xx check. The callback receives the response and returns true for success. This enables custom validation logic like accepting 404 as OK for certain endpoints.", 80 - "affected_files": [ 81 - "lib/requests.mli", 82 - "lib/one.mli", 83 - "lib/response.mli" 84 - ], 85 - "rationale": "Different APIs have different success criteria. Some APIs return 404 for 'not found' but consider it a valid response, not an error. Some return 304 for cache hits. Custom OK callbacks allow users to define success criteria per-request rather than always checking status codes manually. Implementation would add an optional 'ok_callback: (Response.t -> bool)' parameter to request functions, which when provided overrides the default 'status >= 200 && status < 300' check. This integrates with error handling and retry logic." 86 - }, 87 - { 88 - "source_repo": "third_party/javascript/superagent", 89 - "source_language": "JavaScript", 90 - "criticality": "low", 91 - "change_type": "enhancement", 92 - "title": "Add query string sorting support", 93 - "description": "SuperAgent provides .sortQuery() method (request-base.js:698-730) to sort query string parameters alphabetically or with a custom function. This is useful for consistent URL generation, caching, and testing. OCaml library builds query strings but doesn't offer sorting.", 94 - "affected_files": [ 95 - "lib/requests.mli", 96 - "lib/one.mli", 97 - "lib/http_client.ml" 98 - ], 99 - "rationale": "Query string ordering can affect caching, testing, and debugging. Sorted query strings produce consistent URLs which helps with HTTP caching (same URL = cache hit), API testing (predictable URLs), and debugging (easier to compare URLs). Implementation would add an optional 'sort_query: bool' or 'sort_query: ((string * string) -> (string * string) -> int) option' parameter to request functions. When enabled, query parameters would be sorted before URL construction." 100 - }, 101 - { 102 - "source_repo": "third_party/javascript/superagent", 103 - "source_language": "JavaScript", 104 - "criticality": "medium", 105 - "change_type": "feature", 106 - "title": "Add plugin/middleware system for request modification", 107 - "description": "SuperAgent provides a .use(fn) plugin system (request-base.js:301-304) that allows users to inject middleware functions that can modify requests before they're sent. Plugins receive the request object and can add headers, modify bodies, add event listeners, etc. This enables composable request transformation.", 108 - "affected_files": [ 109 - "lib/requests.mli", 110 - "lib/one.mli" 111 - ], 112 - "rationale": "A plugin system enables code reuse and composition. Users can create reusable plugins for common patterns like adding API keys, logging requests, retrying with exponential backoff, caching responses, etc. Without plugins, users must duplicate code across requests or create wrapper functions. Implementation in OCaml could use a functional approach: add 'plugins: (Request_builder.t -> Request_builder.t) list' field, where each plugin function receives and returns a request builder, allowing transformations to be composed via function application." 113 - }, 114 - { 115 - "source_repo": "third_party/javascript/superagent", 116 - "source_language": "JavaScript", 117 - "criticality": "low", 118 - "change_type": "enhancement", 119 - "title": "Add .unset() method to remove headers", 120 - "description": "SuperAgent provides .unset(field) method (request-base.js:398-402) to explicitly remove headers from a request. This is useful when inheriting headers from a session but needing to remove specific ones for certain requests. OCaml library can set headers but has no explicit removal API in the request interface.", 121 - "affected_files": [ 122 - "lib/headers.mli", 123 - "lib/headers.ml", 124 - "lib/requests.mli" 125 - ], 126 - "rationale": "Header removal is important for fine-grained control, especially with session-based APIs where default headers are set but certain requests shouldn't include them. For example, a session might set 'Authorization' by default, but a public endpoint shouldn't send it. Implementation would add 'val remove : t -> string -> t' to Headers module (which may already exist) and ensure it's easily accessible in the request API, either via Headers manipulation or a convenience parameter in request functions." 127 - }, 128 - { 129 - "source_repo": "third_party/javascript/superagent", 130 - "source_language": "JavaScript", 131 - "criticality": "medium", 132 - "change_type": "enhancement", 133 - "title": "Add progress event support for uploads and downloads", 134 - "description": "SuperAgent emits 'progress' events during uploads and downloads (node/index.js:1222-1240) with information about bytes loaded, total bytes, and direction. This enables progress bars and bandwidth monitoring. OCaml library supports streaming but doesn't provide progress callbacks.", 135 - "affected_files": [ 136 - "lib/requests.mli", 137 - "lib/one.mli", 138 - "lib/http_client.ml", 139 - "lib/body.mli" 140 - ], 141 - "rationale": "Progress tracking is essential for good UX with large transfers. Users expect progress bars for file uploads/downloads. Progress events enable monitoring bandwidth usage, estimating time remaining, and providing feedback. Implementation would add optional 'on_upload_progress: (int64 -> int64 option -> unit)' and 'on_download_progress: (int64 -> int64 option -> unit)' callbacks to request functions. Parameters would be (bytes_transferred, total_bytes_opt). Callbacks would be invoked periodically during body streaming." 142 - }, 143 - { 144 - "source_repo": "third_party/javascript/superagent", 145 - "source_language": "JavaScript", 146 - "criticality": "medium", 147 - "change_type": "enhancement", 148 - "title": "Add custom DNS override/connect override for testing", 149 - "description": "SuperAgent provides .connect() method (node/index.js:1314-1324) that allows overriding DNS resolution for specific hostnames, mapping them to custom IP addresses. This is useful for testing against staging servers, localhost, or bypassing DNS. OCaml library has no equivalent feature.", 150 - "affected_files": [ 151 - "lib/requests.mli", 152 - "lib/one.mli", 153 - "lib/http_client.ml" 154 - ], 155 - "rationale": "DNS override is valuable for testing and development. It allows testing against staging servers without modifying /etc/hosts, testing HTTPS against localhost with proper SNI, and working around DNS issues. SuperAgent's implementation (node/index.js:719-750) overrides the host in the URL while preserving the Host header. Implementation in OCaml could add 'dns_override: (string * (string * int option)) list' parameter, mapping hostnames to (ip, port_opt) pairs. This would modify connection establishment in http_client.ml." 156 - }, 157 - { 158 - "source_repo": "third_party/javascript/superagent", 159 - "source_language": "JavaScript", 160 - "criticality": "low", 161 - "change_type": "enhancement", 162 - "title": "Add custom serializer/parser registration system", 163 - "description": "SuperAgent allows global registration of custom serializers (node/index.js:101-106) and parsers (node/index.js:117) for specific MIME types. Users can also override per-request with .serialize(fn) and .parse(fn) methods. This enables handling custom formats beyond JSON/form data.", 164 - "affected_files": [ 165 - "lib/body.mli", 166 - "lib/body.ml", 167 - "lib/response.mli", 168 - "lib/response.ml" 169 - ], 170 - "rationale": "Extensible serialization/parsing enables support for custom data formats (MessagePack, Protocol Buffers, XML, YAML, etc.) without modifying library code. Per-request overrides provide flexibility for special cases. Implementation could add 'val register_serializer : mime:string -> (t -> string) -> unit' and 'val register_parser : mime:string -> (string -> t) -> unit' module-level functions, plus per-request 'serialize' and 'parse' optional parameters that override defaults." 171 - }, 172 - { 173 - "source_repo": "third_party/javascript/superagent", 174 - "source_language": "JavaScript", 175 - "criticality": "high", 176 - "change_type": "bug", 177 - "title": "Add protection against multiple .end() calls", 178 - "description": "SuperAgent explicitly prevents calling .end() multiple times on the same request (node/index.js:968-972), throwing an error if attempted. This prevents subtle bugs from accidentally sending requests twice. OCaml library should verify it has similar protection.", 179 - "affected_files": [ 180 - "lib/requests.ml", 181 - "lib/one.ml", 182 - "lib/http_client.ml" 183 - ], 184 - "rationale": "Allowing duplicate request execution can cause serious bugs: duplicate payments, double-counting metrics, resource leaks, etc. SuperAgent considers this important enough to explicitly prevent it. OCaml's functional style may naturally prevent this (requests are immutable), but if there's any mutable request state or if the same request builder can be executed multiple times, protection is needed. Implementation would track whether a request has been sent (using a mutable flag or atomic reference) and raise an error on subsequent attempts." 185 - }, 186 - { 187 - "source_repo": "third_party/javascript/superagent", 188 - "source_language": "JavaScript", 189 - "criticality": "medium", 190 - "change_type": "enhancement", 191 - "title": "Add .trustLocalhost() convenience for development", 192 - "description": "SuperAgent provides .trustLocalhost() method (node/index.js:1326-1329) that disables TLS certificate verification for localhost and 127.0.0.1 addresses. This is a convenience for local development with self-signed certificates. OCaml library has verify_tls flag but no localhost-specific exception.", 193 - "affected_files": [ 194 - "lib/requests.mli", 195 - "lib/one.mli", 196 - "lib/http_client.ml" 197 - ], 198 - "rationale": "Local development often uses self-signed certificates. Disabling TLS verification globally is dangerous, but localhost-only exception is safe and convenient. Implementation would add 'trust_localhost: bool' parameter (default false). When true, TLS verification would be disabled only for connections to localhost, 127.0.0.1, ::1, and similar loopback addresses. This improves developer experience while maintaining security for production hosts." 199 - }, 200 - { 201 - "source_repo": "third_party/javascript/superagent", 202 - "source_language": "JavaScript", 203 - "criticality": "low", 204 - "change_type": "enhancement", 205 - "title": "Add Unix domain socket support", 206 - "description": "SuperAgent supports Unix domain sockets via http+unix:// and https+unix:// URL schemes (node/index.js:708-716). This allows HTTP clients to connect to servers listening on Unix sockets, common for Docker APIs and local services. OCaml library uses standard TCP/TLS networking.", 207 - "affected_files": [ 208 - "lib/http_client.ml", 209 - "lib/one.ml" 210 - ], 211 - "rationale": "Unix socket support enables communication with containerized services (Docker API), systemd services, and other local HTTP servers that use sockets instead of TCP. This is especially useful for improved performance and security when client and server are on the same machine. Implementation would parse http+unix:// and https+unix:// schemes, extract socket path from URL-encoded hostname, and use Eio's Unix socket support instead of TCP connection. Format: http+unix://%2Fvar%2Frun%2Fdocker.sock/v1.41/containers/json" 212 - }, 213 - { 214 - "source_repo": "third_party/javascript/superagent", 215 - "source_language": "JavaScript", 216 - "criticality": "low", 217 - "change_type": "enhancement", 218 - "title": "Add redirect event emission for tracking redirect chain", 219 - "description": "SuperAgent emits a 'redirect' event whenever a redirect occurs (node/index.js:958-962), allowing users to observe the redirect chain. The OCaml library stores redirect list internally but doesn't expose it via callbacks/events during request execution.", 220 - "affected_files": [ 221 - "lib/requests.mli", 222 - "lib/one.mli", 223 - "lib/response.mli" 224 - ], 225 - "rationale": "Observing redirects in real-time is useful for debugging, logging, and analytics. Users may want to log each redirect, track redirect performance, or make decisions based on redirect patterns. Implementation could add an optional 'on_redirect: (Response.t -> unit)' callback parameter that's invoked each time a redirect is followed, passing the intermediate response. The final response would still include the complete redirect history in its redirect_chain field." 226 - }, 227 - { 228 - "source_repo": "third_party/javascript/superagent", 229 - "source_language": "JavaScript", 230 - "criticality": "low", 231 - "change_type": "refactor", 232 - "title": "Consider adding response sugar properties for common status checks", 233 - "description": "SuperAgent's response includes convenience properties like .ok, .badRequest, .unauthorized, .notFound, .forbidden, .noContent, .created, etc. (response-base.js) for common status code checks. OCaml library has Response.ok but no other convenience functions.", 234 - "affected_files": [ 235 - "lib/response.mli", 236 - "lib/response.ml" 237 - ], 238 - "rationale": "Convenience properties improve code readability. 'if response.unauthorized' reads better than 'if response.status_code = 401'. While this is sugar over status code comparisons, it makes common patterns more expressive and less error-prone. Implementation would add functions: 'val created : t -> bool', 'val no_content : t -> bool', 'val bad_request : t -> bool', 'val unauthorized : t -> bool', 'val forbidden : t -> bool', 'val not_found : t -> bool', 'val server_error : t -> bool', etc. These are simple wrappers around status_code checks." 239 - }, 240 - { 241 - "source_repo": "third_party/javascript/superagent", 242 - "source_language": "JavaScript", 243 - "criticality": "medium", 244 - "change_type": "enhancement", 245 - "title": "Improve error metadata with retry count and request details", 246 - "description": "SuperAgent includes retry count in error objects (node/index.js:896) and attaches the response object to errors (node/index.js:895). This provides better context for error handling. OCaml library's Error module has comprehensive error types but could expose retry metadata.", 247 - "affected_files": [ 248 - "lib/error.mli", 249 - "lib/error.ml", 250 - "lib/retry.ml" 251 - ], 252 - "rationale": "Knowing how many retries were attempted helps with debugging and metrics. Attaching partial responses to errors allows inspection of server error messages even when the request failed. Implementation would extend error variants to include 'retries_attempted: int option' field where applicable, and potentially 'partial_response: Response.t option' for HTTP errors. This requires threading retry state through the error construction path." 253 - } 254 - ] 255 - }
-161
third_party/php/buzz.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/php/buzz", 5 - "source_language": "PHP", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Request/Response Middleware Chain Support", 9 - "description": "Implement a middleware chain pattern that allows request and response interception. Buzz provides a bidirectional middleware system where middleware can modify requests before sending and responses after receiving. This enables modular features like logging, metrics collection, custom authentication, request/response transformation, and debugging without modifying core client code.", 10 - "affected_files": [ 11 - "lib/requests.mli", 12 - "lib/requests.ml", 13 - "lib/one.mli", 14 - "lib/one.ml" 15 - ], 16 - "rationale": "The OCaml library currently lacks a mechanism for request/response interception. Buzz's middleware pattern (Browser.php:146-194) demonstrates how to build extensible HTTP clients where cross-cutting concerns are handled declaratively. This would enable users to add timing instrumentation, custom retry logic, request modification, response caching, and other features without forking the library. The middleware chain executes bidirectionally: request flows through middleware1 → middleware2 → client, then response flows back client → middleware2 → middleware1. This pattern is particularly valuable in OCaml where users could implement type-safe middleware using first-class modules or functors." 17 - }, 18 - { 19 - "source_repo": "third_party/php/buzz", 20 - "source_language": "PHP", 21 - "criticality": "low", 22 - "change_type": "feature", 23 - "title": "Request/Response History Tracking for Debugging", 24 - "description": "Add optional request/response history tracking to capture the last N requests and responses for debugging purposes. Buzz provides getLastRequest()/getLastResponse() methods (Browser.php:196-204) and a HistoryMiddleware with Journal (HistoryMiddleware.php:11-40) that records requests, responses, and timing information. This is invaluable for debugging, testing, and monitoring.", 25 - "affected_files": [ 26 - "lib/requests.mli", 27 - "lib/requests.ml" 28 - ], 29 - "rationale": "The OCaml library provides no built-in way to inspect the last request or capture request history for debugging. This makes troubleshooting difficult, especially when requests fail intermittently or when testing interactions. Buzz's approach stores request/response pairs with elapsed time (HistoryMiddleware.php:29-36), allowing developers to inspect exactly what was sent and received. This would be particularly useful in OCaml for REPL-based debugging and integration testing. Implementation could use a bounded queue or circular buffer to prevent memory leaks, with configurable limits (e.g., last 10 requests)." 30 - }, 31 - { 32 - "source_repo": "third_party/php/buzz", 33 - "source_language": "PHP", 34 - "criticality": "medium", 35 - "change_type": "feature", 36 - "title": "Structured Request Timing Instrumentation", 37 - "description": "Add detailed timing instrumentation that tracks request execution time at various stages (DNS resolution, connection establishment, TLS handshake, time to first byte, total time). Buzz's LoggerMiddleware (LoggerMiddleware.php:33-43) captures microtime before/after requests and logs the duration. This timing data is essential for performance monitoring and SLA tracking.", 38 - "affected_files": [ 39 - "lib/response.mli", 40 - "lib/response.ml", 41 - "lib/http_client.ml" 42 - ], 43 - "rationale": "While the OCaml library tracks total 'elapsed' time in Response.t (response.mli:179), it doesn't provide granular timing breakdowns for different request phases. Buzz demonstrates the value of timing instrumentation with millisecond precision (LoggerMiddleware.php:42). For production OCaml applications, detailed timing would help identify whether slowness comes from DNS, connection pooling, TLS negotiation, or server processing. This could be implemented by capturing timestamps at key points (dns_start, connect_start, tls_start, send_start, receive_start, end) and exposing them in Response metadata or through a dedicated timing record type." 44 - }, 45 - { 46 - "source_repo": "third_party/php/buzz", 47 - "source_language": "PHP", 48 - "criticality": "low", 49 - "change_type": "enhancement", 50 - "title": "Automatic Content-Type Detection for Request Bodies", 51 - "description": "Implement automatic Content-Type header detection for request bodies when not explicitly provided. Buzz's ContentTypeMiddleware (ContentTypeMiddleware.php:55-78) automatically detects JSON and XML content types by inspecting the request body (with size limits to avoid performance issues on large payloads). It only auto-detects for bodies under 16MB and on seekable streams.", 52 - "affected_files": [ 53 - "lib/body.mli", 54 - "lib/body.ml", 55 - "lib/headers.ml" 56 - ], 57 - "rationale": "The OCaml library requires users to explicitly set Content-Type headers for all request bodies. Buzz's approach (ContentTypeMiddleware.php:68-76) provides intelligent defaults by parsing body content to detect JSON/XML, but only when the header isn't already set, the body is under the size limit (default 16MB), and the stream is seekable. This reduces boilerplate for common cases while allowing manual override. In OCaml, this could be implemented as an optional feature during Body construction: detect JSON by checking if the string starts with '{' or '[' and is valid JSON, detect XML by checking for '<' prefix. The size limit prevents expensive parsing on large files." 58 - }, 59 - { 60 - "source_repo": "third_party/php/buzz", 61 - "source_language": "PHP", 62 - "criticality": "high", 63 - "change_type": "security", 64 - "title": "Curl Handle Connection Pooling to Prevent Resource Leaks", 65 - "description": "Implement proper cleanup and reuse of underlying HTTP connection handles to prevent resource exhaustion. Buzz's AbstractCurl (AbstractCurl.php:43-77) maintains a pool of curl handles (max 5 by default) and properly cleans up callback functions before reusing handles. The releaseHandle() method explicitly removes CURLOPT_HEADERFUNCTION, CURLOPT_READFUNCTION, CURLOPT_WRITEFUNCTION, and CURLOPT_PROGRESSFUNCTION callbacks that can hold references and prevent garbage collection.", 66 - "affected_files": [ 67 - "lib/http_client.ml", 68 - "conpool/lib/conpool.ml" 69 - ], 70 - "rationale": "The OCaml library uses Conpool for connection pooling but may not be properly cleaning up all resources associated with connections, particularly callback closures that could hold references. Buzz's implementation (AbstractCurl.php:58-76) demonstrates that simply calling curl_reset() isn't sufficient - callback functions must be explicitly removed because they can hold onto references and prevent cleanup even after curl_reset(). In OCaml with Eio, similar issues can occur with flow callbacks, switch-managed resources, and TLS session caches. The pool should explicitly clear all callbacks and ensure switches are properly canceled before returning connections to the pool. The max handle count (default 5 in Buzz) prevents unbounded pool growth." 71 - }, 72 - { 73 - "source_repo": "third_party/php/buzz", 74 - "source_language": "PHP", 75 - "criticality": "medium", 76 - "change_type": "security", 77 - "title": "HTTP Protocol Restriction to Prevent Protocol Smuggling", 78 - "description": "Restrict allowed protocols to only HTTP and HTTPS to prevent protocol smuggling attacks. Buzz's AbstractCurl (AbstractCurl.php:86-89) explicitly sets CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS to only allow CURLPROTO_HTTP and CURLPROTO_HTTPS, preventing attacks where user-controlled URLs could trigger file://, ftp://, gopher://, or other protocol handlers.", 79 - "affected_files": [ 80 - "lib/http_client.ml", 81 - "lib/one.ml" 82 - ], 83 - "rationale": "The OCaml library doesn't appear to restrict protocols when parsing URLs. Buzz demonstrates a critical security practice (AbstractCurl.php:86-89) by explicitly whitelisting allowed protocols. Without this protection, an attacker who can control URLs (e.g., via redirects or user input) could potentially access local files (file:// URLs) or trigger other unintended protocol handlers. In OCaml, this should be implemented in URL parsing/validation: reject any URL scheme other than 'http' and 'https' before attempting connections. This is especially important when following redirects, where a malicious server could redirect to file://etc/passwd or similar." 84 - }, 85 - { 86 - "source_repo": "third_party/php/buzz", 87 - "source_language": "PHP", 88 - "criticality": "medium", 89 - "change_type": "enhancement", 90 - "title": "Smart Body Size Threshold for Upload Strategy Selection", 91 - "description": "Implement automatic selection between in-memory and streaming upload strategies based on body size. Buzz's AbstractCurl (AbstractCurl.php:168-180) uses a 1MB threshold: bodies larger than 1MB use CURLOPT_UPLOAD with CURLOPT_READFUNCTION for streaming, while smaller bodies use CURLOPT_POSTFIELDS to load into memory. This prevents memory exhaustion on large uploads while optimizing performance for small payloads.", 92 - "affected_files": [ 93 - "lib/body.ml", 94 - "lib/http_write.ml" 95 - ], 96 - "rationale": "The OCaml library handles streaming bodies but doesn't automatically optimize based on size. Buzz's approach (AbstractCurl.php:162-181) shows that the strategy should depend on body size: small bodies (<1MB) benefit from in-memory buffering (simpler, faster), while large bodies need streaming to avoid memory issues. For unknown-size bodies (streaming without Content-Length), streaming is always used. In OCaml, this could be implemented in Body.ml by checking the body size: if Body.content_length returns Some length && length < 1_048_576L, materialize to string and use Content-Length; otherwise use chunked transfer encoding with streaming. This optimization is particularly important for APIs that handle both small JSON payloads and large file uploads." 97 - }, 98 - { 99 - "source_repo": "third_party/php/buzz", 100 - "source_language": "PHP", 101 - "criticality": "low", 102 - "change_type": "enhancement", 103 - "title": "Cookie Jar Hash-based Deduplication Strategy", 104 - "description": "Implement hash-based cookie deduplication in the cookie jar to handle cookie updates efficiently. Buzz's CookieJar (CookieJar.php:95-103) uses a SHA1 hash of (name, domain, path) as the cookie identifier, allowing new Set-Cookie headers with the same identity to replace old values automatically. This prevents duplicate cookies and correctly implements RFC 6265 cookie replacement semantics.", 105 - "affected_files": [ 106 - "cookeio/lib/cookeio_jar.ml" 107 - ], 108 - "rationale": "The OCaml library's cookie jar implementation should follow Buzz's pattern (CookieJar.php:41, 95-103) of using a hash-based identifier for cookie deduplication. When a server sends multiple Set-Cookie headers with the same name, domain, and path, only the latest should be retained. Buzz uses sha1(sprintf('%s|%s|%s', name, domain, path)) as the key, ensuring O(1) cookie replacement. In OCaml, this could be implemented as a Hashtbl with a composite key type `(name * domain * path)` or a hash function over these three fields. This is important for correctly handling session cookies, authentication cookies, and preference updates that may change over the session lifetime." 109 - }, 110 - { 111 - "source_repo": "third_party/php/buzz", 112 - "source_language": "PHP", 113 - "criticality": "low", 114 - "change_type": "enhancement", 115 - "title": "Periodic Cookie Expiration Cleanup", 116 - "description": "Add a method to periodically remove expired cookies from the cookie jar to prevent unbounded memory growth. Buzz's CookieJar provides clearExpiredCookies() (CookieJar.php:78-89) which iterates through all cookies, checks expiration, and rebuilds the jar without expired entries. This prevents memory leaks in long-running applications.", 117 - "affected_files": [ 118 - "cookeio/lib/cookeio_jar.ml", 119 - "cookeio/lib/cookeio_jar.mli" 120 - ], 121 - "rationale": "The OCaml cookie jar likely accumulates expired cookies over time without cleanup. Buzz's approach (CookieJar.php:78-89) demonstrates the need for explicit expiration checking: iterate through cookies, test cookie.isExpired(), and remove expired entries. This is critical for long-running applications (servers, daemons) that make many requests over time - expired cookies consume memory indefinitely without cleanup. In OCaml, implement a `Cookeio_jar.clear_expired : jar -> unit` function that filters the cookie storage. Consider calling this automatically during `processSetCookieHeaders` or periodically (e.g., every 100 requests) to balance overhead with memory efficiency." 122 - }, 123 - { 124 - "source_repo": "third_party/php/buzz", 125 - "source_language": "PHP", 126 - "criticality": "medium", 127 - "change_type": "feature", 128 - "title": "Flexible Callback-based Middleware for Custom Logic", 129 - "description": "Provide a simple callback-based middleware mechanism for users who need custom request/response modification without implementing a full middleware interface. Buzz's CallbackMiddleware (CallbackMiddleware.php:14-56) accepts a callable that receives the request in handleRequest() and both request/response in handleResponse(), enabling quick custom logic injection.", 130 - "affected_files": [ 131 - "lib/requests.mli", 132 - "lib/requests.ml" 133 - ], 134 - "rationale": "If implementing the full middleware chain (Recommendation #1), also provide a simple callback-based middleware like Buzz's CallbackMiddleware (CallbackMiddleware.php:34-56). This lowers the barrier for users who need simple modifications: the callable receives request before sending and (request, response) after receiving. In OCaml, this would be: `type middleware_callback = request -> response option -> (request * response option)`. Users can quickly add logging, inject headers, or modify responses without defining a module. This is particularly useful for one-off customizations, debugging, and testing. Example: `Requests.add_middleware req (fun r resp -> match resp with None -> log_request r; (r, None) | Some rsp -> log_response rsp; (r, Some rsp))`." 135 - }, 136 - { 137 - "source_repo": "third_party/php/buzz", 138 - "source_language": "PHP", 139 - "criticality": "low", 140 - "change_type": "enhancement", 141 - "title": "Safe Mode and open_basedir Redirect Detection", 142 - "description": "Detect PHP safe_mode and open_basedir restrictions that prevent automatic redirect following and fail gracefully or warn the user. Buzz's AbstractCurl (AbstractCurl.php:196-198) checks ini_get('safe_mode') and ini_get('open_basedir') before enabling CURLOPT_FOLLOWLOCATION, because these PHP security restrictions prevent libcurl from following redirects automatically.", 143 - "affected_files": [ 144 - "lib/http_client.ml" 145 - ], 146 - "rationale": "While this is PHP-specific, the underlying principle applies to OCaml: detect runtime restrictions that would prevent redirect following and handle gracefully. In OCaml, equivalent restrictions might come from sandboxing (seccomp, landlock), container network policies, or firewall rules. The library should detect these conditions early and either: (1) fall back to manual redirect handling, (2) raise a clear error message explaining why redirects can't be followed, or (3) provide a warning. Buzz's approach (AbstractCurl.php:196) shows defensive programming: test for restrictions before enabling features. In OCaml, this might mean catching Eio exceptions during redirect attempts and providing better error messages than generic 'connection refused'." 147 - }, 148 - { 149 - "source_repo": "third_party/php/buzz", 150 - "source_language": "PHP", 151 - "criticality": "high", 152 - "change_type": "bug", 153 - "title": "Proper HTTP Response Header Parsing for Redirects", 154 - "description": "Fix HTTP response header parsing to correctly handle multiple HTTP status lines that can occur during redirects. Buzz's FileGetContents client (FileGetContents.php:80-92) filters headers by resetting the array when it encounters a new 'HTTP/' status line, because PHP's file_get_contents() includes all intermediate redirect responses in $http_response_header. Only the final response headers should be returned.", 155 - "affected_files": [ 156 - "lib/http_read.ml" 157 - ], 158 - "rationale": "When following redirects, the HTTP response may contain multiple status lines (one per redirect hop). Buzz's filterHeaders() method (FileGetContents.php:80-92) shows the correct handling: reset the headers array whenever a new 'HTTP/' line is encountered (line 85). Without this, the client would return a mix of headers from intermediate and final responses, leading to incorrect Content-Length, Content-Type, cookies, and other critical headers. The OCaml library should verify that its HTTP parser (http_read.ml) correctly handles this case: when reading responses with redirects, only parse headers from the final status line, not intermediate ones. This is especially important when using manual redirect following (follow_redirects=false) where users expect clean headers from each response." 159 - } 160 - ] 161 - }
-286
third_party/php/guzzle.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/php/guzzle", 5 - "source_language": "PHP", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add Mock Handler for Testing", 9 - "description": "Implement a mock handler similar to Guzzle's MockHandler that allows queuing pre-defined responses and exceptions for testing. This would enable testing HTTP clients without making actual network requests. The mock handler should support: (1) queue-based response/exception returning, (2) inspection of last request/options sent, (3) ability to append new responses/exceptions to the queue.", 10 - "affected_files": [ 11 - "lib/http_client.ml", 12 - "test/test_one.ml" 13 - ], 14 - "rationale": "Guzzle provides MockHandler (src/Handler/MockHandler.php) that queues responses/exceptions and allows inspection of requests, making it easy to test HTTP client logic without network calls. The OCaml library currently lacks a built-in mocking facility, forcing tests to rely on real HTTP servers (httpbin.org in cram tests). A mock handler would enable faster, more reliable unit tests that don't depend on external services, and would allow testing edge cases (connection failures, timeouts, malformed responses) more easily." 15 - }, 16 - { 17 - "source_repo": "third_party/php/guzzle", 18 - "source_language": "PHP", 19 - "criticality": "low", 20 - "change_type": "enhancement", 21 - "title": "Add Transfer Statistics Callback", 22 - "description": "Add an optional 'on_stats' callback to request configuration that provides detailed transfer statistics after request completion. Statistics should include: total transfer time, DNS lookup time, connection time, TLS handshake time, time to first byte, upload/download sizes, and any handler-specific timing data. This would mirror Guzzle's TransferStats functionality.", 23 - "affected_files": [ 24 - "lib/requests.mli", 25 - "lib/one.mli", 26 - "lib/http_client.ml" 27 - ], 28 - "rationale": "Guzzle provides TransferStats (src/TransferStats.php) accessible via 'on_stats' callback, which gives detailed performance metrics including DNS lookup time, connection time, TLS handshake time, and time to first byte. This is valuable for performance debugging, monitoring, and observability. The OCaml library currently doesn't expose these granular timing metrics, making it harder to diagnose performance issues or understand where time is spent in requests." 29 - }, 30 - { 31 - "source_repo": "third_party/php/guzzle", 32 - "source_language": "PHP", 33 - "criticality": "medium", 34 - "change_type": "feature", 35 - "title": "Add Progress Callback for Upload/Download Tracking", 36 - "description": "Implement optional 'on_progress' callbacks for tracking upload and download progress in real-time. The callback should receive: (1) total bytes expected (if known), (2) bytes transferred so far, (3) direction (upload/download). This enables progress bars, bandwidth throttling, and transfer monitoring.", 37 - "affected_files": [ 38 - "lib/requests.mli", 39 - "lib/one.mli", 40 - "lib/http_client.ml", 41 - "lib/body.ml" 42 - ], 43 - "rationale": "Guzzle supports 'progress' option (RequestOptions::PROGRESS) that provides callbacks during upload/download with bytes transferred. This is essential for building progress indicators for large file transfers, implementing bandwidth throttling, or monitoring transfer rates. The OCaml library currently provides no way to track progress of ongoing transfers, making it difficult to provide user feedback for long-running downloads or uploads." 44 - }, 45 - { 46 - "source_repo": "third_party/php/guzzle", 47 - "source_language": "PHP", 48 - "criticality": "low", 49 - "change_type": "enhancement", 50 - "title": "Add On-Headers Callback for Early Response Inspection", 51 - "description": "Add an optional 'on_headers' callback that fires when response headers are received but before the body is downloaded. This allows early inspection of headers (status code, content-length, content-type) to make decisions about whether to continue downloading the body. The callback should be able to abort the download if needed.", 52 - "affected_files": [ 53 - "lib/requests.mli", 54 - "lib/one.mli", 55 - "lib/http_client.ml" 56 - ], 57 - "rationale": "Guzzle's 'on_headers' callback (RequestOptions::ON_HEADERS) allows inspecting response headers before downloading the body, enabling early abort for unwanted responses (wrong content-type, too large, etc.). This can save significant bandwidth and time for large responses. The OCaml library currently downloads the entire body before user code can inspect headers, which is inefficient when the response should be rejected based on headers alone." 58 - }, 59 - { 60 - "source_repo": "third_party/php/guzzle", 61 - "source_language": "PHP", 62 - "criticality": "medium", 63 - "change_type": "feature", 64 - "title": "Add Middleware/Interceptor System", 65 - "description": "Implement a composable middleware system similar to Guzzle's HandlerStack that allows intercepting and transforming requests/responses. Middleware should be able to: (1) modify requests before sending, (2) modify responses after receiving, (3) implement cross-cutting concerns (logging, metrics, request/response transformation), (4) be composed in a stack with defined ordering.", 66 - "affected_files": [ 67 - "lib/requests.ml", 68 - "lib/requests.mli", 69 - "lib/http_client.ml" 70 - ], 71 - "rationale": "Guzzle's middleware system (src/HandlerStack.php and src/Middleware.php) provides a powerful composition pattern for cross-cutting concerns like logging, metrics collection, request/response transformation, and custom retry logic. The OCaml library currently hard-codes behaviors like retry, redirect following, and authentication into the request flow. A middleware system would allow users to customize the request/response pipeline, implement custom behaviors (e.g., request signing, custom caching, API versioning), and compose third-party middleware without modifying core code." 72 - }, 73 - { 74 - "source_repo": "third_party/php/guzzle", 75 - "source_language": "PHP", 76 - "criticality": "medium", 77 - "change_type": "enhancement", 78 - "title": "Add Request History Tracking", 79 - "description": "Add optional request history tracking that records all requests made, including: original request, final response, any exceptions raised, redirects followed, and retry attempts. This would be configurable per-session and useful for debugging, auditing, and testing. Provide a way to iterate through history entries and extract information.", 80 - "affected_files": [ 81 - "lib/requests.ml", 82 - "lib/requests.mli" 83 - ], 84 - "rationale": "Guzzle provides history middleware (Middleware::history()) that captures request/response pairs in a container for inspection. This is extremely valuable for debugging (seeing exactly what was sent/received), testing (asserting specific requests were made), and auditing (recording all API calls). The OCaml library currently provides no built-in way to track request history, making debugging and testing more difficult. Users have to manually log or track requests if they need this information." 85 - }, 86 - { 87 - "source_repo": "third_party/php/guzzle", 88 - "source_language": "PHP", 89 - "criticality": "low", 90 - "change_type": "enhancement", 91 - "title": "Add Synchronization Option for Request Streams", 92 - "description": "Add a 'synchronous' option to control whether request/response streams should be blocking or non-blocking. When enabled, ensure all stream operations complete before returning to the caller. This mirrors Guzzle's 'synchronous' option and helps ensure predictable behavior in certain scenarios.", 93 - "affected_files": [ 94 - "lib/requests.mli", 95 - "lib/one.mli", 96 - "lib/http_client.ml" 97 - ], 98 - "rationale": "Guzzle supports a 'synchronous' option (RequestOptions::SYNCHRONOUS) that forces all stream operations to be blocking, ensuring predictable behavior. While OCaml's Eio model is inherently structured differently, providing explicit control over stream synchronization behavior could help in scenarios where users need to ensure all data is fully transferred before proceeding. This is particularly useful when working with file uploads/downloads where partial transfers could cause issues." 99 - }, 100 - { 101 - "source_repo": "third_party/php/guzzle", 102 - "source_language": "PHP", 103 - "criticality": "low", 104 - "change_type": "enhancement", 105 - "title": "Add Allow-Redirects Fine-Grained Configuration", 106 - "description": "Extend redirect configuration to support more granular control beyond just max_redirects. Add options for: (1) strict mode (maintain method on 301/302 redirects instead of changing POST to GET), (2) referer header behavior (add/remove/preserve), (3) protocol restrictions (allow/disallow cross-protocol redirects), (4) tracking redirect history in responses.", 107 - "affected_files": [ 108 - "lib/requests.ml", 109 - "lib/requests.mli", 110 - "lib/one.ml" 111 - ], 112 - "rationale": "Guzzle's redirect middleware provides extensive configuration (src/RedirectMiddleware.php): strict mode for method preservation, referer header management, protocol restrictions, and redirect tracking. The OCaml library currently has simple boolean follow_redirects and max_redirects integer, but lacks control over redirect behavior specifics. Fine-grained redirect control is important for security (preventing protocol downgrade), compliance (RFC behavior), and debugging (understanding redirect chains)." 113 - }, 114 - { 115 - "source_repo": "third_party/php/guzzle", 116 - "source_language": "PHP", 117 - "criticality": "medium", 118 - "change_type": "enhancement", 119 - "title": "Add Proxy Support with NO_PROXY", 120 - "description": "Implement HTTP/HTTPS proxy support with configuration options for: (1) proxy URL with optional authentication, (2) per-protocol proxy settings (http_proxy, https_proxy), (3) NO_PROXY environment variable support for bypass patterns, (4) dynamic proxy selection based on target URL. Include both environment variable and programmatic configuration.", 121 - "affected_files": [ 122 - "lib/requests.ml", 123 - "lib/requests.mli", 124 - "lib/one.ml", 125 - "lib/http_client.ml" 126 - ], 127 - "rationale": "Guzzle supports comprehensive proxy configuration (proxy option in RequestOptions.php) including authentication, per-protocol settings, and NO_PROXY patterns. The OCaml library currently has no proxy support, which limits its use in corporate environments where proxies are required, makes it impossible to use for web scraping through proxy services, and prevents testing through debugging proxies like mitmproxy or Charles. Environment variable support (HTTP_PROXY, HTTPS_PROXY, NO_PROXY) is standard in HTTP clients and expected by users." 128 - }, 129 - { 130 - "source_repo": "third_party/php/guzzle", 131 - "source_language": "PHP", 132 - "criticality": "low", 133 - "change_type": "enhancement", 134 - "title": "Add IDN (Internationalized Domain Name) Support", 135 - "description": "Add optional support for converting Internationalized Domain Names (IDN) to ASCII-compatible encoding (Punycode) before making requests. This should be configurable via an 'idn_conversion' option and handle Unicode domain names automatically.", 136 - "affected_files": [ 137 - "lib/requests.ml", 138 - "lib/requests.mli", 139 - "lib/one.ml" 140 - ], 141 - "rationale": "Guzzle supports IDN conversion (idn_conversion option in RequestOptions.php) which automatically converts Unicode domain names to Punycode for DNS resolution. The OCaml library currently doesn't handle IDN domains, which means requests to domains like 'münchen.de' or '日本.jp' may fail. While less common than other features, IDN support is important for international applications and prevents cryptic DNS errors when users provide Unicode domains." 142 - }, 143 - { 144 - "source_repo": "third_party/php/guzzle", 145 - "source_language": "PHP", 146 - "criticality": "low", 147 - "change_type": "enhancement", 148 - "title": "Add Decode-Content Option for Selective Decompression", 149 - "description": "Make the 'auto_decompress' option more granular by adding a 'decode_content' flag that controls: (1) automatic addition of Accept-Encoding header, (2) automatic decompression of response, (3) removal of Content-Encoding/Content-Length headers post-decompression. Currently auto_decompress is somewhat opaque.", 150 - "affected_files": [ 151 - "lib/requests.ml", 152 - "lib/requests.mli", 153 - "lib/one.ml", 154 - "lib/http_client.ml" 155 - ], 156 - "rationale": "Guzzle's 'decode_content' option (RequestOptions::DECODE_CONTENT) provides explicit control over compression negotiation and decompression, including whether to add Accept-Encoding header and whether to decode the response. The OCaml library's 'auto_decompress' is less granular and doesn't give users control over the Accept-Encoding header. More explicit control helps when: (1) testing server compression behavior, (2) implementing custom decompression, (3) preserving original compressed bytes for caching, (4) debugging compression issues." 157 - }, 158 - { 159 - "source_repo": "third_party/php/guzzle", 160 - "source_language": "PHP", 161 - "criticality": "low", 162 - "change_type": "enhancement", 163 - "title": "Add Stream Sink Customization for Response Body", 164 - "description": "Add a 'sink' option to specify where the response body should be written: (1) to a file path (string), (2) to an open file handle/flow, (3) to a custom sink implementation. This avoids buffering large responses in memory when they should be streamed to disk or another destination.", 165 - "affected_files": [ 166 - "lib/requests.mli", 167 - "lib/one.mli", 168 - "lib/response.ml", 169 - "lib/http_client.ml" 170 - ], 171 - "rationale": "Guzzle's 'sink' option (RequestOptions::SINK) allows specifying where the response body is written (file path, resource, PSR-7 stream). The OCaml library has One.download for file downloads, but the main API always returns responses with body streams that must be manually consumed. Adding a sink option to the main API would: (1) simplify download-to-file scenarios, (2) prevent accidental memory exhaustion from forgetting to consume streams, (3) enable piping responses to other destinations (network, compression), (4) match user expectations from other HTTP libraries." 172 - }, 173 - { 174 - "source_repo": "third_party/php/guzzle", 175 - "source_language": "PHP", 176 - "criticality": "medium", 177 - "change_type": "feature", 178 - "title": "Add Request Body Stream Support with Size Hints", 179 - "description": "Enhance body streaming to support: (1) size hints/estimates for unknown-length streams (for progress estimation), (2) read timeouts during streaming, (3) summarization for error messages (first N bytes of stream). Currently the library supports streaming but lacks these ergonomic features.", 180 - "affected_files": [ 181 - "lib/body.ml", 182 - "lib/body.mli", 183 - "lib/http_write.ml" 184 - ], 185 - "rationale": "Guzzle's body handling provides stream size hints, read timeouts, and automatic summarization for debugging. The OCaml library supports streaming bodies but doesn't provide size hints (making progress tracking harder), doesn't have per-read timeouts (only overall request timeout), and doesn't summarize stream bodies in errors (making debugging harder). These features improve the developer experience when working with streams, especially for debugging streaming upload/download issues." 186 - }, 187 - { 188 - "source_repo": "third_party/php/guzzle", 189 - "source_language": "PHP", 190 - "criticality": "low", 191 - "change_type": "enhancement", 192 - "title": "Add Delay Option for Request Throttling", 193 - "description": "Add a 'delay' option that specifies milliseconds to sleep before sending the request. This is useful for rate limiting, implementing backoff strategies externally, or testing timeout behavior. The delay should be applied after request is prepared but before network call.", 194 - "affected_files": [ 195 - "lib/requests.mli", 196 - "lib/one.mli", 197 - "lib/http_client.ml" 198 - ], 199 - "rationale": "Guzzle supports 'delay' option (RequestOptions::DELAY) that sleeps before sending the request, which is useful for rate limiting, testing, and implementing custom backoff. The OCaml library currently doesn't provide built-in request delay, requiring users to manually call sleep before each request. While simple to implement externally, having it as a built-in option: (1) makes rate limiting more declarative, (2) works better with retry middleware (if implemented), (3) ensures delay is applied consistently, (4) improves testability." 200 - }, 201 - { 202 - "source_repo": "third_party/php/guzzle", 203 - "source_language": "PHP", 204 - "criticality": "low", 205 - "change_type": "enhancement", 206 - "title": "Add Version Option for HTTP Protocol Selection", 207 - "description": "Add a 'version' option to explicitly specify the HTTP protocol version to use (1.0, 1.1, 2.0). Currently the library only supports HTTP/1.1. This would require underlying transport layer support but the API should expose the option for future HTTP/2 support.", 208 - "affected_files": [ 209 - "lib/requests.mli", 210 - "lib/one.mli", 211 - "lib/http_client.ml" 212 - ], 213 - "rationale": "Guzzle supports 'version' option (RequestOptions::VERSION) to specify HTTP protocol version. While the OCaml library currently only implements HTTP/1.1, exposing a version option in the API would: (1) prepare the API for future HTTP/2 or HTTP/3 support, (2) allow testing against servers that only support HTTP/1.0, (3) make the protocol version explicit rather than implicit, (4) enable potential fallback strategies when adding newer protocol support." 214 - }, 215 - { 216 - "source_repo": "third_party/php/guzzle", 217 - "source_language": "PHP", 218 - "criticality": "low", 219 - "change_type": "enhancement", 220 - "title": "Add Force-IP-Resolve Option for IPv4/IPv6 Selection", 221 - "description": "Add a 'force_ip_resolve' option to force DNS resolution to either IPv4 or IPv6. This is useful for: (1) testing IPv6 connectivity, (2) working around broken IPv6 configurations, (3) ensuring consistent behavior across environments. Options should be: v4, v6, or auto (default).", 222 - "affected_files": [ 223 - "lib/requests.mli", 224 - "lib/one.mli", 225 - "lib/http_client.ml" 226 - ], 227 - "rationale": "Guzzle supports 'force_ip_resolve' option that restricts DNS resolution to v4 or v6. The OCaml library relies on Eio.Net.t for DNS resolution and doesn't provide control over IP version selection. While this requires underlying network stack support, exposing the option would help users: (1) diagnose IPv6 connectivity issues, (2) work around broken dual-stack configurations, (3) test IPv4/IPv6 specific scenarios, (4) ensure consistent behavior in dual-stack environments where resolution order may vary." 228 - }, 229 - { 230 - "source_repo": "third_party/php/guzzle", 231 - "source_language": "PHP", 232 - "criticality": "medium", 233 - "change_type": "enhancement", 234 - "title": "Improve Error Context with Handler Error Data", 235 - "description": "Enhance error types to include handler-specific error context such as: (1) errno codes from underlying transport (e.g., curl errno), (2) low-level error messages from network stack, (3) timing information when error occurred, (4) connection reuse status. This helps diagnose transient network issues vs persistent problems.", 236 - "affected_files": [ 237 - "lib/error.ml", 238 - "lib/error.mli", 239 - "lib/http_client.ml" 240 - ], 241 - "rationale": "Guzzle's exceptions include handler error data (src/Exception/RequestException.php) with low-level details like cURL errno, error messages, and connection info. The OCaml library's error types are comprehensive but don't include handler-specific details like transport-layer error codes or connection pool statistics. Adding this context would help users: (1) distinguish between DNS failures, connection refused, and SSL errors, (2) understand whether errors are from new vs pooled connections, (3) debug network configuration issues, (4) implement smarter retry logic based on error codes." 242 - }, 243 - { 244 - "source_repo": "third_party/php/guzzle", 245 - "source_language": "PHP", 246 - "criticality": "medium", 247 - "change_type": "enhancement", 248 - "title": "Add Read-Timeout Separate from Total Timeout", 249 - "description": "The current library has 'read' timeout in Timeout.t but ensure it's applied to individual read operations during body transfer, not just the initial response. Guzzle distinguishes between 'timeout' (total request) and 'read_timeout' (per-read operation). Verify the OCaml implementation correctly applies read timeout to each chunk read, not just overall.", 250 - "affected_files": [ 251 - "lib/timeout.ml", 252 - "lib/http_client.ml", 253 - "lib/http_read.ml" 254 - ], 255 - "rationale": "Guzzle has both 'timeout' (total request duration) and 'read_timeout' (timeout for individual read operations during body transfer). The OCaml library has 'read' in Timeout.t but the implementation should verify this is applied per-read-operation during streaming, not just to the overall request. Per-read timeouts are critical for detecting stalled transfers where the connection is alive but no data is flowing. Clarifying or improving the semantics ensures large file downloads won't stall indefinitely if the server stops sending data mid-transfer." 256 - }, 257 - { 258 - "source_repo": "third_party/php/guzzle", 259 - "source_language": "PHP", 260 - "criticality": "low", 261 - "change_type": "enhancement", 262 - "title": "Add Debug Option for Verbose Output Stream", 263 - "description": "Add a 'debug' option that accepts a boolean, file path, or output stream to write verbose debugging information including: (1) request headers and body, (2) response headers and body, (3) connection information, (4) SSL/TLS handshake details. This mirrors Guzzle's 'debug' option and complements existing logging.", 264 - "affected_files": [ 265 - "lib/requests.mli", 266 - "lib/one.mli", 267 - "lib/http_client.ml" 268 - ], 269 - "rationale": "Guzzle's 'debug' option (RequestOptions::DEBUG) writes verbose output to a stream (stdout, file, or custom), including full request/response dumps. The OCaml library has comprehensive logging via Logs, but users must configure log levels and sources separately. A simple 'debug' option would: (1) make debugging more accessible to users unfamiliar with Logs, (2) allow per-request debugging without changing global log configuration, (3) enable capturing debug output to files for support tickets, (4) provide formatted output optimized for HTTP debugging rather than general logging." 270 - }, 271 - { 272 - "source_repo": "third_party/php/guzzle", 273 - "source_language": "PHP", 274 - "criticality": "medium", 275 - "change_type": "feature", 276 - "title": "Add Conditional Headers Support Helpers", 277 - "description": "Add helper functions to easily set conditional request headers: (1) if_match, (2) if_none_match, (3) if_modified_since, (4) if_unmodified_since. While these can be set manually via Headers, providing typed helpers with validation (e.g., ETag format, HTTP-date parsing) improves ergonomics and correctness.", 278 - "affected_files": [ 279 - "lib/headers.ml", 280 - "lib/headers.mli", 281 - "lib/requests.mli" 282 - ], 283 - "rationale": "While the OCaml library has Response.etag and Response.last_modified for reading values, it doesn't provide helpers for setting conditional request headers. Guzzle doesn't have specific helpers either, but the OCaml library could improve on this by adding typed helpers that: (1) ensure correct ETag quoting, (2) validate/format HTTP-dates, (3) make conditional requests more discoverable, (4) prevent common mistakes like malformed ETags. This is particularly valuable given the library's existing support for cache-control and conditional response headers." 284 - } 285 - ] 286 - }
-236
third_party/php/http-client.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/php/http-client", 5 - "source_language": "PHP", 6 - "criticality": "medium", 7 - "change_type": "security", 8 - "title": "Implement request cancellation mechanism", 9 - "description": "The PHP library provides a Cancellation interface that allows users to cancel in-flight requests gracefully. This prevents resource leaks and enables timeout-based request cancellation at the application level. OCaml library should provide a cancellation token mechanism compatible with Eio's cancellation contexts.", 10 - "affected_files": [ 11 - "lib/requests.mli", 12 - "lib/one.mli", 13 - "lib/http_client.ml" 14 - ], 15 - "rationale": "Cancellation is critical for preventing resource exhaustion in long-running requests. The PHP library demonstrates how cancellation can be integrated at the interceptor level. In the OCaml library, this could leverage Eio's fiber cancellation, but needs explicit API surface for user-controlled cancellation beyond just timeout." 16 - }, 17 - { 18 - "source_repo": "third_party/php/http-client", 19 - "source_language": "PHP", 20 - "criticality": "medium", 21 - "change_type": "feature", 22 - "title": "Add event listener/hook system for observability", 23 - "description": "The PHP library provides an EventListener interface that allows users to monitor HTTP requests and responses for logging, metrics, and debugging. This enables features like HTTP Archive (HAR) generation for performance analysis. OCaml library should add a similar callback/hook system for request lifecycle events (start, headers received, body chunk, complete, error).", 24 - "affected_files": [ 25 - "lib/requests.mli", 26 - "lib/http_client.ml" 27 - ], 28 - "rationale": "Event listeners provide crucial observability without requiring users to wrap every request. The PHP library's LogHttpArchive listener demonstrates practical value for debugging and performance analysis. This would complement the existing Logs-based logging by providing structured programmatic access to request/response data." 29 - }, 30 - { 31 - "source_repo": "third_party/php/http-client", 32 - "source_language": "PHP", 33 - "criticality": "low", 34 - "change_type": "enhancement", 35 - "title": "Add idle connection limiting to connection pool", 36 - "description": "The PHP ConnectionLimitingPool limits idle connections to 64 (hardcoded) to prevent unbounded memory growth. The OCaml library's Conpool should add configurable idle connection limits with automatic closure of least-recently-used idle connections when the limit is exceeded.", 37 - "affected_files": [ 38 - "lib/requests.mli" 39 - ], 40 - "rationale": "While the OCaml library has connection_idle_timeout, it doesn't limit the total number of idle connections across all hosts. The PHP library shows that keeping too many idle connections can waste memory. A configurable max_idle_connections parameter (with sensible default like 100) would prevent resource exhaustion in long-running applications making requests to many different hosts." 41 - }, 42 - { 43 - "source_repo": "third_party/php/http-client", 44 - "source_language": "PHP", 45 - "criticality": "high", 46 - "change_type": "security", 47 - "title": "Enforce ForbidUriUserInfo by default to prevent credential leakage", 48 - "description": "The PHP library includes a ForbidUriUserInfo interceptor that rejects URIs containing username:password (deprecated per RFC 7230 §2.7.1). This prevents accidental credential exposure in logs and headers via URI.toString(). The OCaml library should validate URIs and reject user info by default, with an explicit opt-out flag if needed.", 49 - "affected_files": [ 50 - "lib/one.ml", 51 - "lib/http_client.ml", 52 - "lib/error.mli" 53 - ], 54 - "rationale": "Userinfo in URIs (http://user:pass@example.com) is deprecated and dangerous because URIs are often logged or sent in headers where credentials can leak. The PHP library treats this as a security issue requiring explicit opt-in. OCaml library should raise Error.Invalid_url when userinfo is detected, forcing users to use proper Authorization headers instead." 55 - }, 56 - { 57 - "source_repo": "third_party/php/http-client", 58 - "source_language": "PHP", 59 - "criticality": "medium", 60 - "change_type": "feature", 61 - "title": "Add request/response interceptor framework for extensibility", 62 - "description": "The PHP library uses an interceptor pattern with ApplicationInterceptor and NetworkInterceptor interfaces that allow composable request/response modification. This enables features like automatic decompression, retries, redirects, and header manipulation to be implemented as modular interceptors. OCaml library should add a similar middleware/interceptor system.", 63 - "affected_files": [ 64 - "lib/requests.mli", 65 - "lib/http_client.ml" 66 - ], 67 - "rationale": "The interceptor pattern provides cleaner separation of concerns than monolithic request handling. PHP library demonstrates how ApplicationInterceptors (operate on logical requests) differ from NetworkInterceptors (operate on actual connections). This would allow users to add custom logic (e.g., request signing, response caching, metrics) without modifying core library code. Could be implemented using function composition or a dedicated Interceptor module type." 68 - }, 69 - { 70 - "source_repo": "third_party/php/http-client", 71 - "source_language": "PHP", 72 - "criticality": "low", 73 - "change_type": "enhancement", 74 - "title": "Add support for HTTP/2 server push interception", 75 - "description": "The PHP library's Request object includes an interceptPush callback that allows handling HTTP/2 server push promises. While HTTP/2 server push is being deprecated in browsers, it may still be useful for API clients. OCaml library should consider adding server push callback support if/when HTTP/2 is implemented.", 76 - "affected_files": [ 77 - "lib/requests.mli" 78 - ], 79 - "rationale": "Server push allows servers to proactively send resources the client will need. The PHP library demonstrates how this can be handled via callbacks. While not urgent (HTTP/2 not yet implemented in OCaml library, and push is deprecated), documenting this for future consideration ensures the API can evolve to support it if needed." 80 - }, 81 - { 82 - "source_repo": "third_party/php/http-client", 83 - "source_language": "PHP", 84 - "criticality": "medium", 85 - "change_type": "enhancement", 86 - "title": "Improve retry logic to distinguish idempotent vs unprocessed requests", 87 - "description": "The PHP RetryRequests interceptor checks both request.isIdempotent() and request.isUnprocessed(). The isUnprocessed flag indicates the connection determined the request wasn't processed (e.g., connection closed before sending), making it safe to retry even for non-idempotent requests. OCaml library should track whether requests were actually sent and allow retrying unsent requests regardless of method.", 88 - "affected_files": [ 89 - "lib/retry.ml", 90 - "lib/retry.mli", 91 - "lib/http_client.ml" 92 - ], 93 - "rationale": "Currently, OCaml retry logic only checks HTTP method and status codes. The PHP library shows that connection-level failures before the request is fully sent are always safe to retry, even for POST. This prevents false failures when connections are dropped before the request reaches the server. Add a 'request_sent' tracking flag and allow retrying when request_sent=false regardless of method." 94 - }, 95 - { 96 - "source_repo": "third_party/php/http-client", 97 - "source_language": "PHP", 98 - "criticality": "medium", 99 - "change_type": "enhancement", 100 - "title": "Add HTTP/2 connection multiplexing with priority-based stream waiting", 101 - "description": "The PHP library's ConnectionLimitingPool implements sophisticated HTTP/2 multiplexing: it waits for the first HTTPS connection to complete to check if HTTP/2 is available before spawning additional connections. This maximizes stream reuse on a single HTTP/2 connection. The OCaml library should implement similar logic when HTTP/2 support is added.", 102 - "affected_files": [ 103 - "lib/requests.mli" 104 - ], 105 - "rationale": "The PHP code shows 'waitForPriorConnection' logic that prevents creating unnecessary TCP connections when HTTP/2 multiplexing is available. Without this, connection pools may create multiple TCP connections to the same host when one HTTP/2 connection could handle all streams. This is a performance optimization to implement when adding HTTP/2 support." 106 - }, 107 - { 108 - "source_repo": "third_party/php/http-client", 109 - "source_language": "PHP", 110 - "criticality": "medium", 111 - "change_type": "enhancement", 112 - "title": "Add configurable decompression bomb protection", 113 - "description": "The PHP library's DecompressResponse interceptor checks request.getBodySizeLimit() and wraps decompressed streams in SizeLimitingReadableStream to prevent decompression bombs. The OCaml library has Body_too_large error but should enforce size limits on decompressed responses, not just raw responses.", 114 - "affected_files": [ 115 - "lib/response_limits.mli", 116 - "lib/http_client.ml", 117 - "lib/one.ml" 118 - ], 119 - "rationale": "A small compressed response can decompress to gigabytes, causing memory exhaustion. The OCaml library has Response_limits.max_body_size but it's unclear if this is enforced post-decompression. Should add explicit decompression bomb detection by tracking decompressed bytes separately and raising Error.Decompression_bomb when ratio exceeds threshold (e.g., 1000x expansion)." 120 - }, 121 - { 122 - "source_repo": "third_party/php/http-client", 123 - "source_language": "PHP", 124 - "criticality": "low", 125 - "change_type": "enhancement", 126 - "title": "Improve response body API to prevent double-consumption", 127 - "description": "The PHP library's Response.getBody() returns a new stream each time it's called, making it harder to accidentally double-consume. The OCaml library's Response.body returns the same flow which can only be read once. Consider adding explicit ownership tracking or response.clone() functionality.", 128 - "affected_files": [ 129 - "lib/response.mli", 130 - "lib/response.ml" 131 - ], 132 - "rationale": "Double-consuming a response body is a common bug. The PHP library's approach of returning new streams (if bufferable) prevents this. OCaml library could add a 'consumed' flag and raise an error on second access, or provide Response.clone for cases where multiple reads are needed. The current documentation warns about this but doesn't enforce it programmatically." 133 - }, 134 - { 135 - "source_repo": "third_party/php/http-client", 136 - "source_language": "PHP", 137 - "criticality": "low", 138 - "change_type": "feature", 139 - "title": "Add support for conditional Accept-Encoding header", 140 - "description": "The PHP DecompressResponse interceptor only adds Accept-Encoding if the user hasn't manually set it, respecting user intent. The OCaml library's auto_decompress flag is all-or-nothing. Should allow users to set custom Accept-Encoding while still getting automatic decompression.", 141 - "affected_files": [ 142 - "lib/http_client.ml", 143 - "lib/one.ml" 144 - ], 145 - "rationale": "Users may want to control which encodings are acceptable (e.g., only gzip, not deflate) while still benefiting from automatic decompression. The PHP approach of checking if the header is already set before adding it is more flexible. OCaml library should check Headers.mem \"accept-encoding\" and skip adding it if user provided their own." 146 - }, 147 - { 148 - "source_repo": "third_party/php/http-client", 149 - "source_language": "PHP", 150 - "criticality": "high", 151 - "change_type": "bug", 152 - "title": "Fix potential retry exception handling bug", 153 - "description": "The PHP RetryRequests interceptor may reference undefined $exception variable if retry loop exhausts without catching an exception on the final attempt. The OCaml retry logic should ensure exceptions are properly propagated on final retry failure.", 154 - "affected_files": [ 155 - "lib/retry.ml" 156 - ], 157 - "rationale": "The PHP code shows 'throw $exception' after the do-while loop, but $exception may be undefined if no exception was caught in the last iteration. This appears to be a bug in the PHP library. OCaml retry.ml should be reviewed to ensure it doesn't have similar issues - the with_retry function should re-raise the exception from the final attempt, not rely on a potentially unbound variable." 158 - }, 159 - { 160 - "source_repo": "third_party/php/http-client", 161 - "source_language": "PHP", 162 - "criticality": "medium", 163 - "change_type": "enhancement", 164 - "title": "Add protocol version negotiation and filtering", 165 - "description": "The PHP library's Connection interface includes getProtocolVersions() and Request includes getProtocolVersions(), allowing filtering connections by supported protocols (HTTP/1.1 vs HTTP/2). The OCaml library should add protocol version tracking and negotiation when HTTP/2 support is added.", 166 - "affected_files": [ 167 - "lib/requests.mli", 168 - "lib/http_client.ml" 169 - ], 170 - "rationale": "The PHP ConnectionLimitingPool checks array_intersect($request->getProtocolVersions(), $connection->getProtocolVersions()) before using a connection. This ensures requests only use connections that support their required protocol version. Useful for gradual HTTP/2 rollout where some requests may need to force HTTP/1.1 for compatibility." 171 - }, 172 - { 173 - "source_repo": "third_party/php/http-client", 174 - "source_language": "PHP", 175 - "criticality": "low", 176 - "change_type": "enhancement", 177 - "title": "Add connection pool statistics and metrics", 178 - "description": "The PHP ConnectionLimitingPool tracks getTotalConnectionAttempts(), getTotalStreamRequests(), and getOpenConnectionCount() for monitoring and debugging. The OCaml Conpool should expose similar metrics for observability.", 179 - "affected_files": [ 180 - "lib/requests.mli" 181 - ], 182 - "rationale": "Connection pool metrics help diagnose performance issues and validate pool configuration. The PHP library exposes these metrics publicly. OCaml Conpool already has internal Stats tracking but it may not be exposed in the public API. Should add Requests.pool_stats() or similar to return {total_connections; active_connections; idle_connections; total_requests}." 183 - }, 184 - { 185 - "source_repo": "third_party/php/http-client", 186 - "source_language": "PHP", 187 - "criticality": "low", 188 - "change_type": "enhancement", 189 - "title": "Improve builder pattern ergonomics with method chaining", 190 - "description": "The PHP HttpClientBuilder uses fluent method chaining where each configuration method returns a new builder instance (clone $this). The OCaml library's Requests.create takes ~20 optional parameters. Consider adding a builder pattern or configuration record type for better ergonomics.", 191 - "affected_files": [ 192 - "lib/requests.mli" 193 - ], 194 - "rationale": "The PHP builder pattern makes configuration more discoverable and readable compared to long parameter lists. While OCaml doesn't support method chaining syntax, a similar pattern could use: let cfg = Config.default |> Config.with_timeout 30.0 |> Config.with_retry retry_cfg in Requests.create ~config:cfg env. This would reduce the function signature from 20 optional parameters to 2-3 core parameters plus a config." 195 - }, 196 - { 197 - "source_repo": "third_party/php/http-client", 198 - "source_language": "PHP", 199 - "criticality": "medium", 200 - "change_type": "enhancement", 201 - "title": "Add automatic User-Agent header with opt-out", 202 - "description": "The PHP library automatically sets User-Agent to 'amphp/http-client/5.x' unless explicitly disabled or overridden. The OCaml library should add a default User-Agent header (e.g., 'ocaml-requests/0.1.0') that can be disabled or customized.", 203 - "affected_files": [ 204 - "lib/requests.mli", 205 - "lib/one.mli", 206 - "lib/http_client.ml" 207 - ], 208 - "rationale": "User-Agent headers help server administrators identify clients and are considered polite HTTP behavior. The PHP library uses SetRequestHeaderIfUnset to add it by default without forcing it. OCaml library should add user_agent optional parameter to Requests.create (default: Some \"ocaml-requests/$VERSION\") and add the header in http_client if not already present." 209 - }, 210 - { 211 - "source_repo": "third_party/php/http-client", 212 - "source_language": "PHP", 213 - "criticality": "low", 214 - "change_type": "enhancement", 215 - "title": "Add automatic Accept header with opt-out", 216 - "description": "The PHP library automatically sets Accept: */* unless explicitly disabled or overridden. The OCaml library could add similar default Accept header behavior for better HTTP compliance.", 217 - "affected_files": [ 218 - "lib/http_client.ml", 219 - "lib/one.ml" 220 - ], 221 - "rationale": "While not strictly required, setting Accept: */* indicates the client can handle any content type. The PHP library adds this via SetRequestHeaderIfUnset interceptor. OCaml library could add this when user hasn't set Accept header, though this is lower priority than User-Agent since Accept defaults are often implied." 222 - }, 223 - { 224 - "source_repo": "third_party/php/http-client", 225 - "source_language": "PHP", 226 - "criticality": "medium", 227 - "change_type": "feature", 228 - "title": "Add request cloning support for retries", 229 - "description": "The PHP library clones requests before each retry attempt (clonedRequest = clone $request) to ensure retries don't mutate the original request. The OCaml library should ensure retry logic doesn't modify the original request state.", 230 - "affected_files": [ 231 - "lib/retry.ml" 232 - ], 233 - "rationale": "The PHP library shows that request state may be modified during attempts (e.g., tracking if request was processed). Cloning ensures each retry starts fresh. OCaml library should verify that with_retry doesn't accidentally share mutable state across retry attempts. Since OCaml tends toward immutability, this may already be correct, but should be verified in retry.ml implementation." 234 - } 235 - ] 236 - }
-138
third_party/php/httplug.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/php/httplug", 5 - "source_language": "PHP", 6 - "criticality": "medium", 7 - "change_type": "enhancement", 8 - "title": "Add request context preservation in exceptions", 9 - "description": "HTTPlug exceptions carry both the request and response objects via RequestAwareTrait, allowing users to inspect the original request that failed. The OCaml library error types contain URLs and status codes but lack access to the full request headers and body. Adding a request context to error variants would help with debugging and retry logic that needs to inspect what was sent.", 10 - "affected_files": [ 11 - "lib/error.mli", 12 - "lib/error.ml" 13 - ], 14 - "rationale": "HTTPlug RequestAwareTrait pattern allows exceptions to carry the full PSR-7 RequestInterface enabling detailed error analysis and retry strategies. The OCaml library currently only stores URLs in some error variants. Adding optional request metadata like method headers and sanitized body preview to error variants would improve debuggability without creating circular dependencies." 15 - }, 16 - { 17 - "source_repo": "third_party/php/httplug", 18 - "source_language": "PHP", 19 - "criticality": "medium", 20 - "change_type": "enhancement", 21 - "title": "Add response access in HTTP error exceptions", 22 - "description": "HTTPlug HttpException provides getResponse to access the response object when HTTP errors occur. This allows users to examine response headers and body for error details. The OCaml library stores body_preview and headers in Http_error but Response.raise_for_status discards the response. Adding a variant that preserves response access would improve error handling.", 23 - "affected_files": [ 24 - "lib/response.mli", 25 - "lib/response.ml", 26 - "lib/error.mli", 27 - "lib/error.ml" 28 - ], 29 - "rationale": "HTTPlug HttpException.getResponse enables access to server error messages in response bodies and error-specific headers. While the OCaml library captures body_preview in Http_error Response.raise_for_status does not provide a way to access the full response after the exception is raised. Adding a result-based API or exception variant that preserves the response would enable better error message extraction." 30 - }, 31 - { 32 - "source_repo": "third_party/php/httplug", 33 - "source_language": "PHP", 34 - "criticality": "low", 35 - "change_type": "enhancement", 36 - "title": "Add standardized error message formatting", 37 - "description": "HTTPlug HttpException.create provides a factory method that generates normalized error messages with a consistent format including URL HTTP method status code and reason phrase. The OCaml library to_string function could benefit from a similar standardized formatting approach for consistency across error types.", 38 - "affected_files": [ 39 - "lib/error.ml" 40 - ], 41 - "rationale": "HTTPlug normalized error messages provide consistent parseable error output. The OCaml library Error.to_string already provides human-readable messages but adopting a more structured format with labeled fields would improve log parsing and error analysis tools." 42 - }, 43 - { 44 - "source_repo": "third_party/php/httplug", 45 - "source_language": "PHP", 46 - "criticality": "low", 47 - "change_type": "enhancement", 48 - "title": "Consider promise-based async API for advanced use cases", 49 - "description": "HTTPlug provides HttpAsyncClient with promise-based asynchronous requests alongside synchronous APIs. While the OCaml library uses Eio fibers for concurrency which is idiomatic for OCaml 5, adding promise-like combinators for common async patterns like all race and timeout could improve ergonomics for complex concurrent request scenarios.", 50 - "affected_files": [ 51 - "lib/requests.mli", 52 - "lib/requests.ml" 53 - ], 54 - "rationale": "HTTPlug HttpAsyncClient with HttpFulfilledPromise and HttpRejectedPromise provides composable async operations. The OCaml library correctly uses Eio.Fiber for concurrency and documents Fiber.both and all patterns. However adding higher-level combinators like Requests.all and Requests.race could reduce boilerplate for common concurrent patterns while maintaining the Eio foundation." 55 - }, 56 - { 57 - "source_repo": "third_party/php/httplug", 58 - "source_language": "PHP", 59 - "criticality": "high", 60 - "change_type": "security", 61 - "title": "Ensure PSR-18 NetworkException compliance for network errors", 62 - "description": "HTTPlug NetworkException implements PSR-18 NetworkExceptionInterface specifically for network failures where no response was received. The OCaml library should ensure clear distinction between connection errors like Dns_resolution_failed Tcp_connect_failed and Tls_handshake_failed versus HTTP protocol errors to align with this standard pattern.", 63 - "affected_files": [ 64 - "lib/error.mli", 65 - "lib/error.ml" 66 - ], 67 - "rationale": "PSR-18 NetworkExceptionInterface represents request cannot be completed because of network issues with no response available. The OCaml library already has granular connection error types and an is_connection query function. Documentation should emphasize this distinction to help users handle network versus HTTP errors appropriately matching the PSR-18 contract." 68 - }, 69 - { 70 - "source_repo": "third_party/php/httplug", 71 - "source_language": "PHP", 72 - "criticality": "medium", 73 - "change_type": "enhancement", 74 - "title": "Add exception chaining for wrapped errors", 75 - "description": "HTTPlug exceptions accept an optional previous Exception parameter enabling exception chaining to preserve the underlying error cause. The OCaml library Eio.Io exceptions support backtraces but could benefit from explicit error chaining for wrapped network and TLS errors to preserve the full error context.", 76 - "affected_files": [ 77 - "lib/error.mli", 78 - "lib/error.ml", 79 - "lib/http_client.ml" 80 - ], 81 - "rationale": "HTTPlug exception constructors include optional previous parameter for error chaining like wrapping socket errors in NetworkException. The OCaml library uses Eio.Io exceptions which capture backtraces but some error variants like Tls_handshake_failed and Tcp_connect_failed only store string reasons. Storing the underlying exn in a variant field would preserve full error context for debugging." 82 - }, 83 - { 84 - "source_repo": "third_party/php/httplug", 85 - "source_language": "PHP", 86 - "criticality": "low", 87 - "change_type": "feature", 88 - "title": "Add middleware plugin architecture for request response transformation", 89 - "description": "HTTPlug ecosystem provides a plugin architecture for decorating HTTP clients with middleware like retry authentication and logging. While the OCaml library has built-in retry and auth adding a plugin middleware system would enable user extensions without modifying library code.", 90 - "affected_files": [ 91 - "lib/requests.mli", 92 - "lib/requests.ml", 93 - "lib/one.mli", 94 - "lib/one.ml" 95 - ], 96 - "rationale": "HTTPlug success partly comes from its plugin decorator pattern. The OCaml library has built-in retry auth and decompression but does not expose extension points for custom request response transformation. Adding optional middleware hooks like before_request and after_response callbacks would enable user extensions like custom logging request signing or metric collection." 97 - }, 98 - { 99 - "source_repo": "third_party/php/httplug", 100 - "source_language": "PHP", 101 - "criticality": "medium", 102 - "change_type": "enhancement", 103 - "title": "Improve testing support with mock stub utilities", 104 - "description": "HTTPlug test suite uses phpspec with mock Request Response objects demonstrating good interface testability. The OCaml library could benefit from documented testing patterns or mock utilities to help users write tests without making real HTTP requests.", 105 - "affected_files": [ 106 - "test/test_simple.ml", 107 - "lib/requests.mli" 108 - ], 109 - "rationale": "HTTPlug test specs show how to test HTTP client code using mocks for RequestInterface and ResponseInterface. The OCaml library has Alcotest tests but primarily tests real HTTP behavior. Adding documented mock patterns like a Test module with mock responses or guidance on using Eio_mock.Backend would help library users write testable HTTP client code." 110 - }, 111 - { 112 - "source_repo": "third_party/php/httplug", 113 - "source_language": "PHP", 114 - "criticality": "low", 115 - "change_type": "enhancement", 116 - "title": "Add comprehensive error type documentation with usage examples", 117 - "description": "HTTPlug exception hierarchy is well-documented with clear inheritance like TransferException extending to RequestException then HttpException and NetworkException. The OCaml library has excellent error documentation but could add more examples of how to pattern match on error types for different retry recovery strategies.", 118 - "affected_files": [ 119 - "lib/error.mli" 120 - ], 121 - "rationale": "HTTPlug documentation clearly explains the exception hierarchy and when each type is raised. The OCaml library Error module has good query functions like is_retryable and is_connection but could expand documentation with concrete examples of error handling patterns such as retry on is_retryable different backoff for is_timeout versus is_connection and logging for is_security_error." 122 - }, 123 - { 124 - "source_repo": "third_party/php/httplug", 125 - "source_language": "PHP", 126 - "criticality": "medium", 127 - "change_type": "enhancement", 128 - "title": "Add builder pattern for complex request configuration", 129 - "description": "While HTTPlug uses PSR-7 request objects that can be built separately from client invocation the OCaml library could benefit from a request builder pattern for complex requests with many optional parameters especially for the One module verbose signatures.", 130 - "affected_files": [ 131 - "lib/one.mli", 132 - "lib/one.ml", 133 - "lib/requests.mli" 134 - ], 135 - "rationale": "HTTPlug separates request creation using PSR-7 RequestInterface from sending via sendRequest or sendAsyncRequest. The OCaml library One module functions have many optional parameters like 14 plus in one.request. Adding a Request.t builder type with a fluent API like Request.make url piped to with_headers with_body with_timeout would improve ergonomics for complex requests while maintaining backward compatibility." 136 - } 137 - ] 138 - }
-135
third_party/python/grequests.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "grequests", 5 - "source_language": "Python", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add concurrent request batching API similar to grequests.map()", 9 - "description": "Grequests provides a `map()` function that takes a collection of request objects and executes them concurrently, returning a list of responses in the same order. This provides a simpler API than manually using Eio.Fiber.all for multiple requests. Consider adding a `Requests.map : t -> request list -> Response.t list` function that internally uses Eio.Fiber.all to execute requests concurrently and collect results.", 10 - "affected_files": [ 11 - "lib/requests.mli", 12 - "lib/requests.ml" 13 - ], 14 - "rationale": "Grequests' map() function is the library's primary value proposition - it makes concurrent requests trivial. The OCaml library requires users to manually manage Fiber.both or Fiber.all, which is more verbose. A map-style API would improve ergonomics for batch operations like fetching multiple API endpoints, downloading multiple files, or polling multiple services. The implementation would be straightforward using Eio.Fiber.all internally while preserving order." 15 - }, 16 - { 17 - "source_repo": "grequests", 18 - "source_language": "Python", 19 - "criticality": "medium", 20 - "change_type": "feature", 21 - "title": "Add lazy concurrent request iteration like grequests.imap()", 22 - "description": "Grequests provides `imap()` which yields responses as they complete, allowing processing to start before all requests finish. This is useful for large batches where you want to process results as they arrive. Consider adding a `Requests.imap : t -> request list -> Response.t Seq.t` that uses Eio.Stream internally to yield responses as they complete.", 23 - "affected_files": [ 24 - "lib/requests.mli", 25 - "lib/requests.ml" 26 - ], 27 - "rationale": "The imap() pattern enables memory-efficient processing of large request batches by processing responses as they arrive rather than waiting for all to complete. This is valuable for operations like web scraping, batch API calls, or health checks where you want to start processing successful responses while others are still pending. The OCaml implementation could use Eio.Stream to achieve similar lazy evaluation semantics." 28 - }, 29 - { 30 - "source_repo": "grequests", 31 - "source_language": "Python", 32 - "criticality": "medium", 33 - "change_type": "enhancement", 34 - "title": "Add exception handler callback for concurrent request failures", 35 - "description": "Grequests' map() and imap() accept an `exception_handler` callback that's called when a request raises an exception, allowing custom error handling logic. The handler can return a value to substitute for the failed request in results. Consider adding optional `on_error:(request -> exn -> 'a option)` callbacks to any batch request APIs, where None means filter out the failure and Some value means include the substitute.", 36 - "affected_files": [ 37 - "lib/requests.mli", 38 - "lib/requests.ml" 39 - ], 40 - "rationale": "In batch request scenarios, it's common to want custom error handling per request - log failures, use default values, retry with different parameters, etc. The current OCaml implementation would require wrapping each request in try/catch blocks. An exception_handler callback provides cleaner separation of success/failure handling and allows partial failure in batch operations without aborting the entire batch." 41 - }, 42 - { 43 - "source_repo": "grequests", 44 - "source_language": "Python", 45 - "criticality": "low", 46 - "change_type": "enhancement", 47 - "title": "Add configurable concurrency pool size for batch requests", 48 - "description": "Grequests allows specifying a `size` parameter to map()/imap() to limit concurrent requests (e.g., `grequests.map(requests, size=5)` runs max 5 concurrent requests). The OCaml library has connection pooling but no user-facing concurrency limit for batched operations. Consider adding a `~max_concurrent:int` parameter to batch request functions.", 49 - "affected_files": [ 50 - "lib/requests.mli", 51 - "lib/requests.ml" 52 - ], 53 - "rationale": "Limiting concurrency is important to avoid overwhelming servers, respect rate limits, or control local resource usage. While the OCaml library has connection pooling (max_connections_per_host), this controls connections per endpoint, not total concurrent requests. For batch operations hitting different hosts or deliberately throttling requests to a single host, a concurrency limit is valuable. This could be implemented using Eio.Semaphore to gate concurrent fibers." 54 - }, 55 - { 56 - "source_repo": "grequests", 57 - "source_language": "Python", 58 - "criticality": "low", 59 - "change_type": "enhancement", 60 - "title": "Add global timeout for batch operations like grequests gtimeout", 61 - "description": "Grequests map() supports a `gtimeout` parameter for overall batch timeout, independent of per-request timeouts. This ensures the entire batch completes within a deadline. Consider adding a `~batch_timeout:float option` parameter to batch request APIs that wraps the entire Fiber.all operation in Eio.Time.with_timeout.", 62 - "affected_files": [ 63 - "lib/requests.mli", 64 - "lib/requests.ml" 65 - ], 66 - "rationale": "Batch operations may have overall SLA requirements separate from individual request timeouts. For example, a health check dashboard might need results within 5 seconds even if individual requests have 10s timeouts. A batch timeout ensures the operation completes within bounds, returning partial results if needed. This is distinct from per-request timeouts and provides better control over batch operation latency." 67 - }, 68 - { 69 - "source_repo": "grequests", 70 - "source_language": "Python", 71 - "criticality": "high", 72 - "change_type": "enhancement", 73 - "title": "Store exception details in response objects for batch operations", 74 - "description": "Grequests stores exceptions on request objects (request.exception, request.traceback) when requests fail, allowing inspection after batch completion. The OCaml library currently propagates exceptions immediately. For batch operations, consider adding a Result-based API variant that captures failures: `Requests.map_result : t -> request list -> (Response.t, exn) result list`.", 75 - "affected_files": [ 76 - "lib/requests.mli", 77 - "lib/requests.ml" 78 - ], 79 - "rationale": "In concurrent batch operations, it's often desirable to collect all results including failures rather than aborting on first exception. Grequests' pattern of storing exceptions on request objects allows map() to complete successfully even with partial failures. An OCaml Result-based API would provide similar functionality with better type safety. Users could then filter successful responses, log failures, or implement custom failure handling logic after the batch completes." 80 - }, 81 - { 82 - "source_repo": "grequests", 83 - "source_language": "Python", 84 - "criticality": "low", 85 - "change_type": "enhancement", 86 - "title": "Add session reuse support for batch async requests", 87 - "description": "Grequests allows passing an existing Session object to AsyncRequest via the `session` parameter, enabling cookie persistence and connection reuse across async requests. The OCaml library already supports sessions (type t), but batch request APIs should explicitly document how to share sessions across concurrent requests and ensure thread-safety for cookie jar access.", 88 - "affected_files": [ 89 - "lib/requests.mli", 90 - "lib/requests.ml" 91 - ], 92 - "rationale": "The OCaml library already has good session support with Eio.Mutex for cookie_jar thread-safety, which is better than grequests' approach. However, documentation should clarify best practices for using a single session across concurrent requests in batch operations. The current implementation is correct but users may not realize the cookie jar is thread-safe via mutex, or that connection pools are already shared across concurrent requests." 93 - }, 94 - { 95 - "source_repo": "grequests", 96 - "source_language": "Python", 97 - "criticality": "medium", 98 - "change_type": "feature", 99 - "title": "Add callback hooks for response processing in concurrent requests", 100 - "description": "Grequests supports response callbacks via `callback` parameter or `hooks={'response': callback}` that execute immediately when responses arrive. This enables fire-and-forget concurrent processing. Consider adding `~on_response:(Response.t -> unit) option` callbacks to batch request APIs that execute in the request's fiber context as soon as the response is received.", 101 - "affected_files": [ 102 - "lib/requests.mli", 103 - "lib/requests.ml" 104 - ], 105 - "rationale": "Response callbacks enable immediate processing without waiting for all requests to complete. Use cases include streaming results to disk, updating UI progress indicators, or publishing events. The OCaml implementation could execute callbacks in the request fiber before collecting results, allowing side effects during concurrent execution. This is more efficient than imap() when you only need side effects, not collected results." 106 - }, 107 - { 108 - "source_repo": "grequests", 109 - "source_language": "Python", 110 - "criticality": "low", 111 - "change_type": "enhancement", 112 - "title": "Document testing patterns for concurrent requests", 113 - "description": "Grequests tests demonstrate patterns for verifying concurrent execution (measuring total time < sum of delays), testing timeout behavior in concurrent contexts, and validating session/cookie handling across concurrent requests. Add similar test patterns and documentation examples to the OCaml library.", 114 - "affected_files": [ 115 - "test/test_simple.ml", 116 - "test/test_localhost.ml", 117 - "lib/requests.mli" 118 - ], 119 - "rationale": "The grequests test suite (tests.py lines 115-120) demonstrates important patterns like verifying that concurrent requests actually execute in parallel by checking total time is less than sequential time. The OCaml library should have similar tests to validate that Fiber.both/Fiber.all actually provide concurrency benefits and that connection pooling works correctly under concurrent load." 120 - }, 121 - { 122 - "source_repo": "grequests", 123 - "source_language": "Python", 124 - "criticality": "low", 125 - "change_type": "enhancement", 126 - "title": "Add response streaming control for concurrent requests", 127 - "description": "Grequests map() and imap() support a `stream=True` parameter that prevents automatic response body download (sets stream=True on requests). This enables memory-efficient processing of large responses in concurrent contexts. The OCaml library already supports streaming via Response.body flow, but batch APIs should document how to avoid buffering all response bodies simultaneously.", 128 - "affected_files": [ 129 - "lib/requests.mli", 130 - "lib/requests.ml" 131 - ], 132 - "rationale": "When processing multiple large responses concurrently, buffering all bodies in memory can cause issues. Grequests addresses this with stream=True which leaves response bodies as lazy streams. The OCaml library's Response.body is already a Eio.Flow that doesn't buffer by default, which is better than grequests. However, the current requests.ml implementation (line 508) calls Eio.Flow.read_all which buffers the entire body. For batch operations with large responses, this should be configurable or documented." 133 - } 134 - ] 135 - }
-371
third_party/python/httplib2.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/python/httplib2", 5 - "source_language": "Python", 6 - "criticality": "medium", 7 - "change_type": "security", 8 - "title": "Strip additional sensitive headers on cross-origin redirects", 9 - "description": "httplib2 strips Authorization headers during redirects (unless forward_authorization_headers=True). The OCaml library strips Authorization, Cookie, Proxy-Authorization, and WWW-Authenticate. Consider also stripping Proxy-Authorization and WWW-Authenticate headers consistently during cross-origin redirects to prevent credential leakage.", 10 - "affected_files": [ 11 - "lib/requests.ml" 12 - ], 13 - "rationale": "httplib2's approach shows that authorization header stripping is critical for preventing credential leakage during redirects. While the OCaml library already has comprehensive header stripping at line 259-264 (strip_sensitive_headers function), ensuring consistency across all redirect scenarios is important. The httplib2 implementation at line 1488 shows this is a well-established security practice." 14 - }, 15 - { 16 - "source_repo": "third_party/python/httplib2", 17 - "source_language": "Python", 18 - "criticality": "low", 19 - "change_type": "feature", 20 - "title": "Add forward_authorization_headers flag for controlled credential forwarding", 21 - "description": "httplib2 provides a forward_authorization_headers flag that allows users to explicitly opt-in to keeping Authorization headers during redirects. This gives users control in scenarios where they trust the redirect chain. Consider adding a similar opt-in mechanism to the OCaml library.", 22 - "affected_files": [ 23 - "lib/requests.ml", 24 - "lib/requests.mli" 25 - ], 26 - "rationale": "httplib2's forward_authorization_headers flag (line 1310, 1488) provides flexibility for trusted scenarios while defaulting to secure behavior. This could be useful for APIs that intentionally redirect with authentication. The OCaml library currently always strips headers (same_origin check at line 245-255), which is secure but inflexible." 27 - }, 28 - { 29 - "source_repo": "third_party/python/httplib2", 30 - "source_language": "Python", 31 - "criticality": "medium", 32 - "change_type": "feature", 33 - "title": "Implement stale nonce recovery for Digest authentication", 34 - "description": "httplib2's DigestAuthentication handles stale nonces by detecting 'stale=true' in 401 responses and automatically retrying with updated nonce (line 619-622). The OCaml library's Digest implementation should handle stale nonce recovery to improve reliability.", 35 - "affected_files": [ 36 - "lib/auth.ml", 37 - "lib/requests.ml" 38 - ], 39 - "rationale": "Stale nonce handling is part of RFC 7616 Digest authentication spec. httplib2 automatically recovers from stale nonces without user intervention, improving user experience. The OCaml library has digest auth infrastructure but doesn't appear to handle the stale nonce retry flow automatically." 40 - }, 41 - { 42 - "source_repo": "third_party/python/httplib2", 43 - "source_language": "Python", 44 - "criticality": "medium", 45 - "change_type": "feature", 46 - "title": "Support nextnonce updates via Authentication-Info header", 47 - "description": "httplib2's Digest authentication parses the Authentication-Info header to update the nonce for subsequent requests (line 624-628). This implements RFC 7615 which allows servers to proactively provide new nonces without requiring 401 responses.", 48 - "affected_files": [ 49 - "lib/auth.ml" 50 - ], 51 - "rationale": "RFC 7615 defines Authentication-Info for digest nonce updates. httplib2's implementation at lines 624-628 shows this reduces round-trips by avoiding 401 challenges on every request. The OCaml library has digest auth (auth.ml) but doesn't parse Authentication-Info headers." 52 - }, 53 - { 54 - "source_repo": "third_party/python/httplib2", 55 - "source_language": "Python", 56 - "criticality": "low", 57 - "change_type": "enhancement", 58 - "title": "Implement nonce counter (nc) persistence in Digest authentication", 59 - "description": "httplib2's DigestAuthentication maintains a nonce counter (nc) that increments with each request (line 578, 614). The OCaml library uses a fixed nc=00000001. Supporting proper nc counting improves security and server compatibility.", 60 - "affected_files": [ 61 - "lib/auth.ml" 62 - ], 63 - "rationale": "RFC 7616 requires the nonce counter to prevent replay attacks. httplib2 properly increments nc (line 614) and resets it when nonces change (line 621, 628). The OCaml library has a hardcoded nc='00000001' at line 196, which doesn't follow the spec for multiple requests with the same nonce." 64 - }, 65 - { 66 - "source_repo": "third_party/python/httplib2", 67 - "source_language": "Python", 68 - "criticality": "high", 69 - "change_type": "security", 70 - "title": "Add configurable minimum and maximum TLS version enforcement", 71 - "description": "httplib2 supports tls_minimum_version and tls_maximum_version parameters (lines 146-174) to enforce specific TLS version ranges. The OCaml library should enhance its TLS configuration to allow both minimum and maximum version constraints, not just minimum.", 72 - "affected_files": [ 73 - "lib/requests.ml", 74 - "lib/requests.mli" 75 - ], 76 - "rationale": "httplib2's TLS version range control (lines 161-174) allows organizations to enforce security policies. The OCaml library supports min_tls_version (line 86, 109) but creates config with range (min_version, `TLS_1_3) hardcoded at lines 123, 135, which doesn't allow restricting maximum version. Supporting both bounds provides better control for compliance and testing scenarios." 77 - }, 78 - { 79 - "source_repo": "third_party/python/httplib2", 80 - "source_language": "Python", 81 - "criticality": "low", 82 - "change_type": "feature", 83 - "title": "Support client certificate authentication with password-protected keys", 84 - "description": "httplib2 supports client certificates with optional password protection (line 185: load_cert_chain with key_password). The OCaml library should add support for password-protected client certificate keys.", 85 - "affected_files": [ 86 - "lib/requests.ml", 87 - "lib/requests.mli" 88 - ], 89 - "rationale": "Password-protected client keys are common in enterprise environments. httplib2's support for key_password parameter (line 185) shows this is a practical requirement. The OCaml library accepts tls_config but doesn't have explicit client certificate helpers with password support." 90 - }, 91 - { 92 - "source_repo": "third_party/python/httplib2", 93 - "source_language": "Python", 94 - "criticality": "medium", 95 - "change_type": "feature", 96 - "title": "Implement optimistic concurrency with automatic If-Match headers", 97 - "description": "httplib2 automatically adds If-Match headers with cached ETags for PUT/PATCH requests (optimistic_concurrency_methods, line 1295). This implements the W3C Editing on the Web pattern for lost update prevention. Consider adding this feature to reduce race conditions.", 98 - "affected_files": [ 99 - "lib/requests.ml", 100 - "lib/response.ml" 101 - ], 102 - "rationale": "httplib2's optimistic concurrency support (line 1295) prevents lost updates in distributed systems. The OCaml library has ETag support in response.ml (line 64) and caching infrastructure but doesn't automatically apply ETags to subsequent modification requests." 103 - }, 104 - { 105 - "source_repo": "third_party/python/httplib2", 106 - "source_language": "Python", 107 - "criticality": "low", 108 - "change_type": "enhancement", 109 - "title": "Add configurable redirect status code set", 110 - "description": "httplib2 allows customization of which HTTP status codes trigger redirects via redirect_codes attribute (line 119, 1291). The OCaml library hardcodes redirect behavior. Adding configurability supports non-standard server behaviors.", 111 - "affected_files": [ 112 - "lib/requests.ml", 113 - "lib/requests.mli" 114 - ], 115 - "rationale": "httplib2's REDIRECT_CODES (line 119) can be customized per Http instance (line 1291), allowing handling of non-standard redirect codes. The OCaml library likely has hardcoded redirect status checks, reducing flexibility for edge cases." 116 - }, 117 - { 118 - "source_repo": "third_party/python/httplib2", 119 - "source_language": "Python", 120 - "criticality": "medium", 121 - "change_type": "enhancement", 122 - "title": "Implement permanent redirect caching (301/308)", 123 - "description": "httplib2 caches permanent redirects (301 for safe methods, 308 for all) using a special -x-permanent-redirect-url marker (line 1480). Future requests can skip the original URL entirely. This optimization reduces latency and server load.", 124 - "affected_files": [ 125 - "lib/requests.ml", 126 - "lib/response.ml" 127 - ], 128 - "rationale": "httplib2's permanent redirect caching (lines 1479-1483) optimizes repeated requests by skipping redirects entirely on subsequent calls. The OCaml library follows redirects but doesn't appear to cache permanent redirects for reuse, causing unnecessary round trips." 129 - }, 130 - { 131 - "source_repo": "third_party/python/httplib2", 132 - "source_language": "Python", 133 - "criticality": "low", 134 - "change_type": "enhancement", 135 - "title": "Support 300 Multiple Choices with no-redirect mode", 136 - "description": "httplib2 handles status 300 (Multiple Choices) specially - it follows redirects if Location is present but allows follow_redirects=False to disable this (test at line 170-192). Consider explicit handling of 300 status to return the choice list to users.", 137 - "affected_files": [ 138 - "lib/requests.ml" 139 - ], 140 - "rationale": "Status 300 is unique in providing multiple redirect options. httplib2's handling shows that users may want to see the options rather than auto-following. The OCaml library should allow users to inspect 300 responses and choose manually." 141 - }, 142 - { 143 - "source_repo": "third_party/python/httplib2", 144 - "source_language": "Python", 145 - "criticality": "medium", 146 - "change_type": "enhancement", 147 - "title": "Add force_exception_to_status_code mode for error handling", 148 - "description": "httplib2 supports force_exception_to_status_code which converts exceptions (like RedirectLimit) into 4xx/5xx status responses instead of raising (line 1305). This allows uniform error handling via status codes. Consider adding a similar mode.", 149 - "affected_files": [ 150 - "lib/requests.ml", 151 - "lib/error.ml" 152 - ], 153 - "rationale": "httplib2's force_exception_to_status_code (line 1305) enables applications to handle all errors uniformly via HTTP status codes rather than exception handling. This can simplify error handling in some architectures. The OCaml library uses exceptions exclusively." 154 - }, 155 - { 156 - "source_repo": "third_party/python/httplib2", 157 - "source_language": "Python", 158 - "criticality": "medium", 159 - "change_type": "enhancement", 160 - "title": "Implement BadStatusLine retry on first attempt", 161 - "description": "httplib2 specially handles BadStatusLine exceptions on the first connection attempt by resetting the retry counter (lines 1404-1409). This recognizes that stale connections are expected and shouldn't count against retry limits. Apply similar logic.", 162 - "affected_files": [ 163 - "lib/requests.ml", 164 - "lib/http_client.ml" 165 - ], 166 - "rationale": "httplib2's BadStatusLine handling (lines 1400-1409) shows that the first request on a reused connection often fails due to server-side timeouts. Not counting this as a retry improves reliability. The OCaml library should treat the first connection error differently." 167 - }, 168 - { 169 - "source_repo": "third_party/python/httplib2", 170 - "source_language": "Python", 171 - "criticality": "medium", 172 - "change_type": "enhancement", 173 - "title": "Retry specific errno values (ENETUNREACH, EADDRNOTAVAIL)", 174 - "description": "httplib2 automatically retries socket errors with errno ENETUNREACH and EADDRNOTAVAIL (line 1379-1380), recognizing these as potentially transient network conditions. Add errno-specific retry logic to improve reliability in unstable networks.", 175 - "affected_files": [ 176 - "lib/requests.ml", 177 - "lib/retry.ml" 178 - ], 179 - "rationale": "httplib2's errno-specific retry logic (line 1379) handles transient network conditions that may resolve quickly. ENETUNREACH (network unreachable) and EADDRNOTAVAIL (address not available) often indicate temporary routing issues. The OCaml library should distinguish retriable socket errors from permanent failures." 180 - }, 181 - { 182 - "source_repo": "third_party/python/httplib2", 183 - "source_language": "Python", 184 - "criticality": "high", 185 - "change_type": "bug", 186 - "title": "Never retry on timeout exceptions", 187 - "description": "httplib2 immediately raises timeout exceptions without retry (lines 1371-1373, 1413-1414). The OCaml library should ensure timeouts are never retried as they indicate the operation took too long, not a transient failure.", 188 - "affected_files": [ 189 - "lib/retry.ml", 190 - "lib/requests.ml" 191 - ], 192 - "rationale": "httplib2's timeout handling (lines 1371-1373) recognizes that timeouts are not transient failures - retrying would just waste more time. The OCaml retry.ml has is_retryable including Timeout (line 216), which may cause incorrect behavior. Timeouts should fail fast." 193 - }, 194 - { 195 - "source_repo": "third_party/python/httplib2", 196 - "source_language": "Python", 197 - "criticality": "medium", 198 - "change_type": "enhancement", 199 - "title": "Add per-connection timeout configuration", 200 - "description": "httplib2 accepts a timeout parameter per Http instance (line 1229, 1307) that applies to all socket operations. The OCaml library has granular timeout config (connect, read, total) which is more flexible, but should ensure connection pool respects these consistently.", 201 - "affected_files": [ 202 - "lib/requests.ml" 203 - ], 204 - "rationale": "httplib2's per-instance timeout (line 1307) ensures consistent timeout behavior across all requests. The OCaml library has superior timeout granularity (Timeout.t with connect/read/total) but should verify that pooled connections properly inherit timeout settings from the session." 205 - }, 206 - { 207 - "source_repo": "third_party/python/httplib2", 208 - "source_language": "Python", 209 - "criticality": "low", 210 - "change_type": "enhancement", 211 - "title": "Add support for Vary header in cache validation", 212 - "description": "httplib2 stores Vary headers in the cache with -varied-{header} annotations (lines 445-453) to support content negotiation. When retrieving cached responses, it can validate that request headers match the cached variant. Implement Vary support for correct caching behavior.", 213 - "affected_files": [ 214 - "lib/response.ml", 215 - "lib/cache_control.ml" 216 - ], 217 - "rationale": "httplib2's Vary handling (lines 445-453) is required for RFC 9111 compliance when servers use content negotiation. The OCaml library has vary parsing (response.ml lines 182-192) but doesn't implement cache variant matching. This could cause serving wrong cached versions." 218 - }, 219 - { 220 - "source_repo": "third_party/python/httplib2", 221 - "source_language": "Python", 222 - "criticality": "medium", 223 - "change_type": "feature", 224 - "title": "Support conditional requests with If-Modified-Since and If-None-Match", 225 - "description": "httplib2 automatically strips If-None-Match and If-Modified-Since headers on redirects (lines 1484-1487) to prevent stale validation. The OCaml library should implement automatic conditional request header management when caching is enabled.", 226 - "affected_files": [ 227 - "lib/requests.ml", 228 - "lib/response.ml" 229 - ], 230 - "rationale": "httplib2's conditional header stripping (lines 1484-1487) prevents validation headers from being applied to redirect targets. The OCaml library has ETag/Last-Modified parsing (response.ml lines 64-66) but should manage conditional headers automatically when following redirects." 231 - }, 232 - { 233 - "source_repo": "third_party/python/httplib2", 234 - "source_language": "Python", 235 - "criticality": "low", 236 - "change_type": "enhancement", 237 - "title": "Implement 303 See Other redirect method change to GET", 238 - "description": "httplib2 converts POST/PUT/etc to GET when following 303 redirects (lines 1496-1498). The OCaml library should implement this RFC-compliant behavior where 303 responses force the next request to use GET.", 239 - "affected_files": [ 240 - "lib/requests.ml" 241 - ], 242 - "rationale": "RFC 9110 Section 15.4.4 requires that 303 responses be followed with GET (or HEAD) regardless of the original method. httplib2's implementation (lines 1496-1498) also converts 302 to GET, which is common browser behavior. The OCaml library should implement method conversion for 302/303." 243 - }, 244 - { 245 - "source_repo": "third_party/python/httplib2", 246 - "source_language": "Python", 247 - "criticality": "medium", 248 - "change_type": "enhancement", 249 - "title": "Add response chaining for redirect history tracking", 250 - "description": "httplib2 preserves redirect history by storing old_response (line 1492) and linking responses together. This allows users to examine the full redirect chain. Consider adding redirect history to the Response type.", 251 - "affected_files": [ 252 - "lib/response.ml", 253 - "lib/response.mli" 254 - ], 255 - "rationale": "httplib2's redirect chain preservation (line 1492, old_response) helps with debugging and analytics. Users can see all intermediate redirects and their headers. The OCaml Response type should optionally track the previous response in the redirect chain." 256 - }, 257 - { 258 - "source_repo": "third_party/python/httplib2", 259 - "source_language": "Python", 260 - "criticality": "low", 261 - "change_type": "feature", 262 - "title": "Add domain-scoped credential management", 263 - "description": "httplib2 stores credentials with optional domain scoping (line 1346-1349, credentials.add with domain parameter). This allows different credentials for different parts of the same host. Consider implementing domain/path-scoped auth credential storage.", 264 - "affected_files": [ 265 - "lib/auth.ml", 266 - "lib/requests.ml" 267 - ], 268 - "rationale": "httplib2's domain-scoped credentials (line 1349) allow fine-grained auth control - different credentials for /api vs /admin on the same host. The Authentication class checks inscope() (line 510) to determine if credentials apply. The OCaml library has session-level auth which is less flexible." 269 - }, 270 - { 271 - "source_repo": "third_party/python/httplib2", 272 - "source_language": "Python", 273 - "criticality": "low", 274 - "change_type": "feature", 275 - "title": "Support authentication scheme prioritization", 276 - "description": "httplib2 uses AUTH_SCHEME_ORDER (line 780) to try authentication methods in priority order: hmacdigest > googlelogin > digest > wsse > basic. When multiple schemes are offered, this ensures the most secure option is used. Add similar prioritization.", 277 - "affected_files": [ 278 - "lib/auth.ml", 279 - "lib/requests.ml" 280 - ], 281 - "rationale": "httplib2's authentication prioritization (lines 780, 1342-1344) ensures strongest auth is preferred when servers offer multiple options. The order prefers digest/HMAC over basic auth. The OCaml library should try auth schemes in security order when servers present multiple WWW-Authenticate headers." 282 - }, 283 - { 284 - "source_repo": "third_party/python/httplib2", 285 - "source_language": "Python", 286 - "criticality": "low", 287 - "change_type": "enhancement", 288 - "title": "Add ignore_etag mode for testing and debugging", 289 - "description": "httplib2 provides an ignore_etag flag (line 1303) that disables ETag-based caching. This is useful for testing, debugging, or when dealing with broken servers. Consider adding a similar debugging mode.", 290 - "affected_files": [ 291 - "lib/requests.ml", 292 - "lib/requests.mli" 293 - ], 294 - "rationale": "httplib2's ignore_etag mode (line 1303) helps debug caching issues and work around broken server implementations. The OCaml library should provide similar cache control flags for development and troubleshooting scenarios." 295 - }, 296 - { 297 - "source_repo": "third_party/python/httplib2", 298 - "source_language": "Python", 299 - "criticality": "low", 300 - "change_type": "enhancement", 301 - "title": "Support safe_methods configuration for custom safety semantics", 302 - "description": "httplib2 allows customizing which methods are considered 'safe' (line 1297, default from SAFE_METHODS). This affects redirect following and caching. Consider making safe method detection configurable.", 303 - "affected_files": [ 304 - "lib/requests.ml", 305 - "lib/method.ml" 306 - ], 307 - "rationale": "httplib2's safe_methods list (lines 116, 1297) can be customized for non-standard HTTP method semantics. While GET/HEAD/OPTIONS/TRACE are standardized (RFC 7231 Section 8.1.3), some applications may have custom methods. The OCaml library should allow method safety configuration." 308 - }, 309 - { 310 - "source_repo": "third_party/python/httplib2", 311 - "source_language": "Python", 312 - "criticality": "low", 313 - "change_type": "enhancement", 314 - "title": "Add hop-by-hop header filtering for caching", 315 - "description": "httplib2 filters hop-by-hop headers when caching responses using _get_end2end_headers (lines 190-193, 440). This implements RFC 9110 Section 7.6.1. Ensure the OCaml library doesn't cache Connection-specific headers.", 316 - "affected_files": [ 317 - "lib/response.ml" 318 - ], 319 - "rationale": "httplib2's hop-by-hop filtering (lines 190-193) prevents caching headers like Connection, Keep-Alive, Transfer-Encoding, etc. per RFC 9110. The list is extended with custom Connection header values. The OCaml library should filter these headers if caching is enabled." 320 - }, 321 - { 322 - "source_repo": "third_party/python/httplib2", 323 - "source_language": "Python", 324 - "criticality": "medium", 325 - "change_type": "enhancement", 326 - "title": "Implement content-location tracking for cache variants", 327 - "description": "httplib2 sets content-location header for permanent redirects to track the original URL (lines 1481-1482, 1493-1494). This helps with cache key management and variant tracking. Add content-location support for proper caching.", 328 - "affected_files": [ 329 - "lib/response.ml" 330 - ], 331 - "rationale": "httplib2's content-location tracking (lines 1481-1482) implements RFC 9110 Section 8.7 for identifying representation locations. This is important for caching redirected resources correctly. The OCaml library should track content-location when building responses." 332 - }, 333 - { 334 - "source_repo": "third_party/python/httplib2", 335 - "source_language": "Python", 336 - "criticality": "low", 337 - "change_type": "feature", 338 - "title": "Support min-fresh cache directive", 339 - "description": "httplib2's cache freshness calculation includes support for the min-fresh directive (lines 377-382), which requires the cached response to be fresh for at least N more seconds. Add min-fresh support to the cache control implementation.", 340 - "affected_files": [ 341 - "lib/cache_control.ml" 342 - ], 343 - "rationale": "httplib2's min-fresh support (lines 377-382) implements RFC 9111 Section 5.2.1.3, allowing clients to require extra freshness margin. This is useful for applications that need responses to remain fresh through processing. The OCaml cache_control.ml should parse and honor min-fresh." 344 - }, 345 - { 346 - "source_repo": "third_party/python/httplib2", 347 - "source_language": "Python", 348 - "criticality": "low", 349 - "change_type": "enhancement", 350 - "title": "Support Pragma: no-cache as fallback for old clients", 351 - "description": "httplib2 treats Pragma: no-cache as equivalent to Cache-Control: no-cache when Cache-Control is absent (lines 345-348). This maintains HTTP/1.0 compatibility. Add similar Pragma header support.", 352 - "affected_files": [ 353 - "lib/cache_control.ml" 354 - ], 355 - "rationale": "httplib2's Pragma handling (lines 345-348) supports legacy HTTP/1.0 clients per RFC 9111 Section 5.4. While Cache-Control is preferred, Pragma: no-cache should be honored for compatibility. The OCaml library should check Pragma when Cache-Control is missing." 356 - }, 357 - { 358 - "source_repo": "third_party/python/httplib2", 359 - "source_language": "Python", 360 - "criticality": "medium", 361 - "change_type": "enhancement", 362 - "title": "Implement only-if-cached directive for offline operation", 363 - "description": "httplib2 supports the only-if-cached directive (lines 353-354) which forces responses to come from cache only, never from the origin server. This enables offline operation modes. Add support for only-if-cached.", 364 - "affected_files": [ 365 - "lib/cache_control.ml", 366 - "lib/requests.ml" 367 - ], 368 - "rationale": "httplib2's only-if-cached support (lines 353-354) implements RFC 9111 Section 5.2.1.7, enabling offline/airplane mode where no network requests are made. This is useful for applications with optional offline capabilities. The OCaml library should support this directive." 369 - } 370 - ] 371 - }
-277
third_party/python/requests.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/python/requests", 5 - "source_language": "Python", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add response hooks system for request/response middleware", 9 - "description": "Python requests implements a hooks system that allows users to register callback functions to be called on responses (and potentially requests). This enables middleware-like functionality for logging, metrics, debugging, or custom response processing without modifying the core library. The OCaml library currently lacks this extensibility mechanism.", 10 - "affected_files": [ 11 - "lib/one.mli", 12 - "lib/one.ml", 13 - "lib/response.mli", 14 - "lib/response.ml" 15 - ], 16 - "rationale": "The hooks system in Python requests (requests/hooks.py) provides valuable extensibility. Users can inject custom logic at key points in the request lifecycle. This is particularly useful for cross-cutting concerns like logging, metrics collection, request/response transformation, or debugging. In OCaml, this could be implemented using function types like `(Response.t -> Response.t option)` that are called before returning the response. The hook could modify the response or perform side effects. This would make the library more flexible without adding bloat to the core API." 17 - }, 18 - { 19 - "source_repo": "third_party/python/requests", 20 - "source_language": "Python", 21 - "criticality": "low", 22 - "change_type": "feature", 23 - "title": "Add session management with persistent cookies and connection pooling", 24 - "description": "Python requests provides a Session object (sessions.py) that persists cookies, connection pooling, and configuration across multiple requests. The OCaml library has connection pooling via ocaml-conpool but lacks a high-level Session abstraction that automatically manages cookies and allows configuration to be set once and reused across requests.", 25 - "affected_files": [ 26 - "lib/one.mli", 27 - "lib/one.ml" 28 - ], 29 - "rationale": "Sessions in Python requests provide significant ergonomic benefits: automatic cookie handling (important for authenticated APIs), connection reuse (already handled by ocaml-conpool), and the ability to set default headers, auth, or timeouts once. While the OCaml library's One module is explicitly stateless, adding a complementary Session module would benefit users making multiple related requests. This could be implemented as a new module that wraps the existing functionality with a state record containing cookies (using http-cookie library), default headers, auth, and timeout settings. The cookie jar would automatically update from Set-Cookie headers and include cookies in subsequent requests." 30 - }, 31 - { 32 - "source_repo": "third_party/python/requests", 33 - "source_language": "Python", 34 - "criticality": "high", 35 - "change_type": "security", 36 - "title": "Improve credential handling in redirect scenarios", 37 - "description": "Python requests implements sophisticated logic (sessions.py:127-157, 282-299) to strip authentication headers when redirecting to different hosts or schemes. It also handles special cases like http->https redirects on standard ports. The OCaml library should implement similar security measures to prevent credential leakage during redirects.", 38 - "affected_files": [ 39 - "lib/one.ml", 40 - "lib/http_read.ml" 41 - ], 42 - "rationale": "The current OCaml implementation may not properly handle Authorization header stripping during cross-origin redirects. Python requests' SessionRedirectMixin.should_strip_auth() implements RFC 7235-compliant behavior: removing auth when hostname/port/scheme changes, with a special case allowing http->https on standard ports (80->443). This prevents accidentally sending credentials to third-party domains. The OCaml library should implement similar logic in its redirect handling code to match this security best practice. Without this, users' credentials could leak to unintended servers during redirect chains." 43 - }, 44 - { 45 - "source_repo": "third_party/python/requests", 46 - "source_language": "Python", 47 - "criticality": "medium", 48 - "change_type": "enhancement", 49 - "title": "Add support for .netrc authentication", 50 - "description": "Python requests automatically reads credentials from .netrc/_netrc files (utils.py:62, sessions.py:298) when no explicit authentication is provided. This is a standard Unix mechanism for storing machine credentials. The OCaml library could add similar functionality to improve usability for command-line tools and scripts.", 51 - "affected_files": [ 52 - "lib/auth.mli", 53 - "lib/auth.ml", 54 - "lib/one.ml" 55 - ], 56 - "rationale": "The .netrc file is a widely-used standard for storing credentials in Unix-like systems. Python requests checks for .netrc credentials when none are explicitly provided and when trust_env is enabled. This provides a secure way to avoid hardcoding credentials while maintaining convenience. The OCaml library could implement this using the netrc library from opam. Add a `?use_netrc:bool` parameter (default: true) that, when enabled, automatically loads credentials for the target host. This would improve developer experience for CLI tools and automated scripts." 57 - }, 58 - { 59 - "source_repo": "third_party/python/requests", 60 - "source_language": "Python", 61 - "criticality": "low", 62 - "change_type": "feature", 63 - "title": "Add proxy authentication support", 64 - "description": "Python requests includes HTTPProxyAuth class (auth.py:99-104) and extensive proxy handling (adapters.py:569-588) including automatic extraction of credentials from proxy URLs. The OCaml library currently lacks comprehensive proxy support.", 65 - "affected_files": [ 66 - "lib/auth.mli", 67 - "lib/auth.ml", 68 - "lib/one.ml" 69 - ], 70 - "rationale": "While full proxy support is complex, adding proxy authentication (Proxy-Authorization header) would enable basic proxy use cases. Python requests supports both explicit proxy auth objects and extracting credentials from proxy URLs (e.g., http://user:pass@proxy:8080). The OCaml library could add: (1) Auth.proxy variant for Proxy-Authorization header, (2) utility function to parse proxy URLs and extract credentials, (3) documentation on using proxies with the library. This would be especially valuable for enterprise environments where HTTP proxies are common." 71 - }, 72 - { 73 - "source_repo": "third_party/python/requests", 74 - "source_language": "Python", 75 - "criticality": "medium", 76 - "change_type": "enhancement", 77 - "title": "Add charset detection and encoding handling for text responses", 78 - "description": "Python requests uses sophisticated charset detection (models.py, utils.py) including examining Content-Type headers, detecting BOMs, and using chardet library as fallback. It also properly handles the 'encoding' attribute on responses. The OCaml library could improve text handling with similar charset detection.", 79 - "affected_files": [ 80 - "lib/response.mli", 81 - "lib/response.ml", 82 - "lib/mime.ml" 83 - ], 84 - "rationale": "The Python requests library has robust charset handling: it first checks the Content-Type header for a charset parameter, then looks for BOM markers, and falls back to chardet for heuristic detection. The Response.text property uses the detected encoding. For the OCaml library, this could be implemented using the uutf library for UTF encoding detection/conversion and examining the Content-Type header. Add Response.text_with_encoding function that returns (string * string option) where the second element is the detected encoding. This prevents mojibake (garbled text) when servers don't properly specify charset." 85 - }, 86 - { 87 - "source_repo": "third_party/python/requests", 88 - "source_language": "Python", 89 - "criticality": "high", 90 - "change_type": "bug", 91 - "title": "Add proper handling of chunked encoding errors", 92 - "description": "Python requests has specific exception types (exceptions.py:119-120) and error handling for chunked encoding errors, which can occur when servers send malformed chunked responses. The OCaml library should detect and report these errors clearly rather than failing with generic parsing errors.", 93 - "affected_files": [ 94 - "lib/error.mli", 95 - "lib/error.ml", 96 - "lib/http_read.ml" 97 - ], 98 - "rationale": "Chunked transfer encoding errors are a specific class of protocol violations that Python requests handles explicitly with ChunkedEncodingError. These occur when a server declares 'Transfer-Encoding: chunked' but sends invalid chunk markers or sizes. The OCaml library should add an error variant `Chunked_encoding_error of { reason: string }` and detect these issues during response body parsing in http_read.ml. This provides better diagnostics than generic parse failures, helping users identify whether the issue is with their client code or the server's protocol compliance." 99 - }, 100 - { 101 - "source_repo": "third_party/python/requests", 102 - "source_language": "Python", 103 - "criticality": "medium", 104 - "change_type": "feature", 105 - "title": "Add support for streaming request bodies with progress callbacks", 106 - "description": "Python requests supports streaming uploads with proper Content-Length handling and the ability to monitor upload progress. While the OCaml library has streaming via Body.of_stream, it could add more ergonomic progress tracking for large uploads similar to the existing download progress callback.", 107 - "affected_files": [ 108 - "lib/body.mli", 109 - "lib/body.ml", 110 - "lib/one.mli" 111 - ], 112 - "rationale": "The upload function in one.mli already has on_progress for tracking, but this should be extended to all streaming uploads through Body.of_stream_with_progress constructor. This would match Python requests' ability to track upload progress. Implementation: Add optional progress callback to Body.of_stream that's called periodically with bytes sent. This is particularly valuable for large file uploads where users want to display progress bars or monitor upload speed." 113 - }, 114 - { 115 - "source_repo": "third_party/python/requests", 116 - "source_language": "Python", 117 - "criticality": "low", 118 - "change_type": "enhancement", 119 - "title": "Add PreparedRequest concept for request inspection and modification", 120 - "description": "Python requests separates Request construction from PreparedRequest (the final HTTP message). This allows users to inspect/modify the exact bytes that will be sent, useful for debugging and custom authentication schemes. The OCaml library could expose similar functionality.", 121 - "affected_files": [ 122 - "lib/one.mli", 123 - "lib/http_write.mli" 124 - ], 125 - "rationale": "The PreparedRequest pattern in Python (models.py:230+) allows users to see the exact HTTP request before it's sent, including all transformations from auth, hooks, etc. This is valuable for debugging, testing, and custom authentication that needs to sign the exact request. For OCaml, this could be a `prepare_request` function that returns a record with method, headers, body, and URL, plus a `send_prepared` function. The prepared request could also be serialized to a string for logging. This would help users debug header injection issues, verify auth signatures, or implement custom request signing." 126 - }, 127 - { 128 - "source_repo": "third_party/python/requests", 129 - "source_language": "Python", 130 - "criticality": "medium", 131 - "change_type": "enhancement", 132 - "title": "Improve retry logic with exponential backoff jitter randomization", 133 - "description": "The OCaml library already has jitter in retry.ml, but the implementation could be refined to match Python's urllib3 Retry class behavior. Python uses more sophisticated jitter algorithms to prevent thundering herd problems and includes configurable backoff strategies.", 134 - "affected_files": [ 135 - "lib/retry.ml", 136 - "lib/retry.mli" 137 - ], 138 - "rationale": "While the OCaml library has basic jitter (adding random value up to base_delay), Python's urllib3.util.retry.Retry (used by requests) implements more sophisticated strategies including full jitter (random between 0 and backoff) and decorrelated jitter. The current OCaml implementation adds jitter on top of backoff, effectively doubling max delay. Consider changing to: `if jitter then Random.float base_delay else base_delay` to match standard jitter behavior. Additionally, document the jitter algorithm clearly since this affects rate limiting and server load patterns." 139 - }, 140 - { 141 - "source_repo": "third_party/python/requests", 142 - "source_language": "Python", 143 - "criticality": "low", 144 - "change_type": "feature", 145 - "title": "Add link header parsing helper", 146 - "description": "Python requests includes parse_header_links() (utils.py:62) to parse RFC 8288 Link headers into structured data. These headers are commonly used for pagination in REST APIs. The OCaml library could add a similar helper to Response module.", 147 - "affected_files": [ 148 - "lib/response.mli", 149 - "lib/response.ml" 150 - ], 151 - "rationale": "Link headers (RFC 8288) are widely used in REST APIs for pagination, especially GitHub, GitLab, and similar services. They contain URLs with rel attributes like 'next', 'prev', 'first', 'last'. Python requests provides parse_header_links() that returns a list of dicts with 'url' and 'rel'. For OCaml, add `Response.links : t -> (string * (string * string) list) list` that parses Link headers into a list of (url, params) where params includes 'rel'. This makes it much easier to implement pagination without manual header parsing." 152 - }, 153 - { 154 - "source_repo": "third_party/python/requests", 155 - "source_language": "Python", 156 - "criticality": "high", 157 - "change_type": "bug", 158 - "title": "Add protection against header injection attacks", 159 - "description": "Python requests validates header names and values (utils.py:29-33, _internal_utils.py) to prevent CRLF injection attacks. The OCaml library should implement similar validation to prevent attackers from injecting additional headers or splitting HTTP requests.", 160 - "affected_files": [ 161 - "lib/headers.ml", 162 - "lib/error.mli", 163 - "lib/error.ml" 164 - ], 165 - "rationale": "Header injection is a serious security vulnerability (CWE-113) where an attacker includes CRLF characters (\\r\\n) in header values to inject additional headers or even a second HTTP request. Python's check_header_validity() rejects headers containing these characters. The OCaml library should add validation in Headers.set and Headers.add that checks for \\r, \\n, and \\0 characters in both header names and values. Raise Error.Invalid_header if found. This prevents a whole class of request smuggling and header injection attacks. The validation is already partially present but should be comprehensive and well-documented." 166 - }, 167 - { 168 - "source_repo": "third_party/python/requests", 169 - "source_language": "Python", 170 - "criticality": "medium", 171 - "change_type": "enhancement", 172 - "title": "Add default User-Agent header", 173 - "description": "Python requests automatically sets a User-Agent header identifying itself and the Python version (utils.py:41-71). This is good HTTP citizenship and helps servers track client types. The OCaml library could add a similar default.", 174 - "affected_files": [ 175 - "lib/headers.ml", 176 - "lib/one.ml" 177 - ], 178 - "rationale": "Setting a User-Agent is HTTP best practice and many servers require it or use it for analytics. Python requests sets 'python-requests/X.Y.Z' by default. The OCaml library could set 'ocaml-requests/X.Y.Z OCaml/A.B.C Eio' including library version, OCaml version, and runtime. This should be easily overridable by users but set by default. Benefits: (1) helps server operators identify clients, (2) some APIs require User-Agent, (3) demonstrates HTTP best practices. Implementation: add to default headers in Headers module, document how to override." 179 - }, 180 - { 181 - "source_repo": "third_party/python/requests", 182 - "source_language": "Python", 183 - "criticality": "low", 184 - "change_type": "feature", 185 - "title": "Add support for streaming JSON responses", 186 - "description": "For very large JSON responses, it would be beneficial to support streaming JSON parsing rather than loading the entire response into memory. While Python requests doesn't have built-in streaming JSON, this is a common need that the OCaml library could address with jsont's streaming capabilities.", 187 - "affected_files": [ 188 - "lib/response.mli", 189 - "lib/response.ml" 190 - ], 191 - "rationale": "Large JSON responses (e.g., database exports, large API responses) can cause memory issues when fully materialized. The OCaml library already uses jsont which supports streaming. Add `Response.json_stream : t -> Jsont.json` that parses JSON from the response body stream without buffering the entire response. This would be particularly valuable for responses in the hundreds of MB or GB range. Python requests users often work around this limitation with ijson library; having it built-in would be a competitive advantage." 192 - }, 193 - { 194 - "source_repo": "third_party/python/requests", 195 - "source_language": "Python", 196 - "criticality": "medium", 197 - "change_type": "enhancement", 198 - "title": "Add comprehensive test coverage matching Python requests test patterns", 199 - "description": "Python requests has extensive test coverage (3000+ lines in test_requests.py alone) covering edge cases, error conditions, redirects, authentication, encoding, and more. The OCaml library's test coverage is significantly lighter and could be expanded.", 200 - "affected_files": [ 201 - "test/test_simple.ml", 202 - "test/test_localhost.ml", 203 - "test/test_one.ml" 204 - ], 205 - "rationale": "Python requests' comprehensive test suite (tests/test_requests.py with 3040 lines) covers numerous edge cases that the OCaml library doesn't currently test: chunked encoding edge cases, various redirect scenarios, header case sensitivity, authentication schemes, timeout behavior, error conditions, encoding detection, etc. While the OCaml library has basic tests, expanding to cover: (1) all error types from error.mli, (2) redirect limit and cross-origin auth stripping, (3) retry backoff timing, (4) digest auth challenge parsing, (5) multipart encoding edge cases would significantly improve reliability. Consider using an HTTP mock server approach like Python's testserver." 206 - }, 207 - { 208 - "source_repo": "third_party/python/requests", 209 - "source_language": "Python", 210 - "criticality": "low", 211 - "change_type": "enhancement", 212 - "title": "Add support for SOCKS proxy", 213 - "description": "Python requests supports SOCKS proxies through urllib3's SOCKSProxyManager (adapters.py:59-63, 256-266). While less common than HTTP proxies, SOCKS support is valuable for users who need to route through SOCKS proxies or use Tor.", 214 - "affected_files": [ 215 - "lib/one.mli", 216 - "lib/one.ml" 217 - ], 218 - "rationale": "SOCKS proxy support enables routing through Tor for anonymity, corporate SOCKS proxies, or SSH tunnels. Python requests handles this through the urllib3 library with PySocks. For OCaml, this would require using a SOCKS library (socks-ocaml if available, or implementing SOCKS5 protocol). Given the complexity, this is low priority, but documenting a workaround (using torsocks or similar) would help users. Alternatively, if there's demand, implement SOCKS5 support using the Eio networking primitives." 219 - }, 220 - { 221 - "source_repo": "third_party/python/requests", 222 - "source_language": "Python", 223 - "criticality": "medium", 224 - "change_type": "feature", 225 - "title": "Add support for request/response history tracking", 226 - "description": "Python requests tracks the history of redirects in response.history, allowing users to see the full redirect chain. The OCaml library could add similar functionality to help debug redirect issues and understand the full request path.", 227 - "affected_files": [ 228 - "lib/response.mli", 229 - "lib/response.ml", 230 - "lib/one.ml" 231 - ], 232 - "rationale": "When following redirects, Python requests builds a response.history list containing all intermediate responses. This is valuable for debugging (seeing where redirects went), analytics (understanding redirect chains), and compliance (tracking Cross-Origin redirects). For OCaml, add a `history : Response.t list` field to Response.t (or make it available via Response.history accessor). Each redirect would prepend the previous response to history. The final response would contain the full chain. This helps users understand complex redirect scenarios and debug issues like redirect loops or unexpected cross-domain redirects." 233 - }, 234 - { 235 - "source_repo": "third_party/python/requests", 236 - "source_language": "Python", 237 - "criticality": "low", 238 - "change_type": "enhancement", 239 - "title": "Add warnings system for deprecated features and common mistakes", 240 - "description": "Python requests uses the warnings module extensively to warn about deprecated features, non-optimal usage patterns, and potential issues (e.g., FileModeWarning for binary files opened in text mode). The OCaml library could use the Logs library more extensively for similar warnings.", 241 - "affected_files": [ 242 - "lib/body.ml", 243 - "lib/one.ml", 244 - "lib/headers.ml" 245 - ], 246 - "rationale": "Python's warnings help users discover issues before they become bugs: FileModeWarning for incorrect file modes (utils.py:165-175), RequestsDependencyWarning for version mismatches, DeprecationWarning for old APIs. The OCaml library could use Logs.warn more extensively to help users: warn when using verify_tls=false (security issue), warn when response bodies aren't closed in certain scenarios, warn about potentially expensive operations. This improves developer experience by catching issues early. Keep warnings at DEBUG level to avoid noise, but provide a way to enable them for development." 247 - }, 248 - { 249 - "source_repo": "third_party/python/requests", 250 - "source_language": "Python", 251 - "criticality": "medium", 252 - "change_type": "enhancement", 253 - "title": "Improve documentation with more comprehensive examples", 254 - "description": "Python requests is famous for its excellent documentation with numerous examples. The OCaml library has good API docs but could expand examples section to cover common patterns like pagination, file uploads, error handling, retry strategies, and authentication.", 255 - "affected_files": [ 256 - "README.md", 257 - "lib/one.mli", 258 - "lib/response.mli", 259 - "examples/" 260 - ], 261 - "rationale": "One of Python requests' key success factors is exceptional documentation with clear examples. The OCaml library's documentation is good but could be enhanced with: (1) comprehensive examples/ directory covering common use cases, (2) troubleshooting guide for common errors, (3) comparison guide for users coming from other HTTP libraries, (4) cookbook of patterns (pagination, rate limiting, file uploads, authentication flows), (5) performance guide explaining when to use streaming vs buffering. This would significantly improve adoption and reduce support burden." 262 - }, 263 - { 264 - "source_repo": "third_party/python/requests", 265 - "source_language": "Python", 266 - "criticality": "high", 267 - "change_type": "security", 268 - "title": "Add validation for redirect location headers", 269 - "description": "Python requests carefully validates and sanitizes redirect Location headers (sessions.py:107-125, 198-217) to handle various edge cases like relative URLs, fragment preservation, and encoding issues. The OCaml library should implement similar robust redirect handling.", 270 - "affected_files": [ 271 - "lib/one.ml", 272 - "lib/http_read.ml" 273 - ], 274 - "rationale": "Python's redirect handling in SessionRedirectMixin is sophisticated: it handles scheme-relative URLs (//example.com), relative paths, fragment preservation (RFC 7231 7.1.2), proper encoding with requote_uri, and prevents redirects to invalid URLs. The OCaml library should add similar validation: (1) validate Location header is a valid URI, (2) handle relative URLs by resolving against current URL, (3) preserve fragments when appropriate, (4) reject redirects to invalid schemes, (5) handle Unicode in URLs properly with percent encoding. This prevents redirect-based attacks and ensures RFC compliance." 275 - } 276 - ] 277 - }
-182
third_party/python/uplink.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/python/uplink", 5 - "source_language": "Python", 6 - "criticality": "high", 7 - "change_type": "feature", 8 - "title": "Add request/response middleware hooks system", 9 - "description": "Implement a hooks system similar to Uplink's TransactionHook that allows users to inject custom logic at specific points in the request/response lifecycle. Uplink provides three hook types: audit_request (before sending), handle_response (after receiving), and handle_exception (on error). These hooks can be chained together and applied globally or per-request. This enables use cases like request logging, response transformation, custom error handling, metrics collection, and request modification without modifying the core library.", 10 - "affected_files": [ 11 - "lib/requests.mli", 12 - "lib/requests.ml", 13 - "lib/one.mli", 14 - "lib/one.ml" 15 - ], 16 - "rationale": "The OCaml library currently has no middleware/hooks system, making it difficult to add cross-cutting concerns like logging, metrics, or custom transformations without forking the library. Uplink's TransactionHook pattern demonstrates the value of this feature - it allows audit_request for inspecting/modifying requests before sending, handle_response for transforming responses, and handle_exception for custom error handling. This is a common pattern in mature HTTP clients (Python requests' hooks, Go's http.RoundTripper, Rust reqwest's middleware). Implementation should use OCaml's function types: type hook = { before_request: (Uri.t -> Headers.t -> Headers.t) option; after_response: (Response.t -> Response.t) option; on_error: (Error.error -> Error.error option) option }. This would enable users to implement request signing, response caching, custom retry logic, and telemetry without library changes." 17 - }, 18 - { 19 - "source_repo": "third_party/python/uplink", 20 - "source_language": "Python", 21 - "criticality": "medium", 22 - "change_type": "feature", 23 - "title": "Add rate limiting functionality per host/endpoint", 24 - "description": "Implement client-side rate limiting similar to Uplink's @ratelimit decorator. Uplink provides per-host rate limiting with configurable max_calls and period (e.g., 15 calls per 900 seconds). When the limit is reached, it either sleeps until the period resets or raises RateLimitExceeded. The implementation uses thread-safe limiters grouped by host:port, with monotonic clock tracking. This prevents clients from overwhelming servers and helps comply with API rate limits.", 25 - "affected_files": [ 26 - "lib/requests.mli", 27 - "lib/requests.ml", 28 - "lib/one.mli" 29 - ], 30 - "rationale": "Many REST APIs enforce rate limits (GitHub: 5000/hour, Twitter: varies, etc.). Currently, OCaml clients must manually track request counts and sleep, which is error-prone and leads to code duplication. Uplink's implementation shows best practices: per-host tracking (different hosts have different limits), automatic period reset using monotonic time, thread-safe with locks, and configurable behavior (sleep vs exception). For OCaml, implement as: type rate_limit = { max_calls: int; period: float; raise_on_limit: bool } with a module RateLimit that maintains a hashtable of (host, port) -> limiter state. The library should use Eio.Time.Mono.now for tracking and Eio.Time.sleep for delays. This is especially valuable for the session API where multiple requests share state. Uplink defaults to 15 calls/900s but allows customization - OCaml should be similarly flexible." 31 - }, 32 - { 33 - "source_repo": "third_party/python/uplink", 34 - "source_language": "Python", 35 - "criticality": "medium", 36 - "change_type": "enhancement", 37 - "title": "Extend retry system with composable predicates and backoff strategies", 38 - "description": "Enhance the retry module to support composable retry conditions (when) and backoff strategies like Uplink. Currently, OCaml has fixed retry logic (status codes + error types). Uplink provides: (1) Composable predicates via | operator (retry.when.status_5xx() | retry.when.raises(ConnectionError)), (2) Separate response vs exception predicates, (3) Multiple backoff strategies (exponential, fixed, from_iterable) that can be composed with | for fallbacks, (4) Per-request customization of retry behavior. The key insight is separating 'when to retry' (predicates) from 'how long to wait' (backoff) from 'when to stop' (max attempts/time).", 39 - "affected_files": [ 40 - "lib/retry.mli", 41 - "lib/retry.ml" 42 - ], 43 - "rationale": "The current OCaml retry implementation has a fixed config record with status_forcelist and allowed_methods, but lacks flexibility for custom retry logic. Uplink's approach shows the value of composable predicates - users can retry on specific exceptions (retry.when.raises(Timeout)), specific status codes (retry.when.status(503)), or combinations. The composability via | operator is powerful and user-friendly. For OCaml, implement: type retry_predicate = Response.t -> bool and type retry_predicate_exn = Error.error -> bool, with combinators: val (||): retry_predicate -> retry_predicate -> retry_predicate. Similarly, backoff strategies should be pluggable: type backoff = attempt:int -> float, with built-in exponential, fixed, and jittered variants. This allows advanced users to implement custom logic (e.g., retry only on specific error messages, adaptive backoff based on Retry-After headers) while maintaining simple defaults." 44 - }, 45 - { 46 - "source_repo": "third_party/python/uplink", 47 - "source_language": "Python", 48 - "criticality": "medium", 49 - "change_type": "feature", 50 - "title": "Add pluggable converter system for request/response serialization", 51 - "description": "Implement a converter/serialization system similar to Uplink's ConverterFactory pattern. Uplink provides converters for transforming request bodies (CONVERT_TO_REQUEST_BODY), response bodies (CONVERT_FROM_RESPONSE_BODY), and values to strings (CONVERT_TO_STRING). It supports multiple serialization libraries (marshmallow schemas, pydantic models, standard JSON) through a registry with fallback chain. Users can register custom converters for domain types. The system uses a factory pattern where converters can inspect type annotations and return appropriate serialization functions.", 52 - "affected_files": [ 53 - "lib/body.mli", 54 - "lib/body.ml", 55 - "lib/response.mli", 56 - "lib/response.ml" 57 - ], 58 - "rationale": "Currently, the OCaml library only supports Jsont.json for JSON serialization. Uplink's ConverterFactory shows how to support multiple serialization formats (JSON Schema validators, MessagePack, Protocol Buffers, custom domain serializers). The key insight is a registry pattern: type 'a converter = { encode: 'a -> Body.t; decode: string -> ('a, string) result } with a module Converter that maintains a type-indexed map. OCaml's ppx_deriving or similar could generate converters automatically. This enables users to write: let user = Response.json_as User.t response instead of manual JSON parsing. The chain pattern (try converter A, fall back to B) is valuable for gradual migration. For OCaml, leverage GADTs or first-class modules: module type CONVERTER = sig type t val encode : t -> Body.t val decode : string -> (t, string) result end. This is lower priority than hooks but valuable for ergonomics, especially with ppx_deriving_yojson or similar." 59 - }, 60 - { 61 - "source_repo": "third_party/python/uplink", 62 - "source_language": "Python", 63 - "criticality": "low", 64 - "change_type": "enhancement", 65 - "title": "Add timeout configuration per-request override", 66 - "description": "Enhance timeout handling to allow per-request overrides while maintaining session defaults, similar to Uplink's approach. Uplink allows @timeout decorator at class level (default) and method level (override). The OCaml library has Timeout.t configuration but it's not clear if individual requests can override session timeouts. Implement Request.with_timeout function that creates a request with modified timeout, preserving other configuration.", 67 - "affected_files": [ 68 - "lib/requests.mli", 69 - "lib/requests.ml", 70 - "lib/one.mli" 71 - ], 72 - "rationale": "Different endpoints often require different timeouts - quick health checks (1s) vs long-running reports (5min). Uplink's decorator pattern shows this is a common need. The OCaml library has Timeout.create with connect/read/total options, but the API should clarify per-request overrides. Looking at requests.mli, the main API uses set_timeout which appears to modify the session state globally. Better pattern: let response = Requests.get ~timeout:(Timeout.create ~total:60.0 ()) req url to override just for that request without mutating session. This is especially important for the session-based API where you want different timeouts for different endpoints. Implementation should thread timeout through the request but not mutate the session's default timeout config. This is a lower priority enhancement but improves API ergonomics." 73 - }, 74 - { 75 - "source_repo": "third_party/python/uplink", 76 - "source_language": "Python", 77 - "criticality": "medium", 78 - "change_type": "enhancement", 79 - "title": "Add support for custom retry backoff strategies beyond exponential", 80 - "description": "Extend retry backoff to support fixed delays, custom iterables, and fallback composition. Uplink provides: retry.backoff.exponential(multiplier, minimum, maximum), retry.backoff.fixed(delay), retry.backoff.from_iterable([0.1, 0.5, 1.0, 5.0]), and composition via | operator for fallback. The OCaml library only has exponential backoff with factor and max. Add support for fixed backoff (always wait N seconds) and custom sequences (useful for testing or specific API requirements).", 81 - "affected_files": [ 82 - "lib/retry.mli", 83 - "lib/retry.ml" 84 - ], 85 - "rationale": "While exponential backoff is good default, some APIs specify exact retry schedules (AWS suggests [1, 2, 4, 8, 16, 32] seconds for some services). Fixed backoff is useful for APIs that reset rate limits at fixed intervals. Uplink's from_iterable allows users to specify exact delays: [0, 0, 1, 5] means no wait for first two retries, then 1s, then 5s. The | composition operator allows fallback: exponential() | fixed(60) means 'use exponential but if it returns None, use fixed 60s'. For OCaml, extend retry config: type backoff_strategy = Exponential of {factor: float; max: float} | Fixed of float | Custom of (int -> float) | Sequence of float list. This gives users fine-grained control while maintaining simple defaults. Implementation in calculate_backoff should pattern match on strategy. Lower priority than composable predicates but complements that feature well." 86 - }, 87 - { 88 - "source_repo": "third_party/python/uplink", 89 - "source_language": "Python", 90 - "criticality": "high", 91 - "change_type": "feature", 92 - "title": "Add Result-based error handling API alongside exceptions", 93 - "description": "Provide an alternative API that returns Result.t instead of raising exceptions, allowing users to choose between exceptions (current) and explicit error handling. Add module Requests.Result with functions like: val get : t -> string -> (Response.t, Error.error) result. This complements the existing exception-based API without replacing it. Uplink uses exceptions exclusively, but OCaml idioms favor Result for recoverable errors. Both patterns have merit - exceptions for 'exceptional' cases (network failures), Results for expected cases (HTTP 4xx/5xx).", 94 - "affected_files": [ 95 - "lib/requests.mli", 96 - "lib/requests.ml", 97 - "lib/one.mli", 98 - "lib/one.ml" 99 - ], 100 - "rationale": "The library currently uses Eio.Io exceptions following Eio patterns, which is reasonable but not idiomatic for OCaml HTTP clients. Many OCaml users prefer Result.t for HTTP errors since 404s and 500s are expected conditions, not exceptional. Uplink uses exceptions, but that's Python convention. OCaml convention (see Cohttp, Piaf) is Result-based APIs. Provide both: existing exception-based API for users who prefer try/with, and new Result-based API for users who prefer match. Implementation can share internals: let get_result req url = try Ok (get req url) with Eio.Io (Error.E e, _) -> Error e. The Result API should also handle HTTP 4xx/5xx as errors (unlike current API which returns responses). This gives users choice: Requests.get for exceptions, Requests.Result.get for Results. Both APIs can coexist - Result module can be thin wrapper. This addresses OCaml ecosystem expectations while maintaining Eio compatibility." 101 - }, 102 - { 103 - "source_repo": "third_party/python/uplink", 104 - "source_language": "Python", 105 - "criticality": "low", 106 - "change_type": "enhancement", 107 - "title": "Add response handler for automatic deserialization based on Content-Type", 108 - "description": "Implement automatic response deserialization based on Content-Type header, similar to how Uplink uses converters with type hints. When Content-Type is application/json, automatically parse as JSON. When text/*, return as string. When application/octet-stream, return as bytes. Provide Response.auto that inspects Content-Type and returns appropriate OCaml value (Jsont.json for JSON, string for text, bytes for binary). This reduces boilerplate: let json = Response.auto resp instead of manually checking content-type then calling Response.json.", 109 - "affected_files": [ 110 - "lib/response.mli", 111 - "lib/response.ml" 112 - ], 113 - "rationale": "Currently, users must manually call Response.json, Response.text, etc. based on expected content type. Uplink's converter system automatically deserializes based on return type annotations. While OCaml lacks runtime type reflection, we can inspect Content-Type header and dispatch appropriately. Implement: type response_value = Json of Jsont.json | Text of string | Binary of string and val auto : t -> response_value. For known MIME types (application/json, text/*, image/*, etc.), automatically parse. This is especially useful when working with APIs that return different content types per endpoint. The auto function should handle errors gracefully (if Content-Type says JSON but body is malformed, return error). This is lower priority 'nice-to-have' that reduces boilerplate but isn't critical. Some HTTP client libraries do this (httpie CLI, some Ruby libraries) while others don't (curl, Go net/http). It's a convenience feature that saves 2-3 lines per request." 114 - }, 115 - { 116 - "source_repo": "third_party/python/uplink", 117 - "source_language": "Python", 118 - "criticality": "medium", 119 - "change_type": "feature", 120 - "title": "Add session context dictionary for request-scoped metadata", 121 - "description": "Add a context mechanism for passing request-scoped metadata through the request lifecycle, similar to Uplink's context argument annotation. Uplink allows context dictionaries that flow through hooks and converters, enabling request IDs, tracing spans, authentication state, or custom metadata. Implement as: type 'a context_key and val create_context_key : string -> 'a context_key and val with_context : t -> 'a context_key -> 'a -> t that allows attaching typed metadata to requests. Hooks can then access this metadata for logging, tracing, etc.", 122 - "affected_files": [ 123 - "lib/requests.mli", 124 - "lib/requests.ml" 125 - ], 126 - "rationale": "Distributed tracing, request IDs, and custom metadata are common in microservices. Uplink's context pattern shows how to thread this through request lifecycle - hooks can inspect context for logging/metrics, auth can store state in context, etc. Currently, the OCaml library has no way to attach request-scoped metadata. This becomes important with hooks (#1) - hooks need access to context. Implementation should use heterogeneous maps (similar to Dream.request's fields): type context = { store : (int, Obj.t) Hashtbl.t } with type-safe wrappers using context_key as witness. Each key gets unique ID via ref counter. This pattern is used in many OCaml web frameworks (Dream, Opium). Users can then attach trace IDs: let req = with_context req trace_id \"abc-123\" and hooks retrieve it. This is medium priority because it's less useful without hooks, but valuable for observability and should be designed together with hooks system." 127 - }, 128 - { 129 - "source_repo": "third_party/python/uplink", 130 - "source_language": "Python", 131 - "criticality": "low", 132 - "change_type": "enhancement", 133 - "title": "Add support for streaming request bodies with progress callbacks", 134 - "description": "Enhance streaming body support to include progress callbacks for upload tracking. Uplink supports this through custom converters and hooks. Add Body.of_stream_with_progress that accepts a progress callback: (bytes_sent:int64 -> unit) -> unit. This enables progress bars for large uploads, bandwidth throttling, and upload metrics. The callback is invoked periodically as chunks are sent.", 135 - "affected_files": [ 136 - "lib/body.mli", 137 - "lib/body.ml" 138 - ], 139 - "rationale": "The library has Body.of_stream for streaming uploads but no progress visibility. Uplink enables this via audit_request hook that can wrap the body stream. For large file uploads (videos, backups, datasets), users want progress feedback. Implementation: wrap the Eio.Flow.source with a tracking layer that calls callback every N bytes. Similar to curl's CURLOPT_PROGRESSFUNCTION or Python requests' stream with manual chunking. This is low priority because users can implement it themselves by wrapping the stream, but it's a common enough pattern that library support would reduce boilerplate. Many CLI tools need this (progress bars with Notty or similar). Implementation complexity is low - just wrap the flow's read method to track bytes and invoke callback. Could also support bandwidth throttling by sleeping in the wrapper." 140 - }, 141 - { 142 - "source_repo": "third_party/python/uplink", 143 - "source_language": "Python", 144 - "criticality": "low", 145 - "change_type": "enhancement", 146 - "title": "Add declarative request builder pattern for complex requests", 147 - "description": "Add a builder pattern for constructing complex requests incrementally, inspired by Uplink's RequestBuilder pattern (though expressed differently in OCaml). Implement Request.builder : unit -> builder with methods like: with_header, with_query, with_body, with_auth, etc., culminating in build : builder -> request. This provides an alternative to function arguments for complex requests. Example: Request.builder () |> with_header \"X-API-Key\" \"secret\" |> with_query [(\"limit\", \"100\")] |> with_body (Body.json data) |> build |> Requests.send req url.", 148 - "affected_files": [ 149 - "lib/requests.mli", 150 - "lib/requests.ml" 151 - ], 152 - "rationale": "Uplink's request preparation goes through RequestDefinitionBuilder which accumulates configuration. While the OCaml API uses labeled arguments, complex requests with many options become unwieldy: Requests.post ~headers:h ~body:b ~auth:a ~timeout:t req url. A builder pattern is more readable: builder() |> with_headers h |> with_body b |> with_auth a |> with_timeout t |> send req url. This is common in Java (OkHttp), Rust (reqwest), Go (builder patterns). OCaml's labeled args partially address this, but builders enable partial configuration and reuse. For example: let base = builder() |> with_header \"User-Agent\" \"myapp\" in let req1 = base |> with_query [(\"page\", \"1\")] |> send and let req2 = base |> with_query [(\"page\", \"2\")] |> send. This is low priority because labeled args mostly solve this, but builders are more composable and familiar to users from other languages. Implementation is straightforward - record type that accumulates config." 153 - }, 154 - { 155 - "source_repo": "third_party/python/uplink", 156 - "source_language": "Python", 157 - "criticality": "medium", 158 - "change_type": "enhancement", 159 - "title": "Add composable authentication with MultiAuth pattern", 160 - "description": "Extend authentication to support multiple auth methods simultaneously, similar to Uplink's MultiAuth. Some APIs require multiple authentication headers (e.g., both API key and request signature, or both Basic auth and Bearer token for proxies). Implement: val multi : t list -> t that applies multiple auth handlers in sequence. Example: Auth.multi [Auth.basic ~username ~password; Auth.bearer token] would add both Authorization: Basic and a second auth header. Each auth handler transforms headers, and multi chains them.", 161 - "affected_files": [ 162 - "lib/auth.mli", 163 - "lib/auth.ml" 164 - ], 165 - "rationale": "Uplink's MultiAuth allows combining authentication methods, which is necessary for some enterprise APIs. For example, AWS Signature V4 requires multiple headers (Authorization, X-Amz-Date, X-Amz-Content-Sha256), while some proxies require Proxy-Authorization in addition to Authorization. Currently, Auth.custom allows this through manual header manipulation, but MultiAuth makes it explicit and composable. Implementation is simple: type t = Headers.t -> Headers.t, so multi auths = List.fold_left (fun headers auth -> apply auth headers) headers auths. The value is making complex auth scenarios first-class. Some enterprise APIs require request signing (custom auth) plus API key header (another custom auth) plus basic auth for proxy - multi makes this clear. This is medium priority because custom auth can handle it but the API is less discoverable and requires more code. MultiAuth makes it obvious and prevents errors." 166 - }, 167 - { 168 - "source_repo": "third_party/python/uplink", 169 - "source_language": "Python", 170 - "criticality": "low", 171 - "change_type": "feature", 172 - "title": "Add request/response timing metrics in Response.t", 173 - "description": "Enhance Response.t to include detailed timing information beyond elapsed time. Add timing breakdown: DNS resolution time, TCP connect time, TLS handshake time, time to first byte, total time. Similar to curl's timing info or Uplink's ability to track this via hooks. Expose as: val timings : t -> timing_info where timing_info = { dns: float option; connect: float option; tls: float option; ttfb: float option; total: float }. This enables performance monitoring and debugging.", 174 - "affected_files": [ 175 - "lib/response.mli", 176 - "lib/response.ml", 177 - "lib/http_client.ml" 178 - ], 179 - "rationale": "Response.elapsed only provides total time, but debugging slow requests requires breakdown. Is it slow DNS? Slow TLS handshake? Slow server processing? Curl provides this via -w format options (time_namelookup, time_connect, time_appconnect, time_starttransfer, time_total). Uplink doesn't have built-in timing but hooks could track it. For OCaml, instrument http_client.ml to record timestamps at each stage using Eio.Time.now. Store in Response.t as optional fields (None if not available due to connection reuse). This is valuable for performance debugging and monitoring. Many production systems track these metrics (Prometheus has http_request_duration_seconds by phase). Implementation requires instrumenting the connection flow - record time before/after DNS, before/after connect, before/after TLS, before/after first response byte. Low priority because elapsed covers basic use case, but valuable for production observability. Could also expose as part of hooks system (before_request, after_connect, after_tls, etc.)." 180 - } 181 - ] 182 - }
-331
third_party/python/urllib3.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/python/urllib3", 5 - "source_language": "python", 6 - "criticality": "high", 7 - "change_type": "security", 8 - "title": "Add certificate fingerprint pinning support", 9 - "description": "urllib3 implements assert_fingerprint() for pinning specific certificates using SHA256, SHA1, or MD5 digests with constant-time comparison. This prevents man-in-the-middle attacks even with compromised CAs. The OCaml library currently has TLS verification via ca-certs but lacks fingerprint pinning for high-security scenarios where you want to pin to specific certificates regardless of CA trust.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/requests.mli", 13 - "lib/http_client.ml" 14 - ], 15 - "rationale": "Certificate pinning is a critical security feature for high-value applications (banking, healthcare, government) where you cannot trust the entire CA ecosystem. urllib3's implementation uses constant-time comparison to prevent timing attacks. This should be added as an optional configuration parameter (assert_fingerprint) to the OCaml library's TLS configuration, allowing users to specify expected certificate fingerprints that are validated after the TLS handshake." 16 - }, 17 - { 18 - "source_repo": "third_party/python/urllib3", 19 - "source_language": "python", 20 - "criticality": "medium", 21 - "change_type": "enhancement", 22 - "title": "Add separate retry counters per error category", 23 - "description": "urllib3's Retry class has fine-grained retry counts: total (max overall), connect (connection errors), read (read errors), redirect (redirect loops), status (status code retries), and other (unknown errors). The OCaml library only has max_retries (total). This granularity allows different retry strategies per failure mode - for example, retry connection errors 5 times but read errors only 2 times.", 24 - "affected_files": [ 25 - "lib/retry.ml", 26 - "lib/retry.mli" 27 - ], 28 - "rationale": "Different error types warrant different retry strategies. Connection errors (DNS, TCP, TLS) are typically safe to retry many times and often transient. Read errors may indicate partial request processing on the server. Status codes may need different limits. urllib3's approach allows: Retry(total=10, connect=5, read=2, status=3) giving users fine-grained control. The OCaml implementation should extend the retry config record with optional per-category limits that default to the total when not specified." 29 - }, 30 - { 31 - "source_repo": "third_party/python/urllib3", 32 - "source_language": "python", 33 - "criticality": "medium", 34 - "change_type": "feature", 35 - "title": "Implement request history tracking for retries", 36 - "description": "urllib3 maintains a RequestHistory list storing (method, url, error, status, redirect_location) for each retry attempt. This provides full visibility into what went wrong and how many times each error occurred. The OCaml library only increments retries_count without preserving attempt history.", 37 - "affected_files": [ 38 - "lib/retry.ml", 39 - "lib/retry.mli", 40 - "lib/requests.ml", 41 - "lib/response.ml", 42 - "lib/response.mli" 43 - ], 44 - "rationale": "Request history is invaluable for debugging production issues, monitoring retry patterns, and understanding failure modes. Users can analyze: 'Did it fail on the 1st attempt or 3rd?', 'Was it the same error each time?', 'Which redirect in the chain failed?'. Add a request_history field to the session type and Response.t containing a list of records with attempt number, error/status, URL, and timestamp. This should be opt-in via a track_history configuration flag to avoid overhead when not needed." 45 - }, 46 - { 47 - "source_repo": "third_party/python/urllib3", 48 - "source_language": "python", 49 - "criticality": "medium", 50 - "change_type": "enhancement", 51 - "title": "Add dynamic timeout budget tracking", 52 - "description": "urllib3's Timeout class tracks when connection phase started (start_connect) and dynamically calculates read_timeout as the remaining budget from total timeout. The OCaml implementation has separate connect/read/total timeouts but doesn't subtract elapsed connect time from the read timeout when total is specified. This means actual total time can exceed the specified total timeout.", 53 - "affected_files": [ 54 - "lib/timeout.ml", 55 - "lib/timeout.mli", 56 - "lib/http_client.ml" 57 - ], 58 - "rationale": "When users specify total timeout, they expect it to be honored across all phases. urllib3's approach: if total=10s and connect takes 3s, read timeout becomes min(read_timeout, 7s). This prevents violations of the total budget. The OCaml library should track connection start time and dynamically compute read deadline = min(read_timeout, total_timeout - connect_elapsed). Add internal state tracking with start_time field and get_remaining_budget() function." 59 - }, 60 - { 61 - "source_repo": "third_party/python/urllib3", 62 - "source_language": "python", 63 - "criticality": "low", 64 - "change_type": "enhancement", 65 - "title": "Add timeout validation on construction", 66 - "description": "urllib3 validates timeout values on construction, rejecting values <= 0 and explicitly rejecting boolean values (common mistake). It also supports a special Timeout.DEFAULT_TIMEOUT sentinel. The OCaml library accepts any float option without validation.", 67 - "affected_files": [ 68 - "lib/timeout.ml", 69 - "lib/timeout.mli" 70 - ], 71 - "rationale": "Early validation prevents confusing runtime errors. urllib3 catches: Timeout(connect=0) - should be None, Timeout(read=-5) - invalid, Timeout(total=True) - type confusion. The OCaml library should add validation in Timeout.create that raises Invalid_argument for values <= 0.0, and add a helpful error message explaining that None should be used for no timeout. Consider adding a validate() function for debugging existing timeout configs." 72 - }, 73 - { 74 - "source_repo": "third_party/python/urllib3", 75 - "source_language": "python", 76 - "criticality": "medium", 77 - "change_type": "feature", 78 - "title": "Add connection dropped detection before reuse", 79 - "description": "urllib3's HTTPConnectionPool._get_conn() checks if a pooled connection is still alive using is_connection_dropped() before returning it for reuse. This prevents 'connection reset by peer' errors from stale connections. The OCaml library uses Conpool but doesn't explicitly validate connection liveness before reuse.", 80 - "affected_files": [ 81 - "lib/requests.ml", 82 - "lib/http_client.ml" 83 - ], 84 - "rationale": "Idle connections can be closed by servers or middleboxes (firewalls, load balancers) without client notification. Attempting to reuse a dropped connection causes immediate failure. urllib3 uses select() with 0 timeout to check socket readability - if readable with no pending data, connection is dead. OCaml implementation should add a quick liveness check (Eio socket peek or similar) before reusing pooled connections, automatically discarding dead ones and creating fresh connections. This reduces user-visible errors." 85 - }, 86 - { 87 - "source_repo": "third_party/python/urllib3", 88 - "source_language": "python", 89 - "criticality": "high", 90 - "change_type": "security", 91 - "title": "Add system time validation warnings", 92 - "description": "urllib3 checks if the system clock is reasonable by comparing against RECENT_DATE (2025-01-01). If system time is before this, it warns users as it causes TLS certificate validation failures. The OCaml library doesn't check system clock skew.", 93 - "affected_files": [ 94 - "lib/requests.ml", 95 - "lib/error.ml" 96 - ], 97 - "rationale": "Incorrect system time is a common source of mysterious TLS failures, especially on embedded devices, VMs after resume, or during first boot. urllib3 emits SystemTimeWarning when now < RECENT_DATE. The OCaml library should add a check during TLS connection that compares Ptime.now() against a recent sentinel date (e.g., library build date). If system time is too old, log a warning via Logs.warn explaining certificate validation may fail due to clock skew. This saves hours of debugging." 98 - }, 99 - { 100 - "source_repo": "third_party/python/urllib3", 101 - "source_language": "python", 102 - "criticality": "low", 103 - "change_type": "enhancement", 104 - "title": "Add socket options customization", 105 - "description": "urllib3 allows passing custom socket options via socket_options parameter (e.g., TCP_NODELAY, SO_KEEPALIVE, SO_LINGER). It defaults to disabling Nagle's algorithm (TCP_NODELAY=1) for lower latency. The OCaml library uses default Eio socket settings without customization.", 106 - "affected_files": [ 107 - "lib/requests.ml", 108 - "lib/http_client.ml" 109 - ], 110 - "rationale": "Different applications have different socket tuning needs. urllib3's default TCP_NODELAY=1 reduces latency for small HTTP requests by disabling Nagle's algorithm (don't wait to coalesce packets). Some users need SO_KEEPALIVE for long-lived connections through NAT, SO_REUSEADDR for rapid reconnection, or custom buffer sizes. Add a socket_options parameter to the session config accepting a list of (level, optname, value) tuples, and apply them via Eio's socket configuration after creation." 111 - }, 112 - { 113 - "source_repo": "third_party/python/urllib3", 114 - "source_language": "python", 115 - "criticality": "medium", 116 - "change_type": "enhancement", 117 - "title": "Add InsecureRequestWarning for unverified HTTPS", 118 - "description": "urllib3 emits InsecureRequestWarning when making HTTPS requests with verify=False (cert_reqs=CERT_NONE). This visible warning helps developers catch security issues during development. The OCaml library has verify_tls=false option but doesn't warn when used.", 119 - "affected_files": [ 120 - "lib/requests.ml" 121 - ], 122 - "rationale": "Disabling TLS verification is dangerous and should never reach production, but is sometimes needed for testing against self-signed certificates. urllib3's warning makes this explicit, preventing accidental production deployment with verify=False. The OCaml library should log a warning (Logs.warn) when verify_tls=false is set, with a message like 'Making HTTPS request with TLS verification disabled. This is insecure and should only be used for testing.' This should log once per session creation, not per request." 123 - }, 124 - { 125 - "source_repo": "third_party/python/urllib3", 126 - "source_language": "python", 127 - "criticality": "low", 128 - "change_type": "feature", 129 - "title": "Add RecentlyUsedContainer for pool eviction policy", 130 - "description": "urllib3 uses a RecentlyUsedContainer (LRU cache) to manage multiple connection pools, automatically disposing old pools when the cache fills. The OCaml library uses Conpool per protocol but doesn't have automatic eviction for multi-host scenarios.", 131 - "affected_files": [ 132 - "lib/requests.ml" 133 - ], 134 - "rationale": "In applications making requests to many different hosts, connection pools can accumulate indefinitely, consuming memory and file descriptors. urllib3's RecentlyUsedContainer limits pool count and calls dispose_func (closes all connections) on evicted pools. While the OCaml library currently uses one pool per protocol (HTTP/HTTPS), if it were extended to support per-host pooling (for better isolation), it would need similar LRU eviction. Consider this for future enhancement when implementing per-host pool limits." 135 - }, 136 - { 137 - "source_repo": "third_party/python/urllib3", 138 - "source_language": "python", 139 - "criticality": "medium", 140 - "change_type": "feature", 141 - "title": "Add PoolKey abstraction for pool lookup", 142 - "description": "urllib3 uses a PoolKey NamedTuple (scheme, host, port, key_* params) for deterministic pool selection based on all relevant connection parameters (not just host). The OCaml library has separate http_pool and https_pool but doesn't key by host or other parameters.", 143 - "affected_files": [ 144 - "lib/requests.ml" 145 - ], 146 - "rationale": "Different TLS configurations, proxy settings, or certificate requirements for different hosts should use separate pools. urllib3's PoolKey includes: scheme, host, port, timeout, retries, block, source_address, key_file, cert_file, etc. Two requests to the same host with different client certificates should use different pools. If the OCaml library adds per-host pooling, implement a similar pooling key that includes all connection-affecting parameters to ensure correct pool isolation." 147 - }, 148 - { 149 - "source_repo": "third_party/python/urllib3", 150 - "source_language": "python", 151 - "criticality": "medium", 152 - "change_type": "enhancement", 153 - "title": "Add intelligent request method encoding dispatch", 154 - "description": "urllib3's RequestMethods mixin automatically chooses encoding based on HTTP method: GET/HEAD/DELETE/OPTIONS encode parameters in URL query string, while POST/PUT/PATCH encode in body. The OCaml library has Body.form for URL encoding but requires manual routing.", 155 - "affected_files": [ 156 - "lib/body.ml", 157 - "lib/body.mli", 158 - "lib/requests.ml" 159 - ], 160 - "rationale": "Developer experience: users shouldn't need to think about whether to put parameters in URL or body based on HTTP method. urllib3's .request(method, url, fields={...}) intelligently routes based on method. For the OCaml library, add a ~params parameter (string * string) list that automatically encodes to query string for safe methods (GET/HEAD/OPTIONS) and body for POST/PUT/PATCH. This matches idiomatic usage patterns and reduces errors." 161 - }, 162 - { 163 - "source_repo": "third_party/python/urllib3", 164 - "source_language": "python", 165 - "criticality": "low", 166 - "change_type": "enhancement", 167 - "title": "Add response preload_content option for streaming control", 168 - "description": "urllib3's HTTPResponse accepts preload_content parameter: True loads entire body immediately, False enables streaming with manual read(). The OCaml library always streams (returns Eio.Flow) without eager loading option.", 169 - "affected_files": [ 170 - "lib/response.ml", 171 - "lib/response.mli" 172 - ], 173 - "rationale": "While streaming is generally better, some users prefer eager loading for simpler code when responses are known to be small. urllib3's preload_content=True buffers the entire response on construction, simplifying error handling (exceptions raised during construction, not during body read). Consider adding Response.text_eager/json_eager convenience functions that immediately consume and validate the body, versus the current lazy text/json. This preserves streaming as default while offering eager option." 174 - }, 175 - { 176 - "source_repo": "third_party/python/urllib3", 177 - "source_language": "python", 178 - "criticality": "medium", 179 - "change_type": "feature", 180 - "title": "Add body seeking and position tracking for retries", 181 - "description": "urllib3 tracks body_pos to support rewinding request bodies for retries. It checks if body is seekable and seeks back to body_pos before retry. The OCaml library's retry mechanism doesn't handle body rewind for failed requests.", 182 - "affected_files": [ 183 - "lib/retry.ml", 184 - "lib/body.ml", 185 - "lib/body.mli" 186 - ], 187 - "rationale": "When a request with a body fails mid-transmission and needs retry, the body stream must be reset. urllib3 tracks the starting position and seeks back before retry. For string/bytes bodies this is trivial, but for file/stream bodies it requires seeking. The OCaml library should: (1) track whether Body.t is rewindable (strings yes, streams no), (2) store original position for files, (3) in retry logic, only retry bodies that can be rewound, (4) add is_rewindable() predicate to Body module." 188 - }, 189 - { 190 - "source_repo": "third_party/python/urllib3", 191 - "source_language": "python", 192 - "criticality": "low", 193 - "change_type": "enhancement", 194 - "title": "Add header case-preserving dictionary", 195 - "description": "urllib3's HTTPHeaderDict is case-insensitive for lookup but preserves original casing for wire format. The OCaml library's Headers.t is case-insensitive but may not preserve original casing in all cases.", 196 - "affected_files": [ 197 - "lib/headers.ml", 198 - "lib/headers.mli" 199 - ], 200 - "rationale": "HTTP headers are case-insensitive (RFC 9110) but some legacy servers expect specific casing (e.g., 'Content-Type' not 'content-type'). urllib3 stores headers in a way that lookups are case-insensitive but iteration preserves original case. The OCaml Headers module should be audited to ensure original casing is preserved in to_list and during serialization. If not already doing so, store headers as (original_name, lowercase_key, value) tuples internally." 201 - }, 202 - { 203 - "source_repo": "third_party/python/urllib3", 204 - "source_language": "python", 205 - "criticality": "medium", 206 - "change_type": "enhancement", 207 - "title": "Add backoff_jitter configuration to retry strategy", 208 - "description": "urllib3's Retry.backoff_jitter adds random jitter as a percentage of backoff time (default 0.0, range 0.0-1.0). The OCaml library has jitter:bool but it's binary (on/off), not configurable in magnitude.", 209 - "affected_files": [ 210 - "lib/retry.ml", 211 - "lib/retry.mli" 212 - ], 213 - "rationale": "Thundering herd prevention requires tunable jitter. urllib3's backoff_jitter=0.3 adds up to 30% random variation. The OCaml library's jitter:bool adds 0-100% variation (full backoff range), which may be too much for some use cases. Change jitter from bool to float option: None (no jitter), Some 0.5 (50% jitter = random delay between backoff and backoff*1.5). This provides fine-grained control while maintaining backward compatibility with a default of 0.5 when jitter was previously true." 214 - }, 215 - { 216 - "source_repo": "third_party/python/urllib3", 217 - "source_language": "python", 218 - "criticality": "medium", 219 - "change_type": "enhancement", 220 - "title": "Add raise_on_redirect and raise_on_status configuration", 221 - "description": "urllib3's Retry allows raise_on_redirect and raise_on_status to control whether these conditions raise exceptions or return responses. The OCaml library always raises on too_many_redirects but doesn't offer configuration for status code error behavior.", 222 - "affected_files": [ 223 - "lib/retry.ml", 224 - "lib/retry.mli", 225 - "lib/requests.ml" 226 - ], 227 - "rationale": "Different applications have different error handling philosophies. Some prefer exceptions for any failure (fail-fast), others prefer responses with error status codes for programmatic handling. urllib3's raise_on_status=True raises MaxRetryError even after successful retry if final status is in status_forcelist. raise_on_status=False returns the response object. The OCaml library should add raise_on_status:bool to retry config (default true for backward compatibility) and only call Response.raise_for_status when enabled." 228 - }, 229 - { 230 - "source_repo": "third_party/python/urllib3", 231 - "source_language": "python", 232 - "criticality": "medium", 233 - "change_type": "feature", 234 - "title": "Add support for HTTP CONNECT tunneling for HTTPS proxies", 235 - "description": "urllib3 automatically uses CONNECT method to tunnel HTTPS through HTTP proxies (connection_requires_http_tunnel). The OCaml library has proxy support mentioned but may not handle CONNECT tunneling.", 236 - "affected_files": [ 237 - "lib/requests.ml", 238 - "lib/http_client.ml" 239 - ], 240 - "rationale": "When using an HTTP proxy for HTTPS requests, the client must establish a TCP tunnel using the CONNECT method (RFC 9110 Section 9.3.6), then perform TLS handshake through the tunnel. urllib3 detects when this is needed and automatically sends 'CONNECT host:port HTTP/1.1'. The OCaml library should implement similar logic: detect proxy + HTTPS, send CONNECT, read 200 response, then switch to TLS over the connected socket. Verify proxy implementation includes this or add it." 241 - }, 242 - { 243 - "source_repo": "third_party/python/urllib3", 244 - "source_language": "python", 245 - "criticality": "high", 246 - "change_type": "security", 247 - "title": "Add hostname matching with wildcard and IDN support", 248 - "description": "urllib3 implements custom match_hostname with proper wildcard matching (*.example.com) and IDN (internationalized domain names) support. The OCaml library relies on Tls library's hostname verification which may have different behavior.", 249 - "affected_files": [ 250 - "lib/requests.ml", 251 - "lib/http_client.ml" 252 - ], 253 - "rationale": "Hostname verification is critical for TLS security. urllib3's match_hostname handles edge cases: wildcards only in leftmost label, no partial wildcards (x*.example.com invalid), IDN normalization, proper subjectAltName parsing. The OCaml library should verify that ocaml-tls's X509 hostname validation handles all these cases. If not, implement supplementary validation. Add tests with: wildcard certificates, IDN domains (xn--*), and certificates with multiple SANs." 254 - }, 255 - { 256 - "source_repo": "third_party/python/urllib3", 257 - "source_language": "python", 258 - "criticality": "low", 259 - "change_type": "feature", 260 - "title": "Add platform detection and capability fallbacks", 261 - "description": "urllib3 detects platform capabilities (OpenSSL version, poll() availability) and gracefully degrades. It delays choice between poll() and select() until first use. The OCaml library uses Eio which abstracts this, but could add platform warnings.", 262 - "affected_files": [ 263 - "lib/requests.ml" 264 - ], 265 - "rationale": "Different platforms have different capabilities. urllib3 detects: broken poll() on some systems, PyPy vs CPython differences, LibreSSL vs OpenSSL, and emits warnings or uses fallbacks. While Eio handles most platform abstraction, the OCaml library could add runtime checks for: adequate Eio version, required system libraries (gzip/zlib support), TLS backend availability. Log warnings at session creation if optional features are unavailable." 266 - }, 267 - { 268 - "source_repo": "third_party/python/urllib3", 269 - "source_language": "python", 270 - "criticality": "medium", 271 - "change_type": "feature", 272 - "title": "Add brotli and zstd decompression support", 273 - "description": "urllib3 supports gzip, deflate, brotli, and zstd decompression (when optional libraries are available). The OCaml library supports gzip, deflate, and zlib but not brotli or zstd.", 274 - "affected_files": [ 275 - "lib/http_client.ml" 276 - ], 277 - "rationale": "Brotli (RFC 7932) provides ~20% better compression than gzip and is widely supported by browsers and CDNs. Zstandard is increasingly used for its speed and compression ratio. Modern servers send 'Content-Encoding: br' or 'Content-Encoding: zstd'. The OCaml library should add optional support (when respective libraries are installed): detect 'br' encoding and use ocaml-brotli library, detect 'zstd' and use ocaml-zstd. Make these optional dependencies with graceful degradation if not available." 278 - }, 279 - { 280 - "source_repo": "third_party/python/urllib3", 281 - "source_language": "python", 282 - "criticality": "medium", 283 - "change_type": "enhancement", 284 - "title": "Add chunked transfer encoding for request bodies", 285 - "description": "urllib3 supports chunked Transfer-Encoding for request bodies when body is an iterable and length is unknown. The OCaml library has streaming request bodies but may not support chunked encoding properly.", 286 - "affected_files": [ 287 - "lib/body.ml", 288 - "lib/http_write.ml" 289 - ], 290 - "rationale": "Chunked encoding (RFC 9112 Section 7.1) allows sending request bodies without knowing Content-Length upfront, useful for generated/streamed content. urllib3 automatically uses chunked encoding when body is an iterable without length. The OCaml library's Body.of_stream accepts optional ~length parameter. When length is None, it should use Transfer-Encoding: chunked. Verify http_write.ml properly emits chunk-size CRLF data CRLF format and final 0 CRLF CRLF terminator." 291 - }, 292 - { 293 - "source_repo": "third_party/python/urllib3", 294 - "source_language": "python", 295 - "criticality": "low", 296 - "change_type": "enhancement", 297 - "title": "Add MaxRetryError with cause chain", 298 - "description": "urllib3's MaxRetryError exception stores the underlying reason (cause) that triggered the retry failure. The OCaml library raises the final exception but doesn't wrap it with retry context.", 299 - "affected_files": [ 300 - "lib/retry.ml", 301 - "lib/error.ml" 302 - ], 303 - "rationale": "When retries are exhausted, users need to know why retries were attempted. urllib3's MaxRetryError includes: url, retry count, and the underlying exception. The OCaml library currently re-raises the last exception. Consider adding Error.Max_retries_exceeded variant that wraps the underlying error: Max_retries_exceeded { url; attempts; underlying_error:error; history:attempt list }. This provides complete context while preserving the original error details." 304 - }, 305 - { 306 - "source_repo": "third_party/python/urllib3", 307 - "source_language": "python", 308 - "criticality": "low", 309 - "change_type": "enhancement", 310 - "title": "Add pool statistics and metrics", 311 - "description": "urllib3's HTTPConnectionPool tracks num_connections and num_requests for monitoring pool health. The OCaml library has session-level statistics (requests_made, total_time, retries_count) but no pool-level metrics.", 312 - "affected_files": [ 313 - "lib/requests.ml" 314 - ], 315 - "rationale": "Pool-level metrics help diagnose connection issues and capacity problems: active connections, idle connections, pool exhaustion events, average connection lifetime. While the OCaml library delegates pooling to Conpool, it could expose Conpool's metrics through the session interface: pool_stats() returning { active:int; idle:int; total_created:int; reuse_count:int }. This aids production monitoring without adding overhead when not queried." 316 - }, 317 - { 318 - "source_repo": "third_party/python/urllib3", 319 - "source_language": "python", 320 - "criticality": "medium", 321 - "change_type": "enhancement", 322 - "title": "Add EmptyPoolError and FullPoolError for pool exhaustion", 323 - "description": "urllib3 raises EmptyPoolError when blocking pool is empty and FullPoolError when returning connection to full pool. The OCaml library uses Conpool but may not expose pool exhaustion errors distinctly.", 324 - "affected_files": [ 325 - "lib/error.ml", 326 - "lib/requests.ml" 327 - ], 328 - "rationale": "Pool exhaustion indicates resource pressure and helps diagnose performance issues. urllib3's block=True raises EmptyPoolError with pool and message when no connections available and pool at max. The OCaml library should catch Conpool exhaustion conditions (if exposed) and raise Error.Pool_exhausted { pool_type:'http'|'https'; max_size:int; current:int }. This helps users tune max_connections_per_host or identify connection leaks." 329 - } 330 - ] 331 - }
-282
third_party/rust/curl-rust.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/rust/curl-rust", 5 - "source_language": "Rust", 6 - "criticality": "medium", 7 - "change_type": "enhancement", 8 - "title": "Add numeric error codes to error variants", 9 - "description": "The curl-rust library exposes numeric error codes alongside error types via the code() method, making it easier to debug issues by cross-referencing with libcurl documentation. Currently, the OCaml Error module uses variant types without numeric codes.", 10 - "affected_files": [ 11 - "lib/error.ml", 12 - "lib/error.mli" 13 - ], 14 - "rationale": "Adding numeric codes to error types aids debugging and allows users to reference official HTTP/TLS error code documentation. This is especially useful for connection errors (DNS, TCP, TLS) where numeric codes provide precise diagnostic information. The curl-rust implementation shows this pattern works well, with codes accessible via error.code() method and displayed in error messages as [code] description." 15 - }, 16 - { 17 - "source_repo": "third_party/rust/curl-rust", 18 - "source_language": "Rust", 19 - "criticality": "medium", 20 - "change_type": "enhancement", 21 - "title": "Implement progress callbacks for large transfers", 22 - "description": "curl-rust provides a progress callback (Handler::progress) that receives download/upload progress information (total bytes, current bytes) during transfers. This enables users to build progress bars, cancel long-running transfers, or implement bandwidth throttling.", 23 - "affected_files": [ 24 - "lib/requests.mli", 25 - "lib/requests.ml", 26 - "lib/one.mli", 27 - "lib/one.ml" 28 - ], 29 - "rationale": "Progress callbacks are essential for user-facing applications that need to display transfer progress or implement transfer cancellation. The curl-rust implementation demonstrates this with f64 parameters (dltotal, dlnow, ultotal, ulnow) and returns bool to allow cancellation. This could be implemented in OCaml using optional callback parameters: ?progress:(total_bytes:int64 -> current_bytes:int64 -> unit) -> unit, integrated with Eio's cancellation mechanism." 30 - }, 31 - { 32 - "source_repo": "third_party/rust/curl-rust", 33 - "source_language": "Rust", 34 - "criticality": "low", 35 - "change_type": "enhancement", 36 - "title": "Add timing information query methods to Response", 37 - "description": "curl-rust exposes detailed timing information after requests complete: namelookup_time, connect_time, total_time, redirect_time. These allow performance analysis without re-executing the request.", 38 - "affected_files": [ 39 - "lib/response.ml", 40 - "lib/response.mli" 41 - ], 42 - "rationale": "The Response module currently tracks elapsed time but could be enhanced with granular timing data. This would help users: (1) profile DNS resolution performance, (2) identify slow connection establishment, (3) measure server response time separately from transfer time, (4) debug performance issues. Implementation would extend the Response.t record with optional timing fields populated during request execution in http_client.ml." 43 - }, 44 - { 45 - "source_repo": "third_party/rust/curl-rust", 46 - "source_language": "Rust", 47 - "criticality": "low", 48 - "change_type": "enhancement", 49 - "title": "Support low-speed transfer detection for stall prevention", 50 - "description": "curl-rust provides low_speed_limit and low_speed_time options to automatically abort transfers that fall below a minimum transfer rate for a specified duration. This prevents indefinite hangs on stalled connections.", 51 - "affected_files": [ 52 - "lib/timeout.ml", 53 - "lib/timeout.mli", 54 - "lib/http_client.ml" 55 - ], 56 - "rationale": "Current timeout configuration only has connect, read, and total timeouts. Low-speed detection complements these by catching cases where connections remain open but data transfer stalls (e.g., due to network congestion or misbehaving servers). curl-rust sets this via low_speed_limit(bytes/sec) and low_speed_time(duration). OCaml implementation could add: type t = { ...; min_transfer_rate: (int * float) option (* bytes/sec, duration *) }." 57 - }, 58 - { 59 - "source_repo": "third_party/rust/curl-rust", 60 - "source_language": "Rust", 61 - "criticality": "medium", 62 - "change_type": "enhancement", 63 - "title": "Add handle reset functionality for connection reuse", 64 - "description": "curl-rust's Easy handle supports a reset() method that clears configuration but preserves live connections, DNS cache, and session data. This enables efficient reuse of handles across multiple requests with different configurations.", 65 - "affected_files": [ 66 - "lib/requests.ml", 67 - "lib/requests.mli" 68 - ], 69 - "rationale": "While the current API supports configuration updates via set_* methods, there's no explicit way to reset configuration to defaults while keeping connection pools alive. This would be useful for applications that want to reuse a Requests.t instance with fresh settings without closing pooled connections. Implementation: val reset : t -> t that clears auth, headers, retry config but preserves http_pool, https_pool, and cookie_jar references." 70 - }, 71 - { 72 - "source_repo": "third_party/rust/curl-rust", 73 - "source_language": "Rust", 74 - "criticality": "medium", 75 - "change_type": "feature", 76 - "title": "Support NTLM and Negotiate/SPNEGO authentication", 77 - "description": "curl-rust supports enterprise authentication schemes beyond Basic/Digest/Bearer: NTLM (Microsoft challenge-response), NTLM_WB (with winbind delegation), and GSS/Negotiate (Kerberos SPNEGO per RFC 4559). These are common in corporate environments.", 78 - "affected_files": [ 79 - "lib/auth.ml", 80 - "lib/auth.mli" 81 - ], 82 - "rationale": "The current auth module supports Basic, Bearer, Digest, and Custom authentication. Adding NTLM and Negotiate would enable OCaml applications to integrate with Windows/Active Directory environments and Kerberos-based systems. This would require OCaml bindings to libntlm or libgssapi, or implementing the protocols directly. The curl-rust implementation shows these can be enabled via Auth bitflags and work via automatic negotiation." 83 - }, 84 - { 85 - "source_repo": "third_party/rust/curl-rust", 86 - "source_language": "Rust", 87 - "criticality": "medium", 88 - "change_type": "feature", 89 - "title": "Add AWS Signature Version 4 authentication", 90 - "description": "curl-rust includes dedicated support for AWS SigV4 authentication via aws_sigv4() method, which is increasingly important for cloud-native applications accessing AWS services.", 91 - "affected_files": [ 92 - "lib/auth.ml", 93 - "lib/auth.mli" 94 - ], 95 - "rationale": "Many OCaml applications need to interact with AWS APIs (S3, Lambda, etc.) which require AWS SigV4 signing. While this could be done via Custom auth, providing built-in support would improve ergonomics. Implementation would add: Auth.aws_sigv4 ~access_key ~secret_key ~region ~service variant and compute the signature per AWS SigV4 specification (HMAC-SHA256 signing process)." 96 - }, 97 - { 98 - "source_repo": "third_party/rust/curl-rust", 99 - "source_language": "Rust", 100 - "criticality": "low", 101 - "change_type": "enhancement", 102 - "title": "Support .netrc file parsing for credential management", 103 - "description": "curl-rust supports automatic credential loading from .netrc files via the netrc() configuration option. This allows users to store credentials securely outside of code.", 104 - "affected_files": [ 105 - "lib/auth.ml", 106 - "lib/auth.mli", 107 - "lib/requests.ml" 108 - ], 109 - "rationale": "The current implementation requires credentials in code or environment variables. Supporting .netrc provides a standard Unix mechanism for credential storage. Implementation would: (1) Parse ~/.netrc format (machine/login/password), (2) Add Auth.netrc variant, (3) Lookup credentials by hostname during request execution. Security consideration: ensure proper file permissions (0600) are enforced." 110 - }, 111 - { 112 - "source_repo": "third_party/rust/curl-rust", 113 - "source_language": "Rust", 114 - "criticality": "medium", 115 - "change_type": "security", 116 - "title": "Add granular TLS/SSL configuration options", 117 - "description": "curl-rust exposes fine-grained SSL options via SslOpt struct: auto_client_cert, native_ca (OS cert store), no_partial_chain, revoke_best_effort, allow_beast. Current implementation only supports min_tls_version and verify_tls.", 118 - "affected_files": [ 119 - "lib/requests.ml", 120 - "lib/requests.mli", 121 - "lib/one.ml", 122 - "lib/one.mli" 123 - ], 124 - "rationale": "Enterprise and security-conscious users need fine-grained TLS control. Key additions: (1) Use OS certificate store (native_ca) instead of bundled CA certs, (2) Configure CRL/OCSP revocation checking (revoke_best_effort), (3) Client certificate selection (auto_client_cert), (4) Partial chain validation (no_partial_chain). These would be added as optional record fields in a new tls_options type." 125 - }, 126 - { 127 - "source_repo": "third_party/rust/curl-rust", 128 - "source_language": "Rust", 129 - "criticality": "low", 130 - "change_type": "enhancement", 131 - "title": "Add cipher suite restriction configuration", 132 - "description": "curl-rust allows users to specify allowed cipher suites via ssl_cipher_list() for compliance with security policies (e.g., disabling weak ciphers).", 133 - "affected_files": [ 134 - "lib/requests.ml", 135 - "lib/requests.mli", 136 - "lib/one.ml" 137 - ], 138 - "rationale": "Some organizations require specific cipher suites for compliance (PCI-DSS, FIPS 140-2). While Tls.Config.client in ocaml-tls supports this, the requests library doesn't expose it. Implementation would add: ?allowed_ciphers:string list parameter that maps to TLS library configuration. This enables users to enforce security policies like: ['TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'; 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384']." 139 - }, 140 - { 141 - "source_repo": "third_party/rust/curl-rust", 142 - "source_language": "Rust", 143 - "criticality": "low", 144 - "change_type": "feature", 145 - "title": "Support SOCKS proxy types (SOCKS4, SOCKS4a, SOCKS5)", 146 - "description": "curl-rust supports multiple proxy types via ProxyType enum: HTTP, HTTP/1.0, SOCKS4, SOCKS4a, SOCKS5, SOCKS5Hostname. Current implementation doesn't specify proxy protocol support.", 147 - "affected_files": [ 148 - "lib/requests.ml", 149 - "lib/requests.mli", 150 - "lib/one.ml" 151 - ], 152 - "rationale": "SOCKS proxies are common in enterprise environments and privacy-focused applications (Tor uses SOCKS5). Adding support would enable use cases like: (1) Routing through Tor, (2) Corporate SOCKS gateways, (3) SSH tunneling via dynamic port forwarding. Implementation requires: (1) Proxy type variant, (2) SOCKS protocol implementation or bindings, (3) Integration with connection establishment in http_client.ml." 153 - }, 154 - { 155 - "source_repo": "third_party/rust/curl-rust", 156 - "source_language": "Rust", 157 - "criticality": "low", 158 - "change_type": "enhancement", 159 - "title": "Add HTTP version negotiation control", 160 - "description": "curl-rust exposes HttpVersion enum allowing users to force specific versions (HTTP/1.0, HTTP/1.1, HTTP/2, HTTP/3) or let the library choose. Current implementation is hard-coded to HTTP/1.1.", 161 - "affected_files": [ 162 - "lib/http_write.ml", 163 - "lib/http_client.ml", 164 - "lib/requests.mli" 165 - ], 166 - "rationale": "While HTTP/1.1 is a solid default, users may want to: (1) Force HTTP/1.0 for legacy servers, (2) Prefer HTTP/2 for performance, (3) Test HTTP/3 support. The curl-rust implementation shows version negotiation via enum: Any, V10, V11, V2, V2TLS, V2PriorKnowledge, V3. OCaml implementation would add http_version configuration parameter and require HTTP/2 library integration (e.g., h2 or httpaf)." 167 - }, 168 - { 169 - "source_repo": "third_party/rust/curl-rust", 170 - "source_language": "Rust", 171 - "criticality": "low", 172 - "change_type": "enhancement", 173 - "title": "Support DNS-over-HTTPS (DoH) configuration", 174 - "description": "curl-rust supports DNS-over-HTTPS via doh_url() method, enabling encrypted DNS lookups for privacy and security.", 175 - "affected_files": [ 176 - "lib/requests.ml", 177 - "lib/requests.mli", 178 - "lib/one.ml" 179 - ], 180 - "rationale": "DNS-over-HTTPS prevents DNS hijacking and provides privacy by encrypting DNS queries. This is increasingly important for security-sensitive applications. Implementation would: (1) Add ?doh_url:string parameter to configuration, (2) Integrate with DoH resolver library or implement RFC 8484, (3) Fall back to system DNS on DoH failure. Use cases: Privacy-focused apps, bypass DNS censorship, prevent MITM attacks." 181 - }, 182 - { 183 - "source_repo": "third_party/rust/curl-rust", 184 - "source_language": "Rust", 185 - "criticality": "low", 186 - "change_type": "enhancement", 187 - "title": "Add Unix domain socket support", 188 - "description": "curl-rust supports Unix domain sockets for HTTP communication, useful for local IPC with containerized services (Docker API) or Unix socket servers.", 189 - "affected_files": [ 190 - "lib/http_client.ml", 191 - "lib/requests.mli", 192 - "lib/one.mli" 193 - ], 194 - "rationale": "Many modern services expose HTTP APIs over Unix sockets (Docker daemon, containerd, systemd). Supporting this would enable OCaml applications to interact with these services without TCP overhead. Implementation: (1) Parse unix:// URLs, (2) Use Eio_unix domain socket support, (3) Modify http_client.ml to handle Unix sockets alongside TCP. Example: Requests.get req 'unix:///var/run/docker.sock/containers/json'." 195 - }, 196 - { 197 - "source_repo": "third_party/rust/curl-rust", 198 - "source_language": "Rust", 199 - "criticality": "low", 200 - "change_type": "enhancement", 201 - "title": "Add custom request method support", 202 - "description": "curl-rust supports arbitrary HTTP methods via custom_request(), allowing use of non-standard methods (PATCH already supported, but WebDAV methods like PROPFIND, MKCOL, etc. are not).", 203 - "affected_files": [ 204 - "lib/method.ml", 205 - "lib/method.mli", 206 - "lib/requests.mli" 207 - ], 208 - "rationale": "While the Method module supports standard HTTP methods, some protocols use custom methods: WebDAV (PROPFIND, MKCOL, COPY, MOVE), CalDAV/CardDAV (REPORT), or application-specific methods. curl-rust allows this via custom_request(). Implementation: Add Method.custom : string -> t variant or val request : t -> ?method_:string -> ... to allow arbitrary method strings." 209 - }, 210 - { 211 - "source_repo": "third_party/rust/curl-rust", 212 - "source_language": "Rust", 213 - "criticality": "medium", 214 - "change_type": "enhancement", 215 - "title": "Add detailed debug logging with protocol inspection", 216 - "description": "curl-rust provides verbose mode and debug callbacks with InfoType classification (Text, HeaderIn, HeaderOut, DataIn, DataOut, SslDataIn, SslDataOut), allowing deep inspection of HTTP protocol exchanges.", 217 - "affected_files": [ 218 - "lib/http_client.ml", 219 - "lib/http_write.ml", 220 - "lib/http_read.ml", 221 - "lib/requests.ml" 222 - ], 223 - "rationale": "While the library uses Logs for general logging, curl-rust's debug mechanism provides structured protocol-level visibility. This is invaluable for debugging: (1) Header order/format issues, (2) TLS handshake problems, (3) Request/response timing. Implementation would add: ?debug:(info_type -> bytes -> unit) callback parameter and emit events at protocol boundaries (before write, after read, SSL negotiation)." 224 - }, 225 - { 226 - "source_repo": "third_party/rust/curl-rust", 227 - "source_language": "Rust", 228 - "criticality": "low", 229 - "change_type": "enhancement", 230 - "title": "Add IP version resolution control", 231 - "description": "curl-rust provides IpResolve enum (V4, V6, Any) to force IPv4-only or IPv6-only connections, useful for testing or networks with broken dual-stack.", 232 - "affected_files": [ 233 - "lib/requests.ml", 234 - "lib/requests.mli", 235 - "lib/one.ml", 236 - "lib/http_client.ml" 237 - ], 238 - "rationale": "Some networks have broken IPv6 or users need to test specific IP versions. curl-rust allows forcing via ip_resolve(). Current implementation uses Eio.Net.getaddrinfo_stream which returns both v4/v6. Enhancement would: (1) Add ip_resolve config type, (2) Filter getaddrinfo results by family, (3) Enable scenarios like 'force IPv4 for compatibility' or 'test IPv6-only deployment'." 239 - }, 240 - { 241 - "source_repo": "third_party/rust/curl-rust", 242 - "source_language": "Rust", 243 - "criticality": "low", 244 - "change_type": "enhancement", 245 - "title": "Support pause/resume for streaming transfers", 246 - "description": "curl-rust supports pausing transfers via WriteError::Pause and ReadError::Pause return values, with corresponding unpause_write/unpause_read methods. This enables flow control and buffering management.", 247 - "affected_files": [ 248 - "lib/one.ml", 249 - "lib/one.mli", 250 - "lib/requests.ml" 251 - ], 252 - "rationale": "Large streaming transfers may need pause/resume for: (1) Backpressure when consumer is slow, (2) Temporary resource constraints, (3) User-initiated pause (downloads). curl-rust implements this via callback return values. OCaml implementation could use Eio's flow control primitives or add explicit pause/resume control via switch-based cancellation and resumption." 253 - }, 254 - { 255 - "source_repo": "third_party/rust/curl-rust", 256 - "source_language": "Rust", 257 - "criticality": "low", 258 - "change_type": "enhancement", 259 - "title": "Add seek callback support for resumable uploads", 260 - "description": "curl-rust provides seek callbacks (Handler::seek with SeekResult) for repositioning in upload streams during retries, especially for multi-pass authentication or connection reuse.", 261 - "affected_files": [ 262 - "lib/body.ml", 263 - "lib/body.mli", 264 - "lib/requests.ml" 265 - ], 266 - "rationale": "When digest authentication or connection reuse requires resending request body, the library needs to rewind the input stream. curl-rust handles this via seek(whence: SeekFrom) -> SeekResult. Current Body module doesn't support seeking. Implementation would: (1) Add seek operation to Body.t for File/Stream sources, (2) Return SeekResult-equivalent (Ok, Fail, CantSeek), (3) Use during auth retry in http_client.ml." 267 - }, 268 - { 269 - "source_repo": "third_party/rust/curl-rust", 270 - "source_language": "Rust", 271 - "criticality": "medium", 272 - "change_type": "enhancement", 273 - "title": "Add response introspection without re-execution", 274 - "description": "curl-rust allows querying effective_url, primary_port, local_ip, remote_ip after request completion without re-executing. Useful for redirect chain analysis and connection debugging.", 275 - "affected_files": [ 276 - "lib/response.ml", 277 - "lib/response.mli" 278 - ], 279 - "rationale": "Response.url tracks final URL, but additional metadata would help debugging: (1) effective_url - final URL after all redirects (already present), (2) primary_port - actual connected port (useful for debugging), (3) local_ip/remote_ip - connection endpoints (network diagnostics). Implementation extends Response.t with optional metadata fields populated during connection establishment in http_client.ml." 280 - } 281 - ] 282 - }
-273
third_party/rust/hyper.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/rust/hyper", 5 - "source_language": "Rust", 6 - "criticality": "high", 7 - "change_type": "security", 8 - "title": "Add header size validation to prevent header injection attacks", 9 - "description": "Hyper validates header names and values during parsing to prevent header injection. The OCaml library should validate header values for control characters (CR, LF) that could enable response splitting attacks. Hyper's Parse::Header::Token error catches invalid header tokens during HTTP parsing.", 10 - "affected_files": [ 11 - "lib/headers.ml", 12 - "lib/headers.mli", 13 - "lib/http_read.ml" 14 - ], 15 - "rationale": "Header injection is a critical security vulnerability (CWE-113) that allows attackers to inject malicious headers or split HTTP responses. Hyper prevents this through strict parsing validation in src/proto/h1/decode.rs. The OCaml library accepts arbitrary header values without validation for control characters, creating a security risk when user input is passed to headers." 16 - }, 17 - { 18 - "source_repo": "third_party/rust/hyper", 19 - "source_language": "Rust", 20 - "criticality": "medium", 21 - "change_type": "enhancement", 22 - "title": "Add connection state tracking and graceful error recovery", 23 - "description": "Hyper tracks detailed connection states (idle, active, closed, poisoned) and provides query methods like is_ready(), is_closed(), poll_ready(). The OCaml library should add similar connection health checks to the connection pool to detect and recover from broken connections before attempting requests.", 24 - "affected_files": [ 25 - "lib/http_client.ml", 26 - "lib/requests.ml" 27 - ], 28 - "rationale": "Hyper's SendRequest type in src/client/conn/http1.rs provides is_ready(), is_closed(), and poll_ready() methods that allow applications to check connection health before sending requests. This prevents wasted request attempts on dead connections and enables better error handling. The OCaml library would benefit from similar connection state tracking in its connection pool to detect EOF, timeouts, or other connection failures proactively." 29 - }, 30 - { 31 - "source_repo": "third_party/rust/hyper", 32 - "source_language": "Rust", 33 - "criticality": "medium", 34 - "change_type": "enhancement", 35 - "title": "Implement HTTP/2 support for multiplexing and performance", 36 - "description": "Hyper supports both HTTP/1.1 and HTTP/2 with automatic protocol negotiation via ALPN. HTTP/2 provides request multiplexing, header compression, and server push. The OCaml library should add HTTP/2 support to improve performance for modern servers.", 37 - "affected_files": [ 38 - "lib/http_client.ml", 39 - "lib/one.ml", 40 - "lib/requests.ml" 41 - ], 42 - "rationale": "HTTP/2 is now the dominant protocol (over 50% of websites) and provides significant performance benefits: multiplexing eliminates head-of-line blocking, HPACK compression reduces header overhead, and binary framing is more efficient. Hyper implements HTTP/2 in src/proto/h2/ using the h2 crate. The OCaml library only supports HTTP/1.1, missing out on these performance improvements. Adding HTTP/2 via ocaml-h2 or similar would modernize the library." 43 - }, 44 - { 45 - "source_repo": "third_party/rust/hyper", 46 - "source_language": "Rust", 47 - "criticality": "high", 48 - "change_type": "security", 49 - "title": "Add URI validation to prevent request smuggling", 50 - "description": "Hyper validates URIs during parsing and rejects invalid characters, overly long URIs, and malformed components. The OCaml library should add strict URI validation before sending requests to prevent HTTP request smuggling attacks.", 51 - "affected_files": [ 52 - "lib/http_write.ml", 53 - "lib/one.ml", 54 - "lib/requests.ml" 55 - ], 56 - "rationale": "HTTP request smuggling (CWE-444) occurs when front-end and back-end servers disagree on request boundaries due to malformed URIs or headers. Hyper catches Parse::Uri and Parse::UriTooLong errors in src/error.rs and validates URIs using the http crate. The OCaml library accepts URIs from the Uri module without additional validation, which could allow smuggling attacks if special characters or excessive length bypass validation." 57 - }, 58 - { 59 - "source_repo": "third_party/rust/hyper", 60 - "source_language": "Rust", 61 - "criticality": "low", 62 - "change_type": "enhancement", 63 - "title": "Add informational (1xx) response handling", 64 - "description": "Hyper provides an extension API for handling informational responses (100 Continue, 102 Processing, 103 Early Hints) via the ext::informational module. The OCaml library handles 100 Continue but should expose other 1xx responses to applications.", 65 - "affected_files": [ 66 - "lib/response.ml", 67 - "lib/response.mli", 68 - "lib/http_read.ml" 69 - ], 70 - "rationale": "Modern HTTP servers may send informational responses like 103 Early Hints to allow clients to preload resources. Hyper exposes these via ext::Informational in src/ext/informational.rs. The OCaml library's 100-continue implementation in lib/http_client.ml only handles 100 responses, discarding other 1xx codes. Exposing these would enable applications to implement Early Hints and other optimizations." 71 - }, 72 - { 73 - "source_repo": "third_party/rust/hyper", 74 - "source_language": "Rust", 75 - "criticality": "medium", 76 - "change_type": "feature", 77 - "title": "Add request cancellation support", 78 - "description": "Hyper provides request cancellation through its Error::Canceled type, allowing in-flight requests to be gracefully cancelled. The OCaml library should add explicit cancellation support beyond switch cancellation to allow finer-grained control.", 79 - "affected_files": [ 80 - "lib/requests.ml", 81 - "lib/one.ml", 82 - "lib/error.ml", 83 - "lib/error.mli" 84 - ], 85 - "rationale": "Hyper's Error::new_canceled() in src/error.rs and is_canceled() query method enable applications to distinguish cancelled requests from other failures. While Eio's switch provides cancellation, the OCaml library doesn't expose a way to programmatically cancel individual requests or detect cancellation vs other errors. Adding explicit cancellation would improve error handling granularity." 86 - }, 87 - { 88 - "source_repo": "third_party/rust/hyper", 89 - "source_language": "Rust", 90 - "criticality": "medium", 91 - "change_type": "enhancement", 92 - "title": "Add body streaming with backpressure", 93 - "description": "Hyper's Body trait implements backpressure through poll_data() and size_hint(), preventing unbounded memory growth. The OCaml library should implement similar backpressure mechanisms when streaming large request/response bodies.", 94 - "affected_files": [ 95 - "lib/body.ml", 96 - "lib/body.mli", 97 - "lib/response.ml" 98 - ], 99 - "rationale": "Hyper's http_body::Body trait in src/body/mod.rs uses async polling and size hints to implement backpressure, preventing the sender from overwhelming the receiver. The OCaml library uses Eio.Flow for streaming, which provides some backpressure, but doesn't expose size hints or explicit flow control to applications. Adding size_hint() and explicit backpressure controls would prevent OOM when streaming very large bodies." 100 - }, 101 - { 102 - "source_repo": "third_party/rust/hyper", 103 - "source_language": "Rust", 104 - "criticality": "low", 105 - "change_type": "enhancement", 106 - "title": "Add HTTP upgrade support for WebSocket and other protocols", 107 - "description": "Hyper provides HTTP upgrade support to switch protocols (e.g., WebSocket, HTTP/2) mid-connection via the upgrade module. The OCaml library should add upgrade support to enable WebSocket clients and other protocol upgrades.", 108 - "affected_files": [ 109 - "lib/http_client.ml", 110 - "lib/response.ml", 111 - "lib/response.mli" 112 - ], 113 - "rationale": "HTTP upgrades (RFC 9110 Section 7.8) allow switching from HTTP to WebSocket, HTTP/2, or custom protocols. Hyper implements this in src/upgrade.rs with Connection::into_parts() to extract the raw IO. The OCaml library doesn't support upgrades, limiting its use for WebSocket clients. Adding upgrade support would enable real-time communication use cases." 114 - }, 115 - { 116 - "source_repo": "third_party/rust/hyper", 117 - "source_language": "Rust", 118 - "criticality": "high", 119 - "change_type": "security", 120 - "title": "Add Content-Length and Transfer-Encoding validation", 121 - "description": "Hyper strictly validates Content-Length headers and rejects requests with both Content-Length and Transfer-Encoding to prevent request smuggling. The OCaml library should add similar validation.", 122 - "affected_files": [ 123 - "lib/http_read.ml", 124 - "lib/http_write.ml" 125 - ], 126 - "rationale": "Request smuggling attacks (CWE-444) often exploit ambiguity when both Content-Length and Transfer-Encoding are present. Hyper raises Parse::Header::ContentLengthInvalid and Parse::Header::TransferEncodingUnexpected errors in src/error.rs to prevent this. The OCaml library should add similar validation in lib/http_read.ml to reject ambiguous or contradictory headers." 127 - }, 128 - { 129 - "source_repo": "third_party/rust/hyper", 130 - "source_language": "Rust", 131 - "criticality": "low", 132 - "change_type": "enhancement", 133 - "title": "Add detailed error context with source chain", 134 - "description": "Hyper's Error type implements the Error::source() chain, allowing applications to access the full causal chain of errors. The OCaml library should enhance error reporting to include more context about what operation failed and why.", 135 - "affected_files": [ 136 - "lib/error.ml", 137 - "lib/error.mli" 138 - ], 139 - "rationale": "Hyper's Error type in src/error.rs uses StdError::source() to chain errors, and provides find_source() to search the chain for specific error types. This enables rich error diagnostics. The OCaml library's Error module provides query functions like is_timeout() and is_connection(), but doesn't expose the underlying Eio exception chain. Adding a get_source() or similar function would help applications debug complex failures." 140 - }, 141 - { 142 - "source_repo": "third_party/rust/hyper", 143 - "source_language": "Rust", 144 - "criticality": "medium", 145 - "change_type": "enhancement", 146 - "title": "Add configurable parser limits", 147 - "description": "Hyper allows configuring parser limits like max_header_name_len, max_headers via Builder::http1_parser_config(). The OCaml library has Response_limits but should make HTTP parser limits configurable to handle non-standard servers.", 148 - "affected_files": [ 149 - "lib/http_read.ml", 150 - "lib/response_limits.ml", 151 - "lib/response_limits.mli" 152 - ], 153 - "rationale": "Hyper's Builder in src/client/conn/http1.rs exposes h1_parser_config() using httparse::ParserConfig to configure tolerances for non-compliant servers. The OCaml library has fixed parser behavior that may fail on servers with unusual formatting. Adding configurable parser strictness would improve compatibility." 154 - }, 155 - { 156 - "source_repo": "third_party/rust/hyper", 157 - "source_language": "Rust", 158 - "criticality": "low", 159 - "change_type": "enhancement", 160 - "title": "Add header case preservation option", 161 - "description": "Hyper provides h1_title_case_headers and h1_preserve_header_case options to control header formatting. The OCaml library should add similar options for compatibility with servers that expect specific header casing.", 162 - "affected_files": [ 163 - "lib/headers.ml", 164 - "lib/headers.mli", 165 - "lib/http_write.ml" 166 - ], 167 - "rationale": "While HTTP headers are case-insensitive, some legacy servers or APIs expect specific casing (e.g., 'Content-Type' vs 'content-type'). Hyper's Builder in src/client/conn/http1.rs provides h1_title_case_headers and h1_preserve_header_case for this. The OCaml library normalizes headers to lowercase, which could break compatibility with non-compliant servers." 168 - }, 169 - { 170 - "source_repo": "third_party/rust/hyper", 171 - "source_language": "Rust", 172 - "criticality": "medium", 173 - "change_type": "enhancement", 174 - "title": "Add writev optimization for scatter-gather I/O", 175 - "description": "Hyper supports vectored writes (writev) to send headers and body in a single syscall via h1_writev option. The OCaml library should use vectored I/O to reduce syscall overhead.", 176 - "affected_files": [ 177 - "lib/http_write.ml" 178 - ], 179 - "rationale": "Hyper's Builder::h1_writev() in src/client/conn/http1.rs enables vectored writes to combine multiple buffers (headers + body) into a single write syscall. This reduces context switches and improves performance. The OCaml library currently makes separate writes for headers and body in lib/http_write.ml. Using Eio's vectored write support would improve performance." 180 - }, 181 - { 182 - "source_repo": "third_party/rust/hyper", 183 - "source_language": "Rust", 184 - "criticality": "low", 185 - "change_type": "feature", 186 - "title": "Add HTTP reason phrase customization", 187 - "description": "Hyper provides ext::ReasonPhrase for custom HTTP status reason phrases. While optional in HTTP/1.1 and removed in HTTP/2, some applications need custom reason phrases for debugging or legacy compatibility.", 188 - "affected_files": [ 189 - "lib/status.ml", 190 - "lib/status.mli" 191 - ], 192 - "rationale": "Hyper's ext::h1_reason_phrase in src/ext/h1_reason_phrase.rs allows setting custom reason phrases for HTTP/1.1 responses. While RFC 9112 makes reason phrases optional, some debugging tools or legacy systems rely on them. The OCaml library uses fixed reason phrases in lib/status.ml. Adding customization would improve debugging visibility." 193 - }, 194 - { 195 - "source_repo": "third_party/rust/hyper", 196 - "source_language": "Rust", 197 - "criticality": "low", 198 - "change_type": "enhancement", 199 - "title": "Add connection pooling metrics and observability", 200 - "description": "Hyper exposes connection state through is_ready(), is_closed() and similar methods. The OCaml library should add metrics for connection pool health (active connections, idle connections, failed connections) to aid debugging and monitoring.", 201 - "affected_files": [ 202 - "lib/requests.ml" 203 - ], 204 - "rationale": "Hyper's Connection and SendRequest types in src/client/conn/http1.rs provide state query methods for observability. The OCaml library uses Conpool for connection pooling but doesn't expose metrics like pool size, checkout/checkin rates, or connection failures. Adding metrics would help diagnose performance issues and connection leaks." 205 - }, 206 - { 207 - "source_repo": "third_party/rust/hyper", 208 - "source_language": "Rust", 209 - "criticality": "medium", 210 - "change_type": "enhancement", 211 - "title": "Add half-close support for request streaming", 212 - "description": "Hyper supports TCP half-close via Builder::half_close() to allow reading responses while still sending request body. The OCaml library should add half-close support for bidirectional streaming scenarios.", 213 - "affected_files": [ 214 - "lib/http_client.ml", 215 - "lib/one.ml" 216 - ], 217 - "rationale": "HTTP allows servers to send responses before fully receiving the request body, requiring TCP half-close. Hyper's Builder::half_close() in src/client/conn/http1.rs enables this for streaming scenarios. The OCaml library doesn't explicitly handle half-close, which could cause hangs if servers send early responses. Adding half-close support would improve robustness." 218 - }, 219 - { 220 - "source_repo": "third_party/rust/hyper", 221 - "source_language": "Rust", 222 - "criticality": "low", 223 - "change_type": "enhancement", 224 - "title": "Add support for HTTP trailers", 225 - "description": "Hyper supports HTTP trailers (headers sent after the body in chunked encoding) via the Body trait. The OCaml library should add trailer support for completeness and advanced use cases like integrity checksums.", 226 - "affected_files": [ 227 - "lib/http_read.ml", 228 - "lib/response.ml", 229 - "lib/response.mli" 230 - ], 231 - "rationale": "HTTP trailers (RFC 9110 Section 6.5) allow sending headers after the message body, useful for checksums, signatures, or dynamic metadata. Hyper's Body::poll_trailers() in src/body/mod.rs supports this. The OCaml library's chunked decoder in lib/http_read.ml doesn't parse trailers, discarding potentially important metadata." 232 - }, 233 - { 234 - "source_repo": "third_party/rust/hyper", 235 - "source_language": "Rust", 236 - "criticality": "medium", 237 - "change_type": "feature", 238 - "title": "Add proxy support with CONNECT method", 239 - "description": "Hyper examples demonstrate HTTP and HTTPS proxy support via CONNECT tunneling. The OCaml library should add proxy support for corporate and restricted network environments.", 240 - "affected_files": [ 241 - "lib/requests.ml", 242 - "lib/one.ml", 243 - "lib/http_client.ml" 244 - ], 245 - "rationale": "HTTP proxies are essential for corporate networks, testing, and privacy. Hyper's http_proxy.rs example shows CONNECT tunneling for HTTPS through proxies. The OCaml library has no proxy support, limiting its use in enterprise environments. Adding HTTP_PROXY/HTTPS_PROXY environment variable support and CONNECT tunneling would address this gap." 246 - }, 247 - { 248 - "source_repo": "third_party/rust/hyper", 249 - "source_language": "Rust", 250 - "criticality": "low", 251 - "change_type": "enhancement", 252 - "title": "Add configurable read buffer size", 253 - "description": "Hyper allows configuring h1_read_buf_exact_size and h1_max_buf_size to tune memory usage vs performance. The OCaml library should expose similar buffer size controls.", 254 - "affected_files": [ 255 - "lib/http_read.ml", 256 - "lib/requests.ml" 257 - ], 258 - "rationale": "Hyper's Builder in src/client/conn/http1.rs provides h1_read_buf_exact_size and h1_max_buf_size to control buffer allocation strategy. The OCaml library uses Eio's default buffer sizes in lib/http_read.ml, which may not be optimal for all scenarios. Exposing buffer size configuration would let applications tune memory vs throughput." 259 - }, 260 - { 261 - "source_repo": "third_party/rust/hyper", 262 - "source_language": "Rust", 263 - "criticality": "low", 264 - "change_type": "enhancement", 265 - "title": "Add examples directory with common use cases", 266 - "description": "Hyper provides 15+ examples covering client/server patterns, JSON APIs, proxy, graceful shutdown, HTTP/2, etc. The OCaml library should expand its examples to cover more real-world scenarios.", 267 - "affected_files": [ 268 - "examples/" 269 - ], 270 - "rationale": "Hyper's examples/ directory in third_party/rust/hyper/examples/ includes client.rs, client_json.rs, http_proxy.rs, graceful_shutdown.rs, and others covering common patterns. The OCaml library has only examples/session_example.ml. Adding examples for JSON APIs, file upload/download, error handling, concurrent requests, and proxy usage would improve developer experience." 271 - } 272 - ] 273 - }
-260
third_party/rust/isahc.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/rust/isahc", 5 - "source_language": "Rust", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add Request/Response Metrics Tracking", 9 - "description": "Implement detailed performance metrics for HTTP requests including DNS lookup time, connection time, TLS handshake time, transfer time, and upload/download speeds. The metrics should be accessible during and after request execution to enable performance monitoring and debugging.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/response.ml" 13 - ], 14 - "rationale": "Isahc provides comprehensive metrics tracking (DNS lookup, TCP connect, TLS handshake, transfer times, upload/download progress and speed) which is invaluable for performance debugging and monitoring. The OCaml library currently only tracks total elapsed time. Adding granular metrics would enable users to identify performance bottlenecks (slow DNS, slow connection, slow transfer) and implement progress callbacks for long-running uploads/downloads. This is particularly useful for debugging timeout issues and optimizing retry strategies." 15 - }, 16 - { 17 - "source_repo": "third_party/rust/isahc", 18 - "source_language": "Rust", 19 - "criticality": "low", 20 - "change_type": "enhancement", 21 - "title": "Add HTTP Proxy Support with Authentication", 22 - "description": "Implement HTTP/HTTPS proxy support with optional authentication (Basic, Digest). Allow per-request proxy configuration and proxy blacklist/whitelist for specific domains. Include environment variable support (HTTP_PROXY, HTTPS_PROXY, NO_PROXY).", 23 - "affected_files": [ 24 - "lib/requests.ml", 25 - "lib/http_client.ml", 26 - "lib/auth.ml" 27 - ], 28 - "rationale": "Isahc provides comprehensive proxy support including proxy authentication, per-request configuration, and domain blacklisting. The OCaml library has placeholder proxy error types but no implementation. Proxy support is essential for enterprise environments, CI/CD pipelines, and users behind corporate firewalls. The current TODO.md mentions proxy support is pending. Implementing this would significantly expand the library's usability in restricted network environments." 29 - }, 30 - { 31 - "source_repo": "third_party/rust/isahc", 32 - "source_language": "Rust", 33 - "criticality": "medium", 34 - "change_type": "enhancement", 35 - "title": "Add Network Interface Binding and IP Version Selection", 36 - "description": "Allow users to bind requests to a specific network interface and select IP version preference (IPv4-only, IPv6-only, or auto). This enables testing from specific network interfaces and working around IPv6 connectivity issues.", 37 - "affected_files": [ 38 - "lib/requests.ml", 39 - "lib/http_client.ml" 40 - ], 41 - "rationale": "Isahc allows binding to specific network interfaces and selecting IP version (IPv4/IPv6), which is useful for testing multi-homed systems, load balancing across interfaces, and working around IPv6 connectivity problems. This is particularly valuable for systems with multiple network interfaces or when debugging network-specific issues. The feature would complement the existing connection pooling infrastructure." 42 - }, 43 - { 44 - "source_repo": "third_party/rust/isahc", 45 - "source_language": "Rust", 46 - "criticality": "low", 47 - "change_type": "enhancement", 48 - "title": "Add TCP Configuration Options (Keep-Alive, NoDelay)", 49 - "description": "Expose TCP socket options including TCP keep-alive interval and TCP_NODELAY (Nagle algorithm control). These options allow fine-tuning connection behavior for different network conditions and application requirements.", 50 - "affected_files": [ 51 - "lib/requests.ml", 52 - "lib/http_client.ml" 53 - ], 54 - "rationale": "Isahc exposes TCP socket configuration including keep-alive intervals and TCP_NODELAY. These options are important for optimizing performance in different scenarios: TCP_NODELAY reduces latency for small messages by disabling Nagle's algorithm, while keep-alive helps detect dead connections in long-lived pooled connections. The OCaml library uses connection pools but doesn't expose these TCP-level controls, which could improve connection reliability and performance." 55 - }, 56 - { 57 - "source_repo": "third_party/rust/isahc", 58 - "source_language": "Rust", 59 - "criticality": "low", 60 - "change_type": "enhancement", 61 - "title": "Add Upload/Download Speed Limiting", 62 - "description": "Implement configurable speed limits for upload and download operations to prevent bandwidth saturation and enable rate-limited data transfers. Support per-request and per-session configuration.", 63 - "affected_files": [ 64 - "lib/requests.ml", 65 - "lib/http_client.ml", 66 - "lib/body.ml" 67 - ], 68 - "rationale": "Isahc provides max_upload_speed and max_download_speed configuration options to throttle bandwidth usage. This is useful for background uploads/downloads that shouldn't saturate the network, testing bandwidth-constrained scenarios, and being a good network citizen. The feature would complement the existing streaming body support and could be implemented using Eio's rate limiting primitives." 69 - }, 70 - { 71 - "source_repo": "third_party/rust/isahc", 72 - "source_language": "Rust", 73 - "criticality": "medium", 74 - "change_type": "enhancement", 75 - "title": "Add Low-Speed Timeout Protection", 76 - "description": "Implement a low-speed timeout that triggers when transfer speed drops below a threshold for a sustained period. This prevents requests from hanging indefinitely on slow/stalled connections that don't fully timeout.", 77 - "affected_files": [ 78 - "lib/timeout.ml", 79 - "lib/requests.ml", 80 - "lib/http_client.ml" 81 - ], 82 - "rationale": "Isahc implements low_speed_timeout which fails requests if average transfer speed falls below a threshold (e.g., abort if speed < 1000 bytes/sec for 30 seconds). The OCaml library has connect/read/total timeouts but not speed-based timeouts. This addresses a common problem where connections become extremely slow but don't fully hang, causing requests to wait for minutes despite making no meaningful progress. This is especially important for large file transfers where total timeout might be too long." 83 - }, 84 - { 85 - "source_repo": "third_party/rust/isahc", 86 - "source_language": "Rust", 87 - "criticality": "low", 88 - "change_type": "enhancement", 89 - "title": "Add DNS Caching with TTL Support", 90 - "description": "Implement optional DNS result caching with configurable TTL to reduce DNS lookup overhead for repeated requests to the same hosts. Support both timeout-based and disabled modes.", 91 - "affected_files": [ 92 - "lib/requests.ml" 93 - ], 94 - "rationale": "Isahc provides DNS caching with configurable TTL (e.g., cache DNS results for 120 seconds) to improve performance when making multiple requests to the same host. The OCaml library performs DNS lookups for each connection request, which can be slow for high-frequency requests. While Eio may have system-level DNS caching, explicit application-level caching with configurable TTL gives users more control and can significantly improve performance in request-heavy scenarios." 95 - }, 96 - { 97 - "source_repo": "third_party/rust/isahc", 98 - "source_language": "Rust", 99 - "criticality": "medium", 100 - "change_type": "enhancement", 101 - "title": "Add Request Body Rewind Support for Retries", 102 - "description": "Implement a rewindable body type that can be replayed for retries and redirects. Provide clear errors when retries fail because the body cannot be rewound (e.g., streaming bodies).", 103 - "affected_files": [ 104 - "lib/body.ml", 105 - "lib/retry.ml", 106 - "lib/error.ml" 107 - ], 108 - "rationale": "Isahc distinguishes between rewindable bodies (in-memory buffers, static data) and non-rewindable bodies (streams) and raises RequestBodyNotRewindable errors when retries/redirects need to replay the body but cannot. The OCaml library's retry logic doesn't currently handle body rewinding - it likely sends the same body multiple times which may fail for streaming bodies or file handles that have been consumed. Adding explicit rewind support or clear errors would prevent subtle bugs and improve retry reliability." 109 - }, 110 - { 111 - "source_repo": "third_party/rust/isahc", 112 - "source_language": "Rust", 113 - "criticality": "low", 114 - "change_type": "enhancement", 115 - "title": "Add Custom Cipher Suite Configuration", 116 - "description": "Allow users to configure custom TLS cipher suites for security hardening or compatibility with specific servers. Support both allowlist and priority ordering of cipher suites.", 117 - "affected_files": [ 118 - "lib/requests.ml" 119 - ], 120 - "rationale": "Isahc allows custom cipher suite configuration for TLS connections, which is important for security-conscious deployments that need to disable weak ciphers or for compatibility with legacy servers that only support specific cipher suites. The OCaml library uses default TLS configuration from the tls library. While the tls_config parameter allows some customization, exposing a higher-level cipher suite API would make it easier for users to enforce security policies without deep TLS knowledge." 121 - }, 122 - { 123 - "source_repo": "third_party/rust/isahc", 124 - "source_language": "Rust", 125 - "criticality": "low", 126 - "change_type": "feature", 127 - "title": "Add HTTP/2 Support with Version Negotiation", 128 - "description": "Implement HTTP/2 protocol support with automatic or manual version negotiation. Allow users to prefer HTTP/2, fall back to HTTP/1.1, or force a specific version. Support HTTP/2 features like multiplexing and server push where applicable.", 129 - "affected_files": [ 130 - "lib/requests.ml", 131 - "lib/http_client.ml" 132 - ], 133 - "rationale": "Isahc supports HTTP/2 with configurable version negotiation (HTTP/1.1 only, HTTP/2 preferred, HTTP/2 required). HTTP/2 provides significant performance benefits through multiplexing, header compression, and server push. The OCaml library currently only supports HTTP/1.1. While implementing full HTTP/2 is a major undertaking, the architecture should be designed to accommodate it (e.g., abstract protocol layer, per-protocol connection pools). This would significantly improve performance for modern APIs that support HTTP/2." 134 - }, 135 - { 136 - "source_repo": "third_party/rust/isahc", 137 - "source_language": "Rust", 138 - "criticality": "low", 139 - "change_type": "enhancement", 140 - "title": "Add Automatic Referer Header Management", 141 - "description": "Implement automatic Referer header management for redirects - automatically set the Referer header to the previous URL when following redirects (configurable). This matches browser behavior and is expected by some APIs.", 142 - "affected_files": [ 143 - "lib/requests.ml" 144 - ], 145 - "rationale": "Isahc provides auto_referer configuration which automatically adds a Referer header pointing to the previous URL when following redirects, matching browser behavior. The OCaml library doesn't currently manage Referer headers during redirects. While users can manually add Referer headers, automatic management would improve compatibility with APIs that check referrers and reduce boilerplate for common use cases." 146 - }, 147 - { 148 - "source_repo": "third_party/rust/isahc", 149 - "source_language": "Rust", 150 - "criticality": "medium", 151 - "change_type": "enhancement", 152 - "title": "Add Interceptor/Middleware Pattern for Request/Response Modification", 153 - "description": "Implement a middleware/interceptor pattern that allows users to intercept and modify requests before sending and responses after receiving. Support chaining multiple interceptors and both sync/async interceptors.", 154 - "affected_files": [ 155 - "lib/requests.ml" 156 - ], 157 - "rationale": "Isahc provides an interceptor pattern (though marked unstable) that allows middleware-like request/response transformation. This is powerful for cross-cutting concerns like logging, request signing, response caching, metrics collection, or custom authentication schemes. The OCaml library has Auth.custom which allows header modification, but a general interceptor pattern would be more flexible. This would enable users to implement custom retry logic, caching layers, and protocol extensions without modifying the library core." 158 - }, 159 - { 160 - "source_repo": "third_party/rust/isahc", 161 - "source_language": "Rust", 162 - "criticality": "low", 163 - "change_type": "enhancement", 164 - "title": "Add Connection Cache TTL Configuration", 165 - "description": "Expose configuration for connection cache TTL separate from idle timeout - control how long successful connections are eligible for reuse even if actively used. This prevents reusing connections that may have server-side timeouts.", 166 - "affected_files": [ 167 - "lib/requests.ml" 168 - ], 169 - "rationale": "Isahc provides connection_cache_ttl to limit the maximum lifetime of pooled connections regardless of activity. The OCaml library has connection_idle_timeout and connection_lifetime which together provide similar functionality. However, the current implementation should verify that max_connection_lifetime is honored even for actively-used connections to prevent issues with servers that close connections after a fixed lifetime. This is already partially implemented but may need validation." 170 - }, 171 - { 172 - "source_repo": "third_party/rust/isahc", 173 - "source_language": "Rust", 174 - "criticality": "low", 175 - "change_type": "enhancement", 176 - "title": "Add Request-Specific Connection Pool Override", 177 - "description": "Allow individual requests to opt-out of connection pooling or use a custom pool. This is useful for requests that shouldn't share connections (e.g., long-polling, streaming) or need isolation (e.g., different authentication contexts).", 178 - "affected_files": [ 179 - "lib/requests.ml" 180 - ], 181 - "rationale": "Isahc allows per-request configuration to close connections immediately (close_connections option) or use different pools. The OCaml library always uses the session's connection pools. Some requests (long-polling, SSE, WebSocket upgrades) benefit from dedicated connections, and some use cases need connection isolation. The One module provides stateless requests but doesn't support advanced pooling controls. Adding per-request pool configuration would increase flexibility." 182 - }, 183 - { 184 - "source_repo": "third_party/rust/isahc", 185 - "source_language": "Rust", 186 - "criticality": "low", 187 - "change_type": "enhancement", 188 - "title": "Add Expect: 100-Continue Header Timeout Configuration", 189 - "description": "Make the Expect: 100-continue timeout independently configurable from other timeouts. Currently it uses a fixed 1-second timeout which may be too short for slow servers.", 190 - "affected_files": [ 191 - "lib/timeout.ml", 192 - "lib/expect_continue.ml" 193 - ], 194 - "rationale": "Isahc separates expect_100_continue timeout from other timeout settings, recognizing that 100-continue responses should be fast but may need different tuning than full request timeouts. The OCaml library implements 100-continue with a fixed 1-second timeout. While this is reasonable, making it configurable would help users deal with slow servers or high-latency connections where 1 second might not be enough to receive the 100 Continue response." 195 - }, 196 - { 197 - "source_repo": "third_party/rust/isahc", 198 - "source_language": "Rust", 199 - "criticality": "low", 200 - "change_type": "enhancement", 201 - "title": "Add Custom DNS Resolution Override", 202 - "description": "Allow users to override DNS resolution for specific hosts, mapping hostnames to custom IP addresses. This is useful for testing, working around DNS issues, or accessing services via non-standard addresses.", 203 - "affected_files": [ 204 - "lib/requests.ml" 205 - ], 206 - "rationale": "Isahc provides dns_resolve configuration to manually map hostnames to IP addresses, bypassing DNS lookup. This is valuable for testing (e.g., test prod code against staging servers), working around broken DNS, or connecting to services via IP while using proper SNI hostnames for TLS. The feature would integrate with Eio's DNS resolution and could be implemented as a hostname->IP map in the session configuration." 207 - }, 208 - { 209 - "source_repo": "third_party/rust/isahc", 210 - "source_language": "Rust", 211 - "criticality": "low", 212 - "change_type": "enhancement", 213 - "title": "Add Text Encoding Detection and Conversion", 214 - "description": "Implement automatic text encoding detection from Content-Type charset parameter and convert response bodies to UTF-8. Support common encodings (ISO-8859-1, Windows-1252, etc.) with fallback to UTF-8.", 215 - "affected_files": [ 216 - "lib/response.ml", 217 - "lib/mime.ml" 218 - ], 219 - "rationale": "Isahc provides text-decoding feature that automatically detects charset from Content-Type headers and converts response text to UTF-8 using encoding_rs. The OCaml library's Response.text returns raw bytes without encoding handling. While OCaml users can manually handle encodings, automatic detection and conversion would improve ergonomics for international content and legacy systems using non-UTF-8 encodings. This could be implemented as Response.text_utf8 using the uutf library." 220 - }, 221 - { 222 - "source_repo": "third_party/rust/isahc", 223 - "source_language": "Rust", 224 - "criticality": "low", 225 - "change_type": "enhancement", 226 - "title": "Add Negotiate/SPNEGO Authentication Support", 227 - "description": "Implement Kerberos/SPNEGO authentication (Negotiate scheme) for enterprise environments using Windows domain authentication or Kerberos. This should be optional (feature-gated) due to system dependencies.", 228 - "affected_files": [ 229 - "lib/auth.ml" 230 - ], 231 - "rationale": "Isahc provides SPNEGO/Kerberos authentication (via spnego feature flag) which is essential for enterprise environments using Windows domain authentication. The OCaml library supports Basic, Bearer, and Digest but not Negotiate. While this requires system dependencies (GSSAPI/SSPI), it would significantly expand enterprise usability. This could be implemented as an optional feature using existing OCaml GSSAPI bindings if available, or documented as a custom authentication implementation pattern." 232 - }, 233 - { 234 - "source_repo": "third_party/rust/isahc", 235 - "source_language": "Rust", 236 - "criticality": "medium", 237 - "change_type": "enhancement", 238 - "title": "Add Per-Host Connection Limit Configuration", 239 - "description": "Make the per-host connection limit configurable at runtime rather than just at session creation. Allow overriding limits for specific hosts to handle servers with different connection constraints.", 240 - "affected_files": [ 241 - "lib/requests.ml" 242 - ], 243 - "rationale": "Isahc allows configuring max connections per host both globally and potentially per-endpoint. The OCaml library sets max_connections_per_host at session creation but doesn't allow per-host overrides. Different servers have different connection limits (e.g., some APIs allow only 2 concurrent connections, others allow 100+). The conpool library may already support this - verify if endpoint-specific limits are possible and expose them if so." 244 - }, 245 - { 246 - "source_repo": "third_party/rust/isahc", 247 - "source_language": "Rust", 248 - "criticality": "low", 249 - "change_type": "enhancement", 250 - "title": "Add Request/Response Logging with Sanitization", 251 - "description": "Enhance logging to include full request/response details (headers, body excerpts) at debug level with automatic sanitization of sensitive headers. Implement structured logging for better observability.", 252 - "affected_files": [ 253 - "lib/requests.ml", 254 - "lib/error.ml", 255 - "lib/headers.ml" 256 - ], 257 - "rationale": "Isahc uses tracing for structured logging with detailed request/response information. The OCaml library has good logging but could be enhanced with: (1) structured logs for metrics/monitoring tools, (2) automatic sanitization in logs (already done in errors, extend to logs), (3) configurable verbosity levels for different components. The current verbose_http flag is good but could be extended to support different log levels per module for finer control." 258 - } 259 - ] 260 - }
-258
third_party/rust/reqwest.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "reqwest", 5 - "source_language": "Rust", 6 - "criticality": "high", 7 - "change_type": "security", 8 - "title": "Add URL sanitization for error messages", 9 - "description": "reqwest provides url() and url_mut() methods on Error types to access and sanitize URLs before logging. It also has without_url() to strip URLs containing sensitive information (like API keys in query parameters). The OCaml library's error module should sanitize URLs in error messages to prevent accidental leakage of credentials embedded in URLs.", 10 - "affected_files": [ 11 - "lib/error.ml", 12 - "lib/error.mli" 13 - ], 14 - "rationale": "reqwest's error.rs (lines 60-91) demonstrates URL sanitization to prevent credential leakage. The OCaml library has sanitize_url and sanitize_headers functions (lib/error.mli:92-100) but should extend this to all error messages and provide similar public API methods for manipulating error URLs." 15 - }, 16 - { 17 - "source_repo": "reqwest", 18 - "source_language": "Rust", 19 - "criticality": "high", 20 - "change_type": "feature", 21 - "title": "Add HTTP proxy support", 22 - "description": "reqwest has comprehensive proxy support including HTTP/HTTPS/SOCKS proxies with authentication, custom headers, NO_PROXY filtering, and system proxy detection. The OCaml library should implement basic HTTP/HTTPS proxy support with authentication and environment variable configuration (HTTP_PROXY, HTTPS_PROXY, NO_PROXY).", 23 - "affected_files": [ 24 - "lib/requests.ml", 25 - "lib/requests.mli", 26 - "lib/http_client.ml" 27 - ], 28 - "rationale": "Proxy support is essential for enterprise environments. reqwest's proxy.rs shows a mature implementation with ProxyMatcher, authentication, and NoProxy filtering. This is a commonly requested feature for HTTP clients." 29 - }, 30 - { 31 - "source_repo": "reqwest", 32 - "source_language": "Rust", 33 - "criticality": "medium", 34 - "change_type": "enhancement", 35 - "title": "Add error_for_status() method on Response", 36 - "description": "reqwest provides error_for_status() on Response which checks if the status code is 4xx/5xx and returns an error if so. The OCaml library has raise_for_status but should also provide a non-raising variant that returns a Result type for functional error handling.", 37 - "affected_files": [ 38 - "lib/response.ml", 39 - "lib/response.mli" 40 - ], 41 - "rationale": "reqwest's response.rs shows both raising and non-raising patterns. The OCaml library has raise_for_status (lib/response.mli:218-230) but could benefit from a Result-based variant like `check_status : t -> (t, Error.error) result` for more functional code." 42 - }, 43 - { 44 - "source_repo": "reqwest", 45 - "source_language": "Rust", 46 - "criticality": "medium", 47 - "change_type": "enhancement", 48 - "title": "Enhance redirect policy customization", 49 - "description": "reqwest allows custom redirect policies with access to attempt status, URL, and previous URLs, plus the ability to stop, follow, or error. The OCaml library should expose similar redirect customization allowing users to implement custom redirect logic beyond simple max-redirect limits.", 50 - "affected_files": [ 51 - "lib/requests.ml", 52 - "lib/requests.mli" 53 - ], 54 - "rationale": "reqwest's redirect.rs (lines 102-109) shows Policy::custom() with an Attempt type providing status(), url(), previous() accessors. The OCaml library currently only supports follow_redirects boolean and max_redirects int (lib/requests.mli:229-230), lacking custom redirect logic." 55 - }, 56 - { 57 - "source_repo": "reqwest", 58 - "source_language": "Rust", 59 - "criticality": "medium", 60 - "change_type": "feature", 61 - "title": "Add connection pooling tuning parameters", 62 - "description": "reqwest exposes pool_idle_timeout (default 90s) and pool_max_idle_per_host (default unlimited) for fine-grained connection pool control. The OCaml library should expose similar tunables for connection_idle_timeout and max_connections_per_host to allow users to optimize for their use cases.", 63 - "affected_files": [ 64 - "lib/requests.mli" 65 - ], 66 - "rationale": "reqwest's client.rs (lines 297-298) shows pool configuration. The OCaml library has connection_idle_timeout and max_connections_per_host parameters in create() (lib/requests.mli:234-261) but should document best practices and defaults more clearly." 67 - }, 68 - { 69 - "source_repo": "reqwest", 70 - "source_language": "Rust", 71 - "criticality": "medium", 72 - "change_type": "enhancement", 73 - "title": "Add TCP keep-alive configuration", 74 - "description": "reqwest provides tcp_keepalive, tcp_keepalive_interval, and tcp_keepalive_retries to configure TCP keep-alive behavior. This helps detect broken connections and maintain long-lived connections. The OCaml library should expose TCP keep-alive settings in the connection pool configuration.", 75 - "affected_files": [ 76 - "lib/requests.mli" 77 - ], 78 - "rationale": "reqwest's client.rs (lines 299-301) shows TCP keep-alive defaults (15s interval). This is important for long-lived connections in production environments to detect network failures early." 79 - }, 80 - { 81 - "source_repo": "reqwest", 82 - "source_language": "Rust", 83 - "criticality": "medium", 84 - "change_type": "enhancement", 85 - "title": "Add response charset/encoding detection", 86 - "description": "reqwest's text() method (with charset feature) automatically detects character encoding from Content-Type header and provides BOM sniffing for proper text decoding. The OCaml library should add encoding detection for Response.text() to properly handle non-UTF-8 responses.", 87 - "affected_files": [ 88 - "lib/response.ml", 89 - "lib/response.mli" 90 - ], 91 - "rationale": "reqwest's response.rs (lines 163-175) shows encoding detection via Content-Type charset parameter. The OCaml Response.text() (lib/response.mli:199-203) currently assumes UTF-8, which may corrupt non-UTF-8 content." 92 - }, 93 - { 94 - "source_repo": "reqwest", 95 - "source_language": "Rust", 96 - "criticality": "medium", 97 - "change_type": "enhancement", 98 - "title": "Add HTTP/2 configuration options", 99 - "description": "reqwest provides extensive HTTP/2 tuning: initial_stream_window_size, initial_connection_window_size, adaptive_window, max_frame_size, max_header_list_size, keep_alive_interval, keep_alive_timeout, keep_alive_while_idle. The OCaml library should expose key HTTP/2 settings for performance tuning.", 100 - "affected_files": [ 101 - "lib/requests.mli" 102 - ], 103 - "rationale": "reqwest's client.rs (lines 211-226) shows comprehensive HTTP/2 configuration. While the OCaml library may use HTTP/1.1, future HTTP/2 support would benefit from planning these configuration options." 104 - }, 105 - { 106 - "source_repo": "reqwest", 107 - "source_language": "Rust", 108 - "criticality": "low", 109 - "change_type": "enhancement", 110 - "title": "Add local IP address binding option", 111 - "description": "reqwest allows binding to a specific local IP address for outgoing connections via local_address option. This is useful for multi-homed systems or when a specific network interface should be used. The OCaml library should add a similar option.", 112 - "affected_files": [ 113 - "lib/requests.mli" 114 - ], 115 - "rationale": "reqwest's client.rs (line 227) shows local_address configuration. This is useful for systems with multiple network interfaces or when testing network behavior from specific source IPs." 116 - }, 117 - { 118 - "source_repo": "reqwest", 119 - "source_language": "Rust", 120 - "criticality": "low", 121 - "change_type": "enhancement", 122 - "title": "Add remote_addr() method to Response", 123 - "description": "reqwest provides remote_addr() on Response to get the actual socket address that was connected to (useful for debugging, logging, and connection reuse tracking). The OCaml library should add this metadata to responses.", 124 - "affected_files": [ 125 - "lib/response.ml", 126 - "lib/response.mli" 127 - ], 128 - "rationale": "reqwest's response.rs (lines 115-121) shows remote address extraction via HttpInfo extension. This is valuable for debugging, logging (especially with proxies/load balancers), and understanding connection behavior." 129 - }, 130 - { 131 - "source_repo": "reqwest", 132 - "source_language": "Rust", 133 - "criticality": "low", 134 - "change_type": "enhancement", 135 - "title": "Add response extensions API", 136 - "description": "reqwest provides extensions() and extensions_mut() on Response for attaching arbitrary typed metadata (like TlsInfo). The OCaml library should provide a similar extensible metadata mechanism for responses to allow library users to attach custom data.", 137 - "affected_files": [ 138 - "lib/response.ml", 139 - "lib/response.mli" 140 - ], 141 - "rationale": "reqwest's response.rs (lines 123-131) shows extensions for TLS info and other metadata. This provides extensibility without modifying the core Response type, useful for middleware and advanced use cases." 142 - }, 143 - { 144 - "source_repo": "reqwest", 145 - "source_language": "Rust", 146 - "criticality": "medium", 147 - "change_type": "feature", 148 - "title": "Add comprehensive test suite with mock server", 149 - "description": "reqwest has extensive integration tests using a local HTTP server (tests/support/server.rs) that test timeouts, redirects, proxies, compression, cookies, multipart, etc. The OCaml library should expand its test coverage with a similar test server infrastructure.", 150 - "affected_files": [ 151 - "test/test_localhost.ml", 152 - "test/test_simple.ml" 153 - ], 154 - "rationale": "reqwest's tests/ directory shows comprehensive testing including edge cases like redirect loops, proxy auth, compression bombs, timeout scenarios. The OCaml library has basic tests but would benefit from more comprehensive coverage." 155 - }, 156 - { 157 - "source_repo": "reqwest", 158 - "source_language": "Rust", 159 - "criticality": "medium", 160 - "change_type": "enhancement", 161 - "title": "Add content_length() method to Response", 162 - "description": "reqwest provides content_length() on Response which returns the actual decoded body size (accounting for decompression), not just the Content-Length header. The OCaml library should distinguish between header value and actual body size in its Response API.", 163 - "affected_files": [ 164 - "lib/response.ml", 165 - "lib/response.mli" 166 - ], 167 - "rationale": "reqwest's response.rs (lines 78-94) shows content_length() that accounts for decompression and streaming. The OCaml Response.content_length() (lib/response.mli:75-77) should clarify whether it returns header value or actual size." 168 - }, 169 - { 170 - "source_repo": "reqwest", 171 - "source_language": "Rust", 172 - "criticality": "low", 173 - "change_type": "enhancement", 174 - "title": "Add version() method to Response", 175 - "description": "reqwest exposes the HTTP version (HTTP/1.0, HTTP/1.1, HTTP/2, HTTP/3) used for the response. The OCaml library should expose the HTTP version in Response for debugging and analytics.", 176 - "affected_files": [ 177 - "lib/response.ml", 178 - "lib/response.mli" 179 - ], 180 - "rationale": "reqwest's response.rs (lines 60-64) shows version() accessor. This is useful for debugging protocol negotiation, monitoring HTTP/2 adoption, and detecting protocol downgrade attacks." 181 - }, 182 - { 183 - "source_repo": "reqwest", 184 - "source_language": "Rust", 185 - "criticality": "low", 186 - "change_type": "enhancement", 187 - "title": "Add HTTPS-only mode", 188 - "description": "reqwest provides an https_only option that rejects HTTP URLs, preventing accidental downgrade from HTTPS to HTTP. The OCaml library should add a similar safety feature to enforce HTTPS-only requests.", 189 - "affected_files": [ 190 - "lib/requests.ml", 191 - "lib/requests.mli" 192 - ], 193 - "rationale": "reqwest's client.rs (line 246) shows https_only flag. This prevents accidental credential leakage over unencrypted HTTP and enforces security policies in production environments." 194 - }, 195 - { 196 - "source_repo": "reqwest", 197 - "source_language": "Rust", 198 - "criticality": "medium", 199 - "change_type": "enhancement", 200 - "title": "Add referer header policy", 201 - "description": "reqwest has a configurable referer policy (default: true) that automatically sets the Referer header on redirects. The OCaml library should add control over automatic Referer header behavior for privacy and compliance.", 202 - "affected_files": [ 203 - "lib/requests.ml", 204 - "lib/requests.mli" 205 - ], 206 - "rationale": "reqwest's client.rs (line 183) shows referer configuration. The Referer header can leak sensitive information in URLs, so libraries should allow users to control this behavior according to privacy policies." 207 - }, 208 - { 209 - "source_repo": "reqwest", 210 - "source_language": "Rust", 211 - "criticality": "high", 212 - "change_type": "security", 213 - "title": "Strip sensitive headers on cross-origin redirects", 214 - "description": "reqwest strips Authorization, Cookie, and Proxy-Authorization headers when redirecting to a different origin (host/port/scheme) to prevent credential leakage. The OCaml library should implement similar header stripping on cross-origin redirects.", 215 - "affected_files": [ 216 - "lib/requests.ml", 217 - "lib/http_client.ml" 218 - ], 219 - "rationale": "reqwest's redirect.rs (line 10) shows headers to strip on cross-origin redirects. This is a critical security feature to prevent sending credentials to unintended domains during redirects." 220 - }, 221 - { 222 - "source_repo": "reqwest", 223 - "source_language": "Rust", 224 - "criticality": "medium", 225 - "change_type": "feature", 226 - "title": "Add DNS resolution customization", 227 - "description": "reqwest supports custom DNS resolvers (including hickory-dns for DoH/DoT), DNS overrides for testing, and system resolver configuration. The OCaml library should allow DNS resolver customization for testing and advanced networking scenarios.", 228 - "affected_files": [ 229 - "lib/requests.mli" 230 - ], 231 - "rationale": "reqwest's client.rs (lines 244, 263-264) shows DNS resolver and override configuration. This is valuable for testing (override specific hosts), performance (custom resolvers), and security (DNS-over-HTTPS)." 232 - }, 233 - { 234 - "source_repo": "reqwest", 235 - "source_language": "Rust", 236 - "criticality": "low", 237 - "change_type": "enhancement", 238 - "title": "Add nodelay TCP option control", 239 - "description": "reqwest provides a nodelay option (default: true) to control TCP_NODELAY (Nagle's algorithm). The OCaml library should expose this for latency-sensitive applications.", 240 - "affected_files": [ 241 - "lib/requests.mli" 242 - ], 243 - "rationale": "reqwest's client.rs (line 241) shows nodelay configuration. Disabling Nagle's algorithm reduces latency for small requests, which is important for RPC-style HTTP APIs." 244 - }, 245 - { 246 - "source_repo": "reqwest", 247 - "source_language": "Rust", 248 - "criticality": "medium", 249 - "change_type": "enhancement", 250 - "title": "Add connection_verbose debugging mode", 251 - "description": "reqwest provides connection_verbose option for detailed connection logging including TLS handshakes, protocol negotiation, and connection reuse. The OCaml library should add a similar verbose debugging mode.", 252 - "affected_files": [ 253 - "lib/requests.mli" 254 - ], 255 - "rationale": "reqwest's client.rs (line 296) shows connection_verbose flag. This is invaluable for debugging connection issues, TLS problems, and understanding connection pool behavior in production." 256 - } 257 - ] 258 - }
-179
third_party/rust/surf.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/rust/surf", 5 - "source_language": "Rust", 6 - "criticality": "medium", 7 - "change_type": "enhancement", 8 - "title": "Add middleware/plugin system for request/response interception", 9 - "description": "Surf implements a powerful middleware system that allows users to intercept and modify requests/responses through a composable chain. This enables cross-cutting concerns like custom logging, request modification, authentication injection, rate limiting, and caching to be implemented as reusable middleware components rather than being hardcoded into the client.", 10 - "affected_files": [ 11 - "lib/requests.mli", 12 - "lib/requests.ml", 13 - "lib/one.mli", 14 - "lib/one.ml" 15 - ], 16 - "rationale": "The OCaml library currently has built-in features like logging, retry, and authentication, but lacks an extensibility mechanism for users to add custom request/response processing logic. A middleware system would allow users to implement custom behaviors (e.g., request signing, custom metrics collection, response transformation, circuit breakers) without modifying the library code. This would make the library more flexible and composable. The middleware could be implemented as a list of functions of type `(Request.t -> (Request.t -> Response.t) -> Response.t)` that are composed together, similar to Surf's `Middleware` trait but using OCaml's functional programming patterns." 17 - }, 18 - { 19 - "source_repo": "third_party/rust/surf", 20 - "source_language": "Rust", 21 - "criticality": "low", 22 - "change_type": "enhancement", 23 - "title": "Add fluent RequestBuilder API for ergonomic request construction", 24 - "description": "Surf provides a RequestBuilder that allows chaining method calls to construct requests ergonomically (e.g., `surf::post(url).header(\"X-API-Key\", key).body_json(&data).await?`). This provides better developer experience compared to passing many optional parameters to request functions.", 25 - "affected_files": [ 26 - "lib/requests.mli", 27 - "lib/requests.ml", 28 - "lib/one.mli", 29 - "lib/one.ml" 30 - ], 31 - "rationale": "The OCaml library currently uses functions with many optional parameters (e.g., `?headers:Headers.t -> ?body:Body.t -> ?auth:Auth.t -> ?timeout:Timeout.t -> string -> Response.t`). While functional, this can become unwieldy with many options. A builder pattern using a mutable record or functional approach with chained functions would provide better ergonomics. This could be implemented as: `let req = Request.builder () |> with_url url |> with_header \"key\" \"value\" |> with_body body |> build` or using a mutable builder record. This is a low priority enhancement as the current API is functional, but would improve developer experience." 32 - }, 33 - { 34 - "source_repo": "third_party/rust/surf", 35 - "source_language": "Rust", 36 - "criticality": "low", 37 - "change_type": "enhancement", 38 - "title": "Add convenience methods for common response body operations", 39 - "description": "Surf's Client provides convenience methods like `recv_bytes()`, `recv_string()`, and `recv_json()` that combine sending a request and reading the response body in one call. This reduces boilerplate for common operations.", 40 - "affected_files": [ 41 - "lib/requests.mli", 42 - "lib/requests.ml" 43 - ], 44 - "rationale": "The OCaml library currently requires users to call `Response.body response |> Eio.Flow.read_all` or `Response.text response` to read response bodies. Adding convenience methods like `get_string`, `get_json`, `post_json` that combine the request and body reading would reduce boilerplate code. For example: `val get_text : t -> ?headers:Headers.t -> string -> string` that performs GET and returns the body as text. This is low priority since the current approach works fine, but it would improve ergonomics for simple use cases." 45 - }, 46 - { 47 - "source_repo": "third_party/rust/surf", 48 - "source_language": "Rust", 49 - "criticality": "medium", 50 - "change_type": "enhancement", 51 - "title": "Add configurable base URL support with relative URL resolution", 52 - "description": "Surf's Config allows setting a base URL, after which all requests can use relative paths that are automatically joined to the base URL. This is particularly useful for API clients where all endpoints share a common base (e.g., `https://api.example.com/v1/`).", 53 - "affected_files": [ 54 - "lib/requests.mli", 55 - "lib/requests.ml" 56 - ], 57 - "rationale": "The OCaml library currently requires full URLs for every request. Adding base URL support would allow users to configure a client with `base_url` and then make requests with relative paths like `get req \"users/123\"` instead of `get req \"https://api.example.com/v1/users/123\"`. This is already noted in Surf's implementation with the caveat that trailing slashes matter (per URL spec). The base URL could be stored in the `t` type and applied during request construction. Implementation should use `Uri.resolve` for proper URL joining semantics." 58 - }, 59 - { 60 - "source_repo": "third_party/rust/surf", 61 - "source_language": "Rust", 62 - "criticality": "low", 63 - "change_type": "enhancement", 64 - "title": "Support query parameter builder for URL construction", 65 - "description": "Surf's RequestBuilder has a `query()` method that accepts a serializable struct and automatically encodes it as query parameters. This provides type-safe query parameter construction and automatic URL encoding.", 66 - "affected_files": [ 67 - "lib/requests.mli", 68 - "lib/requests.ml" 69 - ], 70 - "rationale": "The OCaml library's `get` function accepts `?params:(string * string) list` which is functional but requires manual list construction. While this works, a dedicated query parameter builder could provide better ergonomics. However, since OCaml doesn't have Rust's Serialize trait, the current list-based approach is actually quite idiomatic for OCaml. This recommendation is low priority and mainly for consideration - the current approach may be the most OCaml-idiomatic solution already. Consider adding helper functions for common query operations like `Query.add`, `Query.merge`, etc. if user feedback indicates a need." 71 - }, 72 - { 73 - "source_repo": "third_party/rust/surf", 74 - "source_language": "Rust", 75 - "criticality": "low", 76 - "change_type": "enhancement", 77 - "title": "Add response extension storage for attaching custom metadata", 78 - "description": "Surf's Response type includes extension storage (via `ext<T>()` and `insert_ext<T>()`) that allows attaching typed custom data to responses. This enables middleware and users to attach metadata without modifying the response structure.", 79 - "affected_files": [ 80 - "lib/response.mli", 81 - "lib/response.ml" 82 - ], 83 - "rationale": "The OCaml library Response type is currently opaque and doesn't support attaching custom metadata. While this keeps the API simple, it limits extensibility. Adding an extension mechanism using a heterogeneous map (e.g., using a `Hashtbl` keyed by type IDs or a functional approach with GADTs) would allow middleware or application code to attach custom data like timing information, trace IDs, or caching metadata to responses without modifying the core Response type. This is low priority as it's mainly useful with a middleware system (recommendation #1)." 84 - }, 85 - { 86 - "source_repo": "third_party/rust/surf", 87 - "source_language": "Rust", 88 - "criticality": "medium", 89 - "change_type": "enhancement", 90 - "title": "Enhanced charset/encoding detection and decoding support", 91 - "description": "Surf implements sophisticated response body decoding with optional support for multiple character encodings beyond UTF-8 (via encoding_rs on native platforms, TextDecoder on WASM). It automatically detects charset from Content-Type headers and provides a DecodeError that includes the raw bytes for fallback parsing strategies.", 92 - "affected_files": [ 93 - "lib/response.mli", 94 - "lib/response.ml" 95 - ], 96 - "rationale": "The OCaml library currently assumes UTF-8 encoding for text responses. While UTF-8 is the dominant encoding for modern web APIs, some legacy systems or international content may use other encodings (ISO-8859-1, Windows-1252, various Asian encodings). Surf's approach of detecting charset from Content-Type headers and providing graceful fallback with access to raw bytes is a good pattern. Consider adding optional support for charset detection and decoding using OCaml libraries like `uucp` or `camomile`. The DecodeError pattern that returns raw bytes on failure is particularly valuable for allowing users to implement custom decoding strategies. Priority is medium as most modern APIs use UTF-8, but this prevents edge cases." 97 - }, 98 - { 99 - "source_repo": "third_party/rust/surf", 100 - "source_language": "Rust", 101 - "criticality": "high", 102 - "change_type": "enhancement", 103 - "title": "Implement proper POST body preservation during redirects", 104 - "description": "Surf's redirect middleware has special handling to avoid consuming request bodies during redirect following. It clones the request without the body first to check for redirects, only sending the full request with body when it reaches a non-redirect response. This prevents loss of request bodies during 307/308 redirects where the body should be preserved.", 105 - "affected_files": [ 106 - "lib/requests.ml", 107 - "lib/one.ml" 108 - ], 109 - "rationale": "The OCaml library implements redirect following but may not properly handle request bodies during redirects. RFC 9110 specifies that 307 (Temporary Redirect) and 308 (Permanent Redirect) MUST preserve the request method and body, while 301/302 may change POST to GET. The current implementation should be reviewed to ensure: (1) request bodies are preserved for 307/308 redirects, (2) the body stream can be replayed or is cloned before the initial request, (3) POST requests that redirect with 301/302 are handled according to spec (typically converted to GET). Surf's approach of making a lightweight HEAD-like request first to detect redirects is one solution, though it has the overhead of extra requests. Review the current redirect implementation in `requests.ml` to ensure compliance with RFC 9110 Section 15.4." 110 - }, 111 - { 112 - "source_repo": "third_party/rust/surf", 113 - "source_language": "Rust", 114 - "criticality": "low", 115 - "change_type": "feature", 116 - "title": "Add support for HTTP method constants and custom methods", 117 - "description": "Surf supports all standard HTTP methods (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE, CONNECT) plus custom methods via Method type. The client provides dedicated convenience methods for each standard method.", 118 - "affected_files": [ 119 - "lib/method.mli", 120 - "lib/method.ml", 121 - "lib/requests.mli" 122 - ], 123 - "rationale": "The OCaml library supports the most common HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) which covers 99% of use cases. However, it doesn't appear to support TRACE or CONNECT methods, or custom HTTP methods. While rarely used, TRACE can be useful for debugging and CONNECT is needed for HTTP tunneling. Custom methods are occasionally needed for proprietary APIs or experimental standards (e.g., WebDAV methods like PROPFIND, MKCOL). Consider adding: (1) `val trace` and `val connect` functions to the main API, (2) Support for custom method strings via a `Method.custom : string -> t` constructor. This is low priority as these methods are rarely needed in practice." 124 - }, 125 - { 126 - "source_repo": "third_party/rust/surf", 127 - "source_language": "Rust", 128 - "criticality": "medium", 129 - "change_type": "enhancement", 130 - "title": "Add client cloning with independent middleware stacks", 131 - "description": "Surf's Client implements Clone in a way that creates a new client with an independent middleware stack but shares the underlying HTTP client and configuration. This allows users to create client variants with different middleware without duplicating connection pools.", 132 - "affected_files": [ 133 - "lib/requests.mli", 134 - "lib/requests.ml" 135 - ], 136 - "rationale": "The OCaml library's `t` type is currently opaque and doesn't expose a cloning mechanism. While the library provides functions like `set_auth`, `set_timeout` that return modified sessions, these may not share connection pools efficiently. Adding an explicit `clone : t -> t` function that creates a new session with the same connection pools but allows independent configuration would be useful. This is particularly valuable if middleware support (recommendation #1) is added - users could clone a base client and add different middleware for different use cases while sharing the connection pool. Review the current implementation of `set_*` functions to ensure they share connection pools efficiently." 137 - }, 138 - { 139 - "source_repo": "third_party/rust/surf", 140 - "source_language": "Rust", 141 - "criticality": "low", 142 - "change_type": "enhancement", 143 - "title": "Add version negotiation and HTTP/2 support consideration", 144 - "description": "Surf explicitly exposes HTTP version information (HTTP/1.0, HTTP/1.1, HTTP/2) through its Response.version() method, though the underlying implementation depends on the backend client (h1-client, hyper-client, curl-client).", 145 - "affected_files": [ 146 - "lib/response.mli", 147 - "lib/response.ml", 148 - "lib/http_client.ml" 149 - ], 150 - "rationale": "The OCaml library currently implements HTTP/1.1 protocol handling. While HTTP/1.1 is widely supported, HTTP/2 offers significant performance benefits (multiplexing, header compression, server push). Consider: (1) Adding `val version : t -> string option` to Response to expose the HTTP version used, (2) Planning for future HTTP/2 support, possibly through h2-eio or similar libraries, (3) Documenting the current HTTP version support clearly. This is low priority as HTTP/1.1 is still dominant and the library's current implementation is solid, but HTTP/2 support would be valuable for performance-sensitive applications. The eio ecosystem may already have HTTP/2 libraries that could be integrated." 151 - }, 152 - { 153 - "source_repo": "third_party/rust/surf", 154 - "source_language": "Rust", 155 - "criticality": "low", 156 - "change_type": "enhancement", 157 - "title": "Implement response body mutable operations (swap_body, take_body)", 158 - "description": "Surf's Response provides `take_body()` which returns the body and replaces it with an empty body, and `swap_body()` for exchanging bodies. These are useful in middleware for reading/modifying response bodies without consuming the response itself.", 159 - "affected_files": [ 160 - "lib/response.mli", 161 - "lib/response.ml" 162 - ], 163 - "rationale": "The OCaml library's Response type provides access to the body stream via `body : t -> Flow.source_ty Resource.t`, but doesn't provide mutating operations. While OCaml encourages immutability, there are legitimate use cases in middleware or response processing where you want to: (1) Read the body for inspection (e.g., logging) then replace it with a new stream, (2) Transform the body content (e.g., decryption, decompression) while keeping the same Response structure. Adding `val take_body : t -> Flow.source_ty Resource.t` and `val set_body : t -> Flow.source_ty Resource.t -> unit` would enable these patterns. However, this is low priority and may not align well with OCaml's immutability philosophy. If middleware is added (recommendation #1), reconsider this." 164 - }, 165 - { 166 - "source_repo": "third_party/rust/surf", 167 - "source_language": "Rust", 168 - "criticality": "low", 169 - "change_type": "enhancement", 170 - "title": "Add default client instance for zero-configuration usage", 171 - "description": "Surf provides a global default client (via lazy static) that is used by the one-shot request functions (surf::get, surf::post, etc.). This allows simple usage without explicitly creating a client, while still supporting custom clients for advanced use cases.", 172 - "affected_files": [ 173 - "lib/requests.mli", 174 - "lib/requests.ml" 175 - ], 176 - "rationale": "The OCaml library already has a `simple_get`, `simple_post` pattern that provides one-shot requests, which is similar to Surf's approach. However, these are currently wrappers around the One module. Consider whether having a global/default client instance would be beneficial for the OCaml library. Given Eio's structured concurrency model with explicit environment passing, a global client may not be idiomatic. The current design with explicit `simple_*` functions that take the environment is actually more aligned with Eio's philosophy. This recommendation is very low priority and may not be appropriate for the OCaml/Eio context - the current design is likely better." 177 - } 178 - ] 179 - }
-276
third_party/swift/alamofire.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/swift/alamofire", 5 - "source_language": "Swift", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add Request Compression Support for Outbound Bodies", 9 - "description": "Alamofire provides a DeflateRequestCompressor that compresses outbound request bodies using deflate/gzip encoding. This can significantly reduce bandwidth for large POST/PUT requests. The OCaml library currently supports automatic decompression of responses but lacks request body compression. Implement a similar feature that allows users to optionally compress request bodies before transmission, particularly useful for large JSON payloads or form data.", 10 - "affected_files": [ 11 - "lib/body.ml", 12 - "lib/body.mli", 13 - "lib/http_write.ml", 14 - "lib/requests.ml" 15 - ], 16 - "rationale": "Large request bodies (e.g., bulk API operations, analytics data) can benefit from compression. Alamofire's implementation shows this is valuable enough to warrant a dedicated adapter. The OCaml library already has decompress dependencies, so implementing compression would reuse existing infrastructure. Add an optional ~compress parameter to request functions and Body constructors." 17 - }, 18 - { 19 - "source_repo": "third_party/swift/alamofire", 20 - "source_language": "Swift", 21 - "criticality": "low", 22 - "change_type": "feature", 23 - "title": "Implement Request/Response Event Monitoring Hooks", 24 - "description": "Alamofire's EventMonitor protocol provides extensive lifecycle hooks for monitoring URLSession events, request creation, task lifecycle, metrics collection, retries, and completion. This enables debugging, logging, analytics, and custom instrumentation. The OCaml library uses structured logging but lacks user-extensible event hooks. Implement a similar callback system that allows users to register custom event monitors for observability.", 25 - "affected_files": [ 26 - "lib/requests.ml", 27 - "lib/requests.mli", 28 - "lib/http_client.ml" 29 - ], 30 - "rationale": "Event monitoring is crucial for production debugging and observability. Alamofire provides 30+ lifecycle hooks covering request creation, adaptation, task events, metrics, retries, and completion. While the OCaml library has good internal logging, users cannot intercept these events for custom metrics, distributed tracing, or debugging. A protocol-based monitor system would enable APM integration, custom logging, and testing utilities without modifying core library code." 31 - }, 32 - { 33 - "source_repo": "third_party/swift/alamofire", 34 - "source_language": "Swift", 35 - "criticality": "medium", 36 - "change_type": "feature", 37 - "title": "Add RequestInterceptor Protocol for Adaptation and Retry Logic", 38 - "description": "Alamofire's RequestInterceptor protocol separates concerns into RequestAdapter (modify requests before sending) and RequestRetrier (determine retry behavior after failures). This enables OAuth token refresh, API key injection, custom retry logic, and request signing without modifying the core client. The OCaml library has built-in retry logic but no pre-request modification hooks or custom retry handlers. Implement a similar two-phase interceptor system.", 39 - "affected_files": [ 40 - "lib/requests.ml", 41 - "lib/requests.mli", 42 - "lib/retry.ml", 43 - "lib/retry.mli" 44 - ], 45 - "rationale": "RequestInterceptor enables crucial patterns: (1) RequestAdapter for adding auth headers, signing requests, injecting timestamps, or modifying URLs before execution; (2) RequestRetrier for custom retry logic like OAuth token refresh on 401, rate limit handling, or circuit breaker patterns. The OCaml library's retry logic is hardcoded and cannot be customized per-request. Adding interceptors would enable middleware-style extensibility for authentication, instrumentation, and error handling." 46 - }, 47 - { 48 - "source_repo": "third_party/swift/alamofire", 49 - "source_language": "Swift", 50 - "criticality": "high", 51 - "change_type": "feature", 52 - "title": "Implement Automatic OAuth2 Token Refresh with AuthenticationInterceptor", 53 - "description": "Alamofire provides AuthenticationInterceptor that automatically refreshes OAuth2 tokens when they expire. It detects 401 errors, refreshes the token using a user-provided closure, and retries the original request with the new token. This prevents request failures and handles token expiration transparently. The OCaml library supports Bearer tokens but requires manual token management. Implement similar automatic refresh logic.", 54 - "affected_files": [ 55 - "lib/auth.ml", 56 - "lib/auth.mli", 57 - "lib/requests.ml" 58 - ], 59 - "rationale": "OAuth2 token expiration is common in production APIs. Alamofire's AuthenticationInterceptor handles: (1) Detecting authentication failures via custom predicates, (2) Refreshing credentials with user-provided async refresh function, (3) Preventing duplicate refresh requests during concurrent calls, (4) Retrying failed requests with new tokens. Manual token management is error-prone and leads to failed requests. This feature would significantly improve UX for OAuth2-protected APIs." 60 - }, 61 - { 62 - "source_repo": "third_party/swift/alamofire", 63 - "source_language": "Swift", 64 - "criticality": "medium", 65 - "change_type": "enhancement", 66 - "title": "Add Response Metrics Collection (URLSessionTaskMetrics)", 67 - "description": "Alamofire exposes URLSessionTaskMetrics which provides detailed timing information: DNS lookup duration, TCP connection time, TLS handshake time, request/response times, redirect count, and protocol used. This is invaluable for performance monitoring and debugging. The OCaml library only tracks total elapsed time. Implement detailed metrics collection including connection timing, DNS resolution, TLS handshake, and transfer times.", 68 - "affected_files": [ 69 - "lib/response.ml", 70 - "lib/response.mli", 71 - "lib/http_client.ml" 72 - ], 73 - "rationale": "Detailed performance metrics are essential for production debugging. Alamofire provides: taskInterval (total time), redirectCount, domainLookup times, connect times, secureConnection times, request/response times, and protocol information. The OCaml library only exposes total elapsed time in Response.elapsed. Adding granular metrics would help identify bottlenecks (slow DNS, TLS handshake issues, network latency) and enable better performance monitoring." 74 - }, 75 - { 76 - "source_repo": "third_party/swift/alamofire", 77 - "source_language": "Swift", 78 - "criticality": "low", 79 - "change_type": "enhancement", 80 - "title": "Add Progress Tracking for Uploads and Downloads", 81 - "description": "Alamofire provides Progress objects for upload and download operations with fractionCompleted, totalUnitCount, and completedUnitCount. Users can attach ProgressHandler closures for real-time progress updates. The OCaml library uses streaming but lacks built-in progress tracking. Implement progress callbacks for upload/download operations.", 82 - "affected_files": [ 83 - "lib/body.ml", 84 - "lib/response.ml", 85 - "lib/http_client.ml" 86 - ], 87 - "rationale": "Progress tracking is crucial for user-facing applications, especially for large file uploads/downloads. Alamofire provides Foundation's Progress API with handlers called on specific queues. While the OCaml library supports streaming, users must manually implement progress tracking by monitoring bytes read/written. Built-in progress callbacks with total/completed byte counts would improve UX for file transfer operations." 88 - }, 89 - { 90 - "source_repo": "third_party/swift/alamofire", 91 - "source_language": "Swift", 92 - "criticality": "medium", 93 - "change_type": "enhancement", 94 - "title": "Add Request/Response Validation Extensibility", 95 - "description": "Alamofire provides a validate() method with multiple validation modes: status code ranges, content type matching, custom validators via closures. Validation failures produce detailed ResponseValidationFailureReason errors. The OCaml library has Response.raise_for_status but no customizable validation. Implement extensible validation with custom validators and detailed failure reasons.", 96 - "affected_files": [ 97 - "lib/response.ml", 98 - "lib/response.mli", 99 - "lib/error.ml" 100 - ], 101 - "rationale": "Response validation is more nuanced than simple status code checks. Alamofire supports: (1) Validating acceptable status code ranges, (2) Content-Type validation against acceptable types, (3) Custom validation closures with access to request, response, and data. The OCaml library only has raise_for_status which checks status >= 400. Adding customizable validation would enable domain-specific checks (e.g., verifying JSON structure, checking response signatures, validating content length)." 102 - }, 103 - { 104 - "source_repo": "third_party/swift/alamofire", 105 - "source_language": "Swift", 106 - "criticality": "high", 107 - "change_type": "security", 108 - "title": "Enhance Server Trust Evaluation with Certificate/Public Key Pinning", 109 - "description": "Alamofire provides comprehensive server trust evaluation with multiple evaluators: PinnedCertificatesTrustEvaluator for certificate pinning, PublicKeysTrustEvaluator for public key pinning, RevocationTrustEvaluator for OCSP/CRL checks, and ComposedTrustEvaluator for combining multiple policies. The OCaml library only supports basic TLS verification and disable/enable. Implement certificate pinning and enhanced trust evaluation.", 110 - "affected_files": [ 111 - "lib/requests.ml", 112 - "lib/requests.mli" 113 - ], 114 - "rationale": "Certificate pinning prevents man-in-the-middle attacks by validating against known good certificates/keys. Alamofire's ServerTrustManager provides: (1) Certificate pinning against bundled certificates, (2) Public key pinning (survives certificate rotation), (3) Revocation checking with configurable policy, (4) Per-host trust policies, (5) Self-signed certificate support. The OCaml library only has verify_tls boolean flag. Adding pinning would significantly improve security for high-value APIs and prevent certificate-based attacks." 115 - }, 116 - { 117 - "source_repo": "third_party/swift/alamofire", 118 - "source_language": "Swift", 119 - "criticality": "low", 120 - "change_type": "enhancement", 121 - "title": "Add Request State Machine with Lifecycle Management", 122 - "description": "Alamofire implements a formal request state machine (initialized → resumed → suspended ↔ cancelled/finished) with transition validation. This prevents invalid operations like resuming a cancelled request or suspending a finished request. The OCaml library uses Eio switches for lifecycle but lacks explicit state tracking. Implement request state management with validated transitions.", 123 - "affected_files": [ 124 - "lib/requests.ml", 125 - "lib/http_client.ml" 126 - ], 127 - "rationale": "Explicit state machines prevent bugs from invalid state transitions. Alamofire validates transitions (e.g., cannot transition from cancelled to resumed) and exposes state queries (isInitialized, isResumed, isCancelled, isFinished). While Eio handles resource cleanup automatically, request state visibility helps with debugging, testing, and understanding request lifecycle. State tracking would also enable better error messages when operations fail due to incorrect state." 128 - }, 129 - { 130 - "source_repo": "third_party/swift/alamofire", 131 - "source_language": "Swift", 132 - "criticality": "medium", 133 - "change_type": "enhancement", 134 - "title": "Implement Cached Response Handling with Custom Cache Policies", 135 - "description": "Alamofire's CachedResponseHandler protocol allows customizing cache behavior per-request with ResponseCacher providing behaviors: cache, doNotCache, modify. This enables selective caching, cache key customization, and cache entry modification. The OCaml library has caching helpers (ETag, Last-Modified, Cache-Control parsing) but no actual HTTP cache implementation. Implement HTTP caching with RFC 9111 compliance.", 136 - "affected_files": [ 137 - "lib/response.ml", 138 - "lib/cache_control.ml", 139 - "lib/requests.ml" 140 - ], 141 - "rationale": "HTTP caching reduces latency and bandwidth. While CACHEIO.md indicates caching was intentionally deferred, the library already parses Cache-Control, ETag, and Last-Modified headers. Alamofire delegates caching to URLCache but allows per-request customization. Implementing even basic in-memory caching with RFC 9111 semantics would improve performance for frequently accessed resources. The existing cache_control module provides parsing infrastructure." 142 - }, 143 - { 144 - "source_repo": "third_party/swift/alamofire", 145 - "source_language": "Swift", 146 - "criticality": "low", 147 - "change_type": "enhancement", 148 - "title": "Add Redirect Customization with RedirectHandler Protocol", 149 - "description": "Alamofire's RedirectHandler protocol allows custom redirect logic beyond simple follow/don't-follow. Users can modify redirect requests, implement custom redirect policies, or block redirects to specific hosts. The OCaml library has follow_redirects boolean and max_redirects but no redirect customization. Implement redirect handler callbacks.", 150 - "affected_files": [ 151 - "lib/requests.ml", 152 - "lib/requests.mli" 153 - ], 154 - "rationale": "Redirect handling requires customization for security and functionality. Alamofire's RedirectHandler enables: (1) Blocking redirects to untrusted domains, (2) Modifying redirect requests (e.g., removing auth headers), (3) Logging redirect chains, (4) Implementing custom redirect policies. The OCaml library only supports boolean follow_redirects. Adding handler callbacks would enable security policies (e.g., no HTTP→HTTPS downgrade, no redirects to different domains) and custom redirect logic." 155 - }, 156 - { 157 - "source_repo": "third_party/swift/alamofire", 158 - "source_language": "Swift", 159 - "criticality": "low", 160 - "change_type": "feature", 161 - "title": "Add Multipart Streaming with Disk-Based Encoding for Large Files", 162 - "description": "Alamofire's multipart form data implementation supports both in-memory and disk-based encoding with configurable memory thresholds (default 10MB). Large multipart bodies are written to disk to avoid memory pressure. The OCaml library supports multipart uploads but appears to encode entirely in memory. Implement disk-based multipart encoding for large uploads.", 163 - "affected_files": [ 164 - "lib/body.ml", 165 - "lib/body.mli" 166 - ], 167 - "rationale": "Large multipart uploads (e.g., video files, large archives) can exhaust memory. Alamofire's MultipartFormData uses a memory threshold - bodies under 10MB stay in memory, larger ones stream from disk. This prevents OOM errors during large file uploads. The OCaml library's Body.multipart should implement similar streaming from disk for large payloads. The library already supports file-based bodies via of_file, so extending this to multipart would be consistent." 168 - }, 169 - { 170 - "source_repo": "third_party/swift/alamofire", 171 - "source_language": "Swift", 172 - "criticality": "low", 173 - "change_type": "enhancement", 174 - "title": "Add DataResponse/DownloadResponse Value Types with Metrics", 175 - "description": "Alamofire wraps responses in DataResponse/DownloadResponse types that bundle request, response, data/fileURL, metrics, serialization duration, and Result. This provides comprehensive context in one place. The OCaml library's Response.t is opaque and metrics are limited. Enhance response type to expose more metadata including the original request, metrics, and timing information.", 176 - "affected_files": [ 177 - "lib/response.ml", 178 - "lib/response.mli" 179 - ], 180 - "rationale": "Alamofire's DataResponse provides complete request/response context: original URLRequest, HTTPURLResponse, response data, URLSessionTaskMetrics, serialization duration, and result. This is invaluable for debugging - seeing the full request/response pair. The OCaml library exposes status, headers, body, url, and elapsed time but not the original request details. Adding request context and detailed metrics to responses would improve debuggability and testing." 181 - }, 182 - { 183 - "source_repo": "third_party/swift/alamofire", 184 - "source_language": "Swift", 185 - "criticality": "low", 186 - "change_type": "enhancement", 187 - "title": "Implement Advanced Debug Descriptions with Request/Response Pretty Printing", 188 - "description": "Alamofire provides detailed debug descriptions showing full request (method, URL, headers, body preview), response (status, headers, body preview), network duration, and serialization time. The OCaml library has pp and pp_detailed but limited request visibility. Implement comprehensive debug formatting showing complete request/response pairs.", 189 - "affected_files": [ 190 - "lib/response.ml", 191 - "lib/response.mli" 192 - ], 193 - "rationale": "Alamofire's debug descriptions include full context: request method/URL/headers/body (if decodable as string and under 100KB), response status/headers/body, network duration, serialization duration, and result. This single string contains everything needed for debugging. The OCaml library's pp_detailed shows response headers but not request details. Enhanced debug output would improve development experience and production debugging." 194 - }, 195 - { 196 - "source_repo": "third_party/swift/alamofire", 197 - "source_language": "Swift", 198 - "criticality": "medium", 199 - "change_type": "enhancement", 200 - "title": "Add Separate Queues for Request Creation and Response Serialization", 201 - "description": "Alamofire uses separate dispatch queues for request creation (requestQueue) and response serialization (serializationQueue), both targeting the root queue by default. This allows profiling bottlenecks and optimizing specific stages. The OCaml library uses Eio fibers but lacks similar separation. Implement configurable concurrency domains for different request lifecycle stages.", 202 - "affected_files": [ 203 - "lib/requests.ml", 204 - "lib/requests.mli", 205 - "lib/http_client.ml" 206 - ], 207 - "rationale": "Separating request creation and serialization allows optimizing bottlenecks. Alamofire notes 'Always profile and test before introducing an additional queue' but provides the infrastructure. If request encoding or response serialization becomes a bottleneck (e.g., large JSON encoding, complex multipart), they can be parallelized. The OCaml library could leverage Eio's domain pooling for compute-heavy operations like JSON parsing or compression." 208 - }, 209 - { 210 - "source_repo": "third_party/swift/alamofire", 211 - "source_language": "Swift", 212 - "criticality": "high", 213 - "change_type": "enhancement", 214 - "title": "Add Automatic Request Retry on Network State Changes", 215 - "description": "Alamofire provides OfflineRetrier that queues requests when network is unavailable and automatically retries when connectivity is restored. It integrates with NetworkReachabilityManager to monitor network status. The OCaml library has sophisticated retry logic but doesn't integrate network state monitoring. Implement automatic retry on network restoration.", 216 - "affected_files": [ 217 - "lib/retry.ml", 218 - "lib/retry.mli", 219 - "lib/requests.ml" 220 - ], 221 - "rationale": "Network connectivity issues are transient and automatic retry on restoration improves UX. Alamofire's OfflineRetrier detects network unavailability, holds failed requests, monitors reachability, and retries when network returns. This is particularly valuable for mobile/edge environments. While the OCaml library has excellent retry logic with backoff/jitter, it doesn't detect network state. Integrating with Linux network state monitoring (netlink) would enable similar functionality." 222 - }, 223 - { 224 - "source_repo": "third_party/swift/alamofire", 225 - "source_language": "Swift", 226 - "criticality": "medium", 227 - "change_type": "enhancement", 228 - "title": "Enhance Error Types with Detailed Failure Reasons and Context", 229 - "description": "Alamofire's AFError has granular associated types with detailed failure reasons: MultipartEncodingFailureReason (12 variants), ParameterEncodingFailureReason, ResponseValidationFailureReason, ResponseSerializationFailureReason, ServerTrustFailureReason, etc. Each includes rich context. The OCaml library has 18 error variants but could add more detailed sub-reasons. Enhance error types with detailed failure context.", 230 - "affected_files": [ 231 - "lib/error.ml", 232 - "lib/error.mli" 233 - ], 234 - "rationale": "Detailed error context enables better error handling and debugging. Alamofire's error types include specific failure reasons - e.g., MultipartEncodingFailureReason distinguishes bodyPartFileNotReachable from bodyPartFileIsDirectory from inputStreamReadFailed. The OCaml library has good top-level errors (Timeout, Http_error, Tls_handshake_failed) but could add nested reason types. For example, Tls_handshake_failed could include certificate validation failure reasons, protocol mismatch, or cipher suite negotiation failures." 235 - }, 236 - { 237 - "source_repo": "third_party/swift/alamofire", 238 - "source_language": "Swift", 239 - "criticality": "low", 240 - "change_type": "enhancement", 241 - "title": "Add Request/Task Suspension and Resumption Support", 242 - "description": "Alamofire supports suspending and resuming requests via suspend()/resume() methods backed by URLSessionTask suspension. This is useful for network-aware applications that pause transfers on cellular and resume on WiFi. The OCaml library uses Eio fibers which can be cancelled but not suspended. Explore implementing request pause/resume functionality.", 243 - "affected_files": [ 244 - "lib/requests.ml", 245 - "lib/http_client.ml" 246 - ], 247 - "rationale": "Request suspension enables network-aware applications and user-controlled transfers. Alamofire's state machine includes suspended state with validated transitions. Users can pause large downloads on cellular, resume on WiFi, or implement priority-based transfer scheduling. While Eio's structured concurrency doesn't directly support fiber suspension, similar functionality could be achieved with cancellable contexts and retry mechanisms. Consider whether this is valuable for OCaml use cases." 248 - }, 249 - { 250 - "source_repo": "third_party/swift/alamofire", 251 - "source_language": "Swift", 252 - "criticality": "low", 253 - "change_type": "enhancement", 254 - "title": "Implement Response Serializer Protocol for Custom Response Types", 255 - "description": "Alamofire's ResponseSerializer protocol enables custom deserialization with error handling and type safety. Users can implement serializers for custom formats (Protocol Buffers, MessagePack, XML). The OCaml library has json and text helpers but no extensible serialization framework. Implement response serializer abstraction.", 256 - "affected_files": [ 257 - "lib/response.ml", 258 - "lib/response.mli" 259 - ], 260 - "rationale": "Custom response formats require type-safe deserialization. Alamofire's ResponseSerializer protocol defines serialize(request:response:data:error:) with Result return type. Built-in serializers handle JSON, String, Data, and Decodable types. Custom serializers enable Protocol Buffers, MessagePack, XML, or domain-specific formats. The OCaml library hardcodes json and text. A serializer abstraction (similar to Jsont's codec pattern) would enable extensibility without core library changes." 261 - }, 262 - { 263 - "source_repo": "third_party/swift/alamofire", 264 - "source_language": "Swift", 265 - "criticality": "low", 266 - "change_type": "enhancement", 267 - "title": "Add Combine Publishers and Async/Await Support for Modern Swift Concurrency", 268 - "description": "Alamofire provides first-class support for Combine (reactive programming) and Swift async/await with DataResponsePublisher, AsyncSequence for streaming, and async serialization methods. While this is Swift-specific, the OCaml library could explore similar patterns with lwt/async compatibility or async iterators for streaming responses.", 269 - "affected_files": [ 270 - "lib/response.ml", 271 - "lib/one.ml" 272 - ], 273 - "rationale": "This is a Swift-specific feature showcasing modern concurrency integration. While the OCaml library is built on Eio, many OCaml projects still use Lwt or Async. Consider whether compatibility layers or conversion utilities would be valuable. The streaming response support via Eio.Flow is already good, but async iterator patterns for incremental parsing (e.g., streaming JSON arrays) could be explored." 274 - } 275 - ] 276 - }
-152
third_party/swift/just.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/swift/just", 5 - "source_language": "Swift", 6 - "criticality": "low", 7 - "change_type": "enhancement", 8 - "title": "Add RFC 5988 Link Header Parsing Support", 9 - "description": "Just provides automatic parsing of Link headers (RFC 5988) into a structured dictionary format, making pagination and HATEOAS navigation easier. The library parses Link headers like '<https://api.github.com/user/repos?page=2>; rel=\"next\"' into a dictionary accessible by relationship type (e.g., links['next']['url']). This is particularly useful for paginated API responses.", 10 - "affected_files": [ 11 - "lib/response.ml", 12 - "lib/response.mli" 13 - ], 14 - "rationale": "Many modern REST APIs use Link headers for pagination (GitHub, GitLab, etc.). Currently, the OCaml library requires manual parsing of the Link header. Adding automatic parsing would improve ergonomics for common API interaction patterns. Implementation could use a lazy property similar to cache_control parsing, returning a (string * (string * string) list) list where the outer list contains relationships, and the inner association list contains link attributes." 15 - }, 16 - { 17 - "source_repo": "third_party/swift/just", 18 - "source_language": "Swift", 19 - "criticality": "low", 20 - "change_type": "enhancement", 21 - "title": "Add Response.is_redirect and Response.is_permanent_redirect Helpers", 22 - "description": "Just provides convenient boolean helpers on the response object: is_redirect (3xx range) and is_permanent_redirect (301 specifically). While the OCaml library has Status.is_redirection, adding Response-level helpers improves discoverability and ergonomics.", 23 - "affected_files": [ 24 - "lib/response.ml", 25 - "lib/response.mli" 26 - ], 27 - "rationale": "These helpers reduce boilerplate when checking redirect status. The OCaml library already has Status.is_redirection, but adding Response.is_redirect and Response.is_permanent_redirect would match the pattern of Response.ok and make the API more discoverable. Implementation is straightforward: let is_redirect t = Status.is_redirection (status t) and let is_permanent_redirect t = t.status = 301." 28 - }, 29 - { 30 - "source_repo": "third_party/swift/just", 31 - "source_language": "Swift", 32 - "criticality": "low", 33 - "change_type": "enhancement", 34 - "title": "Add Response.reason Convenience Property", 35 - "description": "Just provides a 'reason' property on responses that returns either the standard HTTP status reason phrase or error description. This provides a single, user-friendly string for logging and error messages without needing to pattern match or look up status codes.", 36 - "affected_files": [ 37 - "lib/response.ml", 38 - "lib/response.mli" 39 - ], 40 - "rationale": "The OCaml library has Status.reason_phrase but requires users to call it explicitly on the status. Adding Response.reason as a convenience would improve ergonomics for common logging patterns like Printf.printf 'Error: %s' (Response.reason resp). Implementation: let reason t = Status.reason_phrase (Status.of_int t.status)." 41 - }, 42 - { 43 - "source_repo": "third_party/swift/just", 44 - "source_language": "Swift", 45 - "criticality": "medium", 46 - "change_type": "enhancement", 47 - "title": "Add Request Cancellation Support via Fiber.cancel", 48 - "description": "Just provides a cancel() method on HTTPResult that allows in-flight requests to be cancelled. While Eio supports fiber cancellation, the library doesn't expose a convenient way to cancel individual requests. Consider exposing a cancellation mechanism that leverages Eio.Fiber.cancel or providing guidance on how to cancel requests using Eio primitives.", 49 - "affected_files": [ 50 - "lib/requests.ml", 51 - "lib/requests.mli", 52 - "lib/one.ml", 53 - "lib/one.mli" 54 - ], 55 - "rationale": "Request cancellation is important for responsive UIs and resource management (e.g., cancelling stale requests when user navigates away). The OCaml library uses Eio's structured concurrency, so cancellation would naturally work via Eio.Cancel.sub or switch cancellation. However, users may not realize this pattern. Adding documentation or a thin wrapper that demonstrates the pattern (e.g., using Eio.Time.with_timeout or Eio.Cancel.sub) would improve usability. This could be as simple as adding examples to documentation rather than new code." 56 - }, 57 - { 58 - "source_repo": "third_party/swift/just", 59 - "source_language": "Swift", 60 - "criticality": "low", 61 - "change_type": "enhancement", 62 - "title": "Expand Status Code Coverage to Include Non-Standard Codes", 63 - "description": "Just includes some non-standard but commonly encountered HTTP status codes in its reason phrase dictionary: 122 (URI too long - WebDAV), 418 (I'm a teapot), 444 (No response - nginx), 449 (Retry with - Microsoft), 450 (Blocked by parental controls), 499 (Client closed request - nginx), 509 (Bandwidth limit exceeded). The OCaml library includes 418 but is missing others.", 64 - "affected_files": [ 65 - "lib/status.ml", 66 - "lib/status.mli" 67 - ], 68 - "rationale": "While non-standard, these codes are encountered in practice (especially nginx codes like 444 and 499). Adding them to the reason_phrase function's catch-all case or as explicit `Code variants would improve debugging when interacting with servers that use these codes. Low priority since the OCaml library already handles unknown codes gracefully via the `Code(int) variant, but adding reason phrases would improve developer experience." 69 - }, 70 - { 71 - "source_repo": "third_party/swift/just", 72 - "source_language": "Swift", 73 - "criticality": "low", 74 - "change_type": "enhancement", 75 - "title": "Add Configurable Multipart Boundary String", 76 - "description": "Just allows customization of the multipart form boundary string via JustSessionDefaults.multipartBoundary. This is useful for testing and debugging multipart uploads, as a predictable boundary makes it easier to verify request formatting.", 77 - "affected_files": [ 78 - "lib/body.ml", 79 - "lib/body.mli", 80 - "lib/requests.ml" 81 - ], 82 - "rationale": "Currently, the OCaml library likely generates random multipart boundaries (standard practice). While not critical, allowing an optional custom boundary parameter would aid in testing and debugging. This is particularly useful for unit tests that need to verify exact multipart request formatting. Implementation would add an optional boundary parameter to Body.multipart_form_data, defaulting to a randomly generated value in production." 83 - }, 84 - { 85 - "source_repo": "third_party/swift/just", 86 - "source_language": "Swift", 87 - "criticality": "low", 88 - "change_type": "enhancement", 89 - "title": "Add Response.description for Quick Debugging", 90 - "description": "Just provides a succinct description property that returns a string like 'GET https://api.example.com/users 200' combining method, URL, and status code. This is extremely useful for logging and debugging, providing context at a glance.", 91 - "affected_files": [ 92 - "lib/response.ml", 93 - "lib/response.mli" 94 - ], 95 - "rationale": "The OCaml library has Response.pp for pretty printing, but adding a simple string-returning description function would improve ergonomics for quick debugging and logging. Implementation could be straightforward: let description t = Printf.sprintf '%s %d' t.url t.status. This would complement the existing pp functions and provide a lightweight alternative when you don't need full formatting." 96 - }, 97 - { 98 - "source_repo": "third_party/swift/just", 99 - "source_language": "Swift", 100 - "criticality": "low", 101 - "change_type": "enhancement", 102 - "title": "Add Response.json with Configurable JSON Options", 103 - "description": "Just exposes JSONReadingOptions on both the response and session defaults level, allowing users to configure JSON parsing behavior (e.g., allowing fragments, mutable containers). The response object also allows per-response configuration via a mutable property.", 104 - "affected_files": [ 105 - "lib/response.ml", 106 - "lib/response.mli" 107 - ], 108 - "rationale": "The OCaml library already has Response.json using Jsont. Consider whether exposing Jsont.json_decoder configuration options would be valuable for edge cases. Most users won't need this, but it could help with non-standard JSON responses. This is the lowest priority recommendation as the current implementation likely covers 99% of use cases, but documenting how to customize JSON parsing (if Jsont supports it) could help advanced users." 109 - }, 110 - { 111 - "source_repo": "third_party/swift/just", 112 - "source_language": "Swift", 113 - "criticality": "low", 114 - "change_type": "enhancement", 115 - "title": "Document Progress Handler Chunk Access Pattern", 116 - "description": "Just's HTTPProgress struct includes an optional 'chunk' field for download progress handlers, providing access to the actual data chunk being processed. This enables streaming processing during download without waiting for completion.", 117 - "affected_files": [ 118 - "lib/requests.ml", 119 - "lib/requests.mli", 120 - "lib/one.ml", 121 - "lib/one.mli" 122 - ], 123 - "rationale": "The OCaml library already supports streaming via Response.body and Eio.Flow, which is actually more powerful than Just's approach. However, documenting a pattern for 'progress with chunk processing' in examples would help users understand how to combine progress tracking with streaming. This is purely a documentation enhancement - the capability already exists through Eio.Flow combinators." 124 - }, 125 - { 126 - "source_repo": "third_party/swift/just", 127 - "source_language": "Swift", 128 - "criticality": "low", 129 - "change_type": "enhancement", 130 - "title": "Add Lowercase Reason Phrases as Alternative", 131 - "description": "Just uses lowercase reason phrases (e.g., 'not found' instead of 'Not Found'), which some developers prefer for logging as it's less shouty and integrates better into sentence-style log messages. Consider providing both Status.reason_phrase (title case) and Status.reason_phrase_lower (lowercase).", 132 - "affected_files": [ 133 - "lib/status.ml", 134 - "lib/status.mli" 135 - ], 136 - "rationale": "This is purely aesthetic but can improve log readability. Messages like 'Request failed: not found' read more naturally than 'Request failed: Not Found'. The OCaml library currently provides title-case phrases matching HTTP RFCs. Adding a lowercase variant (or a ~lowercase:bool parameter) would be trivial and could improve ergonomics for logging-heavy applications. Lowest priority as it's purely cosmetic." 137 - }, 138 - { 139 - "source_repo": "third_party/swift/just", 140 - "source_language": "Swift", 141 - "criticality": "medium", 142 - "change_type": "feature", 143 - "title": "Add Explicit Cache Policy Configuration", 144 - "description": "Just exposes explicit cache policy configuration via JustSessionDefaults.cachePolicy (with default .reloadIgnoringLocalCacheData for security). While the OCaml library has comprehensive cache control parsing, it doesn't expose a simple cache policy enum for basic use cases.", 145 - "affected_files": [ 146 - "lib/requests.ml", 147 - "lib/requests.mli" 148 - ], 149 - "rationale": "The OCaml library has excellent RFC 9111 compliant cache control parsing but appears to have disabled actual HTTP caching (based on CACHEIO.md notes found during exploration). If/when caching is re-enabled, providing a simple cache policy configuration (e.g., type cache_policy = No_cache | Use_cache | Force_cache) would improve usability for common cases, while the existing Cache_control module handles advanced scenarios. This is only relevant if HTTP caching is implemented in the future." 150 - } 151 - ] 152 - }
-200
third_party/swift/kingfisher.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/swift/kingfisher", 5 - "source_language": "Swift", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add Progress Tracking for Downloads and Uploads", 9 - "description": "Kingfisher provides progress callbacks that report received/total bytes during downloads, enabling users to display progress indicators. The OCaml library should add similar progress tracking capability for both downloads and streaming uploads.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/http_client.ml", 13 - "lib/response.ml", 14 - "lib/body.ml" 15 - ], 16 - "rationale": "Kingfisher's progress tracking (received/total bytes) is critical for user-facing applications. The OCaml library currently lacks any progress reporting mechanism. This would enable: 1) Progress bars/indicators for large downloads, 2) Upload progress for file uploads, 3) Better user experience in CLI tools. Implementation would add an optional `~progress:(int64 -> int64 -> unit)` callback parameter to request functions, called periodically during transfer." 17 - }, 18 - { 19 - "source_repo": "third_party/swift/kingfisher", 20 - "source_language": "Swift", 21 - "criticality": "medium", 22 - "change_type": "feature", 23 - "title": "Implement Dual-Layer HTTP Response Cache", 24 - "description": "Kingfisher implements a sophisticated dual-layer cache (memory + disk) with LRU eviction, configurable size limits, and automatic expiration. While the OCaml library has full RFC 9111 Cache-Control parsing, it lacks the actual caching implementation that was removed for simplicity.", 25 - "affected_files": [ 26 - "lib/cache.ml", 27 - "lib/response.ml", 28 - "lib/requests.ml" 29 - ], 30 - "rationale": "The OCaml library explicitly notes 'HTTP caching has been disabled for simplicity' despite having comprehensive RFC 9111 parsing. Kingfisher's dual-layer approach provides: 1) Fast memory cache for hot data, 2) Persistent disk cache across sessions, 3) Automatic size management with LRU eviction, 4) Configurable expiration policies. This would significantly improve performance for applications making repeated requests. Architecture should follow Kingfisher's pattern: separate MemoryCache and DiskCache backends, unified cache interface, cache key generation from URL+headers." 31 - }, 32 - { 33 - "source_repo": "third_party/swift/kingfisher", 34 - "source_language": "Swift", 35 - "criticality": "low", 36 - "change_type": "feature", 37 - "title": "Add Request/Response Prefetching API", 38 - "description": "Kingfisher provides an ImagePrefetcher that batch-downloads multiple resources with configurable concurrency, progress tracking, and automatic prioritization. This is useful for preloading data before it's needed.", 39 - "affected_files": [ 40 - "lib/requests.ml", 41 - "lib/prefetch.ml" 42 - ], 43 - "rationale": "Kingfisher's prefetcher enables batch downloading with: 1) Configurable max concurrent downloads, 2) Progress callbacks for batch operations, 3) Integration with list/table view prefetch APIs. The OCaml library could add a `Prefetch` module using Eio.Fiber.all to fetch multiple URLs concurrently with controlled parallelism. Use case: CLI tools downloading multiple files, web scrapers, batch API clients. This leverages Eio's structured concurrency for clean resource management." 44 - }, 45 - { 46 - "source_repo": "third_party/swift/kingfisher", 47 - "source_language": "Swift", 48 - "criticality": "low", 49 - "change_type": "enhancement", 50 - "title": "Add Alternative Sources/Fallback URL Support", 51 - "description": "Kingfisher supports specifying alternative sources that are automatically tried if the primary source fails. This provides resilience without complex retry logic.", 52 - "affected_files": [ 53 - "lib/requests.ml" 54 - ], 55 - "rationale": "Kingfisher's `alternativeSources` option allows specifying fallback URLs (e.g., CDN mirrors, backup servers) that are tried automatically on failure. The OCaml library should add an `~alternative_sources:string list` parameter to request functions. When a request fails with a retryable error, try the next URL in the list. This is simpler than complex retry logic for cases like: 1) CDN failover to origin server, 2) Regional mirror fallbacks, 3) Development/staging/production URL fallbacks. Implementation would wrap the retry logic to iterate through the source list." 56 - }, 57 - { 58 - "source_repo": "third_party/swift/kingfisher", 59 - "source_language": "Swift", 60 - "criticality": "low", 61 - "change_type": "enhancement", 62 - "title": "Add Response Modification/Processing Pipeline", 63 - "description": "Kingfisher provides an ImageModifier/Processor pipeline using the |> operator for chainable transformations. The OCaml library could provide similar response processing hooks.", 64 - "affected_files": [ 65 - "lib/response.ml", 66 - "lib/requests.ml" 67 - ], 68 - "rationale": "Kingfisher's processor pattern allows chaining transformations (downsampling, filters, custom processing) with clear composition. The OCaml library could add: 1) `~response_processor:(Response.t -> Response.t)` parameter, 2) Chainable processor combinators using |> operator, 3) Built-in processors for common tasks (size limits, format conversion). Use cases: automatic response validation, data transformation, caching decisions based on content. This follows OCaml's functional programming style naturally." 69 - }, 70 - { 71 - "source_repo": "third_party/swift/kingfisher", 72 - "source_language": "Swift", 73 - "criticality": "medium", 74 - "change_type": "enhancement", 75 - "title": "Add Network Connectivity Monitoring for Smart Retries", 76 - "description": "Kingfisher's NetworkRetryStrategy monitors network connectivity and automatically retries when the network reconnects, with optional timeout. This is smarter than blind time-based retries.", 77 - "affected_files": [ 78 - "lib/retry.ml", 79 - "lib/requests.ml" 80 - ], 81 - "rationale": "Kingfisher uses NWPathMonitor to detect network state changes and only retries when connectivity is restored. The OCaml library currently uses only time-based exponential backoff. Adding network-aware retries would: 1) Avoid wasting retry attempts when offline, 2) Retry immediately when connection is restored, 3) Provide better mobile/laptop experience. Implementation could use inotify/netlink on Linux to monitor network interfaces, with fallback to polling. Add new retry strategy type: `Network_aware of { timeout: float option }`." 82 - }, 83 - { 84 - "source_repo": "third_party/swift/kingfisher", 85 - "source_language": "Swift", 86 - "criticality": "high", 87 - "change_type": "enhancement", 88 - "title": "Add Comprehensive Logging with Numeric Error Codes", 89 - "description": "Kingfisher assigns numeric error codes (1001-5006) to all error types, enabling systematic error handling, monitoring, and categorization. The OCaml library has error query functions but no numeric codes.", 90 - "affected_files": [ 91 - "lib/error.ml" 92 - ], 93 - "rationale": "Kingfisher's numeric error codes enable: 1) Systematic error categorization in monitoring systems, 2) Easy filtering/grouping in logs, 3) Stable error identification across versions, 4) Machine-readable error handling. The OCaml library has excellent error types and query functions (is_timeout, is_retryable) but lacks numeric identifiers. Add: 1) Error code field to each variant (1xxx for request errors, 2xxx for response errors, 3xxx for connection errors, 4xxx for security errors, 5xxx for JSON/encoding errors), 2) `Error.code : error -> int` function, 3) `Error.of_code : int -> error option` for deserialization. This improves observability significantly." 94 - }, 95 - { 96 - "source_repo": "third_party/swift/kingfisher", 97 - "source_language": "Swift", 98 - "criticality": "medium", 99 - "change_type": "enhancement", 100 - "title": "Add Request/Response Lifecycle Delegate Pattern", 101 - "description": "Kingfisher provides ImageDownloaderDelegate with callbacks for willDownload, didDownload, didFinishDownload, enabling fine-grained lifecycle hooks. The OCaml library could add similar hooks.", 102 - "affected_files": [ 103 - "lib/requests.ml", 104 - "lib/http_client.ml" 105 - ], 106 - "rationale": "Kingfisher's delegate pattern allows users to hook into: 1) Request/response lifecycle events, 2) Custom validation logic, 3) Metrics collection, 4) Custom logging/monitoring. The OCaml library could add optional callbacks: `~on_request_start`, `~on_response_headers:(Headers.t -> unit)`, `~on_response_complete:(Response.t -> unit)`, `~on_error:(exn -> unit)`. Use cases: distributed tracing integration, custom metrics, request/response logging to files, audit trails. Implementation adds optional callback parameters that are invoked at appropriate points." 107 - }, 108 - { 109 - "source_repo": "third_party/swift/kingfisher", 110 - "source_language": "Swift", 111 - "criticality": "low", 112 - "change_type": "enhancement", 113 - "title": "Add Request Priority Support", 114 - "description": "Kingfisher supports downloadPriority option that maps to URLSessionTask priority, allowing critical requests to be prioritized over background fetches.", 115 - "affected_files": [ 116 - "lib/requests.ml", 117 - "lib/http_client.ml" 118 - ], 119 - "rationale": "Kingfisher's priority system allows marking requests as high/normal/low priority, which URLSession uses to schedule work. The OCaml library could add: 1) `~priority:[`High | `Normal | `Low]` parameter, 2) Priority queue in connection pool for pending requests, 3) Eio fiber priority if supported. Use cases: user-initiated requests vs background sync, critical API calls vs telemetry, interactive UI vs batch processing. With Eio's structured concurrency, this could use separate fibers with different scheduling hints." 120 - }, 121 - { 122 - "source_repo": "third_party/swift/kingfisher", 123 - "source_language": "Swift", 124 - "criticality": "low", 125 - "change_type": "feature", 126 - "title": "Add Request Cancellation Tokens", 127 - "description": "Kingfisher returns DownloadTask objects with cancel() methods, allowing users to cancel in-flight requests. The OCaml library uses Eio switches but lacks explicit per-request cancellation.", 128 - "affected_files": [ 129 - "lib/requests.ml", 130 - "lib/http_client.ml" 131 - ], 132 - "rationale": "Kingfisher's cancellation pattern allows fine-grained control: users get a task handle that can be cancelled individually without killing the entire session. The OCaml library relies on Eio.Switch for lifecycle but doesn't expose per-request cancellation. Add: 1) Return type `type request_handle = { cancel: unit -> unit }` from request functions, 2) Use Eio.Cancel.sub for per-request cancellation context, 3) Document that cancellation raises Error.E(Error.Request_cancelled). Use case: cancelling slow requests when user navigates away, timeout individual operations, user-initiated abort." 133 - }, 134 - { 135 - "source_repo": "third_party/swift/kingfisher", 136 - "source_language": "Swift", 137 - "criticality": "medium", 138 - "change_type": "enhancement", 139 - "title": "Add Configuration Validation and Pretty Printing", 140 - "description": "Kingfisher provides pp_config formatters and validation for all configuration objects. The OCaml library has some pretty printers but lacks comprehensive config validation.", 141 - "affected_files": [ 142 - "lib/requests.ml", 143 - "lib/retry.ml", 144 - "lib/timeout.ml" 145 - ], 146 - "rationale": "Kingfisher validates configuration at creation time and provides detailed pretty printers for debugging. The OCaml library has `Retry.pp_config` but lacks: 1) Validation that max_retries >= 0, backoff_factor > 0, 2) Pretty printer for full session configuration, 3) Validation warnings for suspicious configs (e.g., total_timeout < connect_timeout). Add: 1) `validate` functions that return Result.t with error messages, 2) Comprehensive `pp` functions for all config types, 3) `pp_session` that shows full session state. This improves developer experience significantly." 147 - }, 148 - { 149 - "source_repo": "third_party/swift/kingfisher", 150 - "source_language": "Swift", 151 - "criticality": "low", 152 - "change_type": "enhancement", 153 - "title": "Add Request/Response Metrics Collection", 154 - "description": "Kingfisher's ImageLoadingResult includes NetworkMetrics with timing information. The OCaml library tracks elapsed time but could provide more detailed metrics.", 155 - "affected_files": [ 156 - "lib/response.ml", 157 - "lib/requests.ml" 158 - ], 159 - "rationale": "Kingfisher collects detailed metrics (DNS lookup time, TCP connect time, TLS handshake time, transfer times). The OCaml library only tracks total elapsed time. Add: 1) `type metrics = { dns_time: float option; connect_time: float option; tls_time: float option; transfer_time: float; total_time: float }`, 2) Expose metrics via `Response.metrics`, 3) Track timing at each phase in Http_client. Use cases: performance monitoring, SLA tracking, debugging slow requests, identifying bottlenecks. Minimal performance overhead with gettimeofday calls." 160 - }, 161 - { 162 - "source_repo": "third_party/swift/kingfisher", 163 - "source_language": "Swift", 164 - "criticality": "low", 165 - "change_type": "enhancement", 166 - "title": "Add Response Disposition Control via Callbacks", 167 - "description": "Kingfisher's SessionDelegate allows custom response disposition decisions, enabling conditional processing based on response headers before body download.", 168 - "affected_files": [ 169 - "lib/http_client.ml", 170 - "lib/requests.ml" 171 - ], 172 - "rationale": "Kingfisher allows users to inspect response headers and decide whether to continue downloading the body, cancel, or transform. The OCaml library downloads the entire response body before user code runs. Add: 1) `~on_response_headers:(Headers.t -> [`Continue | `Cancel | `Cancel_with of exn])` callback, 2) Early body download termination on `Cancel, 3) Save bandwidth for unwanted large responses. Use cases: skip large files based on Content-Length, reject unexpected Content-Types early, conditional downloads based on ETag/Last-Modified." 173 - }, 174 - { 175 - "source_repo": "third_party/swift/kingfisher", 176 - "source_language": "Swift", 177 - "criticality": "medium", 178 - "change_type": "enhancement", 179 - "title": "Add Session Statistics and Observability", 180 - "description": "Kingfisher tracks cache hits/misses, download counts, and performance metrics. The OCaml library has basic statistics (requests_made, total_time, retries_count) but could expand this.", 181 - "affected_files": [ 182 - "lib/requests.ml" 183 - ], 184 - "rationale": "Kingfisher provides detailed statistics for monitoring. The OCaml library tracks minimal stats that aren't easily accessible. Enhance: 1) Add `type stats = { requests_made: int; bytes_sent: int64; bytes_received: int64; retries_count: int; failed_requests: int; avg_response_time: float; cache_hits: int; cache_misses: int }`, 2) Add `get_stats : t -> stats` function, 3) Track per-session and per-host statistics. Use cases: performance monitoring, debugging, capacity planning, SLA compliance. Stats should be accessible even when session is wrapped in record update syntax." 185 - }, 186 - { 187 - "source_repo": "third_party/swift/kingfisher", 188 - "source_language": "Swift", 189 - "criticality": "low", 190 - "change_type": "feature", 191 - "title": "Add Request/Response Data Provider Abstraction", 192 - "description": "Kingfisher's ImageDataProvider protocol allows custom data sources beyond URLs (local files, in-memory data, custom protocols). The OCaml library could add similar flexibility.", 193 - "affected_files": [ 194 - "lib/requests.ml", 195 - "lib/body.ml" 196 - ], 197 - "rationale": "Kingfisher's DataProvider abstraction allows: 1) Custom data sources, 2) Unified caching regardless of source, 3) Testing with mock data. The OCaml library could add: `type data_provider = { fetch: unit -> Response.t; cache_key: string }` and `request_from_provider : t -> data_provider -> Response.t` function. Use cases: testing with fixtures, custom protocol handlers, embedding responses, virtual file systems. This enables mocking HTTP responses for tests without running a server." 198 - } 199 - ] 200 - }
-264
third_party/swift/moya.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/swift/moya", 5 - "source_language": "Swift", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Request/Response Interceptor Plugin System", 9 - "description": "Implement a plugin/interceptor system that allows request modification before sending and response transformation after receiving. Moya's PluginType provides prepare(), willSend(), didReceive(), and process() hooks that enable cross-cutting concerns like logging, authentication injection, metrics collection, and request/response transformation without modifying core request logic.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/requests.mli" 13 - ], 14 - "rationale": "A plugin system would enable extensibility for common patterns like custom logging (beyond basic Logs integration), request timing/metrics, header injection based on target endpoint, response validation, and custom error handling. This would allow users to implement cross-cutting concerns cleanly without forking or wrapping the library. The OCaml implementation could use a record type with optional function fields for lifecycle hooks: `type plugin = { prepare: (Headers.t -> Headers.t) option; will_send: (unit -> unit) option; did_receive: (Response.t -> unit) option; process: (Response.t -> Response.t) option }`." 15 - }, 16 - { 17 - "source_repo": "third_party/swift/moya", 18 - "source_language": "Swift", 19 - "criticality": "low", 20 - "change_type": "feature", 21 - "title": "Upload/Download Progress Callbacks", 22 - "description": "Add support for progress tracking during uploads and downloads via callbacks. Moya's ProgressResponse type provides fraction completed and tracks both upload and download progress separately with accumulating progress events.", 23 - "affected_files": [ 24 - "lib/requests.ml", 25 - "lib/requests.mli", 26 - "lib/http_client.ml" 27 - ], 28 - "rationale": "Progress tracking is essential for user-facing applications that upload/download large files. Without progress callbacks, applications cannot provide feedback to users during long-running transfers. The implementation could accept an optional `~on_progress:(float -> unit)` callback parameter that gets invoked periodically with the fraction completed (0.0 to 1.0). This would require integration with Eio's streaming I/O to track bytes transferred." 29 - }, 30 - { 31 - "source_repo": "third_party/swift/moya", 32 - "source_language": "Swift", 33 - "criticality": "medium", 34 - "change_type": "feature", 35 - "title": "Request Deduplication (In-Flight Request Tracking)", 36 - "description": "Implement automatic deduplication of concurrent identical requests via trackInflights mechanism. When enabled, if the same request is made multiple times concurrently, only one network request is performed and the response is shared among all callers.", 37 - "affected_files": [ 38 - "lib/requests.ml" 39 - ], 40 - "rationale": "In web applications and mobile apps, the same API request can be triggered multiple times concurrently (e.g., user double-clicking, reactive UI updates). Without deduplication, this creates unnecessary load on servers and wastes bandwidth. Moya's trackInflights feature maintains a map of in-flight requests by endpoint and queues multiple completion handlers to fire when the single request completes. OCaml implementation could use a `(string, Response.t Eio.Promise.t) Hashtbl.t` to track in-flight requests by normalized URL+method, with proper cleanup on completion/failure." 41 - }, 42 - { 43 - "source_repo": "third_party/swift/moya", 44 - "source_language": "Swift", 45 - "criticality": "low", 46 - "change_type": "enhancement", 47 - "title": "Response Validation/Filtering Helpers", 48 - "description": "Add convenient response validation methods like filter(statusCodes: range), filterSuccessfulStatusCodes(), and filterSuccessfulStatusAndRedirectCodes() that throw descriptive errors when status codes don't match expectations.", 49 - "affected_files": [ 50 - "lib/response.ml", 51 - "lib/response.mli" 52 - ], 53 - "rationale": "Currently, users must manually check status codes and create errors. Moya's filtering approach provides a fluent API for status code validation that can be chained with response mapping operations. This reduces boilerplate and makes error handling more explicit. Implementation: `val filter_status_codes : t -> int list -> t` that raises Error.Http_error if status not in list, with convenience variants for common cases (2xx, 2xx-3xx ranges)." 54 - }, 55 - { 56 - "source_repo": "third_party/swift/moya", 57 - "source_language": "Swift", 58 - "criticality": "low", 59 - "change_type": "enhancement", 60 - "title": "Enhanced Response Mapping with KeyPath Support", 61 - "description": "Extend Response.json() and similar methods to support keyPath extraction, allowing direct parsing of nested JSON values without manual traversal. Moya's map<D: Decodable>() method accepts an optional atKeyPath parameter.", 62 - "affected_files": [ 63 - "lib/response.ml", 64 - "lib/response.mli" 65 - ], 66 - "rationale": "When APIs wrap data in envelope structures (e.g., {\"data\": {actual data}, \"meta\": {...}}), clients must manually unwrap before parsing. KeyPath support allows specifying the path to the actual data (e.g., \"data.users\"), reducing boilerplate. Implementation could accept optional `~at_key_path:string` parameter and use jsont to traverse to the nested value before parsing. Example: `Response.json_at ~key_path:\"data.items\" response`." 67 - }, 68 - { 69 - "source_repo": "third_party/swift/moya", 70 - "source_language": "Swift", 71 - "criticality": "medium", 72 - "change_type": "feature", 73 - "title": "Test Stubbing Support", 74 - "description": "Add built-in support for stubbing network requests during testing with configurable stub behavior (immediate, delayed, never). Moya's StubBehavior and sampleData in TargetType make testing first-class.", 75 - "affected_files": [ 76 - "lib/requests.ml", 77 - "lib/requests.mli", 78 - "test/" 79 - ], 80 - "rationale": "Testing HTTP clients typically requires running local servers or mocking at the network layer. Built-in stubbing makes tests faster, more reliable, and portable. Moya's approach: each endpoint defines sample data, and providers can be configured with stub behavior (immediate return, delayed return, or real network). OCaml implementation could add `~stub:(Method.t -> Uri.t -> (int * Headers.t * string) option)` parameter to session creation that returns stubbed responses instead of making network calls when configured." 81 - }, 82 - { 83 - "source_repo": "third_party/swift/moya", 84 - "source_language": "Swift", 85 - "criticality": "high", 86 - "change_type": "enhancement", 87 - "title": "Structured Error Response Preservation", 88 - "description": "Ensure all error types preserve the original Response object when available, similar to MoyaError variants. This includes parsing errors, validation errors, and mapping errors, not just network errors.", 89 - "affected_files": [ 90 - "lib/error.ml", 91 - "lib/response.ml" 92 - ], 93 - "rationale": "MoyaError consistently attaches Response objects to errors (imageMapping, jsonMapping, stringMapping, statusCode, underlying all carry Response). This is crucial for debugging because error responses often contain detailed error messages in their body. The OCaml library already does this for Http_error but should ensure Json_parse_error and other response-related errors also preserve full response data including headers. Current Json_parse_error only stores body_preview; should store full response object for access to headers, status, etc." 94 - }, 95 - { 96 - "source_repo": "third_party/swift/moya", 97 - "source_language": "Swift", 98 - "criticality": "low", 99 - "change_type": "enhancement", 100 - "title": "cURL Request Formatting for Debugging", 101 - "description": "Add ability to export requests as executable cURL commands for debugging and sharing. Moya's NetworkLoggerPlugin includes formatRequestAscURL option that generates valid cURL commands.", 102 - "affected_files": [ 103 - "lib/requests.ml", 104 - "lib/http_client.ml" 105 - ], 106 - "rationale": "cURL commands are invaluable for debugging HTTP issues - they allow developers to reproduce requests outside the application, share reproduction steps with backend teams, and test variations manually. Implementation: add `val to_curl : method:Method.t -> uri:Uri.t -> headers:Headers.t -> body:Body.t -> string` function that generates a properly escaped cURL command with all headers and body data. Could be integrated into logging at Debug level." 107 - }, 108 - { 109 - "source_repo": "third_party/swift/moya", 110 - "source_language": "Swift", 111 - "criticality": "medium", 112 - "change_type": "enhancement", 113 - "title": "Configurable Request/Response Logging", 114 - "description": "Implement structured, configurable logging with granular control over what gets logged (method, headers, body, success/error responses). Moya's NetworkLoggerPlugin.Configuration provides LogOptions flags and custom formatters.", 115 - "affected_files": [ 116 - "lib/requests.ml" 117 - ], 118 - "rationale": "Current logging uses Logs.info for all requests/responses. Production applications need finer control: log headers but not sensitive auth tokens, log request method but not bodies with PII, log error response bodies but not success bodies. Moya's LogOptions (.requestMethod, .requestHeaders, .requestBody, .successResponseBody, .errorResponseBody) with .default and .verbose presets provides this. OCaml could add a `type log_config` with fields for each loggable component and integrate with existing sanitization in Error module." 119 - }, 120 - { 121 - "source_repo": "third_party/swift/moya", 122 - "source_language": "Swift", 123 - "criticality": "low", 124 - "change_type": "enhancement", 125 - "title": "Response Equality and Comparison", 126 - "description": "Implement equality comparison for Response types to support testing and caching scenarios. Moya's Response implements Equatable based on statusCode, data, and response object.", 127 - "affected_files": [ 128 - "lib/response.ml", 129 - "lib/response.mli" 130 - ], 131 - "rationale": "Testing response handling requires comparing actual vs expected responses. Caching implementations need to determine if cached responses match. Without structural equality, these comparisons require manual field-by-field checks. Implementation: `val equal : t -> t -> bool` that compares status, headers, and body content (reading body streams into strings for comparison). Note: this makes body consumption destructive, so provide documentation or make Response type immutable with body as string." 132 - }, 133 - { 134 - "source_repo": "third_party/swift/moya", 135 - "source_language": "Swift", 136 - "criticality": "low", 137 - "change_type": "enhancement", 138 - "title": "Custom Authorization Type Support", 139 - "description": "Extend Auth module to support custom authorization schemes beyond Basic/Bearer. Moya's AuthorizationType includes .custom(String) variant for non-standard schemes.", 140 - "affected_files": [ 141 - "lib/auth.ml", 142 - "lib/auth.mli" 143 - ], 144 - "rationale": "Some APIs use custom authorization schemes (e.g., AWS Signature, API Key, Custom OAuth). Current Auth.t supports Basic, Bearer, Digest, and Custom handler. The Custom handler requires users to manually construct headers. Adding Auth.custom_scheme variant that takes scheme name and token (e.g., `Custom_scheme { scheme: \"API-Key\"; token: \"abc123\" }`) would make these cases more ergonomic. Implementation: `type t = ... | Custom_scheme of { scheme: string; token: string }` that applies as `Authorization: {scheme} {token}`." 145 - }, 146 - { 147 - "source_repo": "third_party/swift/moya", 148 - "source_language": "Swift", 149 - "criticality": "low", 150 - "change_type": "enhancement", 151 - "title": "Empty Response Handling Options", 152 - "description": "Provide options for handling empty responses in JSON parsing, allowing fallback values instead of errors. Moya's mapJSON(failsOnEmptyData: Bool) parameter controls this behavior.", 153 - "affected_files": [ 154 - "lib/response.ml", 155 - "lib/response.mli" 156 - ], 157 - "rationale": "Some APIs return empty bodies (0 bytes) for successful DELETE operations or 204 No Content responses. Parsing these as JSON currently fails. Moya allows failsOnEmptyData parameter - when false, empty responses map to NSNull instead of throwing. OCaml implementation could add `~fail_on_empty:bool` parameter (default true) to Response.json that returns `None` or default value when false. Example: `val json : ?fail_on_empty:bool -> t -> Jsont.json option`." 158 - }, 159 - { 160 - "source_repo": "third_party/swift/moya", 161 - "source_language": "Swift", 162 - "criticality": "low", 163 - "change_type": "feature", 164 - "title": "Network Activity Indicator Integration", 165 - "description": "Provide hooks for UI network activity indicators to show when requests are in flight. Moya's NetworkActivityPlugin tracks request start/completion to manage activity indicator state.", 166 - "affected_files": [ 167 - "lib/requests.ml", 168 - "lib/requests.mli" 169 - ], 170 - "rationale": "Desktop and mobile applications often show network activity indicators (spinning wheel, progress bar) while requests are pending. Without library support, applications must manually track request state. Implementation: add optional `~on_activity_change:(bool -> unit)` callback to session that fires with true when first request starts and false when last request completes. The session would maintain a counter of in-flight requests. This integrates cleanly with the proposed plugin system as a built-in plugin." 171 - }, 172 - { 173 - "source_repo": "third_party/swift/moya", 174 - "source_language": "Swift", 175 - "criticality": "medium", 176 - "change_type": "enhancement", 177 - "title": "Multipart Upload with Streaming Support", 178 - "description": "Enhance multipart form data to support streaming sources (InputStream equivalent) for memory-efficient large file uploads. Moya's MultipartFormData supports FormDataProvider with .stream(InputStream, UInt64) variant.", 179 - "affected_files": [ 180 - "lib/body.ml", 181 - "lib/body.mli" 182 - ], 183 - "rationale": "Current Multipart implementation loads entire file contents into memory via File variant. For large files (GB+), this is inefficient and can cause OOM. Moya's streaming support allows files to be read incrementally during upload. The OCaml Body.part type already supports `Stream variant, but multipart generation in Body module may buffer the entire part. Ensure multipart boundary writing interleaves with streaming part content, not buffering. Implementation verification: check that File parts are streamed via Eio.Path.load, not loaded entirely into memory first." 184 - }, 185 - { 186 - "source_repo": "third_party/swift/moya", 187 - "source_language": "Swift", 188 - "criticality": "high", 189 - "change_type": "security", 190 - "title": "Request Parameter Encoding Validation", 191 - "description": "Add validation for request parameter encoding to prevent injection attacks through query parameters or form data. Moya's parameterEncoding error captures encoding failures explicitly.", 192 - "affected_files": [ 193 - "lib/requests.ml", 194 - "lib/body.ml" 195 - ], 196 - "rationale": "Improper encoding of query parameters or form data can lead to injection attacks or malformed requests. While Uri.add_query_param' handles basic encoding, there's no explicit validation that parameters don't contain control characters or attempt header injection via encoded newlines. Add validation in Body.form_data and query parameter handling to detect and reject parameters containing encoded CRLF sequences, null bytes, or other control characters. Raise Error.Invalid_request with descriptive reason when detected." 197 - }, 198 - { 199 - "source_repo": "third_party/swift/moya", 200 - "source_language": "Swift", 201 - "criticality": "medium", 202 - "change_type": "feature", 203 - "title": "Endpoint-Specific Configuration", 204 - "description": "Allow per-request overrides of session configuration (timeout, retry, auth) beyond what's currently supported. Moya's endpoint concept separates target specification from execution configuration.", 205 - "affected_files": [ 206 - "lib/requests.ml", 207 - "lib/requests.mli" 208 - ], 209 - "rationale": "Currently, timeout, auth, and redirects can be overridden per-request, but retry configuration is session-global. Some endpoints need different retry strategies (e.g., idempotent operations retry aggressively, mutations retry conservatively). Moya's endpoint closure pattern allows full customization per target. Add `~retry:Retry.config option` parameter to request functions to override session default. This provides flexibility without requiring multiple session objects." 210 - }, 211 - { 212 - "source_repo": "third_party/swift/moya", 213 - "source_language": "Swift", 214 - "criticality": "low", 215 - "change_type": "enhancement", 216 - "title": "Image Response Mapping", 217 - "description": "Add convenience method for parsing responses as images with platform-appropriate image type. Moya provides mapImage() that returns UIImage/NSImage depending on platform.", 218 - "affected_files": [ 219 - "lib/response.ml", 220 - "lib/response.mli" 221 - ], 222 - "rationale": "Applications that fetch images need to parse response data into image objects for display. This is common for profile pictures, thumbnails, etc. While this is platform-specific (different image libraries for different targets), the library could provide an extensible mechanism. Implementation: Add `val map : t -> f:(string -> 'a) -> 'a` that allows custom parsing of response body, with example showing image parsing using stb_image or camlimages. Alternatively, provide ~parser parameter to session creation for registering MIME-type-specific parsers." 223 - }, 224 - { 225 - "source_repo": "third_party/swift/moya", 226 - "source_language": "Swift", 227 - "criticality": "low", 228 - "change_type": "enhancement", 229 - "title": "Cancellable Request Tokens", 230 - "description": "Return explicit cancellation tokens from request calls that allow in-flight request cancellation and status checking. Moya returns Cancellable protocol with isCancelled property and cancel() method.", 231 - "affected_files": [ 232 - "lib/requests.ml", 233 - "lib/requests.mli" 234 - ], 235 - "rationale": "Long-running requests may need cancellation when user navigates away or request becomes irrelevant. Eio's structured concurrency uses fibers and cancellation via switches, but there's no explicit handle returned from request() calls. Implementation: wrap request execution in a fiber and return a cancellation token: `type cancellable = { cancel: unit -> unit; is_cancelled: unit -> bool }`. The cancel function would cancel the fiber. This is particularly useful for UI applications where requests should be cancelled when views are destroyed." 236 - }, 237 - { 238 - "source_repo": "third_party/swift/moya", 239 - "source_language": "Swift", 240 - "criticality": "medium", 241 - "change_type": "enhancement", 242 - "title": "Default Response Encoding Handling", 243 - "description": "Implement automatic character encoding detection and handling for text responses, with fallback strategies for missing or incorrect Content-Type charset. Moya's mapString handles encoding implicitly.", 244 - "affected_files": [ 245 - "lib/response.ml", 246 - "lib/http_client.ml" 247 - ], 248 - "rationale": "Some servers return text without charset in Content-Type header or with incorrect charset declarations. Current Response.text (if it exists) likely assumes UTF-8. Robust handling should: (1) check Content-Type charset parameter, (2) attempt UTF-8 decode, (3) fall back to Latin-1 if UTF-8 fails, (4) optionally detect encoding from byte order mark or HTML meta tags. Implementation: `val text : ?encoding:string -> t -> string` with automatic detection when encoding not specified. Use uutf or similar library for encoding conversion." 249 - }, 250 - { 251 - "source_repo": "third_party/swift/moya", 252 - "source_language": "Swift", 253 - "criticality": "low", 254 - "change_type": "enhancement", 255 - "title": "Composable Request Builders", 256 - "description": "Provide builder pattern or composable functions for constructing complex requests with multiple options. Moya's endpoint concept and task enum provide structured request composition.", 257 - "affected_files": [ 258 - "lib/requests.ml", 259 - "lib/requests.mli" 260 - ], 261 - "rationale": "Complex requests with many optional parameters (headers, body, auth, timeout, retry, redirects) lead to long function signatures and unclear intent. A builder pattern would improve ergonomics. However, OCaml's labeled arguments already provide good ergonomics. Instead, consider adding convenience combinators: `val with_auth : t -> Auth.t -> t`, `val with_headers : t -> Headers.t -> t` that work on session objects to create modified sessions. This is more functional than mutable builders but achieves similar composability." 262 - } 263 - ] 264 - }
-246
third_party/swift/net.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/swift/net", 5 - "source_language": "Swift", 6 - "criticality": "medium", 7 - "change_type": "feature", 8 - "title": "Add Task State Management for Long-Running Operations", 9 - "description": "Implement explicit task state tracking for long-running downloads/uploads with pause/resume/cancel capabilities. The Swift Net library uses an enum-based state machine (Init, Downloading/Uploading, Suspending, Canceled, Completed, Failed) to track task lifecycle, enabling fine-grained control over transfers.", 10 - "affected_files": [ 11 - "lib/one.ml", 12 - "lib/one.mli", 13 - "lib/response.ml", 14 - "lib/response.mli" 15 - ], 16 - "rationale": "Currently, the OCaml library streams responses directly via Eio.Flow but lacks explicit state management for long-running operations. Adding state tracking would enable: (1) Pause/resume for large downloads/uploads, (2) Graceful cancellation with cleanup, (3) Progress tracking integration, (4) Better error recovery for interrupted transfers. This is particularly valuable for mobile/CLI applications dealing with large files or unreliable connections. Implementation can leverage Eio's cancellation contexts and add optional state callbacks to the One module's download/upload functions." 17 - }, 18 - { 19 - "source_repo": "third_party/swift/net", 20 - "source_language": "Swift", 21 - "criticality": "low", 22 - "change_type": "feature", 23 - "title": "Add Progress Callback Support for Uploads and Downloads", 24 - "description": "Implement progress callbacks (via function type `float -> unit`) for upload and download operations to provide real-time transfer progress. The Swift Net library uses ProgressHandler callbacks that receive a float between 0.0-1.0 representing completion percentage, integrated with URLSession delegate methods for byte tracking.", 25 - "affected_files": [ 26 - "lib/one.ml", 27 - "lib/one.mli", 28 - "lib/body.ml", 29 - "lib/body.mli", 30 - "lib/http_client.ml" 31 - ], 32 - "rationale": "The OCaml library currently lacks built-in progress reporting for large uploads/downloads. Users cannot track transfer progress without custom instrumentation. Adding optional progress callbacks would improve UX for CLI tools and applications by enabling: (1) Progress bars for file transfers, (2) Upload/download speed estimation, (3) ETA calculations, (4) Better user feedback for long operations. This can be implemented by: (1) Adding optional `?on_progress:(float -> unit)` parameter to One.download and upload functions, (2) Instrumenting Eio.Flow.copy operations to calculate bytes_transferred/total_bytes, (3) Invoking callback at configurable intervals (e.g., every 100KB or 1% progress)." 33 - }, 34 - { 35 - "source_repo": "third_party/swift/net", 36 - "source_language": "Swift", 37 - "criticality": "medium", 38 - "change_type": "enhancement", 39 - "title": "Add Response Validation Hooks Before Body Processing", 40 - "description": "Implement a response validation mechanism that checks HTTP status codes before attempting to parse response bodies. The Swift Net library validates status code == 200 in ResponseData parsing methods (json(), image(), parseXml()) before processing, returning structured errors with status code context for non-success responses.", 41 - "affected_files": [ 42 - "lib/response.ml", 43 - "lib/response.mli", 44 - "lib/error.ml", 45 - "lib/error.mli" 46 - ], 47 - "rationale": "Currently, Response.json and Response.text consume the body stream regardless of HTTP status code, which can lead to parsing errors on error responses. The Swift pattern of validating status before parsing prevents: (1) Confusing JSON parse errors when server returns HTML error pages, (2) Wasted processing on known-bad responses, (3) Loss of error context when body consumption fails. Recommend adding: (1) Response.json_exn and Response.text_exn that validate status first, (2) Response.json and Response.text that return Result types with validation, (3) Configurable status code allowlists (default: 200-299 for json, 200-299 for text). This preserves current exception-based API while adding safety." 48 - }, 49 - { 50 - "source_repo": "third_party/swift/net", 51 - "source_language": "Swift", 52 - "criticality": "low", 53 - "change_type": "feature", 54 - "title": "Add Automatic Multipart Boundary Generation", 55 - "description": "Implement automatic random boundary generation for multipart/form-data requests instead of requiring users to specify boundaries. The Swift Net library generates random boundaries using arc4random(): `NET-POST-boundary-{random1}-{random2}`, ensuring uniqueness without user intervention.", 56 - "affected_files": [ 57 - "lib/body.ml", 58 - "lib/body.mli" 59 - ], 60 - "rationale": "The OCaml library's Body.multipart function currently uses a hardcoded or library-internal boundary for multipart uploads. While this works, automatic random boundary generation improves: (1) Safety against boundary collision with user data, (2) Compliance with RFC 2046 which recommends unique boundaries, (3) Reduced cognitive load on library users. Recommend: (1) Using Random or mirage-crypto to generate boundaries like `ocaml-requests-{hex_random}-{hex_random}`, (2) Ensuring boundaries don't appear in any part content (scan and regenerate if collision), (3) Documenting boundary format for debugging. This is a minor improvement but aligns with security best practices." 61 - }, 62 - { 63 - "source_repo": "third_party/swift/net", 64 - "source_language": "Swift", 65 - "criticality": "medium", 66 - "change_type": "feature", 67 - "title": "Add Support for Background Session Operations", 68 - "description": "Implement background/daemon mode for long-running uploads and downloads that can survive application suspension or network interruptions. The Swift Net library uses NSURLSession's background session configuration with delegate callbacks, allowing transfers to continue when the app is suspended and providing completion notifications.", 69 - "affected_files": [ 70 - "lib/requests.ml", 71 - "lib/requests.mli", 72 - "lib/one.ml", 73 - "lib/one.mli" 74 - ], 75 - "rationale": "The OCaml library's Eio-based design ties all operations to the current switch/fiber lifecycle. When a program exits or a fiber is cancelled, transfers are aborted. Adding background session support would enable: (1) Large file uploads/downloads that survive process restarts, (2) Resumable transfers with persistent state, (3) Better resource management for long transfers, (4) Integration with system schedulers for batch operations. Implementation approach: (1) Add optional `?persist_to:Eio.Path.t` parameter to store transfer state (URL, headers, progress, resume data), (2) Implement resume logic that reads state and uses HTTP Range headers, (3) Add One.resume_download/upload functions, (4) Store ETag/Last-Modified for validation. This requires careful design to work within Eio's structured concurrency model." 76 - }, 77 - { 78 - "source_repo": "third_party/swift/net", 79 - "source_language": "Swift", 80 - "criticality": "low", 81 - "change_type": "enhancement", 82 - "title": "Add Automatic Content-Type Detection for Binary Uploads", 83 - "description": "Implement automatic Content-Type header setting for binary data uploads based on data characteristics or magic bytes. The Swift Net library sets `application/octet-stream` as default for raw NSData uploads, providing a safe fallback for binary content.", 84 - "affected_files": [ 85 - "lib/body.ml", 86 - "lib/body.mli" 87 - ], 88 - "rationale": "The OCaml library's Body.of_stream function requires explicit MIME type specification. For raw binary data uploads where MIME type isn't known, users must manually set it. Adding automatic detection improves ergonomics: (1) Reduces boilerplate for common upload scenarios, (2) Provides sensible defaults (application/octet-stream for binary), (3) Supports magic byte detection for common formats (PNG, JPEG, PDF headers). Recommend: (1) Default to application/octet-stream for Body.of_stream when mime not provided, (2) Add Body.of_file_auto that uses magic library or simple header detection, (3) Document that explicit MIME types are always preferred. Note: The library already has MIME guessing marked as TODO in body.ml." 89 - }, 90 - { 91 - "source_repo": "third_party/swift/net", 92 - "source_language": "Swift", 93 - "criticality": "medium", 94 - "change_type": "enhancement", 95 - "title": "Add Configurable HTTP Pipelining Support", 96 - "description": "Implement optional HTTP pipelining configuration to allow multiple HTTP requests to be sent on a single connection without waiting for responses. The Swift Net library exposes HTTPShouldUsePipelining as a configurable boolean flag on NSURLSessionConfiguration.", 97 - "affected_files": [ 98 - "lib/requests.ml", 99 - "lib/requests.mli", 100 - "lib/http_client.ml", 101 - "lib/http_client.mli" 102 - ], 103 - "rationale": "HTTP pipelining can significantly reduce latency for multiple requests to the same host by eliminating round-trip wait times. The OCaml library uses connection pooling (via Conpool) but doesn't expose pipelining configuration. Adding this would: (1) Improve performance for bulk API requests to the same endpoint, (2) Better utilize persistent connections, (3) Reduce overall request latency for sequential operations. Implementation: (1) Add `?enable_pipelining:bool` parameter to Requests.create (default: false for safety), (2) Pass flag to underlying HTTP/1.1 client implementation, (3) Ensure proper request/response correlation with pipelining enabled, (4) Document that servers must support it and responses arrive in order. Note: HTTP/2 multiplexing is superior but requires protocol upgrade; pipelining helps with HTTP/1.1 optimization." 104 - }, 105 - { 106 - "source_repo": "third_party/swift/net", 107 - "source_language": "Swift", 108 - "criticality": "medium", 109 - "change_type": "enhancement", 110 - "title": "Add Per-Request Cellular Access Control", 111 - "description": "Implement network type restrictions to control whether requests can use cellular vs WiFi connections. The Swift Net library exposes allowsCellularAccess configuration at both session and request levels, enabling fine-grained control over network usage.", 112 - "affected_files": [ 113 - "lib/requests.ml", 114 - "lib/requests.mli", 115 - "lib/one.ml", 116 - "lib/one.mli" 117 - ], 118 - "rationale": "For mobile or bandwidth-constrained environments, controlling network type usage is critical for: (1) Preventing large downloads on metered connections, (2) Implementing WiFi-only background sync, (3) Reducing data costs for users, (4) Compliance with user preferences for cellular data usage. While this is platform-specific (iOS/Android concept), on Linux/Unix systems this could map to: (1) Network interface restrictions (prefer wlan0 over ppp0), (2) Integration with network monitoring tools, (3) Bandwidth throttling for certain connection types. Implementation could add: (1) `?prefer_interface:string option` parameter, (2) `?max_bandwidth:int option` for rate limiting, (3) Detection of metered connections via system APIs where available. This is lower priority for server applications but valuable for CLI tools and edge computing." 119 - }, 120 - { 121 - "source_repo": "third_party/swift/net", 122 - "source_language": "Swift", 123 - "criticality": "high", 124 - "change_type": "enhancement", 125 - "title": "Add Completion Callbacks for Background Event Handling", 126 - "description": "Implement callback mechanism for handling background session completion events, allowing applications to perform cleanup or UI updates when long-running transfers complete. The Swift Net library uses eventsForBackgroundHandler callback that receives the URLSession when all background tasks finish.", 127 - "affected_files": [ 128 - "lib/requests.ml", 129 - "lib/requests.mli", 130 - "lib/one.ml" 131 - ], 132 - "rationale": "With Eio's structured concurrency model, operations are typically scoped to switches. However, for long-running background operations or daemon processes, completion callbacks enable: (1) Async notification when transfers complete (vs polling), (2) Resource cleanup outside the main fiber, (3) Metrics collection and logging, (4) Integration with event systems or message queues. This is especially valuable when combined with the background session feature (Recommendation #5). Implementation: (1) Add optional `?on_complete:(Response.t -> unit)` and `?on_error:(Error.error -> unit)` callbacks to download/upload functions, (2) Execute callbacks in a separate fiber when transfer finishes, (3) Ensure callbacks run even if parent fiber is cancelled (use Fiber.fork_daemon), (4) Document that callbacks must be thread-safe if used concurrently. This improves ergonomics for fire-and-forget upload/download patterns." 133 - }, 134 - { 135 - "source_repo": "third_party/swift/net", 136 - "source_language": "Swift", 137 - "criticality": "low", 138 - "change_type": "enhancement", 139 - "title": "Add Structured Session Lifecycle Management Methods", 140 - "description": "Implement explicit session lifecycle control with invalidateAndCancel (abort all tasks immediately) and finishTasksAndInvalidate (complete pending tasks then cleanup) methods. The Swift Net library exposes these URLSession lifecycle methods to give users control over graceful vs immediate shutdown.", 141 - "affected_files": [ 142 - "lib/requests.ml", 143 - "lib/requests.mli" 144 - ], 145 - "rationale": "The OCaml library uses Eio switches for automatic resource cleanup, which is excellent for scoped operations. However, adding explicit session control methods would enable: (1) Graceful shutdown that waits for in-flight requests, (2) Immediate cancellation for emergency shutdown, (3) Better control in REPL/interactive environments, (4) Explicit resource management for long-lived sessions. Recommend adding: (1) Requests.shutdown ~graceful:bool t that either waits for pending requests or cancels immediately, (2) Requests.close_all_connections t to drain connection pools, (3) Requests.cancel_all_requests t for emergency abort. Note: These would complement, not replace, switch-based cleanup. Implementation should: (1) Mark session as closed to reject new requests, (2) Cancel or wait for pending operations based on graceful flag, (3) Close connection pools, (4) Clear cookies if not persisted. This is lower priority since Eio switches handle most use cases, but aids explicit resource management." 146 - }, 147 - { 148 - "source_repo": "third_party/swift/net", 149 - "source_language": "Swift", 150 - "criticality": "medium", 151 - "change_type": "feature", 152 - "title": "Add Dedicated XML Response Parsing Support", 153 - "description": "Implement dedicated XML parsing support with delegate-based streaming parser integration, similar to JSON support. The Swift Net library's ResponseData.parseXml(delegate:) method integrates with NSXMLParser, allowing streaming XML processing with user-provided delegate callbacks.", 154 - "affected_files": [ 155 - "lib/response.ml", 156 - "lib/response.mli" 157 - ], 158 - "rationale": "The OCaml library has excellent JSON support via Response.json but lacks equivalent XML parsing. Many APIs (SOAP, RSS, Atom, AWS S3, etc.) return XML responses. Adding XML support would: (1) Reduce boilerplate for XML API consumers, (2) Provide consistent error handling (Error.Xml_parse_error), (3) Enable streaming XML parsing for large documents, (4) Improve ergonomics for common use cases. Recommend adding: (1) Response.xml that returns parsed XML tree (using xmlm or markup.ml), (2) Response.xml_stream for streaming SAX-style parsing, (3) Response.xml_exn for status-validated parsing, (4) Support for common XML formats (RSS via syndic, Atom, etc.). Implementation should: (1) Add xmlm dependency for parsing, (2) Handle encoding detection from Content-Type charset, (3) Provide helpful error messages with line/column info, (4) Consider lazy parsing to avoid loading entire document. This is medium priority as XML is still widely used in enterprise/legacy systems." 159 - }, 160 - { 161 - "source_repo": "third_party/swift/net", 162 - "source_language": "Swift", 163 - "criticality": "low", 164 - "change_type": "enhancement", 165 - "title": "Add Image Response Helper with Format Detection", 166 - "description": "Implement dedicated image response handling with automatic format detection and validation. The Swift Net library provides ResponseData.image() method that converts response data to UIImage, with automatic format support for PNG, JPEG, and other iOS image formats.", 167 - "affected_files": [ 168 - "lib/response.ml", 169 - "lib/response.mli", 170 - "lib/mime.ml" 171 - ], 172 - "rationale": "While the OCaml library can download binary data, it lacks image-specific helpers. Adding image utilities would help applications that work with image APIs: (1) Validate image format matches Content-Type, (2) Extract image metadata (dimensions, format, color space) without full parsing, (3) Detect corrupted images early, (4) Provide type-safe image response handling. This is less critical for server applications but useful for CLI tools, scrapers, and image processing pipelines. Recommend adding: (1) Response.image_info that returns format/dimensions using ImageMagick bindings or image-parsing libraries, (2) Response.validate_image that checks magic bytes match Content-Type, (3) Image format detection utilities in Mime module. Implementation could use: (1) camlimages for format detection, (2) magic byte matching for quick validation (PNG: 89 50 4E 47, JPEG: FF D8 FF), (3) Integration with image processing libraries. This is lower priority as it's domain-specific, but valuable for multimedia applications." 173 - }, 174 - { 175 - "source_repo": "third_party/swift/net", 176 - "source_language": "Swift", 177 - "criticality": "medium", 178 - "change_type": "enhancement", 179 - "title": "Add Redirect Interception Callbacks", 180 - "description": "Implement optional callback hooks that allow users to intercept and customize redirect handling before the redirect is followed. The Swift Net library's willPerformHTTPRedirection delegate method enables inspection and modification of redirect requests before they execute.", 181 - "affected_files": [ 182 - "lib/requests.ml", 183 - "lib/requests.mli", 184 - "lib/http_client.ml" 185 - ], 186 - "rationale": "The OCaml library automatically follows redirects up to max_redirects but doesn't expose hooks for redirect interception. Adding redirect callbacks would enable: (1) Custom redirect validation (e.g., reject cross-origin redirects for security), (2) Redirect logging and metrics, (3) Modifying redirect requests (update headers, change method), (4) Conditional redirect following based on URL patterns. This is valuable for: (1) Security-conscious applications that need to validate redirect targets, (2) Analytics and monitoring (tracking redirect chains), (3) Complex authentication flows that redirect to different domains. Recommend adding: (1) `?on_redirect:(from:string -> to:string -> Headers.t -> bool)` callback that returns whether to follow, (2) `?transform_redirect:(Request.t -> Request.t)` to modify redirect requests, (3) Recording full redirect chain in Response metadata. Implementation: (1) Add redirect callback to Http_client.request, (2) Invoke callback before following each redirect, (3) Respect callback return value (true=follow, false=stop and return 3xx response), (4) Include redirect chain in Response.url_chain field." 187 - }, 188 - { 189 - "source_repo": "third_party/swift/net", 190 - "source_language": "Swift", 191 - "criticality": "low", 192 - "change_type": "feature", 193 - "title": "Add Session Task Counting and Management Utilities", 194 - "description": "Implement utility functions to query the number of active download, upload, and total tasks in a session. The Swift Net library extends NSURLSession with convenience methods getDownloadingTasksCount, getUploadingTaskCount, and getTransferingTaskCount for monitoring active operations.", 195 - "affected_files": [ 196 - "lib/requests.ml", 197 - "lib/requests.mli" 198 - ], 199 - "rationale": "The OCaml library lacks visibility into active operations within a session. Adding task counting utilities would enable: (1) Rate limiting concurrent requests per session, (2) Monitoring and metrics for active transfers, (3) Graceful shutdown that waits for completion, (4) Health checks and diagnostics. Recommend adding: (1) Requests.active_request_count : t -> int for total active requests, (2) Requests.active_downloads : t -> int for download operations, (3) Requests.active_uploads : t -> int for upload operations, (4) Requests.list_active_requests : t -> (string * float) list returning URLs and elapsed time. Implementation: (1) Maintain weak reference map of active requests in session state, (2) Update on request start/completion, (3) Clean up completed requests periodically, (4) Expose via accessor functions. This is useful for: (1) Implementing max concurrent request limits, (2) Dashboard/monitoring UIs, (3) Debugging connection pool issues, (4) Resource management in long-lived applications." 200 - }, 201 - { 202 - "source_repo": "third_party/swift/net", 203 - "source_language": "Swift", 204 - "criticality": "medium", 205 - "change_type": "enhancement", 206 - "title": "Add Support for Query Parameter Arrays and Nested Objects", 207 - "description": "Implement automatic encoding of complex query parameter types including arrays and nested dictionaries following common conventions. The Swift Net library's NetHelper.convertParamsToArray recursively flattens arrays (as key[]) and nested objects (as key[nestedKey]) for URL encoding.", 208 - "affected_files": [ 209 - "lib/requests.ml", 210 - "lib/requests.mli", 211 - "lib/http_write.ml" 212 - ], 213 - "rationale": "The OCaml library accepts query parameters as (string * string) list, requiring manual serialization of arrays and objects. Many APIs expect array/object parameters in specific formats: (1) Arrays: ?tag[]=a&tag[]=b (Rails) or ?tag=a&tag=b (repeating), (2) Objects: ?filter[status]=active&filter[type]=public. Adding automatic encoding would: (1) Reduce boilerplate for complex API calls, (2) Support multiple array/object encoding styles, (3) Improve ergonomics for REST APIs. Recommend adding: (1) Type-safe parameter builder: `type param_value = String of string | Array of string list | Object of (string * param_value) list`, (2) Encoding style parameter: `?array_style:[`Brackets | `Repeat | `Comma]`, (3) Convenience functions: Params.array, Params.object, (4) Integration with existing ~params argument. Example API: `Requests.get req url ~params:(Params.make [\"tags\", Array [\"ocaml\"; \"http\"]; \"filter\", Object [(\"status\", String \"active\")]])`. This improves compatibility with modern REST APIs that expect structured parameters." 214 - }, 215 - { 216 - "source_repo": "third_party/swift/net", 217 - "source_language": "Swift", 218 - "criticality": "high", 219 - "change_type": "feature", 220 - "title": "Add Resumable Download Support with Resume Data", 221 - "description": "Implement resumable download capability that saves resume data (ETag, byte ranges, partial content) to allow restarting interrupted downloads from the last checkpoint. The Swift Net library's DownloadTask.cancel(byProducingResumeData:) captures resume data for later use with downloadTaskWithResumeData, supporting HTTP 206 Partial Content requests.", 222 - "affected_files": [ 223 - "lib/one.ml", 224 - "lib/one.mli", 225 - "lib/response.ml", 226 - "lib/http_client.ml" 227 - ], 228 - "rationale": "Large file downloads over unreliable networks frequently fail midway, forcing re-download from scratch. Resumable downloads improve: (1) User experience for large downloads (videos, datasets, disk images), (2) Bandwidth efficiency by reusing partial downloads, (3) Success rates on unstable connections, (4) Mobile/satellite link reliability. This is critical for CLI tools and applications dealing with large files. Implementation requires: (1) Saving ETag and Last-Modified from initial response, (2) Storing bytes already downloaded and their checksum, (3) Using HTTP Range header (Range: bytes=X-) on resume, (4) Validating server returns 206 Partial Content, (5) Verifying ETag matches to ensure content unchanged, (6) Appending new bytes to existing file. Recommend adding: (1) One.download_resumable that accepts `?resume_from:Path.t option` with metadata, (2) Resume metadata format: JSON with {url, etag, last_modified, bytes_downloaded, partial_file_path}, (3) Automatic validation that server supports resuming (Accept-Ranges: bytes), (4) Fallback to full download if resume fails. This is high-value for production applications." 229 - }, 230 - { 231 - "source_repo": "third_party/swift/net", 232 - "source_language": "Swift", 233 - "criticality": "low", 234 - "change_type": "enhancement", 235 - "title": "Add Support for Custom Accept Headers with Multiple MIME Types", 236 - "description": "Implement automatic Accept header construction with multiple MIME types to support content negotiation. The Swift Net library sets a default Accept header to 'application/json,application/xml,image/png,image/jpeg', enabling servers to choose the best response format.", 237 - "affected_files": [ 238 - "lib/requests.ml", 239 - "lib/requests.mli", 240 - "lib/headers.ml", 241 - "lib/headers.mli" 242 - ], 243 - "rationale": "Content negotiation via Accept headers is important for APIs that support multiple response formats. The OCaml library allows setting arbitrary headers but lacks convenience functions for Accept header construction with quality values (q-factors). Adding helpers would: (1) Improve content negotiation ergonomics, (2) Support RFC 7231 quality values, (3) Enable format fallback chains, (4) Reduce header construction boilerplate. Recommend adding: (1) Headers.accept : Mime.t list -> Headers.t that builds Accept header, (2) Headers.accept_with_quality : (Mime.t * float) list -> Headers.t for q-values (e.g., [(Mime.json, 1.0); (Mime.xml, 0.8)]), (3) Smart defaults like Headers.accept_any, Headers.accept_json_or_xml, (4) Proper formatting: 'application/json; q=1.0, text/html; q=0.8'. Example: `~headers:(Headers.accept_with_quality [(Mime.json, 1.0); (Mime.xml, 0.5)])` generates 'Accept: application/json, application/xml; q=0.5'. This improves API compatibility and developer experience." 244 - } 245 - ] 246 - }
-262
third_party/swift/swifthttp.json
··· 1 - { 2 - "recommendations": [ 3 - { 4 - "source_repo": "third_party/swift/swifthttp", 5 - "source_language": "Swift", 6 - "criticality": "high", 7 - "change_type": "security", 8 - "title": "Add Certificate and Public Key Pinning Support", 9 - "description": "SwiftHTTP implements comprehensive SSL/TLS pinning with both certificate pinning and public key pinning modes. This allows applications to prevent man-in-the-middle attacks even with compromised CAs. The implementation includes: certificate chain extraction, public key extraction from certificates, trust policy configuration, domain validation control, and async key processing. This is a critical security feature missing from the OCaml library.", 10 - "affected_files": [ 11 - "lib/requests.ml", 12 - "lib/one.ml", 13 - "lib/http_client.ml" 14 - ], 15 - "rationale": "Certificate pinning is essential for high-security applications (banking, healthcare, enterprise) to prevent MITM attacks through compromised certificate authorities. The OCaml library currently only supports standard CA-based TLS verification with minimum version enforcement, but lacks pinning capabilities. Adding this would enable applications to pin specific certificates or public keys for critical endpoints. SwiftHTTP's implementation shows this can be done with: 1) Loading certificates from bundle/files as Data, 2) Extracting public keys from certificates, 3) Comparing server cert chain against pinned certs/keys, 4) Optional domain name validation. Implementation would use the existing tls-eio library and add certificate comparison logic." 16 - }, 17 - { 18 - "source_repo": "third_party/swift/swifthttp", 19 - "source_language": "Swift", 20 - "criticality": "medium", 21 - "change_type": "feature", 22 - "title": "Add Global Request/Response Interceptor Hooks", 23 - "description": "SwiftHTTP provides global configuration hooks via HTTP.globalRequest(), HTTP.globalAuth(), and HTTP.globalSecurity(). The globalRequest() hook allows modifying every URLRequest before it's sent (e.g., adding headers, setting timeouts uniformly). This middleware-style pattern enables cross-cutting concerns like logging, metrics, header injection, and debugging without modifying application code.", 24 - "affected_files": [ 25 - "lib/requests.ml", 26 - "lib/one.ml" 27 - ], 28 - "rationale": "Global interceptors provide a clean way to implement cross-cutting concerns: 1) Request logging/debugging - automatically log all outgoing requests, 2) Metric collection - track request counts, timing, sizes, 3) Header injection - add API version, correlation IDs, tracing headers, 4) Testing/mocking - intercept and modify requests for testing. Currently, the OCaml library requires users to manually apply such modifications to every request or wrap the session. Adding optional hooks like `~on_request:(Request.t -> Request.t)` and `~on_response:(Response.t -> Response.t)` to the session configuration would enable this pattern cleanly. SwiftHTTP's implementation uses a closure stored in the DelegateManager that's invoked before every request." 29 - }, 30 - { 31 - "source_repo": "third_party/swift/swifthttp", 32 - "source_language": "Swift", 33 - "criticality": "medium", 34 - "change_type": "feature", 35 - "title": "Add Concurrent Request Queue with Configurable Limits", 36 - "description": "SwiftHTTP implements an HTTPQueue class that manages concurrent request execution with configurable maxSimultaneousRequest limit. It provides: FIFO queue management, automatic request dequeuing as slots free up, mutex-protected thread safety, completion notification when all requests finish, and ability to add requests dynamically. This enables controlled parallelism and prevents resource exhaustion.", 37 - "affected_files": [ 38 - "lib/requests.ml" 39 - ], 40 - "rationale": "While the OCaml library supports concurrent requests via Eio.Fiber.all, it lacks built-in concurrency limiting per-session. This can lead to resource exhaustion when making many requests (e.g., scraping, batch API calls). A queue-based approach provides: 1) Resource control - prevent opening too many connections simultaneously, 2) Backpressure - queue requests when at limit, 3) Priority handling - process high-priority requests first, 4) Batch completion - notify when all queued requests complete. Implementation could use Eio.Stream for the queue with a semaphore to limit concurrent execution. SwiftHTTP's approach uses NSLock for thread safety and maintains active request tracking, which maps well to Eio's structured concurrency with fibers and mutexes." 41 - }, 42 - { 43 - "source_repo": "third_party/swift/swifthttp", 44 - "source_language": "Swift", 45 - "criticality": "low", 46 - "change_type": "enhancement", 47 - "title": "Enhance Progress Callbacks with Granular Reporting", 48 - "description": "SwiftHTTP provides detailed progress tracking for both uploads and downloads through progressHandler callbacks. The progress is reported as a float between 0.0 and 1.0, calculated from expectedContentLength and current bytes transferred. Progress is updated incrementally as data is received/sent, enabling real-time UI updates. The implementation tracks both upload progress (didSendBodyData) and download progress (didWriteData) separately.", 49 - "affected_files": [ 50 - "lib/one.ml", 51 - "lib/requests.ml", 52 - "lib/response.ml" 53 - ], 54 - "rationale": "Progress callbacks are essential for user-facing applications that download/upload large files. The OCaml library has basic on_progress support in the One module for streaming, but it's not exposed in the main Requests API and lacks standardization. Users need progress for: 1) UI progress bars/indicators, 2) Download/upload status monitoring, 3) Timeout detection for stalled transfers, 4) Bandwidth estimation. Enhancement should: 1) Add optional ~on_progress:(float -> unit) parameter to request methods, 2) Calculate progress as (bytes_transferred / content_length) when Content-Length is known, 3) Report indeterminate progress when length is unknown, 4) Support both upload and download progress separately. SwiftHTTP's implementation shows this integrates cleanly with URLSession delegates, which maps to Eio.Flow reading/writing callbacks." 55 - }, 56 - { 57 - "source_repo": "third_party/swift/swifthttp", 58 - "source_language": "Swift", 59 - "criticality": "low", 60 - "change_type": "enhancement", 61 - "title": "Add Suggested Filename Extraction from Response", 62 - "description": "SwiftHTTP extracts and exposes the suggestedFilename from HTTPURLResponse, which comes from Content-Disposition header's filename parameter or URL path. This is available in the Response object and useful for file downloads where the server suggests a filename. SwiftHTTP also provides downloadHandler callback that receives both the Response and temporary file URL, making it easy to move/rename downloaded files.", 63 - "affected_files": [ 64 - "lib/response.ml", 65 - "lib/headers.ml" 66 - ], 67 - "rationale": "When downloading files, servers often suggest filenames via Content-Disposition header (RFC 6266). Example: 'Content-Disposition: attachment; filename=\"report.pdf\"'. The OCaml library doesn't currently parse or expose this, forcing users to manually parse the header or use URL-based naming. Adding Response.suggested_filename() would: 1) Parse Content-Disposition filename/filename* parameters, 2) Handle RFC 2231 encoding for international filenames, 3) Fall back to URL path basename if no header, 4) Sanitize filename to prevent directory traversal. This is a convenience feature that improves download ergonomics. SwiftHTTP gets this from URLResponse, but OCaml would need to implement the Content-Disposition parser." 68 - }, 69 - { 70 - "source_repo": "third_party/swift/swifthttp", 71 - "source_language": "Swift", 72 - "criticality": "medium", 73 - "change_type": "enhancement", 74 - "title": "Add Automatic HTTP Error Creation for 4xx/5xx Status Codes", 75 - "description": "SwiftHTTP automatically creates an NSError when the status code is > 299 (line 396-398 in Operation.swift). The error includes: HTTP domain, status code as error code, and localized description from HTTPStatusCode enum. This makes error handling more consistent - network errors and HTTP errors both appear as errors in the response. Users can check response.error for any failure rather than separately checking status codes.", 76 - "affected_files": [ 77 - "lib/response.ml", 78 - "lib/error.ml", 79 - "lib/requests.ml" 80 - ], 81 - "rationale": "Currently, the OCaml library treats HTTP 4xx/5xx responses as successful at the transport level - users must explicitly call Response.raise_for_status() or check Response.ok(). This leads to two patterns: 1) Check-based: if not (Response.ok r) then handle_error, 2) Exception-based: Response.raise_for_status r. SwiftHTTP's approach unifies this - all errors (network, timeout, HTTP 4xx/5xx) set response.error. While the OCaml library's current behavior is more flexible (some applications want to handle 404 differently than network errors), adding an optional ~error_on_status:bool (default false for backward compatibility) parameter would enable automatic error raising for 4xx/5xx when desired. This reduces boilerplate in applications where any non-2xx is an error. The error would be Error.Http_error with full context." 82 - }, 83 - { 84 - "source_repo": "third_party/swift/swifthttp", 85 - "source_language": "Swift", 86 - "criticality": "low", 87 - "change_type": "enhancement", 88 - "title": "Add Response.text Property for Convenient String Access", 89 - "description": "SwiftHTTP provides a Response.text computed property that automatically converts response.data to a UTF-8 string (line 69-71). This is a convenience accessor that returns String? (nil if not valid UTF-8). Users can access response data as either raw Data via response.data or as String via response.text without manual conversion.", 90 - "affected_files": [ 91 - "lib/response.ml" 92 - ], 93 - "rationale": "The OCaml library currently provides Response.body (streaming source) and Response.text() (reads full body as string). The text() method is already close to SwiftHTTP's approach, but it requires explicit calling and doesn't cache the result. Enhancement: 1) Keep current behavior for backward compatibility, 2) Consider adding cached text access to avoid re-reading body, 3) Ensure UTF-8 validation and return Result.t or option for encoding errors. Actually reviewing the OCaml code shows Response.text() already exists and works well - this is already implemented. However, SwiftHTTP's pattern of having both .data (raw) and .text (decoded) properties side-by-side is good ergonomics. The OCaml library could document this dual access pattern more prominently." 94 - }, 95 - { 96 - "source_repo": "third_party/swift/swifthttp", 97 - "source_language": "Swift", 98 - "criticality": "low", 99 - "change_type": "enhancement", 100 - "title": "Add Response.description for Detailed Debugging Output", 101 - "description": "SwiftHTTP implements a Response.description property (lines 73-92) that produces formatted, human-readable debug output including: URL, status code, headers (all key-value pairs), and payload preview. This is invaluable for debugging as it provides a complete view of the response in a readable format. Users can print response.description to see everything at once.", 102 - "affected_files": [ 103 - "lib/response.ml" 104 - ], 105 - "rationale": "The OCaml library has Response.pp and Response.pp_detailed for pretty-printing (which is excellent), but reviewing the code shows this functionality largely exists. However, comparing with SwiftHTTP: 1) SwiftHTTP always includes URL in output (OCaml may not show final URL after redirects prominently), 2) SwiftHTTP shows ALL headers in description (useful for debugging), 3) Format is optimized for readability. Enhancement: Ensure Response.pp_detailed includes: final URL (after redirects), ALL headers formatted nicely, status code with reason phrase, body preview (truncated if large), elapsed time. Review existing pp_detailed implementation to ensure it matches or exceeds SwiftHTTP's debug output utility." 106 - }, 107 - { 108 - "source_repo": "third_party/swift/swifthttp", 109 - "source_language": "Swift", 110 - "criticality": "medium", 111 - "change_type": "feature", 112 - "title": "Add Support for Ephemeral Sessions (No Caching/Cookies)", 113 - "description": "SwiftHTTP provides SharedSession.ephemeralSession alongside defaultSession (lines 485-486). Ephemeral sessions use URLSessionConfiguration.ephemeral which: disables disk caching, disables cookie storage, uses only in-memory storage, provides better privacy. This is useful for sensitive operations (banking, incognito mode) where persistence is undesirable.", 114 - "affected_files": [ 115 - "lib/requests.ml" 116 - ], 117 - "rationale": "The OCaml library supports persist_cookies flag and has auto_decompress, but doesn't have a dedicated 'ephemeral mode' that ensures no data touches disk. Adding Requests.create_ephemeral() or ~ephemeral:bool flag would: 1) Disable cookie persistence (use in-memory jar only), 2) Disable any response caching when implemented, 3) Document privacy guarantees. Currently users can achieve this with persist_cookies=false, but an explicit ephemeral mode makes the intent clear and ensures future caching features respect it. SwiftHTTP's URLSessionConfiguration.ephemeral provides the model - it's a bundled configuration for privacy-conscious operations." 118 - }, 119 - { 120 - "source_repo": "third_party/swift/swifthttp", 121 - "source_language": "Swift", 122 - "criticality": "low", 123 - "change_type": "enhancement", 124 - "title": "Add Request Method Enum with CONNECT, TRACE, OPTIONS Support", 125 - "description": "SwiftHTTP defines HTTPVerb enum with all standard HTTP methods including CONNECT, TRACE, OPTIONS, and UNKNOWN (lines 38-49 in Request.swift). While CONNECT and TRACE are rarely used in client libraries, OPTIONS is valuable for CORS preflight and API capability discovery. The UNKNOWN variant handles unexpected method strings gracefully.", 126 - "affected_files": [ 127 - "lib/method.ml", 128 - "lib/requests.ml" 129 - ], 130 - "rationale": "The OCaml library's Method module likely supports standard methods (GET, POST, PUT, DELETE, HEAD, PATCH), but checking common patterns: OPTIONS is useful for: 1) CORS preflight requests, 2) API capability discovery (e.g., OPTIONS * HTTP/1.1), 3) WebDAV operations. TRACE is rarely used but part of HTTP spec. CONNECT is for proxy tunneling (not typically used in client libraries but needed for HTTP proxy support when implemented). Enhancement: Ensure Method.t supports all standard HTTP methods including OPTIONS. Add convenience Requests.options() method if missing. CONNECT and TRACE can wait until proxy support is added. SwiftHTTP's inclusion of all methods shows commitment to HTTP spec completeness." 131 - }, 132 - { 133 - "source_repo": "third_party/swift/swifthttp", 134 - "source_language": "Swift", 135 - "criticality": "low", 136 - "change_type": "enhancement", 137 - "title": "Add Configurable Empty Array Serialization for Form Parameters", 138 - "description": "SwiftHTTP provides HTTPParameterProtocolSettings.sendEmptyArray global flag (lines 100-102) to control whether empty arrays in parameters should serialize as '[]' or be omitted entirely. This handles an edge case in form encoding where different APIs expect different behavior for empty arrays.", 139 - "affected_files": [ 140 - "lib/body.ml" 141 - ], 142 - "rationale": "When serializing form data with arrays (e.g., {items: []}), there are two valid approaches: 1) Omit the parameter entirely (most common), 2) Send 'items[]' (or 'items=[]) to indicate empty array explicitly. Different APIs have different expectations. SwiftHTTP defaults to omitting but allows global configuration. The OCaml library's Body.form() likely handles this, but should verify behavior and potentially add configuration. This is a low-priority edge case but important for API compatibility. Enhancement: Document current behavior for empty arrays in form encoding, add optional configuration if not present. Most APIs prefer omission, so that should be default." 143 - }, 144 - { 145 - "source_repo": "third_party/swift/swifthttp", 146 - "source_language": "Swift", 147 - "criticality": "low", 148 - "change_type": "enhancement", 149 - "title": "Add Automatic MIME Type Detection from File Extensions", 150 - "description": "SwiftHTTP's Upload class automatically detects MIME types from file extensions (Upload.swift lines 29-87 map extensions to MIME types). While basic, this provides reasonable defaults for common file types (images, documents, etc.) when the MIME type isn't explicitly provided. This is used in multipart form uploads.", 151 - "affected_files": [ 152 - "lib/body.ml", 153 - "lib/mime.ml" 154 - ], 155 - "rationale": "The OCaml library has a Mime module and likely some MIME detection for file uploads, but the TODO comments mention 'MIME type guessing could [be improved]' (from repository analysis). Enhancement: Expand Mime module with comprehensive extension-to-MIME-type mapping for common types: images (jpg, png, gif, svg, webp), documents (pdf, doc, docx, xls, xlsx), media (mp4, mp3, avi), archives (zip, tar, gz), code (json, xml, js, css, html). Use this in Body.of_file() when MIME type isn't explicitly provided. SwiftHTTP's approach of having a large switch statement with common types is simple and effective. Could also use mime-db or similar comprehensive database." 156 - }, 157 - { 158 - "source_repo": "third_party/swift/swifthttp", 159 - "source_language": "Swift", 160 - "criticality": "medium", 161 - "change_type": "enhancement", 162 - "title": "Add JSON Serializer Alternative to Form Encoding", 163 - "description": "SwiftHTTP provides two serialization strategies via HTTPSerializeProtocol: HTTPParameterSerializer (form encoding) and JSONParameterSerializer (JSON body). Users can choose via requestSerializer parameter (lines 31-45 in Operation.swift). The JSON serializer automatically sets Content-Type: application/json and serializes the parameter dictionary as JSON body instead of form encoding.", 164 - "affected_files": [ 165 - "lib/body.ml", 166 - "lib/requests.ml" 167 - ], 168 - "rationale": "The OCaml library supports JSON via Body.json(yojson_value) and form encoding via Body.form(pairs). This is actually more flexible than SwiftHTTP since it accepts structured Yojson values rather than just dictionaries. However, SwiftHTTP's pattern of accepting the same parameter type and choosing serialization strategy is more ergonomic for simple cases. Enhancement: Consider adding convenience functions like Requests.post_json() that accepts an association list and automatically converts to JSON, similar to how SwiftHTTP does. Currently users must: 1) Convert data to Yojson, 2) Call Body.json(), 3) Pass to post(). A shortcut like post_json url ~data:[\"key\", `String \"value\"] would match SwiftHTTP's ergonomics while preserving the existing powerful API." 169 - }, 170 - { 171 - "source_repo": "third_party/swift/swifthttp", 172 - "source_language": "Swift", 173 - "criticality": "low", 174 - "change_type": "enhancement", 175 - "title": "Add Nested Dictionary/Array Parameter Serialization", 176 - "description": "SwiftHTTP implements recursive serialization of nested dictionaries and arrays in HTTP parameters (Request.swift lines 115-128 for dictionaries, 136-150 for arrays). It creates bracket notation like 'user[name]=John&user[age]=30' for nested structures. This is standard in many web frameworks (Rails, Laravel, etc.) and enables complex data structures in form/query parameters.", 177 - "affected_files": [ 178 - "lib/body.ml" 179 - ], 180 - "rationale": "Complex API requests often need nested parameters. For example, filtering: filter[status]=active&filter[category]=news. The OCaml library's Body.form() accepts (string * string) list which is flat. Enhancement: Support nested parameter encoding via: 1) Accept nested structure type (e.g., Yojson or custom tree), 2) Serialize with bracket notation: dict[\"user\"][\"name\"] becomes user[name]=value, arrays become field[]=value1&field[]=value2, 3) Follow common conventions (Rails, PHP, etc.). SwiftHTTP's recursive createPairs() approach is elegant - traverse structure depth-first, accumulating key path with brackets. This is a nice-to-have feature that improves ergonomics for complex APIs, though users can currently flatten manually." 181 - }, 182 - { 183 - "source_repo": "third_party/swift/swifthttp", 184 - "source_language": "Swift", 185 - "criticality": "low", 186 - "change_type": "refactor", 187 - "title": "Add Request.description Property for Debugging", 188 - "description": "While not explicitly shown in the SwiftHTTP code reviewed, the library's emphasis on debugging (Response.description) suggests that having similar debug output for requests would be valuable. This would show: method, URL, headers, body preview, timeout settings, etc. in a readable format before sending.", 189 - "affected_files": [ 190 - "lib/requests.ml", 191 - "lib/one.ml" 192 - ], 193 - "rationale": "Debugging HTTP issues often requires seeing exactly what request is being sent. Currently, the OCaml library has excellent logging via Logs, but doesn't provide a user-accessible pretty-printed request representation. Enhancement: Add function to format a request for debugging: Request.to_string() or Request.pp. Include: HTTP method and URL, all headers (sanitized for sensitive values), body preview (first 200 chars, marked if truncated), timeout configuration, redirect settings. This would be useful for logging, debugging, and test output. SwiftHTTP's Response.description pattern shows the value of formatted debug output, and the same applies to requests." 194 - }, 195 - { 196 - "source_repo": "third_party/swift/swifthttp", 197 - "source_language": "Swift", 198 - "criticality": "medium", 199 - "change_type": "feature", 200 - "title": "Add Download-Specific Functionality with Temporary File Handling", 201 - "description": "SwiftHTTP provides HTTP.Download() class method (lines 264-269) that handles file downloads specially: creates a downloadTask instead of dataTask, provides downloadHandler callback with temporary file URL, allows user to move/process file before it's deleted. This is more efficient than loading entire file into memory for large downloads.", 202 - "affected_files": [ 203 - "lib/requests.ml", 204 - "lib/one.ml", 205 - "lib/response.ml" 206 - ], 207 - "rationale": "Large file downloads (>100MB) shouldn't be loaded entirely into memory. SwiftHTTP's approach: 1) Download to temporary file, 2) Invoke callback with file path, 3) User moves/processes file, 4) Delete temp file. The OCaml library supports streaming via Response.body (Eio.Flow), which is actually more flexible than SwiftHTTP's approach. However, adding convenience functions would help: Requests.download url ~dest_path:\"file.zip\" that: 1) Streams to destination file incrementally, 2) Verifies Content-Length if provided, 3) Reports progress via optional callback, 4) Handles partial resume with Range headers (future enhancement). The current library can do this but requires users to write streaming logic. Enhancement: Add Requests.download() convenience function that handles the common case of streaming response to file." 208 - }, 209 - { 210 - "source_repo": "third_party/swift/swifthttp", 211 - "source_language": "Swift", 212 - "criticality": "high", 213 - "change_type": "security", 214 - "title": "Add Authentication Challenge-Response Mechanism", 215 - "description": "SwiftHTTP implements flexible authentication via challenge-response callbacks (Operation.swift lines 406-438). When a server sends an authentication challenge, the auth callback is invoked with URLAuthenticationChallenge. The callback can: return URLCredential to attempt authentication, return nil to reject/cancel. This enables: Basic auth, Digest auth, client certificates, custom auth schemes, automatic retry on 401 with credentials. The library supports both per-request and global auth handlers.", 216 - "affected_files": [ 217 - "lib/auth.ml", 218 - "lib/requests.ml", 219 - "lib/one.ml" 220 - ], 221 - "rationale": "The OCaml library implements Digest authentication with automatic 401 challenge handling (auth.ml shows parse_www_authenticate and compute_digest_response). This is good, but SwiftHTTP's pattern of exposing the challenge to user code via callback is more flexible. Enhancement: While keeping the current automatic Digest auth (which is excellent), consider adding optional auth_handler callback that's invoked on 401/407 responses: 1) Pass response headers to handler, 2) Handler returns new credentials or raises exception, 3) Automatically retry request with new auth. This enables: custom auth schemes, conditional auth (prompt user for password), auth token refresh, certificate selection. SwiftHTTP's per-request and global handlers provide flexibility. The OCaml library's current approach is more automated (good default), but exposing hooks enables advanced use cases." 222 - }, 223 - { 224 - "source_repo": "third_party/swift/swifthttp", 225 - "source_language": "Swift", 226 - "criticality": "medium", 227 - "change_type": "enhancement", 228 - "title": "Add Cache Policy Configuration for Requests", 229 - "description": "SwiftHTTP's URLRequest.init allows specifying cachePolicy parameter (Request.swift line 172): .useProtocolCachePolicy, .reloadIgnoringLocalCacheData, .returnCacheDataElseLoad, etc. This controls how requests interact with the HTTP cache (when cache is implemented). While the OCaml library doesn't have caching yet, having the API hooks in place prepares for future implementation.", 230 - "affected_files": [ 231 - "lib/requests.ml", 232 - "lib/cache_control.ml" 233 - ], 234 - "rationale": "The OCaml library has excellent Cache_control module for parsing Cache-Control headers (RFC 9111) but no actual caching layer (per CACHEIO.md reference in comments). When caching is implemented, it will need request-level policy control: 1) Use cache if valid (default HTTP caching), 2) Bypass cache (force fresh request), 3) Prefer cache even if stale, 4) Only use cache (fail if not cached). SwiftHTTP's cachePolicy enum provides the model. Enhancement: Add cache_policy type to Requests module: type cache_policy = Protocol_default | Ignore_cache | Cache_only | Prefer_fresh. Include in request configuration even if not yet implemented, so API is stable when caching is added. The Cache_control module shows the groundwork is laid, just needs the request-side policy and storage layer." 235 - }, 236 - { 237 - "source_repo": "third_party/swift/swifthttp", 238 - "source_language": "Swift", 239 - "criticality": "low", 240 - "change_type": "enhancement", 241 - "title": "Add Response MIME Type Accessor", 242 - "description": "SwiftHTTP exposes response.mimeType as a direct property (Operation.swift line 55, set from HTTPURLResponse.mimeType at line 391). This extracts just the MIME type from Content-Type header (without charset parameter). It's a convenience accessor that's cleaner than parsing Content-Type manually.", 243 - "affected_files": [ 244 - "lib/response.ml" 245 - ], 246 - "rationale": "The OCaml library has Response.content_type() that returns Option.t Mime.t (parsing the full Content-Type header). This is actually more sophisticated than SwiftHTTP since it uses the Mime module. However, for ergonomics, verify that: 1) Mime.t has easy accessor for just the type/subtype without parameters, 2) Common types (JSON, HTML, XML, etc.) are easy to match against. Looking at the code, Response.content_type() returns Option.t Mime.t which is perfect. Enhancement: Document common patterns for matching MIME types. Potentially add Response.is_json(), Response.is_html(), Response.is_xml() convenience functions for common checks. SwiftHTTP's direct mimeType property is convenient, and the OCaml equivalent would be these type-checking helpers." 247 - }, 248 - { 249 - "source_repo": "third_party/swift/swifthttp", 250 - "source_language": "Swift", 251 - "criticality": "low", 252 - "change_type": "enhancement", 253 - "title": "Add Task Cancellation Support", 254 - "description": "SwiftHTTP provides HTTP.cancel() method (lines 207-209) to cancel in-flight requests. This is essential for: user cancellation (e.g., closing a screen), timeout enforcement, racing requests (cancel losers), cleanup during shutdown. The cancellation propagates to the URLSessionTask and triggers completion with cancellation error.", 255 - "affected_files": [ 256 - "lib/requests.ml", 257 - "lib/one.ml" 258 - ], 259 - "rationale": "Eio has excellent cancellation support via Switch and fiber cancellation. The OCaml library likely supports cancellation through Eio's standard mechanisms. Enhancement: Document cancellation patterns clearly: 1) Cancel via switch: Eio.Switch.fail switches cancels all operations, 2) Timeout cancellation: Eio.Time.with_timeout, 3) Explicit cancellation: Eio.Cancel. Also consider exposing a cancel() function on response or session for API ergonomics. SwiftHTTP's explicit .cancel() is user-friendly, and documenting the Eio equivalent prominently would help users. The underlying capability exists via Eio, but making it discoverable is important." 260 - } 261 - ] 262 - }