websocket_stream/util.rs
1// The MIT License (MIT)
2//
3// Copyright (c) 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21// SOFTWARE.
22
23
24use std::fmt;
25
26
27/// Decodes OpCode
28pub const OP_CODE_UN_MASK: u8 = 0b0000_1111;
29
30/// Encodes OpCode
31pub const OP_CODE_MASK: u8 = 0b1000_0000;
32
33/// Decodes payload
34pub const PAYLOAD_KEY_UN_MASK: u8 = 0b0111_1111;
35
36/// Continuation Op byte
37pub const OP_CONTINUATION: u8 = 0x0;
38
39/// Text Op byte
40pub const OP_TEXT: u8 = 0x1;
41
42/// Binary Op byte
43pub const OP_BINARY: u8 = 0x2;
44
45/// Close Op byte
46pub const OP_CLOSE: u8 = 0x8;
47
48/// Ping Op byte
49pub const OP_PING: u8 = 0x9;
50
51/// Pong Op byte
52pub const OP_PONG: u8 = 0xA;
53
54
55#[derive(Debug, Clone)]
56pub enum OpCode {
57 /// Continuation frame from last packed
58 Continuation,
59
60 /// UTF-8 text data
61 Text,
62
63 /// Binary data as u8
64 Binary,
65
66 /// Indicates client has closed connection
67 Close,
68
69 /// Heartbeat requested from client
70 Ping,
71
72 /// Heartbeat response to ping frame
73 /// Can also be sent without a ping request
74 Pong
75}
76
77#[derive(Debug)]
78pub enum ReadError {
79 /// Non-blocking I/O has been selected using O_NONBLOCK and the
80 /// read would block.
81 EAGAIN,
82
83 /// fd is not a valid file descriptor or is not open for reading
84 EBADF,
85
86 /// buf is outside your accessible address space
87 EFAULT,
88
89 /// The call was interrupted by a signal before any data was read
90 EINTR,
91
92 /// fd is attached to an object which is unsuitable for reading;
93 /// or the file was opened with the O_DIRECT flag, and either the address
94 /// specified in buf, the value specified in count, or the current file
95 /// offset is not suitably aligned
96 EINVAL,
97
98 /// I/O error. This will happen for example when the process is in a
99 /// background process group, tries to read from its controlling tty,
100 /// and either it is ignoring or blocking SIGTTIN or its process group
101 /// is orphaned. It may also occur when there is a low-level I/O error
102 /// while reading from a disk or tape.
103 EIO,
104
105 /// fd refers to a directory.
106 EISDIR,
107
108 /// Insufficient memory is available
109 ENOMEM,
110
111 /// Invalid OpCode.
112 /// According to RFC-6455: "If an unknown opcode is received,
113 /// the receiving endpoint MUST _Fail the WebSocket Connection_"
114 OpCode
115}
116
117#[derive(Debug)]
118pub enum WriteError {
119 /// Non-blocking I/O has been selected using O_NONBLOCK and the
120 /// write would block.
121 EAGAIN,
122
123 /// fd is not a valid file descriptor or is not open for writing.
124 EBADF,
125
126 /// buf is outside your accessible address space.
127 EFAULT,
128
129 /// An attempt was made to write a file that exceeds the
130 /// implementation-defined maximum file size or the process’ file size
131 /// limit, or to write at a position past the maximum allowed offset.
132 EFBIG,
133
134 /// The call was interrupted by a signal before any data was written.
135 EINTR,
136
137 /// fd is attached to an object which is unsuitable for writing; or the
138 /// file was opened with the O_DIRECT flag, and either the address
139 /// specified in buf, the value specified in count, or the current file
140 /// offset is not suitably aligned.
141 EINVAL,
142
143 /// A low-level I/O error occurred while modifying the inode.
144 EIO,
145
146 /// The device containing the file referred to by fd has no room for
147 /// the data.
148 ENOSPC,
149
150 /// fd is connected to a pipe or socket whose reading end is closed.
151 /// When this happens the writing process will also receive a SIGPIPE
152 /// signal. (Thus, the write return value is seen only if the program
153 /// catches, blocks or ignores this signal.)
154 EPIPE
155}
156
157#[derive(Debug)]
158pub enum SetFdError {
159 /// Operation is prohibited by locks held by other processes.
160 EACCES,
161
162 /// Operation is prohibited by locks held by other processes.
163 EAGAIN,
164
165 /// fd is not an open file descriptor, or the command was F_SETLK or
166 /// F_SETLKW and the file descriptor open mode doesn’t match with the
167 /// type of lock requested.
168 EBADF,
169
170 /// It was detected that the specified F_SETLKW command would
171 /// cause a deadlock.
172 EDEADLK,
173
174 /// lock is outside your accessible address space.
175 EFAULT,
176
177 /// For F_SETLKW, the command was interrupted by a signal. For F_GETLK
178 /// and F_SETLK, the command was interrupted by a signal before the lock
179 /// was checked or acquired. Most likely when locking a remote file
180 /// (e.g. locking over NFS), but can sometimes happen locally.
181 EINTR,
182
183 /// For F_DUPFD, arg is negative or is greater than the maximum allowable
184 /// value. For F_SETSIG, arg is not an allowable signal number.
185 EINVAL,
186
187 /// For F_DUPFD, the process already has the maximum number of file
188 /// descriptors open.
189 EMFILE,
190
191 /// Too many segment locks open, lock table is full, or a remote locking
192 /// protocol failed (e.g. locking over NFS).
193 ENOLCK,
194
195 /// Attempted to clear the O_APPEND flag on a file that has the
196 /// append-only attribute set.
197 EPERM
198}
199
200impl fmt::Display for ReadError {
201 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
202 match *self {
203 ReadError::EAGAIN => "EAGAIN".fmt(f),
204 ReadError::EBADF => "EBADF".fmt(f),
205 ReadError::EFAULT => "EFAULT".fmt(f),
206 ReadError::EINTR => "EINTR".fmt(f),
207 ReadError::EINVAL => "EINVAL".fmt(f),
208 ReadError::EIO => "EIO".fmt(f),
209 ReadError::EISDIR => "EISDIR".fmt(f),
210 ReadError::ENOMEM => "ENOMEM".fmt(f),
211 ReadError::OpCode => "OpCode".fmt(f)
212 }
213 }
214}
215
216impl fmt::Display for WriteError {
217 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
218 match *self {
219 WriteError::EAGAIN => "EAGAIN".fmt(f),
220 WriteError::EBADF => "EBADF".fmt(f),
221 WriteError::EFAULT => "EFAULT".fmt(f),
222 WriteError::EFBIG => "EFBIG".fmt(f),
223 WriteError::EINTR => "EINTR".fmt(f),
224 WriteError::EINVAL => "EINVAL".fmt(f),
225 WriteError::EIO => "EIO".fmt(f),
226 WriteError::ENOSPC => "ENOSPC".fmt(f),
227 WriteError::EPIPE => "EPIPE".fmt(f)
228 }
229 }
230}
231
232impl fmt::Display for SetFdError {
233 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
234 match *self {
235 SetFdError::EACCES => "EACCES".fmt(f),
236 SetFdError::EAGAIN => "EAGAIN".fmt(f),
237 SetFdError::EBADF => "EBADF".fmt(f),
238 SetFdError::EDEADLK => "EDEADLK".fmt(f),
239 SetFdError::EFAULT => "EFAULT".fmt(f),
240 SetFdError::EINTR => "EINTR".fmt(f),
241 SetFdError::EINVAL => "EINVAL".fmt(f),
242 SetFdError::EMFILE => "EMFILE".fmt(f),
243 SetFdError::ENOLCK => "ENOLCK".fmt(f),
244 SetFdError::EPERM => "EPERM".fmt(f)
245 }
246 }
247}
248
249impl fmt::Display for OpCode {
250 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
251 match *self {
252 OpCode::Continuation => "Continuation".fmt(f),
253 OpCode::Text => "Text".fmt(f),
254 OpCode::Binary => "Binary".fmt(f),
255 OpCode::Close => "Close".fmt(f),
256 OpCode::Ping => "Ping".fmt(f),
257 OpCode::Pong => "Pong".fmt(f),
258 }
259 }
260}