History

a sketch of passing curl options down to curl…

…but it clearly shows that the backend needs to be abstracted or else we can't have general HTTP options as are implied by the way git works.

Sebastian Thiel committed 4 years ago

Commit 63e24fc1 parent 7c5b37d3 files · +48 −1Browse files

Unified · Split

3 files
  1. git-transport/src/client/blocking_io/http/curl/mod.rs +13 −0
  2. git-transport/src/client/blocking_io/http/curl/remote.rs +11 −1
  3. git-transport/src/client/blocking_io/http/mod.rs +24 −0
git-transport/src/client/blocking_io/http/curl/mod.rs+13−0
@@ -10,10 +10,21 @@ use crate::client::blocking_io::http; · 9 unmodified lines
1010
1111 mod remote;
1212
13+/// Options to configure curl requests.
14+#[derive(Default, Clone)]
15+pub struct Options {
16+ /// Corresponds to the `http.extraHeader` configuration, a multi-var.
17+ /// They are applied unconditionally and are expected to be valid.
18+ pub extra_headers: Vec<String>,
19+ /// How to handle redirects.
20+ pub follow_redirects: http::options::FollowRedirects,
21+}
22+
1323 pub struct Curl {
1424 req: SyncSender<remote::Request>,
1525 res: Receiver<remote::Response>,
1626 handle: Option<thread::JoinHandle<Result<(), curl::Error>>>,
27+ options: Options,
1728 }
1829
1930 impl Curl {
@@ -48,6 +59,7 @@ impl Curl { · 28 unmodified lines
4859 url: url.to_owned(),
4960 headers: list,
5061 upload,
62+ config: self.options.clone(),
5163 })
5264 .is_err()
5365 {
@@ -76,6 +88,7 @@ impl Default for Curl { · 22 unmodified lines
7688 handle: Some(handle),
7789 req,
7890 res,
91+ options: Options::default(),
7992 }
8093 }
8194 }
git-transport/src/client/blocking_io/http/curl/remote.rs+11−1
@@ -92,6 +92,7 @@ pub struct Request { · 91 unmodified lines
9292 pub url: String,
9393 pub headers: curl::easy::List,
9494 pub upload: bool,
95+ pub config: http::curl::Options,
9596 }
9697
9798 pub struct Response {
@@ -110,11 +111,20 @@ pub fn new() -> ( · 12 unmodified lines
110111 let handle = std::thread::spawn(move || -> Result<(), curl::Error> {
111112 let mut handle = Easy2::new(Handler::default());
112113
113− for Request { url, headers, upload } in req_recv {
114+ for Request {
115+ url,
116+ mut headers,
117+ upload,
118+ config,
119+ } in req_recv
120+ {
114121 handle.url(&url)?;
115122
116123 // GitHub sends 'chunked' to avoid unknown clients to choke on the data, I suppose
117124 handle.post(upload)?;
125+ for header in config.extra_headers {
126+ headers.append(&header)?;
127+ }
118128 handle.http_headers(headers)?;
119129 handle.transfer_encoding(false)?;
120130 handle.connect_timeout(Duration::from_secs(20))?;
git-transport/src/client/blocking_io/http/mod.rs+24−0
@@ -21,6 +21,30 @@ mod reqwest; · 20 unmodified lines
2121 ///
2222 mod traits;
2323
24+///
25+pub mod options {
26+ /// possible settings for the `http.followRedirects` configuration option.
27+ #[derive(Copy, Clone, PartialEq, Eq)]
28+ pub enum FollowRedirects {
29+ /// Follow only the first redirect request, most suitable for typical git requests.
30+ Initial,
31+ /// Follow all redirect requests from the server unconditionally
32+ All,
33+ /// Follow no redirect request.
34+ None,
35+ }
36+
37+ impl Default for FollowRedirects {
38+ fn default() -> Self {
39+ FollowRedirects::Initial
40+ }
41+ }
42+}
43+
44+/// The http client configuration when using reqwest
45+#[cfg(feature = "http-client-curl")]
46+pub type Options = curl::Options;
47+
2448 /// The http client configuration when using reqwest
2549 #[cfg(feature = "http-client-reqwest")]
2650 pub type Options = reqwest::Options;