Skip to content

feat: implement HTTP auth() — Basic Auth and Bearer Token (BES-29)#14

Merged
fewensa merged 1 commit intorefactorfrom
feat/chunked-transfer
Mar 14, 2026
Merged

feat: implement HTTP auth() — Basic Auth and Bearer Token (BES-29)#14
fewensa merged 1 commit intorefactorfrom
feat/chunked-transfer

Conversation

@fewensa
Copy link
Copy Markdown
Owner

@fewensa fewensa commented Mar 14, 2026

Summary

Implements the previously-unimplemented auth() method on HttpClient with Basic Auth and Bearer Token support (BES-29).

Also evaluates SOCKS proxy socket2 compatibility (BES-30) — conclusion: keep socks crate (see below).

Changes

types/auth.rs (new)

  • Auth enum with Basic { username, password } and Bearer { token } variants
  • Auth::basic(username, password) constructor
  • Auth::bearer(token) constructor
  • Auth::header_value() produces correct Authorization header value
  • Unit tests for Basic and Bearer header encoding

types/mod.rs

  • Export Auth from the types module

client.rs

  • Replace unimplemented!() stub with functional auth<A: AsRef<Auth>>() method
  • Sets Authorization header via existing header() mechanism

tests/support/mod.rs

  • Add spawn_auth_echo_server() — echoes the Authorization header value as the response body

tests/test_http_basic.rs

  • test_basic_auth: verifies Basic dXNlcjpzZWNyZXQ= header is sent
  • test_bearer_auth: verifies Bearer my-token-abc header is sent

SOCKS Proxy Evaluation (BES-30)

The socks crate (v0.3) uses std::net::TcpStream::connect() internally for proxy connection setup. It implements Read + Write on Socks5Stream/Socks4Stream, which is all that block_send_with_stream needs.

Decision: Keep socks crate. The SOCKS protocol handshake is inherently sequential, so socket2-based migration would not provide meaningful benefit. The socket2 migration goal (main TCP path) is already achieved in the parallel feat/async-tls PR.

Verification

cargo test --features "async,tls-rustls"

All tests pass (0 failed).

Add Auth type with Basic and Bearer variants, and implement the
previously-unimplemented auth() method on HttpClient.

- Add types/auth.rs with Auth::basic() and Auth::bearer() constructors
- Auth::header_value() produces correct Authorization header string
- HttpClient::auth() accepts any AsRef<Auth> and sets Authorization header
- Unit tests for Basic/Bearer header encoding in auth.rs
- Integration tests (test_basic_auth, test_bearer_auth) with echo server
- Add spawn_auth_echo_server() to test support module

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@fewensa fewensa force-pushed the feat/chunked-transfer branch from 5df5b49 to 00ece8c Compare March 14, 2026 03:37
@fewensa fewensa merged commit 8417df7 into refactor Mar 14, 2026
@fewensa fewensa deleted the feat/chunked-transfer branch March 14, 2026 03:37
fewensa added a commit that referenced this pull request Mar 14, 2026
* format and special toolchain

* refactor raw builder

* ci

* ci

* ci

* ci

* ci

* danger config

* clippy

* lint

* refactor features

* refactor features

* Revert test host

* Migrate async client to futures and socket2 (#2)

* Migrate async client to futures and socket2 (#3)

* Migrate to socket2: update features, async TLS handling, config tests, and CI (#7)

* Update features and CI for socket2 migration

* Fix rustls feature list

* Bump checkout action to v6

* Fix CI branch and relax dependency specs

* Restore checkout v6 in CI (#8)

* Fix build errors: socket2 API, rustls trait impl, async field access, Alphanumeric type (#9)

- connection/mod.rs: remove incorrect #[cfg(feature = "async")] guard on block_connection
- connection/connection.rs: replace socket.into_tcp_stream() with std::net::TcpStream::from(socket)
- connection/connection.rs: implement missing ServerCertVerifier methods and #[derive(Debug)] for NoCertificateVerification
- connection/connection.rs: call .to_owned() on ServerName to fix lifetime issue
- connection/connection.rs: use Display instead of Debug for native-tls HandshakeError
- request/builder/build_body_async.rs: use self.request field directly instead of self.request() method
- request/builder/form_data.rs: cast u8 to char for Alphanumeric distribution output

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix refactor dependency compatibility (#11)

* Fix refactor dependency compatibility\n\nCo-Authored-By: Paperclip <noreply@paperclip.ing>

* Run CI for refactor PRs\n\nCo-Authored-By: Paperclip <noreply@paperclip.ing>

* Apply rustfmt for CI\n\nCo-Authored-By: Paperclip <noreply@paperclip.ing>

* Fix clippy warnings on refactor branch\n\nCo-Authored-By: Paperclip <noreply@paperclip.ing>

* chore: clean up clippy warnings and upgrade workspace resolver (#12)

- Remove unused native_tls::TlsConnector import in block_connection.rs
- Fix block_send_https_native cfg to only compile when tls-native is enabled
  without tls-rustls (avoids dead_code warning)
- Remove unused ToUrl import in async_connection.rs
- Fix unnecessary mut on disposition in build_body_async.rs
- Gate no_request_features behind cfg to suppress unused warning
- Add resolver = "2" to workspace Cargo.toml for edition 2021 compatibility

* Implement async TLS via futures-rustls (BES-27) (#13)

* Implement async TLS via futures-rustls for async_send_https

- Replace async-rustls (rustls 0.21) with futures-rustls 0.26 (rustls 0.23 compatible)
- Implement async_send_https_rustls using TlsConnector from futures-rustls
- TLS path wraps TcpStream in AllowStdIo for futures-io compatibility
- Expose NoCertificateVerification as pub(crate) for reuse across modules
- Update tls-rustls feature to depend on futures-rustls instead of async-rustls
- Also includes async chunked transfer support in async_read_stream and
  connection_reader (sync path); all cargo test --features async,tls-rustls pass

Co-Authored-By: Paperclip <noreply@paperclip.ing>

* feat: use socket2 directly in async_tcp_stream

Replace delegation to block_tcp_stream with inline socket2-based
connection setup in async_tcp_stream. This makes the async path own
its socket2 usage directly rather than calling through the sync path,
removing the fake-async delegation and keeping the implementation
consistent with the sync block_tcp_stream.

- Import socket2, ToSocketAddrs, io, time in async_connection.rs
- async_tcp_stream now creates socket, sets timeouts, connects via socket2
- Ready for future async-runtime integration at this single call-site

Co-Authored-By: Paperclip <noreply@paperclip.ing>

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>

* feat: implement HTTP auth() with Basic and Bearer support (BES-29) (#14)

Add Auth type with Basic and Bearer variants, and implement the
previously-unimplemented auth() method on HttpClient.

- Add types/auth.rs with Auth::basic() and Auth::bearer() constructors
- Auth::header_value() produces correct Authorization header string
- HttpClient::auth() accepts any AsRef<Auth> and sets Authorization header
- Unit tests for Basic/Bearer header encoding in auth.rs
- Integration tests (test_basic_auth, test_bearer_auth) with echo server
- Add spawn_auth_echo_server() to test support module

Co-authored-by: Paperclip <noreply@paperclip.ing>

* chore: remove empty block_stream.rs placeholder file

* Add local SOCKS proxy coverage (#15)

* Align refactor HTTP client behavior

* Add missing async proxy test attribute (#16)

* Remove dead debug code, update CI branches, bump version to 0.2.0 (#17)

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
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.

1 participant