Прокси службы Rust AWS API Gateway для загрузки файла S3 с использованием необработанного https-запроса

Во-первых, извините за длинное название.

Я настроил шлюз API для работы в качестве прокси-сервера s3, поэтому я могу загружать файлы, отправляя запрос PUT на URL-адрес API. API работает нормально (по крайней мере, я так думаю), но, похоже, я могу правильно загружать только текстовые файлы.

Для загруженных текстовых файлов (например, Content-Type=text/plain) размеры файлов локально идентичны размерам файлов, загруженных в корзину s3. НО это не относится к двоичным файлам (например, Content-Type=application/pdf). Файлы в корзинах s3 имеют больший размер. Когда я загружаю бинарные файлы с s3, я не могу их открыть, они повреждены.

Вот код rust для отправки запроса, я использую https://github.com/hyperium/hyper:

match File::open(file.as_path()) {
        Err(_) => Err("Failed to open file".to_owned()),
        Ok(mut openned_file) => {
            let file_mime = mime_guess::guess_mime_type(file.as_path());
            let connector = HttpsConnector::new(OpensslClient::default());
            let url_str = format!("https://my.api.com/upload/{}",
                                file.file_name().unwrap().to_str().unwrap());
            let mut client =
                Request::with_connector(Method::Put, Url::parse(&url_str).unwrap(), &connector)
                    .unwrap();
            client.headers_mut().set(ContentType(file_mime.clone()));
            // client.headers_mut().set(ContentLength(openned_file.metadata().unwrap().len()));
            let file_mime_str = file_mime.to_string();
            let mut buffer: [u8; 4096] = [0; 4096];
            let mut uploaded: usize = 0;
            let request = match file_mime {
                Mime(TopLevel::Text, _, _) |
                Mime(TopLevel::Application, SubLevel::Javascript, _) => {
                    let mut request = client.start().unwrap();
                    println!("Uploading text ...", );
                    while let Ok(read_count) = openned_file.read(&mut buffer) {
                        if read_count > 0 {
                            println!("Uploading {} bytes", read_count);
                            request.write_all(&buffer[0..read_count]);
                            uploaded += read_count;
                        } else {
                            request.flush();
                            println!("File mime: {}", file_mime_str);
                            println!("File size: {}, Total uploaded: {}",
                                     openned_file.metadata().unwrap().len(),
                                     uploaded);
                            break;
                        }
                    }
                    request
                }
                _ => {
                    // client.headers_mut()
                    //     .set_raw("Content-Encoding", vec![b"base64".to_vec()]);
                    let mut request = client.start().unwrap();

                    let mut config = MIME;
                    config.line_length = None;
                    println!("Uploading binary ...", );
                    while let Ok(read_count) = openned_file.read(&mut buffer) {
                        if read_count > 0 {
                            println!("Uploading {} bytes", read_count);
                            request.write_all(&buffer[0..read_count]);
                            // let base64_str = buffer[0..read_count].to_base64(STANDARD);
                            // request.write_all(base64_str.into_bytes().as_slice());
                            uploaded += read_count;
                        } else {
                            request.flush();
                            println!("File mime: {}", file_mime_str);
                            println!("File size: {}, Total uploaded: {}",
                                     openned_file.metadata().unwrap().len(),
                                     uploaded);
                            break;
                        }
                    }
                    request
                }
            };

            match request.send() {
                Err(err) => Err(format!("{}", err)),
                Ok(mut response) => {
                    let mut rep_str = String::new();
                    response.read_to_string(&mut rep_str);
                    Err(format!("{}", rep_str))
                }
            }

Как видно из закомментированного кода, я пытался использовать Content-Encoding=base64 и кодировать байты, считанные из файла для загрузки. Но Content-Encoding=base64 кажется недопустимым типом кодировки, который принимает s3. Мне не удалось загрузить полностью (500: внутренняя ошибка сервера, я даже не вижу файл неправильного размера в корзине s3) всякий раз, когда я устанавливал Content-Encoding. Но текстовый файл работает отлично.

Для справки:


person zhywu    schedule 21.06.2016    source источник


Ответы (1)


К сожалению, в настоящее время API Gateway не поддерживает двоичные полезные нагрузки. Это общий запрос функции, поэтому он находится в нашем списке невыполненных работ, хотя мы не можем комментировать дату выпуска. Мы обязательно обновим этот пост, когда функция будет выпущена.

person Lorenzo de Lara    schedule 21.06.2016