Skip to content

Conversation

@bug-ops
Copy link
Owner

@bug-ops bug-ops commented Dec 15, 2025

Summary

This PR implements Phase 5.1 of the feedparser-rs roadmap:

HTTP Bindings

  • Python: parse_url() and parse_url_with_limits() functions for fetching feeds via HTTP
  • Node.js: parseUrl() and parseUrlWithOptions() functions for fetching feeds via HTTP
  • Conditional GET support with ETag and Last-Modified headers for efficient polling
  • HTTP metadata exposed on ParsedFeed: status, href, etag, modified, headers
  • SSRF protection inherited from core HTTP client (blocks localhost, private IPs, metadata endpoints)
  • Feature flag http (enabled by default) for conditional compilation

Podcast 2.0 Support

  • Added podcast_transcripts and podcast_persons fields to Entry struct
  • Parses <podcast:transcript> elements with attributes: url, type, language, rel
  • Parses <podcast:person> elements with attributes: name (text), role, group, img, href
  • Full binding support in both Python and Node.js

iTunes Improvements

  • Fixed subcategory parsing with proper nested category handling
  • Correctly handles both flat and hierarchically nested <itunes:category> structures

Changes

File Changes
feedparser-rs-py/Cargo.toml Added http feature flag
feedparser-rs-py/src/lib.rs Added parse_url(), parse_url_with_limits()
feedparser-rs-py/src/types/parsed_feed.rs Added HTTP metadata fields
feedparser-rs-py/src/types/entry.rs Added podcast getters
feedparser-rs-node/Cargo.toml Added http feature flag
feedparser-rs-node/src/lib.rs Added parseUrl(), parseUrlWithOptions(), podcast types
feedparser-rs-core/src/types/entry.rs Added podcast_transcripts, podcast_persons
feedparser-rs-core/src/parser/rss.rs Parse podcast:transcript, podcast:person, iTunes subcategories

Test plan

  • All 315 existing tests pass
  • Zero clippy warnings
  • Code formatted with nightly rustfmt
  • Manual testing with real podcast feeds containing Podcast 2.0 namespace
  • Manual testing of HTTP fetching with conditional GET headers

HTTP Bindings:
- Add parse_url() and parse_url_with_limits() to Python bindings
- Add parseUrl() and parseUrlWithOptions() to Node.js bindings
- Support conditional GET with ETag/Last-Modified headers
- Expose HTTP metadata (status, href, etag, modified, headers)
- Enable http feature flag (default) for both bindings

Podcast 2.0 Support:
- Add podcast_transcripts and podcast_persons to Entry struct
- Parse podcast:transcript elements with url, type, language, rel
- Parse podcast:person elements with name, role, group, img, href
- Expose podcast fields in Python and Node.js Entry types

iTunes Improvements:
- Fix subcategory parsing with proper nested category handling
- Support both flat and nested iTunes category structures

All 315 tests pass, zero clippy warnings.
@codecov-commenter
Copy link

codecov-commenter commented Dec 15, 2025

Codecov Report

❌ Patch coverage is 19.42857% with 141 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/feedparser-rs-core/src/parser/rss.rs 18.63% 131 Missing ⚠️
crates/feedparser-rs-core/src/http/client.rs 16.66% 10 Missing ⚠️

❌ Your patch status has failed because the patch coverage (19.42%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Impacted file tree graph

@@            Coverage Diff             @@
##             main      #12      +/-   ##
==========================================
- Coverage   81.18%   78.80%   -2.38%     
==========================================
  Files          27       27              
  Lines        4145     4303     +158     
==========================================
+ Hits         3365     3391      +26     
- Misses        780      912     +132     
Flag Coverage Δ
rust-core 78.80% <19.42%> (-2.38%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
crates/feedparser-rs-core/src/types/entry.rs 84.90% <100.00%> (+0.59%) ⬆️
crates/feedparser-rs-core/src/http/client.rs 62.87% <16.66%> (-2.08%) ⬇️
crates/feedparser-rs-core/src/parser/rss.rs 59.06% <18.63%> (-9.98%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Security (PRIORITY 1):
- Add 512-byte length limit for User-Agent header
- Add 1KB length limit for ETag header
- Add 64-byte length limit for Last-Modified header
- Prevents header injection and DoS attacks

Performance (PRIORITY 2):
- Pre-allocate HashMap for HTTP response headers
- Add Vec::with_capacity() for Node.js Entry conversion
- Update Entry::with_capacity() defaults for podcasts:
  - podcast_transcripts: 2 (was 1)
  - podcast_persons: 4 (was 2)

Code quality (PRIORITY 3):
- Add limit_string() helper function in RSS parser
- Replace 4 occurrences of chars().take().collect() pattern
- Better byte-length check before char iteration

All 315 tests pass, zero clippy warnings.
@bug-ops
Copy link
Owner Author

bug-ops commented Dec 15, 2025

Review Fixes Applied ✅

All issues from the 4 review agents have been addressed:

Security (PRIORITY 1)

Issue Fix
User-Agent header length Added 512-byte limit
ETag header length Added 1KB limit
Last-Modified header length Added 64-byte limit

Performance (PRIORITY 2)

Issue Fix
HTTP headers HashMap Pre-allocated with with_capacity()
Node.js Entry conversion Added Vec::with_capacity() for all collections
Entry::with_capacity defaults podcast_transcripts: 2, podcast_persons: 4

Code Quality (PRIORITY 3)

Issue Fix
Repeated string limiting pattern Created limit_string() helper, replaced 4 occurrences

Verification:

  • ✅ All 315 tests pass
  • ✅ Zero clippy warnings
  • ✅ Code formatted with cargo +nightly fmt

Node.js native test runner uses --experimental-test-coverage flag,
not --coverage. Add test:coverage script and update CI workflow.
Node.js native test runner outputs coverage to console only.
Use c8 to generate lcov reports for codecov upload.

- Add [email protected] as dev dependency
- Update test:coverage script to use c8 with lcov reporter
- Output coverage files to ./coverage directory
@bug-ops bug-ops merged commit 5ade586 into main Dec 16, 2025
29 checks passed
@bug-ops bug-ops deleted the feat/phase-5.1-http-bindings branch December 16, 2025 00:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants