# Buggy code
def download_logic(slug_candidate=""):
    """
    Download the zip file.
    """
    # Deny new downloads if "Stop After First Download" is checked and there is
    # currently a download
    deny_download = not self.web.stay_open and self.download_in_progress
    if deny_download:
        r = make_response(render_template("denied.html"))
        return self.web.add_security_headers(r)

    # Each download has a unique id
    download_id = self.download_count
    self.download_count += 1

    # Prepare some variables to use inside generate() function below
    # which is outside of the request context
    shutdown_func = request.environ.get("werkzeug.server.shutdown")
    path = request.path

    # If this is a zipped file, then serve as-is. If it's not zipped, then,
    # if the http client supports gzip compression, gzip the file first
    # and serve that
    use_gzip = self.should_use_gzip()
    if use_gzip:
        file_to_download = self.gzip_filename
        self.filesize = self.gzip_filesize
    else:
        file_to_download = self.download_filename
        self.filesize = self.download_filesize

    # Tell GUI the download started
    self.web.add_request(
        self.web.REQUEST_STARTED, path, {"id": download_id, "use_gzip": use_gzip}
    )

    basename = os.path.basename(self.download_filename)

    def generate():
        # The user hasn't canceled the download
        self.client_cancel = False

        # Starting a new download
        if not self.web.stay_open:
            self.download_in_progress = True

        chunk_size = 102400  # 100kb

        fp = open(file_to_download, "rb")
        self.web.done = False
        canceled = False
        while not self.web.done:
            # The user has canceled the download, so stop serving the file
            if self.client_cancel:
                self.web.add_request(
                    self.web.REQUEST_CANCELED, path, {"id": download_id}
                )
                break

            chunk = fp.read(chunk_size)
            if chunk == b"":
                self.web.done = True
            else:
                try:
                    yield chunk

                    # tell GUI the progress
                    downloaded_bytes = fp.tell()
                    percent = (1.0 * downloaded_bytes / self.filesize) * 100

                    # only output to stdout if running onionshare in CLI mode, or if using Linux (#203, #304)
                    if (
                        not self.web.is_gui
                        or self.common.platform == "Linux"
                        or self.common.platform == "BSD"
                    ):
                        sys.stdout.write(
                            "\r{0:s}, {1:.2f}%          ".format(
                                self.common.human_readable_filesize(downloaded_bytes),
                                percent,
                            )
                        )
                        sys.stdout.flush()

                    self.web.add_request(
                        self.web.REQUEST_PROGRESS,
                        path,
                        {"id": download_id, "bytes": downloaded_bytes},
                    )
                    self.web.done = False
                except:
                    # looks like the download was canceled
                    self.web.done = True
                    canceled = True

                    # tell the GUI the download has canceled
                    self.web.add_request(
                        self.web.REQUEST_CANCELED, path, {"id": download_id}
                    )

        fp.close()

        if self.common.platform != "Darwin":
            sys.stdout.write("\n")

        # Download is finished
        if not self.web.stay_open:
            self.download_in_progress = False

        # Close the server, if necessary
        if not self.web.stay_open and not canceled:
            print(strings._("closing_automatically"))
            self.web.running = False
            try:
                if shutdown_func is None:
                    raise RuntimeError("Not running with the Werkzeug Server")
                shutdown_func()
            except:
                pass

    r = Response(generate())
    if use_gzip:
        r.headers.set("Content-Encoding", "gzip")
    r.headers.set("Content-Length", self.filesize)
    r.headers.set("Content-Disposition", "attachment", filename=basename)
    r = self.web.add_security_headers(r)
    # guess content type
    (content_type, _) = mimetypes.guess_type(basename, strict=False)
    if content_type is not None:
        r.headers.set("Content-Type", content_type)
    return r


