mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Add XHR support for FormData
This commit is contained in:
parent
c420a870c1
commit
184b522230
13 changed files with 173 additions and 174 deletions
|
@ -250,13 +250,6 @@ pub enum ResetFrom {
|
|||
|
||||
|
||||
impl HTMLFormElement {
|
||||
fn generate_boundary(&self) -> String {
|
||||
let i1 = random::<u32>();
|
||||
let i2 = random::<u32>();
|
||||
|
||||
format!("---------------------------{0}{1}", i1, i2)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#picking-an-encoding-for-the-form
|
||||
fn pick_encoding(&self) -> EncodingRef {
|
||||
// Step 2
|
||||
|
@ -275,66 +268,6 @@ impl HTMLFormElement {
|
|||
document_from_node(self).encoding()
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#multipart/form-data-encoding-algorithm
|
||||
fn encode_multipart_form_data(&self, form_data: &mut Vec<FormDatum>,
|
||||
boundary: String, encoding: EncodingRef) -> Vec<u8> {
|
||||
// Step 1
|
||||
let mut result = vec![];
|
||||
|
||||
// Step 2
|
||||
let charset = &*encoding.whatwg_name().unwrap_or("UTF-8");
|
||||
|
||||
// Step 3
|
||||
for entry in form_data.iter_mut() {
|
||||
// 3.1
|
||||
if entry.name == "_charset_" && entry.ty == "hidden" {
|
||||
entry.value = FormDatumValue::String(DOMString::from(charset.clone()));
|
||||
}
|
||||
// TODO: 3.2
|
||||
|
||||
// Step 4
|
||||
// https://tools.ietf.org/html/rfc7578#section-4
|
||||
// NOTE(izgzhen): The encoding here expected by most servers seems different from
|
||||
// what spec says (that it should start with a '\r\n').
|
||||
let mut boundary_bytes = format!("--{}\r\n", boundary).into_bytes();
|
||||
result.append(&mut boundary_bytes);
|
||||
let mut content_disposition = ContentDisposition {
|
||||
disposition: DispositionType::Ext("form-data".to_owned()),
|
||||
parameters: vec![DispositionParam::Ext("name".to_owned(), String::from(entry.name.clone()))]
|
||||
};
|
||||
|
||||
match entry.value {
|
||||
FormDatumValue::String(ref s) => {
|
||||
let mut bytes = format!("Content-Disposition: {}\r\n\r\n{}",
|
||||
content_disposition, s).into_bytes();
|
||||
result.append(&mut bytes);
|
||||
}
|
||||
FormDatumValue::File(ref f) => {
|
||||
content_disposition.parameters.push(
|
||||
DispositionParam::Filename(Charset::Ext(String::from(charset.clone())),
|
||||
None,
|
||||
f.name().clone().into()));
|
||||
// https://tools.ietf.org/html/rfc7578#section-4.4
|
||||
let content_type = ContentType(f.upcast::<Blob>().Type()
|
||||
.parse().unwrap_or(mime!(Text / Plain)));
|
||||
let mut type_bytes = format!("Content-Disposition: {}\r\n{}\r\n\r\n",
|
||||
content_disposition,
|
||||
content_type).into_bytes();
|
||||
result.append(&mut type_bytes);
|
||||
|
||||
let mut bytes = f.upcast::<Blob>().get_bytes().unwrap_or(vec![]);
|
||||
|
||||
result.append(&mut bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut boundary_bytes = format!("\r\n--{}--", boundary).into_bytes();
|
||||
result.append(&mut boundary_bytes);
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#text/plain-encoding-algorithm
|
||||
fn encode_plaintext(&self, form_data: &mut Vec<FormDatum>) -> String {
|
||||
// Step 1
|
||||
|
@ -459,7 +392,7 @@ impl HTMLFormElement {
|
|||
// https://html.spec.whatwg.org/multipage/#submit-body
|
||||
fn submit_entity_body(&self, form_data: &mut Vec<FormDatum>, mut load_data: LoadData,
|
||||
enctype: FormEncType, encoding: EncodingRef) {
|
||||
let boundary = self.generate_boundary();
|
||||
let boundary = generate_boundary();
|
||||
let bytes = match enctype {
|
||||
FormEncType::UrlEncoded => {
|
||||
let mut url = load_data.url.clone();
|
||||
|
@ -476,7 +409,7 @@ impl HTMLFormElement {
|
|||
FormEncType::FormDataEncoded => {
|
||||
let mime = mime!(Multipart / FormData; Boundary =(&boundary));
|
||||
load_data.headers.set(ContentType(mime));
|
||||
self.encode_multipart_form_data(form_data, boundary, encoding)
|
||||
encode_multipart_form_data(form_data, boundary, encoding)
|
||||
}
|
||||
FormEncType::TextPlainEncoded => {
|
||||
load_data.headers.set(ContentType(mime!(Text / Plain)));
|
||||
|
@ -718,12 +651,13 @@ impl HTMLFormElement {
|
|||
|
||||
}
|
||||
|
||||
#[derive(JSTraceable, HeapSizeOf, Clone)]
|
||||
pub enum FormDatumValue {
|
||||
File(Root<File>),
|
||||
String(DOMString)
|
||||
}
|
||||
|
||||
// #[derive(HeapSizeOf)]
|
||||
#[derive(HeapSizeOf, JSTraceable, Clone)]
|
||||
pub struct FormDatum {
|
||||
pub ty: DOMString,
|
||||
pub name: DOMString,
|
||||
|
@ -972,3 +906,72 @@ impl Runnable for PlannedNavigation {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#multipart/form-data-encoding-algorithm
|
||||
pub fn encode_multipart_form_data(form_data: &mut Vec<FormDatum>,
|
||||
boundary: String, encoding: EncodingRef) -> Vec<u8> {
|
||||
// Step 1
|
||||
let mut result = vec![];
|
||||
|
||||
// Step 2
|
||||
let charset = &*encoding.whatwg_name().unwrap_or("UTF-8");
|
||||
|
||||
// Step 3
|
||||
for entry in form_data.iter_mut() {
|
||||
// 3.1
|
||||
if entry.name == "_charset_" && entry.ty == "hidden" {
|
||||
entry.value = FormDatumValue::String(DOMString::from(charset.clone()));
|
||||
}
|
||||
// TODO: 3.2
|
||||
|
||||
// Step 4
|
||||
// https://tools.ietf.org/html/rfc7578#section-4
|
||||
// NOTE(izgzhen): The encoding here expected by most servers seems different from
|
||||
// what spec says (that it should start with a '\r\n').
|
||||
let mut boundary_bytes = format!("--{}\r\n", boundary).into_bytes();
|
||||
result.append(&mut boundary_bytes);
|
||||
let mut content_disposition = ContentDisposition {
|
||||
disposition: DispositionType::Ext("form-data".to_owned()),
|
||||
parameters: vec![DispositionParam::Ext("name".to_owned(), String::from(entry.name.clone()))]
|
||||
};
|
||||
|
||||
match entry.value {
|
||||
FormDatumValue::String(ref s) => {
|
||||
let mut bytes = format!("Content-Disposition: {}\r\n\r\n{}",
|
||||
content_disposition, s).into_bytes();
|
||||
result.append(&mut bytes);
|
||||
}
|
||||
FormDatumValue::File(ref f) => {
|
||||
content_disposition.parameters.push(
|
||||
DispositionParam::Filename(Charset::Ext(String::from(charset.clone())),
|
||||
None,
|
||||
f.name().clone().into()));
|
||||
// https://tools.ietf.org/html/rfc7578#section-4.4
|
||||
let content_type = ContentType(f.upcast::<Blob>().Type()
|
||||
.parse().unwrap_or(mime!(Text / Plain)));
|
||||
let mut type_bytes = format!("Content-Disposition: {}\r\ncontent-type: {}\r\n\r\n",
|
||||
content_disposition,
|
||||
content_type).into_bytes();
|
||||
result.append(&mut type_bytes);
|
||||
|
||||
let mut bytes = f.upcast::<Blob>().get_bytes().unwrap_or(vec![]);
|
||||
|
||||
result.append(&mut bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut boundary_bytes = format!("\r\n--{}--", boundary).into_bytes();
|
||||
result.append(&mut boundary_bytes);
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
// https://tools.ietf.org/html/rfc7578#section-4.1
|
||||
pub fn generate_boundary() -> String {
|
||||
let i1 = random::<u32>();
|
||||
let i2 = random::<u32>();
|
||||
|
||||
format!("---------------------------{0}{1}", i1, i2)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue