wreq-rb 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Cargo.lock +2688 -0
- data/Cargo.toml +6 -0
- data/README.md +179 -0
- data/ext/wreq_rb/Cargo.toml +39 -0
- data/ext/wreq_rb/extconf.rb +22 -0
- data/ext/wreq_rb/src/client.rs +565 -0
- data/ext/wreq_rb/src/error.rs +25 -0
- data/ext/wreq_rb/src/lib.rs +20 -0
- data/ext/wreq_rb/src/response.rs +132 -0
- data/lib/wreq-rb/version.rb +5 -0
- data/lib/wreq-rb.rb +17 -0
- data/patches/0001-add-transfer-size-tracking.patch +292 -0
- data/vendor/wreq/Cargo.toml +306 -0
- data/vendor/wreq/LICENSE +202 -0
- data/vendor/wreq/README.md +122 -0
- data/vendor/wreq/examples/cert_store.rs +77 -0
- data/vendor/wreq/examples/connect_via_lower_priority_tokio_runtime.rs +258 -0
- data/vendor/wreq/examples/emulation.rs +118 -0
- data/vendor/wreq/examples/form.rs +14 -0
- data/vendor/wreq/examples/http1_websocket.rs +37 -0
- data/vendor/wreq/examples/http2_websocket.rs +45 -0
- data/vendor/wreq/examples/json_dynamic.rs +41 -0
- data/vendor/wreq/examples/json_typed.rs +47 -0
- data/vendor/wreq/examples/keylog.rs +16 -0
- data/vendor/wreq/examples/request_with_emulation.rs +115 -0
- data/vendor/wreq/examples/request_with_interface.rs +37 -0
- data/vendor/wreq/examples/request_with_local_address.rs +16 -0
- data/vendor/wreq/examples/request_with_proxy.rs +13 -0
- data/vendor/wreq/examples/request_with_redirect.rs +22 -0
- data/vendor/wreq/examples/request_with_version.rs +15 -0
- data/vendor/wreq/examples/tor_socks.rs +24 -0
- data/vendor/wreq/examples/unix_socket.rs +33 -0
- data/vendor/wreq/src/client/body.rs +304 -0
- data/vendor/wreq/src/client/conn/conn.rs +231 -0
- data/vendor/wreq/src/client/conn/connector.rs +549 -0
- data/vendor/wreq/src/client/conn/http.rs +1023 -0
- data/vendor/wreq/src/client/conn/proxy/socks.rs +233 -0
- data/vendor/wreq/src/client/conn/proxy/tunnel.rs +260 -0
- data/vendor/wreq/src/client/conn/proxy.rs +39 -0
- data/vendor/wreq/src/client/conn/tls_info.rs +98 -0
- data/vendor/wreq/src/client/conn/uds.rs +44 -0
- data/vendor/wreq/src/client/conn/verbose.rs +149 -0
- data/vendor/wreq/src/client/conn.rs +323 -0
- data/vendor/wreq/src/client/core/body/incoming.rs +485 -0
- data/vendor/wreq/src/client/core/body/length.rs +118 -0
- data/vendor/wreq/src/client/core/body.rs +34 -0
- data/vendor/wreq/src/client/core/common/buf.rs +149 -0
- data/vendor/wreq/src/client/core/common/rewind.rs +141 -0
- data/vendor/wreq/src/client/core/common/watch.rs +76 -0
- data/vendor/wreq/src/client/core/common.rs +3 -0
- data/vendor/wreq/src/client/core/conn/http1.rs +342 -0
- data/vendor/wreq/src/client/core/conn/http2.rs +307 -0
- data/vendor/wreq/src/client/core/conn.rs +11 -0
- data/vendor/wreq/src/client/core/dispatch.rs +299 -0
- data/vendor/wreq/src/client/core/error.rs +435 -0
- data/vendor/wreq/src/client/core/ext.rs +201 -0
- data/vendor/wreq/src/client/core/http1.rs +178 -0
- data/vendor/wreq/src/client/core/http2.rs +483 -0
- data/vendor/wreq/src/client/core/proto/h1/conn.rs +988 -0
- data/vendor/wreq/src/client/core/proto/h1/decode.rs +1170 -0
- data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +684 -0
- data/vendor/wreq/src/client/core/proto/h1/encode.rs +580 -0
- data/vendor/wreq/src/client/core/proto/h1/io.rs +879 -0
- data/vendor/wreq/src/client/core/proto/h1/role.rs +694 -0
- data/vendor/wreq/src/client/core/proto/h1.rs +104 -0
- data/vendor/wreq/src/client/core/proto/h2/client.rs +650 -0
- data/vendor/wreq/src/client/core/proto/h2/ping.rs +539 -0
- data/vendor/wreq/src/client/core/proto/h2.rs +379 -0
- data/vendor/wreq/src/client/core/proto/headers.rs +138 -0
- data/vendor/wreq/src/client/core/proto.rs +58 -0
- data/vendor/wreq/src/client/core/rt/bounds.rs +57 -0
- data/vendor/wreq/src/client/core/rt/timer.rs +150 -0
- data/vendor/wreq/src/client/core/rt/tokio.rs +99 -0
- data/vendor/wreq/src/client/core/rt.rs +25 -0
- data/vendor/wreq/src/client/core/upgrade.rs +267 -0
- data/vendor/wreq/src/client/core.rs +16 -0
- data/vendor/wreq/src/client/emulation.rs +161 -0
- data/vendor/wreq/src/client/http/client/error.rs +142 -0
- data/vendor/wreq/src/client/http/client/exec.rs +29 -0
- data/vendor/wreq/src/client/http/client/extra.rs +77 -0
- data/vendor/wreq/src/client/http/client/lazy.rs +79 -0
- data/vendor/wreq/src/client/http/client/pool.rs +1105 -0
- data/vendor/wreq/src/client/http/client/util.rs +104 -0
- data/vendor/wreq/src/client/http/client.rs +1003 -0
- data/vendor/wreq/src/client/http/future.rs +99 -0
- data/vendor/wreq/src/client/http.rs +1629 -0
- data/vendor/wreq/src/client/layer/config/options.rs +156 -0
- data/vendor/wreq/src/client/layer/config.rs +116 -0
- data/vendor/wreq/src/client/layer/cookie.rs +161 -0
- data/vendor/wreq/src/client/layer/decoder.rs +139 -0
- data/vendor/wreq/src/client/layer/redirect/future.rs +270 -0
- data/vendor/wreq/src/client/layer/redirect/policy.rs +63 -0
- data/vendor/wreq/src/client/layer/redirect.rs +145 -0
- data/vendor/wreq/src/client/layer/retry/classify.rs +105 -0
- data/vendor/wreq/src/client/layer/retry/scope.rs +51 -0
- data/vendor/wreq/src/client/layer/retry.rs +151 -0
- data/vendor/wreq/src/client/layer/timeout/body.rs +233 -0
- data/vendor/wreq/src/client/layer/timeout/future.rs +90 -0
- data/vendor/wreq/src/client/layer/timeout.rs +177 -0
- data/vendor/wreq/src/client/layer.rs +15 -0
- data/vendor/wreq/src/client/multipart.rs +717 -0
- data/vendor/wreq/src/client/request.rs +818 -0
- data/vendor/wreq/src/client/response.rs +534 -0
- data/vendor/wreq/src/client/ws/json.rs +99 -0
- data/vendor/wreq/src/client/ws/message.rs +453 -0
- data/vendor/wreq/src/client/ws.rs +714 -0
- data/vendor/wreq/src/client.rs +27 -0
- data/vendor/wreq/src/config.rs +140 -0
- data/vendor/wreq/src/cookie.rs +579 -0
- data/vendor/wreq/src/dns/gai.rs +249 -0
- data/vendor/wreq/src/dns/hickory.rs +78 -0
- data/vendor/wreq/src/dns/resolve.rs +180 -0
- data/vendor/wreq/src/dns.rs +69 -0
- data/vendor/wreq/src/error.rs +502 -0
- data/vendor/wreq/src/ext.rs +398 -0
- data/vendor/wreq/src/hash.rs +143 -0
- data/vendor/wreq/src/header.rs +506 -0
- data/vendor/wreq/src/into_uri.rs +187 -0
- data/vendor/wreq/src/lib.rs +586 -0
- data/vendor/wreq/src/proxy/mac.rs +82 -0
- data/vendor/wreq/src/proxy/matcher.rs +806 -0
- data/vendor/wreq/src/proxy/uds.rs +66 -0
- data/vendor/wreq/src/proxy/win.rs +31 -0
- data/vendor/wreq/src/proxy.rs +569 -0
- data/vendor/wreq/src/redirect.rs +575 -0
- data/vendor/wreq/src/retry.rs +198 -0
- data/vendor/wreq/src/sync.rs +129 -0
- data/vendor/wreq/src/tls/conn/cache.rs +123 -0
- data/vendor/wreq/src/tls/conn/cert_compression.rs +125 -0
- data/vendor/wreq/src/tls/conn/ext.rs +82 -0
- data/vendor/wreq/src/tls/conn/macros.rs +34 -0
- data/vendor/wreq/src/tls/conn/service.rs +138 -0
- data/vendor/wreq/src/tls/conn.rs +681 -0
- data/vendor/wreq/src/tls/keylog/handle.rs +64 -0
- data/vendor/wreq/src/tls/keylog.rs +99 -0
- data/vendor/wreq/src/tls/options.rs +464 -0
- data/vendor/wreq/src/tls/x509/identity.rs +122 -0
- data/vendor/wreq/src/tls/x509/parser.rs +71 -0
- data/vendor/wreq/src/tls/x509/store.rs +228 -0
- data/vendor/wreq/src/tls/x509.rs +68 -0
- data/vendor/wreq/src/tls.rs +154 -0
- data/vendor/wreq/src/trace.rs +55 -0
- data/vendor/wreq/src/util.rs +122 -0
- data/vendor/wreq/tests/badssl.rs +228 -0
- data/vendor/wreq/tests/brotli.rs +350 -0
- data/vendor/wreq/tests/client.rs +1098 -0
- data/vendor/wreq/tests/connector_layers.rs +227 -0
- data/vendor/wreq/tests/cookie.rs +306 -0
- data/vendor/wreq/tests/deflate.rs +347 -0
- data/vendor/wreq/tests/emulation.rs +260 -0
- data/vendor/wreq/tests/gzip.rs +347 -0
- data/vendor/wreq/tests/layers.rs +261 -0
- data/vendor/wreq/tests/multipart.rs +165 -0
- data/vendor/wreq/tests/proxy.rs +438 -0
- data/vendor/wreq/tests/redirect.rs +629 -0
- data/vendor/wreq/tests/retry.rs +135 -0
- data/vendor/wreq/tests/support/delay_server.rs +117 -0
- data/vendor/wreq/tests/support/error.rs +16 -0
- data/vendor/wreq/tests/support/layer.rs +183 -0
- data/vendor/wreq/tests/support/mod.rs +9 -0
- data/vendor/wreq/tests/support/server.rs +232 -0
- data/vendor/wreq/tests/timeouts.rs +281 -0
- data/vendor/wreq/tests/unix_socket.rs +135 -0
- data/vendor/wreq/tests/upgrade.rs +98 -0
- data/vendor/wreq/tests/zstd.rs +559 -0
- metadata +225 -0
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
//! WebSocket message types and utilities
|
|
2
|
+
//!
|
|
3
|
+
//! This module provides WebSocket message types that wrap the underlying
|
|
4
|
+
//! tungstenite message implementation, offering a more ergonomic API
|
|
5
|
+
//! for working with WebSocket communications.
|
|
6
|
+
|
|
7
|
+
use std::{fmt, ops::Deref};
|
|
8
|
+
|
|
9
|
+
use bytes::Bytes;
|
|
10
|
+
|
|
11
|
+
use super::tungstenite;
|
|
12
|
+
use crate::Error;
|
|
13
|
+
|
|
14
|
+
/// UTF-8 wrapper for [Bytes].
|
|
15
|
+
///
|
|
16
|
+
/// An [Utf8Bytes] is always guaranteed to contain valid UTF-8.
|
|
17
|
+
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
|
18
|
+
pub struct Utf8Bytes(pub(super) tungstenite::Utf8Bytes);
|
|
19
|
+
|
|
20
|
+
impl Utf8Bytes {
|
|
21
|
+
/// Creates from a static str.
|
|
22
|
+
#[inline]
|
|
23
|
+
pub const fn from_static(str: &'static str) -> Self {
|
|
24
|
+
Self(tungstenite::Utf8Bytes::from_static(str))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/// Returns as a string slice.
|
|
28
|
+
#[inline]
|
|
29
|
+
pub fn as_str(&self) -> &str {
|
|
30
|
+
self.0.as_str()
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
impl Deref for Utf8Bytes {
|
|
35
|
+
type Target = str;
|
|
36
|
+
|
|
37
|
+
/// ```
|
|
38
|
+
/// /// Example fn that takes a str slice
|
|
39
|
+
/// fn a(s: &str) {}
|
|
40
|
+
///
|
|
41
|
+
/// let data = wreq::Utf8Bytes::from_static("foo123");
|
|
42
|
+
///
|
|
43
|
+
/// // auto-deref as arg
|
|
44
|
+
/// a(&data);
|
|
45
|
+
///
|
|
46
|
+
/// // deref to str methods
|
|
47
|
+
/// assert_eq!(data.len(), 6);
|
|
48
|
+
/// ```
|
|
49
|
+
#[inline]
|
|
50
|
+
fn deref(&self) -> &Self::Target {
|
|
51
|
+
self.as_str()
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
impl fmt::Display for Utf8Bytes {
|
|
56
|
+
#[inline]
|
|
57
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
|
|
58
|
+
f.write_str(self.as_str())
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
impl TryFrom<Bytes> for Utf8Bytes {
|
|
63
|
+
type Error = std::str::Utf8Error;
|
|
64
|
+
|
|
65
|
+
#[inline]
|
|
66
|
+
fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
|
|
67
|
+
Ok(Self(bytes.try_into()?))
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
impl TryFrom<Vec<u8>> for Utf8Bytes {
|
|
72
|
+
type Error = std::str::Utf8Error;
|
|
73
|
+
|
|
74
|
+
#[inline]
|
|
75
|
+
fn try_from(v: Vec<u8>) -> Result<Self, Self::Error> {
|
|
76
|
+
Ok(Self(v.try_into()?))
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
impl From<String> for Utf8Bytes {
|
|
81
|
+
#[inline]
|
|
82
|
+
fn from(s: String) -> Self {
|
|
83
|
+
Self(s.into())
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
impl From<&str> for Utf8Bytes {
|
|
88
|
+
#[inline]
|
|
89
|
+
fn from(s: &str) -> Self {
|
|
90
|
+
Self(s.into())
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
impl From<&String> for Utf8Bytes {
|
|
95
|
+
#[inline]
|
|
96
|
+
fn from(s: &String) -> Self {
|
|
97
|
+
Self(s.into())
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
impl From<Utf8Bytes> for Bytes {
|
|
102
|
+
#[inline]
|
|
103
|
+
fn from(Utf8Bytes(bytes): Utf8Bytes) -> Self {
|
|
104
|
+
bytes.into()
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
impl<T> PartialEq<T> for Utf8Bytes
|
|
109
|
+
where
|
|
110
|
+
for<'a> &'a str: PartialEq<T>,
|
|
111
|
+
{
|
|
112
|
+
/// ```
|
|
113
|
+
/// let payload = wreq::Utf8Bytes::from_static("foo123");
|
|
114
|
+
/// assert_eq!(payload, "foo123");
|
|
115
|
+
/// assert_eq!(payload, "foo123".to_string());
|
|
116
|
+
/// assert_eq!(payload, &"foo123".to_string());
|
|
117
|
+
/// assert_eq!(payload, std::borrow::Cow::from("foo123"));
|
|
118
|
+
/// ```
|
|
119
|
+
#[inline]
|
|
120
|
+
fn eq(&self, other: &T) -> bool {
|
|
121
|
+
self.as_str() == *other
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/// Status code used to indicate why an endpoint is closing the WebSocket connection.
|
|
126
|
+
#[derive(Debug, Clone, Eq, PartialEq)]
|
|
127
|
+
pub struct CloseCode(pub(super) u16);
|
|
128
|
+
|
|
129
|
+
impl CloseCode {
|
|
130
|
+
//! Constants for [`CloseCode`]s.
|
|
131
|
+
//!
|
|
132
|
+
//! [`CloseCode`]: super::CloseCode
|
|
133
|
+
|
|
134
|
+
/// Indicates a normal closure, meaning that the purpose for which the connection was
|
|
135
|
+
/// established has been fulfilled.
|
|
136
|
+
pub const NORMAL: CloseCode = CloseCode(1000);
|
|
137
|
+
|
|
138
|
+
/// Indicates that an endpoint is "going away", such as a server going down or a browser having
|
|
139
|
+
/// navigated away from a page.
|
|
140
|
+
pub const AWAY: CloseCode = CloseCode(1001);
|
|
141
|
+
|
|
142
|
+
/// Indicates that an endpoint is terminating the connection due to a protocol error.
|
|
143
|
+
pub const PROTOCOL: CloseCode = CloseCode(1002);
|
|
144
|
+
|
|
145
|
+
/// Indicates that an endpoint is terminating the connection because it has received a type of
|
|
146
|
+
/// data that it cannot accept.
|
|
147
|
+
///
|
|
148
|
+
/// For example, an endpoint MAY send this if it understands only text data, but receives a
|
|
149
|
+
/// binary message.
|
|
150
|
+
pub const UNSUPPORTED: CloseCode = CloseCode(1003);
|
|
151
|
+
|
|
152
|
+
/// Indicates that no status code was included in a closing frame.
|
|
153
|
+
pub const STATUS: CloseCode = CloseCode(1005);
|
|
154
|
+
|
|
155
|
+
/// Indicates an abnormal closure.
|
|
156
|
+
pub const ABNORMAL: CloseCode = CloseCode(1006);
|
|
157
|
+
|
|
158
|
+
/// Indicates that an endpoint is terminating the connection because it has received data
|
|
159
|
+
/// within a message that was not consistent with the type of the message.
|
|
160
|
+
///
|
|
161
|
+
/// For example, an endpoint received non-UTF-8 RFC3629 data within a text message.
|
|
162
|
+
pub const INVALID: CloseCode = CloseCode(1007);
|
|
163
|
+
|
|
164
|
+
/// Indicates that an endpoint is terminating the connection because it has received a message
|
|
165
|
+
/// that violates its policy.
|
|
166
|
+
///
|
|
167
|
+
/// This is a generic status code that can be returned when there is
|
|
168
|
+
/// no other more suitable status code (e.g., `UNSUPPORTED` or `SIZE`) or if there is a need to
|
|
169
|
+
/// hide specific details about the policy.
|
|
170
|
+
pub const POLICY: CloseCode = CloseCode(1008);
|
|
171
|
+
|
|
172
|
+
/// Indicates that an endpoint is terminating the connection because it has received a message
|
|
173
|
+
/// that is too big for it to process.
|
|
174
|
+
pub const SIZE: CloseCode = CloseCode(1009);
|
|
175
|
+
|
|
176
|
+
/// Indicates that an endpoint (client) is terminating the connection because the server
|
|
177
|
+
/// did not respond to extension negotiation correctly.
|
|
178
|
+
///
|
|
179
|
+
/// Specifically, the client has expected the server to negotiate one or more extension(s),
|
|
180
|
+
/// but the server didn't return them in the response message of the WebSocket handshake.
|
|
181
|
+
/// The list of extensions that are needed should be given as the reason for closing.
|
|
182
|
+
/// Note that this status code is not used by the server,
|
|
183
|
+
/// because it can fail the WebSocket handshake instead.
|
|
184
|
+
pub const EXTENSION: CloseCode = CloseCode(1010);
|
|
185
|
+
|
|
186
|
+
/// Indicates that a server is terminating the connection because it encountered an unexpected
|
|
187
|
+
/// condition that prevented it from fulfilling the request.
|
|
188
|
+
pub const ERROR: CloseCode = CloseCode(1011);
|
|
189
|
+
|
|
190
|
+
/// Indicates that the server is restarting.
|
|
191
|
+
pub const RESTART: CloseCode = CloseCode(1012);
|
|
192
|
+
|
|
193
|
+
/// Indicates that the server is overloaded and the client should either connect to a different
|
|
194
|
+
/// IP (when multiple targets exist), or reconnect to the same IP when a user has performed an
|
|
195
|
+
/// action.
|
|
196
|
+
pub const AGAIN: CloseCode = CloseCode(1013);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
impl From<CloseCode> for u16 {
|
|
200
|
+
#[inline]
|
|
201
|
+
fn from(code: CloseCode) -> u16 {
|
|
202
|
+
code.0
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
impl From<u16> for CloseCode {
|
|
207
|
+
#[inline]
|
|
208
|
+
fn from(code: u16) -> CloseCode {
|
|
209
|
+
CloseCode(code)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/// A struct representing the close command.
|
|
214
|
+
#[derive(Debug, Clone, Eq, PartialEq)]
|
|
215
|
+
pub struct CloseFrame {
|
|
216
|
+
/// The reason as a code.
|
|
217
|
+
pub code: CloseCode,
|
|
218
|
+
/// The reason as text string.
|
|
219
|
+
pub reason: Utf8Bytes,
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/// A WebSocket message.
|
|
223
|
+
//
|
|
224
|
+
// This code comes from https://github.com/snapview/tungstenite-rs/blob/master/src/protocol/message.rs and is under following license:
|
|
225
|
+
// Copyright (c) 2017 Alexey Galakhov
|
|
226
|
+
// Copyright (c) 2016 Jason Housley
|
|
227
|
+
//
|
|
228
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
229
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
230
|
+
// in the Software without restriction, including without limitation the rights
|
|
231
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
232
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
233
|
+
// furnished to do so, subject to the following conditions:
|
|
234
|
+
//
|
|
235
|
+
// The above copyright notice and this permission notice shall be included in
|
|
236
|
+
// all copies or substantial portions of the Software.
|
|
237
|
+
//
|
|
238
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
239
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
240
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
241
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
242
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
243
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
244
|
+
// THE SOFTWARE.
|
|
245
|
+
#[derive(Debug, Eq, PartialEq, Clone)]
|
|
246
|
+
pub enum Message {
|
|
247
|
+
/// A text WebSocket message
|
|
248
|
+
Text(Utf8Bytes),
|
|
249
|
+
/// A binary WebSocket message
|
|
250
|
+
Binary(Bytes),
|
|
251
|
+
/// A ping message with the specified payload
|
|
252
|
+
///
|
|
253
|
+
/// The payload here must have a length less than 125 bytes.
|
|
254
|
+
///
|
|
255
|
+
/// Ping messages will be automatically responded to by the server, so you do not have to worry
|
|
256
|
+
/// about dealing with them yourself.
|
|
257
|
+
Ping(Bytes),
|
|
258
|
+
/// A pong message with the specified payload
|
|
259
|
+
///
|
|
260
|
+
/// The payload here must have a length less than 125 bytes.
|
|
261
|
+
///
|
|
262
|
+
/// Pong messages will be automatically sent to the client if a ping message is received, so
|
|
263
|
+
/// you do not have to worry about constructing them yourself unless you want to implement a
|
|
264
|
+
/// [unidirectional heartbeat](https://tools.ietf.org/html/rfc6455#section-5.5.3).
|
|
265
|
+
Pong(Bytes),
|
|
266
|
+
/// A close message with the optional close frame.
|
|
267
|
+
///
|
|
268
|
+
/// You may "uncleanly" close a WebSocket connection at any time
|
|
269
|
+
/// by simply dropping the [`super::WebSocket`].
|
|
270
|
+
/// However, you may also use the graceful closing protocol, in which
|
|
271
|
+
/// 1. peer A sends a close frame, and does not send any further messages;
|
|
272
|
+
/// 2. peer B responds with a close frame, and does not send any further messages;
|
|
273
|
+
/// 3. peer A processes the remaining messages sent by peer B, before finally
|
|
274
|
+
/// 4. both peers close the connection.
|
|
275
|
+
///
|
|
276
|
+
/// After sending a close frame,
|
|
277
|
+
/// you may still read messages,
|
|
278
|
+
/// but attempts to send another message will error.
|
|
279
|
+
/// After receiving a close frame,
|
|
280
|
+
/// wreq will automatically respond with a close frame if necessary
|
|
281
|
+
/// (you do not have to deal with this yourself).
|
|
282
|
+
/// Since no further messages will be received,
|
|
283
|
+
/// you may either do nothing
|
|
284
|
+
/// or explicitly drop the connection.
|
|
285
|
+
Close(Option<CloseFrame>),
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
impl Message {
|
|
289
|
+
/// Converts this `Message` into a `tungstenite::Message`.
|
|
290
|
+
///
|
|
291
|
+
/// This method transforms the current `Message` instance into its corresponding
|
|
292
|
+
/// `tungstenite::Message` representation. This is useful when you need to work
|
|
293
|
+
/// with the `tungstenite` library directly.
|
|
294
|
+
///
|
|
295
|
+
/// # Returns
|
|
296
|
+
///
|
|
297
|
+
/// A `tungstenite::Message` instance that represents the current `Message`.
|
|
298
|
+
pub(super) fn into_tungstenite(self) -> tungstenite::Message {
|
|
299
|
+
match self {
|
|
300
|
+
Self::Text(text) => tungstenite::Message::Text(text.0),
|
|
301
|
+
Self::Binary(binary) => tungstenite::Message::Binary(binary),
|
|
302
|
+
Self::Ping(ping) => tungstenite::Message::Ping(ping),
|
|
303
|
+
Self::Pong(pong) => tungstenite::Message::Pong(pong),
|
|
304
|
+
Self::Close(Some(close)) => {
|
|
305
|
+
tungstenite::Message::Close(Some(tungstenite::protocol::CloseFrame {
|
|
306
|
+
code: tungstenite::protocol::frame::coding::CloseCode::from(close.code.0),
|
|
307
|
+
reason: close.reason.0,
|
|
308
|
+
}))
|
|
309
|
+
}
|
|
310
|
+
Self::Close(None) => tungstenite::Message::Close(None),
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/// Converts a `tungstenite::Message` into an `Option<Message>`.
|
|
315
|
+
///
|
|
316
|
+
/// This method transforms a given `tungstenite::Message` into its corresponding
|
|
317
|
+
/// `Message` representation. This is useful when you need to convert messages
|
|
318
|
+
/// received from the `tungstenite` library into the `Message` type used by this
|
|
319
|
+
/// library.
|
|
320
|
+
///
|
|
321
|
+
/// # Arguments
|
|
322
|
+
///
|
|
323
|
+
/// * `message` - The `tungstenite::Message` to convert.
|
|
324
|
+
///
|
|
325
|
+
/// # Returns
|
|
326
|
+
///
|
|
327
|
+
/// An `Option<Message>` instance that represents the given `tungstenite::Message`.
|
|
328
|
+
/// Returns `None` if the message is a `Frame` frame, as recommended by the
|
|
329
|
+
/// `tungstenite` maintainers.
|
|
330
|
+
pub(super) fn from_tungstenite(message: tungstenite::Message) -> Option<Self> {
|
|
331
|
+
match message {
|
|
332
|
+
tungstenite::Message::Text(text) => Some(Self::Text(Utf8Bytes(text))),
|
|
333
|
+
tungstenite::Message::Binary(binary) => Some(Self::Binary(binary)),
|
|
334
|
+
tungstenite::Message::Ping(ping) => Some(Self::Ping(ping)),
|
|
335
|
+
tungstenite::Message::Pong(pong) => Some(Self::Pong(pong)),
|
|
336
|
+
tungstenite::Message::Close(Some(close)) => Some(Self::Close(Some(CloseFrame {
|
|
337
|
+
code: CloseCode(close.code.into()),
|
|
338
|
+
reason: Utf8Bytes(close.reason),
|
|
339
|
+
}))),
|
|
340
|
+
tungstenite::Message::Close(None) => Some(Self::Close(None)),
|
|
341
|
+
// we can ignore `Frame` frames as recommended by the tungstenite maintainers
|
|
342
|
+
// https://github.com/snapview/tungstenite-rs/issues/268
|
|
343
|
+
tungstenite::Message::Frame(_) => None,
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/// Consume the WebSocket and return it as binary data.
|
|
348
|
+
pub fn into_data(self) -> Bytes {
|
|
349
|
+
match self {
|
|
350
|
+
Self::Text(string) => Bytes::from(string),
|
|
351
|
+
Self::Binary(data) | Self::Ping(data) | Self::Pong(data) => data,
|
|
352
|
+
Self::Close(None) => Bytes::new(),
|
|
353
|
+
Self::Close(Some(frame)) => Bytes::from(frame.reason),
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/// Attempt to consume the WebSocket message and convert it to a Utf8Bytes.
|
|
358
|
+
pub fn into_text(self) -> crate::Result<Utf8Bytes> {
|
|
359
|
+
match self {
|
|
360
|
+
Self::Text(string) => Ok(string),
|
|
361
|
+
Self::Binary(data) | Self::Ping(data) | Self::Pong(data) => {
|
|
362
|
+
Utf8Bytes::try_from(data).map_err(Error::decode)
|
|
363
|
+
}
|
|
364
|
+
Self::Close(None) => Ok(Utf8Bytes::default()),
|
|
365
|
+
Self::Close(Some(frame)) => Ok(frame.reason),
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/// Attempt to get a &str from the WebSocket message,
|
|
370
|
+
/// this will try to convert binary data to utf8.
|
|
371
|
+
pub fn to_text(&self) -> crate::Result<&str> {
|
|
372
|
+
match *self {
|
|
373
|
+
Self::Text(ref string) => Ok(string.as_str()),
|
|
374
|
+
Self::Binary(ref data) | Self::Ping(ref data) | Self::Pong(ref data) => {
|
|
375
|
+
std::str::from_utf8(data).map_err(Error::decode)
|
|
376
|
+
}
|
|
377
|
+
Self::Close(None) => Ok(""),
|
|
378
|
+
Self::Close(Some(ref frame)) => Ok(&frame.reason),
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
impl Message {
|
|
384
|
+
/// Create a new text WebSocket message from a stringable.
|
|
385
|
+
pub fn text<S>(string: S) -> Message
|
|
386
|
+
where
|
|
387
|
+
S: Into<Utf8Bytes>,
|
|
388
|
+
{
|
|
389
|
+
Message::Text(string.into())
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/// Create a new binary WebSocket message by converting to `Bytes`.
|
|
393
|
+
pub fn binary<B>(bin: B) -> Message
|
|
394
|
+
where
|
|
395
|
+
B: Into<Bytes>,
|
|
396
|
+
{
|
|
397
|
+
Message::Binary(bin.into())
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/// Create a new ping WebSocket message by converting to `Bytes`.
|
|
401
|
+
pub fn ping<B>(bin: B) -> Message
|
|
402
|
+
where
|
|
403
|
+
B: Into<Bytes>,
|
|
404
|
+
{
|
|
405
|
+
Message::Ping(bin.into())
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/// Create a new pong WebSocket message by converting to `Bytes`.
|
|
409
|
+
pub fn pong<B>(bin: B) -> Message
|
|
410
|
+
where
|
|
411
|
+
B: Into<Bytes>,
|
|
412
|
+
{
|
|
413
|
+
Message::Pong(bin.into())
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/// Create a new close WebSocket message with an optional close frame.
|
|
417
|
+
pub fn close<C>(close: C) -> Message
|
|
418
|
+
where
|
|
419
|
+
C: Into<Option<CloseFrame>>,
|
|
420
|
+
{
|
|
421
|
+
Message::Close(close.into())
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
impl From<String> for Message {
|
|
426
|
+
fn from(string: String) -> Self {
|
|
427
|
+
Message::Text(string.into())
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
impl<'s> From<&'s str> for Message {
|
|
432
|
+
fn from(string: &'s str) -> Self {
|
|
433
|
+
Message::Text(string.into())
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
impl<'b> From<&'b [u8]> for Message {
|
|
438
|
+
fn from(data: &'b [u8]) -> Self {
|
|
439
|
+
Message::Binary(Bytes::copy_from_slice(data))
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
impl From<Vec<u8>> for Message {
|
|
444
|
+
fn from(data: Vec<u8>) -> Self {
|
|
445
|
+
Message::Binary(data.into())
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
impl From<Message> for Vec<u8> {
|
|
450
|
+
fn from(msg: Message) -> Self {
|
|
451
|
+
msg.into_data().to_vec()
|
|
452
|
+
}
|
|
453
|
+
}
|