Skip to content

Commit

Permalink
Honor the limit in the bodyParser
Browse files Browse the repository at this point in the history
Pass it along to `concat`, so that only
`limit` number of bytes are loaded into
memory.
  • Loading branch information
helje5 committed Apr 22, 2023
1 parent 2c33cd1 commit 608c9d8
Showing 1 changed file with 33 additions and 10 deletions.
43 changes: 33 additions & 10 deletions Sources/connect/BodyParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -329,12 +329,34 @@ public enum bodyParser {
* Options for use in request body parsers.
*/
public class Options {
public var inflate = false
public var limit = 100 * 1024
public var extended = true


/// Whether the body should be decompressed.
/// Unsupported yet.
public let inflate = false

/// The maximum number of bytes that will be loaded into memory.
/// Defaults to just 100kB, must be explicitly set if larger
/// bodies are allowed! (also consider using multer).
public var limit : Int

/// If set, `qs.parse` is used to parse URL parameters, otherwise
/// `querystring.parse` is used.
public var extended : Bool

/**
* Setup ``bodyParser`` options.
*
* - Parameters:
* - limit: The maximum number of bytes that will be loaded into memory
* (defaults to just 100kB, explictly set for larger bodies!).
* - extended: Whether to use `qs.parse` or `querystring.parse` for
* URL encoded parameters.
*/
@inlinable
public init() {}
public init(limit: Int = 100_000, extended: Bool = true) {
self.limit = limit
self.extended = extended
}
}

fileprivate enum BodyKey: EnvironmentKey {
Expand Down Expand Up @@ -425,7 +447,7 @@ public extension bodyParser {

case .notParsed:
// lame, should be streaming
concatError(request: req, next: next) { bytes in
concatError(request: req, limit: opts.limit, next: next) { bytes in
setBodyIfNotNil(JSONModule.parse(bytes))
return nil
}
Expand Down Expand Up @@ -454,12 +476,13 @@ public extension bodyParser {
// state

private func concatError(request : IncomingMessage,
limit : Int,
next : @escaping Next,
handler : @escaping ( Buffer ) -> Swift.Error?)
{
var didCallNext = false // used to share the error state

request | concat { bytes in
request | concat(maximumSize: limit) { bytes in
guard !didCallNext else { return }
if let error = handler(bytes) {
next(error)
Expand Down Expand Up @@ -507,7 +530,7 @@ public extension bodyParser {
return next() // already loaded

case .notParsed:
concatError(request: req, next: next) { bytes in
concatError(request: req, limit: opts.limit, next: next) { bytes in
req.body = .raw(bytes)
return nil
}
Expand Down Expand Up @@ -556,7 +579,7 @@ public extension bodyParser {
return next() // already loaded

case .notParsed:
concatError(request: req, next: next) { bytes in
concatError(request: req, limit: opts.limit, next: next) { bytes in
do {
req.body = .text(try bytes.toString())
return nil
Expand Down Expand Up @@ -630,7 +653,7 @@ public extension bodyParser {
return next() // already loaded

case .notParsed:
concatError(request: req, next: next) { bytes in
concatError(request: req, limit: opts.limit, next: next) { bytes in
do {
let s = try bytes.toString()
let qp = opts.extended ? qs.parse(s) : querystring.parse(s)
Expand Down

0 comments on commit 608c9d8

Please sign in to comment.