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
5 io,5 io,
6 io::Read,6 io::Read,
7 sync::mpsc::{sync_channel, Receiver, SyncSender, TrySendError},7 sync::mpsc::{sync_channel, Receiver, SyncSender, TrySendError},
8 thread,
8};9};
9 10
10#[derive(Default)]11#[derive(Default)]
@@ -17,7 +18,35 @@ struct Handler { · 6 unmodified lines
17impl curl::easy::Handler for Handler {}18impl curl::easy::Handler for Handler {}
18 19
19pub struct Curl {20pub struct Curl {
20 handle: Easy2<Handler>,21 req: SyncSender<Request>,
22 res: Receiver<Response>,
23 handle: Option<thread::JoinHandle<Result<(), curl::Error>>>,
24}
25
26impl 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 }
21}50}
22 51
23struct Request {52struct Request {
@@ -28,11 +57,11 @@ struct Request { · 4 unmodified lines
28struct Response {57struct Response {
29 headers: pipe::Reader,58 headers: pipe::Reader,
30 body: pipe::Reader,59 body: pipe::Reader,
31 upload_body: pipe::Writer,60 _upload_body: pipe::Writer,
32}61}
33 62
34fn new_remote_curl() -> (63fn new_remote_curl() -> (
35 std::thread::JoinHandle<Result<(), curl::Error>>,64 thread::JoinHandle<Result<(), curl::Error>>,
36 SyncSender<Request>,65 SyncSender<Request>,
37 Receiver<Response>,66 Receiver<Response>,
38) {67) {
@@ -85,7 +114,7 @@ fn new_remote_curl() -> ( · 46 unmodified lines
85 .send(Response {114 .send(Response {
86 headers: receive_headers,115 headers: receive_headers,
87 body: receive_data,116 body: receive_data,
88 upload_body: send_body,117 _upload_body: send_body,
89 })118 })
90 .is_err()119 .is_err()
91 {120 {
@@ -97,14 +126,6 @@ fn new_remote_curl() -> ( · 5 unmodified lines
97 (handle, req_send, res_recv)126 (handle, req_send, res_recv)
98}127}
99 128
100impl Curl {
101 pub fn new() -> Self {
102 Curl {
103 handle: Easy2::new(Handler::default()),
104 }
105 }
106}
107
108impl From<curl::Error> for http::Error {129impl From<curl::Error> for http::Error {
109 fn from(err: curl::Error) -> Self {130 fn from(err: curl::Error) -> Self {
110 http::Error::Detail(err.to_string())131 http::Error::Detail(err.to_string())
@@ -120,19 +141,30 @@ impl crate::client::http::Http for Curl { · 9 unmodified lines
120 url: &str,141 url: &str,
121 headers: impl IntoIterator<Item = impl AsRef<str>>,142 headers: impl IntoIterator<Item = impl AsRef<str>>,
122 ) -> Result<(Self::Headers, Self::ResponseBody), http::Error> {143 ) -> Result<(Self::Headers, Self::ResponseBody), http::Error> {
123 self.handle.url(url)?;
124 let mut list = curl::easy::List::new();144 let mut list = curl::easy::List::new();
125 for header in headers {145 for header in headers {
126 list.append(header.as_ref())?;146 list.append(header.as_ref())?;
127 }147 }
128 self.handle.http_headers(list)?;148 if self
129 149 .req
130 let (send, receive_data) = pipe::unidirectional(1);150 .send(Request {
131 self.handle.get_mut().send_data = Some(send);151 url: url.to_owned(),
132 let (send, receive_headers) = pipe::unidirectional(1);152 headers: list,
133 self.handle.get_mut().send_header = Some(send);153 })
134 154 .is_err()
135 Ok((receive_headers, receive_data))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))
136 }168 }
137 169
138 fn post(170 fn post(
git-transport/src/client/http/mod.rs+0−3
@@ -9,9 +9,6 @@ quick_error! { · 8 unmodified lines
9 Detail(description: String) {9 Detail(description: String) {
10 display("{}", description)10 display("{}", description)
11 }11 }
12 Status(status: u16, method: &'static str, url: String) {
13 display("{}:{} saw HTTP status {}", method, url, status)
14 }
15 }12 }
16}13}
17 14