mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 05:51:39 +00:00
Factor out general web utilities to web_util
This commit is contained in:
parent
8d4213ddf1
commit
86d6cc5259
3 changed files with 73 additions and 69 deletions
|
|
@ -13,6 +13,7 @@ extern crate tempfile;
|
||||||
pub mod rbx_session;
|
pub mod rbx_session;
|
||||||
pub mod id;
|
pub mod id;
|
||||||
pub mod web;
|
pub mod web;
|
||||||
|
pub mod web_util;
|
||||||
pub mod core;
|
pub mod core;
|
||||||
pub mod project;
|
pub mod project;
|
||||||
pub mod pathext;
|
pub mod pathext;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,12 @@
|
||||||
use std::io::Read;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use rouille;
|
use rouille;
|
||||||
use serde;
|
|
||||||
use serde_json;
|
|
||||||
|
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use vfs::{VfsSession, VfsChange};
|
use vfs::{VfsSession, VfsChange};
|
||||||
use rbx::RbxInstance;
|
use rbx::RbxInstance;
|
||||||
use middleware::MiddlewareChain;
|
use middleware::MiddlewareChain;
|
||||||
|
use web_util::{json, read_json};
|
||||||
static MAX_BODY_SIZE: usize = 25 * 1024 * 1024; // 25 MiB
|
|
||||||
|
|
||||||
/// The set of configuration the web server needs to start.
|
/// The set of configuration the web server needs to start.
|
||||||
pub struct WebConfig {
|
pub struct WebConfig {
|
||||||
|
|
@ -52,70 +48,6 @@ struct WriteSpecifier {
|
||||||
item: RbxInstance,
|
item: RbxInstance,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn json<T: serde::Serialize>(value: T) -> rouille::Response {
|
|
||||||
let data = serde_json::to_string(&value).unwrap();
|
|
||||||
rouille::Response::from_data("application/json", data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Pulls text that may be JSON out of a Rouille Request object.
|
|
||||||
///
|
|
||||||
/// Doesn't do any actual parsing -- all this method does is verify the content
|
|
||||||
/// type of the request and read the request's body.
|
|
||||||
fn read_json_text(request: &rouille::Request) -> Option<String> {
|
|
||||||
// Bail out if the request body isn't marked as JSON
|
|
||||||
match request.header("Content-Type") {
|
|
||||||
Some(header) => if !header.starts_with("application/json") {
|
|
||||||
return None;
|
|
||||||
},
|
|
||||||
None => return None,
|
|
||||||
}
|
|
||||||
|
|
||||||
let body = match request.data() {
|
|
||||||
Some(v) => v,
|
|
||||||
None => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allocate a buffer and read up to MAX_BODY_SIZE+1 bytes into it.
|
|
||||||
let mut out = Vec::new();
|
|
||||||
match body.take(MAX_BODY_SIZE.saturating_add(1) as u64).read_to_end(&mut out) {
|
|
||||||
Ok(_) => {},
|
|
||||||
Err(_) => return None,
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the body was too big (MAX_BODY_SIZE+1), we abort instead of trying to
|
|
||||||
// process it.
|
|
||||||
if out.len() > MAX_BODY_SIZE {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let parsed = match String::from_utf8(out) {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(_) => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(parsed)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads the body out of a Rouille Request and attempts to turn it into JSON.
|
|
||||||
fn read_json<T>(request: &rouille::Request) -> Option<T>
|
|
||||||
where
|
|
||||||
T: serde::de::DeserializeOwned,
|
|
||||||
{
|
|
||||||
let body = match read_json_text(&request) {
|
|
||||||
Some(v) => v,
|
|
||||||
None => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let parsed = match serde_json::from_str(&body) {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(_) => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Change return type to some sort of Result
|
|
||||||
|
|
||||||
Some(parsed)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Start the Rojo web server and park our current thread.
|
/// Start the Rojo web server and park our current thread.
|
||||||
pub fn start(config: WebConfig, project: Project, middleware_chain: &'static MiddlewareChain, vfs: Arc<Mutex<VfsSession>>) {
|
pub fn start(config: WebConfig, project: Project, middleware_chain: &'static MiddlewareChain, vfs: Arc<Mutex<VfsSession>>) {
|
||||||
let address = format!("localhost:{}", config.port);
|
let address = format!("localhost:{}", config.port);
|
||||||
|
|
|
||||||
71
server/src/web_util.rs
Normal file
71
server/src/web_util.rs
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
use rouille;
|
||||||
|
use serde;
|
||||||
|
use serde_json;
|
||||||
|
|
||||||
|
static MAX_BODY_SIZE: usize = 25 * 1024 * 1024; // 25 MiB
|
||||||
|
|
||||||
|
pub fn json<T: serde::Serialize>(value: T) -> rouille::Response {
|
||||||
|
let data = serde_json::to_string(&value).unwrap();
|
||||||
|
rouille::Response::from_data("application/json", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pulls text that may be JSON out of a Rouille Request object.
|
||||||
|
///
|
||||||
|
/// Doesn't do any actual parsing -- all this method does is verify the content
|
||||||
|
/// type of the request and read the request's body.
|
||||||
|
pub fn read_json_text(request: &rouille::Request) -> Option<String> {
|
||||||
|
// Bail out if the request body isn't marked as JSON
|
||||||
|
match request.header("Content-Type") {
|
||||||
|
Some(header) => if !header.starts_with("application/json") {
|
||||||
|
return None;
|
||||||
|
},
|
||||||
|
None => return None,
|
||||||
|
}
|
||||||
|
|
||||||
|
let body = match request.data() {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Allocate a buffer and read up to MAX_BODY_SIZE+1 bytes into it.
|
||||||
|
let mut out = Vec::new();
|
||||||
|
match body.take(MAX_BODY_SIZE.saturating_add(1) as u64).read_to_end(&mut out) {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(_) => return None,
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the body was too big (MAX_BODY_SIZE+1), we abort instead of trying to
|
||||||
|
// process it.
|
||||||
|
if out.len() > MAX_BODY_SIZE {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsed = match String::from_utf8(out) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads the body out of a Rouille Request and attempts to turn it into JSON.
|
||||||
|
pub fn read_json<T>(request: &rouille::Request) -> Option<T>
|
||||||
|
where
|
||||||
|
T: serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
let body = match read_json_text(&request) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let parsed = match serde_json::from_str(&body) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Change return type to some sort of Result
|
||||||
|
|
||||||
|
Some(parsed)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue