aboutsummaryrefslogtreecommitdiff

FileHTTPServer

Characteristics

  • Access files in your computer around your home (or worldwide)
  • Remote file manager
  • Download files from your computer
  • Upload files to your computer

Support

  • Web-Interface (any browser)
  • Script-Interface (Python required)
  • Tested Python: 2.7.11, 3.2.5
  • Tested O.S: Windows 10, OS X El Capitan
  • Tested Browser: Chrome, Safari, Opera, Firefox

Image

Notes

History

The project started with the need for access to other projects remotely, for example to continue editing a program in my laptop that was started in my desktop. The obvious answer was Dropbox; easy to use, nice interface and 2GB free. This was a great solution for the first year at least, then problems started to come up. Again, no problem, why not use Google Drive. The exact same deal, nice interface and this time 15GB free. Including that I already had a Google account and I could test that handy feature of Gmail for sending big files.

After a project with a FTP server, as a website updater for a friend. As he was good making them with his programs but he didn’t keep it up-to-date, as it was tedious and even hard to keep track of all the modified or created files. I created for him program to update the website quickly with a single click (now updated every time, even for simple font or line edits).

I realised that maybe I could pull something up for a similar functionality as Dropbox or Google Drive, as it was just another server. Similar to some multiplayer game I made, but with some aspects of HTML as the FTP project. Counting the files and some simple coding to display them. I quickly realised that if I that work, I could literally have a private unlimited mass storage online. No limit at 2GB or 15GB neither MEGA’s 50GB free, literally unlimited (well 2TB, my hard drive size).

Looked up some library already build in Python for at least the HTML server, and perfect SimpleHTMLServer (Python 3.X) was there. Even it had a file listing method incase you didn’t provide a ‘index.html’ for the server. That seemed perfect, just improvements to the Web-Interface and add an uploading functionality, that’s it. And with some Google searching someone already created a version of the HTML server with uploaded functionality. There was no indication to how to actually use it, and there was no option for upload on the Web-Interface, so it seemed as it could deal with uploads but you had to modify the HTML yourself.

That was added with more findings on how HTML worked, as at the time I just know some basic HTML formatting and really basic JavaScript. Then was time for some formating and making the interface nicer, finally something I knew how to do without shearing every 5 minutes. I added some simple things that I saw in file sharing websites, like some file size calculations and icons for files. That was pretty much it. Some JavaScript for the ‘Back’ and ‘Go’ buttons and code compatibility edits, a project in less than a week.

Then a month later I rewrote most of the code for improvements purposes; the listing of a directory, authentication and verification, HTML style and some internal functionality. I added an extra layout of the page for the liking of less tech-savvy people, with a single cookie to memorize the prefered layout of the user. Now at the start of the connection a HTML and JavaScript code is sent that enables the web page to not update as a whole. Therefore the server after only need to send a small lists with the file names, and not send a dynamically build page. This leaves the client to build it and reduces stress in the server side. Also the icons and images are now included in the HTML code as Base64, so it reduces number of request for files and the images are no longer need at the server folder.

Utilization

Server Setup

  1. Download the FileHTTPServer code file, and ensure you have an install of Python.
  2. Create a Python file for your custom server, using the end code provided in the downloaded file (keep this file in the same directory as the FileHTTPServer one).
#Modules
import FileHTTPServer
 
