Closed pzmudzinski closed 2 months ago
What do you mean by
But
imageFile
is not recognized asfile
part
Is that error coming from the encode
function? I tried to find a test that shows Data
being encoded but I can't which isn't great...
I mean it's not encoded in such format:
Content-Disposition: attachment; filename="yourfilename"
I haven't found any way to use it to encode form with file and just gave up and spin up own solution.
Content-Disposition
is a response header when used with the attachment
type, not a request header so I'm confused as to why you need it when doing encoding?
Sorry, I meant "filename" part. Basically was trying to use this library to make a request with multipart form-data body containing both regular key - values and a file within. So in the end it would look like:
Content-Disposition: form-data; name=some-key
...
some value
...
Content-Disposition: form-data; name=image_input; filename=something.png
...
file content
...
But I have not found a way to encode file using it. Does it make sense?
Yes it does make sense. Have you tried File
instead of Data
? That should encode correctly and is a bug if not
I am not sure what are you referring to. There is no such thing as File
In Foundation
framework.
Sorry it's a Vapor thing https://github.com/vapor/vapor/blob/main/Sources/Vapor/Utilities/File.swift
If you're trying to use this outside of Vapor you can copy and paste it and I think it will work
When using Vapor.File
, it gets encoded as follows:
-----bound5952344343153968676
Content-Disposition: form-data; name="image[data]"
<binary data>
-----bound5952344343153968676
Content-Disposition: form-data; name="image[filename]"
myfile.jpg
However, it seems like @pzmudzinski is expecting it to be encoded like this:
Content-Disposition: form-data; name=image; filename=myfile.jpg
I also agree with this, and it appears that without this format, some runtimes may not recognize the file as such.
Sorry, I had missed the extension in Vapor that addresses this issue. With this extension, it would work as expected
@pzmudzinski Here is the simple File.swift
import Foundation
import MultipartKit
import NIOFoundationCompat
public struct File: Codable, Equatable, Sendable, MultipartPartConvertible {
public var filename: String
public var data: Data
public var contentType: String?
public init(data: Data, filename: String, contentType: String? = nil) {
self.data = data
self.filename = filename
self.contentType = contentType
}
// MARK: - MultipartPartConvertible
public var multipart: MultipartPart? {
var part = MultipartPart(headers: [:], body: data)
if let contentType {
part.headers.replaceOrAdd(name: "Content-Type", value: contentType)
}
part.headers.replaceOrAdd(
name: "Content-Disposition",
value: !filename.contains("\"")
? "form-data; filename=\"\(filename)\""
: "form-data; filename='\(filename)'"
)
return part
}
public init?(multipart: MultipartPart) {
let filenameRegex = /filename=(?:"([^"]+)"|'([^']+)'|([^\s"';]+))/
guard let contentDisposition = multipart.headers.first(name: "Content-Disposition"),
let output = contentDisposition.firstMatch(of: filenameRegex)?.output,
let filename = output.1 ?? output.2 ?? output.3
else {
return nil
}
self.init(
data: Data(buffer: multipart.body),
filename: String(filename),
contentType: multipart.headers.first(name: "Content-Type")
)
}
}
@pzmudzinski Does this solve your issue? File
probably should be part of MultipartKit but it would be a breaking change to move it as this point I think, right @gwynne ? (We'd end up with duplicated symbols due to the re-export), so if you're not pulling in Vapor as well you'll need to copy in File
is iOS supported ? https://github.com/vapor/multipart-kit/issues/99
Closing due to inactivity - I believe this is solved now. Feel free to reopen if not!
I was trying to encode struct like that:
But
imageFile
is not recognized asfile
part. Also I could not find any example.Also sorry for bug label - don't know how to remove it 😅