mirror of
https://github.com/OMGeeky/google-apis-rs.git
synced 2026-01-22 19:21:27 +01:00
fix(CLI): simple and resumable upload works
* fixed boundary syntax of multi-part message. Was --BOUNDARY, now is --BOUNDARY-- * Fixed ContentRange parsing and serialization. We actually managed to break it last time we tried to update it to match the Go implementation. * fixed uploadType header parameter. It's based on chosen protocol and whether or not the method supports multipart operation for the given protocol. Related to #76
This commit is contained in:
@@ -496,6 +496,14 @@ match result {
|
||||
% for p in field_params:
|
||||
<%
|
||||
pname = 'self.' + property(p.name) # property identifier
|
||||
if media_params and 'mediaUpload' in m:
|
||||
upload_type_map = dict()
|
||||
for mp in media_params:
|
||||
if mp.protocol == 'simple':
|
||||
upload_type_map[mp.protocol] = m.mediaUpload.protocols.simple.multipart and 'multipart' or 'media'
|
||||
break
|
||||
# for each meadia param
|
||||
# end build media param map
|
||||
%>\
|
||||
## parts can also be derived from the request, but we do that only if it's not set
|
||||
% if p.name == 'part' and request_value:
|
||||
@@ -561,21 +569,21 @@ match result {
|
||||
% endif ## response schema
|
||||
|
||||
% if media_params:
|
||||
let mut url = \
|
||||
let (mut url, upload_type) =
|
||||
% for mp in media_params:
|
||||
% if loop.first:
|
||||
if \
|
||||
if \
|
||||
% else:
|
||||
else if \
|
||||
% endif
|
||||
protocol == "${mp.protocol}" {
|
||||
"${join_url(rootUrl, mp.path)}".to_string()
|
||||
("${join_url(rootUrl, mp.path)}".to_string(), "${upload_type_map.get(mp.protocol, mp.protocol)}")
|
||||
} \
|
||||
% endfor
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
params.push(("uploadType", protocol.to_string()));
|
||||
};
|
||||
params.push(("uploadType", upload_type.to_string()));
|
||||
% else:
|
||||
let mut url = "${baseUrl}${m.path}".to_string();
|
||||
% endif
|
||||
@@ -788,9 +796,9 @@ else {
|
||||
${READER_SEEK | indent_all_but_first_by(6)}
|
||||
let mut client = &mut *self.hub.client.borrow_mut();
|
||||
let upload_result = {
|
||||
let url = &res.headers.get::<Location>().expect("Location header is part of protocol").0;
|
||||
let url_str = &res.headers.get::<Location>().expect("Location header is part of protocol").0;
|
||||
if upload_url_from_server {
|
||||
dlg.store_upload_url(url);
|
||||
dlg.store_upload_url(url_str);
|
||||
}
|
||||
|
||||
cmn::ResumableUploadHelper {
|
||||
@@ -800,7 +808,7 @@ else {
|
||||
auth: &mut *self.hub.auth.borrow_mut(),
|
||||
user_agent: &self.hub._user_agent,
|
||||
auth_header: auth_header.clone(),
|
||||
url: url,
|
||||
url: url_str,
|
||||
reader: &mut reader,
|
||||
media_type: reader_mime_type.clone(),
|
||||
content_length: size
|
||||
|
||||
@@ -429,7 +429,7 @@ impl<'a> Read for MultiPartReader<'a> {
|
||||
// before clearing the last part, we will add the boundary that
|
||||
// will be written last
|
||||
self.last_part_boundary = Some(Cursor::new(
|
||||
format!("{}--{}", LINE_ENDING, BOUNDARY).into_bytes()))
|
||||
format!("{}--{}--", LINE_ENDING, BOUNDARY).into_bytes()))
|
||||
}
|
||||
// We are depleted - this can trigger the next part to come in
|
||||
self.current_part = None;
|
||||
@@ -517,7 +517,7 @@ impl Header for ContentRange {
|
||||
|
||||
impl HeaderFormat for ContentRange {
|
||||
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(fmt.write_str("bytes="));
|
||||
try!(fmt.write_str("bytes "));
|
||||
match self.range {
|
||||
Some(ref c) => try!(c.fmt(fmt)),
|
||||
None => try!(fmt.write_str("*"))
|
||||
@@ -538,7 +538,7 @@ impl Header for RangeResponseHeader {
|
||||
fn parse_header(raw: &[Vec<u8>]) -> Option<RangeResponseHeader> {
|
||||
if let [ref v] = raw {
|
||||
if let Ok(s) = std::str::from_utf8(v) {
|
||||
const PREFIX: &'static str = "bytes=";
|
||||
const PREFIX: &'static str = "bytes ";
|
||||
if s.starts_with(PREFIX) {
|
||||
if let Ok(c) = <Chunk as FromStr>::from_str(&s[PREFIX.len()..]) {
|
||||
return Some(RangeResponseHeader(c))
|
||||
|
||||
@@ -21,7 +21,6 @@ mod test_api {
|
||||
use self::hyper_mock::*;
|
||||
use std::io::Read;
|
||||
use std::default::Default;
|
||||
use std::old_path::BytesContainer;
|
||||
use hyper;
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -38,9 +37,9 @@ Content-Length: 25\r\n\
|
||||
Content-Type: application/plain\r\n\
|
||||
\r\n\
|
||||
bar\r\n\
|
||||
--MDuXWGyeE33QFXGchb2VFWc4Z7945d";
|
||||
--MDuXWGyeE33QFXGchb2VFWc4Z7945d--";
|
||||
|
||||
const EXPECTED_LEN: usize= 221;
|
||||
const EXPECTED_LEN: usize= 223;
|
||||
|
||||
#[test]
|
||||
fn multi_part_reader() {
|
||||
@@ -130,9 +129,9 @@ bar\r\n\
|
||||
#[test]
|
||||
fn content_range() {
|
||||
for &(ref c, ref expected) in
|
||||
&[(ContentRange {range: None, total_length: 50 }, "Content-Range: bytes=*/50\r\n"),
|
||||
&[(ContentRange {range: None, total_length: 50 }, "Content-Range: bytes */50\r\n"),
|
||||
(ContentRange {range: Some(Chunk { first: 23, last: 40 }), total_length: 45},
|
||||
"Content-Range: bytes=23-40/45\r\n")] {
|
||||
"Content-Range: bytes 23-40/45\r\n")] {
|
||||
let mut headers = hyper::header::Headers::new();
|
||||
headers.set(c.clone());
|
||||
assert_eq!(headers.to_string(), expected.to_string());
|
||||
@@ -147,7 +146,7 @@ bar\r\n\
|
||||
|
||||
#[test]
|
||||
fn parse_range_response() {
|
||||
let r: RangeResponseHeader = hyper::header::Header::parse_header(&[b"bytes=2-42".to_vec()]).unwrap();
|
||||
let r: RangeResponseHeader = hyper::header::Header::parse_header(&[b"bytes 2-42".to_vec()]).unwrap();
|
||||
assert_eq!(r.0.first, 2);
|
||||
assert_eq!(r.0.last, 42);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user