#Variables
OPTIONS = {                  #(Optional) Customization options for server
    "ip": "",                #> Bind to a specific ip, example "192.168.1.130" ("" for automatic)
    "port": 0,               #> Bind to a specific port, example 8888 (0 for automatic)
    "path": ".",             #> Path to add at the start of requested route (. = Current Folder, "" = Full Navigation)
    "home": "",              #> If access the server without any path given redirect to this location (If not set, path attribute. If not valid, first non-empty allow. If allow = "", master folder if valid)
    "allow": [""],           #> Paths to allow online access (assume that the Path attribute will be added to the start, "" = Full Access)
    "block": [],             #> Paths to blocks online access (assume that the Path attribute will be added to the start, "" = Full Block)
    "log_info": True,        #> Shows information about the server and its actions
    "cli_info": False,       #> Shows both the ip and port of the clients in the log info
    "hide_err": True,        #> Hides files or folder when they are impossible to handle (name with characters out of encoding range)
    "dir_read": True,        #> Hides directories if the server can not read them
    "dir_write": True,       #> Disable upload option if server can not write to the directory
    "dir_size": False,       #> Calculate and show directory size (could slow down request handling if directories are too large)
    "dir_down": True,        #> Allow downloads of whole directories
    "dir_sub": True,         #> When working with directories if a sub-directory is block check for lower down files or folders that are allow to include them
    "buffer": 16*1024,       #> Read and write rate data to the web connection
    "upload": True,          #> Disable upload option generaly
    "userpass": [],          #> Username's and Password's needed to enter web access ("username:password" = Syntax, if empty no authorization required)
    "name": "My Server",     #> Name to show in the online explorer title
    "msg_err": "Error",      #> Message to show on error in the web access
    "ban_tries": 3,          #> Number of request on authentication until user block
    "ban_time": 30*60,       #> Seconds to block user if number of request on authentication is surpassed
    "secure": {              #> Enables HTTPS functionality
        "level": None,       #-> Method of security (select desired PROTOCOL from the SSL module or None for disabled)
        "key": "file.key",   #-> Path to key file (. = Current Folder)
        "cert": "file.cert", #-> Path to certificate file (. = Current Folder)
        "redirect": False},  #-> Redirect HTTP requests to HTTPS (False = Not Respond HTTP, Port number for HTTP = Redirect HTTP to HTTPS - example 8888 or 0 for automatic)
    "hide_data": [           #> Excludes files and folders, usually to hide some system files (this are still accessible)
        "desktop.ini",
        "Thumbs.db",
        "~*",
        ".*",
        "$*",
        ],
    }
 
#Main
FileHTTPServer.run(OPTIONS)
  1. Edit the options you desire accordingly with the help of the descriptions beside them (recommended to select a port so each time you start the server it has the same address). If the default options are fine or you prefer a smaller code, you could do something like this:
#Default
from FileHTTPServer import run;run()
 
#With some options
from FileHTTPServer import run;run({"port":8000})

Web-Interface (Access)

  1. Look at your server console and find the IP and the port it says it is using when you start it.
  2. On your preferred web browser type in the address bar the IP followed by ‘:’ and the port (example: ‘192.168.1.131:52316’).
  3. Now you should have access the Web-Interface. If you added a user with password a dialog box should pop-up to ask for the credentials.

Note: For worldwide access to the server port forwarding / opening have to be done, this is different across different internet routers / modems. Normally this is done by accessing your router / modem by conecteing to it and going to ‘192.168.1.1’ (or similar) in a browser. Login in with some kind of username and password (‘admin’, ‘123’, ‘1234’, ‘12345’, ‘0000’ are often used for both) and going to a tab called ‘Port forwarding’ (‘…Routing’, ‘…Mapping’, ‘NAT’ or different). Then opening or making accessible the port you selected for your server (normally 4-5 digit ones). Finally in the server’s computer access a web page to get your global IP (example: WhatIsMyIp). Use that followed again by the port, only if you’re not connected to the same network as the server, else still use the same IP as before.

Web-Interface (Navigation)

