Skip to content
This repository has been archived by the owner on Jan 16, 2025. It is now read-only.

refactor(websocket): Major changes, abstract WebSocket message structure #94

Merged
merged 7 commits into from
Aug 7, 2024

Conversation

0x676e67
Copy link
Owner

@0x676e67 0x676e67 commented Aug 7, 2024

Summary by CodeRabbit

  • New Features

    • Introduced methods for JSON serialization and deserialization of WebSocket messages.
    • Added a method for gracefully closing WebSocket connections with specific codes and reasons.
  • Improvements

    • Enhanced error handling for WebSocket connections and message types.
    • Simplified the WebSocket client creation process and updated dependency configurations for better performance and usability.
    • Updated project description to include WebSocket capabilities.
  • Bug Fixes

    • Resolved issues with outdated dependencies affecting WebSocket functionality.

Copy link

coderabbitai bot commented Aug 7, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

The updates enhance the WebSocket functionality in the Rust project by integrating the async-tungstenite library, allowing for more efficient handling of WebSocket connections. Key changes include adding a websocket feature by default, refining API methods for clarity, introducing JSON serialization capabilities for messages, and transitioning error handling to an asynchronous model, which collectively improve performance and user experience.

Changes

Files Change Summary
Cargo.toml Added "websocket" to default features, removed tungstenite, updated async-tungstenite version.
examples/websocket.rs Updated main function with Client::ws_builder(), changed Tokio runtime flavor, and improved imports.
src/async_impl/client.rs Removed impersonate_websocket from ClientBuilder, added ws_builder() to Client for new configurations.
src/async_impl/websocket/json.rs Introduced JSON serialization methods for Message handling, enhancing versatility.
src/async_impl/websocket/mod.rs Added close() method to WebSocket, improved error handling in Stream, and enhanced message type conversion.
src/error.rs Changed error handling to use async_tungstenite::tungstenite::Error for asynchronous compatibility.
src/lib.rs Revised websocket function for broader availability and updated exports to include CloseCode.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant WebSocketClient
    participant Server

    User->>WebSocketClient: Open WebSocket connection
    WebSocketClient->>Server: Establish connection
    Server-->>WebSocketClient: Connection established
    User->>WebSocketClient: Send message
    WebSocketClient->>Server: Send message
    Server-->>WebSocketClient: Acknowledge message
    WebSocketClient->>User: Acknowledge receipt
    User->>WebSocketClient: Close connection
    WebSocketClient->>Server: Send close code and reason
    Server-->>WebSocketClient: Connection closed
Loading

Poem

🐰 In the meadow, the code hops high,
With WebSocket whispers, it reaches the sky.
Async-tungstenite, oh what a delight,
Messages dance in the moon's gentle light.
Close codes and messages, all in a row,
Celebrating changes, our project's new glow! ✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Outside diff range, codebase verification and nitpick comments (3)
examples/websocket.rs (2)

17-18: Commented-out alternative method for establishing the WebSocket connection.

The commented-out alternative method provides flexibility by offering a different approach to connect to WebSocket servers.

Consider documenting the differences between the two methods for clarity.


7-7: Instances of Client::builder() still exist and need to be replaced with Client::ws_builder().

Please update the following occurrences:

  • tests/upgrade.rs
  • tests/timeouts.rs
  • tests/proxy.rs
  • tests/redirect.rs
  • tests/cookie.rs
  • tests/badssl.rs
  • tests/client.rs
  • examples/headers_order.rs
  • tests/blocking.rs
  • examples/set_interface.rs
  • examples/psk_impersonate.rs
  • examples/impersonate.rs
  • examples/set_local_address.rs
  • examples/tor_socks.rs
  • examples/set_proxies.rs
  • src/redirect.rs
  • src/proxy.rs
  • src/async_impl/client.rs
  • src/blocking/mod.rs
  • src/blocking/client.rs
Analysis chain

Verify the usage of the Client::ws_builder() method.

Ensure that all instances of Client::builder() have been replaced with Client::ws_builder().

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the `Client::ws_builder()` method.

