http_request/request/socket/shared/
impl.rs1use http_type::{HTTP_LOWERCASE, HTTP_UPPERCASE};
2
3use crate::*;
4
5impl std::fmt::Display for WebSocketError {
6 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
7 match self.kind {
8 WebSocketErrorKind::Connection => write!(f, "Connection error: {}", self.message),
9 WebSocketErrorKind::String => write!(f, "String error: {}", self.message),
10 WebSocketErrorKind::Timeout => write!(f, "Timeout error: {}", self.message),
11 WebSocketErrorKind::InvalidUrl => write!(f, "Invalid URL: {}", self.message),
12 WebSocketErrorKind::Io => write!(f, "IO error: {}", self.message),
13 WebSocketErrorKind::Tls => write!(f, "TLS error: {}", self.message),
14 }
15 }
16}
17
18impl std::error::Error for WebSocketError {}
19
20impl WebSocketError {
21 pub(crate) fn connection<T: ToString>(message: T) -> Self {
22 Self {
23 kind: WebSocketErrorKind::Connection,
24 message: message.to_string(),
25 }
26 }
27
28 pub(crate) fn protocol<T: ToString>(message: T) -> Self {
29 Self {
30 kind: WebSocketErrorKind::String,
31 message: message.to_string(),
32 }
33 }
34
35 pub(crate) fn timeout<T: ToString>(message: T) -> Self {
36 Self {
37 kind: WebSocketErrorKind::Timeout,
38 message: message.to_string(),
39 }
40 }
41
42 pub(crate) fn invalid_url<T: ToString>(message: T) -> Self {
43 Self {
44 kind: WebSocketErrorKind::InvalidUrl,
45 message: message.to_string(),
46 }
47 }
48
49 pub(crate) fn io<T: ToString>(message: T) -> Self {
50 Self {
51 kind: WebSocketErrorKind::Io,
52 message: message.to_string(),
53 }
54 }
55
56 pub(crate) fn tls<T: ToString>(message: T) -> Self {
57 Self {
58 kind: WebSocketErrorKind::Tls,
59 message: message.to_string(),
60 }
61 }
62}
63
64impl SharedWebSocketBuilder {
65 pub(crate) fn parse_url(url: &str) -> Result<HttpUrlComponents, WebSocketError> {
66 if url.is_empty() {
67 return Err(WebSocketError::invalid_url("URL is empty"));
68 }
69 let mut url_obj: HttpUrlComponents = HttpUrlComponents::default();
70 if url.starts_with("ws://") {
71 url_obj.protocol = HTTP_LOWERCASE.to_string();
72 url_obj.port = Some(80);
73 } else if url.starts_with("wss://") {
74 url_obj.protocol = HTTP_UPPERCASE.to_string();
75 url_obj.port = Some(443);
76 } else {
77 return Err(WebSocketError::invalid_url("Invalid WebSocket URL scheme"));
78 }
79 let without_protocol: &str = if let Some(stripped) = url.strip_prefix("ws://") {
80 stripped
81 } else {
82 &url[6..]
83 };
84 let parts: Vec<&str> = without_protocol.splitn(2, '/').collect();
85 let host_port: &str = parts[0];
86 let path: &str = if parts.len() > 1 { parts[1] } else { "" };
87 if host_port.contains(':') {
88 let host_port_parts: Vec<&str> = host_port.splitn(2, ':').collect();
89 url_obj.host = Some(host_port_parts[0].to_string());
90 if let Ok(port) = host_port_parts[1].parse::<u16>() {
91 url_obj.port = Some(port);
92 }
93 } else {
94 url_obj.host = Some(host_port.to_string());
95 }
96 url_obj.path = Some(if path.is_empty() {
97 "/".to_string()
98 } else {
99 format!("/{path}")
100 });
101 Ok(url_obj)
102 }
103}