WebSocket Firefox
This commit is contained in:
@ -24,14 +24,13 @@ pub fn connection_handler(client: super::Stream) {
|
||||
fn request_handler(client: &mut super::HttpStream) {
|
||||
let mut res = super::Response::new();
|
||||
|
||||
if let Some(conn) = res.find_header("Connection") {
|
||||
client.client_keep_alive = client.client_keep_alive && conn.eq_ignore_ascii_case("keep-alive");
|
||||
}
|
||||
|
||||
match super::parser::parse_request(&mut client.stream) {
|
||||
Ok(Some(req)) => {
|
||||
println!("{} {}", req.method, req.uri);
|
||||
|
||||
client.client_keep_alive =
|
||||
client.client_keep_alive && req.header.field_has_value("Connection", "keep-alive");
|
||||
|
||||
if !req.uri.starts_with("/")
|
||||
|| req.uri.contains("/./")
|
||||
|| req.uri.contains("/../")
|
||||
@ -43,8 +42,8 @@ fn request_handler(client: &mut super::HttpStream) {
|
||||
} else if req.uri.eq("/") {
|
||||
res.status(200);
|
||||
} else if req.uri.starts_with("/_usimp/") {
|
||||
res.add_header("Cache-Control", "no-store");
|
||||
res.add_header("Access-Control-Allow-Origin", "*");
|
||||
res.header.add_field("Cache-Control", "no-store");
|
||||
res.header.add_field("Access-Control-Allow-Origin", "*");
|
||||
|
||||
if req.uri.eq("/_usimp/websocket") {
|
||||
return websocket::connection_handler(client, &req, res);
|
||||
@ -62,7 +61,7 @@ fn request_handler(client: &mut super::HttpStream) {
|
||||
Method::POST => return endpoint_handler(client, &req, res, endpoint),
|
||||
_ => {
|
||||
res.status(405);
|
||||
res.add_header("Allow", "POST");
|
||||
res.header.add_field("Allow", "POST");
|
||||
error = Some(Error::new(Kind::UsimpProtocolError, Class::ClientError))
|
||||
}
|
||||
},
|
||||
@ -119,8 +118,10 @@ pub fn error_handler(client: &mut super::HttpStream, mut res: super::Response, e
|
||||
let buf = obj.to_string() + "\r\n";
|
||||
|
||||
let length = buf.as_bytes().len();
|
||||
res.add_header("Content-Length", length.to_string().as_str());
|
||||
res.add_header("Content-Type", "application/json; charset=utf-8");
|
||||
res.header
|
||||
.add_field("Content-Length", length.to_string().as_str());
|
||||
res.header
|
||||
.add_field("Content-Type", "application/json; charset=utf-8");
|
||||
|
||||
if let Err(e) = client.respond(&mut res) {
|
||||
println!("Unable to send: {}", e);
|
||||
@ -136,7 +137,7 @@ fn endpoint_handler(
|
||||
mut res: super::Response,
|
||||
endpoint: &str,
|
||||
) {
|
||||
let length = req.find_header("Content-Length");
|
||||
let length = req.header.find_field("Content-Length");
|
||||
let length: usize = match match length {
|
||||
Some(length) => length,
|
||||
None => {
|
||||
@ -178,8 +179,10 @@ fn endpoint_handler(
|
||||
|
||||
// TODO compress
|
||||
let length = buf.as_bytes().len();
|
||||
res.add_header("Content-Length", length.to_string().as_str());
|
||||
res.add_header("Content-Type", "application/json; charset=utf-8");
|
||||
res.header
|
||||
.add_field("Content-Length", length.to_string().as_str());
|
||||
res.header
|
||||
.add_field("Content-Type", "application/json; charset=utf-8");
|
||||
|
||||
res.status(200);
|
||||
client.respond(&mut res).unwrap();
|
||||
|
@ -66,13 +66,13 @@ pub struct Request {
|
||||
version: String,
|
||||
pub method: Method,
|
||||
pub uri: String,
|
||||
header: Header,
|
||||
pub header: Header,
|
||||
}
|
||||
|
||||
pub struct Response {
|
||||
version: String,
|
||||
status: Status,
|
||||
header: Header,
|
||||
pub header: Header,
|
||||
}
|
||||
|
||||
impl Method {
|
||||
@ -200,15 +200,17 @@ impl Header {
|
||||
value: String::from(value),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Request {
|
||||
pub fn find_header(&self, name: &str) -> Option<&str> {
|
||||
self.header.find_field(name)
|
||||
}
|
||||
|
||||
pub fn add_header(&mut self, name: &str, value: &str) {
|
||||
self.header.add_field(name, value)
|
||||
pub fn field_has_value(&self, field_name: &str, value: &str) -> bool {
|
||||
if let Some(field) = self.find_field(field_name) {
|
||||
let value = value.to_lowercase();
|
||||
field
|
||||
.to_lowercase()
|
||||
.split(",")
|
||||
.any(|mut s| s.trim().eq(value.as_str()))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,8 +221,8 @@ impl Response {
|
||||
status: Status::from_code(200).unwrap(),
|
||||
header: Header::new(),
|
||||
};
|
||||
res.add_header("Server", "Locutus");
|
||||
res.add_header(
|
||||
res.header.add_field("Server", "Locutus");
|
||||
res.header.add_field(
|
||||
"Date",
|
||||
chrono::Utc::now()
|
||||
.format("%a, %d %b %Y %H:%M:%S GMT")
|
||||
@ -230,14 +232,6 @@ impl Response {
|
||||
res
|
||||
}
|
||||
|
||||
pub fn find_header(&self, name: &str) -> Option<&str> {
|
||||
self.header.find_field(name)
|
||||
}
|
||||
|
||||
pub fn add_header(&mut self, name: &str, value: &str) {
|
||||
self.header.add_field(name, value)
|
||||
}
|
||||
|
||||
pub fn status(&mut self, status_code: u16) {
|
||||
self.status = Status::from_code(status_code).unwrap()
|
||||
}
|
||||
@ -261,13 +255,14 @@ impl Response {
|
||||
|
||||
pub fn send_default(&mut self, stream: &mut Stream) -> Result<(), std::io::Error> {
|
||||
let mut buf = None;
|
||||
if let None = self.find_header("Content-Length") {
|
||||
if let None = self.header.find_field("Content-Length") {
|
||||
let new_buf = self.format_default_response();
|
||||
self.add_header(
|
||||
self.header.add_field(
|
||||
"Content-Length",
|
||||
new_buf.as_bytes().len().to_string().as_str(),
|
||||
);
|
||||
self.add_header("Content-Type", "text/html; charset=utf-8");
|
||||
self.header
|
||||
.add_field("Content-Type", "text/html; charset=utf-8");
|
||||
buf = Some(new_buf);
|
||||
}
|
||||
|
||||
@ -324,8 +319,8 @@ impl HttpStream {
|
||||
|
||||
fn keep_alive(&mut self, res: &mut Response) {
|
||||
if self.client_keep_alive && self.server_keep_alive {
|
||||
res.add_header("Connection", "keep-alive");
|
||||
res.add_header("Keep-Alive", "timeout=3600, max=200");
|
||||
res.header.add_field("Connection", "keep-alive");
|
||||
res.header.add_field("Keep-Alive", "timeout=3600, max=200");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ pub fn connection_handler(
|
||||
if let http::Method::GET = req.method {
|
||||
} else {
|
||||
res.status(405);
|
||||
res.add_header("Allow", "GET");
|
||||
res.header.add_field("Allow", "GET");
|
||||
return http::error_handler(
|
||||
client,
|
||||
res,
|
||||
@ -23,8 +23,8 @@ pub fn connection_handler(
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(connection) = req.find_header("Connection") {
|
||||
if !connection.eq_ignore_ascii_case("upgrade") {
|
||||
if let Some(_) = req.header.find_field("Connection") {
|
||||
if !req.header.field_has_value("Connection", "upgrade") {
|
||||
return http::error_handler(
|
||||
client,
|
||||
res,
|
||||
@ -41,7 +41,7 @@ pub fn connection_handler(
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(upgrade) = req.find_header("Upgrade") {
|
||||
if let Some(upgrade) = req.header.find_field("Upgrade") {
|
||||
if !upgrade.eq_ignore_ascii_case("websocket") {
|
||||
return http::error_handler(
|
||||
client,
|
||||
@ -59,7 +59,7 @@ pub fn connection_handler(
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(version) = req.find_header("Sec-WebSocket-Version") {
|
||||
if let Some(version) = req.header.find_field("Sec-WebSocket-Version") {
|
||||
if !version.eq("13") {
|
||||
return http::error_handler(
|
||||
client,
|
||||
@ -77,7 +77,7 @@ pub fn connection_handler(
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(key) = req.find_header("Sec-WebSocket-Key") {
|
||||
if let Some(key) = req.header.find_field("Sec-WebSocket-Key") {
|
||||
let mut hasher = crypto::sha1::Sha1::new();
|
||||
hasher.input_str(key);
|
||||
hasher.input_str("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
|
||||
@ -85,7 +85,7 @@ pub fn connection_handler(
|
||||
let mut result = [0u8; 160 / 8];
|
||||
hasher.result(&mut result);
|
||||
let key = base64::encode(result);
|
||||
res.add_header("Sec-WebSocket-Accept", key.as_str());
|
||||
res.header.add_field("Sec-WebSocket-Accept", key.as_str());
|
||||
} else {
|
||||
return http::error_handler(
|
||||
client,
|
||||
@ -96,8 +96,8 @@ pub fn connection_handler(
|
||||
}
|
||||
|
||||
client.server_keep_alive = false;
|
||||
res.add_header("Connection", "Upgrade");
|
||||
res.add_header("Upgrade", "websocket");
|
||||
res.header.add_field("Connection", "Upgrade");
|
||||
res.header.add_field("Upgrade", "websocket");
|
||||
|
||||
res.status(101);
|
||||
res.send(&mut client.stream).unwrap();
|
||||
|
Reference in New Issue
Block a user