やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Rust自習(HTTPリクエスト reqwest 1)

 簡単にHTTPリクエストする方法を探した。

成果物

情報源

コード

必要なライブラリのインストール

sudo apt-get install libssl-dev

libssl-devがないとコンパイルに失敗した。

$ cargo run
    Updating crates.io index
  Downloaded reqwest v0.9.19
  Downloaded bytes v0.4.12
  Downloaded cookie v0.12.0
  Downloaded log v0.4.8
  Downloaded cookie_store v0.7.0
  Downloaded mime_guess v2.0.0-alpha.6
  Downloaded hyper v0.12.33
  Downloaded http v0.1.18
  Downloaded tokio-timer v0.2.11
  Downloaded serde_urlencoded v0.5.5
  Downloaded flate2 v1.0.9
  Downloaded mime v0.3.13
  Downloaded native-tls v0.2.3
  Downloaded tokio-io v0.1.12
  Downloaded tokio-threadpool v0.1.15
  Downloaded hyper-tls v0.3.2
  Downloaded tokio v0.1.22
  Downloaded url v1.7.2
  Downloaded tokio-executor v0.1.8
  Downloaded uuid v0.7.4
  Downloaded either v1.5.2
  Downloaded iovec v0.1.2
  Downloaded futures-cpupool v0.1.8
  Downloaded want v0.2.0
  Downloaded tokio-current-thread v0.1.6
  Downloaded http-body v0.1.0
  Downloaded idna v0.1.5
  Downloaded try_from v0.3.2
  Downloaded slab v0.4.2
  Downloaded openssl-probe v0.1.2
  Downloaded tokio-reactor v0.1.9
  Downloaded crossbeam-queue v0.1.2
  Downloaded dtoa v0.4.4
  Downloaded crc32fast v1.2.0
  Downloaded h2 v0.1.26
  Downloaded crossbeam-utils v0.6.6
  Downloaded publicsuffix v1.5.2
  Downloaded mio v0.6.19
  Downloaded tokio-buf v0.1.1
  Downloaded unicase v2.4.0
  Downloaded miniz_oxide_c_api v0.2.3
  Downloaded openssl v0.10.24
  Downloaded futures v0.1.28
  Downloaded httparse v1.3.4
  Downloaded tokio-tcp v0.1.3
  Downloaded unicase v1.4.2
  Downloaded crossbeam-deque v0.7.1
  Downloaded backtrace v0.3.34
  Downloaded openssl-sys v0.9.48
  Downloaded matches v0.1.8
  Downloaded net2 v0.2.33
  Downloaded parking_lot v0.7.1
  Downloaded try-lock v0.2.2
  Downloaded version_check v0.1.5
  Downloaded error-chain v0.12.1
  Downloaded tokio-sync v0.1.6
  Downloaded indexmap v1.0.2
  Downloaded string v0.2.1
  Downloaded miniz_oxide v0.3.0
  Downloaded unicode-bidi v0.3.4
  Downloaded unicode-normalization v0.1.8
  Downloaded percent-encoding v1.0.1
  Downloaded foreign-types v0.3.2
  Downloaded parking_lot_core v0.4.0
  Downloaded crossbeam-epoch v0.7.2
  Downloaded foreign-types-shared v0.1.1
  Downloaded adler32 v1.0.3
  Downloaded arrayvec v0.4.11
  Downloaded memoffset v0.5.1
  Downloaded lock_api v0.1.5
  Downloaded scopeguard v1.0.0
  Downloaded owning_ref v0.4.0
  Downloaded scopeguard v0.3.3
  Downloaded stable_deref_trait v1.1.1
   Compiling libc v0.2.60
   Compiling autocfg v0.1.5
   Compiling semver-parser v0.7.0
   Compiling rand_core v0.4.0
   Compiling version_check v0.1.5
   Compiling byteorder v1.3.2
   Compiling log v0.4.8
   Compiling arrayvec v0.4.11
   Compiling proc-macro2 v0.4.30
   Compiling stable_deref_trait v1.1.1
   Compiling either v1.5.2
   Compiling smallvec v0.6.10
   Compiling cc v1.0.38
   Compiling lazy_static v1.3.0
   Compiling scopeguard v0.3.3
   Compiling unicode-xid v0.1.0
   Compiling nodrop v0.1.13
   Compiling cfg-if v0.1.9
   Compiling futures v0.1.28
   Compiling pkg-config v0.3.15
   Compiling fnv v1.0.6
   Compiling slab v0.4.2
   Compiling siphasher v0.2.3
   Compiling memchr v2.2.1
   Compiling scopeguard v1.0.0
   Compiling syn v0.15.42
   Compiling matches v0.1.8
   Compiling bitflags v1.1.0
   Compiling failure_derive v0.1.5
   Compiling serde v1.0.98
   Compiling rustc-demangle v0.1.15
   Compiling ryu v1.0.0
   Compiling openssl v0.10.24
   Compiling itoa v0.4.4
   Compiling foreign-types-shared v0.1.1
   Compiling httparse v1.3.4
   Compiling crc32fast v1.2.0
   Compiling ucd-util v0.1.5
   Compiling indexmap v1.0.2
   Compiling native-tls v0.2.3
   Compiling try-lock v0.2.2
   Compiling percent-encoding v1.0.1
   Compiling utf8-ranges v1.0.3
   Compiling adler32 v1.0.3
   Compiling openssl-probe v0.1.2
   Compiling encoding_rs v0.8.17
   Compiling dtoa v0.4.4
   Compiling rand_core v0.3.1
   Compiling rand_jitter v0.1.4
   Compiling rand_chacha v0.1.1
   Compiling rand_pcg v0.1.2
   Compiling rand v0.6.5
   Compiling semver v0.9.0
   Compiling unicase v1.4.2
   Compiling unicase v2.4.0
   Compiling error-chain v0.12.1
   Compiling owning_ref v0.4.0
   Compiling thread_local v0.3.6
   Compiling unicode-normalization v0.1.8
   Compiling crossbeam-utils v0.6.6
   Compiling try_from v0.3.2
   Compiling unicode-bidi v0.3.4
   Compiling backtrace-sys v0.1.31
   Compiling openssl-sys v0.9.48
   Compiling miniz_oxide_c_api v0.2.3
   Compiling tokio-sync v0.1.6
   Compiling foreign-types v0.3.2
   Compiling regex-syntax v0.6.10
   Compiling miniz_oxide v0.3.0
   Compiling rand_hc v0.1.0
   Compiling rand_isaac v0.1.1
   Compiling rand_xorshift v0.1.1
   Compiling lock_api v0.1.5
   Compiling rustc_version v0.2.3
   Compiling tokio-executor v0.1.8
   Compiling crossbeam-queue v0.1.2
