slinger

Struct Client

Source
pub struct Client { /* private fields */ }
Expand description

A Client to make Requests with.

The Client has various configuration values to tweak, but the defaults are set to what is usually the most commonly desired value. To configure a Client, use Client::builder().

The Client holds a connection pool internally, so it is advised that you create one and reuse it.

§Examples

use slinger::Client;
let client = Client::new();
let resp = client.get("http://httpbin.org/").send()?;

Implementations§

Source§

impl Client

Source

pub fn new() -> Client

Constructs a new Client.

§Panic

This method panics if TLS backend cannot be initialized, or the resolver cannot load the system configuration.

Use Client::builder() if you wish to handle the failure as an Error instead of panicking.

See docs on slinger for details.

Source

pub fn builder() -> ClientBuilder

Creates a ClientBuilder to configure a Client.

This is the same as ClientBuilder::new().

Source

pub fn get<U>(&self, url: U) -> RequestBuilder
where Uri: TryFrom<U>, <Uri as TryFrom<U>>::Error: Into<Error>,

Convenience method to make a GET request to a URL.

§Errors

This method fails whenever supplied Uri cannot be parsed.

Examples found in repository?
examples/proxy.rs (line 7)
4
5
6
7
8
9
10
fn main() -> Result<(), Box<dyn std::error::Error>> {
  let proxy = slinger::Proxy::parse("http://127.0.0.1:8080").unwrap();
  let client = ClientBuilder::new().proxy(proxy).build().unwrap();
  let resp = client.get("https://httpbin.org/get").send()?;
  println!("{:?}", resp.text());
  Ok(())
}
More examples
Hide additional examples
examples/http_record.rs (line 6)
3
4
5
6
7
8
9
10
11
12
fn main() -> Result<(), Box<dyn std::error::Error>> {
  let client = ClientBuilder::new().build().unwrap();
  let resp = client
    .get("https://httpbin.org/redirect-to?url=https%3A%2F%2Fhttpbin.org%2Fget")
    .send()?;
  println!("{:?}", resp.request());
  let record = resp.http_record().unwrap();
  println!("{:?}", record.len());
  Ok(())
}
examples/redirect.rs (line 34)
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
fn customize() -> Result<(), Box<dyn std::error::Error>> {
  let redirect = slinger::redirect::Policy::Custom(custom);
  let client = ClientBuilder::new().redirect(redirect).build().unwrap();
  let resp = client
    .get("http://httpbin.org/base64/c2xpbmdlcgo%3D")
    .send()?;
  assert!(resp.text().unwrap_or_default().contains("slinger=awesome"));
  Ok(())
}
fn limit(max_redirect: usize) -> Result<(), Box<dyn std::error::Error>> {
  let redirect = slinger::redirect::Policy::Limit(max_redirect);
  let client = ClientBuilder::new().redirect(redirect).build().unwrap();
  let resp = client.get("http://httpbin.org/redirect/10").send()?;
  let record = resp.extensions().get::<Vec<HTTPRecord>>().unwrap();
  assert_eq!(record.len(), 3);
  Ok(())
}

fn jump() -> Result<(), Box<dyn std::error::Error>> {
  let client = ClientBuilder::new().build().unwrap();
  let resp = client
    .get("http://httpbin.org/redirect-to?url=http://www.example.com/")
    .send()?;
  let record = resp.extensions().get::<Vec<HTTPRecord>>().unwrap();
  println!("{:?}", record);
  assert_eq!(record.len(), 2);
  Ok(())
}

fn only_same_host() -> Result<(), Box<dyn std::error::Error>> {
  let redirect = slinger::redirect::Policy::Custom(slinger::redirect::only_same_host);
  let client = ClientBuilder::new().redirect(redirect).build().unwrap();
  let resp = client
    .get("http://httpbin.org/redirect-to?url=http://www.example.com/")
    .send()?;
  let record = resp.extensions().get::<Vec<HTTPRecord>>().unwrap();
  println!("{:?}", record);
  assert_eq!(record.len(), 1);
  let redirect_record = resp.redirect_record().unwrap();
  println!("{:?}", redirect_record);
  assert_eq!(
    redirect_record.next,
    Some(http::Uri::from_static("http://www.example.com/"))
  );
  Ok(())
}
Source

