Merge remote-tracking branch 'origin/mr/18' into main

This commit is contained in:
Nick Mathewson 2021-03-04 13:30:46 -05:00
commit a2ac0f724e
4 changed files with 38 additions and 14 deletions

26
tor-decompress/Cargo.toml Normal file
View File

@ -0,0 +1,26 @@
[package]
name = "tor-decompress"
version = "0.0.0"
authors = ["Nick Mathewson <nickm@torproject.org>"]
edition = "2018"
license = "MIT OR Apache-2.0"
publish = false
[dependencies]
anyhow = "1.0.38"
#async-trait = "0.1.41"
base64 = "0.13.0"
# chrono = "0.4.19"
#event-listener = "2.5.1"
futures = "0.3.13"
hex = "0.4.2"
http = "0.2.3"
httpdate = "0.3.2"
httparse = "1.3.5"
miniz_oxide = "0.4.3"
#rand = "0.7.3"
log = "0.4.14"
thiserror = "1.0.24"
xz2 = "0.1.6"
zstd = "0.6.0"

View File

@ -11,7 +11,7 @@ use anyhow::Result;
/// Possible return conditions from a decompression operation.
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum StatusKind {
pub enum StatusKind {
/// Some data was written.
Written,
/// We're out of space in the output buffer.
@ -23,7 +23,7 @@ pub(crate) enum StatusKind {
/// Return value from [`Decompressor::process`]. It describes how much data
/// was transferred, and what the caller needs to do next.
#[derive(Debug, Clone)]
pub(crate) struct Status {
pub struct Status {
/// The (successful) result of the decompression
pub status: StatusKind,
/// How many bytes were consumed from `inp`.
@ -33,7 +33,7 @@ pub(crate) struct Status {
}
/// An implementation of a compression algorithm, including its state.
pub(crate) trait Decompressor {
pub trait Decompressor {
/// Decompress data from 'inp' into 'out'. If 'finished' is true, no
/// more data will be provided after the current contents of inputs.
fn process(&mut self, inp: &[u8], out: &mut [u8], finished: bool) -> Result<Status>;
@ -43,7 +43,7 @@ pub(crate) trait Decompressor {
///
/// This does more copying than Rust best practices would prefer, but
/// we should never actually use it in practice.
pub(crate) mod identity {
pub mod identity {
use super::{Decompressor, Status, StatusKind};
use anyhow::Result;
@ -80,7 +80,7 @@ pub(crate) mod identity {
/// [`::miniz_oxide::inflate::stream::InflateState`].
///
/// This implements zlib compression as used in Tor.
mod miniz_oxide {
pub mod miniz_oxide {
use super::{Decompressor, Status, StatusKind};
use anyhow::{anyhow, Result};
@ -115,7 +115,7 @@ mod miniz_oxide {
/// Implementation for the [`Decompressor`] trait on [`zstd::stream`].
///
/// This implements zstd compression as used in Tor.
mod zstd {
pub mod zstd {
use super::{Decompressor, Status, StatusKind};
use anyhow::{anyhow, Result};
@ -151,7 +151,7 @@ mod zstd {
/// Implementation for the [`Decompressor`] trait on [`xz2::Stream`].
///
/// This implements lzma compression as used in Tor.
mod lzma {
pub mod lzma {
use super::{Decompressor, Status, StatusKind};
use anyhow::{anyhow, Result};
@ -189,8 +189,8 @@ mod lzma {
#[cfg(test)]
mod test {
use super::Decompressor;
use super::StatusKind;
use crate::decompress::Decompressor;
use std::str;
#[test]

View File

@ -9,6 +9,7 @@ publish = false
[dependencies]
tor-circmgr = { path="../tor-circmgr", version= "*" }
tor-chanmgr = { path="../tor-chanmgr", version= "*", default-features=false }
tor-decompress = { path="../tor-decompress", version= "*", default-features=false }
tor-llcrypto = { path="../tor-llcrypto", version= "*" }
tor-proto = { path="../tor-proto", version= "*" }
tor-netdoc = { path="../tor-netdoc", version= "*" }

View File

@ -14,15 +14,13 @@
#![deny(missing_docs)]
#![deny(clippy::missing_docs_in_private_items)]
mod decompress;
mod err;
pub mod request;
mod response;
mod util;
use crate::decompress::Decompressor;
use tor_circmgr::{CircMgr, DirInfo};
use tor_decompress::{identity, Decompressor, StatusKind};
use anyhow::{Context, Result};
use futures::FutureExt;
@ -230,7 +228,6 @@ async fn read_and_decompress(
let mut written_total = 0;
let mut done_reading = false;
use decompress::StatusKind;
// XXX should be an option and is too long.
let read_timeout = Duration::from_secs(10);
@ -298,7 +295,7 @@ async fn read_and_decompress(
/// Return a decompressor object corresponding to a given Content-Encoding.
fn get_decompressor(encoding: Option<&str>) -> Result<Box<dyn Decompressor + Send>> {
match encoding {
None | Some("identity") => Ok(Box::new(decompress::identity::Identity)),
None | Some("identity") => Ok(Box::new(identity::Identity)),
Some("deflate") => Ok(miniz_oxide::inflate::stream::InflateState::new_boxed(
miniz_oxide::DataFormat::Zlib,
)),
@ -334,7 +331,7 @@ mod test {
let mut buf = vec![0; 2048];
let s = d.process(inp, &mut buf[..], true).unwrap();
// TODO: what if d requires multiple steps to work?
assert_eq!(s.status, decompress::StatusKind::Done);
assert_eq!(s.status, StatusKind::Done);
assert_eq!(s.consumed, inp.len());
buf.truncate(s.written);
buf