# Test: Search for the usage of the `Client::ws_builder()` method. Expect: Only occurrences of the new method.
rg --type rust -A 2 $'Client::ws_builder'

Length of output: 307


Script:

#!/bin/bash
# Description: Verify if any instances of `Client::builder()` still exist.

# Test: Search for the usage of the `Client::builder()` method. Expect: No occurrences of the old method.
rg --type rust -A 2 $'Client::builder'

Length of output: 13129

src/async_impl/websocket/mod.rs (1)

344-364: The close method does not handle WASM targets appropriately.

The current implementation of the close method in WebSocket only includes a conditional compilation block for non-WASM targets (#[cfg(not(target_arch = "wasm32"))]). There is no specific handling or fallback for WASM targets, which could lead to issues when the method is called in a WASM environment.

  • Ensure that the close method includes appropriate handling for WASM targets.
  • Add a conditional compilation block for WASM targets if necessary.
Analysis chain

LGTM! But verify the correctness of the method implementation.

The code changes are approved.

However, ensure that the close method is correctly implemented and handles different targets appropriately.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the correctness of the `close` method implementation.

# Test: Search for the usage of the `close` method. Expect: Proper implementation and handling of different targets.
rg --type rust -A 5 $'WebSocket::close'

Length of output: 745


Script:

#!/bin/bash
# Description: Search for the implementation and usage of the `close` method in the codebase.

# Search for the implementation of the `close` method in the `WebSocket` struct.
rg --type rust 'impl WebSocket' -A 20 | rg 'fn close'

# Search for the usage of the `close` method in the codebase.
rg --type rust 'close(' -A 5

Length of output: 272


Script:

#!/bin/bash
# Description: Search for the usage of the `close` method in the codebase with corrected regex.

# Search for the usage of the `close` method in the codebase.
rg --type rust 'close\(' -A 5

Length of output: 1221


Script:

#!/bin/bash
# Description: Search for specific handling or implementation for WASM targets in the codebase.

# Search for the usage of `#[cfg(target_arch = "wasm32")]` in the codebase.
rg --type rust '#\[cfg\(target_arch = "wasm32"\)\]' -A 5

Length of output: 457

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 0204bb4 and 378e267.

Files selected for processing (7)
  • Cargo.toml (2 hunks)
  • examples/websocket.rs (2 hunks)
  • src/async_impl/client.rs (2 hunks)
  • src/async_impl/websocket/message.rs (1 hunks)
  • src/async_impl/websocket/mod.rs (5 hunks)
  • src/error.rs (1 hunks)
  • src/lib.rs (2 hunks)
Additional comments not posted (20)
examples/websocket.rs (2)

2-2: Import statement for Message looks good.

The import statement for Message from the rquest library is correctly added.


5-5: Verify the impact of the flavor = "current_thread" attribute.

The flavor = "current_thread" attribute affects the execution model of the asynchronous runtime. Ensure that this change aligns with the intended behavior of the application.

Cargo.toml (3)

22-22: Addition of the "websocket" feature to the default feature set looks good.

This change ensures that WebSocket functionality is enabled by default.


30-30: Update to the websocket feature dependencies looks good.

The change to use async-tungstenite version 0.27.0 leverages improvements in the newer version.


135-135: Update to the async-tungstenite dependency looks good.

The change to version 0.27.0 ensures that the project uses the latest version of async-tungstenite.

src/async_impl/websocket/message.rs (9)

3-33: Definition of the Message enum looks good.

The enum provides a clear and structured way to handle different types of WebSocket messages.


64-164: Definition of the CloseCode enum looks good.

The enum provides a comprehensive set of status codes for different scenarios.


36-55: Implementations for Message conversions look good.

The implementations provide useful conversion methods for the Message enum.


57-62: Implementations for Message conversions look good.

The implementations provide useful conversion methods for the Message enum.


167-176: Implementation of the is_allowed method for CloseCode looks good.

The method provides a way to check if a CloseCode is allowed.


178-182: Implementation of the Display trait for CloseCode looks good.

The implementation provides a way to display the CloseCode.


185-207: Implementation of the From<CloseCode> trait for u16 looks good.

The implementation provides a conversion from CloseCode to u16.


210-233: Implementation of the From<u16> trait for CloseCode looks good.

The implementation provides a conversion from u16 to CloseCode.


235-245: Implementations for conversions between tungstenite::protocol::frame::coding::CloseCode and CloseCode look good.

The implementations provide interoperability between tungstenite and the CloseCode enum.

src/error.rs (1)

223-226: LGTM! But verify the integration of the new error type.

The code changes are approved.

However, ensure that the new error type async_tungstenite::tungstenite::Error is properly integrated across the codebase.

src/lib.rs (2)

Line range hint 356-360:
LGTM! But verify the integration of the new type.

The code changes are approved.

However, ensure that the new type CloseCode is properly integrated across the codebase.

Verification successful

The CloseCode type is properly integrated across the codebase.

The CloseCode type is used in various places within the src/async_impl/websocket module, including function signatures, enum definitions, and implementations for conversions and display formatting. This confirms that it is well-integrated.

  • src/async_impl/websocket/mod.rs
  • src/async_impl/websocket/message.rs
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration of the new type.

# Test: Search for the usage of the new type. Expect: Proper integration across the codebase.
rg --type rust -A 5 $'CloseCode'

Length of output: 6431


316-325: LGTM! But verify the correctness of the new method implementation.

The code changes are approved.

However, ensure that the new method for creating a WebSocket client is correctly implemented.

Verification successful

The new method for creating a WebSocket client is correctly implemented.

The ws_builder and build methods are properly defined and implemented in src/async_impl/client.rs. The ws_builder method returns a ClientBuilder, which is then used to configure and build a Client instance.

  • ws_builder method: src/async_impl/client.rs: pub fn ws_builder() -> ClientBuilder
  • build method: src/async_impl/client.rs: pub fn build(self) -> crate::Result<Client>
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the correctness of the new method implementation.

# Test: Search for the usage of the new method. Expect: Proper implementation and usage.
rg --type rust -A 5 $'Client::ws_builder().build()'

Length of output: 52


Script:

#!/bin/bash
# Search for the definition and implementation of the `ws_builder` method in the `Client` class.
ast-grep --lang rust --pattern 'impl Client {
  $_
  fn ws_builder($_) -> $_ {
    $_
  }
  $_
}'

