10

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.

7
  • What kind of file is it? PDF, image, MS Office, ...? Commented Jun 2, 2016 at 7:20
  • .sh .config etc extensions but the content inside is ascii. I am able to see .txt files although but i want to see other files as well Commented Jun 2, 2016 at 7:22
  • 1
    Check two things: 1) Can your browser display these files inline? 2) What is the Content-Type header of the HTTP response? Commented Jun 2, 2016 at 7:27
  • For .sh file , Content-type: application/x-sh Commented Jun 2, 2016 at 7:30
  • What OS are you running this server on? Commented Jun 2, 2016 at 7:31

2 Answers 2

8

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)
Sign up to request clarification or add additional context in comments.

2 Comments

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.
Couldn't view mhtml files after changing it to its content type multipart/related .
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.

3 Comments

Content-type: application/x-sh is returned in my case
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.
yes i found this file and corresponding entry is application/x-sh sh for me. thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.