pshs — the awesome file sharing tool

For a long time I lacked a proper tool to quickly share a few files for a short time. The tools I was able to find either required some setup, installing client counterparts or sending my files to a third-party host. So I felt the need to write something new.

The HTTP protocol seemed an obvious choice. Relatively simple, efficient, with some client software installed almost everywhere. So I took HTTP::Server::Simple (I think) and wrote the first version of publish.pl script. I added a few features to that script but it never felt good enough…

So back in 2011 I decided to reboot the project. This time I decided to use C and libevent, and that’s how pshs came into being. With some development occuring in the last three years, lately I started adding new features aiming to turn it into something really awesome.

So what pshs is? It’s a simple, zero-configuration command-line HTTP server to share files. You pass a list of files and it lets you share them.


Screenshot of pshs

But what really makes pshs special are the features:

  1. it shares only the files specified on the command-line — no need for extra configuration, moving files to separate directories etc. It simply returns 404 for any path not specified on the command-line, whether it exists or not.
  2. Full, working Range support. You can resume interrupted downloads and seek freely. Confirmed that playing a movie remotely works just fine.
  3. Unless told otherwise, it chooses a random port to use. You don’t have to decide on one, you have use pshs alongside regular HTTP servers and other services, and you can freely run multiple instances of pshs if you need to. TODO: perform port search until free port is found on the interface having external IP.
  4. Netlink and UPnP support provide the best means to obtain the external IP. If you have one on local interface, pshs will find and print it. If you don’t, it will try to enable port forwarding using UPnP and obtain the external IP from a UPnP-compliant router.
  5. QRCode printing (idea copied from systemd). Want to text a link to your files? Just scan the code!
  6. MIME-type guessing. Well, it’s not that special but makes sure your images show up as imagines in a web browser rather than opaque files that can only be saved.
  7. Zero-configuration SSL/TLS support — the keys and a self-signed certificate with correct public IP are generated at startup. While this is far from perfect (think of all the browsers complaining about self-signed certificates), it at least gives you the possibility of using encryption. It also prints the certificate fingerprint if you’d like to verify the authenticity.

I have also a few nice ideas in TODO, yet unsure which of them will be actually implemented:

  1. HTTP digest authentication support — in case you wanted some real security on the files you share.
  2. Download progress reporting — to let you know if and for how long do you need to keep the server up. Sadly, this does not look easy given the current libevent design.
  3. ncurses UI — to provide visual means for progress reporting :). Additional possibilities include keeping server URL on screen, a status line, and possibly scrolling logs.
  4. GTK+ UI with a tray icon and notification daemon support — to provide better desktop integration for sharing files from your favorite file manager.
  5. Recursive directory sharing — currently you have to list all files explicitly. This may include better directory indexes since currently pshs creates only one index of all files.

Which of those features would you find useful? What other features you’d like to see in pshs?

23 thoughts on “pshs — the awesome file sharing tool”

  1. thanks for this nice tool.

    it would be nice to have another parameter to pass a different IP for the “Server reachable at” output so that pshs can be used on machines that are reachable via port forward only.

  2. Wow, this is really cool and so easy to use. I think this would perfect for the chrome cast-like device I am building on a raspberry pi with Gentoo! Thank you for your work on this project. I would find the GTK UI and recursive directory sharing particularly useful.

  3. Excellent tool, thanks. Response to your proposed enhancements below.

    > HTTP digest authentication support
    Meh.

    > Download progress reporting
    YES PLEASE!

    > ncurses UI
    Meh.

    > GTK+ UI with a tray icon and notification daemon support — to provide better desktop integration for sharing files from your favorite file manager.
    Meh.

    > Recursive directory sharing
    Absolutely yes yes yes!

      1. There’s actually a nice way to do it in the terminal.

        [192.95.5.69:39760] /fix-kdbd.sh [******* 50%]
        [1.2.3.4:18181] /blablah.jpg [*********** 70%]
        [1.2.3.4:21211] /schmaschm.txt [** 10%]

        By keeping track of how many log lines you’ve outputted, you can ANSI up that many lines and draw over them. No ncurses needed. Let me know if you need help with this – I can make a little PoC for you to integrate.

        1. I know I can do that. Plus disable echo to avoid user messing up the output ;). However, I don’t see how much different that would be from just letting ncurses handle the escape sequence semi-portably. Though I’m myself a bit unconvinced by the idea that ncurses would likely want to clear the screen :).

  4. What if you already have an apache running, and/or turn off your main pc?
    I find magnet links the better solution anyway. They just need a form of authentication/authorization. Automatic archive passwords would be simple enough.

    1. pshs is intended to be fast, zero-configuration file sharing tool that you run for a few minutes when you need to move file from one location to another, or wait till someone else gets it. It’s no replacement for long-term file hosting solutions.

  5. But only crazy people with a hack-wish have UPNP activated!
    The Fritz!Box, probably Germany’s most popular router (and for a reason) deliberately doesn’t have UPNP activated.
    I mean, what are we? Wintards?

    1. Don’t be offensive to others, not to mention it’s completely off-topic. Next thing I know, I am a wintard because the servers I use often have public IP…

  6. That encryption is exactly equal to zero encryption. MITM-galore!
    No matter if self-signed or ranom-untrustworthy-person-I-have-never-met-signed (aka CA) by the way.

    GPG would have made more sense. (If secrecy was important, that added difficulty would have been acceptable. If.)

    1. That’s why you get certificate fingerprint. You can compare it, if you are paranoid. GPG would defeat the goal of quick & portable file sharing with systems that don’t have any specific configuration.

  7. Hm, I’m using for it scp + nginx. It’s requires a little more configuring, but, IMHO, much more easy in support :).

    1. Yeah, I see we have similar ideas. I completely forgot that I wanted to add the upload form feature :). However, pshs has one big advantage: it doesn’t use go but plain C :). Well, maybe C++ soon to avoid reinventing some things.

  8. I kinda hoped it’d work behind NAT as well (that is, even with uPNP-router behind NAT). Well, that is a pity :)

  9. Thanks for the tool and that detailed announcement!

    Maybe good idea is options for forking to background and for terminate when download complete. Second option can be specified with count of full downloads before server terminates (and 1 as default, I guess).

    > HTTP digest authentication support
    And include user:password pair in URL, that would be convenient in use.

  10. Oh, neat!

    A feature-request, if I may: a way to limit the upload rate would be great, so I don’t have to worry about my upstream getting all clogged up.

  11. good afternoon how to figure that out while build pshs?:

    In file included from /var/tmp/portage/www-servers/pshs-0.2.4/work/pshs-0.2.4/src/rtnl.c:16:0:
    /usr/include/libnetlink.h:12:27: fatal error: linux/netconf.h: No such file or directory
    #include
    ^
    compilation terminated.

Comments are closed.