diff options
author | Zhen Zhang <izgzhen@gmail.com> | 2016-08-08 20:55:26 +0200 |
---|---|---|
committer | Zhen Zhang <izgzhen@gmail.com> | 2016-08-10 12:58:35 +0200 |
commit | 184b52223091cd822dbacb79eea6bde6b992d2e3 (patch) | |
tree | f1b9fd4c2e02ba87ecf6280f042ac8233b221fc7 /components/script/dom/htmlformelement.rs | |
parent | c420a870c1b1bca7e740e8bb737ef2bcdb1a139d (diff) | |
download | servo-184b52223091cd822dbacb79eea6bde6b992d2e3.tar.gz servo-184b52223091cd822dbacb79eea6bde6b992d2e3.zip |
Add XHR support for FormData
Diffstat (limited to 'components/script/dom/htmlformelement.rs')
-rw-r--r-- | components/script/dom/htmlformelement.rs | 143 |
1 files changed, 73 insertions, 70 deletions
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 72b8cc19c16..db9e3cb8d41 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -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) +} |