mirror of
https://github.com/actix/actix-web.git
synced 2024-11-27 12:01:15 +00:00
ws/context: Increase write()
visibility to public (#402)
This type is introduced to avoid confusion between the `.binary()` and `.write_raw()` methods on WebSocket contexts
This commit is contained in:
parent
2988a84e5f
commit
0925a7691a
4 changed files with 31 additions and 20 deletions
|
@ -27,7 +27,7 @@ use client::{
|
||||||
Pipeline, SendRequest, SendRequestError,
|
Pipeline, SendRequest, SendRequestError,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::frame::Frame;
|
use super::frame::{Frame, FramedMessage};
|
||||||
use super::proto::{CloseReason, OpCode};
|
use super::proto::{CloseReason, OpCode};
|
||||||
use super::{Message, ProtocolError, WsWriter};
|
use super::{Message, ProtocolError, WsWriter};
|
||||||
|
|
||||||
|
@ -529,10 +529,10 @@ pub struct ClientWriter {
|
||||||
impl ClientWriter {
|
impl ClientWriter {
|
||||||
/// Write payload
|
/// Write payload
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, mut data: Binary) {
|
fn write(&mut self, mut data: FramedMessage) {
|
||||||
let inner = self.inner.borrow_mut();
|
let inner = self.inner.borrow_mut();
|
||||||
if !inner.closed {
|
if !inner.closed {
|
||||||
let _ = inner.tx.unbounded_send(data.take());
|
let _ = inner.tx.unbounded_send(data.0.take());
|
||||||
} else {
|
} else {
|
||||||
warn!("Trying to write to disconnected response");
|
warn!("Trying to write to disconnected response");
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ use context::{ActorHttpContext, Drain, Frame as ContextFrame};
|
||||||
use error::{Error, ErrorInternalServerError, PayloadError};
|
use error::{Error, ErrorInternalServerError, PayloadError};
|
||||||
use httprequest::HttpRequest;
|
use httprequest::HttpRequest;
|
||||||
|
|
||||||
use ws::frame::Frame;
|
use ws::frame::{Frame, FramedMessage};
|
||||||
use ws::proto::{CloseReason, OpCode};
|
use ws::proto::{CloseReason, OpCode};
|
||||||
use ws::{Message, ProtocolError, WsStream, WsWriter};
|
use ws::{Message, ProtocolError, WsStream, WsWriter};
|
||||||
|
|
||||||
|
@ -132,14 +132,19 @@ where
|
||||||
A: Actor<Context = Self>,
|
A: Actor<Context = Self>,
|
||||||
{
|
{
|
||||||
/// Write payload
|
/// Write payload
|
||||||
|
///
|
||||||
|
/// This is a low-level function that accepts framed messages that should
|
||||||
|
/// be created using `Frame::message()`. If you want to send text or binary
|
||||||
|
/// data you should prefer the `text()` or `binary()` convenience functions
|
||||||
|
/// that handle the framing for you.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, data: Binary) {
|
pub fn write_raw(&mut self, data: FramedMessage) {
|
||||||
if !self.disconnected {
|
if !self.disconnected {
|
||||||
if self.stream.is_none() {
|
if self.stream.is_none() {
|
||||||
self.stream = Some(SmallVec::new());
|
self.stream = Some(SmallVec::new());
|
||||||
}
|
}
|
||||||
let stream = self.stream.as_mut().unwrap();
|
let stream = self.stream.as_mut().unwrap();
|
||||||
stream.push(ContextFrame::Chunk(Some(data)));
|
stream.push(ContextFrame::Chunk(Some(data.0)));
|
||||||
} else {
|
} else {
|
||||||
warn!("Trying to write to disconnected response");
|
warn!("Trying to write to disconnected response");
|
||||||
}
|
}
|
||||||
|
@ -167,19 +172,19 @@ where
|
||||||
/// Send text frame
|
/// Send text frame
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn text<T: Into<Binary>>(&mut self, text: T) {
|
pub fn text<T: Into<Binary>>(&mut self, text: T) {
|
||||||
self.write(Frame::message(text.into(), OpCode::Text, true, false));
|
self.write_raw(Frame::message(text.into(), OpCode::Text, true, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send binary frame
|
/// Send binary frame
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn binary<B: Into<Binary>>(&mut self, data: B) {
|
pub fn binary<B: Into<Binary>>(&mut self, data: B) {
|
||||||
self.write(Frame::message(data, OpCode::Binary, true, false));
|
self.write_raw(Frame::message(data, OpCode::Binary, true, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send ping frame
|
/// Send ping frame
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ping(&mut self, message: &str) {
|
pub fn ping(&mut self, message: &str) {
|
||||||
self.write(Frame::message(
|
self.write_raw(Frame::message(
|
||||||
Vec::from(message),
|
Vec::from(message),
|
||||||
OpCode::Ping,
|
OpCode::Ping,
|
||||||
true,
|
true,
|
||||||
|
@ -190,7 +195,7 @@ where
|
||||||
/// Send pong frame
|
/// Send pong frame
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn pong(&mut self, message: &str) {
|
pub fn pong(&mut self, message: &str) {
|
||||||
self.write(Frame::message(
|
self.write_raw(Frame::message(
|
||||||
Vec::from(message),
|
Vec::from(message),
|
||||||
OpCode::Pong,
|
OpCode::Pong,
|
||||||
true,
|
true,
|
||||||
|
@ -201,7 +206,7 @@ where
|
||||||
/// Send close frame
|
/// Send close frame
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn close(&mut self, reason: Option<CloseReason>) {
|
pub fn close(&mut self, reason: Option<CloseReason>) {
|
||||||
self.write(Frame::close(reason, false));
|
self.write_raw(Frame::close(reason, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if connection still open
|
/// Check if connection still open
|
||||||
|
|
|
@ -28,7 +28,7 @@ impl Frame {
|
||||||
|
|
||||||
/// Create a new Close control frame.
|
/// Create a new Close control frame.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn close(reason: Option<CloseReason>, genmask: bool) -> Binary {
|
pub fn close(reason: Option<CloseReason>, genmask: bool) -> FramedMessage {
|
||||||
let payload = match reason {
|
let payload = match reason {
|
||||||
None => Vec::new(),
|
None => Vec::new(),
|
||||||
Some(reason) => {
|
Some(reason) => {
|
||||||
|
@ -295,7 +295,7 @@ impl Frame {
|
||||||
/// Generate binary representation
|
/// Generate binary representation
|
||||||
pub fn message<B: Into<Binary>>(
|
pub fn message<B: Into<Binary>>(
|
||||||
data: B, code: OpCode, finished: bool, genmask: bool,
|
data: B, code: OpCode, finished: bool, genmask: bool,
|
||||||
) -> Binary {
|
) -> FramedMessage {
|
||||||
let payload = data.into();
|
let payload = data.into();
|
||||||
let one: u8 = if finished {
|
let one: u8 = if finished {
|
||||||
0x80 | Into::<u8>::into(code)
|
0x80 | Into::<u8>::into(code)
|
||||||
|
@ -325,7 +325,7 @@ impl Frame {
|
||||||
buf
|
buf
|
||||||
};
|
};
|
||||||
|
|
||||||
if genmask {
|
let binary = if genmask {
|
||||||
let mask = rand::random::<u32>();
|
let mask = rand::random::<u32>();
|
||||||
buf.put_u32_le(mask);
|
buf.put_u32_le(mask);
|
||||||
buf.extend_from_slice(payload.as_ref());
|
buf.extend_from_slice(payload.as_ref());
|
||||||
|
@ -335,7 +335,9 @@ impl Frame {
|
||||||
} else {
|
} else {
|
||||||
buf.put_slice(payload.as_ref());
|
buf.put_slice(payload.as_ref());
|
||||||
buf.into()
|
buf.into()
|
||||||
}
|
};
|
||||||
|
|
||||||
|
FramedMessage(binary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,6 +374,10 @@ impl fmt::Display for Frame {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `WebSocket` message with framing.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FramedMessage(pub(crate) Binary);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -502,7 +508,7 @@ mod tests {
|
||||||
|
|
||||||
let mut v = vec![137u8, 4u8];
|
let mut v = vec![137u8, 4u8];
|
||||||
v.extend(b"data");
|
v.extend(b"data");
|
||||||
assert_eq!(frame, v.into());
|
assert_eq!(frame.0, v.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -511,7 +517,7 @@ mod tests {
|
||||||
|
|
||||||
let mut v = vec![138u8, 4u8];
|
let mut v = vec![138u8, 4u8];
|
||||||
v.extend(b"data");
|
v.extend(b"data");
|
||||||
assert_eq!(frame, v.into());
|
assert_eq!(frame.0, v.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -521,12 +527,12 @@ mod tests {
|
||||||
|
|
||||||
let mut v = vec![136u8, 6u8, 3u8, 232u8];
|
let mut v = vec![136u8, 6u8, 3u8, 232u8];
|
||||||
v.extend(b"data");
|
v.extend(b"data");
|
||||||
assert_eq!(frame, v.into());
|
assert_eq!(frame.0, v.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_empty_close_frame() {
|
fn test_empty_close_frame() {
|
||||||
let frame = Frame::close(None, false);
|
let frame = Frame::close(None, false);
|
||||||
assert_eq!(frame, vec![0x88, 0x00].into());
|
assert_eq!(frame.0, vec![0x88, 0x00].into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub use self::client::{
|
||||||
Client, ClientError, ClientHandshake, ClientReader, ClientWriter,
|
Client, ClientError, ClientHandshake, ClientReader, ClientWriter,
|
||||||
};
|
};
|
||||||
pub use self::context::WebsocketContext;
|
pub use self::context::WebsocketContext;
|
||||||
pub use self::frame::Frame;
|
pub use self::frame::{Frame, FramedMessage};
|
||||||
pub use self::proto::{CloseCode, CloseReason, OpCode};
|
pub use self::proto::{CloseCode, CloseReason, OpCode};
|
||||||
|
|
||||||
/// Websocket protocol errors
|
/// Websocket protocol errors
|
||||||
|
|
Loading…
Reference in a new issue