pub fn post<U>(&self, url: U) -> RequestBuilder
where Uri: TryFrom<U>, <Uri as TryFrom<U>>::Error: Into<Error>,

Convenience method to make a POST request to a URL.

§Errors

This method fails whenever supplied Uri cannot be parsed.

Examples found in repository?
examples/request_budiler.rs (line 6)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fn main() -> Result<(), Box<dyn std::error::Error>> {
  let client = ClientBuilder::new().build().unwrap();
  let resp = client
    .post("https://httpbin.org/post")
    .header("XX", "XX")
    .header_line("X: X")
    .body(b"data".as_slice())
    .send()?;
  println!("{:?}", resp.text());
  let u = http::Uri::from_static("https://httpbin.org/post");
  let raw = Request::raw(u, "", true);
  println!("{:?}", raw);
  Ok(())
}
More examples
Hide additional examples
examples/base.rs (line 14)
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fn main() -> Result<(), Box<dyn std::error::Error>> {
  let client = ClientBuilder::new()
    .user_agent(HeaderValue::from_static(
      "Mozilla/5.0 (X11; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0",
    ))
    .build()
    .unwrap();
  let resp = slinger::get("http://httpbin.org/get")?;
  println!("{:?}", resp.body());
  let resp = client
    .post("http://httpbin.org/post")
    .body(b"test".to_vec())
    .send()?;
  println!("{:?}", resp.text());
  let req = Request::builder()
    .uri("http://httpbin.org/head")
    .method("HEAD")
    .header("pragma", "akamai-x-cache-on")
    .body(None)
    .unwrap();
  let resp = client.execute(req).unwrap();
  println!("{:?}", resp);
  Ok(())
}
Source

pub fn put<U>(&self, url: U) -> RequestBuilder
where Uri: TryFrom<U>, <Uri as TryFrom<U>>::Error: Into<Error>,

Convenience method to make a PUT request to a URL.

§Errors

This method fails whenever supplied Uri cannot be parsed.

Source

pub fn patch<U>(&self, url: U) -> RequestBuilder
where Uri: TryFrom<U>, <Uri as TryFrom<U>>::Error: Into<Error>,

Convenience method to make a PATCH request to a URL.

§Errors

This method fails whenever supplied Uri cannot be parsed.

Source

pub fn delete<U>(&self, url: U) -> RequestBuilder
where Uri: TryFrom<U>, <Uri as TryFrom<U>>::Error: Into<Error>,

Convenience method to make a DELETE request to a URL.

§Errors

This method fails whenever supplied Uri cannot be parsed.

Source

pub fn head<U>(&self, url: U) -> RequestBuilder
where Uri: TryFrom<U>, <Uri as TryFrom<U>>::Error: Into<Error>,

Convenience method to make a HEAD request to a URL.

§Errors

This method fails whenever supplied Uri cannot be parsed.

Source

pub fn trace<U>(&self, url: U) -> RequestBuilder
where Uri: TryFrom<U>, <Uri as TryFrom<U>>::Error: Into<Error>,

Convenience method to make a TRACE request to a URL.

§Errors

This method fails whenever supplied Uri cannot be parsed.

Source

pub fn connect<U>(&self, url: U) -> RequestBuilder
where Uri: TryFrom<U>, <Uri as TryFrom<U>>::Error: Into<Error>,

Convenience method to make a CONNECT request to a URL.

§Errors

This method fails whenever supplied Uri cannot be parsed.

Source

pub fn options<U>(&self, url: U) -> RequestBuilder
where Uri: TryFrom<U>, <Uri as TryFrom<U>>::Error: Into<Error>,

Convenience method to make a OPTIONS request to a URL.

§Errors

This method fails whenever supplied Uri cannot be parsed.

Source

