Setting Content-Type with MIME type and encoding

This commit is contained in:
Darren Burns
2024-08-12 13:23:35 +01:00
parent 2c7ee2abfc
commit c9d22fdb73
8 changed files with 31 additions and 267 deletions

View File

@@ -15,7 +15,6 @@ class ScreenshotApp(App[None]):
self.action_deliver_screenshot()
def action_deliver_screenshot(self) -> None:
print("Delivering screenshot action!")
filename = self.save_screenshot("screenshot.svg")
self.deliver_text(filename)

View File

@@ -1,213 +0,0 @@
<svg class="rich-terminal" viewBox="0 0 1653 1001.5999999999999" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.terminal-1887221314-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.terminal-1887221314-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.terminal-1887221314-r1 { fill: #05080f }
.terminal-1887221314-r2 { fill: #e1e1e1 }
.terminal-1887221314-r3 { fill: #c5c8c6 }
.terminal-1887221314-r4 { fill: #1e2226;font-weight: bold }
.terminal-1887221314-r5 { fill: #35393d }
</style>
<defs>
<clipPath id="terminal-1887221314-clip-terminal">
<rect x="0" y="0" width="1633.8" height="950.5999999999999" />
</clipPath>
<clipPath id="terminal-1887221314-line-0">
<rect x="0" y="1.5" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-1">
<rect x="0" y="25.9" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-2">
<rect x="0" y="50.3" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-3">
<rect x="0" y="74.7" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-4">
<rect x="0" y="99.1" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-5">
<rect x="0" y="123.5" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-6">
<rect x="0" y="147.9" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-7">
<rect x="0" y="172.3" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-8">
<rect x="0" y="196.7" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-9">
<rect x="0" y="221.1" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-10">
<rect x="0" y="245.5" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-11">
<rect x="0" y="269.9" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-12">
<rect x="0" y="294.3" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-13">
<rect x="0" y="318.7" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-14">
<rect x="0" y="343.1" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-15">
<rect x="0" y="367.5" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-16">
<rect x="0" y="391.9" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-17">
<rect x="0" y="416.3" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-18">
<rect x="0" y="440.7" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-19">
<rect x="0" y="465.1" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-20">
<rect x="0" y="489.5" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-21">
<rect x="0" y="513.9" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-22">
<rect x="0" y="538.3" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-23">
<rect x="0" y="562.7" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-24">
<rect x="0" y="587.1" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-25">
<rect x="0" y="611.5" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-26">
<rect x="0" y="635.9" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-27">
<rect x="0" y="660.3" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-28">
<rect x="0" y="684.7" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-29">
<rect x="0" y="709.1" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-30">
<rect x="0" y="733.5" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-31">
<rect x="0" y="757.9" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-32">
<rect x="0" y="782.3" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-33">
<rect x="0" y="806.7" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-34">
<rect x="0" y="831.1" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-35">
<rect x="0" y="855.5" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-36">
<rect x="0" y="879.9" width="1634.8" height="24.65"/>
</clipPath>
<clipPath id="terminal-1887221314-line-37">
<rect x="0" y="904.3" width="1634.8" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1651" height="999.6" rx="8"/><text class="terminal-1887221314-title" fill="#c5c8c6" text-anchor="middle" x="825" y="27">ScreenshotApp</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-1887221314-clip-terminal)">
<rect fill="#1e2226" x="0" y="1.5" width="195.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="195.2" y="1.5" width="1439.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#a3a4a4" x="0" y="25.9" width="183" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e2226" x="183" y="25.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="195.2" y="25.9" width="1439.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e2226" x="0" y="50.3" width="195.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="195.2" y="50.3" width="1439.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="74.7" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="99.1" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="123.5" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="147.9" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="172.3" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="196.7" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="221.1" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="245.5" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="269.9" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="294.3" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="318.7" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="343.1" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="367.5" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="391.9" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="416.3" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="440.7" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="465.1" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="489.5" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="513.9" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="538.3" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="562.7" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="587.1" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="611.5" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="635.9" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="660.3" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="684.7" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="709.1" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="733.5" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="757.9" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="782.3" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="806.7" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="831.1" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="855.5" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="879.9" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="904.3" width="1634.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="928.7" width="1634.8" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-1887221314-matrix">
<text class="terminal-1887221314-r1" x="0" y="20" textLength="195.2" clip-path="url(#terminal-1887221314-line-0)">▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔</text><text class="terminal-1887221314-r3" x="1634.8" y="20" textLength="12.2" clip-path="url(#terminal-1887221314-line-0)">
</text><text class="terminal-1887221314-r4" x="0" y="44.4" textLength="183" clip-path="url(#terminal-1887221314-line-1)">&#160;Hello,&#160;World!&#160;</text><text class="terminal-1887221314-r3" x="1634.8" y="44.4" textLength="12.2" clip-path="url(#terminal-1887221314-line-1)">
</text><text class="terminal-1887221314-r5" x="0" y="68.8" textLength="195.2" clip-path="url(#terminal-1887221314-line-2)">▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁</text><text class="terminal-1887221314-r3" x="1634.8" y="68.8" textLength="12.2" clip-path="url(#terminal-1887221314-line-2)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="93.2" textLength="12.2" clip-path="url(#terminal-1887221314-line-3)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="117.6" textLength="12.2" clip-path="url(#terminal-1887221314-line-4)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="142" textLength="12.2" clip-path="url(#terminal-1887221314-line-5)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="166.4" textLength="12.2" clip-path="url(#terminal-1887221314-line-6)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="190.8" textLength="12.2" clip-path="url(#terminal-1887221314-line-7)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="215.2" textLength="12.2" clip-path="url(#terminal-1887221314-line-8)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="239.6" textLength="12.2" clip-path="url(#terminal-1887221314-line-9)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="264" textLength="12.2" clip-path="url(#terminal-1887221314-line-10)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="288.4" textLength="12.2" clip-path="url(#terminal-1887221314-line-11)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="312.8" textLength="12.2" clip-path="url(#terminal-1887221314-line-12)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="337.2" textLength="12.2" clip-path="url(#terminal-1887221314-line-13)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="361.6" textLength="12.2" clip-path="url(#terminal-1887221314-line-14)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="386" textLength="12.2" clip-path="url(#terminal-1887221314-line-15)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="410.4" textLength="12.2" clip-path="url(#terminal-1887221314-line-16)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="434.8" textLength="12.2" clip-path="url(#terminal-1887221314-line-17)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="459.2" textLength="12.2" clip-path="url(#terminal-1887221314-line-18)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="483.6" textLength="12.2" clip-path="url(#terminal-1887221314-line-19)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="508" textLength="12.2" clip-path="url(#terminal-1887221314-line-20)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="532.4" textLength="12.2" clip-path="url(#terminal-1887221314-line-21)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="556.8" textLength="12.2" clip-path="url(#terminal-1887221314-line-22)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="581.2" textLength="12.2" clip-path="url(#terminal-1887221314-line-23)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="605.6" textLength="12.2" clip-path="url(#terminal-1887221314-line-24)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="630" textLength="12.2" clip-path="url(#terminal-1887221314-line-25)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="654.4" textLength="12.2" clip-path="url(#terminal-1887221314-line-26)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="678.8" textLength="12.2" clip-path="url(#terminal-1887221314-line-27)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="703.2" textLength="12.2" clip-path="url(#terminal-1887221314-line-28)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="727.6" textLength="12.2" clip-path="url(#terminal-1887221314-line-29)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="752" textLength="12.2" clip-path="url(#terminal-1887221314-line-30)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="776.4" textLength="12.2" clip-path="url(#terminal-1887221314-line-31)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="800.8" textLength="12.2" clip-path="url(#terminal-1887221314-line-32)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="825.2" textLength="12.2" clip-path="url(#terminal-1887221314-line-33)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="849.6" textLength="12.2" clip-path="url(#terminal-1887221314-line-34)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="874" textLength="12.2" clip-path="url(#terminal-1887221314-line-35)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="898.4" textLength="12.2" clip-path="url(#terminal-1887221314-line-36)">
</text><text class="terminal-1887221314-r3" x="1634.8" y="922.8" textLength="12.2" clip-path="url(#terminal-1887221314-line-37)">
</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -9,7 +9,7 @@ dependencies = [
"aiohttp>=3.9.5",
"aiohttp-jinja2>=1.6",
"jinja2>=3.1.4",
"textual[syntax] @ file:///Users/darrenburns/Code/textual-serve/../textual",
"textual[syntax] @ file:///Users/darrenburns/code/textual-serve/../textual",
"msgpack>=1.0.8",
"rich",
"msgpack-types>=0.3.0",

View File

@@ -77,7 +77,7 @@ rich==13.7.1
sniffio==1.3.1
# via anyio
# via httpx
textual @ file:///Users/darrenburns/Code/textual-serve/../textual
textual @ file:///Users/darrenburns/code/textual-serve/../textual
# via textual-dev
# via textual-serve
textual-dev==1.5.1

View File

@@ -56,7 +56,7 @@ pygments==2.18.0
rich==13.7.1
# via textual
# via textual-serve
textual @ file:///Users/darrenburns/Code/textual-serve/../textual
textual @ file:///Users/darrenburns/code/textual-serve/../textual
# via textual-serve
tree-sitter==0.20.4
# via textual

View File

@@ -313,8 +313,9 @@ class AppService:
await self._download_manager.create_download(
app_service=self,
delivery_key=delivery_key,
file_name=Path(str(meta_data["path"])).name,
open_method=str(meta_data["open_method"]),
file_name=Path(meta_data["path"]).name,
open_method=meta_data["open_method"],
mime_type=meta_data["mime_type"],
)
except KeyError:
log.error("Missing key in `deliver_file_start` meta packet")
@@ -325,15 +326,6 @@ class AppService:
# to start the download.
json_string = json.dumps(["deliver_file_start", delivery_key])
await self.remote_write_str(json_string)
elif meta_type == "deliver_file_end":
try:
delivery_key = str(meta_data["key"])
await self._download_manager.finish_download(delivery_key)
except KeyError:
log.error("Missing key in `deliver_file_end` meta packet")
return
else:
await self._download_manager.finish_download(delivery_key)
else:
log.warning(
f"Unknown meta type: {meta_type!r}. You may need to update `textual-serve`."
@@ -350,5 +342,4 @@ class AppService:
# If we receive a chunk, hand it to the download manager to
# handle distribution to the browser.
_, delivery_key, chunk_bytes = unpacked
print("unpacked chunk:" + str(unpacked))
await self._download_manager.chunk_received(delivery_key, chunk_bytes)

View File

@@ -12,6 +12,7 @@ if TYPE_CHECKING:
log = logging.getLogger("textual-serve")
DOWNLOAD_TIMEOUT = 4
DOWNLOAD_CHUNK_SIZE = 1024 * 64 # 64 KB
@dataclass
@@ -20,6 +21,8 @@ class Download:
delivery_key: str
file_name: str
open_method: str
mime_type: str
encoding: str | None = None
incoming_chunks: asyncio.Queue[bytes | None] = field(default_factory=asyncio.Queue)
@@ -52,6 +55,8 @@ class DownloadManager:
delivery_key: str,
file_name: str,
open_method: str,
mime_type: str,
encoding: str | None = None,
) -> None:
"""Prepare for a new download.
@@ -67,31 +72,10 @@ class DownloadManager:
delivery_key,
file_name,
open_method,
mime_type,
encoding,
)
async def finish_download(self, delivery_key: str) -> None:
"""Finish a download for the given delivery key.
Args:
delivery_key: The delivery key to finish the download for.
"""
try:
download = self._active_downloads[delivery_key]
except KeyError:
log.error(f"Download {delivery_key!r} not found")
return
# Shut down the download queue. Attempt graceful shutdown, but
# timeout after DOWNLOAD_TIMEOUT seconds if the queue doesn't clear.
await download.incoming_chunks.put(None)
with suppress(asyncio.TimeoutError):
await asyncio.wait_for(
download.incoming_chunks.join(), timeout=DOWNLOAD_TIMEOUT
)
async with self._active_downloads_lock:
del self._active_downloads[delivery_key]
async def download(self, delivery_key: str) -> AsyncGenerator[bytes, None]:
"""Download a file from the given app service.
@@ -110,21 +94,25 @@ class DownloadManager:
{
"type": "deliver_chunk_request",
"key": delivery_key,
"size": 1024 * 64,
"size": DOWNLOAD_CHUNK_SIZE,
}
)
chunk = await incoming_chunks.get()
if not chunk:
# The app process has finished sending the file.
# Empty chunk - the app process has finished sending the file.
incoming_chunks.task_done()
with suppress(asyncio.TimeoutError):
await asyncio.wait_for(
download.incoming_chunks.join(), timeout=DOWNLOAD_TIMEOUT
)
async with self._active_downloads_lock:
del self._active_downloads[delivery_key]
break
else:
incoming_chunks.task_done()
yield chunk
await asyncio.sleep(0.01)
async def chunk_received(self, delivery_key: str, chunk: bytes) -> None:
"""Handle a chunk received from the app service for a download.

View File

@@ -3,6 +3,7 @@ from __future__ import annotations
import asyncio
import logging
import mimetypes
import os
from pathlib import Path
import signal
@@ -154,7 +155,6 @@ class Server:
async def handle_download(self, request: web.Request) -> web.StreamResponse:
"""Handle a download request."""
print("in download handler")
key = request.match_info["key"]
try:
@@ -162,26 +162,25 @@ class Server:
except KeyError:
raise web.HTTPNotFound(text=f"Download with key {key!r} not found")
print("download_meta:", download_meta)
response = web.StreamResponse()
response.headers["Content-Type"] = "application/octet-stream"
disposition = (
"attachment" if download_meta.open_method == "download" else "inline"
)
mime_type = download_meta.mime_type
content_type = mime_type
if download_meta.encoding:
content_type += f"; charset={download_meta.encoding}"
response.headers["Content-Type"] = content_type
disposition = "inline" if download_meta.open_method == "download" else "inline"
response.headers["Content-Disposition"] = (
f"inline; filename={download_meta.file_name}"
f"{disposition}; filename={download_meta.file_name}"
)
await response.prepare(request)
async for chunk in self.download_manager.download(key):
print("writing chunk to response stream")
await response.write(chunk)
await response.drain()
await asyncio.sleep(0.01)
print("=== writing eof")
await response.write_eof()
return response