[
  {
    "path": ".appveyor.bat",
    "content": "echo on\nSetLocal EnableDelayedExpansion\n\nREM This is the recommended way to choose the toolchain version, according to\nREM Appveyor's documentation.\nSET PATH=C:\\Program Files (x86)\\MSBuild\\%TOOLCHAIN_VERSION%\\Bin;%PATH%\n\nset VCVARSALL=\"C:\\Program Files (x86)\\Microsoft Visual Studio %TOOLCHAIN_VERSION%\\VC\\vcvarsall.bat\"\n\nif [%Platform%] NEQ [x64] goto win32\nset TARGET_ARCH=x86_64\nset TARGET_PROGRAM_FILES=%ProgramFiles%\ncall %VCVARSALL% amd64\nif %ERRORLEVEL% NEQ 0 exit 1\ngoto download\n\n:win32\necho on\nif [%Platform%] NEQ [Win32] exit 1\nset TARGET_ARCH=i686\nset TARGET_PROGRAM_FILES=%ProgramFiles(x86)%\ncall %VCVARSALL% amd64_x86\nif %ERRORLEVEL% NEQ 0 exit 1\ngoto download\n\n:download\nREM vcvarsall turns echo off\necho on\n\nmkdir windows_build_tools\nmkdir windows_build_tools\\\necho Downloading Yasm...\npowershell -Command \"(New-Object Net.WebClient).DownloadFile('http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win64.exe', 'windows_build_tools\\yasm.exe')\"\nif %ERRORLEVEL% NEQ 0 (\n  echo ...downloading Yasm failed.\n  exit 1\n)\n\nmkdir build\nset RUSTUP_URL=https://win.rustup.rs/%TARGET_ARCH%\nset RUSTUP_EXE=build\\rustup-init-%TARGET_ARCH%.exe\necho Downloading %RUSTUP_URL%...\npowershell -Command \"(New-Object Net.WebClient).DownloadFile('%RUSTUP_URL%', '%RUSTUP_EXE%')\"\nif %ERRORLEVEL% NEQ 0 (\n  echo ...downloading rustup failed.\n  exit 1\n)\n\nset TARGET=%TARGET_ARCH%-pc-windows-msvc\n%RUSTUP_EXE% -y --default-host %TARGET% --default-toolchain %RUST%\nif %ERRORLEVEL% NEQ 0 exit 1\n\nset PATH=%USERPROFILE%\\.cargo\\bin;%cd%\\windows_build_tools;%PATH%\n\nif [%Configuration%] == [Release] set CARGO_MODE=--release\n\nset\n\nlink /?\ncl /?\nrustc --version\ncargo --version\n\ncargo test -vv %CARGO_MODE%\nif %ERRORLEVEL% NEQ 0 exit 1\n\nREM Verify that `cargo build`, independent from `cargo test`, works; i.e.\nREM verify that non-test builds aren't trying to use test-only features.\ncargo build -vv %CARGO_MODE%\nif %ERRORLEVEL% NEQ 0 exit 1\n"
  },
  {
    "path": ".appveyor.yml",
    "content": "version: 1.0.{build}\nos:\n  - Visual Studio 2015\nclone_depth: 1\nconfiguration:\n  - Debug\nplatform:\n  - Win32\n  - x64\nenvironment:\n  matrix:\n    - TOOLCHAIN_VERSION: 14.0\n      RUST: stable\n\nbuild_script: .appveyor.bat\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\non:\n  push:\n    branches:\n      - master\n  pull_request:\n\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v2\n    - name: Build\n      run: cargo build --verbose\n    - name: Run tests\n      run: cargo test --verbose\n"
  },
  {
    "path": ".gitignore",
    "content": "target/\n**/*.rs.bk\n.DS_Store\n.idea\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: rust\ncache: cargo\nrust:\n- stable\nscript:\n- cargo build --verbose --all\n- cargo test --verbose --all\nnotifications:\n  email: false\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[package]\nname = \"duma\"\nversion = \"0.2.0\"\nauthors = [\"Matt Gathu <mattgathu@gmail.com>\"]\ndescription = \"A minimal file downloader\"\ndocumentation = \"https://github.com/mattgathu/duma\"\nhomepage = \"https://github.com/mattgathu/duma\"\nrepository = \"https://github.com/mattgathu/duma\"\nreadme = \"README.md\"\nkeywords = [\"http\", \"client\", \"cli\", \"file\", \"download\"]\ncategories = [\"web-programming::http-client\", \"command-line-utilities\", \"network-programming\"]\nlicense = \"MIT\"\nedition = \"2018\"\n\n[dependencies]\nindicatif = \"0.15.0\"\nconsole = \"0.13.0\"\nclap = \"2.33.2\"\nftp = \"3.0.1\"\nthreadpool = \"1.8.1\"\nfailure = { version = \"0.1.8\", features = [] }\nurl = \"1.7.2\"\nreqwest = {version = \"0.10.8\", features = [\"blocking\"]}\n\n[dev-dependencies]\nassert_cmd = \"0.11\"\ntiny_http = \"0.6.2\"\nassert_fs = \"0.11\"\npredicates = \"1.0\"\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Matt Gathu\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "## duma\n\n[![Build Status](https://travis-ci.org/mattgathu/duma.svg?branch=master)](https://travis-ci.org/mattgathu/duma)\n[![Build status](https://ci.appveyor.com/api/projects/status/007cmm9c6c9onai9?svg=true)](https://ci.appveyor.com/project/mattgathu/duma)\n[![Build status](https://github.com/mattgathu/duma/workflows/CI/badge.svg?branch=master)](https://github.com/mattgathu/duma/actions)\n\nA minimal file downloader written in Rust.\n\n## features\n\n* support for **http** and **https** downloads\n* support for **ftp** downloads\n* Download **resume** capability\n* download **progress bar**\n\n## usage\n\n```\nDuma 0.1.0\nMatt Gathu <mattgathu@gmail.com>\nA minimal file downloader\n\nUSAGE:\n    duma [FLAGS] [OPTIONS] <URL>\n\nFLAGS:\n    -c, --continue        resume getting a partially-downloaded file\n    -h, --help            Prints help information\n    -H, --headers         prints the headers sent by the HTTP server\n    -q, --quiet           quiet (no output)\n    -s, --singlethread    download using only a single thread\n    -V, --version         Prints version information\n\nOPTIONS:\n    -U, --useragent <AGENT>                    identify as AGENT instead of Duma/VERSION\n    -O, --output <FILE>                        write documents to FILE\n    -n, --num_connections <NUM_CONNECTIONS>    maximum number of concurrent connections (default is 8)\n    -T, --timeout <SECONDS>                    set all timeout values to SECONDS\n\nARGS:\n    <URL>    url to download\n\n```\n\n## Installation\n\nVia cargo\n\n```\ncargo install duma\n```\n\n## screenshot\n\n![screenshot](screenshot.png)\n\n## license\n\nThis project is license used the MIT license. See [LICENSE](LICENSE) for more details.\n"
  },
  {
    "path": "rustfmt.toml",
    "content": ""
  },
  {
    "path": "src/bar.rs",
    "content": "use indicatif::{ProgressBar, ProgressStyle};\n\nstatic PBAR_FMT: &'static str =\n    \"{msg} {spinner:.green} {percent}% [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} eta: {eta}\";\n\npub fn create_progress_bar(msg: &str, length: Option<u64>) -> ProgressBar {\n    let progbar = match length {\n        Some(len) => ProgressBar::new(len),\n        None => ProgressBar::new_spinner(),\n    };\n\n    progbar.set_message(msg);\n    if length.is_some() {\n        progbar.set_style(\n            ProgressStyle::default_bar()\n                .template(PBAR_FMT)\n                .progress_chars(\"=> \"),\n        );\n    } else {\n        progbar.set_style(ProgressStyle::default_spinner());\n    }\n\n    progbar\n}\n"
  },
  {
    "path": "src/core.rs",
    "content": "use std::cell::RefCell;\nuse std::fmt;\nuse std::io::Read;\nuse std::sync::mpsc;\nuse std::time::Duration;\n\nuse failure::{format_err, Fallible};\nuse reqwest::blocking::{Client, Request};\nuse reqwest::header::{self, HeaderMap, HeaderValue};\nuse url::Url;\n\nuse threadpool::ThreadPool;\n\nuse ftp::FtpStream;\n\n#[derive(Debug, Clone)]\npub struct Config {\n    pub user_agent: String,\n    pub resume: bool,\n    pub headers: HeaderMap,\n    pub file: String,\n    pub timeout: u64,\n    pub concurrent: bool,\n    pub max_retries: i32,\n    pub num_workers: usize,\n    pub bytes_on_disk: Option<u64>,\n    pub chunk_offsets: Option<Vec<(u64, u64)>>,\n    pub chunk_size: u64,\n}\n\n#[allow(unused_variables)]\npub trait EventsHandler {\n    fn on_resume_download(&mut self, bytes_on_disk: u64) {}\n\n    fn on_headers(&mut self, headers: HeaderMap) {}\n\n    fn on_content(&mut self, content: &[u8]) -> Fallible<()> {\n        Ok(())\n    }\n\n    fn on_concurrent_content(&mut self, content: (u64, u64, &[u8])) -> Fallible<()> {\n        Ok(())\n    }\n\n    fn on_content_length(&mut self, ct_len: u64) {}\n\n    fn on_ftp_content_length(&mut self, ct_len: Option<u64>) {}\n\n    fn on_success_status(&self) {}\n\n    fn on_failure_status(&self, status_code: i32) {}\n\n    fn on_finish(&mut self) {}\n\n    fn on_max_retries(&mut self) {}\n\n    fn on_server_supports_resume(&mut self) {}\n}\n\npub struct FtpDownload {\n    url: Url,\n    hooks: Vec<RefCell<Box<dyn EventsHandler>>>,\n}\n\nimpl FtpDownload {\n    pub fn new(url: Url) -> Self {\n        Self {\n            url,\n            hooks: Vec::new(),\n        }\n    }\n\n    pub fn download(&mut self) -> Fallible<()> {\n        let ftp_server = format!(\n            \"{}:{}\",\n            self.url\n                .host_str()\n                .ok_or_else(|| format_err!(\"failed to parse hostname from url: {}\", self.url))?,\n            self.url\n                .port_or_known_default()\n                .ok_or_else(|| format_err!(\"failed to parse port from url: {}\", self.url))?,\n        );\n        let username = if self.url.username().is_empty() {\n            \"anonymous\"\n        } else {\n            self.url.username()\n        };\n        let password = self.url.password().unwrap_or(\"anonymous\");\n\n        let mut path_segments: Vec<&str> = self\n            .url\n            .path_segments()\n            .ok_or_else(|| format_err!(\"failed to get url path segments: {}\", self.url))?\n            .collect();\n        let ftp_fname = path_segments\n            .pop()\n            .ok_or_else(|| format_err!(\"got empty path segments from url: {}\", self.url))?;\n\n        let mut conn = FtpStream::connect(ftp_server)?;\n        conn.login(username, password)?;\n        for path in &path_segments {\n            conn.cwd(path)?;\n        }\n        let ct_len = conn.size(ftp_fname)?;\n        let mut reader = conn.get(ftp_fname)?;\n\n        for hook in &self.hooks {\n            let ct_len = ct_len.map(|x| x as u64);\n            hook.borrow_mut().on_ftp_content_length(ct_len);\n        }\n\n        loop {\n            let mut buffer = vec![0; 2048usize];\n            let bcount = reader.read(&mut buffer[..])?;\n            buffer.truncate(bcount);\n            if !buffer.is_empty() {\n                self.send_content(buffer.as_slice())?;\n            } else {\n                break;\n            }\n        }\n\n        for hook in &self.hooks {\n            hook.borrow_mut().on_finish();\n        }\n\n        Ok(())\n    }\n\n    fn send_content(&self, contents: &[u8]) -> Fallible<()> {\n        for hk in &self.hooks {\n            hk.borrow_mut().on_content(contents)?;\n        }\n        Ok(())\n    }\n    pub fn events_hook<E: EventsHandler + 'static>(&mut self, hk: E) -> &mut FtpDownload {\n        self.hooks.push(RefCell::new(Box::new(hk)));\n        self\n    }\n}\n\npub struct HttpDownload {\n    url: Url,\n    hooks: Vec<RefCell<Box<dyn EventsHandler>>>,\n    conf: Config,\n    retries: i32,\n    client: Client,\n}\n\nimpl fmt::Debug for HttpDownload {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"HttpDownload url: {}\", self.url)\n    }\n}\n\nimpl HttpDownload {\n    pub fn new(url: Url, conf: Config) -> HttpDownload {\n        HttpDownload {\n            url,\n            hooks: Vec::new(),\n            conf,\n            retries: 0,\n            client: Client::new(),\n        }\n    }\n\n    pub fn download(&mut self) -> Fallible<()> {\n        let resp = self\n            .client\n            .get(self.url.as_ref())\n            .timeout(Duration::from_secs(self.conf.timeout))\n            .headers(self.conf.headers.clone())\n            .header(\n                header::USER_AGENT,\n                HeaderValue::from_str(&self.conf.user_agent)?,\n            )\n            .send()?;\n        let headers = resp.headers();\n\n        let server_supports_bytes = match headers.get(header::ACCEPT_RANGES) {\n            Some(val) => val == \"bytes\",\n            None => false,\n        };\n\n        if server_supports_bytes && self.conf.headers.contains_key(header::RANGE) {\n            if self.conf.concurrent {\n                self.conf.headers.remove(header::RANGE);\n            }\n            for hook in &self.hooks {\n                hook.borrow_mut().on_server_supports_resume();\n            }\n        }\n\n        let req = self\n            .client\n            .get(self.url.as_ref())\n            .timeout(Duration::from_secs(self.conf.timeout))\n            .headers(self.conf.headers.clone())\n            .build()?;\n\n        for hk in &self.hooks {\n            hk.borrow_mut().on_headers(headers.clone());\n        }\n        if server_supports_bytes\n            && self.conf.concurrent\n            && headers.contains_key(header::CONTENT_LENGTH)\n        {\n            self.concurrent_download(req, headers.get(header::CONTENT_LENGTH).unwrap())?;\n        } else {\n            self.singlethread_download(req)?;\n        }\n\n        for hook in &self.hooks {\n            hook.borrow_mut().on_finish();\n        }\n\n        Ok(())\n    }\n\n    pub fn events_hook<E: EventsHandler + 'static>(&mut self, hk: E) -> &mut HttpDownload {\n        self.hooks.push(RefCell::new(Box::new(hk)));\n        self\n    }\n\n    fn singlethread_download(&mut self, req: Request) -> Fallible<()> {\n        let mut resp = self.client.execute(req)?;\n        let ct_len = if let Some(val) = resp.headers().get(header::CONTENT_LENGTH) {\n            Some(val.to_str()?.parse::<usize>()?)\n        } else {\n            None\n        };\n        let mut cnt = 0;\n        loop {\n            let mut buffer = vec![0; self.conf.chunk_size as usize];\n            let bcount = resp.read(&mut buffer[..])?;\n            cnt += bcount;\n            buffer.truncate(bcount);\n            if !buffer.is_empty() {\n                self.send_content(buffer.as_slice())?;\n            } else {\n                break;\n            }\n            if Some(cnt) == ct_len {\n                break;\n            }\n        }\n        Ok(())\n    }\n\n    pub fn concurrent_download(&mut self, req: Request, ct_val: &HeaderValue) -> Fallible<()> {\n        let (data_tx, data_rx) = mpsc::channel();\n        let (errors_tx, errors_rx) = mpsc::channel();\n        let ct_len = ct_val.to_str()?.parse::<u64>()?;\n        let chunk_offsets = self\n            .conf\n            .chunk_offsets\n            .clone()\n            .unwrap_or_else(|| self.get_chunk_offsets(ct_len, self.conf.chunk_size));\n        let worker_pool = ThreadPool::new(self.conf.num_workers);\n        for offsets in chunk_offsets {\n            let data_tx = data_tx.clone();\n            let errors_tx = errors_tx.clone();\n            let req = req.try_clone().unwrap();\n            worker_pool.execute(move || download_chunk(req, offsets, data_tx.clone(), errors_tx))\n        }\n\n        let mut count = self.conf.bytes_on_disk.unwrap_or(0);\n        loop {\n            if count == ct_len {\n                break;\n            }\n            let (byte_count, offset, buf) = data_rx.recv()?;\n            count += byte_count;\n            for hk in &self.hooks {\n                hk.borrow_mut()\n                    .on_concurrent_content((byte_count, offset, &buf))?;\n            }\n            match errors_rx.recv_timeout(Duration::from_micros(1)) {\n                Err(_) => {}\n                Ok(offsets) => {\n                    if self.retries > self.conf.max_retries {\n                        for hk in &self.hooks {\n                            hk.borrow_mut().on_max_retries();\n                        }\n                    }\n                    self.retries += 1;\n                    let data_tx = data_tx.clone();\n                    let errors_tx = errors_tx.clone();\n                    let req = req.try_clone().unwrap();\n                    worker_pool.execute(move || download_chunk(req, offsets, data_tx, errors_tx))\n                }\n            }\n        }\n        Ok(())\n    }\n\n    fn get_chunk_offsets(&self, ct_len: u64, chunk_size: u64) -> Vec<(u64, u64)> {\n        let no_of_chunks = ct_len / chunk_size;\n        let mut sizes = Vec::new();\n\n        for chunk in 0..no_of_chunks {\n            let bound = if chunk == no_of_chunks - 1 {\n                ct_len\n            } else {\n                ((chunk + 1) * chunk_size) - 1\n            };\n            sizes.push((chunk * chunk_size, bound));\n        }\n        if sizes.is_empty() {\n            sizes.push((0, ct_len));\n        }\n\n        sizes\n    }\n\n    fn send_content(&mut self, contents: &[u8]) -> Fallible<()> {\n        for hk in &self.hooks {\n            hk.borrow_mut().on_content(contents)?;\n        }\n\n        Ok(())\n    }\n}\n\nfn download_chunk(\n    req: Request,\n    offsets: (u64, u64),\n    sender: mpsc::Sender<(u64, u64, Vec<u8>)>,\n    errors: mpsc::Sender<(u64, u64)>,\n) {\n    fn inner(\n        mut req: Request,\n        offsets: (u64, u64),\n        sender: mpsc::Sender<(u64, u64, Vec<u8>)>,\n        start_offset: &mut u64,\n    ) -> Fallible<()> {\n        let byte_range = format!(\"bytes={}-{}\", offsets.0, offsets.1);\n        let headers = req.headers_mut();\n        headers.insert(header::RANGE, HeaderValue::from_str(&byte_range)?);\n        headers.insert(header::ACCEPT, HeaderValue::from_str(\"*/*\")?);\n        headers.insert(header::CONNECTION, HeaderValue::from_str(\"keep-alive\")?);\n        let mut resp = Client::new().execute(req)?;\n        let chunk_sz = offsets.1 - offsets.0;\n        let mut cnt = 0u64;\n        loop {\n            let mut buf = vec![0; chunk_sz as usize];\n            let byte_count = resp.read(&mut buf[..])?;\n            cnt += byte_count as u64;\n            buf.truncate(byte_count);\n            if !buf.is_empty() {\n                sender.send((byte_count as u64, *start_offset, buf.clone()))?;\n                *start_offset += byte_count as u64;\n            } else {\n                break;\n            }\n            if cnt == (chunk_sz + 1) {\n                break;\n            }\n        }\n\n        Ok(())\n    }\n    let mut start_offset = offsets.0;\n    let end_offset = offsets.1;\n    match inner(req, offsets, sender, &mut start_offset) {\n        Ok(_) => {}\n        Err(_) => match errors.send((start_offset, end_offset)) {\n            _ => {}\n        },\n    }\n}\n"
  },
  {
    "path": "src/download.rs",
    "content": "use std::fs;\nuse std::io::{BufRead, BufReader, BufWriter, Seek, SeekFrom, Write};\nuse std::path::Path;\nuse std::time::Duration;\n\nuse clap::ArgMatches;\nuse console::style;\nuse failure::{format_err, Fallible};\nuse indicatif::{HumanBytes, ProgressBar};\nuse reqwest::blocking::Client;\nuse reqwest::header::{self, HeaderMap, HeaderValue};\n\nuse url::Url;\n\nuse crate::bar::create_progress_bar;\nuse crate::core::{Config, EventsHandler, FtpDownload, HttpDownload};\nuse crate::utils::{decode_percent_encoded_data, get_file_handle};\n\nfn request_headers_from_server(url: &Url, timeout: u64, ua: &str) -> Fallible<HeaderMap> {\n    let resp = Client::new()\n        .get(url.as_ref())\n        .timeout(Duration::from_secs(timeout))\n        .header(header::USER_AGENT, HeaderValue::from_str(ua)?)\n        .header(header::ACCEPT, HeaderValue::from_str(\"*/*\")?)\n        .send()?;\n    Ok(resp.headers().clone())\n}\n\nfn print_headers(headers: HeaderMap) {\n    for (hdr, val) in headers.iter() {\n        println!(\n            \"{}: {}\",\n            style(hdr.as_str()).red(),\n            style(val.to_str().unwrap_or(\"<..>\")).green()\n        );\n    }\n}\n\nfn get_resume_chunk_offsets(\n    fname: &str,\n    ct_len: u64,\n    chunk_size: u64,\n) -> Fallible<Vec<(u64, u64)>> {\n    let st_fname = format!(\"{}.st\", fname);\n    let input = fs::File::open(st_fname)?;\n    let buf = BufReader::new(input);\n    let mut downloaded = vec![];\n    for line in buf.lines() {\n        let l = line?;\n        let l = l.split(':').collect::<Vec<_>>();\n        let n = (l[0].parse::<u64>()?, l[1].parse::<u64>()?);\n        downloaded.push(n);\n    }\n    downloaded.sort_by_key(|a| a.1);\n    let mut chunks = vec![];\n\n    let mut i: u64 = 0;\n    for (bc, offset) in downloaded {\n        if i == offset {\n            i = offset + bc;\n        } else {\n            chunks.push((i, offset - 1));\n            i = offset + bc;\n        }\n    }\n\n    while (ct_len - i) > chunk_size {\n        chunks.push((i, i + chunk_size - 1));\n        i += chunk_size;\n    }\n    chunks.push((i, ct_len));\n\n    Ok(chunks)\n}\n\nfn gen_filename(url: &Url, fname: Option<&str>, headers: Option<&HeaderMap>) -> String {\n    let content_disposition = headers\n        .and_then(|hdrs| hdrs.get(header::CONTENT_DISPOSITION))\n        .and_then(|val| {\n            let val = val.to_str().unwrap_or(\"\");\n            if val.contains(\"filename=\") {\n                Some(val)\n            } else {\n                None\n            }\n        })\n        .and_then(|val| {\n            let x = val\n                .rsplit(';')\n                .nth(0)\n                .unwrap_or(\"\")\n                .rsplit('=')\n                .nth(0)\n                .unwrap_or(\"\")\n                .trim_start_matches('\"')\n                .trim_end_matches('\"');\n            if !x.is_empty() {\n                Some(x.to_string())\n            } else {\n                None\n            }\n        });\n    match fname {\n        Some(name) => name.to_owned(),\n        None => match content_disposition {\n            Some(val) => val,\n            None => {\n                let name = &url.path().split('/').last().unwrap_or(\"\");\n                if !name.is_empty() {\n                    match decode_percent_encoded_data(name) {\n                        Ok(val) => val,\n                        _ => name.to_string(),\n                    }\n                } else {\n                    \"index.html\".to_owned()\n                }\n            }\n        },\n    }\n}\n\nfn calc_bytes_on_disk(fname: &str) -> Fallible<Option<u64>> {\n    // use state file if present\n    let st_fname = format!(\"{}.st\", fname);\n    if Path::new(&st_fname).exists() {\n        let input = fs::File::open(st_fname)?;\n        let buf = BufReader::new(input);\n        let mut byte_count: u64 = 0;\n        for line in buf.lines() {\n            let num_of_bytes = line?\n                .split(':')\n                .nth(0)\n                .ok_or_else(|| format_err!(\"failed to split state file line\"))?\n                .parse::<u64>()?;\n            byte_count += num_of_bytes;\n        }\n        return Ok(Some(byte_count));\n    }\n    match fs::metadata(fname) {\n        Ok(metadata) => Ok(Some(metadata.len())),\n        _ => Ok(None),\n    }\n}\n\nfn prep_headers(fname: &str, resume: bool, user_agent: &str) -> Fallible<HeaderMap> {\n    let bytes_on_disk = calc_bytes_on_disk(fname)?;\n    let mut headers = HeaderMap::new();\n    if let Some(bcount) = bytes_on_disk {\n        if resume {\n            let byte_range = format!(\"bytes={}-\", bcount);\n            headers.insert(header::RANGE, byte_range.parse()?);\n        }\n    }\n\n    headers.insert(header::USER_AGENT, user_agent.parse()?);\n\n    Ok(headers)\n}\n\npub fn ftp_download(url: Url, quiet_mode: bool, filename: Option<&str>) -> Fallible<()> {\n    let fname = gen_filename(&url, filename, None);\n\n    let mut client = FtpDownload::new(url.clone());\n    let events_handler = DefaultEventsHandler::new(&fname, false, false, quiet_mode)?;\n    client.events_hook(events_handler).download()?;\n    Ok(())\n}\n\npub fn http_download(url: Url, args: &ArgMatches, version: &str) -> Fallible<()> {\n    let resume_download = args.is_present(\"continue\");\n    let concurrent_download = !args.is_present(\"singlethread\");\n    let user_agent = args\n        .value_of(\"AGENT\")\n        .unwrap_or(&format!(\"Duma/{}\", version))\n        .to_owned();\n    let timeout = if let Some(secs) = args.value_of(\"SECONDS\") {\n        secs.parse::<u64>()?\n    } else {\n        30u64\n    };\n    let num_workers = if let Some(num) = args.value_of(\"NUM_CONNECTIONS\") {\n        num.parse::<usize>()?\n    } else {\n        8usize\n    };\n    let headers = request_headers_from_server(&url, timeout, &user_agent)?;\n    let fname = gen_filename(&url, args.value_of(\"FILE\"), Some(&headers));\n\n    // early exit if headers flag is present\n    if args.is_present(\"headers\") {\n        print_headers(headers);\n        return Ok(());\n    }\n    let ct_len = if let Some(val) = headers.get(\"Content-Length\") {\n        val.to_str()?.parse::<u64>().unwrap_or(0)\n    } else {\n        0u64\n    };\n\n    let headers = prep_headers(&fname, resume_download, &user_agent)?;\n\n    let state_file_exists = Path::new(&format!(\"{}.st\", fname)).exists();\n    let chunk_size = 512_000u64;\n\n    let chunk_offsets =\n        if state_file_exists && resume_download && concurrent_download && ct_len != 0 {\n            Some(get_resume_chunk_offsets(&fname, ct_len, chunk_size)?)\n        } else {\n            None\n        };\n\n    let bytes_on_disk = if resume_download {\n        calc_bytes_on_disk(&fname)?\n    } else {\n        None\n    };\n\n    let conf = Config {\n        user_agent: user_agent.clone(),\n        resume: resume_download,\n        headers,\n        file: fname.clone(),\n        timeout,\n        concurrent: concurrent_download,\n        max_retries: 100,\n        num_workers,\n        bytes_on_disk,\n        chunk_offsets,\n        chunk_size,\n    };\n\n    let mut client = HttpDownload::new(url.clone(), conf.clone());\n    let quiet_mode = args.is_present(\"quiet\");\n    let events_handler =\n        DefaultEventsHandler::new(&fname, resume_download, concurrent_download, quiet_mode)?;\n    client.events_hook(events_handler).download()?;\n    Ok(())\n}\n\npub struct DefaultEventsHandler {\n    prog_bar: Option<ProgressBar>,\n    bytes_on_disk: Option<u64>,\n    fname: String,\n    file: BufWriter<fs::File>,\n    st_file: Option<BufWriter<fs::File>>,\n    server_supports_resume: bool,\n    quiet_mode: bool,\n}\n\nimpl DefaultEventsHandler {\n    pub fn new(\n        fname: &str,\n        resume: bool,\n        concurrent: bool,\n        quiet_mode: bool,\n    ) -> Fallible<DefaultEventsHandler> {\n        let st_file = if concurrent {\n            Some(BufWriter::new(get_file_handle(\n                &format!(\"{}.st\", fname),\n                resume,\n                true,\n            )?))\n        } else {\n            None\n        };\n        Ok(DefaultEventsHandler {\n            prog_bar: None,\n            bytes_on_disk: calc_bytes_on_disk(fname)?,\n            fname: fname.to_owned(),\n            file: BufWriter::new(get_file_handle(fname, resume, !concurrent)?),\n            st_file,\n            server_supports_resume: false,\n            quiet_mode,\n        })\n    }\n\n    fn create_prog_bar(&mut self, length: Option<u64>) {\n        let byte_count = if self.server_supports_resume {\n            self.bytes_on_disk\n        } else {\n            None\n        };\n        if let Some(len) = length {\n            let exact = style(len).green();\n            let human_readable = style(format!(\"{}\", HumanBytes(len))).red();\n\n            println!(\"Length: {} ({})\", exact, human_readable);\n        } else {\n            println!(\"Length: {}\", style(\"unknown\").red());\n        }\n\n        let prog_bar = create_progress_bar(&self.fname, length);\n        if let Some(count) = byte_count {\n            prog_bar.inc(count);\n        }\n        self.prog_bar = Some(prog_bar);\n    }\n}\n\nimpl EventsHandler for DefaultEventsHandler {\n    fn on_headers(&mut self, headers: HeaderMap) {\n        if self.quiet_mode {\n            return;\n        }\n        let ct_type = if let Some(val) = headers.get(header::CONTENT_TYPE) {\n            val.to_str().unwrap_or(\"\")\n        } else {\n            \"\"\n        };\n        println!(\"Type: {}\", style(ct_type).green());\n\n        println!(\"Saving to: {}\", style(&self.fname).green());\n        if let Some(val) = headers.get(header::CONTENT_LENGTH) {\n            self.create_prog_bar(val.to_str().unwrap_or(\"\").parse::<u64>().ok());\n        } else {\n            println!(\n                \"{}\",\n                style(\"Got no content-length. Progress bar skipped.\").red()\n            );\n        }\n    }\n\n    fn on_ftp_content_length(&mut self, ct_len: Option<u64>) {\n        if !self.quiet_mode {\n            self.create_prog_bar(ct_len);\n        }\n    }\n\n    fn on_server_supports_resume(&mut self) {\n        self.server_supports_resume = true;\n    }\n\n    fn on_content(&mut self, content: &[u8]) -> Fallible<()> {\n        let byte_count = content.len() as u64;\n        self.file.write_all(content)?;\n        if let Some(ref mut b) = self.prog_bar {\n            b.inc(byte_count);\n        }\n\n        Ok(())\n    }\n\n    fn on_concurrent_content(&mut self, content: (u64, u64, &[u8])) -> Fallible<()> {\n        let (byte_count, offset, buf) = content;\n        self.file.seek(SeekFrom::Start(offset))?;\n        self.file.write_all(buf)?;\n        self.file.flush()?;\n        if let Some(ref mut b) = self.prog_bar {\n            b.inc(byte_count);\n        }\n        if let Some(ref mut file) = self.st_file {\n            writeln!(file, \"{}:{}\", byte_count, offset)?;\n            file.flush()?;\n        }\n        Ok(())\n    }\n\n    fn on_resume_download(&mut self, bytes_on_disk: u64) {\n        self.bytes_on_disk = Some(bytes_on_disk);\n    }\n\n    fn on_finish(&mut self) {\n        if let Some(ref mut b) = self.prog_bar {\n            b.finish();\n        }\n        match fs::remove_file(&format!(\"{}.st\", self.fname)) {\n            _ => {}\n        }\n    }\n\n    fn on_max_retries(&mut self) {\n        if !self.quiet_mode {\n            eprintln!(\"{}\", style(\"max retries exceeded. Quitting!\").red());\n        }\n        match self.file.flush() {\n            _ => {}\n        }\n        if let Some(ref mut file) = self.st_file {\n            match file.flush() {\n                _ => {}\n            }\n        }\n        ::std::process::exit(0);\n    }\n\n    fn on_failure_status(&self, status: i32) {\n        if self.quiet_mode {\n            return;\n        }\n        if status == 416 {\n            println!(\n                \"{}\",\n                &style(\"\\nThe file is already fully retrieved; nothing to do.\\n\").red()\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "src/lib.rs",
    "content": "pub mod bar;\npub mod core;\npub mod download;\npub mod utils;\n"
  },
  {
    "path": "src/main.rs",
    "content": "use std::process;\n\nuse clap::{clap_app, crate_version};\nuse duma::download::{ftp_download, http_download};\nuse duma::utils;\nuse failure::{format_err, Fallible};\n\nfn main() {\n    match run() {\n        Ok(_) => {}\n        Err(e) => {\n            eprintln!(\"error: {}\", e);\n            process::exit(1);\n        }\n    }\n}\n\nfn run() -> Fallible<()> {\n    let args = clap_app!(Duma =>\n    (version: crate_version!())\n    (author: \"Matt Gathu <mattgathu@gmail.com>\")\n    (about: \"A minimal file downloader\")\n    (@arg quiet: -q --quiet \"quiet (no output)\")\n    (@arg continue: -c --continue \"resume getting a partially-downloaded file\")\n    (@arg singlethread: -s --singlethread \"download using only a single thread\")\n    (@arg headers: -H --headers \"prints the headers sent by the HTTP server\")\n    (@arg FILE: -O --output +takes_value \"write documents to FILE\")\n    (@arg AGENT: -U --useragent +takes_value \"identify as AGENT instead of Duma/VERSION\")\n    (@arg SECONDS: -T --timeout +takes_value \"set all timeout values to SECONDS\")\n    (@arg NUM_CONNECTIONS: -n --num_connections +takes_value \"maximum number of concurrent connections (default is 8)\")\n    (@arg URL: +required +takes_value \"url to download\")\n    )\n    .get_matches_safe().unwrap_or_else(|e| e.exit());\n\n    let url = utils::parse_url(\n        args.value_of(\"URL\")\n            .ok_or_else(|| format_err!(\"missing URL argument\"))?,\n    )?;\n    let quiet_mode = args.is_present(\"quiet\");\n    let file_name = args.value_of(\"FILE\");\n\n    match url.scheme() {\n        \"ftp\" => ftp_download(url, quiet_mode, file_name),\n        \"http\" | \"https\" => http_download(url, &args, crate_version!()),\n        _ => utils::gen_error(format!(\"unsupported url scheme '{}'\", url.scheme())),\n    }\n}\n"
  },
  {
    "path": "src/utils.rs",
    "content": "use failure::{bail, Fallible};\nuse std::fs::File;\nuse std::fs::OpenOptions;\nuse std::io;\nuse std::path::Path;\nuse url::{ParseError, Url};\n\npub fn parse_url(url: &str) -> Result<Url, ParseError> {\n    match Url::parse(url) {\n        Ok(url) => Ok(url),\n        Err(error) if error == ParseError::RelativeUrlWithoutBase => {\n            let url_with_base = format!(\"{}{}\", \"http://\", url);\n            Url::parse(url_with_base.as_str())\n        }\n        Err(error) => Err(error),\n    }\n}\n\npub fn gen_error(msg: String) -> Fallible<()> {\n    bail!(msg)\n}\n\npub fn get_file_handle(fname: &str, resume_download: bool, append: bool) -> io::Result<File> {\n    if resume_download && Path::new(fname).exists() {\n        if append {\n            match OpenOptions::new().append(true).open(fname) {\n                Ok(file) => Ok(file),\n                Err(error) => Err(error),\n            }\n        } else {\n            match OpenOptions::new().write(true).open(fname) {\n                Ok(file) => Ok(file),\n                Err(error) => Err(error),\n            }\n        }\n    } else {\n        match OpenOptions::new().write(true).create(true).open(fname) {\n            Ok(file) => Ok(file),\n            Err(error) => Err(error),\n        }\n    }\n}\n\npub fn decode_percent_encoded_data(data: &str) -> Fallible<String> {\n    let mut unescaped_bytes: Vec<u8> = Vec::new();\n    let mut bytes = data.bytes();\n    while let Some(b) = bytes.next() {\n        match b as char {\n            '%' => {\n                let bytes_to_decode = &[bytes.next().unwrap(), bytes.next().unwrap()];\n                let hex_str = std::str::from_utf8(bytes_to_decode).unwrap();\n                unescaped_bytes.push(u8::from_str_radix(hex_str, 16).unwrap());\n            }\n            _ => {\n                unescaped_bytes.push(b);\n            }\n        }\n    }\n    Ok(String::from_utf8(unescaped_bytes)?)\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_decode_percent_encoded_data() {\n        let x = \"hello%20world\";\n        let y = decode_percent_encoded_data(x).unwrap();\n        assert_eq!(&y, \"hello world\");\n    }\n}\n"
  },
  {
    "path": "tests/client.rs",
    "content": "mod server;\nuse self::server::setup;\nuse assert_cmd::prelude::*;\nuse assert_fs;\nuse assert_fs::prelude::*;\nuse predicates::prelude::*;\nuse std::process::Command;\n\n#[test]\nfn calling_duma_without_args() {\n    let mut cmd = Command::cargo_bin(env!(\"CARGO_PKG_NAME\")).unwrap();\n    cmd.assert().failure();\n}\n\n#[test]\nfn calling_duma_with_invalid_url() {\n    let mut cmd: Command = Command::cargo_bin(env!(\"CARGO_PKG_NAME\")).unwrap();\n    cmd.args(&[\"wwww.shouldnotwork.com\"]).assert().failure();\n}\n\n#[test]\nfn test_request_timeout() {\n    setup();\n    let mut cmd = Command::cargo_bin(env!(\"CARGO_PKG_NAME\")).unwrap();\n    cmd.args(&[\"-H\", \"-T\", \"3\", \"http://0.0.0.0:35550/timeout\"])\n        .assert()\n        .failure();\n}\n\n#[test]\n#[cfg(all(unix))]\nfn test_headers() {\n    setup();\n    let mut cmd = Command::cargo_bin(env!(\"CARGO_PKG_NAME\")).unwrap();\n    let output = cmd\n        .args(&[\"-H\", \"http://0.0.0.0:35550/headers\"])\n        .output()\n        .expect(\"failed to get command ouput\");\n    let stdout = String::from_utf8(output.stdout).unwrap();\n    assert!(stdout.contains(\"server: tiny-http (Rust)\"));\n    assert!(stdout.contains(\"content-type: text/plain\"));\n    assert!(stdout.contains(\"content-length: 0\"));\n}\n\n#[test]\n#[cfg(all(unix))]\nfn test_file() {\n    setup();\n    let temp = assert_fs::TempDir::new().unwrap().persist_if(true);\n    let input_file = temp.child(\"foo.txt\");\n    let mut cmd = Command::cargo_bin(env!(\"CARGO_PKG_NAME\")).unwrap();\n    cmd.args(&[\"-s\", \"-O\", \"foo.txt\", \"http://0.0.0.0:35550/file\"])\n        .current_dir(temp.path())\n        .assert();\n    input_file.assert(predicate::path::is_file());\n}\n\n#[test]\n#[cfg(all(unix))]\nfn test_content_disposition() {\n    setup();\n    let temp = assert_fs::TempDir::new().unwrap().persist_if(true);\n    let input_file = temp.child(\"renamed.txt\");\n    let mut cmd = Command::cargo_bin(env!(\"CARGO_PKG_NAME\")).unwrap();\n    cmd.args(&[\"-s\", \"http://0.0.0.0:35550/content-disposition\"])\n        .current_dir(temp.path())\n        .assert();\n    input_file.assert(predicate::path::is_file());\n}\n"
  },
  {
    "path": "tests/foo.txt",
    "content": "\tTHE RAPE OF LUCRECE\n\nTO THE\nRIGHT HONORABLE HENRY WRIOTHESLY,\nEarl of Southampton, and Baron of Tichfield.\n\nThe love I dedicate to your lordship is without end; whereof\nthis pamphlet, without beginning, is but a superfluous moiety.\nThe warrant I have of your honourable disposition, not the worth\nof my untutored lines, makes it assured of acceptance. What I\nhave done is yours; what I have to do is yours; being part in\nall I have, devoted yours. Were my worth greater, my duty would\nshow greater; meantime, as it is, it is bound to your lordship,\nto whom I wish long life, still lengthened with all happiness.\n\nYour lordship's in all duty,\nWILLIAM SHAKESPEARE.\n\n\tTHE RAPE OF LUCRECE\n\n\tTHE ARGUMENT\n\nLucius Tarquinius, for his excessive pride surnamed Superbus,\nafter he had caused his own father-in-law Servius Tullius to be\ncruelly murdered, and, contrary to the Roman laws and customs,\nnot requiring or staying for the people's suffrages, had\npossessed himself of the kingdom, went, accompanied with his sons\nand other noblemen of Rome, to besiege Ardea. During which siege\nthe principal men of the army meeting one evening at the tent of\nSextus Tarquinius, the king's son, in their discourses after\nsupper every one commended the virtues of his own wife: among\nwhom Collatinus extolled the incomparable chastity of his wife\nLucretia. In that pleasant humour they posted to Rome; and\nintending, by their secret and sudden arrival, to make trial of\nthat which every one had before avouched, only Collatinus finds\nhis wife, though it were late in the night, spinning amongst her\nmaids: the other ladies were all found dancing and revelling, or\nin several disports. Whereupon the noblemen yielded Collatinus\nthe victory, and his wife the fame. At that time Sextus\nTarquinius being inflamed with Lucrece' beauty, yet smothering\nhis passions for the present, departed with the rest back to the\ncamp; from whence he shortly after privily withdrew himself, and\nwas, according to his estate, royally entertained and lodged by\nLucrece at Collatium. The same night he treacherously stealeth\ninto her chamber, violently ravished her, and early in the\nmorning speedeth away. Lucrece, in this lamentable plight,\nhastily dispatcheth messengers, one to Rome for her father,\nanother to the camp for Collatine. They came, the one\naccompanied with Junius Brutus, the other with Publius Valerius;\nand finding Lucrece attired in mourning habit, demanded the cause\nof her sorrow. She, first taking an oath of them for her\nrevenge, revealed the actor, and whole manner of his dealing, and\nwithal suddenly stabbed herself. Which done, with one consent\nthey all vowed to root out the whole hated family of the\nTarquins; and bearing the dead body to Rome, Brutus acquainted\nthe people with the doer and manner of the vile deed, with a\nbitter invective against the tyranny of the king: wherewith the\npeople were so moved, that with one consent and a general\nacclamation the Tarquins were all exiled, and the state\ngovernment changed from kings to consuls.\n\n\tTHE RAPE OF LUCRECE\n\nFROM the besieged Ardea all in post,\nBorne by the trustless wings of false desire,\nLust-breathed Tarquin leaves the Roman host,\nAnd to Collatium bears the lightless fire\nWhich, in pale embers hid, lurks to aspire\nAnd girdle with embracing flames the waist\nOf Collatine's fair love, Lucrece the chaste.\n\nHaply that name of 'chaste' unhappily set\nThis bateless edge on his keen appetite;\nWhen Collatine unwisely did not let\nTo praise the clear unmatched red and white\nWhich triumph'd in that sky of his delight,\nWhere mortal stars, as bright as heaven's beauties,\nWith pure aspects did him peculiar duties.\n\nFor he the night before, in Tarquin's tent,\nUnlock'd the treasure of his happy state;\nWhat priceless wealth the heavens had him lent\nIn the possession of his beauteous mate;\nReckoning his fortune at such high-proud rate,\nThat kings might be espoused to more fame,\nBut king nor peer to such a peerless dame.\n\nO happiness enjoy'd but of a few!\nAnd, if possess'd, as soon decay'd and done\nAs is the morning's silver-melting dew\nAgainst the golden splendor of the sun!\nAn expired date, cancell'd ere well begun:\nHonour and beauty, in the owner's arms,\nAre weakly fortress'd from a world of harms.\n\nBeauty itself doth of itself persuade\nThe eyes of men without an orator;\nWhat needeth then apologies be made,\nTo set forth that which is so singular?\nOr why is Collatine the publisher\nOf that rich jewel he should keep unknown\nFrom thievish ears, because it is his own?\n\nPerchance his boast of Lucrece' sovereignty\nSuggested this proud issue of a king;\nFor by our ears our hearts oft tainted be:\nPerchance that envy of so rich a thing,\nBraving compare, disdainfully did sting\nHis high-pitch'd thoughts, that meaner men should vaunt\nThat golden hap which their superiors want.\n\nBut some untimely thought did instigate\nHis all-too-timeless speed, if none of those:\nHis honour, his affairs, his friends, his state,\nNeglected all, with swift intent he goes\nTo quench the coal which in his liver glows.\nO rash false heat, wrapp'd in repentant cold,\nThy hasty spring still blasts, and ne'er grows old!\n\nWhen at Collatium this false lord arrived,\nWell was he welcomed by the Roman dame,\nWithin whose face beauty and virtue strived\nWhich of them both should underprop her fame:\nWhen virtue bragg'd, beauty would blush for shame;\nWhen beauty boasted blushes, in despite\nVirtue would stain that o'er with silver white.\n\nBut beauty, in that white intituled,\nFrom Venus' doves doth challenge that fair field:\nThen virtue claims from beauty beauty's red,\nWhich virtue gave the golden age to gild\nTheir silver cheeks, and call'd it then their shield;\nTeaching them thus to use it in the fight,\nWhen shame assail'd, the red should fence the white.\n\nThis heraldry in Lucrece' face was seen,\nArgued by beauty's red and virtue's white\nOf either's colour was the other queen,\nProving from world's minority their right:\nYet their ambition makes them still to fight;\nThe sovereignty of either being so great,\nThat oft they interchange each other's seat.\n\nTheir silent war of lilies and of roses,\nWhich Tarquin view'd in her fair face's field,\nIn their pure ranks his traitor eye encloses;\nWhere, lest between them both it should be kill'd,\nThe coward captive vanquished doth yield\nTo those two armies that would let him go,\nRather than triumph in so false a foe.\n\nNow thinks he that her husband's shallow tongue,--\nThe niggard prodigal that praised her so,--\nIn that high task hath done her beauty wrong,\nWhich far exceeds his barren skill to show:\nTherefore that praise which Collatine doth owe\nEnchanted Tarquin answers with surmise,\nIn silent wonder of still-gazing eyes.\n\nThis earthly saint, adored by this devil,\nLittle suspecteth the false worshipper;\nFor unstain'd thoughts do seldom dream on evil;\nBirds never limed no secret bushes fear:\nSo guiltless she securely gives good cheer\nAnd reverend welcome to her princely guest,\nWhose inward ill no outward harm express'd:\n\nFor that he colour'd with his high estate,\nHiding base sin in plaits of majesty;\nThat nothing in him seem'd inordinate,\nSave something too much wonder of his eye,\nWhich, having all, all could not satisfy;\nBut, poorly rich, so wanteth in his store,\nThat, cloy'd with much, he pineth still for more.\n\nBut she, that never coped with stranger eyes,\nCould pick no meaning from their parling looks,\nNor read the subtle-shining secrecies\nWrit in the glassy margents of such books:\nShe touch'd no unknown baits, nor fear'd no hooks;\nNor could she moralize his wanton sight,\nMore than his eyes were open'd to the light.\n\nHe stories to her ears her husband's fame,\nWon in the fields of fruitful Italy;\nAnd decks with praises Collatine's high name,\nMade glorious by his manly chivalry\nWith bruised arms and wreaths of victory:\nHer joy with heaved-up hand she doth express,\nAnd, wordless, so greets heaven for his success.\n\nFar from the purpose of his coming hither,\nHe makes excuses for his being there:\nNo cloudy show of stormy blustering weather\nDoth yet in his fair welkin once appear;\nTill sable Night, mother of Dread and Fear,\nUpon the world dim darkness doth display,\nAnd in her vaulty prison stows the Day.\n\nFor then is Tarquin brought unto his bed,\nIntending weariness with heavy spright;\nFor, after supper, long he questioned\nWith modest Lucrece, and wore out the night:\nNow leaden slumber with life's strength doth fight;\nAnd every one to rest themselves betake,\nSave thieves, and cares, and troubled minds, that wake.\n\nAs one of which doth Tarquin lie revolving\nThe sundry dangers of his will's obtaining;\nYet ever to obtain his will resolving,\nThough weak-built hopes persuade him to abstaining:\nDespair to gain doth traffic oft for gaining;\nAnd when great treasure is the meed proposed,\nThough death be adjunct, there's no death supposed.\n\nThose that much covet are with gain so fond,\nFor what they have not, that which they possess\nThey scatter and unloose it from their bond,\nAnd so, by hoping more, they have but less;\nOr, gaining more, the profit of excess\nIs but to surfeit, and such griefs sustain,\nThat they prove bankrupt in this poor-rich gain.\n\nThe aim of all is but to nurse the life\nWith honour, wealth, and ease, in waning age;\nAnd in this aim there is such thwarting strife,\nThat one for all, or all for one we gage;\nAs life for honour in fell battle's rage;\nHonour for wealth; and oft that wealth doth cost\nThe death of all, and all together lost.\n\nSo that in venturing ill we leave to be\nThe things we are for that which we expect;\nAnd this ambitious foul infirmity,\nIn having much, torments us with defect\nOf that we have: so then we do neglect\nThe thing we have; and, all for want of wit,\nMake something nothing by augmenting it.\n\nSuch hazard now must doting Tarquin make,\nPawning his honour to obtain his lust;\nAnd for himself himself be must forsake:\nThen where is truth, if there be no self-trust?\nWhen shall he think to find a stranger just,\nWhen he himself himself confounds, betrays\nTo slanderous tongues and wretched hateful days?\n\nNow stole upon the time the dead of night,\nWhen heavy sleep had closed up mortal eyes:\nNo comfortable star did lend his light,\nNo noise but owls' and wolves' death-boding cries;\nNow serves the season that they may surprise\nThe silly lambs: pure thoughts are dead and still,\nWhile lust and murder wake to stain and kill.\n\nAnd now this lustful lord leap'd from his bed,\nThrowing his mantle rudely o'er his arm;\nIs madly toss'd between desire and dread;\nTh' one sweetly flatters, th' other feareth harm;\nBut honest fear, bewitch'd with lust's foul charm,\nDoth too too oft betake him to retire,\nBeaten away by brain-sick rude desire.\n\nHis falchion on a flint he softly smiteth,\nThat from the cold stone sparks of fire do fly;\nWhereat a waxen torch forthwith he lighteth,\nWhich must be lode-star to his lustful eye;\nAnd to the flame thus speaks advisedly,\n'As from this cold flint I enforced this fire,\nSo Lucrece must I force to my desire.'\n\nHere pale with fear he doth premeditate\nThe dangers of his loathsome enterprise,\nAnd in his inward mind he doth debate\nWhat following sorrow may on this arise:\nThen looking scornfully, he doth despise\nHis naked armour of still-slaughter'd lust,\nAnd justly thus controls his thoughts unjust:\n\n'Fair torch, burn out thy light, and lend it not\nTo darken her whose light excelleth thine:\nAnd die, unhallow'd thoughts, before you blot\nWith your uncleanness that which is divine;\nOffer pure incense to so pure a shrine:\nLet fair humanity abhor the deed\nThat spots and stains love's modest snow-white weed.\n\n'O shame to knighthood and to shining arms!\nO foul dishonour to my household's grave!\nO impious act, including all foul harms!\nA martial man to be soft fancy's slave!\nTrue valour still a true respect should have;\nThen my digression is so vile, so base,\nThat it will live engraven in my face.\n\n'Yea, though I die, the scandal will survive,\nAnd be an eye-sore in my golden coat;\nSome loathsome dash the herald will contrive,\nTo cipher me how fondly I did dote;\nThat my posterity, shamed with the note\nShall curse my bones, and hold it for no sin\nTo wish that I their father had not bin.\n\n'What win I, if I gain the thing I seek?\nA dream, a breath, a froth of fleeting joy.\nWho buys a minute's mirth to wail a week?\nOr sells eternity to get a toy?\nFor one sweet grape who will the vine destroy?\nOr what fond beggar, but to touch the crown,\nWould with the sceptre straight be strucken down?\n\n'If Collatinus dream of my intent,\nWill he not wake, and in a desperate rage\nPost hither, this vile purpose to prevent?\nThis siege that hath engirt his marriage,\nThis blur to youth, this sorrow to the sage,\nThis dying virtue, this surviving shame,\nWhose crime will bear an ever-during blame?\n\n'O, what excuse can my invention make,\nWhen thou shalt charge me with so black a deed?\nWill not my tongue be mute, my frail joints shake,\nMine eyes forego their light, my false heart bleed?\nThe guilt being great, the fear doth still exceed;\nAnd extreme fear can neither fight nor fly,\nBut coward-like with trembling terror die.\n\n'Had Collatinus kill'd my son or sire,\nOr lain in ambush to betray my life,\nOr were he not my dear friend, this desire\nMight have excuse to work upon his wife,\nAs in revenge or quittal of such strife:\nBut as he is my kinsman, my dear friend,\nThe shame and fault finds no excuse nor end.\n\n'Shameful it is; ay, if the fact be known:\nHateful it is; there is no hate in loving:\nI'll beg her love; but she is own:\nThe worst is but denial and reproving:\nMy will is strong, past reason's weak removing.\nWho fears a sentence or an old man's saw\nShall by a painted cloth be kept in awe.'\n\nThus, graceless, holds he disputation\n'Tween frozen conscience and hot-burning will,\nAnd with good thoughts make dispensation,\nUrging the worser sense for vantage still;\nWhich in a moment doth confound and kill\nAll pure effects, and doth so far proceed,\nThat what is vile shows like a virtuous deed.\n\nQuoth he, 'She took me kindly by the hand,\nAnd gazed for tidings in my eager eyes,\nFearing some hard news from the warlike band,\nWhere her beloved Collatinus lies.\nO, how her fear did make her colour rise!\nFirst red as roses that on lawn we lay,\nThen white as lawn, the roses took away.\n\n'And how her hand, in my hand being lock'd\nForced it to tremble with her loyal fear!\nWhich struck her sad, and then it faster rock'd,\nUntil her husband's welfare she did hear;\nWhereat she smiled with so sweet a cheer,\nThat had Narcissus seen her as she stood,\nSelf-love had never drown'd him in the flood.\n\n'Why hunt I then for colour or excuses?\nAll orators are dumb when beauty pleadeth;\nPoor wretches have remorse in poor abuses;\nLove thrives not in the heart that shadows dreadeth:\nAffection is my captain, and he leadeth;\nAnd when his gaudy banner is display'd,\nThe coward fights and will not be dismay'd.\n\n'Then, childish fear, avaunt! debating, die!\nRespect and reason, wait on wrinkled age!\nMy heart shall never countermand mine eye:\nSad pause and deep regard beseem the sage;\nMy part is youth, and beats these from the stage:\nDesire my pilot is, beauty my prize;\nThen who fears sinking where such treasure lies?'\n\nAs corn o'ergrown by weeds, so heedful fear\nIs almost choked by unresisted lust.\nAway he steals with open listening ear,\nFull of foul hope and full of fond mistrust;\nBoth which, as servitors to the unjust,\nSo cross him with their opposite persuasion,\nThat now he vows a league, and now invasion.\n\nWithin his thought her heavenly image sits,\nAnd in the self-same seat sits Collatine:\nThat eye which looks on her confounds his wits;\nThat eye which him beholds, as more divine,\nUnto a view so false will not incline;\nBut with a pure appeal seeks to the heart,\nWhich once corrupted takes the worser part;\n\nAnd therein heartens up his servile powers,\nWho, flatter'd by their leader's jocund show,\nStuff up his lust, as minutes fill up hours;\nAnd as their captain, so their pride doth grow,\nPaying more slavish tribute than they owe.\nBy reprobate desire thus madly led,\nThe Roman lord marcheth to Lucrece' bed.\n\nThe locks between her chamber and his will,\nEach one by him enforced, retires his ward;\nBut, as they open, they all rate his ill,\nWhich drives the creeping thief to some regard:\nThe threshold grates the door to have him heard;\nNight-wandering weasels shriek to see him there;\nThey fright him, yet he still pursues his fear.\n\nAs each unwilling portal yields him way,\nThrough little vents and crannies of the place\nThe wind wars with his torch to make him stay,\nAnd blows the smoke of it into his face,\nExtinguishing his conduct in this case;\nBut his hot heart, which fond desire doth scorch,\nPuffs forth another wind that fires the torch:\n\nAnd being lighted, by the light he spies\nLucretia's glove, wherein her needle sticks:\nHe takes it from the rushes where it lies,\nAnd griping it, the needle his finger pricks;\nAs who should say 'This glove to wanton tricks\nIs not inured; return again in haste;\nThou see'st our mistress' ornaments are chaste.'\n\nBut all these poor forbiddings could not stay him;\nHe in the worst sense construes their denial:\nThe doors, the wind, the glove, that did delay him,\nHe takes for accidental things of trial;\nOr as those bars which stop the hourly dial,\nWho with a lingering slay his course doth let,\nTill every minute pays the hour his debt.\n\n'So, so,' quoth he, 'these lets attend the time,\nLike little frosts that sometime threat the spring,\nTo add a more rejoicing to the prime,\nAnd give the sneaped birds more cause to sing.\nPain pays the income of each precious thing;\nHuge rocks, high winds, strong pirates, shelves and sands,\nThe merchant fears, ere rich at home he lands.'\n\nNow is he come unto the chamber-door,\nThat shuts him from the heaven of his thought,\nWhich with a yielding latch, and with no more,\nHath barr'd him from the blessed thing be sought.\nSo from himself impiety hath wrought,\nThat for his prey to pray he doth begin,\nAs if the heavens should countenance his sin.\n\nBut in the midst of his unfruitful prayer,\nHaving solicited th' eternal power\nThat his foul thoughts might compass his fair fair,\nAnd they would stand auspicious to the hour,\nEven there he starts: quoth he, 'I must deflower:\nThe powers to whom I pray abhor this fact,\nHow can they then assist me in the act?\n\n'Then Love and Fortune be my gods, my guide!\nMy will is back'd with resolution:\nThoughts are but dreams till their effects be tried;\nThe blackest sin is clear'd with absolution;\nAgainst love's fire fear's frost hath dissolution.\nThe eye of heaven is out, and misty night\nCovers the shame that follows sweet delight.'\n\nThis said, his guilty hand pluck'd up the latch,\nAnd with his knee the door he opens wide.\nThe dove sleeps fast that this night-owl will catch:\nThus treason works ere traitors be espied.\nWho sees the lurking serpent steps aside;\nBut she, sound sleeping, fearing no such thing,\nLies at the mercy of his mortal sting.\n\nInto the chamber wickedly he stalks,\nAnd gazeth on her yet unstained bed.\nThe curtains being close, about he walks,\nRolling his greedy eyeballs in his head:\nBy their high treason is his heart misled;\nWhich gives the watch-word to his hand full soon\nTo draw the cloud that hides the silver moon.\n\nLook, as the fair and fiery-pointed sun,\nRushing from forth a cloud, bereaves our sight;\nEven so, the curtain drawn, his eyes begun\nTo wink, being blinded with a greater light:\nWhether it is that she reflects so bright,\nThat dazzleth them, or else some shame supposed;\nBut blind they are, and keep themselves enclosed.\n\nO, had they in that darksome prison died!\nThen had they seen the period of their ill;\nThen Collatine again, by Lucrece' side,\nIn his clear bed might have reposed still:\nBut they must ope, this blessed league to kill;\nAnd holy-thoughted Lucrece to their sight\nMust sell her joy, her life, her world's delight.\n\nHer lily hand her rosy cheek lies under,\nCozening the pillow of a lawful kiss;\nWho, therefore angry, seems to part in sunder,\nSwelling on either side to want his bliss;\nBetween whose hills her head entombed is:\nWhere, like a virtuous monument, she lies,\nTo be admired of lewd unhallow'd eyes.\n\nWithout the bed her other fair hand was,\nOn the green coverlet; whose perfect white\nShow'd like an April daisy on the grass,\nWith pearly sweat, resembling dew of night.\nHer eyes, like marigolds, had sheathed their light,\nAnd canopied in darkness sweetly lay,\nTill they might open to adorn the day.\n\nHer hair, like golden threads, play'd with her breath;\nO modest wantons! wanton modesty!\nShowing life's triumph in the map of death,\nAnd death's dim look in life's mortality:\nEach in her sleep themselves so beautify,\nAs if between them twain there were no strife,\nBut that life lived in death, and death in life.\n\nHer breasts, like ivory globes circled with blue,\nA pair of maiden worlds unconquered,\nSave of their lord no bearing yoke they knew,\nAnd him by oath they truly honoured.\nThese worlds in Tarquin new ambition bred;\nWho, like a foul ursurper, went about\nFrom this fair throne to heave the owner out.\n\nWhat could he see but mightily he noted?\nWhat did he note but strongly he desired?\nWhat he beheld, on that he firmly doted,\nAnd in his will his wilful eye he tired.\nWith more than admiration he admired\nHer azure veins, her alabaster skin,\nHer coral lips, her snow-white dimpled chin.\n\nAs the grim lion fawneth o'er his prey,\nSharp hunger by the conquest satisfied,\nSo o'er this sleeping soul doth Tarquin stay,\nHis rage of lust by gazing qualified;\nSlack'd, not suppress'd; for standing by her side,\nHis eye, which late this mutiny restrains,\nUnto a greater uproar tempts his veins:\n\nAnd they, like straggling slaves for pillage fighting,\nObdurate vassals fell exploits effecting,\nIn bloody death and ravishment delighting,\nNor children's tears nor mothers' groans respecting,\nSwell in their pride, the onset still expecting:\nAnon his beating heart, alarum striking,\nGives the hot charge and bids them do their liking.\n\nHis drumming heart cheers up his burning eye,\nHis eye commends the leading to his hand;\nHis hand, as proud of such a dignity,\nSmoking with pride, march'd on to make his stand\nOn her bare breast, the heart of all her land;\nWhose ranks of blue veins, as his hand did scale,\nLeft there round turrets destitute and pale.\n\nThey, mustering to the quiet cabinet\nWhere their dear governess and lady lies,\nDo tell her she is dreadfully beset,\nAnd fright her with confusion of their cries:\nShe, much amazed, breaks ope her lock'd-up eyes,\nWho, peeping forth this tumult to behold,\nAre by his flaming torch dimm'd and controll'd.\n\nImagine her as one in dead of night\nFrom forth dull sleep by dreadful fancy waking,\nThat thinks she hath beheld some ghastly sprite,\nWhose grim aspect sets every joint a-shaking;\nWhat terror or 'tis! but she, in worser taking,\nFrom sleep disturbed, heedfully doth view\nThe sight which makes supposed terror true.\n\nWrapp'd and confounded in a thousand fears,\nLike to a new-kill'd bird she trembling lies;\nShe dares not look; yet, winking, there appears\nQuick-shifting antics, ugly in her eyes:\nSuch shadows are the weak brain's forgeries;\nWho, angry that the eyes fly from their lights,\nIn darkness daunts them with more dreadful sights.\n\nHis hand, that yet remains upon her breast,--\nRude ram, to batter such an ivory wall!--\nMay feel her heart-poor citizen!--distress'd,\nWounding itself to death, rise up and fall,\nBeating her bulk, that his hand shakes withal.\nThis moves in him more rage and lesser pity,\nTo make the breach and enter this sweet city.\n\nFirst, like a trumpet, doth his tongue begin\nTo sound a parley to his heartless foe;\nWho o'er the white sheet peers her whiter chin,\nThe reason of this rash alarm to know,\nWhich he by dumb demeanor seeks to show;\nBut she with vehement prayers urgeth still\nUnder what colour he commits this ill.\n\nThus he replies: 'The colour in thy face,\nThat even for anger makes the lily pale,\nAnd the red rose blush at her own disgrace,\nShall plead for me and tell my loving tale:\nUnder that colour am I come to scale\nThy never-conquer'd fort: the fault is thine,\nFor those thine eyes betray thee unto mine.\n\n'Thus I forestall thee, if thou mean to chide:\nThy beauty hath ensnared thee to this night,\nWhere thou with patience must my will abide;\nMy will that marks thee for my earth's delight,\nWhich I to conquer sought with all my might;\nBut as reproof and reason beat it dead,\nBy thy bright beauty was it newly bred.\n\n'I see what crosses my attempt will bring;\nI know what thorns the growing rose defends;\nI think the honey guarded with a sting;\nAll this beforehand counsel comprehends:\nBut will is deaf and hears no heedful friends;\nOnly he hath an eye to gaze on beauty,\nAnd dotes on what he looks, 'gainst law or duty.\n\n'I have debated, even in my soul,\nWhat wrong, what shame, what sorrow I shall breed;\nBut nothing can affection's course control,\nOr stop the headlong fury of his speed.\nI know repentant tears ensue the deed,\nReproach, disdain, and deadly enmity;\nYet strive I to embrace mine infamy.'\n\nThis said, he shakes aloft his Roman blade,\nWhich, like a falcon towering in the skies,\nCoucheth the fowl below with his wings' shade,\nWhose crooked beak threats if he mount he dies:\nSo under his insulting falchion lies\nHarmless Lucretia, marking what he tells\nWith trembling fear, as fowl hear falcon's bells.\n\n'Lucrece,' quoth he,'this night I must enjoy thee:\nIf thou deny, then force must work my way,\nFor in thy bed I purpose to destroy thee:\nThat done, some worthless slave of thine I'll slay,\nTo kill thine honour with thy life's decay;\nAnd in thy dead arms do I mean to place him,\nSwearing I slew him, seeing thee embrace him.\n\n'So thy surviving husband shall remain\nThe scornful mark of every open eye;\nThy kinsmen hang their heads at this disdain,\nThy issue blurr'd with nameless bastardy:\nAnd thou, the author of their obloquy,\nShalt have thy trespass cited up in rhymes,\nAnd sung by children in succeeding times.\n\n'But if thou yield, I rest thy secret friend:\nThe fault unknown is as a thought unacted;\nA little harm done to a great good end\nFor lawful policy remains enacted.\nThe poisonous simple sometimes is compacted\nIn a pure compound; being so applied,\nHis venom in effect is purified.\n\n'Then, for thy husband and thy children's sake,\nTender my suit: bequeath not to their lot\nThe shame that from them no device can take,\nThe blemish that will never be forgot;\nWorse than a slavish wipe or birth-hour's blot:\nFor marks descried in men's nativity\nAre nature's faults, not their own infamy.'\n\nHere with a cockatrice' dead-killing eye\nHe rouseth up himself and makes a pause;\nWhile she, the picture of pure piety,\nLike a white hind under the gripe's sharp claws,\nPleads, in a wilderness where are no laws,\nTo the rough beast that knows no gentle right,\nNor aught obeys but his foul appetite.\n\nBut when a black-faced cloud the world doth threat,\nIn his dim mist the aspiring mountains hiding,\nFrom earth's dark womb some gentle gust doth get,\nWhich blows these pitchy vapours from their bidding,\nHindering their present fall by this dividing;\nSo his unhallow'd haste her words delays,\nAnd moody Pluto winks while Orpheus plays.\n\nYet, foul night-waking cat, he doth but dally,\nWhile in his hold-fast foot the weak mouse panteth:\nHer sad behavior feeds his vulture folly,\nA swallowing gulf that even in plenty wanteth:\nHis ear her prayers admits, but his heart granteth\nNo penetrable entrance to her plaining:\nTears harden lust, though marble wear with raining.\n\nHer pity-pleading eyes are sadly fix'd\nIn the remorseless wrinkles of his face;\nHer modest eloquence with sighs is mix'd,\nWhich to her oratory adds more grace.\nShe puts the period often from his place;\nAnd midst the sentence so her accent breaks,\nThat twice she doth begin ere once she speaks.\n\nShe conjures him by high almighty Jove,\nBy knighthood, gentry, and sweet friendship's oath,\nBy her untimely tears, her husband's love,\nBy holy human law, and common troth,\nBy heaven and earth, and all the power of both,\nThat to his borrow'd bed he make retire,\nAnd stoop to honour, not to foul desire.\n\nQuoth she, 'Reward not hospitality\nWith such black payment as thou hast pretended;\nMud not the fountain that gave drink to thee;\nMar not the thing that cannot be amended;\nEnd thy ill aim before thy shoot be ended;\nHe is no woodman that doth bend his bow\nTo strike a poor unseasonable doe.\n\n'My husband is thy friend; for his sake spare me:\nThyself art mighty; for thine own sake leave me:\nMyself a weakling; do not then ensnare me:\nThou look'st not like deceit; do not deceive me.\nMy sighs, like whirlwinds, labour hence to heave thee:\nIf ever man were moved with woman moans,\nBe moved with my tears, my sighs, my groans:\n\n'All which together, like a troubled ocean,\nBeat at thy rocky and wreck-threatening heart,\nTo soften it with their continual motion;\nFor stones dissolved to water do convert.\nO, if no harder than a stone thou art,\nMelt at my tears, and be compassionate!\nSoft pity enters at an iron gate.\n\n'In Tarquin's likeness I did entertain thee:\nHast thou put on his shape to do him shame?\nTo all the host of heaven I complain me,\nThou wrong'st his honour, wound'st his princely name.\nThou art not what thou seem'st; and if the same,\nThou seem'st not what thou art, a god, a king;\nFor kings like gods should govern everything.\n\n'How will thy shame be seeded in thine age,\nWhen thus thy vices bud before thy spring!\nIf in thy hope thou darest do such outrage,\nWhat darest thou not when once thou art a king?\nO, be remember'd, no outrageous thing\nFrom vassal actors can be wiped away;\nThen kings' misdeeds cannot be hid in clay.\n\n'This deed will make thee only loved for fear;\nBut happy monarchs still are fear'd for love:\nWith foul offenders thou perforce must bear,\nWhen they in thee the like offences prove:\nIf but for fear of this, thy will remove;\nFor princes are the glass, the school, the book,\nWhere subjects' eyes do learn, do read, do look.\n\n'And wilt thou be the school where Lust shall learn?\nMust he in thee read lectures of such shame?\nWilt thou be glass wherein it shall discern\nAuthority for sin, warrant for blame,\nTo privilege dishonour in thy name?\nThou black'st reproach against long-living laud,\nAnd makest fair reputation but a bawd.\n\n'Hast thou command? by him that gave it thee,\nFrom a pure heart command thy rebel will:\nDraw not thy sword to guard iniquity,\nFor it was lent thee all that brood to kill.\nThy princely office how canst thou fulfil,\nWhen, pattern'd by thy fault, foul sin may say,\nHe learn'd to sin, and thou didst teach the way?\n\n'Think but how vile a spectacle it were,\nTo view thy present trespass in another.\nMen's faults do seldom to themselves appear;\nTheir own transgressions partially they smother:\nThis guilt would seem death-worthy in thy brother.\nO, how are they wrapp'd in with infamies\nThat from their own misdeeds askance their eyes!\n\n'To thee, to thee, my heaved-up hands appeal,\nNot to seducing lust, thy rash relier:\nI sue for exiled majesty's repeal;\nLet him return, and flattering thoughts retire:\nHis true respect will prison false desire,\nAnd wipe the dim mist from thy doting eyne,\nThat thou shalt see thy state and pity mine.'\n\n'Have done,' quoth he: 'my uncontrolled tide\nTurns not, but swells the higher by this let.\nSmall lights are soon blown out, huge fires abide,\nAnd with the wind in greater fury fret:\nThe petty streams that pay a daily debt\nTo their salt sovereign, with their fresh falls' haste\nAdd to his flow, but alter not his taste.'\n\n'Thou art,' quoth she, 'a sea, a sovereign king;\nAnd, lo, there falls into thy boundless flood\nBlack lust, dishonour, shame, misgoverning,\nWho seek to stain the ocean of thy blood.\nIf all these pretty ills shall change thy good,\nThy sea within a puddle's womb is hearsed,\nAnd not the puddle in thy sea dispersed.\n\n'So shall these slaves be king, and thou their slave;\nThou nobly base, they basely dignified;\nThou their fair life, and they thy fouler grave:\nThou loathed in their shame, they in thy pride:\nThe lesser thing should not the greater hide;\nThe cedar stoops not to the base shrub's foot,\nBut low shrubs wither at the cedar's root.\n\n'So let thy thoughts, low vassals to thy state'--\nNo more,' quoth he; 'by heaven, I will not hear thee:\nYield to my love; if not, enforced hate,\nInstead of love's coy touch, shall rudely tear thee;\nThat done, despitefully I mean to bear thee\nUnto the base bed of some rascal groom,\nTo be thy partner in this shameful doom.'\n\nThis said, he sets his foot upon the light,\nFor light and lust are deadly enemies:\nShame folded up in blind concealing night,\nWhen most unseen, then most doth tyrannize.\nThe wolf hath seized his prey, the poor lamb cries;\nTill with her own white fleece her voice controll'd\nEntombs her outcry in her lips' sweet fold:\n\nFor with the nightly linen that she wears\nHe pens her piteous clamours in her head;\nCooling his hot face in the chastest tears\nThat ever modest eyes with sorrow shed.\nO, that prone lust should stain so pure a bed!\nThe spots whereof could weeping purify,\nHer tears should drop on them perpetually.\n\nBut she hath lost a dearer thing than life,\nAnd he hath won what he would lose again:\nThis forced league doth force a further strife;\nThis momentary joy breeds months of pain;\nThis hot desire converts to cold disdain:\nPure Chastity is rifled of her store,\nAnd Lust, the thief, far poorer than before.\n\nLook, as the full-fed hound or gorged hawk,\nUnapt for tender smell or speedy flight,\nMake slow pursuit, or altogether balk\nThe prey wherein by nature they delight;\nSo surfeit-taking Tarquin fares this night:\nHis taste delicious, in digestion souring,\nDevours his will, that lived by foul devouring.\n\nO, deeper sin than bottomless conceit\nCan comprehend in still imagination!\nDrunken Desire must vomit his receipt,\nEre he can see his own abomination.\nWhile Lust is in his pride, no exclamation\nCan curb his heat or rein his rash desire,\nTill like a jade Self-will himself doth tire.\n\nAnd then with lank and lean discolour'd cheek,\nWith heavy eye, knit brow, and strengthless pace,\nFeeble Desire, all recreant, poor, and meek,\nLike to a bankrupt beggar wails his case:\nThe flesh being proud, Desire doth fight with Grace,\nFor there it revels; and when that decays,\nThe guilty rebel for remission prays.\n\nSo fares it with this faultful lord of Rome,\nWho this accomplishment so hotly chased;\nFor now against himself he sounds this doom,\nThat through the length of times he stands disgraced:\nBesides, his soul's fair temple is defaced;\nTo whose weak ruins muster troops of cares,\nTo ask the spotted princess how she fares.\n\nShe says, her subjects with foul insurrection\nHave batter'd down her consecrated wall,\nAnd by their mortal fault brought in subjection\nHer immortality, and made her thrall\nTo living death and pain perpetual:\nWhich in her prescience she controlled still,\nBut her foresight could not forestall their will.\n\nEven in this thought through the dark night he stealeth,\nA captive victor that hath lost in gain;\nBearing away the wound that nothing healeth,\nThe scar that will, despite of cure, remain;\nLeaving his spoil perplex'd in greater pain.\nShe bears the load of lust he left behind,\nAnd he the burden of a guilty mind.\n\nHe like a thievish dog creeps sadly thence;\nShe like a wearied lamb lies panting there;\nHe scowls and hates himself for his offence;\nShe, desperate, with her nails her flesh doth tear;\nHe faintly flies, sneaking with guilty fear;\nShe stays, exclaiming on the direful night;\nHe runs, and chides his vanish'd, loathed delight.\n\nHe thence departs a heavy convertite;\nShe there remains a hopeless castaway;\nHe in his speed looks for the morning light;\nShe prays she never may behold the day,\n'For day,' quoth she, 'nights scapes doth open lay,\nAnd my true eyes have never practised how\nTo cloak offences with a cunning brow.\n\n'They think not but that every eye can see\nThe same disgrace which they themselves behold;\nAnd therefore would they still in darkness be,\nTo have their unseen sin remain untold;\nFor they their guilt with weeping will unfold,\nAnd grave, like water that doth eat in steel,\nUpon my cheeks what helpless shame I feel.'\n\nHere she exclaims against repose and rest,\nAnd bids her eyes hereafter still be blind.\nShe wakes her heart by beating on her breast,\nAnd bids it leap from thence, where it may find\nSome purer chest to close so pure a mind.\nFrantic with grief thus breathes she forth her spite\nAgainst the unseen secrecy of night:\n\n'O comfort-killing Night, image of hell!\nDim register and notary of shame!\nBlack stage for tragedies and murders fell!\nVast sin-concealing chaos! nurse of blame!\nBlind muffled bawd! dark harbour for defame!\nGrim cave of death! whispering conspirator\nWith close-tongued treason and the ravisher!\n\n'O hateful, vaporous, and foggy Night!\nSince thou art guilty of my cureless crime,\nMuster thy mists to meet the eastern light,\nMake war against proportion'd course of time;\nOr if thou wilt permit the sun to climb\nHis wonted height, yet ere he go to bed,\nKnit poisonous clouds about his golden head.\n\n'With rotten damps ravish the morning air;\nLet their exhaled unwholesome breaths make sick\nThe life of purity, the supreme fair,\nEre he arrive his weary noon-tide prick;\nAnd let thy misty vapours march so thick,\nThat in their smoky ranks his smother'd light\nMay set at noon and make perpetual night.\n\n'Were Tarquin Night, as he is but Night's child,\nThe silver-shining queen he would distain;\nHer twinkling handmaids too, by him defiled,\nThrough Night's black bosom should not peep again:\nSo should I have co-partners in my pain;\nAnd fellowship in woe doth woe assuage,\nAs palmers' chat makes short their pilgrimage.\n\n'Where now I have no one to blush with me,\nTo cross their arms and hang their heads with mine,\nTo mask their brows and hide their infamy;\nBut I alone alone must sit and pine,\nSeasoning the earth with showers of silver brine,\nMingling my talk with tears, my grief with groans,\nPoor wasting monuments of lasting moans.\n\n'O Night, thou furnace of foul-reeking smoke,\nLet not the jealous Day behold that face\nWhich underneath thy black all-hiding cloak\nImmodestly lies martyr'd with disgrace!\nKeep still possession of thy gloomy place,\nThat all the faults which in thy reign are made\nMay likewise be sepulchred in thy shade!\n\n'Make me not object to the tell-tale Day!\nThe light will show, character'd in my brow,\nThe story of sweet chastity's decay,\nThe impious breach of holy wedlock vow:\nYea the illiterate, that know not how\nTo cipher what is writ in learned books,\nWill quote my loathsome trespass in my looks.\n\n'The nurse, to still her child, will tell my story,\nAnd fright her crying babe with Tarquin's name;\nThe orator, to deck his oratory,\nWill couple my reproach to Tarquin's shame;\nFeast-finding minstrels, tuning my defame,\nWill tie the hearers to attend each line,\nHow Tarquin wronged me, I Collatine.\n\n'Let my good name, that senseless reputation,\nFor Collatine's dear love be kept unspotted:\nIf that be made a theme for disputation,\nThe branches of another root are rotted,\nAnd undeserved reproach to him allotted\nThat is as clear from this attaint of mine\nAs I, ere this, was pure to Collatine.\n\n'O unseen shame! invisible disgrace!\nO unfelt sore! crest-wounding, private scar!\nReproach is stamp'd in Collatinus' face,\nAnd Tarquin's eye may read the mot afar,\nHow he in peace is wounded, not in war.\nAlas, how many bear such shameful blows,\nWhich not themselves, but he that gives them knows!\n\n'If, Collatine, thine honour lay in me,\nFrom me by strong assault it is bereft.\nMy honour lost, and I, a drone-like bee,\nHave no perfection of my summer left,\nBut robb'd and ransack'd by injurious theft:\nIn thy weak hive a wandering wasp hath crept,\nAnd suck'd the honey which thy chaste bee kept.\n\n'Yet am I guilty of thy honour's wrack;\nYet for thy honour did I entertain him;\nComing from thee, I could not put him back,\nFor it had been dishonour to disdain him:\nBesides, of weariness he did complain him,\nAnd talk'd of virtue: O unlook'd-for evil,\nWhen virtue is profaned in such a devil!\n\n'Why should the worm intrude the maiden bud?\nOr hateful cuckoos hatch in sparrows' nests?\nOr toads infect fair founts with venom mud?\nOr tyrant folly lurk in gentle breasts?\nOr kings be breakers of their own behests?\nBut no perfection is so absolute,\nThat some impurity doth not pollute.\n\n'The aged man that coffers-up his gold\nIs plagued with cramps and gouts and painful fits;\nAnd scarce hath eyes his treasure to behold,\nBut like still-pining Tantalus he sits,\nAnd useless barns the harvest of his wits;\nHaving no other pleasure of his gain\nBut torment that it cannot cure his pain.\n\n'So then he hath it when he cannot use it,\nAnd leaves it to be master'd by his young;\nWho in their pride do presently abuse it:\nTheir father was too weak, and they too strong,\nTo hold their cursed-blessed fortune long.\nThe sweets we wish for turn to loathed sours\nEven in the moment that we call them ours.\n\n'Unruly blasts wait on the tender spring;\nUnwholesome weeds take root with precious flowers;\nThe adder hisses where the sweet birds sing;\nWhat virtue breeds iniquity devours:\nWe have no good that we can say is ours,\nBut ill-annexed Opportunity\nOr kills his life or else his quality.\n\n'O Opportunity, thy guilt is great!\n'Tis thou that executest the traitor's treason:\nThou set'st the wolf where he the lamb may get;\nWhoever plots the sin, thou 'point'st the season;\n'Tis thou that spurn'st at right, at law, at reason;\nAnd in thy shady cell, where none may spy him,\nSits Sin, to seize the souls that wander by him.\n\n'Thou makest the vestal violate her oath;\nThou blow'st the fire when temperance is thaw'd;\nThou smother'st honesty, thou murder'st troth;\nThou foul abettor! thou notorious bawd!\nThou plantest scandal and displacest laud:\nThou ravisher, thou traitor, thou false thief,\nThy honey turns to gall, thy joy to grief!\n\n'Thy secret pleasure turns to open shame,\nThy private feasting to a public fast,\nThy smoothing titles to a ragged name,\nThy sugar'd tongue to bitter wormwood taste:\nThy violent vanities can never last.\nHow comes it then, vile Opportunity,\nBeing so bad, such numbers seek for thee?\n\n'When wilt thou be the humble suppliant's friend,\nAnd bring him where his suit may be obtain'd?\nWhen wilt thou sort an hour great strifes to end?\nOr free that soul which wretchedness hath chain'd?\nGive physic to the sick, ease to the pain'd?\nThe poor, lame, blind, halt, creep, cry out for thee;\nBut they ne'er meet with Opportunity.\n\n'The patient dies while the physician sleeps;\nThe orphan pines while the oppressor feeds;\nJustice is feasting while the widow weeps;\nAdvice is sporting while infection breeds:\nThou grant'st no time for charitable deeds:\nWrath, envy, treason, rape, and murder's rages,\nThy heinous hours wait on them as their pages.\n\n'When Truth and Virtue have to do with thee,\nA thousand crosses keep them from thy aid:\nThey buy thy help; but Sin ne'er gives a fee,\nHe gratis comes; and thou art well appaid\nAs well to hear as grant what he hath said.\nMy Collatine would else have come to me\nWhen Tarquin did, but he was stay'd by thee.\n\nGuilty thou art of murder and of theft,\nGuilty of perjury and subornation,\nGuilty of treason, forgery, and shift,\nGuilty of incest, that abomination;\nAn accessary by thine inclination\nTo all sins past, and all that are to come,\nFrom the creation to the general doom.\n\n'Mis-shapen Time, copesmate of ugly Night,\nSwift subtle post, carrier of grisly care,\nEater of youth, false slave to false delight,\nBase watch of woes, sin's pack-horse, virtue's snare;\nThou nursest all and murder'st all that are:\nO, hear me then, injurious, shifting Time!\nBe guilty of my death, since of my crime.\n\n'Why hath thy servant, Opportunity,\nBetray'd the hours thou gavest me to repose,\nCancell'd my fortunes, and enchained me\nTo endless date of never-ending woes?\nTime's office is to fine the hate of foes;\nTo eat up errors by opinion bred,\nNot spend the dowry of a lawful bed.\n\n'Time's glory is to calm contending kings,\nTo unmask falsehood and bring truth to light,\nTo stamp the seal of time in aged things,\nTo wake the morn and sentinel the night,\nTo wrong the wronger till he render right,\nTo ruinate proud buildings with thy hours,\nAnd smear with dust their glittering golden towers;\n\n'To fill with worm-holes stately monuments,\nTo feed oblivion with decay of things,\nTo blot old books and alter their contents,\nTo pluck the quills from ancient ravens' wings,\nTo dry the old oak's sap and cherish springs,\nTo spoil antiquities of hammer'd steel,\nAnd turn the giddy round of Fortune's wheel;\n\n'To show the beldam daughters of her daughter,\nTo make the child a man, the man a child,\nTo slay the tiger that doth live by slaughter,\nTo tame the unicorn and lion wild,\nTo mock the subtle in themselves beguiled,\nTo cheer the ploughman with increaseful crops,\nAnd waste huge stones with little water drops.\n\n'Why work'st thou mischief in thy pilgrimage,\nUnless thou couldst return to make amends?\nOne poor retiring minute in an age\nWould purchase thee a thousand thousand friends,\nLending him wit that to bad debtors lends:\nO, this dread night, wouldst thou one hour come back,\nI could prevent this storm and shun thy wrack!\n\n'Thou ceaseless lackey to eternity,\nWith some mischance cross Tarquin in his flight:\nDevise extremes beyond extremity,\nTo make him curse this cursed crimeful night:\nLet ghastly shadows his lewd eyes affright;\nAnd the dire thought of his committed evil\nShape every bush a hideous shapeless devil.\n\n'Disturb his hours of rest with restless trances,\nAfflict him in his bed with bedrid groans;\nLet there bechance him pitiful mischances,\nTo make him moan; but pity not his moans:\nStone him with harden'd hearts harder than stones;\nAnd let mild women to him lose their mildness,\nWilder to him than tigers in their wildness.\n\n'Let him have time to tear his curled hair,\nLet him have time against himself to rave,\nLet him have time of Time's help to despair,\nLet him have time to live a loathed slave,\nLet him have time a beggar's orts to crave,\nAnd time to see one that by alms doth live\nDisdain to him disdained scraps to give.\n\n'Let him have time to see his friends his foes,\nAnd merry fools to mock at him resort;\nLet him have time to mark how slow time goes\nIn time of sorrow, and how swift and short\nHis time of folly and his time of sport;\nAnd ever let his unrecalling crime\nHave time to wail th' abusing of his time.\n\n'O Time, thou tutor both to good and bad,\nTeach me to curse him that thou taught'st this ill!\nAt his own shadow let the thief run mad,\nHimself himself seek every hour to kill!\nSuch wretched hands such wretched blood should spill;\nFor who so base would such an office have\nAs slanderous death's-man to so base a slave?\n\n'The baser is he, coming from a king,\nTo shame his hope with deeds degenerate:\nThe mightier man, the mightier is the thing\nThat makes him honour'd, or begets him hate;\nFor greatest scandal waits on greatest state.\nThe moon being clouded presently is miss'd,\nBut little stars may hide them when they list.\n\n'The crow may bathe his coal-black wings in mire,\nAnd unperceived fly with the filth away;\nBut if the like the snow-white swan desire,\nThe stain upon his silver down will stay.\nPoor grooms are sightless night, kings glorious day:\nGnats are unnoted wheresoe'er they fly,\nBut eagles gazed upon with every eye.\n\n'Out, idle words, servants to shallow fools!\nUnprofitable sounds, weak arbitrators!\nBusy yourselves in skill-contending schools;\nDebate where leisure serves with dull debaters;\nTo trembling clients be you mediators:\nFor me, I force not argument a straw,\nSince that my case is past the help of law.\n\n'In vain I rail at Opportunity,\nAt Time, at Tarquin, and uncheerful Night;\nIn vain I cavil with mine infamy,\nIn vain I spurn at my confirm'd despite:\nThis helpless smoke of words doth me no right.\nThe remedy indeed to do me good\nIs to let forth my foul-defiled blood.\n\n'Poor hand, why quiver'st thou at this decree?\nHonour thyself to rid me of this shame:\nFor if I die, my honour lives in thee;\nBut if I live, thou livest in my defame:\nSince thou couldst not defend thy loyal dame,\nAnd wast afeard to scratch her wicked foe,\nKill both thyself and her for yielding so.'\n\nThis said, from her be-tumbled couch she starteth,\nTo find some desperate instrument of death:\nBut this no slaughterhouse no tool imparteth\nTo make more vent for passage of her breath;\nWhich, thronging through her lips, so vanisheth\nAs smoke from AEtna, that in air consumes,\nOr that which from discharged cannon fumes.\n\n'In vain,' quoth she, 'I live, and seek in vain\nSome happy mean to end a hapless life.\nI fear'd by Tarquin's falchion to be slain,\nYet for the self-same purpose seek a knife:\nBut when I fear'd I was a loyal wife:\nSo am I now: O no, that cannot be;\nOf that true type hath Tarquin rifled me.\n\n'O, that is gone for which I sought to live,\nAnd therefore now I need not fear to die.\nTo clear this spot by death, at least I give\nA badge of fame to slander's livery;\nA dying life to living infamy:\nPoor helpless help, the treasure stol'n away,\nTo burn the guiltless casket where it lay!\n\n'Well, well, dear Collatine, thou shalt not know\nThe stained taste of violated troth;\nI will not wrong thy true affection so,\nTo flatter thee with an infringed oath;\nThis bastard graff shall never come to growth:\nHe shall not boast who did thy stock pollute\nThat thou art doting father of his fruit.\n\n'Nor shall he smile at thee in secret thought,\nNor laugh with his companions at thy state:\nBut thou shalt know thy interest was not bought\nBasely with gold, but stol'n from forth thy gate.\nFor me, I am the mistress of my fate,\nAnd with my trespass never will dispense,\nTill life to death acquit my forced offence.\n\n'I will not poison thee with my attaint,\nNor fold my fault in cleanly-coin'd excuses;\nMy sable ground of sin I will not paint,\nTo hide the truth of this false night's abuses:\nMy tongue shall utter all; mine eyes, like sluices,\nAs from a mountain-spring that feeds a dale,\nShall gush pure streams to purge my impure tale.'\n\nBy this, lamenting Philomel had ended\nThe well-tuned warble of her nightly sorrow,\nAnd solemn night with slow sad gait descended\nTo ugly hell; when, lo, the blushing morrow\nLends light to all fair eyes that light will borrow:\nBut cloudy Lucrece shames herself to see,\nAnd therefore still in night would cloister'd be.\n\nRevealing day through every cranny spies,\nAnd seems to point her out where she sits weeping;\nTo whom she sobbing speaks: 'O eye of eyes,\nWhy pry'st thou through my window? leave thy peeping:\nMock with thy tickling beams eyes that are sleeping:\nBrand not my forehead with thy piercing light,\nFor day hath nought to do what's done by night.'\n\nThus cavils she with every thing she sees:\nTrue grief is fond and testy as a child,\nWho wayward once, his mood with nought agrees:\nOld woes, not infant sorrows, bear them mild;\nContinuance tames the one; the other wild,\nLike an unpractised swimmer plunging still,\nWith too much labour drowns for want of skill.\n\nSo she, deep-drenched in a sea of care,\nHolds disputation with each thing she views,\nAnd to herself all sorrow doth compare;\nNo object but her passion's strength renews;\nAnd as one shifts, another straight ensues:\nSometime her grief is dumb and hath no words;\nSometime 'tis mad and too much talk affords.\n\nThe little birds that tune their morning's joy\nMake her moans mad with their sweet melody:\nFor mirth doth search the bottom of annoy;\nSad souls are slain in merry company;\nGrief best is pleased with grief's society:\nTrue sorrow then is feelingly sufficed\nWhen with like semblance it is sympathized.\n\n'Tis double death to drown in ken of shore;\nHe ten times pines that pines beholding food;\nTo see the salve doth make the wound ache more;\nGreat grief grieves most at that would do it good;\nDeep woes roll forward like a gentle flood,\nWho being stopp'd, the bounding banks o'erflows;\nGrief dallied with nor law nor limit knows.\n\n'You mocking-birds,' quoth she, 'your tunes entomb\nWithin your hollow-swelling feather'd breasts,\nAnd in my hearing be you mute and dumb:\nMy restless discord loves no stops nor rests;\nA woeful hostess brooks not merry guests:\nRelish your nimble notes to pleasing ears;\nDistress likes dumps when time is kept with tears.\n\n'Come, Philomel, that sing'st of ravishment,\nMake thy sad grove in my dishevell'd hair:\nAs the dank earth weeps at thy languishment,\nSo I at each sad strain will strain a tear,\nAnd with deep groans the diapason bear;\nFor burden-wise I'll hum on Tarquin still,\nWhile thou on Tereus descant'st better skill.\n\n'And whiles against a thorn thou bear'st thy part,\nTo keep thy sharp woes waking, wretched I,\nTo imitate thee well, against my heart\nWill fix a sharp knife to affright mine eye;\nWho, if it wink, shall thereon fall and die.\nThese means, as frets upon an instrument,\nShall tune our heart-strings to true languishment.\n\n'And for, poor bird, thou sing'st not in the day,\nAs shaming any eye should thee behold,\nSome dark deep desert, seated from the way,\nThat knows not parching heat nor freezing cold,\nWill we find out; and there we will unfold\nTo creatures stern sad tunes, to change their kinds:\nSince men prove beasts, let beasts bear gentle minds.'\n\nAs the poor frighted deer, that stands at gaze,\nWildly determining which way to fly,\nOr one encompass'd with a winding maze,\nThat cannot tread the way out readily;\nSo with herself is she in mutiny,\nTo live or die which of the twain were better,\nWhen life is shamed, and death reproach's debtor.\n\n'To kill myself,' quoth she, 'alack, what were it,\nBut with my body my poor soul's pollution?\nThey that lose half with greater patience bear it\nThan they whose whole is swallow'd in confusion.\nThat mother tries a merciless conclusion\nWho, having two sweet babes, when death takes one,\nWill slay the other and be nurse to none.\n\n'My body or my soul, which was the dearer,\nWhen the one pure, the other made divine?\nWhose love of either to myself was nearer,\nWhen both were kept for heaven and Collatine?\nAy me! the bark peel'd from the lofty pine,\nHis leaves will wither and his sap decay;\nSo must my soul, her bark being peel'd away.\n\n'Her house is sack'd, her quiet interrupted,\nHer mansion batter'd by the enemy;\nHer sacred temple spotted, spoil'd, corrupted,\nGrossly engirt with daring infamy:\nThen let it not be call'd impiety,\nIf in this blemish'd fort I make some hole\nThrough which I may convey this troubled soul.\n\n'Yet die I will not till my Collatine\nHave heard the cause of my untimely death;\nThat he may vow, in that sad hour of mine,\nRevenge on him that made me stop my breath.\nMy stained blood to Tarquin I'll bequeath,\nWhich by him tainted shall for him be spent,\nAnd as his due writ in my testament.\n\n'My honour I'll bequeath unto the knife\nThat wounds my body so dishonoured.\n'Tis honour to deprive dishonour'd life;\nThe one will live, the other being dead:\nSo of shame's ashes shall my fame be bred;\nFor in my death I murder shameful scorn:\nMy shame so dead, mine honour is new-born.\n\n'Dear lord of that dear jewel I have lost,\nWhat legacy shall I bequeath to thee?\nMy resolution, love, shall be thy boast,\nBy whose example thou revenged mayest be.\nHow Tarquin must be used, read it in me:\nMyself, thy friend, will kill myself, thy foe,\nAnd for my sake serve thou false Tarquin so.\n\n'This brief abridgement of my will I make:\nMy soul and body to the skies and ground;\nMy resolution, husband, do thou take;\nMine honour be the knife's that makes my wound;\nMy shame be his that did my fame confound;\nAnd all my fame that lives disbursed be\nTo those that live, and think no shame of me.\n\n'Thou, Collatine, shalt oversee this will;\nHow was I overseen that thou shalt see it!\nMy blood shall wash the slander of mine ill;\nMy life's foul deed, my life's fair end shall free it.\nFaint not, faint heart, but stoutly say 'So be it:'\nYield to my hand; my hand shall conquer thee:\nThou dead, both die, and both shall victors be.'\n\nThis Plot of death when sadly she had laid,\nAnd wiped the brinish pearl from her bright eyes,\nWith untuned tongue she hoarsely calls her maid,\nWhose swift obedience to her mistress hies;\nFor fleet-wing'd duty with thought's feathers flies.\nPoor Lucrece' cheeks unto her maid seem so\nAs winter meads when sun doth melt their snow.\n\nHer mistress she doth give demure good-morrow,\nWith soft-slow tongue, true mark of modesty,\nAnd sorts a sad look to her lady's sorrow,\nFor why her face wore sorrow's livery;\nBut durst not ask of her audaciously\nWhy her two suns were cloud-eclipsed so,\nNor why her fair cheeks over-wash'd with woe.\n\nBut as the earth doth weep, the sun being set,\nEach flower moisten'd like a melting eye;\nEven so the maid with swelling drops gan wet\nHer circled eyne, enforced by sympathy\nOf those fair suns set in her mistress' sky,\nWho in a salt-waved ocean quench their light,\nWhich makes the maid weep like the dewy night.\n\nA pretty while these pretty creatures stand,\nLike ivory conduits coral cisterns filling:\nOne justly weeps; the other takes in hand\nNo cause, but company, of her drops spilling:\nTheir gentle sex to weep are often willing;\nGrieving themselves to guess at others' smarts,\nAnd then they drown their eyes or break their hearts.\n\nFor men have marble, women waxen, minds,\nAnd therefore are they form'd as marble will;\nThe weak oppress'd, the impression of strange kinds\nIs form'd in them by force, by fraud, or skill:\nThen call them not the authors of their ill,\nNo more than wax shall be accounted evil\nWherein is stamp'd the semblance of a devil.\n\nTheir smoothness, like a goodly champaign plain,\nLays open all the little worms that creep;\nIn men, as in a rough-grown grove, remain\nCave-keeping evils that obscurely sleep:\nThrough crystal walls each little mote will peep:\nThough men can cover crimes with bold stern looks,\nPoor women's faces are their own fault's books.\n\nNo man inveigh against the wither'd flower,\nBut chide rough winter that the flower hath kill'd:\nNot that devour'd, but that which doth devour,\nIs worthy blame. O, let it not be hild\nPoor women's faults, that they are so fulfill'd\nWith men's abuses: those proud lords, to blame,\nMake weak-made women tenants to their shame.\n\nThe precedent whereof in Lucrece view,\nAssail'd by night with circumstances strong\nOf present death, and shame that might ensue\nBy that her death, to do her husband wrong:\nSuch danger to resistance did belong,\nThat dying fear through all her body spread;\nAnd who cannot abuse a body dead?\n\nBy this, mild patience bid fair Lucrece speak\nTo the poor counterfeit of her complaining:\n'My girl,' quoth she, 'on what occasion break\nThose tears from thee, that down thy cheeks are\nraining?\nIf thou dost weep for grief of my sustaining,\nKnow, gentle wench, it small avails my mood:\nIf tears could help, mine own would do me good.\n\n'But tell me, girl, when went'--and there she stay'd\nTill after a deep groan--'Tarquin from hence?'\n'Madam, ere I was up,' replied the maid,\n'The more to blame my sluggard negligence:\nYet with the fault I thus far can dispense;\nMyself was stirring ere the break of day,\nAnd, ere I rose, was Tarquin gone away.\n\n'But, lady, if your maid may be so bold,\nShe would request to know your heaviness.'\n'O, peace!' quoth Lucrece: 'if it should be told,\nThe repetition cannot make it less;\nFor more it is than I can well express:\nAnd that deep torture may be call'd a hell\nWhen more is felt than one hath power to tell.\n\n'Go, get me hither paper, ink, and pen:\nYet save that labour, for I have them here.\nWhat should I say? One of my husband's men\nBid thou be ready, by and by, to bear\nA letter to my lord, my love, my dear;\nBid him with speed prepare to carry it;\nThe cause craves haste, and it will soon be writ.'\n\nHer maid is gone, and she prepares to write,\nFirst hovering o'er the paper with her quill:\nConceit and grief an eager combat fight;\nWhat wit sets down is blotted straight with will;\nThis is too curious-good, this blunt and ill:\nMuch like a press of people at a door,\nThrong her inventions, which shall go before.\n\nAt last she thus begins: 'Thou worthy lord\nOf that unworthy wife that greeteth thee,\nHealth to thy person! next vouchsafe t' afford--\nIf ever, love, thy Lucrece thou wilt see--\nSome present speed to come and visit me.\nSo, I commend me from our house in grief:\nMy woes are tedious, though my words are brief.'\n\nHere folds she up the tenor of her woe,\nHer certain sorrow writ uncertainly.\nBy this short schedule Collatine may know\nHer grief, but not her grief's true quality:\nShe dares not thereof make discovery,\nLest he should hold it her own gross abuse,\nEre she with blood had stain'd her stain'd excuse.\n\nBesides, the life and feeling of her passion\nShe hoards, to spend when he is by to hear her:\nWhen sighs and groans and tears may grace the fashion\nOf her disgrace, the better so to clear her\nFrom that suspicion which the world might bear her.\nTo shun this blot, she would not blot the letter\nWith words, till action might become them better.\n\nTo see sad sights moves more than hear them told;\nFor then eye interprets to the ear\nThe heavy motion that it doth behold,\nWhen every part a part of woe doth bear.\n'Tis but a part of sorrow that we hear:\nDeep sounds make lesser noise than shallow fords,\nAnd sorrow ebbs, being blown with wind of words.\n\nHer letter now is seal'd, and on it writ\n'At Ardea to my lord with more than haste.'\nThe post attends, and she delivers it,\nCharging the sour-faced groom to hie as fast\nAs lagging fowls before the northern blast:\nSpeed more than speed but dull and slow she deems:\nExtremity still urgeth such extremes.\n\nThe homely villain court'sies to her low;\nAnd, blushing on her, with a steadfast eye\nReceives the scroll without or yea or no,\nAnd forth with bashful innocence doth hie.\nBut they whose guilt within their bosoms lie\nImagine every eye beholds their blame;\nFor Lucrece thought he blush'd to her see shame:\n\nWhen, silly groom! God wot, it was defect\nOf spirit, Life, and bold audacity.\nSuch harmless creatures have a true respect\nTo talk in deeds, while others saucily\nPromise more speed, but do it leisurely:\nEven so this pattern of the worn-out age\nPawn'd honest looks, but laid no words to gage.\n\nHis kindled duty kindled her mistrust,\nThat two red fires in both their faces blazed;\nShe thought he blush'd, as knowing Tarquin's lust,\nAnd, blushing with him, wistly on him gazed;\nHer earnest eye did make him more amazed:\nThe more she saw the blood his cheeks replenish,\nThe more she thought he spied in her some blemish.\n\nBut long she thinks till he return again,\nAnd yet the duteous vassal scarce is gone.\nThe weary time she cannot entertain,\nFor now 'tis stale to sigh, to weep, and groan:\nSo woe hath wearied woe, moan tired moan,\nThat she her plaints a little while doth stay,\nPausing for means to mourn some newer way.\n\nAt last she calls to mind where hangs a piece\nOf skilful painting, made for Priam's Troy:\nBefore the which is drawn the power of Greece.\nFor Helen's rape the city to destroy,\nThreatening cloud-kissing Ilion with annoy;\nWhich the conceited painter drew so proud,\nAs heaven, it seem'd, to kiss the turrets bow'd.\n\nA thousand lamentable objects there,\nIn scorn of nature, art gave lifeless life:\nMany a dry drop seem'd a weeping tear,\nShed for the slaughter'd husband by the wife:\nThe red blood reek'd, to show the painter's strife;\nAnd dying eyes gleam'd forth their ashy lights,\nLike dying coals burnt out in tedious nights.\n\nThere might you see the labouring pioner\nBegrimed with sweat, and smeared all with dust;\nAnd from the towers of Troy there would appear\nThe very eyes of men through loop-holes thrust,\nGazing upon the Greeks with little lust:\nSuch sweet observance in this work was had,\nThat one might see those far-off eyes look sad.\n\nIn great commanders grace and majesty\nYou might behold, triumphing in their faces;\nIn youth, quick bearing and dexterity;\nPale cowards, marching on with trembling paces;\nWhich heartless peasants did so well resemble,\nThat one would swear he saw them quake and tremble.\n\nIn Ajax and Ulysses, O, what art\nOf physiognomy might one behold!\nThe face of either cipher'd either's heart;\nTheir face their manners most expressly told:\nIn Ajax' eyes blunt rage and rigor roll'd;\nBut the mild glance that sly Ulysses lent\nShow'd deep regard and smiling government.\n\nThere pleading might you see grave Nestor stand,\nAs 'twere encouraging the Greeks to fight;\nMaking such sober action with his hand,\nThat it beguiled attention, charm'd the sight:\nIn speech, it seem'd, his beard, all silver white,\nWagg'd up and down, and from his lips did fly\nThin winding breath, which purl'd up to the sky.\n\nAbout him were a press of gaping faces,\nWhich seem'd to swallow up his sound advice;\nAll jointly listening, but with several graces,\nAs if some mermaid did their ears entice,\nSome high, some low, the painter was so nice;\nThe scalps of many, almost hid behind,\nTo jump up higher seem'd, to mock the mind.\n\nHere one man's hand lean'd on another's head,\nHis nose being shadow'd by his neighbour's ear;\nHere one being throng'd bears back, all boll'n and\nred;\nAnother smother'd seems to pelt and swear;\nAnd in their rage such signs of rage they bear,\nAs, but for loss of Nestor's golden words,\nIt seem'd they would debate with angry swords.\n\nFor much imaginary work was there;\nConceit deceitful, so compact, so kind,\nThat for Achilles' image stood his spear,\nGriped in an armed hand; himself, behind,\nWas left unseen, save to the eye of mind:\nA hand, a foot, a face, a leg, a head,\nStood for the whole to be imagined.\n\nAnd from the walls of strong-besieged Troy\nWhen their brave hope, bold Hector, march'd to\nfield,\nStood many Trojan mothers, sharing joy\nTo see their youthful sons bright weapons wield;\nAnd to their hope they such odd action yield,\nThat through their light joy seemed to appear,\nLike bright things stain'd, a kind of heavy fear.\n\nAnd from the strand of Dardan, where they fought,\nTo Simois' reedy banks the red blood ran,\nWhose waves to imitate the battle sought\nWith swelling ridges; and their ranks began\nTo break upon the galled shore, and than\nRetire again, till, meeting greater ranks,\nThey join and shoot their foam at Simois' banks.\n\nTo this well-painted piece is Lucrece come,\nTo find a face where all distress is stell'd.\nMany she sees where cares have carved some,\nBut none where all distress and dolour dwell'd,\nTill she despairing Hecuba beheld,\nStaring on Priam's wounds with her old eyes,\nWhich bleeding under Pyrrhus' proud foot lies.\n\nIn her the painter had anatomized\nTime's ruin, beauty's wreck, and grim care's reign:\nHer cheeks with chaps and wrinkles were disguised;\nOf what she was no semblance did remain:\nHer blue blood changed to black in every vein,\nWanting the spring that those shrunk pipes had fed,\nShow'd life imprison'd in a body dead.\n\nOn this sad shadow Lucrece spends her eyes,\nAnd shapes her sorrow to the beldam's woes,\nWho nothing wants to answer her but cries,\nAnd bitter words to ban her cruel foes:\nThe painter was no god to lend her those;\nAnd therefore Lucrece swears he did her wrong,\nTo give her so much grief and not a tongue.\n\n'Poor instrument,' quoth she,'without a sound,\nI'll tune thy woes with my lamenting tongue;\nAnd drop sweet balm in Priam's painted wound,\nAnd rail on Pyrrhus that hath done him wrong;\nAnd with my tears quench Troy that burns so long;\nAnd with my knife scratch out the angry eyes\nOf all the Greeks that are thine enemies.\n\n'Show me the strumpet that began this stir,\nThat with my nails her beauty I may tear.\nThy heat of lust, fond Paris, did incur\nThis load of wrath that burning Troy doth bear:\nThy eye kindled the fire that burneth here;\nAnd here in Troy, for trespass of thine eye,\nThe sire, the son, the dame, and daughter die.\n\n'Why should the private pleasure of some one\nBecome the public plague of many moe?\nLet sin, alone committed, light alone\nUpon his head that hath transgressed so;\nLet guiltless souls be freed from guilty woe:\nFor one's offence why should so many fall,\nTo plague a private sin in general?\n\n'Lo, here weeps Hecuba, here Priam dies,\nHere manly Hector faints, here Troilus swounds,\nHere friend by friend in bloody channel lies,\nAnd friend to friend gives unadvised wounds,\nAnd one man's lust these many lives confounds:\nHad doting Priam cheque'd his son's desire,\nTroy had been bright with fame and not with fire.'\n\nHere feelingly she weeps Troy's painted woes:\nFor sorrow, like a heavy-hanging bell,\nOnce set on ringing, with his own weight goes;\nThen little strength rings out the doleful knell:\nSo Lucrece, set a-work, sad tales doth tell\nTo pencill'd pensiveness and colour'd sorrow;\nShe lends them words, and she their looks doth borrow.\n\nShe throws her eyes about the painting round,\nAnd whom she finds forlorn she doth lament.\nAt last she sees a wretched image bound,\nThat piteous looks to Phrygian shepherds lent:\nHis face, though full of cares, yet show'd content;\nOnward to Troy with the blunt swains he goes,\nSo mild, that Patience seem'd to scorn his woes.\n\nIn him the painter labour'd with his skill\nTo hide deceit, and give the harmless show\nAn humble gait, calm looks, eyes wailing still,\nA brow unbent, that seem'd to welcome woe;\nCheeks neither red nor pale, but mingled so\nThat blushing red no guilty instance gave,\nNor ashy pale the fear that false hearts have.\n\nBut, like a constant and confirmed devil,\nHe entertain'd a show so seeming just,\nAnd therein so ensconced his secret evil,\nThat jealousy itself could not mistrust\nFalse-creeping craft and perjury should thrust\nInto so bright a day such black-faced storms,\nOr blot with hell-born sin such saint-like forms.\n\nThe well-skill'd workman this mild image drew\nFor perjured Sinon, whose enchanting story\nThe credulous old Priam after slew;\nWhose words like wildfire burnt the shining glory\nOf rich-built Ilion, that the skies were sorry,\nAnd little stars shot from their fixed places,\nWhen their glass fell wherein they view'd their faces.\n\nThis picture she advisedly perused,\nAnd chid the painter for his wondrous skill,\nSaying, some shape in Sinon's was abused;\nSo fair a form lodged not a mind so ill:\nAnd still on him she gazed; and gazing still,\nSuch signs of truth in his plain face she spied,\nThat she concludes the picture was belied.\n\n'It cannot be,' quoth she,'that so much guile'--\nShe would have said 'can lurk in such a look;'\nBut Tarquin's shape came in her mind the while,\nAnd from her tongue 'can lurk' from 'cannot' took:\n'It cannot be' she in that sense forsook,\nAnd turn'd it thus,' It cannot be, I find,\nBut such a face should bear a wicked mind.\n\n'For even as subtle Sinon here is painted.\nSo sober-sad, so weary, and so mild,\nAs if with grief or travail he had fainted,\nTo me came Tarquin armed; so beguiled\nWith outward honesty, but yet defiled\nWith inward vice: as Priam him did cherish,\nSo did I Tarquin; so my Troy did perish.\n\n'Look, look, how listening Priam wets his eyes,\nTo see those borrow'd tears that Sinon sheds!\nPriam, why art thou old and yet not wise?\nFor every tear he falls a Trojan bleeds:\nHis eye drops fire, no water thence proceeds;\nThose round clear pearls of his, that move thy pity,\nAre balls of quenchless fire to burn thy city.\n\n'Such devils steal effects from lightless hell;\nFor Sinon in his fire doth quake with cold,\nAnd in that cold hot-burning fire doth dwell;\nThese contraries such unity do hold,\nOnly to flatter fools and make them bold:\nSo Priam's trust false Sinon's tears doth flatter,\nThat he finds means to burn his Troy with water.'\n\nHere, all enraged, such passion her assails,\nThat patience is quite beaten from her breast.\nShe tears the senseless Sinon with her nails,\nComparing him to that unhappy guest\nWhose deed hath made herself herself detest:\nAt last she smilingly with this gives o'er;\n'Fool, fool!' quoth she, 'his wounds will not be sore.'\n\nThus ebbs and flows the current of her sorrow,\nAnd time doth weary time with her complaining.\nShe looks for night, and then she longs for morrow,\nAnd both she thinks too long with her remaining:\nShort time seems long in sorrow's sharp sustaining:\nThough woe be heavy, yet it seldom sleeps,\nAnd they that watch see time how slow it creeps.\n\nWhich all this time hath overslipp'd her thought,\nThat she with painted images hath spent;\nBeing from the feeling of her own grief brought\nBy deep surmise of others' detriment;\nLosing her woes in shows of discontent.\nIt easeth some, though none it ever cured,\nTo think their dolour others have endured.\n\nBut now the mindful messenger, come back,\nBrings home his lord and other company;\nWho finds his Lucrece clad in mourning black:\nAnd round about her tear-stained eye\nBlue circles stream'd; like rainbows in the sky:\nThese water-galls in her dim element\nForetell new storms to those already spent.\n\nWhich when her sad-beholding husband saw,\nAmazedly in her sad face he stares:\nHer eyes, though sod in tears, look'd red and raw,\nHer lively colour kill'd with deadly cares.\nHe hath no power to ask her how she fares:\nBoth stood, like old acquaintance in a trance,\nMet far from home, wondering each other's chance.\n\nAt last he takes her by the bloodless hand,\nAnd thus begins: 'What uncouth ill event\nHath thee befall'n, that thou dost trembling stand?\nSweet love, what spite hath thy fair colour spent?\nWhy art thou thus attired in discontent?\nUnmask, dear dear, this moody heaviness,\nAnd tell thy grief, that we may give redress.'\n\nThree times with sighs she gives her sorrow fire,\nEre once she can discharge one word of woe:\nAt length address'd to answer his desire,\nShe modestly prepares to let them know\nHer honour is ta'en prisoner by the foe;\nWhile Collatine and his consorted lords\nWith sad attention long to hear her words.\n\nAnd now this pale swan in her watery nest\nBegins the sad dirge of her certain ending;\n'Few words,' quoth she, 'Shall fit the trespass best,\nWhere no excuse can give the fault amending:\nIn me moe woes than words are now depending;\nAnd my laments would be drawn out too long,\nTo tell them all with one poor tired tongue.\n\n'Then be this all the task it hath to say\nDear husband, in the interest of thy bed\nA stranger came, and on that pillow lay\nWhere thou was wont to rest thy weary head;\nAnd what wrong else may be imagined\nBy foul enforcement might be done to me,\nFrom that, alas, thy Lucrece is not free.\n\n'For in the dreadful dead of dark midnight,\nWith shining falchion in my chamber came\nA creeping creature, with a flaming light,\nAnd softly cried 'Awake, thou Roman dame,\nAnd entertain my love; else lasting shame\nOn thee and thine this night I will inflict,\nIf thou my love's desire do contradict.\n\n' 'For some hard-favour'd groom of thine,' quoth he,\n'Unless thou yoke thy liking to my will,\nI'll murder straight, and then I'll slaughter thee\nAnd swear I found you where you did fulfil\nThe loathsome act of lust, and so did kill\nThe lechers in their deed: this act will be\nMy fame and thy perpetual infamy.'\n\n'With this, I did begin to start and cry;\nAnd then against my heart he sets his sword,\nSwearing, unless I took all patiently,\nI should not live to speak another word;\nSo should my shame still rest upon record,\nAnd never be forgot in mighty Rome\nTh' adulterate death of Lucrece and her groom.\n\n'Mine enemy was strong, my poor self weak,\nAnd far the weaker with so strong a fear:\nMy bloody judge forbade my tongue to speak;\nNo rightful plea might plead for justice there:\nHis scarlet lust came evidence to swear\nThat my poor beauty had purloin'd his eyes;\nAnd when the judge is robb'd the prisoner dies.\n\n'O, teach me how to make mine own excuse!\nOr at the least this refuge let me find;\nThough my gross blood be stain'd with this abuse,\nImmaculate and spotless is my mind;\nThat was not forced; that never was inclined\nTo accessary yieldings, but still pure\nDoth in her poison'd closet yet endure.'\n\nLo, here, the hopeless merchant of this loss,\nWith head declined, and voice damm'd up with woe,\nWith sad set eyes, and wretched arms across,\nFrom lips new-waxen pale begins to blow\nThe grief away that stops his answer so:\nBut, wretched as he is, he strives in vain;\nWhat he breathes out his breath drinks up again.\n\nAs through an arch the violent roaring tide\nOutruns the eye that doth behold his haste,\nYet in the eddy boundeth in his pride\nBack to the strait that forced him on so fast;\nIn rage sent out, recall'd in rage, being past:\nEven so his sighs, his sorrows, make a saw,\nTo push grief on, and back the same grief draw.\n\nWhich speechless woe of his poor she attendeth,\nAnd his untimely frenzy thus awaketh:\n'Dear lord, thy sorrow to my sorrow lendeth\nAnother power; no flood by raining slaketh.\nMy woe too sensible thy passion maketh\nMore feeling-painful: let it then suffice\nTo drown one woe, one pair of weeping eyes.\n\n'And for my sake, when I might charm thee so,\nFor she that was thy Lucrece, now attend me:\nBe suddenly revenged on my foe,\nThine, mine, his own: suppose thou dost defend me\nFrom what is past: the help that thou shalt lend me\nComes all too late, yet let the traitor die;\nFor sparing justice feeds iniquity.\n\n'But ere I name him, you fair lords,' quoth she,\nSpeaking to those that came with Collatine,\n'Shall plight your honourable faiths to me,\nWith swift pursuit to venge this wrong of mine;\nFor 'tis a meritorious fair design\nTo chase injustice with revengeful arms:\nKnights, by their oaths, should right poor ladies' harms.'\n\nAt this request, with noble disposition\nEach present lord began to promise aid,\nAs bound in knighthood to her imposition,\nLonging to hear the hateful foe bewray'd.\nBut she, that yet her sad task hath not said,\nThe protestation stops. 'O, speak, ' quoth she,\n'How may this forced stain be wiped from me?\n\n'What is the quality of mine offence,\nBeing constrain'd with dreadful circumstance?\nMay my pure mind with the foul act dispense,\nMy low-declined honour to advance?\nMay any terms acquit me from this chance?\nThe poison'd fountain clears itself again;\nAnd why not I from this compelled stain?'\n\nWith this, they all at once began to say,\nHer body's stain her mind untainted clears;\nWhile with a joyless smile she turns away\nThe face, that map which deep impression bears\nOf hard misfortune, carved in it with tears.\n'No, no,' quoth she, 'no dame, hereafter living,\nBy my excuse shall claim excuse's giving.'\n\nHere with a sigh, as if her heart would break,\nShe throws forth Tarquin's name; 'He, he,' she says,\nBut more than 'he' her poor tongue could not speak;\nTill after many accents and delays,\nUntimely breathings, sick and short assays,\nShe utters this, 'He, he, fair lords, 'tis he,\nThat guides this hand to give this wound to me.'\n\nEven here she sheathed in her harmless breast\nA harmful knife, that thence her soul unsheathed:\nThat blow did that it from the deep unrest\nOf that polluted prison where it breathed:\nHer contrite sighs unto the clouds bequeath'd\nHer winged sprite, and through her wounds doth fly\nLife's lasting date from cancell'd destiny.\n\nStone-still, astonish'd with this deadly deed,\nStood Collatine and all his lordly crew;\nTill Lucrece' father, that beholds her bleed,\nHimself on her self-slaughter'd body threw;\nAnd from the purple fountain Brutus drew\nThe murderous knife, and, as it left the place,\nHer blood, in poor revenge, held it in chase;\n\nAnd bubbling from her breast, it doth divide\nIn two slow rivers, that the crimson blood\nCircles her body in on every side,\nWho, like a late-sack'd island, vastly stood\nBare and unpeopled in this fearful flood.\nSome of her blood still pure and red remain'd,\nAnd some look'd black, and that false Tarquin stain'd.\n\nAbout the mourning and congealed face\nOf that black blood a watery rigol goes,\nWhich seems to weep upon the tainted place:\nAnd ever since, as pitying Lucrece' woes,\nCorrupted blood some watery token shows;\nAnd blood untainted still doth red abide,\nBlushing at that which is so putrified.\n\n'Daughter, dear daughter,' old Lucretius cries,\n'That life was mine which thou hast here deprived.\nIf in the child the father's image lies,\nWhere shall I live now Lucrece is unlived?\nThou wast not to this end from me derived.\nIf children predecease progenitors,\nWe are their offspring, and they none of ours.\n\n'Poor broken glass, I often did behold\nIn thy sweet semblance my old age new born;\nBut now that fresh fair mirror, dim and old,\nShows me a bare-boned death by time out-worn:\nO, from thy cheeks my image thou hast torn,\nAnd shivered all the beauty of my glass,\nThat I no more can see what once I was!\n\n'O time, cease thou thy course and last no longer,\nIf they surcease to be that should survive.\nShall rotten death make conquest of the stronger\nAnd leave the faltering feeble souls alive?\nThe old bees die, the young possess their hive:\nThen live, sweet Lucrece, live again and see\nThy father die, and not thy father thee!\n\nBy this, starts Collatine as from a dream,\nAnd bids Lucretius give his sorrow place;\nAnd then in key-cold Lucrece' bleeding stream\nHe falls, and bathes the pale fear in his face,\nAnd counterfeits to die with her a space;\nTill manly shame bids him possess his breath\nAnd live to be revenged on her death.\n\nThe deep vexation of his inward soul\nHath served a dumb arrest upon his tongue;\nWho, mad that sorrow should his use control,\nOr keep him from heart-easing words so long,\nBegins to talk; but through his lips do throng\nWeak words, so thick come in his poor heart's aid,\nThat no man could distinguish what he said.\n\nYet sometime 'Tarquin' was pronounced plain,\nBut through his teeth, as if the name he tore.\nThis windy tempest, till it blow up rain,\nHeld back his sorrow's tide, to make it more;\nAt last it rains, and busy winds give o'er:\nThen son and father weep with equal strife\nWho should weep most, for daughter or for wife.\n\nThe one doth call her his, the other his,\nYet neither may possess the claim they lay.\nThe father says 'She's mine.' 'O, mine she is,'\nReplies her husband: 'do not take away\nMy sorrow's interest; let no mourner say\nHe weeps for her, for she was only mine,\nAnd only must be wail'd by Collatine.'\n\n'O,' quoth Lucretius,' I did give that life\nWhich she too early and too late hath spill'd.'\n'Woe, woe,' quoth Collatine, 'she was my wife,\nI owed her, and 'tis mine that she hath kill'd.'\n'My daughter' and 'my wife' with clamours fill'd\nThe dispersed air, who, holding Lucrece' life,\nAnswer'd their cries, 'my daughter' and 'my wife.'\n\nBrutus, who pluck'd the knife from Lucrece' side,\nSeeing such emulation in their woe,\nBegan to clothe his wit in state and pride,\nBurying in Lucrece' wound his folly's show.\nHe with the Romans was esteemed so\nAs silly-jeering idiots are with kings,\nFor sportive words and uttering foolish things:\n\nBut now he throws that shallow habit by,\nWherein deep policy did him disguise;\nAnd arm'd his long-hid wits advisedly,\nTo cheque the tears in Collatinus' eyes.\n'Thou wronged lord of Rome,' quoth be, 'arise:\nLet my unsounded self, supposed a fool,\nNow set thy long-experienced wit to school.\n\n'Why, Collatine, is woe the cure for woe?\nDo wounds help wounds, or grief help grievous deeds?\nIs it revenge to give thyself a blow\nFor his foul act by whom thy fair wife bleeds?\nSuch childish humour from weak minds proceeds:\nThy wretched wife mistook the matter so,\nTo slay herself, that should have slain her foe.\n\n'Courageous Roman, do not steep thy heart\nIn such relenting dew of lamentations;\nBut kneel with me and help to bear thy part,\nTo rouse our Roman gods with invocations,\nThat they will suffer these abominations,\nSince Rome herself in them doth stand disgraced,\nBy our strong arms from forth her fair streets chased.\n\n'Now, by the Capitol that we adore,\nAnd by this chaste blood so unjustly stain'd,\nBy heaven's fair sun that breeds the fat earth's\nstore,\nBy all our country rights in Rome maintain'd,\nAnd by chaste Lucrece' soul that late complain'd\nHer wrongs to us, and by this bloody knife,\nWe will revenge the death of this true wife.'\n\nThis said, he struck his hand upon his breast,\nAnd kiss'd the fatal knife, to end his vow;\nAnd to his protestation urged the rest,\nWho, wondering at him, did his words allow:\nThen jointly to the ground their knees they bow;\nAnd that deep vow, which Brutus made before,\nHe doth again repeat, and that they swore.\n\nWhen they had sworn to this advised doom,\nThey did conclude to bear dead Lucrece thence;\nTo show her bleeding body thorough Rome,\nAnd so to publish Tarquin's foul offence:\nWhich being done with speedy diligence,\nThe Romans plausibly did give consent\nTo Tarquin's everlasting banishment.\n\n"
  },
  {
    "path": "tests/server.rs",
    "content": "extern crate tiny_http;\nuse self::tiny_http::{Header, Request, Response, Server};\nuse std::fs::File;\nuse std::io::Error;\nuse std::sync::Arc;\nuse std::sync::Once;\nuse std::thread;\nuse std::time::Duration;\n\nstatic INIT: Once = Once::new();\n\npub fn setup() {\n    INIT.call_once(|| {\n        let server = Arc::new(Server::http(\"0.0.0.0:35550\").unwrap());\n        for _ in 0..4 {\n            let server = server.clone();\n\n            thread::spawn(move || loop {\n                let request = server.recv().unwrap();\n                handle_req(request).unwrap();\n            });\n        }\n    });\n}\n\nfn handle_req(req: Request) -> Result<(), Error> {\n    match req.url() {\n        \"/headers\" => respond_with_headers(req),\n        \"/timeout\" => respond_with_timeout(req),\n        \"/file\" => respond_with_file(req),\n        \"/content-disposition\" => respond_with_content_disposition(req),\n        _ => respond_with_headers(req),\n    }\n}\n\nfn respond_with_headers(req: Request) -> Result<(), Error> {\n    let res = Response::empty(200)\n        .with_header(Header::from_bytes(&b\"Content-Type\"[..], &b\"text/plain\"[..]).unwrap());\n\n    req.respond(res)\n}\n\nfn respond_with_timeout(req: Request) -> Result<(), Error> {\n    thread::sleep(Duration::from_secs(5));\n    let res = Response::empty(200);\n    req.respond(res)\n}\n\nfn respond_with_file(req: Request) -> Result<(), Error> {\n    let mut path = std::env::current_dir()?;\n    path.push(\"tests\");\n    path.push(\"foo.txt\");\n    let f = File::open(path)?;\n    let len = f.metadata()?.len();\n    let ctype = \"Content-Type: text/plain\".parse::<Header>().unwrap();\n    let clength = format!(\"Content-Length: {}\", len)\n        .parse::<Header>()\n        .unwrap();\n    req.respond(\n        Response::from_file(f)\n            .with_header(ctype)\n            .with_header(clength),\n    )\n}\n\nfn respond_with_content_disposition(req: Request) -> Result<(), Error> {\n    let mut path = std::env::current_dir()?;\n    path.push(\"tests\");\n    path.push(\"foo.txt\");\n    let f = File::open(path)?;\n    let len = f.metadata()?.len();\n    let ctype = \"Content-Type: text/plain\".parse::<Header>().unwrap();\n    let cdisp = \"Content-Disposition: attachment; filename=\\\"renamed.txt\\\"\"\n        .parse::<Header>()\n        .unwrap();\n    let clength = format!(\"Content-Length: {}\", len)\n        .parse::<Header>()\n        .unwrap();\n    req.respond(\n        Response::from_file(f)\n            .with_header(ctype)\n            .with_header(cdisp)\n            .with_header(clength),\n    )\n}\n"
  }
]