2 unstable releases

Uses old Rust 2015

0.1.1 Jun 26, 2017
0.0.0 May 9, 2017

#32 in #hyper-client


Used in nessus

MIT license

33KB
558 lines

Roadrunner (RR)

Roadrunner is a Rust Rest client based on hyper project to provide an user friendly interface for use.

The API interface is partially inspired by unirest java library.

Why?

I recently started to look at rust and noticed the choice of rest client in rust seemed to be limited. Hyper client and some libcurl bindings I tried seem to be pretty low level to me.

Another big reason is that writing a library (no matter how small it is) seems to be a good way to start a new language. :)

Documentation

Documentation generated by cargo doc.

Example

(Besides the examples below, there is also a standalone example that uses RoadRunner client to call themoviedb.org for upcoming movies, check it out: https://github.com/luanzhu/movie_alert)

To run the example below, add RoadRunner to your Cargo.toml:

tokio-core = "0.1.6"
serde="1.0"
serde_json = "1.0"
serde_derive="1.0"
hyper = "0.11"

roadrunner = { git="https://github.com/luanzhu/roadrunner", branch="update-to-hyper-0.11" }

Then copy to your main.rs:

#[macro_use] extern crate serde_derive;
extern crate tokio_core;

extern crate serde_json;
extern crate hyper;
extern crate roadrunner;

// need both RestClient and RestClientMethods
use roadrunner::RestClient;
use roadrunner::RestClientMethods;

use hyper::StatusCode;
use serde_json::Value;

#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Address {
    street: String,
    city: String,
}

fn main () {
    let mut core = tokio_core::reactor::Core::new().unwrap();

    let original_typed = Address {
        street: "135 College View Ave.".to_owned(),
        city: "San Francisco".to_owned(),
    };

    let response = RestClient::post("http://mockbin.com/request")
        .cookie("food", "bar")
        .authorization_bearer("QWxhZGRpbjpvcGVuIHNlc2FtZQ".to_string())
        .json_body_typed(&original_typed)
        .execute_on(&mut core)
        .unwrap();

    println!("{:?}", response);

    assert_eq!(*response.status(), StatusCode::Ok);

    let json_value = response.content().as_value().unwrap();
    assert_eq!(Value::String("application/json".to_owned()),
    json_value["headers"]["content-type"]);

    let data_str = json_value["postData"]["text"].as_str().unwrap();

    println!("data_str : {:?}", data_str);

    let response_typed: Address = serde_json::from_str(data_str).unwrap();
    assert_eq!(original_typed, response_typed);
}

Usage

High level

High level API access is provided through RestClient and methods available in trait RestClientMethods.

Please refer to tests in the tests folder for more example.

Low level

For more control of request configuration, please use request_for_response.

The high level RestClient is a thin layer on top of this function.

Supported Methods

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE
  • OPTIONS

Run integration tests in tests folder?

To make tests self-contained, all integration tests are hitting local httpbin container (behind a nginx container) in docker.

Please run the start.sh in the docker-httpbin folder to start two containers (one for httpbin and another one for nginx) locally before you run integration tests.

Warning: because of a recent regression in httpbin, httpbin.org cannot see the request body transferred in chunks. Before the bug is fixed in httpbin, many tests will fail if they hit httpbin.org directly.

Add self-signed SSL cert into your CA

Hyper client relies on [rust-native-tls]((https://github.com/sfackler/rust-native-tls) to handle https connections. However, there is no easy option to allow self-signed certs yet. There is an open issue regarding this.

(Why not use a hosted version of https endpoint for tests? You may ask. Well, I personally would like to see what takes to work around this invalid certificate problem. I think it is fairly common to have self-signed certificates in testing environments. To me, this extra step serves as an exercise when I use this rest client or hyper client in future projects.)

As a result, the self-signed cert used in docker (docker-httpbin/config/localhost.cert) has to be set to trusted (or added to trusted CA store). Otherwise, one test will fail.

References

Some parts of implementations are based on ideas/examples from:

Related

Dependencies

~14–22MB
~326K SLoC