Skip to content

Commit 8d22454

Browse files
authored
transport: correctly handle rpc parameter (#684)
When rpc is off, libgit2 reuses the stream allocated during upload-pack-ls or receive-pack-ls. The previous API forced the user of the API to create a new stream even if rpc was false. Issue: #681
1 parent 64920c8 commit 8d22454

File tree

1 file changed

+34
-17
lines changed

1 file changed

+34
-17
lines changed

src/transport.rs

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub trait SmartSubtransport: Send + 'static {
5454
}
5555

5656
/// Actions that a smart transport can ask a subtransport to perform
57-
#[derive(Copy, Clone)]
57+
#[derive(Copy, Clone, PartialEq)]
5858
#[allow(missing_docs)]
5959
pub enum Service {
6060
UploadPackLs,
@@ -87,6 +87,8 @@ struct TransportData {
8787
#[repr(C)]
8888
struct RawSmartSubtransport {
8989
raw: raw::git_smart_subtransport,
90+
stream: Option<*mut raw::git_smart_subtransport_stream>,
91+
rpc: bool,
9092
obj: Box<dyn SmartSubtransport>,
9193
}
9294

@@ -142,6 +144,8 @@ impl Transport {
142144
close: Some(subtransport_close),
143145
free: Some(subtransport_free),
144146
},
147+
stream: None,
148+
rpc,
145149
obj: Box::new(subtransport),
146150
});
147151
let mut defn = raw::git_smart_subtransport_definition {
@@ -246,23 +250,36 @@ extern "C" fn subtransport_action(
246250
raw::GIT_SERVICE_RECEIVEPACK => Service::ReceivePack,
247251
n => panic!("unknown action: {}", n),
248252
};
249-
let transport = &mut *(raw_transport as *mut RawSmartSubtransport);
250-
let obj = match transport.obj.action(url, action) {
251-
Ok(s) => s,
252-
Err(e) => {
253-
set_err(&e);
254-
return e.raw_code() as c_int;
253+
254+
let mut transport = &mut *(raw_transport as *mut RawSmartSubtransport);
255+
// Note: we only need to generate if rpc is on. Else, for receive-pack and upload-pack
256+
// libgit2 reuses the stream generated for receive-pack-ls or upload-pack-ls.
257+
let generate_stream =
258+
transport.rpc || action == Service::UploadPackLs || action == Service::ReceivePackLs;
259+
if generate_stream {
260+
let obj = match transport.obj.action(url, action) {
261+
Ok(s) => s,
262+
Err(e) => {
263+
set_err(&e);
264+
return e.raw_code() as c_int;
265+
}
266+
};
267+
*stream = mem::transmute(Box::new(RawSmartSubtransportStream {
268+
raw: raw::git_smart_subtransport_stream {
269+
subtransport: raw_transport,
270+
read: Some(stream_read),
271+
write: Some(stream_write),
272+
free: Some(stream_free),
273+
},
274+
obj: obj,
275+
}));
276+
transport.stream = Some(*stream);
277+
} else {
278+
if transport.stream.is_none() {
279+
return -1;
255280
}
256-
};
257-
*stream = mem::transmute(Box::new(RawSmartSubtransportStream {
258-
raw: raw::git_smart_subtransport_stream {
259-
subtransport: raw_transport,
260-
read: Some(stream_read),
261-
write: Some(stream_write),
262-
free: Some(stream_free),
263-
},
264-
obj: obj,
265-
}));
281+
*stream = transport.stream.unwrap();
282+
}
266283
0
267284
})
268285
.unwrap_or(-1)

0 commit comments

Comments
 (0)