error: failed to run custom build command for `openssl-sys v0.9.48`

Caused by:
  process didn't exit successfully: `/tmp/work/Rust.Reqwest.20190801181317/src/reqwest_hello/target/debug/build/openssl-sys-b8dc21b837a6b3d7/build-script-main` (exit code: 101)
--- stdout
cargo:rustc-cfg=const_fn
cargo:rerun-if-env-changed=ARMV7_UNKNOWN_LINUX_GNUEABIHF_OPENSSL_LIB_DIR
ARMV7_UNKNOWN_LINUX_GNUEABIHF_OPENSSL_LIB_DIR unset
cargo:rerun-if-env-changed=OPENSSL_LIB_DIR
OPENSSL_LIB_DIR unset
cargo:rerun-if-env-changed=ARMV7_UNKNOWN_LINUX_GNUEABIHF_OPENSSL_INCLUDE_DIR
ARMV7_UNKNOWN_LINUX_GNUEABIHF_OPENSSL_INCLUDE_DIR unset
cargo:rerun-if-env-changed=OPENSSL_INCLUDE_DIR
OPENSSL_INCLUDE_DIR unset
cargo:rerun-if-env-changed=ARMV7_UNKNOWN_LINUX_GNUEABIHF_OPENSSL_DIR
ARMV7_UNKNOWN_LINUX_GNUEABIHF_OPENSSL_DIR unset
cargo:rerun-if-env-changed=OPENSSL_DIR
OPENSSL_DIR unset
run pkg_config fail: "`\"pkg-config\" \"--libs\" \"--cflags\" \"openssl\"` did not exit successfully: exit code: 1\n--- stderr\nPackage openssl was not found in the pkg-config search path.\nPerhaps you should add the directory containing `openssl.pc\'\nto the PKG_CONFIG_PATH environment variable\nNo package \'openssl\' found\n"

--- stderr
thread 'main' panicked at '

Could not find directory of OpenSSL installation, and this `-sys` crate cannot
proceed without this knowledge. If OpenSSL is installed and this crate had
trouble finding it,  you can set the `OPENSSL_DIR` environment variable for the
compilation process.

Make sure you also have the development packages of openssl installed.
For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.

If you're in a situation where you think the directory *should* be found
automatically, please open a bug at https://github.com/sfackler/rust-openssl
and include information about your system as well as this message.

$HOST = armv7-unknown-linux-gnueabihf
$TARGET = armv7-unknown-linux-gnueabihf
openssl-sys = 0.9.48

', /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/openssl-sys-0.9.48/build/find_normal.rs:150:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
sudo apt-get install libssl-dev

クレート作成

Cargo.toml

[dependencies]
reqwest = "*"

 初回ビルドでダウンロード&コンパイル。たぶん30分くらいかかった。

cargo build

main.rs

 WebAPIを想定したJSON送受信。

use std::collections::HashMap;

fn main() -> Result<(), Box<std::error::Error>> {
    // GET
    let resp: HashMap<String, String> = reqwest::get("https://httpbin.org/ip")?
        .json()?;
    println!("{:#?}", resp);
    
    // POST
    let mut map = HashMap::new();
    map.insert("lang", "rust");
    map.insert("body", "json");

    let client = reqwest::Client::new();
    let res = client.post("http://httpbin.org/post");
    println!("{:#?}", res);
    
    Ok(())
}

実行

cargo run
{
    "origin": "XXX.XXX.XXX.XXX, XXX.XXX.XXX.XXX",
}
RequestBuilder {
    client: Client,
    request: Ok(
        Request {
            method: POST,
            url: "http://httpbin.org/post",
            headers: {},
        },
    ),
}

GET

 テキストで取得する。

fn main() -> Result<(), Box<std::error::Error>> {
    // GET
    let body = reqwest::get("https://www.rust-lang.org")?
        .text()?;
    println!("body = {:?}", body);
    Ok(())
}
$ cargo run
...

POST(body)

 送信する。

fn main() -> Result<(), Box<std::error::Error>> {
    // POST
    let client = reqwest::Client::new();
    let res = client.post("http://httpbin.org/post")
        .body("the exact body that is sent")
        .send()?;
    Ok(())
}
$ cargo run
...

POST(form)

 <form>形式で送信する。

fn main() -> Result<(), Box<std::error::Error>> {
    // POST(Form)
    let params = [("foo", "bar"), ("baz", "quux")];
    let client = reqwest::Client::new();
    let res = client.post("http://httpbin.org/post")
        .form(&params)
        .send()?;
    Ok(())
}
$ cargo run
...

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

前回まで