RustのhyperをOpenSSLなしで使う


はじめに

RustのHTTPライブラリであるhyperはHTTPS対応のためOpenSSLに依存しています。しかし、LinuxならともかくWindowsでOpenSSL込みのビルドは結構厄介です。HTTPしか使わないならOpenSSL依存をなくせるのではないかと思い、やってみました。

やり方

Cargo.tomlを

Cargo.toml

[dependencies]
hyper = "x.y.z"
hoge  = "a.b.c"

から

Cargo.toml

[dependencies]
hoge  = "a.b.c"

[dependencies.hyper]
version  = "x.y.z"
default-features = false

に変更すればOKです。
この時のコンパイルログは以下のようになり、確かにOpenSSL関連のライブラリがコンパイルされなくなっています。

//OpenSSLあり版                                  //OpenSSLなし版
Compiling winapi-build v0.1.1                    Compiling matches v0.1.2
Compiling httparse v1.1.2                        Compiling winapi-build v0.1.1
Compiling winapi v0.2.8                          Compiling num-traits v0.1.35
Compiling num-traits v0.1.35                     Compiling language-tags v0.2.2
Compiling lazy_static v0.2.1                     Compiling traitobject v0.0.1
Compiling language-tags v0.2.2                   Compiling rustc-serialize v0.3.19
Compiling num-integer v0.1.32                    Compiling semver v0.1.20
Compiling bitflags v0.7.0                        Compiling rustc_version v0.1.7
Compiling rustc-serialize v0.3.19                Compiling httparse v1.1.2
Compiling libc v0.2.15                           Compiling log v0.3.6
Compiling rand v0.3.14                           Compiling hpack v0.2.0
Compiling num_cpus v0.2.13                       Compiling solicit v0.4.4
Compiling matches v0.1.2                         Compiling unicase v1.4.0
Compiling unicode-bidi v0.2.3                    Compiling num-integer v0.1.32
Compiling log v0.3.6                             Compiling unicode-bidi v0.2.3
Compiling hpack v0.2.0                           Compiling num-iter v0.1.32
Compiling solicit v0.4.4                         Compiling num v0.1.35
Compiling kernel32-sys v0.2.2                    Compiling typeable v0.1.2
Compiling typeable v0.1.2                        Compiling libc v0.2.15
Compiling num-iter v0.1.32                       Compiling serde v0.6.15
Compiling time v0.1.35                           Compiling rand v0.3.14
Compiling num v0.1.35                            Compiling num_cpus v0.2.13
Compiling serde v0.6.15                          Compiling uuid v0.2.3
Compiling semver v0.1.20                         Compiling unicode-normalization v0.1.2
Compiling rustc_version v0.1.7                   Compiling idna v0.1.0
Compiling unicase v1.4.0                         Compiling mime v0.1.3
Compiling traitobject v0.0.1                     Compiling url v1.2.0
Compiling pkg-config v0.3.8                      Compiling url v0.5.10
Compiling openssl-sys v0.7.17                    Compiling winapi v0.2.8
Compiling uuid v0.2.3                            Compiling kernel32-sys v0.2.2
Compiling gcc v0.3.35                            Compiling time v0.1.35
Compiling mime v0.1.3                            Compiling cookie v0.2.5
Compiling openssl v0.7.14                        Compiling hyper v0.7.2
Compiling openssl-sys-extras v0.7.14
Compiling unicode-normalization v0.1.2
Compiling idna v0.1.0
Compiling url v0.5.10
Compiling url v1.2.0
Compiling cookie v0.2.5
Compiling hyper v0.7.2

また、OpenSSLなし版でHTTPSアクセスを試みると

extern crate hyper;

use hyper::Client;
use hyper::header::Connection;

fn main() {
    let client = Client::new();
    let res = client.get( "https://www.google.com" ).header( Connection::close() ).send();
    println!( "{:?}", res );
}

当然ながらエラーになります。

Err(Io(Error { repr: Custom(Custom { kind: InvalidInput, error: StringError("Invalid scheme for Http") }) }))

解説

hyperのCargo.tomlからOpenSSLに関連した部分を抜粋したものが以下になります。

Cargo.toml
[dependencies.openssl]
version = "0.7"
optional = true

[features]
default = ["ssl"]
ssl = ["openssl", "openssl-verify", "cookie/secure"]

optional = trueはOpenSSLへの依存がオプションであることを、ssl = ["openssl", "openssl-verify", "cookie/secure"]sslフィーチャがOpenSSL等に依存していることを示しています。
また、default = ["ssl"]なのでsslフィーチャはデフォルトで有効になっています。
(このため普通にhyperを使うと必ずOpenSSLへの依存が発生するわけです)

というわけでこのデフォルト指定を無効化するのがdefault-features = falseになります。
逆にデフォルトでないフィーチャは

Cargo.toml
[dependencies.hyper]
version  = "x.y.z"
features = ["serde-serialization"]

のように有効にすることが出来ます。