Skip to content

Conversation

@RishiAhuja
Copy link

@RishiAhuja RishiAhuja commented Nov 1, 2025

PR Description

Overview

This pull request implements functional Hurl file import capability for API Dash on macOS, building upon the foundational Flutter Rust Bridge infrastructure established by @WrathOP. Support for other platforms remains a known issue (detailed below), but this provides the foundation.

The implementation utilizes the official hurl_core v7.0.0 Rust library through FFI, following the architectural direction suggested by @ashitaprasad to leverage Flutter Rust Bridge for generating Dart-readable JSON output from Hurl files.

Technical Approach and Key Differences

The current solution utilizes hurl_core::parser::parse_hurl_file() and manually extracts only the HTTP request-relevant data from the AST, producing a simplified JSON structure tailored for API Dash's data models.

This approach addresses the core requirement identified by @ashitaprasad: using Flutter Rust Bridge to parse Hurl files into Dart-readable JSON format, rather than attempting to reimplement the Hurl specification in pure Dart.

Implementation Details

The implementation follows a three-layers:

  • Rust FFI Bridge (hurl_parser.rs): The Rust layer exposes a single function parse_hurl_to_json(). It uses the official hurl_core library to parse the .hurl file, traverse its AST, and extract relevant request fields (method, URL, headers, bodies, auth, etc.) into a simplified JSON string.

  • Dart Integration (hurl_io.dart): The HurlIO class consumes this JSON and maps it to API Dash's HttpRequestModel. This layer handles the "business logic" of converting Hurl-specific sections (like [BasicAuth] and [Cookies]) into the standard HTTP headers and models that Apidash understands.

  • Build System Integration (Cargokit): Cargokit manages the Rust compilation and links the resulting dynamic library into the Flutter app during the build process.

Feature Coverage and Hurl Specification Support

The implementation supports the following Hurl features with varying degrees of completeness:

Hurl Feature Implementation Status API Dash Mapping Notes
HTTP Methods Fully Supported HTTPVerb enum All standard methods supported
URL with Query Parameters Fully Supported url + params Both inline and section-based
Request Headers Fully Supported headers list Direct header mapping
[QueryStringParams] Section Fully Supported Merged into params Combined with URL params
[FormParams] Section Fully Supported formData with ContentType.formdata Standard form encoding
[MultipartFormData] Section Partially Supported formData with type metadata Text fields only; file uploads extract metadata
[BasicAuth] Section Fully Supported Converted to Authorization header RFC 7617 compliant
[Cookies] Section Fully Supported Converted to Cookie header RFC 6265 compliant
JSON Request Bodies Fully Supported body with ContentType.json Auto-detected from AST
Text/XML Bodies Fully Supported body with ContentType.text Direct string extraction
Base64/Hex Bodies Metadata Only String representation Format prefix preserved
File References Metadata Only File path as string Path extracted but not loaded
Template Variables Not Supported Remains as literal text Would require variable resolution system
[Options] Section Not Supported N/A CLI execution options, not HTTP requests
Response Assertions Not Supported N/A Testing-specific, not relevant for import

Critical Limitations and Platform Constraints

FFI Testing Architecture Constraints

The test suite in hurl_parser_test.dart cannot execute via the standard flutter test command due to fundamental FFI architectural limitations. The Dart VM test environment does not include the compiled Rust dynamic library, which is only built during full application compilation through flutter build or flutter run. This constraint affects all Flutter FFI implementations and is not specific to this codebase.

Platform-Specific Build Requirements: macOS

On macOS, the Hurl Rust library has a transitive dependency on libxml2 for XML parsing capabilities. While macOS includes a system libxml2, the Homebrew-installed version is often required for proper compilation. The Podfile requires manual modification after running flutter create --platforms=macos . to add necessary linker flags:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_macos_build_settings(target)
    
    target.build_configurations.each do |config|
      config.build_settings['OTHER_LDFLAGS'] ||= ['$(inherited)']
      config.build_settings['OTHER_LDFLAGS'] << '-lxml2'
      config.build_settings['HEADER_SEARCH_PATHS'] ||= ['$(inherited)']
      config.build_settings['HEADER_SEARCH_PATHS'] << '/opt/homebrew/opt/libxml2/include/libxml2'
      config.build_settings['LIBRARY_SEARCH_PATHS'] ||= ['$(inherited)']
      config.build_settings['LIBRARY_SEARCH_PATHS'] << '/opt/homebrew/opt/libxml2/lib'
    end
  end
