Updating the Readme and License files.
This commit is contained in:
parent
8a3dc6995c
commit
2c516fec96
|
|
@ -0,0 +1,18 @@
|
||||||
|
Copyright (c) 2026 Elf M. Sternberg
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
# tower-http-servezip
|
||||||
|
|
||||||
|
ServeZip is a [Rust](https://rust-lang.org/)
|
||||||
|
[Tower](https://github.com/tower-rs/tower) leaf service that serves files from a
|
||||||
|
given Zip file. The Zip file can either be specified by a Pathbuf or a `static
|
||||||
|
&[u8]`; the latter is intended to allow you to embed your Zip file directly into
|
||||||
|
the binary, creating a complete standalone solution for a deployable web
|
||||||
|
service. You just need to supply the logic.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The `demo` folder contains a somewhat complete implementation, including a demo
|
||||||
|
zip file. **TODO** Full indexing is not currently implemented. The demo can be started via:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
cargo run -p demo -- --zip demo/assets/demo.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
Valid targets are: `http://localhost:8001/index.html`, `hello.txt`, and
|
||||||
|
`docs/just-a-file.txt`. These demonstrate the basics of mime-types,
|
||||||
|
content-length, and file lookup. Any other file should return a simple 404.
|
||||||
|
|
||||||
|
## Internals
|
||||||
|
|
||||||
|
Interally, this is a mess. It was a project-based learning exercise, and like so
|
||||||
|
much of my career now I'm not sure I could reimplement it without the book open
|
||||||
|
and the lots of example code.
|
||||||
|
|
||||||
|
I'm mostly unhappy with the fact that I have to make a copy of whatever stream
|
||||||
|
I'm sending out over the wire, rather than pulling it sequentially from the Zip
|
||||||
|
file while it's decompressing. This is mostly intended to supply a PWA and its
|
||||||
|
back-end logic in a single package; it shouldn't be doing work that often, but
|
||||||
|
it still annoys me that I have to do it more than once while (briefly) wasting
|
||||||
|
memory. I wish I understond Rust well enough to say "Either let me keep wasting
|
||||||
|
the memory and keep the performance, or let me take the performance hit without
|
||||||
|
wasting the memory."
|
||||||
|
|
||||||
|
But I'm not that good at Rust quite yet.
|
||||||
|
|
||||||
|
## Lessons learned
|
||||||
|
|
||||||
|
There's a lot going on here, and I'm still not entirely thrilled with how it
|
||||||
|
went down. I *am* proud of figuring out how to use the NewType pattern to create
|
||||||
|
an implementation of ServeZip that works with `Arc[u8]`, which is the data type
|
||||||
|
I pass around containing the compresed data. Reading
|
||||||
|
[ServeDir's](https://github.com/tower-rs/tower-http/tree/main/tower-http/src/services/fs/serve_dir)
|
||||||
|
source code opened my eyes to a lot of the little bits, like separating the
|
||||||
|
Config, the Builder, the Service; I have some old habits about keeping
|
||||||
|
everything really close at hand, but Rust makes the implentation so smooth and
|
||||||
|
efficient that I'm really starting to appreciate how it works.
|
||||||
|
|
||||||
|
This implementation just unpacks the Zip file *every time*. I was hoping for
|
||||||
|
something smarter, maybe a way to just keep separate ZipCursors alive and
|
||||||
|
re-usable, but for now this will have to do. It's not bad, it just feels like
|
||||||
|
there's a lot of Rust to learn before it's much more idiomatic.
|
||||||
|
|
||||||
|
Huge shoutout to @bearcave [[Bearcove](https://github.com/bearcove)]] for the
|
||||||
|
sans-io implementation of Zip in Rust. I learned a lot about sans-io in the
|
||||||
|
process, even if I didn't end up using much of it this time.
|
||||||
|
|
||||||
|
## Todo
|
||||||
|
|
||||||
|
- Implement full indexing
|
||||||
|
- Implement ServeDir's use of http::body, instead of axum
|
||||||
|
- Read ServeDir much more closely in order to understand what it's doing
|
||||||
|
internally; all the security and safety issues, plus performance
|
||||||
|
- Reduce the amount of copying. Oy, the copying
|
||||||
|
- Put an upper limit on Zip size, configurable from the command line
|
||||||
|
- Provide a `build.rs` file in the demo to show how `include_bytes!` works
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Tower-http-servezip is Copyright [Elf M. Sternberg](https://elfsternberg.com)
|
||||||
|
(c) 2026, and licensed under the original [MIT License](./LICENSE.md). A copy of
|
||||||
|
the license file is included in the root folder.
|
||||||
|
|
||||||
|
## An all-human effort.
|
||||||
|
|
||||||
|
Every last line of this code I typed myself. No AI-provided code included. I
|
||||||
|
wouldn't have learned anything otherwise. Just sayin'.
|
||||||
Loading…
Reference in New Issue