Location Bar: The box on top of the web acces shows your location in the server’s computer hard drive or selected path. Go: If you know the paths on the server computer you can type them in the ‘Location Bar’ and click ‘Go’ to enter a particular folder quickly (the address bar in the browser can function equally but with the IP and port at the start). Back: Automatically brings you up a folder, showing you where the folder you were looking was located in the tree directory. Display: Changes the layout of the page between a list with the sizes of the file and one with large and simple icons. Upload: Uploads a file to the folder you’re currently looking. Select the file with the option to the left of the button (it can vary between browsers). Down Arrow: Downloads the file or folder you are hovering above. You can provide direct download to files or directories by following this scheme ‘IP:PORT/PATH_TO_OBJECTIVE?download’ (file example: ‘192.168.1.131:52316/C:/Users/MAProgram/Documents/File.doc?download’, folder example: ‘192.168.1.131:52316/C:/Users/MAProgram/Documents?download’ or ‘192.168.1.131:52316/C:/Users/MAProgram/Documents/?download’).

Documentation

Name

FileHTTPServer.py

Language

Python: 2.X - 3.X

Information

class FileHTTPServer.Server(options=Server.base_options, handler=RequestHandler)

  • Both arguments are optional, the first being the customization options and the second the request handler that the server should use (this is available for custom request handlers that adds extra functionality).

  • There is a an example of the options argument in the documentation of the server class.

  • An example of the option argument is included in the source code of the module, this shows the default arguments if not set, followed by an explanation of it. {'secure': {'redirect': False, 'cert': 'file.cert', 'key': 'file.key', 'level': None}, 'ip': '', 'dir_size': False, 'ban_time': 1800, 'home': '', 'port': 0, 'msg_err': 'Error', 'dir_down': True, 'hide_data': ['desktop.ini', 'Thumbs.db', '~*', '.*', '$*'], 'cli_info': False, 'buffer': 16384, 'dir_write': True, 'log_info': True, 'ban_tries': 3, 'path': '.', 'userpass': [], 'dir_read': True, 'dir_sub': True, 'name': 'My Server', 'upload': True, 'allow': [''], 'hide_err': True, 'block': []}

    • ip: Bind server to a specific ip.
      • Example: 192.168.1.130.
      • Use '' or empty for automatic selection of a IP.
    • port: Bind server to a specific port.
      • Example: 8000.
      • Use 0 for automatic selection of a port.
    • allow: Paths to allow online access.
      • Example: ['C:/User/MAProgram/Projects','D:/report.txt','./Server Images'].
      • If path is empty the first non-empty path will be used as home path.
      • When declared a path all subdirectories and files in that path are accessible.
      • Use / as path separators in the routes instead of \.
      • This path is relative to the path attribute.
        • Example: path value C:\Server, therefore Images is at C:\Server\Images.
      • Use '' or empty to allow full access to the computer. Via the Web-Interface you will be able to access any file inside the main path.
    • block: Blocks sub-paths allowed from before.
      • Example if allow is ['C:'], block ['C:/Private'] will allow access to everything in the C: drive except the folder Private.
      • Use / as path separators in the routes instead of \.
      • This path is relative to the ‘path’ attribute.
        • Example: path value C:\Server, therefore Images is at C:\Server\Images.
      • Use '' or empty to block full access to the computer.
    • log_info: Shows information about the server and its actions.
      • Example: True.
      • You can set it to False to not receive any out by the server if it is annoying.
    • dir_read: Hides directories if the server can not read them.
      • Example: True.
      • It can be changed to False to show all directories present, even it will fail once you try to enter that specific directories.
    • dir_write: Disable upload option if server can not write to the directory.
      • Example: True.
      • It can be changed to False to show the upload option even if the server thinks he can’t write to the specific directory, for an attempt purpose. If the upload fails or succeed will be notified in the Web-Interface.
    • dir_size: Calculates and show the size of a directory in the Web-Interface.
      • Example: False.
      • By default this option is off because of performance reasons but it can be changed to True. This is because the server will try to calculate the full size of the directory, going into all files and subdirectories in it for a slow but accurate result. If the directories allowed are small this option is nice to have on.
      • This option will make the server calculate the size of directories and display them in the Web-Interface. This will be shown exactly how the files sizes are shown.
    • dir_down: Enables downloads of whole directories.
      • Example: True.
      • If False the web access would not display the option to download the requested directory, and any link to a directory with the ?download parameter will be denied.
    • dir_sub: Includes directories if paths bellow are allowed.
      • Example: True.
      • When working with directories if a sub-directory is block and this is set to True, the server will check for lower down files or folders that are allow to include them. For example, activated if C:/ and C:/Users/MAProgram is allow but C:/Users is blocked, when accessing C:/ the C:/Users will be visible. When entered the C:/Users folder will be shown empty as it is blocked but with the folder of C:/Users/MAProgram accessible. All data of the C:/Users folder is still maintain private but access to C:/Users/MAProgram is granted.
      • If set to False if a directory is block it will not be shown even if lower down there is file or folder that is allowed, to access them you would need a direct URL to that folder or file that is allowed.
      • This options affects the directory size calculation and also the download of directories.
    • upload: Controls if uploads are allowed.
      • Example: True.
      • If True the server will act normally, obeying the dir_write if selected.
      • If False the server will deny any uploads to it and hide the option, even if it is able to satisfy them.
    • userpass: Usernames and Passwords needed to enter Web-Interface.
      • Example: ['maprogram-code:secretpassword','friendname:hispassword'].
      • If the list is empty no authentication is required.
      • The syntax of the strings for userpass codes are the desired username followed by : finished by its password.
      • This is just a simple security measure but this not ensures complete protection against unintended access.
    • name: Name to show in the browser’s title page.
      • Example: My Server.
      • If not declare it will default to FileHTTPServer Web.
    • hide_data: Excludes files or folders, usually to hide some system files.
      • Example: ['desktop.ini', 'Thumbs.db', '~*', '.*', '$*'].
      • The server will hide from the Web-Interface files or folders, but if requested the full path to it the file will be served, it is only not shown. For blocking use the option block.
      • Append a name to hide a file or folder exactly named like that. Add a * at the start to symbolize anything that ends with the followed string, or at the end to symbolize anything that starts with that string. If you want to hide files or folders that contain a string add an * at the start and end of it. Any * in the middle of a name will be treated as the normal * character.
    • buffer: Read and write rate from memory to web connection.
      • Example: 16*1024 (16Kb per read).
      • The server will use this value to read that amount of bytes and write them to the web connection. This process will be repeated several times until the current file or data in memory is finished.
      • This value can be increased if Python’s interpreter is slowing the maximum connection speed, but the larger the value the greater the memory usage will be.
    • hide_err: Hides a file if it can’t be process correctly.
      • Example: True.
      • Normally if files or folders have names with unicode characters Python will have troubles reading information about them. If True they will simply not be display, when False it will display a error file to simply inform there is a file but I can not be access.
    • home: Home path, redirects if the requested URL is empty.
      • Example: ''.
      • If you access the server without asking for any path in particular, you can set this attribute so it redirect clients to a certain path. For example if you give full access you might want this to equal your documents folder, then you can access all the files but when entered you go to your folder.
      • This path is relative to the path attribute.
        • Example: path value C:\Server, therefore Images is at C:\Server\Images.
      • If leave this empty the server will try to find a relevant and allowed path to welcome the user. This automated find will only fail if for example you give full access but block the drive in which the server is located, this is caused as it can not get the parent directory of a drive to see other plausible routes (as it starts in its location to have a path going up).
    • path: Path to add at the start of requested route.
      • Example: ..
      • Home path serves as a the main folder you give access via the be service, no access will be granted above. This path will be appended to all request. For example the url 192.168.1.130:8000/Folder with path of C:/Users/ will return the request to C:/Users/Folder.
      • If this option is empty the first non-empty path in allow will be used instead. If allow is empty it will default to . (the servers directory).
      • Use / as path separators in the routes instead of \.
      • Use . at the start of a path to represent the server’s current folder.
        • Example: Server script C:\Server\Script.py, therefore ./Images is at C:\Server\Images.
      • Use '' or empty to allow full access to the computer. Via the Web-Interface you will be able to access any file inside any drive.
    • cli_info: Shows extra information about the user requesting a page.
      • Example: False.
      • If the user is not logged in False will show the user’s IP, with True will also show the PORT. If logged in with authentication False will display the Username in use, with True it will also display the IP and PORT of the user.
    • msg_err: Title of the message to display in the error web pages.
      • Example: Error responding request.
      • Errors may vary between authentication, read error, blocked user.
    • ban_tries: Number of request on authentication until user block.
      • Example: 3.
      • If userpass empty this options has no effect.
      • If 0 is used no block will be applied and unlimited tries will be permitted.
    • ban_time: Seconds to block user if ban_tries is surpassed.
      • Example: 1800.
      • If userpass empty this options has no effect.
      • If ban_tries is set to 0 this option has no effect.
      • This timer will be reset if the if requests continues while the block is present to the user.
    • secure: Contains information about HTTPS functionality.
      • level: Decides which encryption method to use.
        • Example: None.
        • If set to None the HTTPS functionality will be disabled.
        • This value should be set by choosing the correct protocol to use from the SSL module (Python 3.X), the variables that start with PROTOCOL_… represent all the posible options. This represent a number based on the release date of each one, normally as the number increase the security also does.
      • key: Path to the Private Key file of the server.
        • Example: file.key.
        • Use / as path separators in the routes instead of \.
        • Use . at the start of a path to represent the server’s current folder.
          • Example: Server script C:\Server\Script.py, therefore ./Images is at C:\Server\Images.
      • cert: Path to the Certificate file of the server.
        • Example: file.cert.
        • Use / as path separators in the routes instead of \.
        • Use . at the start of a path to represent the server’s current folder.
        • Example: Server script C:\Server\Script.py, therefore ./Images is at C:\Server\Images.
      • redirect: Enabled redirects from HTTP to HTTPS.
        • Example: False.
        • If set to False the server will not respond to any requests via HTTP.
        • This should be set to the port number of the normal HTTP requests, so the clients get redirected by the server, switch to the correct protocol and to the main port.
        • This is normally set to 80 and the main port to 443, with this configuration (if the rest is correctly set) once type only the IP of the server (without even specifying the PORT) it will switch. but is not needed to be set like that.
  • The handler option serves for users want to add extra functionality with a custom request handler, but it is advised that any functionality it includes it is replace by an equivalent one before adding new ones.

    • The handler contains a large amount of functions, which if you need an explanation there is one just after the declaration of each in the source code.
  • function start(lock=True)

    • The call of this function in the server instance will start it running, the function will not end until the server stops. This is what the function run in the module will call just after creating the server.
    • If the optional argument lock is set to True, this function will not return until the server has been closed. This can be performed by calling the method end() in a separate thread or by a keyboard interrupt (Ctrl + C or Cmd + C). If the argument is set to False, the function will start the server in another thread and return immediately, you can stop the server by calling the end() method or killing the process in which is running.
    • This function is provided for users that want to get data from the server before it starts handling requests.
      • Remember that the server has already bind to an IP and PORT.
      • This will be exactly the same if you had accessed the Server class on the module without creating one. The only change is that the options variable has been created with your settings, and if some had been left blank, been pre-filled with the defaults.
        • For totally intact options access Server.base_options.
      • To retrieve information from the server practically identically to what it would look like running, call the internal method setup() and then retrieve the options variable from the server, before starting it.
  • function end()

    • The call of this function will stop the server but if the server is started in locked mode you will have to call this function from another thread.
  • function FileHTTPServer.run(options=Server.base_options, handler=RequestHandler)

    • When called it will create a server instance and start it, it will not continue until the server is closed or ended.
    • This function is the equivalent to creating the server and call start just after.