2011-04-29

By Xyne

quickserve

Meta

AUR:32312
Arch Forum Thread:85751
Binary Package:xyne-any/quickserve-2011.04.17.1-1-any.pkg.tar.xz
PKGBUILD:pkgbuilds/quickserve
Repos:[xyne-any]
Source Package:quickserve-2011.04.17.1.tar.gz
Taurball:quickserve.tar.gz
Version:2011.04.17.1

About

Quickserve is a very simple HTTP server written in Python that is intended for quickly sharing files on an ad-hoc basis. Aside from opening a port in your firewall if you have one, quickserve requires no set-up and should work with no hassle.

Quickserve can serve single files or entire directories by simply passing it paths on the command line. It can also accept a list of files to share with the "--filelist" option. It is even possible to enable uploads using the "--upload" option, which accepts a directory path as its argument.

Features

  • Simple (simple to use, simple to understand the code)
  • Support for file and filter lists
  • Upload support
  • HTTP Digest Authentication
  • HTTPS with client certificates for secure connections
  • Pure Python... no compilation necessary

Example

Your friend has just stopped by for a few minutes to grab a file from you (/home/foo/bar). He's using Windows and you don't have time to fiddle around with Samba shares or netcat or whatever. You just want to let him connect to your computer and grab "bar". All you need to do is run the following command:

quickserve /home/foo/bar

This will start up a server on all interfaces listening on port 8080. If you have a firewall you will have to open port 8080 in this case but that's it. Now your friend can open his web browser (or use "wget" or something similar) and navigate to your IP address on the lan. For example, if your internal IP is 192.168.0.1, then the address would be "http://192.168.0.1:8080/". This page will show a link to "bar" that can then be downloaded. Of course he could have just nativated to "http://192.168.0.1:8080/bar" to begin with, but if you share multiple files then the default page will list them all and you can use tools such as aria2c to grab everything at once.

See "quickserve -h" for options and usage.

Screenshots

quickserve screenshot quickserve screenshot

Certificate Generation

See the python-xynehttpserver page for references and commands to generate certificates for HTTPS connections.

Quickbrowse

After noticing that I would often open a browser just to tranfer a file, I added support for the query option "text=plain". When passed, quickserve will return plaintext pages that are much easier for human readers. These should also be tractable for scripts, even if the usual HTML is strict XHTML.

To return plaintext pages, include "text=plain" in the URI's query, e.g.

http://localhost:8080/?plain=text

For quick browsing with curl, use

curl -G -d text=plain http://localhost:/8080/

The use of the -G and -d options keep the query off of the end of the URI so it's easier to navigate. This could be useful as an alias, e.g.

alias quickbrowse="curl -G -d text=plain"

Usage: quickbrowse <URI>

Example output:

$ quickbrowse http://localhost:8080/sandbox/
2010-09-22 18:14:37              /sandbox/uploaded/
2010-09-22 16:00:59   11.00   B  /sandbox/bar.txt
2010-09-22 16:01:05   11.00   B  /sandbox/foo.txt
2010-09-22 16:31:05  301.00   B  /sandbox/quickupload

Quickupload

Here's a simple script that uses curl to upload files to quickserve from the command line:

#!/bin/bash
set -e

# help message function
function display_help()
{
  cat <<HELP
usage: $0 [CURL OPTIONS] <URI> [FILES]

  The order of the arguments is not important. The arguments are simply filtered
  and passed to curl, wrapping detected files so that curl can upload them.

  See "curl --help" for information about curl options.
HELP
  exit
}

if [ -z "$1" ]; then
  display_help
fi


# argument filter
args=()
_i=1
for arg in "$@"; do
  case "$arg" in
    -h)
      display_help
    ;;
    --help)
      display_help
    ;;
  esac

  if [ -e "$arg" ]; then
    args[${#args[*]}]="-F"
    args[${#args[*]}]="file_$_i=@$arg"
    _i=$(($_i + 1))
  else
    args[${#args[*]}]="$arg"
  fi
done


# curl binary
curl_bin="$(which curl)"
if [ -z "$curl_bin" ]; then
  echo "error: curl not found"
  exit 1
fi

# run the command
"$curl_bin" "${args[@]}"

Usage: quickupload <URI> [FILES]

Firefox Bug

When requesting a URL on localhost, Firefox sometimes truncates the path. This means that if you try to navigate to "http://localhost:8080/foo", Firefox might only request "/" instead of "/foo". This bug (feature?) appears to be a consequence of an attempt to prevent malicious requests for local files but I really do not understand it or how it works and have given up trying to discover the underlying logic. It seems that sometimes you can bypass it by using a path with a final "/" in it, e.g. "http://localhost:8080/info/" instead of "http://localhost:8080/info", or by placing files in a directory instead of in the root path, but sometimes even that doesn't work.

This only affects Firefox and only applies to localhost. You can bypass it by using "127.0.0.1", by accessing quickserve through a different interface via Firefox (e.g. 192.168.x.x) or by using a different web browser or tool. If you feel inclined to file a bug on Mozilla's site or if you understand the underlying logic and want to explain it to me, please do.

Changelog

2010.10.02

  • added support for requiring client certificates

2010.09.28

  • added regex filtering options (see "--help" and "--filterhelp")

2010.09.18

  • added "text=plain" query to enable plaintext file listings (see above)

2010.09.18

2010.07.14

  • added threading support to handle multiple connection simultaneously
  • fixed "Content-Range" bug
  • added support for HEAD requests
  • re-organized HTML generation
    • cleaner code
    • W3C XHTML Validation
    • W3C CSS Validation
  • re-organized startup and info page output
  • added icon
  • fixed MIMEtype detection bug
  • added "Content-Encoding" header