Skip to content

Submitting a form with an empty file field throws exception #149

@nikosk

Description

@nikosk

Minimal repro:

case class FormRoute()(implicit
    cc: castor.Context,
    log: cask.Logger
) extends cask.MainRoutes:

  @cask.get("/")
  def index() =
    Response("""
    <!DOCTYPE html>
    <html lang="en">
    <head></head>
    <body>
        <form action="/post" method="post" enctype="multipart/form-data">    
            <input type="file" id="image" name="image" accept="image/*">
            <button type="submit">Submit</button>
        </form>
    </body>
    </html>
    """, 200, Seq(("Content-Type", "text/html")))    

  @cask.postForm("/post")
  def post(image: cask.FormFile) = s"Image filename: ${image.fileName}"

  initialize()


object Application extends cask.Main:
    val allRoutes = Seq(FormRoute())


Stacktrace:

Unable to parse form data: java.lang.IllegalStateException: UT000017: Form value is a file, use getFileItem() instead
java.lang.IllegalStateException: UT000017: Form value is a file, use getFileItem() instead
	at io.undertow.server.handlers.form.FormData$FormValueImpl.getValue(FormData.java:351)
	at cask.model.FormEntry$.fromUndertow(Params.scala:102)	

The method cask.model.FormEntry#fromUndertow is naively implemented and does not take into account optional field values. Browsers AFAIK will always send fields even if they are empty, it's up to the server/app to decide what emptiness means.
At the very least I would expect fromUndertow to return Option[FormEntry] and let the postForm decorator deal with it.

Below is an example request from Firefox, but I would expect all browsers to behave the same.

-----------------------------265322345236697440593672026017
Content-Disposition: form-data; name="image"; filename=""
Content-Type: application/octet-stream


-----------------------------265322345236697440593672026017--

I tried to take a stab at fixing this but the project doesn't compile (tried all tags as low as 0.9.0) and the error messages are too cryptic for me (scala.reflect.internal.FatalError: bad constant pool index: 0 at pos: 48454 wtf?!). Let me know if you want me to open a ticket for that also.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions