Seaside icon indicating copy to clipboard operation
Seaside copied to clipboard

Error in ZnZincServerAdaptor when extracting the body in a multipart/mixed request

Open eMaringolo opened this issue 3 years ago • 3 comments

When Seaside tries to extract the body from a multipart/mixed request it causes an error since the rule used in ZnZincServerAdaptor>>requestBodyFor: aZincRequest to determine the body assumes the request entity might be a bytearray instead of a ZnMultiPartFormDataEntity

requestBodyFor: aZincRequest
  ^ (aZincRequest method ~= #TRACE 
    and: [ aZincRequest hasEntity
      and: [ aZincRequest entity isEmpty not
        and: [ (aZincRequest entity contentType matches: ZnMimeType applicationFormUrlEncoded) not
          and: [ (aZincRequest entity contentType matches: ZnMimeType multiPartFormData) not ] ] ] ])
            ifTrue: [
              "Seaside wants to do its own text conversions"
	      aZincRequest entity bytes asString ] "<-- ZnMultiPartFormDataEntity does not understand #bytes"
	    ifFalse: [ String new ]

How to reproduce

Create a REST Restful handler at /rest with the following route

multipartMixed
	<post>
	<path: '/multipart1'>

Run the following request against the handler:

curl -X POST -H 'Content-type:multipart/mixed' \
   -F "text=Plain content;type=text/plain" \
   -F 'json={"foo": [1, true], "baz": "bar"};type=application/json'  \
   http://localhost:8080/rest/multipart1

eMaringolo avatar Feb 16 '21 18:02 eMaringolo

It is not clear to me whether there is a bug in the handling, or the request is malformed.

eMaringolo avatar Feb 16 '21 18:02 eMaringolo

I that piece of code needs to be improved. I've stumbled over the same thing when implementing streaming requests. The conditional is just not flexible enough to handle all possible cases.

theseion avatar Feb 17 '21 06:02 theseion

The "proper" solution I see is to reify the body as an entity, which for most cases will be a simple one (as it is now) or a composite/multipart one (for cases like this), so if it's multipart we return a WAMultipartBody or a WASimpleBody (names TBD) .

Anything else could be done as a workaround, like putting each "part" in the postFields, but if we made it this far without supporting it, I'd do it right from the beginning.

eMaringolo avatar Feb 18 '21 17:02 eMaringolo