@@ -3,26 +3,7 @@ public import RFC_2046
33public import RFC_2183
44
55// MARK: - RFC 7578: Multipart/Form-Data
6-
7- extension RFC_2046 . Multipart . Subtype {
8- /// Form data with file uploads
9- ///
10- /// Used in HTTP POST requests with file uploads.
11- /// Each part has a `Content-Disposition: form-data` header
12- /// with the form field name.
13- ///
14- /// **RFC 7578** - Returning Values from Forms: multipart/form-data
15- ///
16- /// ## Example
17- ///
18- /// ```swift
19- /// let formData = try RFC_2046.Multipart.formData(
20- /// fields: ["username": "john_doe"],
21- /// files: [...]
22- /// )
23- /// ```
24- public static let formData = RFC_2046 . Multipart. Subtype ( rawValue: " form-data " )
25- }
6+ // Note: .formData subtype is defined in RFC_2046.Multipart.Subtype
267
278extension RFC_2046 . Multipart {
289 /// Creates a multipart/form-data message
@@ -65,10 +46,13 @@ extension RFC_2046.Multipart {
6546
6647 // Add text fields
6748 for (name, value) in fields. sorted ( by: { $0. key < $1. key } ) {
49+ var headers = RFC_2046 . BodyPart. Headers ( )
50+ headers. contentDisposition = RFC_2183 . ContentDisposition. formData ( name: name)
51+ headers. contentType = . textPlainUTF8
6852 parts. append (
6953 RFC_2046 . BodyPart (
70- headers: . formDataTextField ( name : name ) ,
71- text : value
54+ headers: headers ,
55+ content : RFC_2046 . BodyPart . Content ( Array ( value. utf8 ) )
7256 )
7357 )
7458 }
@@ -77,22 +61,25 @@ extension RFC_2046.Multipart {
7761 for file in files {
7862 // Note: Content-Transfer-Encoding not added per RFC 7578 §4.7
7963 // HTTP supports binary data natively
64+ var headers = RFC_2046 . BodyPart. Headers ( )
65+ headers. contentDisposition = RFC_2183 . ContentDisposition. formData (
66+ name: file. fieldName,
67+ filename: file. filename
68+ )
69+ headers. contentType = file. contentType
8070 parts. append (
8171 RFC_2046 . BodyPart (
82- headers: . formDataFile(
83- name: file. fieldName,
84- filename: file. filename,
85- contentType: file. contentType
86- ) ,
87- content: file. content
72+ headers: headers,
73+ content: RFC_2046 . BodyPart. Content ( file. content)
8874 )
8975 )
9076 }
9177
9278 // Generate boundary if not provided
93- let effectiveBoundary =
79+ let effectiveBoundaryString =
9480 boundary
9581 ?? " ----FormData \( parts. count) \( parts. first? . headers. contentType? . type ?? " data " ) "
82+ let effectiveBoundary = try RFC_2046 . Boundary ( effectiveBoundaryString)
9683
9784 return try Self (
9885 subtype: . formData,
@@ -271,8 +258,7 @@ extension RFC_2046.Multipart {
271258 // Use typed Content-Disposition header
272259 guard let disposition = part. headers. contentDisposition,
273260 disposition. type == RFC_2183 . DispositionType. formData,
274- let fieldName = disposition. name,
275- let textContent = part. textContent
261+ let fieldName = disposition. name
276262 else {
277263 continue
278264 }
@@ -282,6 +268,8 @@ extension RFC_2046.Multipart {
282268 continue
283269 }
284270
271+ // Get text content from raw bytes
272+ let textContent = String ( part. content)
285273 fields [ fieldName] = textContent
286274 }
287275
0 commit comments