git client successfully pulling a text file from server
Diff
Cargo.lock | 30 ++++++++++++++++++++++++++++++
Cargo.toml | 4 ++++
src/main.rs | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
src/git/packfile.rs | 6 +++---
4 files changed, 122 insertions(+), 11 deletions(-)
@@ -194,7 +194,9 @@
"crc",
"env_logger",
"flate2",
"format-bytes",
"futures",
"hex",
"sha-1",
"thrussh",
"thrussh-keys",
@@ -358,6 +360,28 @@
]
[[package]]
name = "format-bytes"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e244f30e6c9389f9df0c65fe09a81bcd766c766fca74f0f12d0dae34de33a608"
dependencies = [
"format-bytes-macros",
"proc-macro-hack",
]
[[package]]
name = "format-bytes-macros"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63987e7c19e6a14fc925a32b82c5d4805c7ca6de815fbdb79c457354ff060e45"
dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -480,6 +504,12 @@
dependencies = [
"libc",
]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hmac"
@@ -23,3 +23,7 @@
sha-1 = "0.9"
const-sha1 = "0.2"
crc = "2"
format-bytes = "0.1"
hex = "0.4"
@@ -1,9 +1,9 @@
pub mod git;
use crate::git::PktLine;
use bytes::BytesMut;
use bytes::BufMut;
use bytes::BytesMut;
use futures::future::Future;
use git::codec::Encoder;
use git::codec::GitCodec;
@@ -152,9 +152,52 @@
} else if frame.as_ref() == "command=fetch".as_bytes() {
fetch = true;
} else if frame.as_ref() == "done".as_bytes() {
fetch = false;
done = true;
}
}
let tree_bytes = format_bytes::format_bytes!(
b"100644 test\0{}",
const_sha1::sha1(&const_sha1::ConstBuffer::from_slice(
"blob 33\0testing this is a test cool test!".as_bytes()
))
.bytes()
);
let tree = format_bytes::format_bytes!(
b"tree {}\0{}",
tree_bytes.len().to_string().as_bytes(),
tree_bytes
);
let tree_hash = hex::encode(sha1::Sha1::digest(&tree));
let commit_bytes = format!(
"tree {}
author Jordan Doyle <jordan@doyle.la> 1630244577 +0100
committer Jordan Doyle <jordan@doyle.la> 1630244577 +0100
test",
tree_hash
);
let commit = format!("commit {}\0{}", commit_bytes.len(), commit_bytes);
let commit_hash = hex::encode(sha1::Sha1::digest(commit.as_bytes()));
use sha1::Digest;
println!(
"commit hash: {} - tree hash: {} - file hash: {}",
commit_hash,
tree_hash,
const_sha1::sha1(&const_sha1::ConstBuffer::from_slice(
"blob 33\0testing this is a test cool test!".as_bytes()
))
);
@@ -163,7 +206,9 @@
if ls_refs {
self.write(PktLine::Data(b"1a1b25ae7c87a0e87b7a9aa478a6bc4331c6b954 HEAD symref-target:refs/heads/master\n"))?;
self.write(PktLine::Data(
format!("{} HEAD symref-target:refs/heads/master\n", commit_hash).as_bytes(),
))?;
self.write(PktLine::Flush)?;
self.flush(&mut session, channel);
}
@@ -179,11 +224,31 @@
if done {
self.write(PktLine::Data(b"packfile\n"))?;
{
let mut buf = BytesMut::new();
buf.put_u8(2);
buf.extend_from_slice(b"Hello from chartered!\n");
self.write(PktLine::Data(buf.as_ref()))?;
self.flush(&mut session, channel);
}
let packfile = git::packfile::PackFile::new(vec![git::packfile::PackFileEntry::new(
git::packfile::PackFileEntryType::Blob,
b"testing this is a test cool test!",
)?]);
let packfile = git::packfile::PackFile::new(vec![
git::packfile::PackFileEntry::new(
git::packfile::PackFileEntryType::Commit,
commit_bytes.as_bytes(),
)?,
git::packfile::PackFileEntry::new(
git::packfile::PackFileEntryType::Tree,
&tree_bytes,
)?,
git::packfile::PackFileEntry::new(
git::packfile::PackFileEntryType::Blob,
b"testing this is a test cool test!",
)?,
]);
@@ -198,14 +263,26 @@
{
let mut buf = BytesMut::new();
buf.put_u8(1);
buf.put_u8(1);
packfile.encode_to(&mut buf)?;
self.write(PktLine::Data(buf.as_ref()))?;
}
self.write(PktLine::Flush)?;
self.write(PktLine::Flush)?;
self.flush(&mut session, channel);
session.exit_status_request(channel, 0);
session.eof(channel);
session.close(channel);
}
Ok((self, session))
@@ -1,9 +1,9 @@
use bytes::{BufMut, BytesMut};
use const_sha1::{sha1, ConstBuffer};
use flate2::{write::ZlibEncoder, Compression};
use sha1::{Digest, Sha1};
use std::convert::TryInto;
use std::io::Write as IoWrite;
use sha1::{Sha1, Digest};
@@ -173,14 +173,14 @@
entry_type: PackFileEntryType,
compressed_data: Vec<u8>,
compressed_crc32: u32,
uncompressed_sha1: [u8; 20],
pub uncompressed_sha1: [u8; 20],
uncompressed_size: usize,
}
impl PackFileEntry {
pub fn new(entry_type: PackFileEntryType, data: &[u8]) -> Result<Self, anyhow::Error> {
let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
e.write_all(&data)?;
e.write_all(data)?;
let compressed_data = e.finish()?;
let compressed_crc32 = crc::Crc::<u32>::new(&crc::CRC_32_CKSUM).checksum(&compressed_data);