diff --git a/.ameba.yml b/.ameba.yml new file mode 100644 index 0000000..1b6a522 --- /dev/null +++ b/.ameba.yml @@ -0,0 +1,7 @@ +Metrics/CyclomaticComplexity: + Description: Disallows methods with a cyclomatic complexity higher than `MaxComplexity` + MaxComplexity: 10 + Excluded: + - src/zipstream/http/server/handlers/static_file_handler.cr + Enabled: true + Severity: Convention diff --git a/README.md b/README.md index 9fe5bc1..7d534d5 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,8 @@ OPTIONS -f FORMAT, --format=FORMAT the format of output archive, zip, tar or tgz. Only for CLI mode. (default: `zip`) -o FILENAME, --output=FILENAME the output file name without extension. Only for CLI mode. (default: `download`) -e PATH, --endpoint=PATH the URL path to the resource. Only for CLI mode. (default: ``) + -j, --junk-parent stream the content of an archive without including the parent directory + -h, --hidden match hidden files and folders --user=user the username user for file retrieval --password=password the password password for file retrieval -V, --version print program version diff --git a/shard.lock b/shard.lock index 3c473f9..ae3e5cd 100644 --- a/shard.lock +++ b/shard.lock @@ -1,5 +1,9 @@ version: 2.0 shards: + cr_zip_tricks: + git: https://github.com/mamantoha/cr_zip_tricks.git + version: 0.2.0+git.commit.e524228904e94f144bc4b240d5e0e0b2502cdb2c + crystar: git: https://github.com/naqvis/crystar.git version: 0.1.8 diff --git a/shard.yml b/shard.yml index 7435488..d936dda 100644 --- a/shard.yml +++ b/shard.yml @@ -8,6 +8,9 @@ dependencies: crystar: github: naqvis/crystar version: ">= 0.1.8" + cr_zip_tricks: + github: mamantoha/cr_zip_tricks + branch: crystal/0.35.1 targets: zipstream: diff --git a/src/zipstream.cr b/src/zipstream.cr index 1be72fc..7be27fa 100644 --- a/src/zipstream.cr +++ b/src/zipstream.cr @@ -1,9 +1,9 @@ -require "compress/zip" require "compress/gzip" require "http/server" require "mime" require "option_parser" require "crystar" +require "cr_zip_tricks" require "./zipstream/**" diff --git a/src/zipstream/cli.cr b/src/zipstream/cli.cr index 2f88d5e..64afa3d 100644 --- a/src/zipstream/cli.cr +++ b/src/zipstream/cli.cr @@ -76,6 +76,10 @@ module Zipstream config.junk = true end + parser.on("-h", "--hidden", "match hidden files and folders") do + config.hidden = true + end + parser.on("--user=user", "the username user for file retrieval") do |name| config.user = name end diff --git a/src/zipstream/config.cr b/src/zipstream/config.cr index 35e6086..c9b5431 100644 --- a/src/zipstream/config.cr +++ b/src/zipstream/config.cr @@ -15,6 +15,7 @@ module Zipstream property password : String? = nil property prefix : String? = nil property junk : Bool = false + property hidden : Bool = false def initialize @host = "0.0.0.0" diff --git a/src/zipstream/http/server/handlers/tar_helper.cr b/src/zipstream/http/server/handlers/tar_helper.cr index d824b55..7036a98 100644 --- a/src/zipstream/http/server/handlers/tar_helper.cr +++ b/src/zipstream/http/server/handlers/tar_helper.cr @@ -2,7 +2,7 @@ module Zipstream module TarHelper def tar_directory!(path : String, io) Crystar::Writer.open(io) do |tar| - Dir[File.join(path, "**/*")].each do |entry| + Dir.glob(File.join(path, "**/*"), match_hidden: config.hidden).each do |entry| next unless File.readable?(entry) relative_path = [config.prefix, entry.sub(path, "").lstrip("/")].compact.join("/") diff --git a/src/zipstream/http/server/handlers/zip_handler.cr b/src/zipstream/http/server/handlers/zip_handler.cr index 23945b4..d8c39d8 100644 --- a/src/zipstream/http/server/handlers/zip_handler.cr +++ b/src/zipstream/http/server/handlers/zip_handler.cr @@ -35,24 +35,28 @@ module Zipstream end private def zip_directory!(path : String, io : IO) - Compress::Zip::Writer.open(io) do |zip| - Dir[File.join(path, "**/*")].each do |entry| + ZipTricks::Streamer.archive(io) do |zip| + Dir.glob(File.join(path, "**/*"), match_hidden: config.hidden).each do |entry| next unless File.readable?(entry) relative_path = [config.prefix, entry.sub(path, "").lstrip("/")].compact.join("/") if File.directory?(entry) - zip.add_dir(relative_path) + zip.add_stored("#{relative_path}/") { } else - zip.add(relative_path, File.open(entry)) + zip.add_deflated(relative_path) do |sink| + sink << File.read(entry) + end end end end end private def zip_file!(file : String, io : IO) - Compress::Zip::Writer.open(io) do |zip| - zip.add("/#{File.basename(file)}", File.read(file)) + ZipTricks::Streamer.archive(io) do |zip| + zip.add_deflated("/#{File.basename(file)}") do |sink| + sink << File.read(file) + end end end end