# Traceback (KeyError)
[Jan 07 2019 20:58:37] Onion.cleanup: trying to remove onion 5yym6w3kg4tof56umfy6a632nvtoc5dkkpkhj4zd2slqzp5wuiwml7yd
=> 2.4 MiB         video 1.mov[Jan 07 2019 20:58:37] ReceiveMode.update_primary_action
Traceback (most recent call last):
File "onionshare_gui/onionshare_gui.py", line 382, in timer_callback
mode.handle_request_progress(event)
File "onionshare_gui/mode/receive_mode/__init__.py", line 159, in handle_request_progress
'progress': event["data"]["progress"]
File "onionshare_gui/mode/history.py", line 451, in update
self.item_list.update(id, data)
File "onionshare_gui/mode/history.py", line 347, in update
self.items[id].update(data)
KeyError: 0
=> 2.4 MiB         video 1.movAbort trap: 6

# Fixed code
def download_logic(slug_candidate=""):
    """
    Download the zip file.
    """
    # Deny new downloads if "Stop After First Download" is checked and there is
    # currently a download
    deny_download = not self.web.stay_open and self.download_in_progress
    if deny_download:
        r = make_response(render_template("denied.html"))
        return self.web.add_security_headers(r)

    # Each download has a unique id
    download_id = self.download_count
    self.download_count += 1

    # Prepare some variables to use inside generate() function below
    # which is outside of the request context
    shutdown_func = request.environ.get("werkzeug.server.shutdown")
    path = request.path

    # If this is a zipped file, then serve as-is. If it's not zipped, then,
    # if the http client supports gzip compression, gzip the file first
    # and serve that
    use_gzip = self.should_use_gzip()
    if use_gzip:
        file_to_download = self.gzip_filename
        self.filesize = self.gzip_filesize
    else:
        file_to_download = self.download_filename
        self.filesize = self.download_filesize

    # Tell GUI the download started
    self.web.add_request(
        self.web.REQUEST_STARTED, path, {"id": download_id, "use_gzip": use_gzip}
    )

    basename = os.path.basename(self.download_filename)

    def generate():
        # Starting a new download
        if not self.web.stay_open:
            self.download_in_progress = True

        chunk_size = 102400  # 100kb

        fp = open(file_to_download, "rb")
        self.web.done = False
        canceled = False
        while not self.web.done:
            # The user has canceled the download, so stop serving the file
            if not self.web.stop_q.empty():
                self.web.add_request(
                    self.web.REQUEST_CANCELED, path, {"id": download_id}
                )
                break

            chunk = fp.read(chunk_size)
            if chunk == b"":
                self.web.done = True
            else:
                try:
                    yield chunk

                    # tell GUI the progress
                    downloaded_bytes = fp.tell()
                    percent = (1.0 * downloaded_bytes / self.filesize) * 100

                    # only output to stdout if running onionshare in CLI mode, or if using Linux (#203, #304)
                    if (
                        not self.web.is_gui
                        or self.common.platform == "Linux"
                        or self.common.platform == "BSD"
                    ):
                        sys.stdout.write(
                            "\r{0:s}, {1:.2f}%          ".format(
                                self.common.human_readable_filesize(downloaded_bytes),
                                percent,
                            )
                        )
                        sys.stdout.flush()

                    self.web.add_request(
                        self.web.REQUEST_PROGRESS,
                        path,
                        {"id": download_id, "bytes": downloaded_bytes},
                    )
                    self.web.done = False
                except:
                    # looks like the download was canceled
                    self.web.done = True
                    canceled = True

                    # tell the GUI the download has canceled
                    self.web.add_request(
                        self.web.REQUEST_CANCELED, path, {"id": download_id}
                    )

        fp.close()

        if self.common.platform != "Darwin":
            sys.stdout.write("\n")

        # Download is finished
        if not self.web.stay_open:
            self.download_in_progress = False

        # Close the server, if necessary
        if not self.web.stay_open and not canceled:
            print(strings._("closing_automatically"))
            self.web.running = False
            try:
                if shutdown_func is None:
                    raise RuntimeError("Not running with the Werkzeug Server")
                shutdown_func()
            except:
                pass

    r = Response(generate())
    if use_gzip:
        r.headers.set("Content-Encoding", "gzip")
    r.headers.set("Content-Length", self.filesize)
    r.headers.set("Content-Disposition", "attachment", filename=basename)
    r = self.web.add_security_headers(r)
    # guess content type
    (content_type, _) = mimetypes.guess_type(basename, strict=False)
    if content_type is not None:
        r.headers.set("Content-Type", content_type)
    return r