akka/akka-http

Receiving overlarge request should not log error EntityStreamSizeException

Open

#2,125 opened on Jul 25, 2018

View on GitHub
 (0 comments) (1 reaction) (0 assignees)Scala (598 forks)batch import
1 - triagedhelp wantedt:server

Repository metrics

Stars
 (1,311 stars)
PR merge metrics
 (Avg merge 1d 10h) (2 merged PRs in 30d)

Description

Hi,

I want to prevent the user from uploading huge files. In my opinion the user should neither be able to blow up the system nor make it write errors to the log. Using akka.http.[server|client].parsing.max-content-length or MiscDirectives#withSizeLimit works fine but errors are logged because of: https://github.com/akka/akka/issues/25386 Example:

  private val sizeExceptionHandler = ExceptionHandler {
    case _: EntityStreamSizeException =>
      complete(StatusCodes.BadRequest)
  }

  val upload: Route = post {
    handleExceptions(sizeExceptionHandler) {
      withSizeLimit(2000000) {
        fileUpload("file") {
          case (_, _) =>
            //Do something
            complete(StatusCodes.OK)
        }
      }
    }
  }

To not get an error logged and still prevent the user from blow up the system I needed to implement it in a very ugly way not using akka http MiscDirectives#withSizeLimit function .

  val upload: Route = post {
    withoutSizeLimit {
      fileUpload("file") {
        case (fileInfo, source) =>
          onComplete(
            source.runFold(Array[Byte]())((totalBytes, bytes) => {
              val newTotal = totalBytes ++ bytes
              if (newTotal.length > 2000000) throw new IllegalStateException(s"File size exceed limit of 2000000 byte")
              newTotal
            }).map({
              //Do something
              bytes => println(bytes)
            }).recover {
              case e: IllegalStateException =>
                HttpResponse(StatusCodes.BadRequest, entity = e.getMessage)
            })(_ => complete(s"${fileInfo.fileName} successfully uploaded"))
      }
    }
  }

Would it be possible to have MiscDirectives#withSizeLimit without having errors logged or is there a nicer working solution using other akka http functions for this?

Contributor guide