History

[clone] Curl can now use remote to perform operations (get only for now)

Sebastian Thiel committed 6 years ago

Commit a82f0281 parent b450bfc2 files · +53 −24Browse files

Unified · Split

2 files
  1. git-transport/src/client/http/curl.rs +53 −21
  2. git-transport/src/client/http/mod.rs +0 −3
git-transport/src/client/http/curl.rs+53−21
@@ -5,6 +5,7 @@ use std::{ · 4 unmodified lines
55 io,
66 io::Read,
77 sync::mpsc::{sync_channel, Receiver, SyncSender, TrySendError},
8+ thread,
89 };
910
1011 #[derive(Default)]
@@ -17,7 +18,35 @@ struct Handler { · 6 unmodified lines
1718 impl curl::easy::Handler for Handler {}
1819
1920 pub struct Curl {
20− handle: Easy2<Handler>,
21+ req: SyncSender<Request>,
22+ res: Receiver<Response>,
23+ handle: Option<thread::JoinHandle<Result<(), curl::Error>>>,
24+}
25+
26+impl Curl {
27+ pub fn new() -> Self {
28+ let (handle, req, res) = new_remote_curl();
29+ Curl {
30+ handle: Some(handle),
31+ req,
32+ res,
33+ }
34+ }
35+
36+ fn restore_thread_after_failure(&mut self) -> http::Error {
37+ let err_that_brought_thread_down = self
38+ .handle
39+ .take()
40+ .expect("thread present")
41+ .join()
42+ .expect("handler thread should never panic")
43+ .expect_err("something should have gone wrong with curl");
44+ let (handle, req, res) = new_remote_curl();
45+ self.handle = Some(handle);
46+ self.req = req;
47+ self.res = res;
48+ return err_that_brought_thread_down.into();
49+ }
2150 }
2251
2352 struct Request {
@@ -28,11 +57,11 @@ struct Request { · 4 unmodified lines
2857 struct Response {
2958 headers: pipe::Reader,
3059 body: pipe::Reader,
31− upload_body: pipe::Writer,
60+ _upload_body: pipe::Writer,
3261 }
3362
3463 fn new_remote_curl() -> (
35− std::thread::JoinHandle<Result<(), curl::Error>>,
64+ thread::JoinHandle<Result<(), curl::Error>>,
3665 SyncSender<Request>,
3766 Receiver<Response>,
3867 ) {
@@ -85,7 +114,7 @@ fn new_remote_curl() -> ( · 46 unmodified lines
85114 .send(Response {
86115 headers: receive_headers,
87116 body: receive_data,
88− upload_body: send_body,
117+ _upload_body: send_body,
89118 })
90119 .is_err()
91120 {
@@ -97,14 +126,6 @@ fn new_remote_curl() -> ( · 5 unmodified lines
97126 (handle, req_send, res_recv)
98127 }
99128
100−impl Curl {
101− pub fn new() -> Self {
102− Curl {
103− handle: Easy2::new(Handler::default()),
104− }
105− }
106−}
107−
108129 impl From<curl::Error> for http::Error {
109130 fn from(err: curl::Error) -> Self {
110131 http::Error::Detail(err.to_string())
@@ -120,19 +141,30 @@ impl crate::client::http::Http for Curl { · 9 unmodified lines
120141 url: &str,
121142 headers: impl IntoIterator<Item = impl AsRef<str>>,
122143 ) -> Result<(Self::Headers, Self::ResponseBody), http::Error> {
123− self.handle.url(url)?;
124144 let mut list = curl::easy::List::new();
125145 for header in headers {
126146 list.append(header.as_ref())?;
127147 }
128− self.handle.http_headers(list)?;
129−
130− let (send, receive_data) = pipe::unidirectional(1);
131− self.handle.get_mut().send_data = Some(send);
132− let (send, receive_headers) = pipe::unidirectional(1);
133− self.handle.get_mut().send_header = Some(send);
134−
135− Ok((receive_headers, receive_data))
148+ if self
149+ .req
150+ .send(Request {
151+ url: url.to_owned(),
152+ headers: list,
153+ })
154+ .is_err()
155+ {
156+ return Err(self.restore_thread_after_failure());
157+ }
158+ let Response {
159+ headers,
160+ body,
161+ _upload_body: _,
162+ } = match self.res.recv() {
163+ Ok(res) => res,
164+ Err(_) => return Err(self.restore_thread_after_failure()),
165+ };
166+
167+ Ok((headers, body))
136168 }
137169
138170 fn post(
git-transport/src/client/http/mod.rs+0−3
@@ -9,9 +9,6 @@ quick_error! { · 8 unmodified lines
99 Detail(description: String) {
1010 display("{}", description)
1111 }
12− Status(status: u16, method: &'static str, url: String) {
13− display("{}:{} saw HTTP status {}", method, url, status)
14− }
1512 }
1613 }
1714