end

This limitation is inherited from @WrathOP's original implementation. Since the macos directory is Flutter-generated and conventionally excluded from version control, developers must manually apply these modifications. This represents a known documentation gap and a significant friction point for other contributors.

@ashitaprasad - I'm not familiar enough with Cargokit or the Podfile to automate this. Do you have any suggestions on how we could script these linker flags as part of the flutter build process?

Cross-Platform Testing Status and Known Blockers

Testing has been conducted exclusively on macOS (Apple Silicon M-series processor) because that is the machine I own. The implementation theoretically supports all platforms through Cargokit's cross-compilation infrastructure, but the following platforms remain unverified:

Windows: Cargokit should compile successfully on Windows, but Windows-specific linker requirements and libxml2 availability are unknown. The Rust ecosystem supports Windows natively, suggesting likely compatibility, but verification is required.

Linux: Expected to work without significant modification, as Linux distributions typically include libxml2 development packages. The dynamic library linking process on Linux may require different configuration than macOS, pending verification.

iOS and Android: These platforms face a critical blocker identified by @WrathOP during initial implementation. Mobile platforms do not include libxml2 as a system library, and the Rust crate wrapper used by hurl_core does not currently support iOS or Android compilation targets. @WrathOP's extensive investigation documented in flutter_rust_bridge_experiment.md details the attempted solutions and confirmed this as an unresolved issue.

The mobile platform limitation represents the primary outstanding technical challenge for this feature. Potential solutions documented by @WrathOP include using legacy Hurl versions predating the libxml2 dependency, implementing custom XML parsing, or waiting for mobile platform support in the Rust libxml2 wrapper crate. Each approach involves significant trade-offs in terms of maintenance burden, feature completeness, and implementation complexity.

Demonstration Video

hurl-implementation.mp4

Related Issues

Checklist

  • I have gone through the contributing guide
  • I have updated my branch and synced it with project main branch before making this PR
  • I am using the latest Flutter stable branch (run flutter upgrade and verify)
  • I have run the tests (flutter test) and all tests are passing

Added/updated tests?

  • Yes

OS on which you have developed and tested the feature?

  • Windows
  • macOS
  • Linux

Platform Testing Notes:

Development and comprehensive testing were conducted exclusively on macOS running on Apple Silicon (M-series) processors. The implementation utilizes Cargokit for theoretical cross-platform support, but other platforms remain untested in this PR.

- Implemented Hurl file parser using official hurl_core library via Rust FFI
- Added request selection dialog for choosing which requests to import
- Supports method, URL, headers, query parameters, form data, JSON body, and basic auth
- Integrated Hurl import into main app with new ImportFormat enum entry
- Added comprehensive tests for enhanced parsing features
- Fixed comprehensive.hurl BasicAuth syntax issue
- All parsed requests converted to HttpRequestModel format

Resolves foss42#123
- Added multipart form data support (text fields) to Rust parser
- Added cookies support, converting to Cookie header in Dart
- Enhanced hurl_io.dart to handle multipartParams and cookies
- Added advanced_features_test.dart with 4 new tests
- All 13 tests passing (basic + advanced features)
- Multipart params converted to FormDataModel with type 'text'
- Cookies concatenated with semicolon separator
- Skipped Options section (not relevant for HTTP request import)

Related to foss42#123
- Selection dialog now only appears for Hurl file imports
- Other import formats (Postman, Insomnia, HAR) retain original behavior
- Import all requests directly without selection
- Added proper imports for ImportFormat and HttpRequestModel
- Improved code organization with shouldShowSelectionDialog flag
- Maintains backward compatibility for existing import workflows
…onsolidate tests

- Renamed rust/src/api/simple.rs to hurl_parser.rs for clearer intent
- Updated all FFI binding references in Dart generated code
- Deleted scattered test files (parser_test.dart, enhanced_parser_test.dart, advanced_features_test.dart)
- Created single consolidated hurl_parser_test.dart with 13 tests in 7 logical groups
- Removed apidash_core hurl_io_test.dart (FFI limitations make it impractical)
- Updated comment style in hurl_io.dart for consistency
- Regenerated Flutter Rust Bridge bindings with correct content hash
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.

Importing Requests from hurl file

1 participant