pub fn request<U>(&self, method: Method, url: U) -> RequestBuilder
where Uri: TryFrom<U>, <Uri as TryFrom<U>>::Error: Into<Error>,

Start building a Request with the Method and Uri.

Returns a RequestBuilder, which will allow setting headers and request body before sending.

§Errors

This method fails whenever supplied Uri cannot be parsed.

Source

pub fn raw<U, R>(&self, uri: U, raw: R, unsafe_raw: bool) -> RequestBuilder
where Bytes: From<R>, Uri: TryFrom<U>, <Uri as TryFrom<U>>::Error: Into<Error>,

Start building a Request with the Method and Uri.

Returns a RequestBuilder, which will allow setting headers and request body before sending.

§Errors

This method fails whenever supplied Uri cannot be parsed.

Examples found in repository?
examples/smuggling.rs (line 29)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
fn cve_2020_11724() {
  let raw: &str = r#"GET /test1 HTTP/1.1
Host: 192.168.83.196:8081
Content-Length: 42
Transfer-Encoding: chunked

0

GET /test1 HTTP/1.1
Host: 192.168.83.196:8081
X: GET http://192.168.83.1:8080/admin.jsp HTTP/1.0

"#;
  // let proxy = slinger::Proxy::parse("http://127.0.0.1:8080").unwrap();
  let client = ClientBuilder::new().build().unwrap();
  // replace \n to \r\n
  let raw = raw.replace('\n', "\r\n");
  let resp = client
    .raw("http://127.0.0.1:9015/", raw, true)
    .send()
    .unwrap();
  println!("{:?}", resp.text());
  let command = resp.request().unwrap().get_command();
  println!("{}", command);
}

fn nginx() {
  let raw = r#"
GET /a HTTP/1.1
Host: localhost
Content-Length: 56

GET /_hidden/index.html HTTP/1.1
Host: notlocalhost


"#;
  let client = ClientBuilder::new().build().unwrap();
  // replace \n to \r\n
  let raw = raw.replace('\n', "\r\n");
  let resp = client
    .raw("http://127.0.0.1:9015/", raw, true)
    .send()
    .unwrap();
  println!("{:?}", resp.text());
  let command = resp.request().unwrap().get_command();
  println!("{}", command);
}
Source

pub fn execute_request( &self, socket: &mut Socket, request: &Request, ) -> Result<Response>

Executes a Request.

A Request can be built manually with Request::new() or obtained from a RequestBuilder with RequestBuilder::build().

You should prefer to use the RequestBuilder and RequestBuilder::send().

§Errors

This method fails if there was an error while sending request, or redirect limit was exhausted.

Source

pub fn execute<R: Into<Request>>(&self, request: R) -> Result<Response>

Executes a Request.

A Request can be built manually with Request::new() or obtained from a RequestBuilder with RequestBuilder::build().

You should prefer to use the RequestBuilder and RequestBuilder::send().

§Errors

This method fails if there was an error while sending request, or redirect limit was exhausted.

Examples found in repository?
examples/base.rs (line 24)
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fn main() -> Result<(), Box<dyn std::error::Error>> {
  let client = ClientBuilder::new()
    .user_agent(HeaderValue::from_static(
      "Mozilla/5.0 (X11; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0",
    ))
    .build()
    .unwrap();
  let resp = slinger::get("http://httpbin.org/get")?;
  println!("{:?}", resp.body());
  let resp = client
    .post("http://httpbin.org/post")
    .body(b"test".to_vec())
    .send()?;
  println!("{:?}", resp.text());
  let req = Request::builder()
    .uri("http://httpbin.org/head")
    .method("HEAD")
    .header("pragma", "akamai-x-cache-on")
    .body(None)
    .unwrap();
  let resp = client.execute(req).unwrap();
  println!("{:?}", resp);
  Ok(())
}

Trait Implementations§

Source§

impl Clone for Client

Source§

fn clone(&self) -> Client

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Client

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Client

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Client

§

impl RefUnwindSafe for Client

§

impl Send for Client

§

impl Sync for Client

§

impl Unpin for Client

§

impl UnwindSafe for Client

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.