9

I am creating a python httpserver for a folder on remote machine using command :

python -m SimpleHTTPServer 9999

But I am unable to view a file in the browser using this. As soon as click on the link the file gets downloaded. Is there a way to create a server so that i can view the files in my browser only.

Nishant Lakhara
  • 2,295
  • 4
  • 23
  • 46

2 Answers2

7

To make the browser open files inline instead of downloading them, you have to serve the files with the appropriate http Content headers.

What makes the content load inline in the browser tab, instead of as a download, is the header Content-Disposition: inline.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

To add these headers, you you can subclass the default SimpleHTTPRequestHandler with a custom one.

This is how it can be done using python 3. You have to modify the imports and maybe some other parts if you have to use python 2.

Put it in a executable script file which you can call myserver.py and run it like so: ./myserver.py 9999

#!/usr/bin/env python3

from http.server import SimpleHTTPRequestHandler, test
import argparse


class InlineHandler(SimpleHTTPRequestHandler):

    def end_headers(self):
        mimetype = self.guess_type(self.path)
        is_file = not self.path.endswith('/')
        # This part adds extra headers for some file types.
        if is_file and mimetype in ['text/plain', 'application/octet-stream']:
            self.send_header('Content-Type', 'text/plain')
            self.send_header('Content-Disposition', 'inline')
        super().end_headers()

# The following is based on the standard library implementation 
# https://github.com/python/cpython/blob/3.6/Lib/http/server.py#L1195
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--bind', '-b', default='', metavar='ADDRESS',
                        help='Specify alternate bind address '
                             '[default: all interfaces]')
    parser.add_argument('port', action='store',
                        default=8000, type=int,
                        nargs='?',
                        help='Specify alternate port [default: 8000]')
    args = parser.parse_args()
    test(InlineHandler, port=args.port, bind=args.bind)
Håken Lid
  • 22,318
  • 9
  • 52
  • 67
  • 1
    I was having trouble serving html content without .htm/.html extension using python3's http.server. Using method above I replaced `self.send_header('Content-Type', 'text/plain')` with `self.send_header('Content-Type', 'text/html')` and now it works. Really useful snippet. –  Dec 26 '17 at 08:28
  • Couldn't view mhtml files after changing it to its content type `multipart/related` . – Tinkaal Gogoi Aug 23 '18 at 10:36
0

Serving files like foo.sh should work fine using the SimpleHTTPServer. Using curl as the client, I get a HTTP response like this:

$ curl -v http://localhost:9999/so.sh
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9999 (#0)
> GET /so.sh HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:9999
> Accept: */*
> 
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: SimpleHTTP/0.6 Python/2.7.6
< Date: Thu, 02 Jun 2016 07:28:57 GMT
< Content-type: text/x-sh
< Content-Length: 11
< Last-Modified: Thu, 02 Jun 2016 07:27:41 GMT
< 
echo "foo"
* Closing connection 0

You see the header line

Content-type: text/x-sh

which is correct for the file foo.sh. The mapping from the file extensions sh to text/x-sh happens in /etc/mime.types on GNU/Linux systems. My browser

Chromium 50.0.2661.102

is able to display the file inline.

Summary: As long as you serve known files and your browser can display them inline, everything should work.

  • Content-type: application/x-sh is returned in my case – Nishant Lakhara Jun 02 '16 at 07:35
  • 1
    This probably depends on the configuration of your OS. Does your OS have a file `/etc/mime.types`? On my Ubuntu this includes a mapping from `sh` to `text/x-sh`. Python probaly reads this configuration to set the `Content-Type` header. –  Jun 02 '16 at 07:42
  • yes i found this file and corresponding entry is application/x-sh sh for me. thanks – Nishant Lakhara Jun 02 '16 at 09:03