Rob--W / open-in-browser

A browser extension that offers the ability to open files directly in the browser instead of downloading them.
Other
88 stars 16 forks source link

Default download dialog is visible in some cases #28

Closed Lekensteyn closed 6 years ago

Lekensteyn commented 6 years ago

In some occassions, I have noticed that the open-in-browser download dialog window is being opened (but not rendered) and then quickly closed and replaced by the default dialog. So far I have only observed it with two HTTPS sites, any attempt to reproduce it locally with plain HTTP does not have any effect. It is also not 100% reproducible, there are rare cases where the download dialog is shown (maybe a race condition based on network quality?)

One failing example that I have been reproducing with is the "Download PDF Format" on the https://oyster.tfl.gov.uk/oyster/journeyHistory.do.

In a failing case, the onErrorOccured callback is invoked with NS_ERROR_NET_ON_RECEIVING_FROM. In Wireshark, I can observe that the server sends a TCP FIN/ACK right after sending the data and receiving an ACK from the client. The client then sends a close_notify TLS alert and also closes the connection.

Due to triggering this abortionObserver signal, the ModalDialog is immediately closed.

Lekensteyn commented 6 years ago

Reproducer:

openssl req -newkey rsa:2048 -x509 -nodes -keyout server.pem -new -out server.pem -subj /CN=localhost
python repro.py

Visit https://localhost:4433/, accept the certificate. The faulty behavior will become visible.

repro.py:

from socketserver import TCPServer, BaseRequestHandler
import ssl
import time

#body = open('foo.pdf', 'rb').read()
body = b'x' * 13230
head = b'''HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="foo.pdf"
Content-Length: %d
Connection: close

''' % len(body)

PORT = 4433
class Handler(BaseRequestHandler):
    def setup(self):
        self.raw_sock = self.request
        self.request = ssl.wrap_socket(self.request, certfile='server.pem',
                server_side=True)

    def handle(self):
        sock = self.request
        sock.recv()
        response = head.replace(b'\n', b'\r\n') + body
        size = 1024
        while response:
            chunk, response = response[:size], response[size:]
            self.request.write(chunk)
            time.sleep(.01)

    def finish(self):
        self.raw_sock.close()

with TCPServer(("", PORT), Handler) as svr:
    svr.serve_forever()
Rob--W commented 6 years ago

Can't reproduce in a fresh profile on Firefox 57, Firefox Nightly (59.0a1).

Did you install any other add-ons or software that may interfere with the request handing of Firefox?

Lekensteyn commented 6 years ago

nope, it was a clean profile. reproduced with the version from AMO and also the one from #27.

Maybe try to keep dev tools open on the network tab?

Rob--W commented 6 years ago

Opening the devtools is necessary to reproduce the bug.

I reported this bug as https://bugzilla.mozilla.org/show_bug.cgi?id=1420917