# Search for the definition and implementation of the `build` method in the `Client` class.
ast-grep --lang rust --pattern 'impl Client {
  $_
  fn build($_) -> $_ {
    $_
  }
  $_
}'

Length of output: 194


Script:

#!/bin/bash
# Search for the definition of the `ws_builder` method across the entire codebase.
rg --type rust 'fn ws_builder'

# Search for the definition of the `build` method across the entire codebase.
rg --type rust 'fn build'

Length of output: 1360


Script:

#!/bin/bash
# Display the implementation of the `ws_builder` method in `src/async_impl/client.rs`.
rg --type rust -A 10 'pub fn ws_builder() -> ClientBuilder' src/async_impl/client.rs

# Display the implementation of the `build` method in `src/async_impl/client.rs`.
rg --type rust -A 10 'pub fn build(self) -> crate::Result<Client>' src/async_impl/client.rs

Length of output: 180


Script:

#!/bin/bash
# Search for the definition of the `ws_builder` method within the `src/async_impl/client.rs` file.
rg --type rust 'ws_builder' src/async_impl/client.rs

# Search for the definition of the `build` method within the `src/async_impl/client.rs` file.
rg --type rust 'build' src/async_impl/client.rs

Length of output: 3099

src/async_impl/websocket/mod.rs (3)

375-385: LGTM! But verify the correctness of the error handling.

The code changes are approved.

However, ensure that the error handling within the Stream implementation is correctly implemented.

Verification successful

The error handling within the Stream implementation is correctly implemented.

The log message and the creation of the Error object with Kind::Body and the message "unsupported websocket frame" are present, confirming the correctness of the error handling.

  • src/async_impl/websocket/mod.rs: Lines 375-385
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the correctness of the error handling within the `Stream` implementation.

# Test: Search for the error handling code. Expect: Proper implementation and feedback on unsupported WebSocket frames.
rg --type rust -A 5 $'received invalid frame'

Length of output: 499


1-14: LGTM! But verify the integration of the new Message type.

The code changes are approved.

However, ensure that the new Message type is properly integrated across the codebase.

Verification successful

The new Message type is properly integrated across the codebase.

The integration of the new Message type is evident in multiple files, including implementations and conversions, ensuring proper usage throughout the system.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration of the new `Message` type.

# Test: Search for the usage of the new `Message` type. Expect: Proper integration across the codebase.
rg --type rust -A 5 $'message::Message'

Length of output: 38


Script:

#!/bin/bash
# Description: Verify the integration of the new `Message` type.

# Test: Search for all instances of `Message` in the codebase. Expect: Proper integration across the codebase.
rg --type rust -A 5 $'Message'

Length of output: 8139


410-450: LGTM! But verify the correctness of the implementations.

The code changes are approved.

However, ensure that the TryFrom and From implementations for Message are correctly implemented.

src/async_impl/client.rs Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 378e267 and 1d936b8.

Files selected for processing (7)
  • Cargo.toml (3 hunks)
  • README.md (2 hunks)
  • src/async_impl/client.rs (2 hunks)
  • src/async_impl/websocket/json.rs (1 hunks)
  • src/async_impl/websocket/mod.rs (5 hunks)
  • src/error.rs (1 hunks)
  • src/lib.rs (3 hunks)
Files skipped from review as they are similar to previous changes (2)
  • Cargo.toml
  • src/lib.rs
Additional comments not posted (14)
src/async_impl/websocket/json.rs (4)

4-20: LGTM!

The text_from_json function correctly serializes JSON into a Message::Text and handles errors appropriately.


22-37: LGTM!

The binary_from_json function correctly serializes JSON into a Message::Binary and handles errors appropriately.


39-63: LGTM!

The json function correctly deserializes a Message into JSON and handles errors appropriately.


66-96: LGTM!

The test module provides adequate coverage for the text_from_json, binary_from_json, and json functions.

README.md (3)

70-71: LGTM!

The import statements are correctly updated to reflect the usage of the rquest library.


73-73: LGTM!

The tokio::main macro is correctly updated to specify the current_thread flavor.


75-75: LGTM!

The WebSocket usage example is correctly updated to use the rquest::websocket function.

src/error.rs (2)

223-224: LGTM!

The From<async_tungstenite::tungstenite::Error> implementation correctly maps the error to the Kind::Upgrade variant and wraps it in an Error.


229-234: LGTM!

The From<serde_json::Error> implementation correctly maps the error to the Kind::Decode variant and wraps it in an Error.

src/async_impl/websocket/mod.rs (4)

15-15: LGTM! Improved type safety and clarity in message handling.

The import statement has been updated to use CloseCode and Message from the message module, enhancing type safety and clarity.


411-434: LGTM! Enhanced type safety and clarity in message handling.

The implementation of the TryFrom trait for converting tungstenite::Message to the custom Message type ensures proper conversion and error handling for unsupported frames.


436-450: LGTM! Enhanced interoperability in message handling.

The implementation of the From trait for converting the custom Message type to tungstenite::Message ensures seamless conversion and enhances interoperability.


345-365: LGTM! Controlled closure of WebSocket connection.

The new close method in the WebSocket struct enables controlled closure of the WebSocket connection with a specified close code and an optional reason. The conditional compilation for WebAssembly is correctly implemented.

src/async_impl/client.rs (1)

1341-1346: LGTM! Improve method documentation for ws_builder.

The new ws_builder method enhances the clarity and usability of the client configuration process. Consider providing more details about the purpose and usage of this method.

-    /// Create a `ClientBuilder` to configure a `Client`.
+    /// Create a `ClientBuilder` specifically configured for WebSocket connections.
     ///
-    /// This is required http1 only.
+    /// This method configures the `ClientBuilder` to use HTTP/1.0 only, which is required for certain WebSocket connections.

@0x676e67 0x676e67 merged commit 266f0cb into main Aug 7, 2024
1 check passed
@0x676e67 0x676e67 deleted the refactor branch August 7, 2024 12:34
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant