-
Notifications
You must be signed in to change notification settings - Fork 426
Description
Hi!
First thing first, I'd like to say that this crate is nice and it's pretty cool to use.
Now, I think creating custom transport, like https://github.com/rust-lang/git2-rs/tree/master/git2-curl but with rpc=false will fail. I may be missing a thing, but I'm currently writing a custom transport with this crate. The transport is using a bidirectional channel with a custom & minimal git server I did.
struct WolfTransport {
channel: Arc<Mutex<Channel<Vec<u8>, Vec<u8>>>>,
}
(...)
Transport::smart(
remote,
false, // Here git2-curl is true
WolfTransport {
channel
},
)Now, just to get a trace, this is what I see and what is problematic:
Client: git-2-rs:transport.rs => subtransport_action with action = upload-pack-ls
Client: SmartSubtransport::action (with action = upload-pack-ls) Init subtransport, return Ok(Box::new(WolfSubTransport {
Client: WolfSubTransport::read()
Server: recv pkt: 0028git-upload-pack /zdshost=localhost
Server: send references capabilities
006ac29eb686c3638633bff5b852ee1ed76211882ba1 HEADside-band side-band-64k shallow no-progress include-tag
003f7300c6f39366e2c0bcaf99efc05cc45e8511a384 refs/heads/master
0046c29eb686c3638633bff5b852ee1ed76211882ba1 refs/remotes/origin/HEAD
0048c29eb686c3638633bff5b852ee1ed76211882ba1 refs/remotes/origin/master
Client: WolfSubTransport::read()
Server: send flush (0000)
Client: SmartSubtransport::action (with action = upload-pack) Init subtransport, return Ok(Box::new(WolfSubTransport {
Client: WolfSubTransport::write()
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { code: -1, klass: 35, message: "unrecoverable internal error: \'t->rpc || t->current_stream == stream\'" }', src/main.rs:33:53
I don't know if it's clear, but the issue is located during the second Init subtransport. libgit2 will call subtransport_action with action=upload-pack and here, subtransport_action should and, because rpc=false re-use previous initialized stream to be able to send want xxxxxxxxx packets and start packfile negotiation.
This is basically what we will have in cpp with libgit2:
int
SubTransportAction(git_smart_subtransport_stream** out,
git_smart_subtransport* transport,
const char* url,
git_smart_service_t action)
{
auto* sub = reinterpret_cast<SubTransport*>(transport);
if (!sub || !sub->remote) {
return -1;
}
if (action == GIT_SERVICE_UPLOADPACK_LS) {
auto stream = std::make_unique<Stream>();
// Init Stream cb
sub->stream = std::move(stream);
*out = &sub->stream->base;
return 0;
} else if (action == GIT_SERVICE_UPLOADPACK) {
if (sub->stream) {
*out = &sub->stream->base;
return 0;
}
return -1;
}
return 0;
}However in current implementation (
Line 250 in 6880563
| let obj = match transport.obj.action(url, action) { |
So imho subtransport_action should be rewritten in order to be able to return the previous stream if necessary. I don't have a fix and don't know what would be the preferred solution (or if I missed something, I just saw that this morning at 1am).
Best regards,