Skip to content

Commit

Permalink
fix: put/post oom
Browse files Browse the repository at this point in the history
  • Loading branch information
Dwynr committed Sep 4, 2024
1 parent 9091e18 commit 6ffce22
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 27 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@filen/webdav",
"version": "0.2.38",
"version": "0.2.39",
"description": "Filen WebDAV",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
26 changes: 24 additions & 2 deletions src/handlers/put.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { v4 as uuidv4 } from "uuid"
import mimeTypes from "mime-types"
import { removeLastSlash } from "../utils"
import Responses from "../responses"
import { PassThrough } from "stream"

/**
* Put
Expand Down Expand Up @@ -66,7 +67,7 @@ export class Put {
return
}

if (!req.bodySize || !req.bodyStream || req.bodySize === 0) {
if (!req.firstBodyChunk || req.firstBodyChunk.byteLength === 0) {
this.server.getVirtualFilesForUser(req.username)[path] = {
type: "file",
uuid: uuidv4(),
Expand Down Expand Up @@ -101,9 +102,30 @@ export class Put {
}

let didError = false
const stream = new PassThrough()

await new Promise<void>((resolve, reject) => {
stream.write(req.firstBodyChunk, err => {
if (err) {
reject(err)

return
}

resolve()
})
})

stream.on("error", () => {
delete this.server.getVirtualFilesForUser(req.username)[path]

didError = true

Responses.internalError(res).catch(() => {})
})

const item = await sdk.cloud().uploadLocalFileStream({
source: req.bodyStream,
source: req.pipe(stream),
parent: parentResource.uuid,
name,
onError: () => {
Expand Down
35 changes: 15 additions & 20 deletions src/middlewares/body.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
import { type Request, type Response, type NextFunction } from "express"
import { PassThrough } from "stream"
import Responses from "../responses"

export default function body(req: Request, _: Response, next: NextFunction): void {
const passThrough = new PassThrough()
let size = 0

req.bodyStream = passThrough

req.on("data", chunk => {
if (chunk instanceof Buffer) {
size += chunk.byteLength
export default function body(req: Request, res: Response, next: NextFunction): void {
if (!["POST", "PUT"].includes(req.method)) {
next()

passThrough.write(chunk)
}
})
return
}

req.on("end", () => {
req.bodySize = size
req.once("readable", () => {
try {
const chunk = req.read(1)

passThrough.end()
req.firstBodyChunk = chunk instanceof Buffer ? chunk : null

next()
})
req.resume()

req.on("error", err => {
passThrough.emit("error", err)
next()
} catch {
Responses.internalError(res).catch(() => {})
}
})
}
7 changes: 3 additions & 4 deletions types.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { type PassThrough } from "stream"

declare global {
namespace Express {
interface Request {
username?: string
bodyStream?: PassThrough
bodySize?: number
firstBodyChunk?: Buffer | null
}
}
}

export {}

0 comments on commit 6ffce22

Please sign in to comment.