Tupi: A simple web server

Tupi’s main purpose is to provide an easy way to upload and download files. It supports basic http auth for file uploads.

Install

Tupi is written in go, so you need a go compiler installed. Then, clone the code:

$ git clone https://github.com/jucacrispim/tupi

And install the program with:

$ cd tupi
$ make install

Note

For all make targets use make help

Usage

Serving files

Now you can use the tupi command to start the server. By default it serves the current working dir. It can be changed using the param -root:

$ tupi -root /some/dir

By default tupi listens in the port 8080. You can change using the param -port:

$ tupi -port 8000

Now you can download files

$ curl http://localhost:8080/some-file.txt

You can also list the contents of a directory:

$ curl http://localhost:8080/

One can instead of listing the contents of a directory, return the index.html file in it. To do so use the option default-to-index.

$ tupi -default-to-index

To authenticate downloads, use the options -auth-methods POST,GET and htpasswd.

$ tupi -auth-methods POST,GET -htpasswd /some/htpasswd/file.

Note

Tupi also supports other authentication methods via plugins. Check Writing plugins.

Uploading files

To upload files a htpasswd file must be created first for authenticated access:

$ htpasswd -c -B /some/htpasswd/file some-user

And start the server using the htpasswd param:

$ tupi -htpasswd -htpasswd /some/htpasswd/file

Danger

Your htpasswd MUST NOT be whithin the directory being served by tupi

To upload a file send a POST request to the “/u/” path in the server. The request must have the multipart/form-data Content-Type header and the file must be in a input named file.

Note

The upload path can be changed by a config param.

$ curl --user test:123 -F 'file=@/home/juca/powerreplica.jpg' http://localhost:8080/u/

A prefix can be passed in the request so the file will be saved inside the prefix directory

$ curl --user test:123 -F 'file=@/home/juca/powerreplica.jpg' http://localhost:8080/u/ -F 'prefix=something'

Upload and extract

Tupi can extract the contets of uploaded tar.gz files. The contents will be extracted in the root directory being served and the directory structure in the tar file will be preserved.

To upload and extract the contents o a file send a POST request to the “/e/” path in the server. The request must also have the multipart/form-data Content-Type header and the file must be in a input named file.

Note

The extract path can be changed by a config param.

$ curl --user test:123 -F 'file=@/home/juca/package.tar.gz' http://localhost:8080/e/

HTTPS connections

To use an HTTPS connection, one must use the -certfile and -keyfile params:

$ tupi -certfile /some/cert.pem -keyfile /some/file.key

For all options available for tupi use the command tupi -h

$ tupi -h
Usage of tupi:
  -auth-downloads
         Autenticate downloads
  -certfile string
        Path for the tls certificate file
  -conf string
        Path for the configuration file
  -default-to-index
        Returns the index.html instead of listing a directory
  -epath string
        Path to extract files (default "/e/")
  -host string
        host to listen. (default "0.0.0.0")
  -htpasswd string
        Full path for a htpasswd file used for authentication
  -keyfile string
        Path for the tls key file
  -loglevel string
     Log level (default "info")
  -maxupload int
        Max size for uploaded files (default 10485760)
  -port int
        port to listen. (default 8080)
  -prevent-overwrite
     Prevents over writing existent files
  -root string
        The directory to serve files from (default ".")
  -timeout int
        Timeout in seconds for read/write (default 240)
  -upath string
        Path to upload files (default "/u/")

Config file

Instead of command line options one can also use a toml configuration file by using the -conf command line option or by setting the TUPI_CONFIG_FILE environment variable.

Note

Command line arguments have precedence over values from a config file. The -conf argument has precedence over the TUPI_CONFIG_FILE environment variable.

Here is an example of a config file:

# all parameters here are optional
host = "0.0.0.0"
port = 1234
rootDir = "/some/dir"
# timeout in seconds
timeout = 500
htpasswdFile = "/some/htpasswd"
uploadPath = "/u/"
extractPath = "/e/"
# defaults to 10 MB
maxUploadSize = 10485760
certFilePath = "/some/cert.pem"
keyFilePath = "/some/file.key"
defaultToIndex = true
logLevel = "debug"
preventOverwrite = true
# methods that need authentication
authMethods = ["POST"]

Listening on multiple ports

In order to listen on multiple ports you need to use the ports param in the config file.

...
ports = [
    {"port" = 1234, "usessl" = true},
    {"port" = 2234, "usessl" = false}
]
...

Note

If usessl is true, the params keyFilePath an certFilePath must be set.

To use virutal domains one need to configure the domains in the config file. Each different section of the config file corresponds to a virtual domain handled by tupi.

[default]
ports = [
    {"port" = 443, "usessl" = true},
    {"port" = 80, "usessl" = false}
]

[adomain.net]
# Here a request to adomain.net will only be handled by the
# adomain.net configs if it is in the port 443. Requests to
# the port 80 will be handled by the default confs.
ports = [
    {"port" = 443, "usessl" = true},
]
rootDir "/some/dir"
# timeout in seconds
timeout = 500
htpasswdFile = "/some/htpasswd"
uploadPath = "/u/"
extractPath = "/e/"
# defaults to 10 MB
maxUploadSize = 10485760
certFilePath = "/some/cert.pem"
keyFilePath = "/some/file.key"
defaultToIndex = true
logLevel = "debug"


[otherdomain.net]
rootDir "/other/dir"
# timeout in seconds
timeout = 500
htpasswdFile = "/other/htpasswd"
uploadPath = "/u/"
extractPath = "/e/"
# defaults to 10 MB
maxUploadSize = 10485760
certFilePath = "/other/cert.pem"
keyFilePath = "/other/file.key"
defaultToIndex = false

All options available ara supported by the virtual domains, except loglevel that is only available for the default server.

Plugins

Tupi can be extended by plugins. Check the docs on how to write your own plugins