Skip to content
This repository has been archived by the owner on Sep 4, 2024. It is now read-only.

Commit

Permalink
Reuse socket
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph committed Oct 27, 2022
1 parent 7c94adf commit 9f4ab54
Showing 1 changed file with 43 additions and 18 deletions.
61 changes: 43 additions & 18 deletions src/simple_http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
#[cfg(feature = "proxy")]
use socks::Socks5Stream;
use std::io::{BufRead, BufReader, Write};
#[cfg(not(feature = "proxy"))]
use std::net::TcpStream;
use std::net::{SocketAddr, ToSocketAddrs};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use std::{error, fmt, io, net, thread};

Expand Down Expand Up @@ -38,6 +38,7 @@ pub struct SimpleHttpTransport {
proxy_addr: net::SocketAddr,
#[cfg(feature = "proxy")]
proxy_auth: Option<(String, String)>,
sock: Arc<Mutex<Option<TcpStream>>>,
}

impl Default for SimpleHttpTransport {
Expand All @@ -57,6 +58,7 @@ impl Default for SimpleHttpTransport {
),
#[cfg(feature = "proxy")]
proxy_auth: None,
sock: Arc::new(Mutex::new(None)),
}
}
}
Expand All @@ -73,29 +75,52 @@ impl SimpleHttpTransport {
}

fn request<R>(&self, req: impl serde::Serialize) -> Result<R, Error>
where
R: for<'a> serde::de::Deserialize<'a>,
{
match self.try_request(req) {
Ok(response) => Ok(response),
Err(err) => {
*self.sock.lock().unwrap() = None;
Err(err)
}
}
}

fn try_request<R>(&self, req: impl serde::Serialize) -> Result<R, Error>
where
R: for<'a> serde::de::Deserialize<'a>,
{
// Open connection
let request_deadline = Instant::now() + self.timeout;
#[cfg(feature = "proxy")]
let mut sock = if let Some((username, password)) = &self.proxy_auth {
Socks5Stream::connect_with_password(
self.proxy_addr,
self.addr,
username.as_str(),
password.as_str(),
)?
.into_inner()
} else {
Socks5Stream::connect(self.proxy_addr, self.addr)?.into_inner()
};

#[cfg(not(feature = "proxy"))]
let mut sock = TcpStream::connect_timeout(&self.addr, self.timeout)?;
let mut sock = self.sock.lock().unwrap();
if sock.is_none() {
*sock = Some({
#[cfg(feature = "proxy")]
{
if let Some((username, password)) = &self.proxy_auth {
Socks5Stream::connect_with_password(
self.proxy_addr,
self.addr,
username.as_str(),
password.as_str(),
)?
.into_inner()
} else {
Socks5Stream::connect(self.proxy_addr, self.addr)?.into_inner()
}
}

sock.set_read_timeout(Some(self.timeout))?;
sock.set_write_timeout(Some(self.timeout))?;
#[cfg(not(feature = "proxy"))]
{
let stream = TcpStream::connect_timeout(&self.addr, Duration::from_secs(15))?;
stream.set_read_timeout(Some(self.timeout))?;
stream.set_write_timeout(Some(self.timeout))?;
stream
}
})
};
let sock = sock.as_mut().unwrap();

// Serialize the body first so we can set the Content-Length header.
let body = serde_json::to_vec(&req)?;
Expand Down

0 comments on commit 9f4ab54

Please sign in to comment.