🏡 index : ~doyle/chartered.git

author Jordan Doyle <jordan@doyle.la> 2021-08-30 20:46:09.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2021-08-30 20:46:09.0 +01:00:00
commit
ab8d6b2533ef970edd6b201d0207cc3c86b95376 [patch]
tree
d7572c2d4fbe30c970040435363e0e01499f6c98
parent
bbbde41699d81968662685bda1bf657b92c4f408
download
ab8d6b2533ef970edd6b201d0207cc3c86b95376.tar.gz

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(-)

diff --git a/Cargo.lock b/Cargo.lock
index d019dc2..9fd759c 100644
--- a/Cargo.lock
+++ a/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index d85c62a..b65ea86 100644
--- a/Cargo.toml
+++ a/Cargo.toml
@@ -23,3 +23,7 @@
sha-1 = "0.9"
const-sha1 = "0.2"
crc = "2"


format-bytes = "0.1"
hex = "0.4"
diff --git a/src/main.rs b/src/main.rs
index 03b6e7f..06cb08f 100644
--- a/src/main.rs
+++ a/src/main.rs
@@ -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;
                }
            }

            // echo -ne "0012command=fetch\n0001000ethin-pack\n0010include-tag\n000eofs-delta\n0032want d24d8020163b5fee57c9babfd0c595b8c90ba253\n0009done\n"
            // echo -ne

            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()
                ))
            );

            // echo -ne "0014command=ls-refs\n0014agent=git/2.321\n00010008peel000bsymrefs000aunborn0014ref-prefix HEAD\n0000"
            // GIT_PROTOCOL=version=2 ssh -o SendEnv=GIT_PROTOCOL git@github.com git-upload-pack '/w4/chartered.git'
@@ -163,7 +206,9 @@
            // sends a 000dpackfile back
            // https://shafiul.github.io/gitbook/7_the_packfile.html
            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); // sideband, 1 = msg
                    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!",
                )?]);
                // fatal: bad object 4ff484817ca2f1a10183da210a6e74f29764857d
                // error: ssh://127.0.0.1:2233/ did not send all necessary objects
                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!",
                    )?,
                ]);

                // {
                //     let mut buf = BytesMut::new();
@@ -198,14 +263,26 @@

                {
                    let mut buf = BytesMut::new();
                    buf.put_u8(1);
                    buf.put_u8(1); // sideband, 1 = continue
                    packfile.encode_to(&mut buf)?;
                    self.write(PktLine::Data(buf.as_ref()))?;
                }

                self.write(PktLine::Flush)?;
                // {
                //     let mut buf = BytesMut::new();
                //     buf.put_u8(2); // sideband, 1 = msg
                //     buf.extend_from_slice(
                //         b"Total 3 (delta 0), reused 0 (delta 0), pack-reused 0\n",
                //     );
                //     self.write(PktLine::Data(buf.as_ref()))?;
                //     self.flush(&mut session, channel);
                // }

                self.write(PktLine::Flush)?;
                self.flush(&mut session, channel);
                session.exit_status_request(channel, 0);
                session.eof(channel);
                session.close(channel);
            }

            Ok((self, session))
diff --git a/src/git/packfile.rs b/src/git/packfile.rs
index cdb78f9..48c06f0 100644
--- a/src/git/packfile.rs
+++ a/src/git/packfile.rs
@@ -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};

// The offset/sha1[] tables are sorted by sha1[] values (this is to
// allow binary search of this table), and fanout[] table points at
@@ -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);