LoginSignup
2
0

More than 1 year has passed since last update.

RustでAWS S3のファイルをダウンロードして、reqwestでpostしてみる

Last updated at Posted at 2021-02-06

追記(2021/08/26)

rustro_coreの0.47.0からByteStreamからSyncがなくなりました。なので一旦ローカルにファイルを作成してPartを作る必要があります。その部分は以下のようになります。

let file = std::fs::File.open("test.jpg");
let tokio_file = tokio::fs::File::from_std(file);
let stream = tokio_util::codec::FramedRead::new(tokio_file, tokio_util::codec::BytesCodec::new());
let Part::stream(reqwest::Body::wrap_stream(stream))

目的

AWSからダウンロードしたファイルを、HTTPのPOSTメソッドでアップロードしたいです。ローカルにファイルとして保存してアップロードするのはダサいので、ストリームで流してみました。

httpbin.orgはこちらが送ったデータをレスポンスで返してくれるので、自身が送ったパラメーターのデバッグなどで便利です。

プログラム

Cargo.toml
[package]
name = "upload_test"
version = "0.1.0"
edition = "2018"

[dependencies]
reqwest = { version = "~0.10.10", features = ["json", "stream"] }
rusoto_core = "~0.45.0"
rusoto_s3 = "~0.45.0"
serde_json = "~1.0.0"
tokio = { version = "~0.2", features = ["macros"] }
main.rs
use rusoto_core::Region;
use rusoto_s3::{GetObjectRequest, S3Client, S3};

use reqwest::multipart::{Form, Part};

type Error = Box<dyn std::error::Error>;
type Result<T, E = Error> = std::result::Result<T, E>;

#[tokio::main]
async fn main() -> Result<()> {
    // S3からファイルをダウンロードする
    let client = S3Client::new(Region::ApNortheast1);
    let mut object = client
        .get_object(GetObjectRequest {
            bucket: "my_bucket".into(),
            key: "target.txt".into(),
            ..Default::default()
        })
        .await?;

    // ダウンロードしたファイルをマルチパートのストリームに渡す
    let body = object.body.take().unwrap();
    let part = Part::stream(reqwest::Body::wrap_stream(body));
    let form = Form::new().part("file", part);

    // POSTしてみる
    let http_client = reqwest::Client::new();
    let res = http_client
        .post("http://httpbin.org/post")
        .multipart(form)
        .send()
        .await?;
    let json: serde_json::Value = res.json().await?;
    println!("{:?}", json);
    Ok(())
}

target.txt
予定表~①💖ハンカクだ
結果
{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "file": "予定表~①💖ハンカクだ"
  },
  "headers": {
    "Accept": "*/*",
    "Content-Length": "227",
    "Content-Type": "multipart/form-data; boundary=b7ff64c9dbddec30-c7bfea0ddcf8be1d-96b51cb6af4a31c7-c3e7a3069bab2189",
    "Host": "httpbin.org",
    "X-Amzn-Trace-Id": "Root=1-601e515e-0fa5de530c1ea26d188d69e6"
  },
  "json": null,
  "origin": "xxx.xxxx.xxx.xxx",
  "url": "http://httpbin.org/post"
}
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0