Christoph Thiede uploaded a new version of WebClient-Core to project The Inbox:
http://source.squeak.org/inbox/WebClient-Core-ct.125.mcz ==================== Summary ==================== Name: WebClient-Core-ct.125 Author: ct Time: 8 September 2020, 10:09:01.217336 am UUID: b5a5321e-904d-ca40-aa6a-8ae3236fe629 Ancestors: WebClient-Core-ct.124 Adds UTF-8 conversion to multipart/form-data encoding & decoding in WebUtils. Also includes overall refactoring of the relevant methods. Last but not least, makes the filename parameter optional as specified in RFC7578 Sec. 4.2. NOTE that this is a breaking change for any users of the multipart/form-data protocol provided by the WebClient package! If you manually converted (file)names or plain-text fields to UTF-8 via #squeakToUtf8 before passing them to the WebClient, you should stop doing so now. Vice versa, as a user of WebRequest >> #fields or #multipartFields, you should no longer call #utf8ToSqueak on the output. For more information, please refer to [2]. Thanks to Levente (ul) for the help! Depends indeed on WebClient-Core-ct.124. [1] https://tools.ietf.org/html/rfc7578#section-4.2 [2] http://forum.world.st/Are-we-missing-some-string-encoding-in-SqueakSSL-WebClient-td5121341.html =============== Diff against WebClient-Core-ct.124 =============== Item was changed: ----- Method: WebUtils class>>decodeMultipartForm:boundary:do: (in category 'decoding') ----- decodeMultipartForm: aStream boundary: boundary do: aBlock "Parse the contents of a multipart/form-data submission. + + Evaluate aBlock with three parts: The headers, the (parsed) form-data arguments and the (undecoded) contents of the part. The sender is expected to take care of other issues such as content-transfer-encoding and similar headers." - Evaluate aBlock with three parts: The headers, the (parsed) form-data - arguments and the (undecoded) contents of the part. The sender is - expected to take care of other issues such as content-transfer-encoding - and similar headers." - | skip headers content disposition index params | aStream upToAll: '--', boundary. + [aStream atEnd or: [(skip := aStream next: 2) = '--']] whileFalse: [ + self assert: skip = String crlf description: 'Error decoding multipart/form-data fields'. + + headers := Dictionary newFrom: (WebUtils readHeadersFrom: aStream). - [aStream atEnd or:[(skip := aStream next: 2) = '--']] whileFalse:[ - skip = String crlf ifFalse:[self error: 'Error decoding multipart/form-data fields']. - headers := Dictionary new. - (WebUtils readHeadersFrom: aStream) do:[:hdr| headers add: hdr]. - content := aStream upToAll: String crlf, '--', boundary. params := Dictionary new. + content := aStream upToAll: String crlf, '--', boundary. + + disposition := (headers at: 'content-disposition' ifAbsent: ['']) utf8ToSqueak. + self flag: #todo. "Support content-type and charset as described in RFC7578." + #(name filename) do: [:arg | + | len | - disposition := headers at: 'content-disposition' ifAbsent:['']. - #(name filename) do:[:arg| | len val | len := arg size + 2. + index := disposition findString: arg, '='. + index > 0 ifTrue: [ + params at: arg put: (disposition + copyFrom: index + len + to: (disposition indexOf: $" startingAt: index + len) - 1) utf8ToSqueak]]. + aBlock value: headers value: params value: content].! - index := disposition findString: arg,'='. - index > 0 ifTrue:[ - val := disposition copyFrom: index + len to: (disposition indexOf: $" startingAt: index+len) - 1. - params at: arg put: val. - ]. - ]. - aBlock value: headers value: params value: content. - ].! Item was changed: ----- Method: WebUtils class>>encodeMultipartForm:boundary: (in category 'decoding') ----- encodeMultipartForm: fieldMap boundary: boundary + "Encode the fieldMap as multipart/form-data. + + The fieldMap may contain MIMEDocument instances to indicate the presence of a file to upload to the server. If the MIMEDocument is present, its content type and file name will be used for the upload. + + The fieldMap can be EITHER an array of associations OR a Dictionary of key value pairs (the former is useful for providing multiple fields and/or specifying the order of fields)." - "Encodes the fieldMap as multipart/form-data. + ^ String streamContents: [:stream | + (fieldMap as: OrderedDictionary) keysAndValuesDo: [:fieldName :fieldValue | + | fieldContent | - The fieldMap may contain MIMEDocument instances to indicate the presence - of a file to upload to the server. If the MIMEDocument is present, its - content type and file name will be used for the upload. - - The fieldMap can be EITHER an array of associations OR a Dictionary of - key value pairs (the former is useful for providing multiple fields and/or - specifying the order of fields)." - - ^String streamContents:[:stream| - (fieldMap as: Dictionary) keysAndValuesDo:[:fieldName :fieldValue | | fieldContent | "Write multipart boundary and common headers" stream nextPutAll: '--', boundary; crlf. + stream nextPutAll: 'Content-Disposition: form-data; name="' + , fieldName squeakToUtf8 + , '"'. + self flag: #todo. "Support Content-Type and charset as described in RFC7578." + + "Write field content - either a file or a string" + fieldContent := (fieldValue isKindOf: MIMEDocument) + ifTrue: [ + fieldValue url ifNotNil: [:url | + stream nextPutAll: '; filename="', url pathForFile squeakToUtf8, '"']. + stream crlf. + stream + nextPutAll: 'Content-Type: '; + nextPutAll: fieldValue contentType squeakToUtf8. + (fieldValue content ifNil: [ + (FileStream readOnlyFileNamed: fieldValue url pathForFile) contentsOfEntireFile]) asString] + ifFalse: [fieldValue asString squeakToUtf8]. - stream nextPutAll: 'Content-Disposition: form-data; name="', fieldName, '"'. - "Figure out if this is a file upload" - (fieldValue isKindOf: MIMEDocument) ifTrue:[ - stream nextPutAll: '; filename="', fieldValue url pathForFile, '"'; crlf. - stream nextPutAll: 'Content-Type: ', fieldValue contentType. - fieldContent := (fieldValue content ifNil:[ - (FileStream readOnlyFileNamed: fieldValue url pathForFile) contentsOfEntireFile. - ]) asString. - ] ifFalse: [fieldContent := fieldValue]. stream crlf; crlf. + stream nextPutAll: fieldContent. + + stream crlf]. + stream nextPutAll: '--', boundary, '--', String crlf]! - stream nextPutAll: fieldContent asString. - stream crlf. - ]. - stream nextPutAll: '--', boundary, '--', String crlf. - ]. - ! |
Free forum by Nabble | Edit this page |