Repository: getnikola/nikola

Issue:
`nikola auto` serves CSS with wrong MIME type on livereload
I'm using Nikola to develop a static site, and the live-reload functionality of `nikola auto` is not working for CSS. When I save my SASS file, it successfully builds a new CSS file and sends it to the browser, but it sends it with the MIME type "application/octet-stream" instead of "text/css", which makes the page lose *all* styling. The only way to get styling back is to refresh the page manually. I've tested this in both Chrome and Firefox, both on Debian Stretch.


Discussion:
The code used to choose the mime type is this:

```
mimetype = 'text/html' if uri.endswith('/') else mimetypes.guess_type(uri)[0] or 'application/octet-stream'
```

Manual checking says this should give text/css:

```
>>> mimetypes.guess_type('http://foo.com/bar.css')
('text/css', None)
```

So, I don't really know why this fails for you, yet. Can you check with your browser's development tools what request is being made and what headers it contains?
The url is http://localhost:8000/assets/css/styles.css?livereload=1485291602299

Could it be due to the query parameter at the end? I checked in the python REPL and got the following:

    >>> import mimetypes
    >>> mimetypes.guess_type("http://localhost:8000/assets/css/styles.css?livereload=1485291602299")
    (None, None)
    >>> mimetypes.guess_type("http://localhost:8000/assets/css/styles.css")
    ('text/css', None)
    
That seems like the cause to me, but there might be a reason I'm missing to guess based on the full URI. It seems like the following would work:

```python
uri = wsgiref.util.request_uri(environ)
p_uri = urlparse(uri)
f_path = os.path.join(self.site.config['OUTPUT_FOLDER'], *[unquote(x) for x in p_uri.path.split('/')])

# mimetypes.guess_type can't handle query strings, so we need
# to strip the URI to only the path for mimetype guessing
stripped_uri = urlparse.urljoin(url, p_uri.path)

# ‘Pretty’ URIs and root are assumed to be HTML
mimetype = 'text/html' if uri.endswith('/') else mimetypes.guess_type(stripped_uri)[0] or 'application/octet-stream'
```

I've attached the rest of the HTTP info below, in case that helps:

    Request URL     http://localhost:8000/assets/css/styles.css?livereload=1485291602299
    Request Method  GET
    Status Code     00 OK
    Remote Address  127.0.0.1:8000


    # Response Headers

    Content-Length  6181
    Content-type    application/octet-stream
    Date            Tue, 24 Jan 2017 21:00:02 GMT


    # Request Headers

    Accept          text/css,*/*;q=0.1
    Accept-Encoding gzip, deflate, sdch, br
    Accept-Language en-US,en;q=0.8
    Cache-Control   no-cache
    Connection      keep-alive
    DNT             1
    Host            localhost:8000
    Pragma          no-cache
    Referer         http://localhost:8000/categories/
Ok, yes, the query parameter could break it.
I'll try to do a fix today.

Resolving patch:
diff --git a/nikola/plugins/command/auto/__init__.py b/nikola/plugins/command/auto/__init__.py
--- a/nikola/plugins/command/auto/__init__.py
+++ b/nikola/plugins/command/auto/__init__.py
@@ -299,7 +299,7 @@ def serve_static(self, environ, start_response):
         f_path = os.path.join(self.site.config['OUTPUT_FOLDER'], *[unquote(x) for x in p_uri.path.split('/')])
 
         # ‘Pretty’ URIs and root are assumed to be HTML
-        mimetype = 'text/html' if uri.endswith('/') else mimetypes.guess_type(uri)[0] or 'application/octet-stream'
+        mimetype = 'text/html' if uri.endswith('/') else mimetypes.guess_type(p_uri.path)[0] or 'application/octet-stream'
 
         if os.path.isdir(f_path):
             if not p_uri.path.endswith('/'):  # Redirect to avoid breakage


Test patch: