0

I am trying to serve static files (HTML + CSS) under Django. (Later on, I will password protect them). However, I am getting the wrong content-type. HTML files are downloaded, not displayed.

My webserver is Apache, and I'm running this under Webfaction. I'm looking at the site under Chromium 18.

I am trying both a naive FileWrapper (sending the file from Django) approach, where I use mimetype to determine the type, and x_modsendfile, where I let the webserver decide.

HTML files are downloaded, not displayed.

Here is what the content header should be, when I serve through my Apache webserver not Django:

HTTP/1.1 200 OK => 
Server => nginx
Date => Wed, 19 Sep 2012 21:51:35 GMT
Content-Type => text/html
Content-Length => 9362
Connection => close
Vary => Accept-Encoding
Last-Modified => Wed, 19 Sep 2012 05:53:00 GMT
ETag => "e3a0c43-2492-4ca079e8fea23"
Accept-Ranges => bytes

Observe that the server claims to be nginx. Webfaction says that for static services it sets up Apache, and indeed I have been configuring an Apache server for Django. But the response says Nginx (!)

Here is the response from the naive FileWrapper implementation, wherein I choose the Content-Type using mimetypes:

HTTP/1.1 200 OK => 
Server => nginx
Date => Wed, 19 Sep 2012 21:53:28 GMT
Content-Type => ('text/html', none)
Content-Length => 9362
Connection => close

The content-type is a TUPLE.

Here is the response from the mod_xsendfile implementation, wherein I don't choose the Content-Type:

HTTP/1.1 200 OK => 
Server => nginx
Date => Wed, 19 Sep 2012 21:52:40 GMT
Content-Type => text/plain
Content-Length => 9362
Connection => close
Vary => Accept-Encoding
Last-Modified => Wed, 19 Sep 2012 05:53:00 GMT
ETag => "e3a0c43-2492-4ca079e8fea23"

Here is my code:

def _serve_file_xsendfile(abs_filename):
    response = django.http.HttpResponse() # 200 OK
    del response['content-type'] # We'll let the web server guess this.
    response['X-Sendfile'] = abs_filename
    return response

def _serve_file_filewrapper(abs_filename):
    p_filename = abs_filename
    if not os.path.exists(p_filename):
        raise Exception('File %s does not exist!')

    try:
        _content_type = mimetypes.guess_type(p_filename)
    except:
        _content_type = 'application/octet-stream'

    print p_filename, _content_type

    wrapper = FileWrapper(file(p_filename))
    response = HttpResponse(wrapper, content_type=_content_type)
    response['Content-Length'] = os.path.getsize(p_filename)
    response['Content-Type'] = _content_type
    return response

def _serve_file(filename):
    abs_filename = _get_absolute_filename(filename)
    return _serve_file_filewrapper(abs_filename)

def public_files(request, filename):
    return _serve_file(filename)

How do I get the correct Content-Type to be served, either for the FileWrapper or mod_xsendfile approach?

Joseph Turian
  • 15,430
  • 14
  • 47
  • 62

1 Answers1

0

_content_type = mimetypes.guess_type(p_filename)

should be

_content_type, encoding = mimetypes.guess_type(p_filename)

Joseph Turian
  • 15,430
  • 14
  • 47
  • 62