我不知道除了使用原始后期数据字符串作为输入手动解析多部分表单之外你是怎么想的
我将尝试调整Hyper示例,但任何帮助将不胜感激.
相关问题:
Rocket对数据的主要抽象是FromData特征.给定POST数据和请求,您可以构造给定的类型:
pub trait FromData: Sized {
type Error;
fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error>;
}
Run Code Online (Sandbox Code Playgroud)
#![feature(plugin)]
#![plugin(rocket_codegen)]
extern crate rocket;
extern crate multipart;
#[post("/", data = "<upload>")]
fn index(upload: DummyMultipart) -> String {
format!("I read this: {:?}", upload)
}
#[derive(Debug)]
struct DummyMultipart {
alpha: String,
one: i32,
file: Vec<u8>,
}
use std::io::{Cursor, Read};
use rocket::{Request, Data, Outcome};
use rocket::data::{self, FromData};
use multipart::server::Multipart;
impl FromData for DummyMultipart {
type Error = ();
fn from_data(request: &Request, data: Data) -> data::Outcome<Self, Self::Error> {
// All of these errors should be reported
let ct = request.headers().get_one("Content-Type").expect("no content-type");
let idx = ct.find("boundary=").expect("no boundary");
let boundary = &ct[(idx + "boundary=".len())..];
let mut d = Vec::new();
data.stream_to(&mut d).expect("Unable to read");
let mut mp = Multipart::with_body(Cursor::new(d), boundary);
// Custom implementation parts
let mut alpha = None;
let mut one = None;
let mut file = None;
mp.foreach_entry(|mut entry| {
match entry.name.as_str() {
"alpha" => {
let t = entry.data.as_text().expect("not text");
alpha = Some(t.into());
},
"one" => {
let t = entry.data.as_text().expect("not text");
let n = t.parse().expect("not number");
one = Some(n);
},
"file" => {
let mut d = Vec::new();
let f = entry.data.as_file().expect("not file");
f.read_to_end(&mut d).expect("cant read");
file = Some(d);
},
other => panic!("No known key {}", other),
}
}).expect("Unable to iterate");
let v = DummyMultipart {
alpha: alpha.expect("alpha not set"),
one: one.expect("one not set"),
file: file.expect("file not set"),
};
// End custom
Outcome::Success(v)
}
}
fn main() {
rocket::ignite().mount("/", routes![index]).launch();
}
Run Code Online (Sandbox Code Playgroud)
我在大约一个小时之前从未使用过这些API,因此无法保证这是一个很好的实现.事实上,所有对错误的恐慌绝对意味着它不是最理想的.生产用法可以干净地处理所有这些.
但是,它确实有效:
$ curl -X POST -F alpha=omega -F one=2 -F file=@hello http://localhost:8000/
I read this: DummyMultipart { alpha: "omega", one: 2, file: [104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 10] }
Run Code Online (Sandbox Code Playgroud)
高级实现将允许在用户特定数据和通用多部分方面之间进行一些抽象.像Multipart<MyForm>这样的东西会很好.
Rocket的作者指出,这个解决方案允许恶意最终用户POST一个无限大小的文件,这会导致机器内存不足.根据预期用途,您可能希望在读取的字节数上建立某种上限,可能会在某个断点处写入文件系统.