├── .gitignore ├── .swift-version ├── Assets └── CompatiilityTests │ └── Server │ ├── .node-version │ ├── index.js │ ├── package-lock.json │ └── package.json ├── Cartfile ├── Cartfile.resolved ├── LICENSE ├── MultipartFormDataKit.podspec ├── MultipartFormDataKit.xcodeproj ├── MultipartFormDataKitTests_Info.plist ├── MultipartFormDataKit_Info.plist ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── MultipartFormDataKit-iOS.xcscheme │ ├── MultipartFormDataKit-macOS.xcscheme │ ├── MultipartFormDataKit-tvOS.xcscheme │ ├── MultipartFormDataKit-watchOS.xcscheme │ ├── MultipartFormDataKitTests.xcscheme │ └── xcschememanagement.plist ├── Package.swift ├── README.md ├── Sources └── MultipartFormDataKit │ ├── BoundaryGenerator.swift │ ├── CRLF.swift │ ├── ContentDisposition.swift │ ├── ContentType.swift │ ├── Dash.swift │ ├── Filename.swift │ ├── MIMEType.swift │ ├── MultipartFormData+Builder.swift │ ├── MultipartFormData+Part.swift │ ├── MultipartFormData.swift │ ├── Name.swift │ └── ValidationResult.swift └── Tests ├── LinuxMain.swift └── MultipartFormDataKitTests ├── CompatibilityTests.swift ├── ContentDispositionTests.swift ├── ContentTypeTests.swift ├── FilenameTests.swift ├── MultipartFormDataBuilderTests.swift ├── MultipartFormDataTests.swift └── NameTests.swift /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots 68 | fastlane/test_output 69 | 70 | node_modules 71 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 4.0 2 | -------------------------------------------------------------------------------- /Assets/CompatiilityTests/Server/.node-version: -------------------------------------------------------------------------------- 1 | v8.8.1 2 | -------------------------------------------------------------------------------- /Assets/CompatiilityTests/Server/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Path = require('path'); 4 | const Http = require('http'); 5 | const express = require('express'); 6 | const multer = require('multer'); 7 | const upload = multer(); 8 | 9 | const PORT = process.env.PORT || 8080; 10 | const HOSTNAME = 'localhost'; 11 | 12 | const app = express(); 13 | 14 | 15 | app.post('/echo', upload.single("example", 2), (req, res, next) => { 16 | console.log(req.body); 17 | console.log(req.file); 18 | res.sendStatus(200).end(); 19 | }) 20 | 21 | 22 | Http.createServer(app).listen(PORT, HOSTNAME, () => { 23 | console.log(`Listening on http://${HOSTNAME}:${PORT}`) 24 | }); 25 | -------------------------------------------------------------------------------- /Assets/CompatiilityTests/Server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "multipart-form-data-swift-tests", 3 | "version": "0.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", 9 | "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", 10 | "requires": { 11 | "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", 12 | "negotiator": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz" 13 | } 14 | }, 15 | "append-field": { 16 | "version": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", 17 | "integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo=" 18 | }, 19 | "array-flatten": { 20 | "version": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 21 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 22 | }, 23 | "body-parser": { 24 | "version": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", 25 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", 26 | "requires": { 27 | "bytes": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 28 | "content-type": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 29 | "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 30 | "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 31 | "http-errors": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 32 | "iconv-lite": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 33 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 34 | "qs": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", 35 | "raw-body": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", 36 | "type-is": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz" 37 | } 38 | }, 39 | "busboy": { 40 | "version": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", 41 | "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", 42 | "requires": { 43 | "dicer": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", 44 | "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz" 45 | } 46 | }, 47 | "bytes": { 48 | "version": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 49 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 50 | }, 51 | "concat-stream": { 52 | "version": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", 53 | "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", 54 | "requires": { 55 | "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 56 | "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 57 | "typedarray": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" 58 | }, 59 | "dependencies": { 60 | "isarray": { 61 | "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 62 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 63 | }, 64 | "readable-stream": { 65 | "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 66 | "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", 67 | "requires": { 68 | "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 69 | "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 70 | "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 71 | "process-nextick-args": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", 72 | "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 73 | "string_decoder": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 74 | "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" 75 | } 76 | }, 77 | "string_decoder": { 78 | "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 79 | "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", 80 | "requires": { 81 | "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" 82 | } 83 | } 84 | } 85 | }, 86 | "content-disposition": { 87 | "version": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 88 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 89 | }, 90 | "content-type": { 91 | "version": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 92 | "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=" 93 | }, 94 | "cookie": { 95 | "version": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 96 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 97 | }, 98 | "cookie-signature": { 99 | "version": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 100 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 101 | }, 102 | "core-util-is": { 103 | "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 104 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 105 | }, 106 | "debug": { 107 | "version": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 108 | "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", 109 | "requires": { 110 | "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" 111 | } 112 | }, 113 | "depd": { 114 | "version": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 115 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" 116 | }, 117 | "destroy": { 118 | "version": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 119 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 120 | }, 121 | "dicer": { 122 | "version": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", 123 | "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", 124 | "requires": { 125 | "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 126 | "streamsearch": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz" 127 | } 128 | }, 129 | "ee-first": { 130 | "version": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 131 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 132 | }, 133 | "encodeurl": { 134 | "version": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", 135 | "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" 136 | }, 137 | "escape-html": { 138 | "version": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 139 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 140 | }, 141 | "etag": { 142 | "version": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 143 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 144 | }, 145 | "express": { 146 | "version": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", 147 | "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", 148 | "requires": { 149 | "accepts": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", 150 | "array-flatten": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 151 | "body-parser": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", 152 | "content-disposition": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 153 | "content-type": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 154 | "cookie": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 155 | "cookie-signature": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 156 | "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 157 | "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 158 | "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", 159 | "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 160 | "etag": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 161 | "finalhandler": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", 162 | "fresh": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 163 | "merge-descriptors": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 164 | "methods": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 165 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 166 | "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 167 | "path-to-regexp": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 168 | "proxy-addr": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", 169 | "qs": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", 170 | "range-parser": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 171 | "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 172 | "send": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", 173 | "serve-static": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", 174 | "setprototypeof": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 175 | "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", 176 | "type-is": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", 177 | "utils-merge": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 178 | "vary": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" 179 | } 180 | }, 181 | "finalhandler": { 182 | "version": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", 183 | "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", 184 | "requires": { 185 | "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 186 | "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", 187 | "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 188 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 189 | "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 190 | "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", 191 | "unpipe": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" 192 | } 193 | }, 194 | "forwarded": { 195 | "version": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 196 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 197 | }, 198 | "fresh": { 199 | "version": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 200 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 201 | }, 202 | "http-errors": { 203 | "version": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 204 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 205 | "requires": { 206 | "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 207 | "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 208 | "setprototypeof": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 209 | "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz" 210 | }, 211 | "dependencies": { 212 | "setprototypeof": { 213 | "version": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 214 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" 215 | } 216 | } 217 | }, 218 | "iconv-lite": { 219 | "version": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 220 | "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs=" 221 | }, 222 | "inherits": { 223 | "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 224 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 225 | }, 226 | "ipaddr.js": { 227 | "version": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", 228 | "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" 229 | }, 230 | "isarray": { 231 | "version": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 232 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 233 | }, 234 | "media-typer": { 235 | "version": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 236 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 237 | }, 238 | "merge-descriptors": { 239 | "version": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 240 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 241 | }, 242 | "methods": { 243 | "version": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 244 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 245 | }, 246 | "mime": { 247 | "version": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 248 | "integrity": "sha1-Eh+evEnjdm8xGnbh+hyAA8SwOqY=" 249 | }, 250 | "mime-db": { 251 | "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", 252 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" 253 | }, 254 | "mime-types": { 255 | "version": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", 256 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", 257 | "requires": { 258 | "mime-db": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz" 259 | } 260 | }, 261 | "minimist": { 262 | "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 263 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 264 | }, 265 | "mkdirp": { 266 | "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 267 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 268 | "requires": { 269 | "minimist": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" 270 | } 271 | }, 272 | "ms": { 273 | "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 274 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 275 | }, 276 | "multer": { 277 | "version": "https://registry.npmjs.org/multer/-/multer-1.3.0.tgz", 278 | "integrity": "sha1-CSsmcPaEb6SRSWXvyM+Uwg/sbNI=", 279 | "requires": { 280 | "append-field": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", 281 | "busboy": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", 282 | "concat-stream": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", 283 | "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 284 | "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", 285 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 286 | "type-is": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", 287 | "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" 288 | } 289 | }, 290 | "negotiator": { 291 | "version": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 292 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 293 | }, 294 | "object-assign": { 295 | "version": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", 296 | "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" 297 | }, 298 | "on-finished": { 299 | "version": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 300 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 301 | "requires": { 302 | "ee-first": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" 303 | } 304 | }, 305 | "parseurl": { 306 | "version": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 307 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 308 | }, 309 | "path-to-regexp": { 310 | "version": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 311 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 312 | }, 313 | "process-nextick-args": { 314 | "version": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", 315 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" 316 | }, 317 | "proxy-addr": { 318 | "version": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", 319 | "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", 320 | "requires": { 321 | "forwarded": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 322 | "ipaddr.js": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz" 323 | } 324 | }, 325 | "qs": { 326 | "version": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", 327 | "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg=" 328 | }, 329 | "range-parser": { 330 | "version": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 331 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 332 | }, 333 | "raw-body": { 334 | "version": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", 335 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", 336 | "requires": { 337 | "bytes": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 338 | "http-errors": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 339 | "iconv-lite": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 340 | "unpipe": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" 341 | } 342 | }, 343 | "readable-stream": { 344 | "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 345 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 346 | "requires": { 347 | "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 348 | "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 349 | "isarray": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 350 | "string_decoder": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" 351 | } 352 | }, 353 | "safe-buffer": { 354 | "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 355 | "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=" 356 | }, 357 | "send": { 358 | "version": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", 359 | "integrity": "sha1-pw4coh0TgsEdDZ9iMd6ygQgNerM=", 360 | "requires": { 361 | "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 362 | "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 363 | "destroy": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 364 | "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", 365 | "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 366 | "etag": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 367 | "fresh": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 368 | "http-errors": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 369 | "mime": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 370 | "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 371 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 372 | "range-parser": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 373 | "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz" 374 | } 375 | }, 376 | "serve-static": { 377 | "version": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", 378 | "integrity": "sha1-TFfVNASnYdjy58HooYpH2/J4pxk=", 379 | "requires": { 380 | "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", 381 | "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 382 | "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 383 | "send": "https://registry.npmjs.org/send/-/send-0.16.1.tgz" 384 | } 385 | }, 386 | "setprototypeof": { 387 | "version": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 388 | "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=" 389 | }, 390 | "statuses": { 391 | "version": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", 392 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" 393 | }, 394 | "streamsearch": { 395 | "version": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", 396 | "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" 397 | }, 398 | "string_decoder": { 399 | "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 400 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 401 | }, 402 | "type-is": { 403 | "version": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", 404 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", 405 | "requires": { 406 | "media-typer": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 407 | "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz" 408 | } 409 | }, 410 | "typedarray": { 411 | "version": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 412 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" 413 | }, 414 | "unpipe": { 415 | "version": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 416 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 417 | }, 418 | "util-deprecate": { 419 | "version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 420 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 421 | }, 422 | "utils-merge": { 423 | "version": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 424 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 425 | }, 426 | "vary": { 427 | "version": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 428 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 429 | }, 430 | "xtend": { 431 | "version": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 432 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" 433 | } 434 | } 435 | } 436 | -------------------------------------------------------------------------------- /Assets/CompatiilityTests/Server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "multipart-form-data-swift-tests", 3 | "version": "0.0.0", 4 | "description": "A test server for MultipartFormData", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Kuniwak", 10 | "license": "MIT", 11 | "dependencies": { 12 | "express": "^4.16.2", 13 | "multer": "^1.3.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuniwak/MultipartFormDataKit/666c1715f6e70f4589d11ae2936eb16bf018ccd4/Cartfile -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kuniwak/MultipartFormDataKit/666c1715f6e70f4589d11ae2936eb16bf018ccd4/Cartfile.resolved -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Kuniwak 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /MultipartFormDataKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'MultipartFormDataKit' 3 | s.version = '2.0.0' 4 | s.summary = 'multipart/form-data for Swift.' 5 | s.description = <<-DESC 6 | multipart/form-data for Swift. 7 | You can communicate by using this module and URLSession or other HTTP libraries. 8 | DESC 9 | s.homepage = 'https://github.com/Kuniwak/MultipartFormDataKit' 10 | s.license = { :type => 'MIT', :file => 'LICENSE' } 11 | s.author = { 'Kuniwak' => 'orga.chem.job@gmail.com' } 12 | s.source = { :git => 'https://github.com/Kuniwak/MultipartFormDataKit.git', :tag => s.version.to_s } 13 | s.ios.deployment_target = '9.0' 14 | s.source_files = 'Sources/**/*' 15 | s.frameworks = 'Foundation' 16 | end 17 | -------------------------------------------------------------------------------- /MultipartFormDataKit.xcodeproj/MultipartFormDataKitTests_Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CFBundleDevelopmentRegion 5 | en 6 | CFBundleExecutable 7 | $(EXECUTABLE_NAME) 8 | CFBundleIdentifier 9 | $(PRODUCT_BUNDLE_IDENTIFIER) 10 | CFBundleInfoDictionaryVersion 11 | 6.0 12 | CFBundleName 13 | $(PRODUCT_NAME) 14 | CFBundlePackageType 15 | BNDL 16 | CFBundleShortVersionString 17 | 1.0 18 | CFBundleSignature 19 | ???? 20 | CFBundleVersion 21 | $(CURRENT_PROJECT_VERSION) 22 | NSPrincipalClass 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /MultipartFormDataKit.xcodeproj/MultipartFormDataKit_Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CFBundleDevelopmentRegion 5 | en 6 | CFBundleExecutable 7 | $(EXECUTABLE_NAME) 8 | CFBundleIdentifier 9 | $(PRODUCT_BUNDLE_IDENTIFIER) 10 | CFBundleInfoDictionaryVersion 11 | 6.0 12 | CFBundleName 13 | $(PRODUCT_NAME) 14 | CFBundlePackageType 15 | FMWK 16 | CFBundleShortVersionString 17 | 1.0 18 | CFBundleSignature 19 | ???? 20 | CFBundleVersion 21 | $(CURRENT_PROJECT_VERSION) 22 | NSPrincipalClass 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /MultipartFormDataKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | "MultipartFormDataKit::MultipartFormDataKitPackageTests::ProductTarget" /* MultipartFormDataKitPackageTests */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = OBJ_74 /* Build configuration list for PBXAggregateTarget "MultipartFormDataKitPackageTests" */; 13 | buildPhases = ( 14 | ); 15 | dependencies = ( 16 | OBJ_77 /* PBXTargetDependency */, 17 | ); 18 | name = MultipartFormDataKitPackageTests; 19 | productName = MultipartFormDataKitPackageTests; 20 | }; 21 | /* End PBXAggregateTarget section */ 22 | 23 | /* Begin PBXBuildFile section */ 24 | 621346C51FA61B5800DD098E /* BoundaryGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* BoundaryGenerator.swift */; }; 25 | 621346C61FA61B5800DD098E /* CRLF.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* CRLF.swift */; }; 26 | 621346C71FA61B5800DD098E /* ContentDisposition.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* ContentDisposition.swift */; }; 27 | 621346C81FA61B5800DD098E /* ContentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* ContentType.swift */; }; 28 | 621346C91FA61B5800DD098E /* Dash.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* Dash.swift */; }; 29 | 621346CA1FA61B5800DD098E /* Filename.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* Filename.swift */; }; 30 | 621346CB1FA61B5800DD098E /* MIMEType.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* MIMEType.swift */; }; 31 | 621346CC1FA61B5800DD098E /* MultipartFormData+Builder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* MultipartFormData+Builder.swift */; }; 32 | 621346CD1FA61B5800DD098E /* MultipartFormData+Part.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* MultipartFormData+Part.swift */; }; 33 | 621346CE1FA61B5800DD098E /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* MultipartFormData.swift */; }; 34 | 621346CF1FA61B5800DD098E /* Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_19 /* Name.swift */; }; 35 | 621346D01FA61B5800DD098E /* ValidationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* ValidationResult.swift */; }; 36 | 621346D11FA61B5D00DD098E /* BoundaryGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* BoundaryGenerator.swift */; }; 37 | 621346D21FA61B5D00DD098E /* CRLF.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* CRLF.swift */; }; 38 | 621346D31FA61B5D00DD098E /* ContentDisposition.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* ContentDisposition.swift */; }; 39 | 621346D41FA61B5D00DD098E /* ContentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* ContentType.swift */; }; 40 | 621346D51FA61B5D00DD098E /* Dash.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* Dash.swift */; }; 41 | 621346D61FA61B5D00DD098E /* Filename.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* Filename.swift */; }; 42 | 621346D71FA61B5D00DD098E /* MIMEType.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* MIMEType.swift */; }; 43 | 621346D81FA61B5D00DD098E /* MultipartFormData+Builder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* MultipartFormData+Builder.swift */; }; 44 | 621346D91FA61B5D00DD098E /* MultipartFormData+Part.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* MultipartFormData+Part.swift */; }; 45 | 621346DA1FA61B5D00DD098E /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* MultipartFormData.swift */; }; 46 | 621346DB1FA61B5D00DD098E /* Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_19 /* Name.swift */; }; 47 | 621346DC1FA61B5D00DD098E /* ValidationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* ValidationResult.swift */; }; 48 | 621346DD1FA61B6000DD098E /* BoundaryGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* BoundaryGenerator.swift */; }; 49 | 621346DE1FA61B6000DD098E /* CRLF.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* CRLF.swift */; }; 50 | 621346DF1FA61B6000DD098E /* ContentDisposition.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* ContentDisposition.swift */; }; 51 | 621346E01FA61B6000DD098E /* ContentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* ContentType.swift */; }; 52 | 621346E11FA61B6000DD098E /* Dash.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* Dash.swift */; }; 53 | 621346E21FA61B6000DD098E /* Filename.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* Filename.swift */; }; 54 | 621346E31FA61B6000DD098E /* MIMEType.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* MIMEType.swift */; }; 55 | 621346E41FA61B6000DD098E /* MultipartFormData+Builder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* MultipartFormData+Builder.swift */; }; 56 | 621346E51FA61B6000DD098E /* MultipartFormData+Part.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* MultipartFormData+Part.swift */; }; 57 | 621346E61FA61B6000DD098E /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* MultipartFormData.swift */; }; 58 | 621346E71FA61B6000DD098E /* Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_19 /* Name.swift */; }; 59 | 621346E81FA61B6000DD098E /* ValidationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* ValidationResult.swift */; }; 60 | OBJ_39 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; }; 61 | OBJ_45 /* CompatibilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_23 /* CompatibilityTests.swift */; }; 62 | OBJ_46 /* ContentDispositionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_24 /* ContentDispositionTests.swift */; }; 63 | OBJ_47 /* ContentTypeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_25 /* ContentTypeTests.swift */; }; 64 | OBJ_48 /* FilenameTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* FilenameTests.swift */; }; 65 | OBJ_49 /* MultipartFormDataBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_27 /* MultipartFormDataBuilderTests.swift */; }; 66 | OBJ_50 /* MultipartFormDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_28 /* MultipartFormDataTests.swift */; }; 67 | OBJ_51 /* NameTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_29 /* NameTests.swift */; }; 68 | OBJ_53 /* MultipartFormDataKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "MultipartFormDataKit::MultipartFormDataKit::Product" /* MultipartFormDataKit.framework */; }; 69 | OBJ_60 /* BoundaryGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* BoundaryGenerator.swift */; }; 70 | OBJ_61 /* CRLF.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* CRLF.swift */; }; 71 | OBJ_62 /* ContentDisposition.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* ContentDisposition.swift */; }; 72 | OBJ_63 /* ContentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* ContentType.swift */; }; 73 | OBJ_64 /* Dash.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* Dash.swift */; }; 74 | OBJ_65 /* Filename.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* Filename.swift */; }; 75 | OBJ_66 /* MIMEType.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* MIMEType.swift */; }; 76 | OBJ_67 /* MultipartFormData+Builder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* MultipartFormData+Builder.swift */; }; 77 | OBJ_68 /* MultipartFormData+Part.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* MultipartFormData+Part.swift */; }; 78 | OBJ_69 /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* MultipartFormData.swift */; }; 79 | OBJ_70 /* Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_19 /* Name.swift */; }; 80 | OBJ_71 /* ValidationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* ValidationResult.swift */; }; 81 | /* End PBXBuildFile section */ 82 | 83 | /* Begin PBXContainerItemProxy section */ 84 | 621346971FA60B9400DD098E /* PBXContainerItemProxy */ = { 85 | isa = PBXContainerItemProxy; 86 | containerPortal = OBJ_1 /* Project object */; 87 | proxyType = 1; 88 | remoteGlobalIDString = "MultipartFormDataKit::MultipartFormDataKit"; 89 | remoteInfo = MultipartFormDataKit; 90 | }; 91 | 621346981FA60B9500DD098E /* PBXContainerItemProxy */ = { 92 | isa = PBXContainerItemProxy; 93 | containerPortal = OBJ_1 /* Project object */; 94 | proxyType = 1; 95 | remoteGlobalIDString = "MultipartFormDataKit::MultipartFormDataKitTests"; 96 | remoteInfo = MultipartFormDataKitTests; 97 | }; 98 | /* End PBXContainerItemProxy section */ 99 | 100 | /* Begin PBXFileReference section */ 101 | 6213469E1FA60C4500DD098E /* MultipartFormDataKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MultipartFormDataKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 102 | 621346AB1FA60CCB00DD098E /* MultipartFormDataKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MultipartFormDataKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 103 | 621346B81FA60D0800DD098E /* MultipartFormDataKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MultipartFormDataKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 104 | "MultipartFormDataKit::MultipartFormDataKit::Product" /* MultipartFormDataKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MultipartFormDataKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 105 | "MultipartFormDataKit::MultipartFormDataKitTests::Product" /* MultipartFormDataKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = MultipartFormDataKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 106 | OBJ_10 /* CRLF.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CRLF.swift; sourceTree = ""; }; 107 | OBJ_11 /* ContentDisposition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentDisposition.swift; sourceTree = ""; }; 108 | OBJ_12 /* ContentType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentType.swift; sourceTree = ""; }; 109 | OBJ_13 /* Dash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dash.swift; sourceTree = ""; }; 110 | OBJ_14 /* Filename.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filename.swift; sourceTree = ""; }; 111 | OBJ_15 /* MIMEType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MIMEType.swift; sourceTree = ""; }; 112 | OBJ_16 /* MultipartFormData+Builder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MultipartFormData+Builder.swift"; sourceTree = ""; }; 113 | OBJ_17 /* MultipartFormData+Part.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MultipartFormData+Part.swift"; sourceTree = ""; }; 114 | OBJ_18 /* MultipartFormData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipartFormData.swift; sourceTree = ""; }; 115 | OBJ_19 /* Name.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Name.swift; sourceTree = ""; }; 116 | OBJ_20 /* ValidationResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidationResult.swift; sourceTree = ""; }; 117 | OBJ_23 /* CompatibilityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompatibilityTests.swift; sourceTree = ""; }; 118 | OBJ_24 /* ContentDispositionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentDispositionTests.swift; sourceTree = ""; }; 119 | OBJ_25 /* ContentTypeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentTypeTests.swift; sourceTree = ""; }; 120 | OBJ_26 /* FilenameTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilenameTests.swift; sourceTree = ""; }; 121 | OBJ_27 /* MultipartFormDataBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipartFormDataBuilderTests.swift; sourceTree = ""; }; 122 | OBJ_28 /* MultipartFormDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipartFormDataTests.swift; sourceTree = ""; }; 123 | OBJ_29 /* NameTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NameTests.swift; sourceTree = ""; }; 124 | OBJ_30 /* Assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Assets; sourceTree = SOURCE_ROOT; }; 125 | OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 126 | OBJ_9 /* BoundaryGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoundaryGenerator.swift; sourceTree = ""; }; 127 | /* End PBXFileReference section */ 128 | 129 | /* Begin PBXFrameworksBuildPhase section */ 130 | 6213469A1FA60C4500DD098E /* Frameworks */ = { 131 | isa = PBXFrameworksBuildPhase; 132 | buildActionMask = 2147483647; 133 | files = ( 134 | ); 135 | runOnlyForDeploymentPostprocessing = 0; 136 | }; 137 | 621346A71FA60CCB00DD098E /* Frameworks */ = { 138 | isa = PBXFrameworksBuildPhase; 139 | buildActionMask = 2147483647; 140 | files = ( 141 | ); 142 | runOnlyForDeploymentPostprocessing = 0; 143 | }; 144 | 621346B41FA60D0800DD098E /* Frameworks */ = { 145 | isa = PBXFrameworksBuildPhase; 146 | buildActionMask = 2147483647; 147 | files = ( 148 | ); 149 | runOnlyForDeploymentPostprocessing = 0; 150 | }; 151 | OBJ_52 /* Frameworks */ = { 152 | isa = PBXFrameworksBuildPhase; 153 | buildActionMask = 0; 154 | files = ( 155 | OBJ_53 /* MultipartFormDataKit.framework in Frameworks */, 156 | ); 157 | runOnlyForDeploymentPostprocessing = 0; 158 | }; 159 | OBJ_72 /* Frameworks */ = { 160 | isa = PBXFrameworksBuildPhase; 161 | buildActionMask = 0; 162 | files = ( 163 | ); 164 | runOnlyForDeploymentPostprocessing = 0; 165 | }; 166 | /* End PBXFrameworksBuildPhase section */ 167 | 168 | /* Begin PBXGroup section */ 169 | OBJ_21 /* Tests */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | OBJ_22 /* MultipartFormDataKitTests */, 173 | ); 174 | name = Tests; 175 | sourceTree = SOURCE_ROOT; 176 | }; 177 | OBJ_22 /* MultipartFormDataKitTests */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | OBJ_23 /* CompatibilityTests.swift */, 181 | OBJ_24 /* ContentDispositionTests.swift */, 182 | OBJ_25 /* ContentTypeTests.swift */, 183 | OBJ_26 /* FilenameTests.swift */, 184 | OBJ_27 /* MultipartFormDataBuilderTests.swift */, 185 | OBJ_28 /* MultipartFormDataTests.swift */, 186 | OBJ_29 /* NameTests.swift */, 187 | ); 188 | name = MultipartFormDataKitTests; 189 | path = Tests/MultipartFormDataKitTests; 190 | sourceTree = SOURCE_ROOT; 191 | }; 192 | OBJ_31 /* Products */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | "MultipartFormDataKit::MultipartFormDataKitTests::Product" /* MultipartFormDataKitTests.xctest */, 196 | "MultipartFormDataKit::MultipartFormDataKit::Product" /* MultipartFormDataKit.framework */, 197 | 6213469E1FA60C4500DD098E /* MultipartFormDataKit.framework */, 198 | 621346AB1FA60CCB00DD098E /* MultipartFormDataKit.framework */, 199 | 621346B81FA60D0800DD098E /* MultipartFormDataKit.framework */, 200 | ); 201 | name = Products; 202 | sourceTree = BUILT_PRODUCTS_DIR; 203 | }; 204 | OBJ_5 = { 205 | isa = PBXGroup; 206 | children = ( 207 | OBJ_6 /* Package.swift */, 208 | OBJ_7 /* Sources */, 209 | OBJ_21 /* Tests */, 210 | OBJ_30 /* Assets */, 211 | OBJ_31 /* Products */, 212 | ); 213 | sourceTree = ""; 214 | }; 215 | OBJ_7 /* Sources */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | OBJ_8 /* MultipartFormDataKit */, 219 | ); 220 | name = Sources; 221 | sourceTree = SOURCE_ROOT; 222 | }; 223 | OBJ_8 /* MultipartFormDataKit */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | OBJ_9 /* BoundaryGenerator.swift */, 227 | OBJ_10 /* CRLF.swift */, 228 | OBJ_11 /* ContentDisposition.swift */, 229 | OBJ_12 /* ContentType.swift */, 230 | OBJ_13 /* Dash.swift */, 231 | OBJ_14 /* Filename.swift */, 232 | OBJ_15 /* MIMEType.swift */, 233 | OBJ_16 /* MultipartFormData+Builder.swift */, 234 | OBJ_17 /* MultipartFormData+Part.swift */, 235 | OBJ_18 /* MultipartFormData.swift */, 236 | OBJ_19 /* Name.swift */, 237 | OBJ_20 /* ValidationResult.swift */, 238 | ); 239 | name = MultipartFormDataKit; 240 | path = Sources/MultipartFormDataKit; 241 | sourceTree = SOURCE_ROOT; 242 | }; 243 | /* End PBXGroup section */ 244 | 245 | /* Begin PBXHeadersBuildPhase section */ 246 | 6213469B1FA60C4500DD098E /* Headers */ = { 247 | isa = PBXHeadersBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | ); 251 | runOnlyForDeploymentPostprocessing = 0; 252 | }; 253 | 621346A81FA60CCB00DD098E /* Headers */ = { 254 | isa = PBXHeadersBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | }; 260 | 621346B51FA60D0800DD098E /* Headers */ = { 261 | isa = PBXHeadersBuildPhase; 262 | buildActionMask = 2147483647; 263 | files = ( 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | /* End PBXHeadersBuildPhase section */ 268 | 269 | /* Begin PBXNativeTarget section */ 270 | 6213469D1FA60C4500DD098E /* MultipartFormDataKit-iOS */ = { 271 | isa = PBXNativeTarget; 272 | buildConfigurationList = 621346A31FA60C4500DD098E /* Build configuration list for PBXNativeTarget "MultipartFormDataKit-iOS" */; 273 | buildPhases = ( 274 | 621346991FA60C4500DD098E /* Sources */, 275 | 6213469A1FA60C4500DD098E /* Frameworks */, 276 | 6213469B1FA60C4500DD098E /* Headers */, 277 | 6213469C1FA60C4500DD098E /* Resources */, 278 | ); 279 | buildRules = ( 280 | ); 281 | dependencies = ( 282 | ); 283 | name = "MultipartFormDataKit-iOS"; 284 | productName = MultipartFormDataKit; 285 | productReference = 6213469E1FA60C4500DD098E /* MultipartFormDataKit.framework */; 286 | productType = "com.apple.product-type.framework"; 287 | }; 288 | 621346AA1FA60CCB00DD098E /* MultipartFormDataKit-watchOS */ = { 289 | isa = PBXNativeTarget; 290 | buildConfigurationList = 621346B01FA60CCC00DD098E /* Build configuration list for PBXNativeTarget "MultipartFormDataKit-watchOS" */; 291 | buildPhases = ( 292 | 621346A61FA60CCB00DD098E /* Sources */, 293 | 621346A71FA60CCB00DD098E /* Frameworks */, 294 | 621346A81FA60CCB00DD098E /* Headers */, 295 | 621346A91FA60CCB00DD098E /* Resources */, 296 | ); 297 | buildRules = ( 298 | ); 299 | dependencies = ( 300 | ); 301 | name = "MultipartFormDataKit-watchOS"; 302 | productName = MultipartFormDataKit; 303 | productReference = 621346AB1FA60CCB00DD098E /* MultipartFormDataKit.framework */; 304 | productType = "com.apple.product-type.framework"; 305 | }; 306 | 621346B71FA60D0800DD098E /* MultipartFormDataKit-tvOS */ = { 307 | isa = PBXNativeTarget; 308 | buildConfigurationList = 621346BD1FA60D0800DD098E /* Build configuration list for PBXNativeTarget "MultipartFormDataKit-tvOS" */; 309 | buildPhases = ( 310 | 621346B31FA60D0800DD098E /* Sources */, 311 | 621346B41FA60D0800DD098E /* Frameworks */, 312 | 621346B51FA60D0800DD098E /* Headers */, 313 | 621346B61FA60D0800DD098E /* Resources */, 314 | ); 315 | buildRules = ( 316 | ); 317 | dependencies = ( 318 | ); 319 | name = "MultipartFormDataKit-tvOS"; 320 | productName = MultipartFormDataKit; 321 | productReference = 621346B81FA60D0800DD098E /* MultipartFormDataKit.framework */; 322 | productType = "com.apple.product-type.framework"; 323 | }; 324 | "MultipartFormDataKit::MultipartFormDataKit" /* MultipartFormDataKit-macOS */ = { 325 | isa = PBXNativeTarget; 326 | buildConfigurationList = OBJ_56 /* Build configuration list for PBXNativeTarget "MultipartFormDataKit-macOS" */; 327 | buildPhases = ( 328 | OBJ_59 /* Sources */, 329 | OBJ_72 /* Frameworks */, 330 | ); 331 | buildRules = ( 332 | ); 333 | dependencies = ( 334 | ); 335 | name = "MultipartFormDataKit-macOS"; 336 | productName = MultipartFormDataKit; 337 | productReference = "MultipartFormDataKit::MultipartFormDataKit::Product" /* MultipartFormDataKit.framework */; 338 | productType = "com.apple.product-type.framework"; 339 | }; 340 | "MultipartFormDataKit::MultipartFormDataKitTests" /* MultipartFormDataKitTests */ = { 341 | isa = PBXNativeTarget; 342 | buildConfigurationList = OBJ_41 /* Build configuration list for PBXNativeTarget "MultipartFormDataKitTests" */; 343 | buildPhases = ( 344 | OBJ_44 /* Sources */, 345 | OBJ_52 /* Frameworks */, 346 | ); 347 | buildRules = ( 348 | ); 349 | dependencies = ( 350 | OBJ_54 /* PBXTargetDependency */, 351 | ); 352 | name = MultipartFormDataKitTests; 353 | productName = MultipartFormDataKitTests; 354 | productReference = "MultipartFormDataKit::MultipartFormDataKitTests::Product" /* MultipartFormDataKitTests.xctest */; 355 | productType = "com.apple.product-type.bundle.unit-test"; 356 | }; 357 | "MultipartFormDataKit::SwiftPMPackageDescription" /* MultipartFormDataKitPackageDescription */ = { 358 | isa = PBXNativeTarget; 359 | buildConfigurationList = OBJ_35 /* Build configuration list for PBXNativeTarget "MultipartFormDataKitPackageDescription" */; 360 | buildPhases = ( 361 | OBJ_38 /* Sources */, 362 | ); 363 | buildRules = ( 364 | ); 365 | dependencies = ( 366 | ); 367 | name = MultipartFormDataKitPackageDescription; 368 | productName = MultipartFormDataKitPackageDescription; 369 | productType = "com.apple.product-type.framework"; 370 | }; 371 | /* End PBXNativeTarget section */ 372 | 373 | /* Begin PBXProject section */ 374 | OBJ_1 /* Project object */ = { 375 | isa = PBXProject; 376 | attributes = { 377 | LastUpgradeCheck = 0900; 378 | TargetAttributes = { 379 | 6213469D1FA60C4500DD098E = { 380 | CreatedOnToolsVersion = 9.0.1; 381 | ProvisioningStyle = Automatic; 382 | }; 383 | 621346AA1FA60CCB00DD098E = { 384 | CreatedOnToolsVersion = 9.0.1; 385 | ProvisioningStyle = Automatic; 386 | }; 387 | 621346B71FA60D0800DD098E = { 388 | CreatedOnToolsVersion = 9.0.1; 389 | ProvisioningStyle = Automatic; 390 | }; 391 | }; 392 | }; 393 | buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "MultipartFormDataKit" */; 394 | compatibilityVersion = "Xcode 3.2"; 395 | developmentRegion = English; 396 | hasScannedForEncodings = 0; 397 | knownRegions = ( 398 | en, 399 | ); 400 | mainGroup = OBJ_5; 401 | productRefGroup = OBJ_31 /* Products */; 402 | projectDirPath = ""; 403 | projectRoot = ""; 404 | targets = ( 405 | "MultipartFormDataKit::SwiftPMPackageDescription" /* MultipartFormDataKitPackageDescription */, 406 | "MultipartFormDataKit::MultipartFormDataKitTests" /* MultipartFormDataKitTests */, 407 | "MultipartFormDataKit::MultipartFormDataKitPackageTests::ProductTarget" /* MultipartFormDataKitPackageTests */, 408 | "MultipartFormDataKit::MultipartFormDataKit" /* MultipartFormDataKit-macOS */, 409 | 6213469D1FA60C4500DD098E /* MultipartFormDataKit-iOS */, 410 | 621346AA1FA60CCB00DD098E /* MultipartFormDataKit-watchOS */, 411 | 621346B71FA60D0800DD098E /* MultipartFormDataKit-tvOS */, 412 | ); 413 | }; 414 | /* End PBXProject section */ 415 | 416 | /* Begin PBXResourcesBuildPhase section */ 417 | 6213469C1FA60C4500DD098E /* Resources */ = { 418 | isa = PBXResourcesBuildPhase; 419 | buildActionMask = 2147483647; 420 | files = ( 421 | ); 422 | runOnlyForDeploymentPostprocessing = 0; 423 | }; 424 | 621346A91FA60CCB00DD098E /* Resources */ = { 425 | isa = PBXResourcesBuildPhase; 426 | buildActionMask = 2147483647; 427 | files = ( 428 | ); 429 | runOnlyForDeploymentPostprocessing = 0; 430 | }; 431 | 621346B61FA60D0800DD098E /* Resources */ = { 432 | isa = PBXResourcesBuildPhase; 433 | buildActionMask = 2147483647; 434 | files = ( 435 | ); 436 | runOnlyForDeploymentPostprocessing = 0; 437 | }; 438 | /* End PBXResourcesBuildPhase section */ 439 | 440 | /* Begin PBXSourcesBuildPhase section */ 441 | 621346991FA60C4500DD098E /* Sources */ = { 442 | isa = PBXSourcesBuildPhase; 443 | buildActionMask = 2147483647; 444 | files = ( 445 | 621346C51FA61B5800DD098E /* BoundaryGenerator.swift in Sources */, 446 | 621346C61FA61B5800DD098E /* CRLF.swift in Sources */, 447 | 621346C71FA61B5800DD098E /* ContentDisposition.swift in Sources */, 448 | 621346C81FA61B5800DD098E /* ContentType.swift in Sources */, 449 | 621346C91FA61B5800DD098E /* Dash.swift in Sources */, 450 | 621346CA1FA61B5800DD098E /* Filename.swift in Sources */, 451 | 621346CB1FA61B5800DD098E /* MIMEType.swift in Sources */, 452 | 621346CC1FA61B5800DD098E /* MultipartFormData+Builder.swift in Sources */, 453 | 621346CD1FA61B5800DD098E /* MultipartFormData+Part.swift in Sources */, 454 | 621346CE1FA61B5800DD098E /* MultipartFormData.swift in Sources */, 455 | 621346CF1FA61B5800DD098E /* Name.swift in Sources */, 456 | 621346D01FA61B5800DD098E /* ValidationResult.swift in Sources */, 457 | ); 458 | runOnlyForDeploymentPostprocessing = 0; 459 | }; 460 | 621346A61FA60CCB00DD098E /* Sources */ = { 461 | isa = PBXSourcesBuildPhase; 462 | buildActionMask = 2147483647; 463 | files = ( 464 | 621346D11FA61B5D00DD098E /* BoundaryGenerator.swift in Sources */, 465 | 621346D21FA61B5D00DD098E /* CRLF.swift in Sources */, 466 | 621346D31FA61B5D00DD098E /* ContentDisposition.swift in Sources */, 467 | 621346D41FA61B5D00DD098E /* ContentType.swift in Sources */, 468 | 621346D51FA61B5D00DD098E /* Dash.swift in Sources */, 469 | 621346D61FA61B5D00DD098E /* Filename.swift in Sources */, 470 | 621346D71FA61B5D00DD098E /* MIMEType.swift in Sources */, 471 | 621346D81FA61B5D00DD098E /* MultipartFormData+Builder.swift in Sources */, 472 | 621346D91FA61B5D00DD098E /* MultipartFormData+Part.swift in Sources */, 473 | 621346DA1FA61B5D00DD098E /* MultipartFormData.swift in Sources */, 474 | 621346DB1FA61B5D00DD098E /* Name.swift in Sources */, 475 | 621346DC1FA61B5D00DD098E /* ValidationResult.swift in Sources */, 476 | ); 477 | runOnlyForDeploymentPostprocessing = 0; 478 | }; 479 | 621346B31FA60D0800DD098E /* Sources */ = { 480 | isa = PBXSourcesBuildPhase; 481 | buildActionMask = 2147483647; 482 | files = ( 483 | 621346DD1FA61B6000DD098E /* BoundaryGenerator.swift in Sources */, 484 | 621346DE1FA61B6000DD098E /* CRLF.swift in Sources */, 485 | 621346DF1FA61B6000DD098E /* ContentDisposition.swift in Sources */, 486 | 621346E01FA61B6000DD098E /* ContentType.swift in Sources */, 487 | 621346E11FA61B6000DD098E /* Dash.swift in Sources */, 488 | 621346E21FA61B6000DD098E /* Filename.swift in Sources */, 489 | 621346E31FA61B6000DD098E /* MIMEType.swift in Sources */, 490 | 621346E41FA61B6000DD098E /* MultipartFormData+Builder.swift in Sources */, 491 | 621346E51FA61B6000DD098E /* MultipartFormData+Part.swift in Sources */, 492 | 621346E61FA61B6000DD098E /* MultipartFormData.swift in Sources */, 493 | 621346E71FA61B6000DD098E /* Name.swift in Sources */, 494 | 621346E81FA61B6000DD098E /* ValidationResult.swift in Sources */, 495 | ); 496 | runOnlyForDeploymentPostprocessing = 0; 497 | }; 498 | OBJ_38 /* Sources */ = { 499 | isa = PBXSourcesBuildPhase; 500 | buildActionMask = 0; 501 | files = ( 502 | OBJ_39 /* Package.swift in Sources */, 503 | ); 504 | runOnlyForDeploymentPostprocessing = 0; 505 | }; 506 | OBJ_44 /* Sources */ = { 507 | isa = PBXSourcesBuildPhase; 508 | buildActionMask = 0; 509 | files = ( 510 | OBJ_45 /* CompatibilityTests.swift in Sources */, 511 | OBJ_46 /* ContentDispositionTests.swift in Sources */, 512 | OBJ_47 /* ContentTypeTests.swift in Sources */, 513 | OBJ_48 /* FilenameTests.swift in Sources */, 514 | OBJ_49 /* MultipartFormDataBuilderTests.swift in Sources */, 515 | OBJ_50 /* MultipartFormDataTests.swift in Sources */, 516 | OBJ_51 /* NameTests.swift in Sources */, 517 | ); 518 | runOnlyForDeploymentPostprocessing = 0; 519 | }; 520 | OBJ_59 /* Sources */ = { 521 | isa = PBXSourcesBuildPhase; 522 | buildActionMask = 0; 523 | files = ( 524 | OBJ_60 /* BoundaryGenerator.swift in Sources */, 525 | OBJ_61 /* CRLF.swift in Sources */, 526 | OBJ_62 /* ContentDisposition.swift in Sources */, 527 | OBJ_63 /* ContentType.swift in Sources */, 528 | OBJ_64 /* Dash.swift in Sources */, 529 | OBJ_65 /* Filename.swift in Sources */, 530 | OBJ_66 /* MIMEType.swift in Sources */, 531 | OBJ_67 /* MultipartFormData+Builder.swift in Sources */, 532 | OBJ_68 /* MultipartFormData+Part.swift in Sources */, 533 | OBJ_69 /* MultipartFormData.swift in Sources */, 534 | OBJ_70 /* Name.swift in Sources */, 535 | OBJ_71 /* ValidationResult.swift in Sources */, 536 | ); 537 | runOnlyForDeploymentPostprocessing = 0; 538 | }; 539 | /* End PBXSourcesBuildPhase section */ 540 | 541 | /* Begin PBXTargetDependency section */ 542 | OBJ_54 /* PBXTargetDependency */ = { 543 | isa = PBXTargetDependency; 544 | target = "MultipartFormDataKit::MultipartFormDataKit" /* MultipartFormDataKit-macOS */; 545 | targetProxy = 621346971FA60B9400DD098E /* PBXContainerItemProxy */; 546 | }; 547 | OBJ_77 /* PBXTargetDependency */ = { 548 | isa = PBXTargetDependency; 549 | target = "MultipartFormDataKit::MultipartFormDataKitTests" /* MultipartFormDataKitTests */; 550 | targetProxy = 621346981FA60B9500DD098E /* PBXContainerItemProxy */; 551 | }; 552 | /* End PBXTargetDependency section */ 553 | 554 | /* Begin XCBuildConfiguration section */ 555 | 621346A41FA60C4500DD098E /* Debug */ = { 556 | isa = XCBuildConfiguration; 557 | buildSettings = { 558 | ALWAYS_SEARCH_USER_PATHS = NO; 559 | CLANG_ANALYZER_NONNULL = YES; 560 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 561 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 562 | CLANG_CXX_LIBRARY = "libc++"; 563 | CLANG_ENABLE_MODULES = YES; 564 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 565 | CLANG_WARN_BOOL_CONVERSION = YES; 566 | CLANG_WARN_COMMA = YES; 567 | CLANG_WARN_CONSTANT_CONVERSION = YES; 568 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 569 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 570 | CLANG_WARN_EMPTY_BODY = YES; 571 | CLANG_WARN_ENUM_CONVERSION = YES; 572 | CLANG_WARN_INFINITE_RECURSION = YES; 573 | CLANG_WARN_INT_CONVERSION = YES; 574 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 575 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 576 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 577 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 578 | CLANG_WARN_STRICT_PROTOTYPES = YES; 579 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 580 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 581 | CLANG_WARN_UNREACHABLE_CODE = YES; 582 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 583 | CODE_SIGN_IDENTITY = "iPhone Developer"; 584 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 585 | CODE_SIGN_STYLE = Automatic; 586 | CURRENT_PROJECT_VERSION = 1; 587 | DEFINES_MODULE = YES; 588 | DYLIB_COMPATIBILITY_VERSION = 1; 589 | DYLIB_CURRENT_VERSION = 1; 590 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 591 | ENABLE_STRICT_OBJC_MSGSEND = YES; 592 | ENABLE_TESTABILITY = YES; 593 | GCC_C_LANGUAGE_STANDARD = gnu11; 594 | GCC_DYNAMIC_NO_PIC = NO; 595 | GCC_NO_COMMON_BLOCKS = YES; 596 | GCC_PREPROCESSOR_DEFINITIONS = ( 597 | "DEBUG=1", 598 | "$(inherited)", 599 | ); 600 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 601 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 602 | GCC_WARN_UNDECLARED_SELECTOR = YES; 603 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 604 | GCC_WARN_UNUSED_FUNCTION = YES; 605 | GCC_WARN_UNUSED_VARIABLE = YES; 606 | INFOPLIST_FILE = MultipartFormDataKit.xcodeproj/MultipartFormDataKit_Info.plist; 607 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 608 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 609 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 610 | MTL_ENABLE_DEBUG_INFO = YES; 611 | PRODUCT_BUNDLE_IDENTIFIER = com.kuniwak.MultipartFormDataKit; 612 | PRODUCT_NAME = MultipartFormDataKit; 613 | SDKROOT = iphoneos; 614 | SKIP_INSTALL = YES; 615 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 616 | SWIFT_VERSION = 4.0; 617 | TARGETED_DEVICE_FAMILY = "1,2"; 618 | VERSIONING_SYSTEM = "apple-generic"; 619 | VERSION_INFO_PREFIX = ""; 620 | }; 621 | name = Debug; 622 | }; 623 | 621346A51FA60C4500DD098E /* Release */ = { 624 | isa = XCBuildConfiguration; 625 | buildSettings = { 626 | ALWAYS_SEARCH_USER_PATHS = NO; 627 | CLANG_ANALYZER_NONNULL = YES; 628 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 629 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 630 | CLANG_CXX_LIBRARY = "libc++"; 631 | CLANG_ENABLE_MODULES = YES; 632 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 633 | CLANG_WARN_BOOL_CONVERSION = YES; 634 | CLANG_WARN_COMMA = YES; 635 | CLANG_WARN_CONSTANT_CONVERSION = YES; 636 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 637 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 638 | CLANG_WARN_EMPTY_BODY = YES; 639 | CLANG_WARN_ENUM_CONVERSION = YES; 640 | CLANG_WARN_INFINITE_RECURSION = YES; 641 | CLANG_WARN_INT_CONVERSION = YES; 642 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 643 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 644 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 645 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 646 | CLANG_WARN_STRICT_PROTOTYPES = YES; 647 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 648 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 649 | CLANG_WARN_UNREACHABLE_CODE = YES; 650 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 651 | CODE_SIGN_IDENTITY = "iPhone Developer"; 652 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 653 | CODE_SIGN_STYLE = Automatic; 654 | COPY_PHASE_STRIP = NO; 655 | CURRENT_PROJECT_VERSION = 1; 656 | DEFINES_MODULE = YES; 657 | DYLIB_COMPATIBILITY_VERSION = 1; 658 | DYLIB_CURRENT_VERSION = 1; 659 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 660 | ENABLE_NS_ASSERTIONS = NO; 661 | ENABLE_STRICT_OBJC_MSGSEND = YES; 662 | GCC_C_LANGUAGE_STANDARD = gnu11; 663 | GCC_NO_COMMON_BLOCKS = YES; 664 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 665 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 666 | GCC_WARN_UNDECLARED_SELECTOR = YES; 667 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 668 | GCC_WARN_UNUSED_FUNCTION = YES; 669 | GCC_WARN_UNUSED_VARIABLE = YES; 670 | INFOPLIST_FILE = MultipartFormDataKit.xcodeproj/MultipartFormDataKit_Info.plist; 671 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 672 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 673 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 674 | MTL_ENABLE_DEBUG_INFO = NO; 675 | PRODUCT_BUNDLE_IDENTIFIER = com.kuniwak.MultipartFormDataKit; 676 | PRODUCT_NAME = MultipartFormDataKit; 677 | SDKROOT = iphoneos; 678 | SKIP_INSTALL = YES; 679 | SWIFT_VERSION = 4.0; 680 | TARGETED_DEVICE_FAMILY = "1,2"; 681 | VALIDATE_PRODUCT = YES; 682 | VERSIONING_SYSTEM = "apple-generic"; 683 | VERSION_INFO_PREFIX = ""; 684 | }; 685 | name = Release; 686 | }; 687 | 621346B11FA60CCC00DD098E /* Debug */ = { 688 | isa = XCBuildConfiguration; 689 | buildSettings = { 690 | ALWAYS_SEARCH_USER_PATHS = NO; 691 | APPLICATION_EXTENSION_API_ONLY = YES; 692 | CLANG_ANALYZER_NONNULL = YES; 693 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 694 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 695 | CLANG_CXX_LIBRARY = "libc++"; 696 | CLANG_ENABLE_MODULES = YES; 697 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 698 | CLANG_WARN_BOOL_CONVERSION = YES; 699 | CLANG_WARN_COMMA = YES; 700 | CLANG_WARN_CONSTANT_CONVERSION = YES; 701 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 702 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 703 | CLANG_WARN_EMPTY_BODY = YES; 704 | CLANG_WARN_ENUM_CONVERSION = YES; 705 | CLANG_WARN_INFINITE_RECURSION = YES; 706 | CLANG_WARN_INT_CONVERSION = YES; 707 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 708 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 709 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 710 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 711 | CLANG_WARN_STRICT_PROTOTYPES = YES; 712 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 713 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 714 | CLANG_WARN_UNREACHABLE_CODE = YES; 715 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 716 | CODE_SIGN_IDENTITY = ""; 717 | CODE_SIGN_STYLE = Automatic; 718 | CURRENT_PROJECT_VERSION = 1; 719 | DEFINES_MODULE = YES; 720 | DYLIB_COMPATIBILITY_VERSION = 1; 721 | DYLIB_CURRENT_VERSION = 1; 722 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 723 | ENABLE_STRICT_OBJC_MSGSEND = YES; 724 | ENABLE_TESTABILITY = YES; 725 | GCC_C_LANGUAGE_STANDARD = gnu11; 726 | GCC_DYNAMIC_NO_PIC = NO; 727 | GCC_NO_COMMON_BLOCKS = YES; 728 | GCC_PREPROCESSOR_DEFINITIONS = ( 729 | "DEBUG=1", 730 | "$(inherited)", 731 | ); 732 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 733 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 734 | GCC_WARN_UNDECLARED_SELECTOR = YES; 735 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 736 | GCC_WARN_UNUSED_FUNCTION = YES; 737 | GCC_WARN_UNUSED_VARIABLE = YES; 738 | INFOPLIST_FILE = MultipartFormDataKit.xcodeproj/MultipartFormDataKit_Info.plist; 739 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 740 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 741 | MTL_ENABLE_DEBUG_INFO = YES; 742 | PRODUCT_BUNDLE_IDENTIFIER = com.kuniwak.MultipartFormDataKit; 743 | PRODUCT_NAME = MultipartFormDataKit; 744 | SDKROOT = watchos; 745 | SKIP_INSTALL = YES; 746 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 747 | SWIFT_VERSION = 4.0; 748 | TARGETED_DEVICE_FAMILY = 4; 749 | VERSIONING_SYSTEM = "apple-generic"; 750 | VERSION_INFO_PREFIX = ""; 751 | WATCHOS_DEPLOYMENT_TARGET = 4.0; 752 | }; 753 | name = Debug; 754 | }; 755 | 621346B21FA60CCC00DD098E /* Release */ = { 756 | isa = XCBuildConfiguration; 757 | buildSettings = { 758 | ALWAYS_SEARCH_USER_PATHS = NO; 759 | APPLICATION_EXTENSION_API_ONLY = YES; 760 | CLANG_ANALYZER_NONNULL = YES; 761 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 762 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 763 | CLANG_CXX_LIBRARY = "libc++"; 764 | CLANG_ENABLE_MODULES = YES; 765 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 766 | CLANG_WARN_BOOL_CONVERSION = YES; 767 | CLANG_WARN_COMMA = YES; 768 | CLANG_WARN_CONSTANT_CONVERSION = YES; 769 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 770 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 771 | CLANG_WARN_EMPTY_BODY = YES; 772 | CLANG_WARN_ENUM_CONVERSION = YES; 773 | CLANG_WARN_INFINITE_RECURSION = YES; 774 | CLANG_WARN_INT_CONVERSION = YES; 775 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 776 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 777 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 778 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 779 | CLANG_WARN_STRICT_PROTOTYPES = YES; 780 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 781 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 782 | CLANG_WARN_UNREACHABLE_CODE = YES; 783 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 784 | CODE_SIGN_IDENTITY = ""; 785 | CODE_SIGN_STYLE = Automatic; 786 | COPY_PHASE_STRIP = NO; 787 | CURRENT_PROJECT_VERSION = 1; 788 | DEFINES_MODULE = YES; 789 | DYLIB_COMPATIBILITY_VERSION = 1; 790 | DYLIB_CURRENT_VERSION = 1; 791 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 792 | ENABLE_NS_ASSERTIONS = NO; 793 | ENABLE_STRICT_OBJC_MSGSEND = YES; 794 | GCC_C_LANGUAGE_STANDARD = gnu11; 795 | GCC_NO_COMMON_BLOCKS = YES; 796 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 797 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 798 | GCC_WARN_UNDECLARED_SELECTOR = YES; 799 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 800 | GCC_WARN_UNUSED_FUNCTION = YES; 801 | GCC_WARN_UNUSED_VARIABLE = YES; 802 | INFOPLIST_FILE = MultipartFormDataKit.xcodeproj/MultipartFormDataKit_Info.plist; 803 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 804 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 805 | MTL_ENABLE_DEBUG_INFO = NO; 806 | PRODUCT_BUNDLE_IDENTIFIER = com.kuniwak.MultipartFormDataKit; 807 | PRODUCT_NAME = MultipartFormDataKit; 808 | SDKROOT = watchos; 809 | SKIP_INSTALL = YES; 810 | SWIFT_VERSION = 4.0; 811 | TARGETED_DEVICE_FAMILY = 4; 812 | VALIDATE_PRODUCT = YES; 813 | VERSIONING_SYSTEM = "apple-generic"; 814 | VERSION_INFO_PREFIX = ""; 815 | WATCHOS_DEPLOYMENT_TARGET = 4.0; 816 | }; 817 | name = Release; 818 | }; 819 | 621346BE1FA60D0800DD098E /* Debug */ = { 820 | isa = XCBuildConfiguration; 821 | buildSettings = { 822 | ALWAYS_SEARCH_USER_PATHS = NO; 823 | CLANG_ANALYZER_NONNULL = YES; 824 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 825 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 826 | CLANG_CXX_LIBRARY = "libc++"; 827 | CLANG_ENABLE_MODULES = YES; 828 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 829 | CLANG_WARN_BOOL_CONVERSION = YES; 830 | CLANG_WARN_COMMA = YES; 831 | CLANG_WARN_CONSTANT_CONVERSION = YES; 832 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 833 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 834 | CLANG_WARN_EMPTY_BODY = YES; 835 | CLANG_WARN_ENUM_CONVERSION = YES; 836 | CLANG_WARN_INFINITE_RECURSION = YES; 837 | CLANG_WARN_INT_CONVERSION = YES; 838 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 839 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 840 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 841 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 842 | CLANG_WARN_STRICT_PROTOTYPES = YES; 843 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 844 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 845 | CLANG_WARN_UNREACHABLE_CODE = YES; 846 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 847 | CODE_SIGN_IDENTITY = ""; 848 | CODE_SIGN_STYLE = Automatic; 849 | CURRENT_PROJECT_VERSION = 1; 850 | DEFINES_MODULE = YES; 851 | DYLIB_COMPATIBILITY_VERSION = 1; 852 | DYLIB_CURRENT_VERSION = 1; 853 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 854 | ENABLE_STRICT_OBJC_MSGSEND = YES; 855 | ENABLE_TESTABILITY = YES; 856 | GCC_C_LANGUAGE_STANDARD = gnu11; 857 | GCC_DYNAMIC_NO_PIC = NO; 858 | GCC_NO_COMMON_BLOCKS = YES; 859 | GCC_PREPROCESSOR_DEFINITIONS = ( 860 | "DEBUG=1", 861 | "$(inherited)", 862 | ); 863 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 864 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 865 | GCC_WARN_UNDECLARED_SELECTOR = YES; 866 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 867 | GCC_WARN_UNUSED_FUNCTION = YES; 868 | GCC_WARN_UNUSED_VARIABLE = YES; 869 | INFOPLIST_FILE = MultipartFormDataKit.xcodeproj/MultipartFormDataKit_Info.plist; 870 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 871 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 872 | MTL_ENABLE_DEBUG_INFO = YES; 873 | PRODUCT_BUNDLE_IDENTIFIER = com.kuniwak.MultipartFormDataKit; 874 | PRODUCT_NAME = MultipartFormDataKit; 875 | SDKROOT = appletvos; 876 | SKIP_INSTALL = YES; 877 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 878 | SWIFT_VERSION = 4.0; 879 | TARGETED_DEVICE_FAMILY = 3; 880 | VERSIONING_SYSTEM = "apple-generic"; 881 | VERSION_INFO_PREFIX = ""; 882 | }; 883 | name = Debug; 884 | }; 885 | 621346BF1FA60D0800DD098E /* Release */ = { 886 | isa = XCBuildConfiguration; 887 | buildSettings = { 888 | ALWAYS_SEARCH_USER_PATHS = NO; 889 | CLANG_ANALYZER_NONNULL = YES; 890 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 891 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 892 | CLANG_CXX_LIBRARY = "libc++"; 893 | CLANG_ENABLE_MODULES = YES; 894 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 895 | CLANG_WARN_BOOL_CONVERSION = YES; 896 | CLANG_WARN_COMMA = YES; 897 | CLANG_WARN_CONSTANT_CONVERSION = YES; 898 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 899 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 900 | CLANG_WARN_EMPTY_BODY = YES; 901 | CLANG_WARN_ENUM_CONVERSION = YES; 902 | CLANG_WARN_INFINITE_RECURSION = YES; 903 | CLANG_WARN_INT_CONVERSION = YES; 904 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 905 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 906 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 907 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 908 | CLANG_WARN_STRICT_PROTOTYPES = YES; 909 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 910 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 911 | CLANG_WARN_UNREACHABLE_CODE = YES; 912 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 913 | CODE_SIGN_IDENTITY = ""; 914 | CODE_SIGN_STYLE = Automatic; 915 | COPY_PHASE_STRIP = NO; 916 | CURRENT_PROJECT_VERSION = 1; 917 | DEFINES_MODULE = YES; 918 | DYLIB_COMPATIBILITY_VERSION = 1; 919 | DYLIB_CURRENT_VERSION = 1; 920 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 921 | ENABLE_NS_ASSERTIONS = NO; 922 | ENABLE_STRICT_OBJC_MSGSEND = YES; 923 | GCC_C_LANGUAGE_STANDARD = gnu11; 924 | GCC_NO_COMMON_BLOCKS = YES; 925 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 926 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 927 | GCC_WARN_UNDECLARED_SELECTOR = YES; 928 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 929 | GCC_WARN_UNUSED_FUNCTION = YES; 930 | GCC_WARN_UNUSED_VARIABLE = YES; 931 | INFOPLIST_FILE = MultipartFormDataKit.xcodeproj/MultipartFormDataKit_Info.plist; 932 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 933 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 934 | MTL_ENABLE_DEBUG_INFO = NO; 935 | PRODUCT_BUNDLE_IDENTIFIER = com.kuniwak.MultipartFormDataKit; 936 | PRODUCT_NAME = MultipartFormDataKit; 937 | SDKROOT = appletvos; 938 | SKIP_INSTALL = YES; 939 | SWIFT_VERSION = 4.0; 940 | TARGETED_DEVICE_FAMILY = 3; 941 | VALIDATE_PRODUCT = YES; 942 | VERSIONING_SYSTEM = "apple-generic"; 943 | VERSION_INFO_PREFIX = ""; 944 | }; 945 | name = Release; 946 | }; 947 | OBJ_3 /* Debug */ = { 948 | isa = XCBuildConfiguration; 949 | buildSettings = { 950 | CLANG_ENABLE_OBJC_ARC = YES; 951 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 952 | CLANG_WARN_BOOL_CONVERSION = YES; 953 | CLANG_WARN_COMMA = YES; 954 | CLANG_WARN_CONSTANT_CONVERSION = YES; 955 | CLANG_WARN_EMPTY_BODY = YES; 956 | CLANG_WARN_ENUM_CONVERSION = YES; 957 | CLANG_WARN_INFINITE_RECURSION = YES; 958 | CLANG_WARN_INT_CONVERSION = YES; 959 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 960 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 961 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 962 | CLANG_WARN_STRICT_PROTOTYPES = YES; 963 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 964 | CLANG_WARN_UNREACHABLE_CODE = YES; 965 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 966 | COMBINE_HIDPI_IMAGES = YES; 967 | COPY_PHASE_STRIP = NO; 968 | DEBUG_INFORMATION_FORMAT = dwarf; 969 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 970 | ENABLE_NS_ASSERTIONS = YES; 971 | ENABLE_STRICT_OBJC_MSGSEND = YES; 972 | ENABLE_TESTABILITY = YES; 973 | GCC_NO_COMMON_BLOCKS = YES; 974 | GCC_OPTIMIZATION_LEVEL = 0; 975 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 976 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 977 | GCC_WARN_UNDECLARED_SELECTOR = YES; 978 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 979 | GCC_WARN_UNUSED_FUNCTION = YES; 980 | GCC_WARN_UNUSED_VARIABLE = YES; 981 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 982 | MACOSX_DEPLOYMENT_TARGET = 10.10; 983 | ONLY_ACTIVE_ARCH = YES; 984 | OTHER_SWIFT_FLAGS = "-DXcode"; 985 | PRODUCT_NAME = "$(TARGET_NAME)"; 986 | SDKROOT = macosx; 987 | SUPPORTED_PLATFORMS = "$(inherited)"; 988 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; 989 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 990 | USE_HEADERMAP = NO; 991 | }; 992 | name = Debug; 993 | }; 994 | OBJ_36 /* Debug */ = { 995 | isa = XCBuildConfiguration; 996 | buildSettings = { 997 | LD = /usr/bin/true; 998 | OTHER_SWIFT_FLAGS = "-swift-version 4 -I /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/pm/4 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk"; 999 | SWIFT_VERSION = 4.0; 1000 | }; 1001 | name = Debug; 1002 | }; 1003 | OBJ_37 /* Release */ = { 1004 | isa = XCBuildConfiguration; 1005 | buildSettings = { 1006 | LD = /usr/bin/true; 1007 | OTHER_SWIFT_FLAGS = "-swift-version 4 -I /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/pm/4 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk"; 1008 | SWIFT_VERSION = 4.0; 1009 | }; 1010 | name = Release; 1011 | }; 1012 | OBJ_4 /* Release */ = { 1013 | isa = XCBuildConfiguration; 1014 | buildSettings = { 1015 | CLANG_ENABLE_OBJC_ARC = YES; 1016 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1017 | CLANG_WARN_BOOL_CONVERSION = YES; 1018 | CLANG_WARN_COMMA = YES; 1019 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1020 | CLANG_WARN_EMPTY_BODY = YES; 1021 | CLANG_WARN_ENUM_CONVERSION = YES; 1022 | CLANG_WARN_INFINITE_RECURSION = YES; 1023 | CLANG_WARN_INT_CONVERSION = YES; 1024 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1025 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1026 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1027 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1028 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1029 | CLANG_WARN_UNREACHABLE_CODE = YES; 1030 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1031 | COMBINE_HIDPI_IMAGES = YES; 1032 | COPY_PHASE_STRIP = YES; 1033 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1034 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1035 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1036 | GCC_NO_COMMON_BLOCKS = YES; 1037 | GCC_OPTIMIZATION_LEVEL = s; 1038 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1039 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 1040 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1041 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 1042 | GCC_WARN_UNUSED_FUNCTION = YES; 1043 | GCC_WARN_UNUSED_VARIABLE = YES; 1044 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 1045 | MACOSX_DEPLOYMENT_TARGET = 10.10; 1046 | OTHER_SWIFT_FLAGS = "-DXcode"; 1047 | PRODUCT_NAME = "$(TARGET_NAME)"; 1048 | SDKROOT = macosx; 1049 | SUPPORTED_PLATFORMS = "$(inherited)"; 1050 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; 1051 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 1052 | USE_HEADERMAP = NO; 1053 | }; 1054 | name = Release; 1055 | }; 1056 | OBJ_42 /* Debug */ = { 1057 | isa = XCBuildConfiguration; 1058 | buildSettings = { 1059 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1060 | FRAMEWORK_SEARCH_PATHS = ( 1061 | "$(inherited)", 1062 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 1063 | ); 1064 | HEADER_SEARCH_PATHS = "$(inherited)"; 1065 | INFOPLIST_FILE = MultipartFormDataKit.xcodeproj/MultipartFormDataKitTests_Info.plist; 1066 | LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/Frameworks"; 1067 | OTHER_LDFLAGS = "$(inherited)"; 1068 | OTHER_SWIFT_FLAGS = "$(inherited)"; 1069 | SWIFT_VERSION = 4.0; 1070 | TARGET_NAME = MultipartFormDataKitTests; 1071 | }; 1072 | name = Debug; 1073 | }; 1074 | OBJ_43 /* Release */ = { 1075 | isa = XCBuildConfiguration; 1076 | buildSettings = { 1077 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1078 | FRAMEWORK_SEARCH_PATHS = ( 1079 | "$(inherited)", 1080 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 1081 | ); 1082 | HEADER_SEARCH_PATHS = "$(inherited)"; 1083 | INFOPLIST_FILE = MultipartFormDataKit.xcodeproj/MultipartFormDataKitTests_Info.plist; 1084 | LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/Frameworks"; 1085 | OTHER_LDFLAGS = "$(inherited)"; 1086 | OTHER_SWIFT_FLAGS = "$(inherited)"; 1087 | SWIFT_VERSION = 4.0; 1088 | TARGET_NAME = MultipartFormDataKitTests; 1089 | }; 1090 | name = Release; 1091 | }; 1092 | OBJ_57 /* Debug */ = { 1093 | isa = XCBuildConfiguration; 1094 | buildSettings = { 1095 | ENABLE_TESTABILITY = YES; 1096 | FRAMEWORK_SEARCH_PATHS = ( 1097 | "$(inherited)", 1098 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 1099 | ); 1100 | HEADER_SEARCH_PATHS = "$(inherited)"; 1101 | INFOPLIST_FILE = MultipartFormDataKit.xcodeproj/MultipartFormDataKit_Info.plist; 1102 | LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; 1103 | OTHER_LDFLAGS = "$(inherited)"; 1104 | OTHER_SWIFT_FLAGS = "$(inherited)"; 1105 | PRODUCT_BUNDLE_IDENTIFIER = MultipartFormDataKit; 1106 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 1107 | PRODUCT_NAME = MultipartFormDataKit; 1108 | SKIP_INSTALL = YES; 1109 | SWIFT_VERSION = 4.0; 1110 | TARGET_NAME = MultipartFormDataKit; 1111 | }; 1112 | name = Debug; 1113 | }; 1114 | OBJ_58 /* Release */ = { 1115 | isa = XCBuildConfiguration; 1116 | buildSettings = { 1117 | ENABLE_TESTABILITY = YES; 1118 | FRAMEWORK_SEARCH_PATHS = ( 1119 | "$(inherited)", 1120 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 1121 | ); 1122 | HEADER_SEARCH_PATHS = "$(inherited)"; 1123 | INFOPLIST_FILE = MultipartFormDataKit.xcodeproj/MultipartFormDataKit_Info.plist; 1124 | LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; 1125 | OTHER_LDFLAGS = "$(inherited)"; 1126 | OTHER_SWIFT_FLAGS = "$(inherited)"; 1127 | PRODUCT_BUNDLE_IDENTIFIER = MultipartFormDataKit; 1128 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 1129 | PRODUCT_NAME = MultipartFormDataKit; 1130 | SKIP_INSTALL = YES; 1131 | SWIFT_VERSION = 4.0; 1132 | TARGET_NAME = MultipartFormDataKit; 1133 | }; 1134 | name = Release; 1135 | }; 1136 | OBJ_75 /* Debug */ = { 1137 | isa = XCBuildConfiguration; 1138 | buildSettings = { 1139 | }; 1140 | name = Debug; 1141 | }; 1142 | OBJ_76 /* Release */ = { 1143 | isa = XCBuildConfiguration; 1144 | buildSettings = { 1145 | }; 1146 | name = Release; 1147 | }; 1148 | /* End XCBuildConfiguration section */ 1149 | 1150 | /* Begin XCConfigurationList section */ 1151 | 621346A31FA60C4500DD098E /* Build configuration list for PBXNativeTarget "MultipartFormDataKit-iOS" */ = { 1152 | isa = XCConfigurationList; 1153 | buildConfigurations = ( 1154 | 621346A41FA60C4500DD098E /* Debug */, 1155 | 621346A51FA60C4500DD098E /* Release */, 1156 | ); 1157 | defaultConfigurationIsVisible = 0; 1158 | defaultConfigurationName = Debug; 1159 | }; 1160 | 621346B01FA60CCC00DD098E /* Build configuration list for PBXNativeTarget "MultipartFormDataKit-watchOS" */ = { 1161 | isa = XCConfigurationList; 1162 | buildConfigurations = ( 1163 | 621346B11FA60CCC00DD098E /* Debug */, 1164 | 621346B21FA60CCC00DD098E /* Release */, 1165 | ); 1166 | defaultConfigurationIsVisible = 0; 1167 | defaultConfigurationName = Debug; 1168 | }; 1169 | 621346BD1FA60D0800DD098E /* Build configuration list for PBXNativeTarget "MultipartFormDataKit-tvOS" */ = { 1170 | isa = XCConfigurationList; 1171 | buildConfigurations = ( 1172 | 621346BE1FA60D0800DD098E /* Debug */, 1173 | 621346BF1FA60D0800DD098E /* Release */, 1174 | ); 1175 | defaultConfigurationIsVisible = 0; 1176 | defaultConfigurationName = Debug; 1177 | }; 1178 | OBJ_2 /* Build configuration list for PBXProject "MultipartFormDataKit" */ = { 1179 | isa = XCConfigurationList; 1180 | buildConfigurations = ( 1181 | OBJ_3 /* Debug */, 1182 | OBJ_4 /* Release */, 1183 | ); 1184 | defaultConfigurationIsVisible = 0; 1185 | defaultConfigurationName = Debug; 1186 | }; 1187 | OBJ_35 /* Build configuration list for PBXNativeTarget "MultipartFormDataKitPackageDescription" */ = { 1188 | isa = XCConfigurationList; 1189 | buildConfigurations = ( 1190 | OBJ_36 /* Debug */, 1191 | OBJ_37 /* Release */, 1192 | ); 1193 | defaultConfigurationIsVisible = 0; 1194 | defaultConfigurationName = Debug; 1195 | }; 1196 | OBJ_41 /* Build configuration list for PBXNativeTarget "MultipartFormDataKitTests" */ = { 1197 | isa = XCConfigurationList; 1198 | buildConfigurations = ( 1199 | OBJ_42 /* Debug */, 1200 | OBJ_43 /* Release */, 1201 | ); 1202 | defaultConfigurationIsVisible = 0; 1203 | defaultConfigurationName = Debug; 1204 | }; 1205 | OBJ_56 /* Build configuration list for PBXNativeTarget "MultipartFormDataKit-macOS" */ = { 1206 | isa = XCConfigurationList; 1207 | buildConfigurations = ( 1208 | OBJ_57 /* Debug */, 1209 | OBJ_58 /* Release */, 1210 | ); 1211 | defaultConfigurationIsVisible = 0; 1212 | defaultConfigurationName = Debug; 1213 | }; 1214 | OBJ_74 /* Build configuration list for PBXAggregateTarget "MultipartFormDataKitPackageTests" */ = { 1215 | isa = XCConfigurationList; 1216 | buildConfigurations = ( 1217 | OBJ_75 /* Debug */, 1218 | OBJ_76 /* Release */, 1219 | ); 1220 | defaultConfigurationIsVisible = 0; 1221 | defaultConfigurationName = Debug; 1222 | }; 1223 | /* End XCConfigurationList section */ 1224 | }; 1225 | rootObject = OBJ_1 /* Project object */; 1226 | } 1227 | -------------------------------------------------------------------------------- /MultipartFormDataKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MultipartFormDataKit.xcodeproj/xcshareddata/xcschemes/MultipartFormDataKit-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 74 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /MultipartFormDataKit.xcodeproj/xcshareddata/xcschemes/MultipartFormDataKit-macOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 57 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 76 | 78 | 79 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /MultipartFormDataKit.xcodeproj/xcshareddata/xcschemes/MultipartFormDataKit-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /MultipartFormDataKit.xcodeproj/xcshareddata/xcschemes/MultipartFormDataKit-watchOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /MultipartFormDataKit.xcodeproj/xcshareddata/xcschemes/MultipartFormDataKitTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 57 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 76 | 78 | 79 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /MultipartFormDataKit.xcodeproj/xcshareddata/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SchemeUserState 5 | 6 | MultipartFormDataKit-Package.xcscheme 7 | 8 | 9 | SuppressBuildableAutocreation 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.6 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "MultipartFormDataKit", 8 | products: [ 9 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 10 | .library( 11 | name: "MultipartFormDataKit", 12 | targets: ["MultipartFormDataKit"]), 13 | ], 14 | dependencies: [ 15 | // Dependencies declare other packages that this package depends on. 16 | // .package(url: /* package url */, from: "1.0.0"), 17 | ], 18 | targets: [ 19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 20 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 21 | .target( 22 | name: "MultipartFormDataKit", 23 | dependencies: []), 24 | .testTarget( 25 | name: "MultipartFormDataKitTests", 26 | dependencies: ["MultipartFormDataKit"]), 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MultipartFormDataKit 2 | ==================== 3 | 4 | ![Swift 5.6 compatible](https://img.shields.io/badge/Swift%20version-5.6-green.svg) 5 | ![Swift Package Manager and Carthage and CocoaPods compatible](https://img.shields.io/badge/SPM%20%7C%20Carthage%20%7C%20CocoaPods-compatible-green.svg) 6 | [![v2.0.0](https://img.shields.io/badge/version-2.0.0-blue.svg)](https://github.com/Kuniwak/MultipartFormData/releases) 7 | [![Build Status](https://www.bitrise.io/app/8c05b2758bfbf0d8/status.svg?token=vqY7qlmU6qeCPZ17EX7vRA&branch=master)](https://www.bitrise.io/app/8c05b2758bfbf0d8) 8 | 9 | 10 | `multipart/form-data` for Swift. 11 | 12 | 13 | Basic Usage 14 | ----------- 15 | 16 | ```swift 17 | let multipartFormData = try MultipartFormData.Builder.build( 18 | with: [ 19 | ( 20 | name: "example1", 21 | filename: nil, 22 | mimeType: nil, 23 | data: "Hello, World!".data(using: .utf8)! 24 | ), 25 | ( 26 | name: "example2", 27 | filename: "example.txt", 28 | mimeType: MIMEType.textPlain, 29 | data: "EXAMPLE_TXT".data(using: .utf8)! 30 | ), 31 | ], 32 | willSeparateBy: RandomBoundaryGenerator.generate() 33 | ) 34 | 35 | var request = URLRequest(url: URL(string: "http://example.com")!) 36 | request.httpMethod = "POST" 37 | request.setValue(multipartFormData.contentType, forHTTPHeaderField: "Content-Type") 38 | request.httpBody = multipartFormData.body 39 | 40 | let task = URLSession.shared.dataTask(with: request) 41 | task.resume() 42 | ``` 43 | 44 | 45 | 46 | Advanced Usage 47 | -------------- 48 | 49 | ```swift 50 | let multipartFormData = MultipartFormData( 51 | uniqueAndValidLengthBoundary: "boundary", 52 | body: [ 53 | MultipartFormData.Part( 54 | contentDisposition: ContentDisposition( 55 | name: Name(asPercentEncoded: "field%201"), 56 | filename: nil 57 | ), 58 | contentType: nil, 59 | content: "value1".data(using: .utf8)! 60 | ), 61 | MultipartFormData.Part( 62 | contentDisposition: ContentDisposition( 63 | name: Name(asPercentEncoded: "field%202"), 64 | filename: Filename(asPercentEncoded: "example.txt") 65 | ), 66 | contentType: ContentType(representing: .textPlain), 67 | content: "value2".data(using: .utf8)! 68 | ), 69 | ] 70 | ) 71 | 72 | print(multipartFormData.header.name) 73 | // Content-Type 74 | 75 | print(multipartFormData.header.value) 76 | // multipart/form-data; boundary="boundary" 77 | 78 | switch multipartFormData.asData() { 79 | case let .valid(data): 80 | print(String(data: data, encoding: .utf8)) 81 | 82 | // --boundary 83 | // Content-Disposition: form-data; name="field1" 84 | // 85 | // value1 86 | // --boundary 87 | // Content-Disposition: form-data; name="filed2"; filename="example.txt" 88 | // Content-Type: text/plain 89 | // 90 | // value2 91 | // --boundary-- 92 | 93 | case let .invalid(error): 94 | print(error) 95 | } 96 | ``` 97 | 98 | 99 | License 100 | ------- 101 | 102 | MIT 103 | -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/BoundaryGenerator.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | 5 | public protocol BoundaryGenerator { 6 | static func generate() -> String 7 | } 8 | 9 | 10 | 11 | public class RandomBoundaryGenerator: BoundaryGenerator { 12 | public static func generate() -> String { 13 | return String(format: "%08x%08x", UInt32.random(in: 0...UInt32.max), UInt32.random(in: 0...UInt32.max)) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/CRLF.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | 5 | let CRLF: Data = "\r\n".data(using: .ascii)! -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/ContentDisposition.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | 5 | // RFC 7528 multipart/form-data 6 | // 4.2. Content-Disposition Header Field for Each Part 7 | public struct ContentDisposition { 8 | // Each part MUST contain a Content-Disposition header field [RFC2183] 9 | // where the disposition type is "form-data". 10 | public var value: String { 11 | return "form-data" 12 | } 13 | 14 | // Each part MUST contain a Content-Disposition header field [RFC2183] 15 | // where the disposition type is "form-data". The Content-Disposition 16 | // header field MUST also contain an additional parameter of "name"; the 17 | // value of the "name" parameter is the original field name from the 18 | // form (possibly encoded; see Section 5.1). For example, a part might 19 | // contain a header field such as the following, with the body of the 20 | // part containing the form data of the "user" field: 21 | // 22 | // Content-Disposition: form-data; name="user" 23 | // 24 | public var name: Name 25 | 26 | // For form data that represents the content of a file, a name for the 27 | // file SHOULD be supplied as well, by using a "filename" parameter of 28 | // the Content-Disposition header field. The file name isn't mandatory 29 | // for cases where the file name isn't available or is meaningless or 30 | // private; this might result, for example, when selection or drag-and- 31 | // drop is used or when the form data content is streamed directly from 32 | // a device. 33 | public var filename: Filename? 34 | 35 | 36 | public init(name: Name, filename: Filename?) { 37 | self.name = name 38 | self.filename = filename 39 | } 40 | 41 | 42 | public func asHeader() -> Header { 43 | var parameters: [Parameter] = [ 44 | Parameter( 45 | attribute: "name", 46 | value: self.name.percentEncodedString 47 | ), 48 | ] 49 | 50 | if let filename = self.filename { 51 | parameters.append(Parameter( 52 | attribute: "filename", 53 | value: filename.percentEncodedString 54 | )) 55 | } 56 | 57 | return .from(value: self.value, parameters: parameters) 58 | } 59 | 60 | 61 | public func asData() -> ValidationResult { 62 | let headerText = self.asHeader().text 63 | guard let data = headerText.data(using: .utf8) else { 64 | return .invalid(because: .cannotEncodeAsUTF8(debugInfo: headerText)) 65 | } 66 | 67 | return .valid(data) 68 | } 69 | 70 | 71 | 72 | public struct Header /* : CustomStringConvertible */ { 73 | public var name: String { 74 | return "Content-Disposition" 75 | } 76 | public let value: String 77 | 78 | 79 | public var text: String { 80 | return "\(self.name): \(self.value)" 81 | } 82 | 83 | 84 | public init(representing value: String) { 85 | self.value = value 86 | } 87 | 88 | 89 | public static func from(value: String, parameters: [Parameter]) -> Header { 90 | let parametersPart = parameters 91 | .map { "; \($0.text)" } 92 | .joined(separator: "") 93 | 94 | return Header(representing: "\(value)\(parametersPart)") 95 | } 96 | } 97 | 98 | 99 | 100 | public struct Parameter /* : CustomStringConvertible */ { 101 | public let attribute: String 102 | public let value: String 103 | 104 | 105 | public var text: String { 106 | return "\(self.attribute)=\"\(self.value)\"" 107 | } 108 | } 109 | 110 | 111 | 112 | public enum DataTransformError: Error { 113 | case cannotEncodeAsUTF8(debugInfo: String) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/ContentType.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | 5 | // RFC 7528 multipart/form-data 6 | // 4.4. Content-Type Header Field for Each Part 7 | public struct ContentType { 8 | // Each part MAY have an (optional) "Content-Type" header field, which 9 | // defaults to "text/plain". If the contents of a file are to be sent, 10 | // the file data SHOULD be labeled with an appropriate media type, if 11 | // known, or "application/octet-stream". 12 | public var value: MIMEType 13 | public var parameters: [Parameter] 14 | 15 | 16 | public init(representing value: MIMEType, with parameters: [Parameter] = []) { 17 | self.value = value 18 | self.parameters = parameters 19 | } 20 | 21 | 22 | public func asHeader() -> Header { 23 | return .from( 24 | mimeType: self.value, 25 | parameters: self.parameters 26 | ) 27 | } 28 | 29 | 30 | 31 | public func asData() -> ValidationResult { 32 | let headerText = self.asHeader().text 33 | guard let data = headerText.data(using: .utf8) else { 34 | return .invalid(because: .cannotEncodeAsUTF8(debugInfo: headerText)) 35 | } 36 | 37 | return .valid(data) 38 | } 39 | 40 | 41 | 42 | public struct Header /* : CustomStringConvertible */ { 43 | public var name: String { 44 | return "Content-Type" 45 | } 46 | public var value: String 47 | 48 | 49 | public var text: String { 50 | return "\(self.name): \(self.value)" 51 | } 52 | 53 | 54 | public init(representing value: String) { 55 | self.value = value 56 | } 57 | 58 | 59 | public static func from(mimeType: MIMEType, parameters: [Parameter]) -> Header { 60 | let parametersPart = parameters 61 | .map { "; \($0.text)" } 62 | .joined(separator: "") 63 | 64 | return Header(representing: "\(mimeType.text)\(parametersPart)") 65 | } 66 | } 67 | 68 | 69 | 70 | public struct Parameter /* : CustomStringConvertible */ { 71 | public var attribute: String 72 | public var value: String 73 | 74 | public var text: String { 75 | return "\(self.attribute)=\"\(self.value)\"" 76 | } 77 | } 78 | 79 | 80 | 81 | public enum DataTransformError: Error { 82 | case cannotEncodeAsUTF8(debugInfo: String) 83 | } 84 | } -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/Dash.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | 5 | let DASH = "--".data(using: .utf8)! -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/Filename.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | // RFC 7528 multipart/form-data 5 | // 4.2. Content-Disposition Header Field for Each Part 6 | // 7 | // ... 8 | // 9 | // If a "filename" parameter is supplied, the requirements of 10 | // Section 2.3 of [RFC2183] for the "receiving MUA" (i.e., the receiving 11 | // Mail User Agent) apply to receivers of multipart/form-data as well: 12 | // do not use the file name blindly, check and possibly change to match 13 | // local file system conventions if applicable, and do not use directory 14 | // path information that may be present. 15 | // In most multipart types, the MIME header fields in each part are 16 | // restricted to US-ASCII; for compatibility with those systems, file 17 | // names normally visible to users MAY be encoded using the percent- 18 | // encoding method in Section 2, following how a "file:" URI 19 | // [URI-SCHEME] might be encoded. 20 | // 21 | // ... 22 | public struct Filename { 23 | public let percentEncodedString: String 24 | 25 | 26 | public init(asPercentEncoded percentEncodedString: String) { 27 | self.percentEncodedString = percentEncodedString 28 | } 29 | 30 | 31 | public static func create(by filename: String) -> ValidationResult { 32 | guard let percentEncodedString = filename.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { 33 | return .invalid(because: .cannotPercentEncode(debugInfo: filename)) 34 | } 35 | 36 | return .valid(Filename(asPercentEncoded: percentEncodedString)) 37 | } 38 | 39 | 40 | public enum FailureReason: Error { 41 | case cannotPercentEncode(debugInfo: String) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/MIMEType.swift: -------------------------------------------------------------------------------- 1 | public struct MIMEType { 2 | public var text: String 3 | 4 | public init(text: String) { 5 | self.text = text 6 | } 7 | 8 | public static var multipartFormData = MIMEType(text: "multipart/form-data") 9 | 10 | public static var textPlain = MIMEType(text: "text/plain") 11 | public static var textHtml = MIMEType(text: "text/html") 12 | public static var textCss = MIMEType(text: "text/css") 13 | public static var textJavascript = MIMEType(text: "text/javascript") 14 | 15 | public static var imageGif = MIMEType(text: "image/gif") 16 | public static var imagePng = MIMEType(text: "image/png") 17 | public static var imageJpeg = MIMEType(text: "image/jpeg") 18 | public static var imageBmp = MIMEType(text: "image/bmp") 19 | public static var imageWebp = MIMEType(text: "image/webp") 20 | public static var imageSvgXml = MIMEType(text: "image/svg+xml") 21 | 22 | public static var audioAudio = MIMEType(text: "audio/midi") 23 | public static var audioMpeg = MIMEType(text: "audio/mpeg") 24 | public static var audioWebm = MIMEType(text: "audio/webm") 25 | public static var audioOgg = MIMEType(text: "audio/ogg") 26 | public static var audioWav = MIMEType(text: "audio/wav") 27 | 28 | public static var videoWebm = MIMEType(text: "video/webm") 29 | public static var videoOgg = MIMEType(text: "video/ogg") 30 | 31 | public static var applicationOctetStream = MIMEType(text: "application/octet-stream") 32 | public static var applicationXml = MIMEType(text: "application/xml") 33 | public static var applicationJson = MIMEType(text: "application/json") 34 | } -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/MultipartFormData+Builder.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | 5 | extension MultipartFormData { 6 | public typealias PartParam = ( 7 | name: String, 8 | filename: String?, 9 | mimeType: MIMEType?, 10 | data: Data 11 | ) 12 | 13 | 14 | 15 | public enum Builder { 16 | public static func build( 17 | with partParams: [PartParam], 18 | willSeparateBy uniqueBoundary: String 19 | ) throws -> BuildResult { 20 | switch TypedBuilder.build(with: partParams, willSeparateBy: uniqueBoundary) { 21 | case let .invalid(because: error): 22 | throw error 23 | 24 | case let .valid(result): 25 | return result 26 | } 27 | } 28 | } 29 | 30 | 31 | 32 | public enum TypedBuilder { 33 | public static func build( 34 | with partParams: [PartParam], 35 | willSeparateBy uniqueBoundary: String 36 | ) -> ValidationResult { 37 | var validParts = [MultipartFormData.Part]() 38 | for partParam in partParams { 39 | switch MultipartFormData.Part.create( 40 | name: partParam.name, 41 | filename: partParam.filename, 42 | mimeType: partParam.mimeType, 43 | data: partParam.data 44 | ) { 45 | case let .valid(part): 46 | validParts.append(part) 47 | 48 | case let .invalid(because: reason): 49 | return .invalid(because: .partCreationError(reason)) 50 | } 51 | } 52 | 53 | let multipartFormData = MultipartFormData( 54 | uniqueAndValidLengthBoundary: uniqueBoundary, 55 | body: validParts 56 | ) 57 | 58 | switch multipartFormData.asData() { 59 | case let .valid(data): 60 | return .valid(BuildResult( 61 | contentType: multipartFormData.header.value, 62 | body: data 63 | )) 64 | 65 | case let .invalid(because: reason): 66 | return .invalid(because: .dataTransformError(reason)) 67 | } 68 | } 69 | } 70 | 71 | 72 | 73 | public enum BuildError: Error { 74 | case partCreationError(MultipartFormData.Part.CreationError) 75 | case dataTransformError(MultipartFormData.DataTransformError) 76 | } 77 | 78 | 79 | 80 | public struct BuildResult { 81 | public let contentType: String 82 | public let body: Data 83 | 84 | 85 | public init(contentType: String, body: Data) { 86 | self.contentType = contentType 87 | self.body = body 88 | } 89 | } 90 | } 91 | 92 | 93 | 94 | extension MultipartFormData.BuildResult: Equatable { 95 | public static func ==( 96 | lhs: MultipartFormData.BuildResult, 97 | rhs: MultipartFormData.BuildResult 98 | ) -> Bool { 99 | return lhs.contentType == rhs.contentType 100 | && lhs.body == rhs.body 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/MultipartFormData+Part.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | 5 | extension MultipartFormData { 6 | public struct Part { 7 | public let contentDisposition: ContentDisposition 8 | public let contentType: ContentType? 9 | public let content: Data 10 | 11 | 12 | public init( 13 | contentDisposition: ContentDisposition, 14 | contentType: ContentType?, 15 | content: Data 16 | ) { 17 | self.contentDisposition = contentDisposition 18 | self.contentType = contentType 19 | self.content = content 20 | } 21 | 22 | 23 | // RFC 2046 Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types 24 | // 5.1.1. Common Syntax 25 | // 26 | // ... 27 | // 28 | // This Content-Type value indicates that the content consists of one or 29 | // more parts, each with a structure that is syntactically identical to 30 | // an RFC 822 message, except that the header area is allowed to be 31 | // completely empty, and that the parts are each preceded by the line 32 | // 33 | // --gc0pJq0M:08jU534c0p 34 | // 35 | // The boundary delimiter MUST occur at the beginning of a line, i.e., 36 | // following a CRLF, and the initial CRLF is considered to be attached 37 | // to the boundary delimiter line rather than part of the preceding 38 | // part. The boundary may be followed by zero or more characters of 39 | // linear whitespace. It is then terminated by either another CRLF and 40 | // the header fields for the next part, or by two CRLFs, in which case 41 | // there are no header fields for the next part. If no Content-Type 42 | // field is present it is assumed to be "message/rfc822" in a 43 | // "multipart/digest" and "text/plain" otherwise. 44 | public func write(to data: inout Data) -> DataTransformError? { 45 | guard let contentType = self.contentType else { 46 | switch self.contentDisposition.asData() { 47 | case let .valid(contentDispositionData): 48 | data.append(contentDispositionData) 49 | data.append(CRLF) 50 | data.append(CRLF) 51 | data.append(self.content) 52 | data.append(CRLF) 53 | return nil 54 | 55 | case let .invalid(because: error): 56 | return .contentDispositionError(error) 57 | } 58 | } 59 | 60 | switch ( 61 | self.contentDisposition.asData(), 62 | contentType.asData() 63 | ) { 64 | case let (.valid(contentDispositionData), .valid(contentTypeData)): 65 | data.append(contentDispositionData) 66 | data.append(CRLF) 67 | data.append(contentTypeData) 68 | data.append(CRLF) 69 | data.append(CRLF) 70 | data.append(self.content) 71 | data.append(CRLF) 72 | return nil 73 | 74 | case let (.invalid(because: error), _): 75 | return .contentDispositionError(error) 76 | 77 | case let (_, .invalid(because: error)): 78 | return .contentTypeError(error) 79 | } 80 | } 81 | 82 | 83 | 84 | public static func create( 85 | name: String, 86 | filename: String?, 87 | mimeType: MIMEType?, 88 | data: Data 89 | ) -> ValidationResult { 90 | guard let filename = filename else { 91 | switch Name.create(by: name) { 92 | case let .valid(name): 93 | return .valid( 94 | MultipartFormData.Part( 95 | contentDisposition: ContentDisposition( 96 | name: name, 97 | filename: nil 98 | ), 99 | contentType: mimeType.map { mimeType in 100 | ContentType(representing: mimeType) 101 | }, 102 | content: data 103 | ) 104 | ) 105 | 106 | case let .invalid(because: error): 107 | return .invalid(because: .invalidName(error)) 108 | } 109 | } 110 | 111 | switch ( 112 | Name.create(by: name), 113 | Filename.create(by: filename) 114 | ) { 115 | case let (.valid(name), .valid(filename)): 116 | return .valid(MultipartFormData.Part( 117 | contentDisposition: ContentDisposition( 118 | name: name, 119 | filename: filename 120 | ), 121 | contentType: mimeType.map { mimeType in 122 | ContentType(representing: mimeType) 123 | }, 124 | content: data 125 | )) 126 | 127 | case let (.invalid(because: reason), _): 128 | return .invalid(because: .invalidName(reason)) 129 | 130 | case let (_, .invalid(because: reason)): 131 | return .invalid(because: .invalidFilename(reason)) 132 | } 133 | } 134 | 135 | 136 | 137 | public enum CreationError: Error { 138 | case invalidName(Name.FailureReason) 139 | case invalidFilename(Filename.FailureReason) 140 | } 141 | } 142 | } -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/MultipartFormData.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | 5 | // RFC 7528 multipart/form-data 6 | // 4. Definition of multipart/form-data 7 | // 8 | // The media type multipart/form-data follows the model of multipart 9 | // MIME data streams as specified in Section 5.1 of [RFC2046]; changes 10 | // are noted in this document. 11 | // 12 | // A multipart/form-data body contains a series of parts separated by a 13 | // boundary. 14 | public struct MultipartFormData { 15 | public var header: ContentType.Header { 16 | return .from( 17 | mimeType: .multipartFormData, 18 | parameters: [ 19 | ContentType.Parameter( 20 | attribute: "boundary", 21 | value: self.uniqueAndValidLengthBoundary 22 | ), 23 | ] 24 | ) 25 | } 26 | 27 | 28 | // 4.1. "Boundary" Parameter of multipart/form-data 29 | // 30 | // As with other multipart types, the parts are delimited with a 31 | // boundary delimiter, constructed using CRLF, "--", and the value of 32 | // the "boundary" parameter. The boundary is supplied as a "boundary" 33 | // parameter to the multipart/form-data type. As noted in Section 5.1 34 | // of [RFC2046], the boundary delimiter MUST NOT appear inside any of 35 | // the encapsulated parts, and it is often necessary to enclose the 36 | // "boundary" parameter values in quotes in the Content-Type header 37 | // field. 38 | public let uniqueAndValidLengthBoundary: String 39 | public let body: [Part] 40 | 41 | 42 | // Boundary delimiters must not appear within the encapsulated material, 43 | // and must be no longer than 70 characters, not counting the two 44 | // leading hyphens. 45 | public static let maxLengthOfBoundary = 70 46 | 47 | 48 | public init( 49 | uniqueAndValidLengthBoundary: String, 50 | body: [Part] 51 | ) { 52 | self.uniqueAndValidLengthBoundary = uniqueAndValidLengthBoundary 53 | self.body = body 54 | } 55 | 56 | 57 | public func asData() -> ValidationResult { 58 | var data = Data() 59 | guard let boundaryData = self.uniqueAndValidLengthBoundary.data(using: .utf8) else { 60 | return .invalid(because: .boundaryError(debugInfo: self.uniqueAndValidLengthBoundary)) 61 | } 62 | 63 | for part in self.body { 64 | data.append(DASH) 65 | data.append(boundaryData) 66 | data.append(CRLF) 67 | if let error = part.write(to: &data) { 68 | return .invalid(because: error) 69 | } 70 | } 71 | 72 | data.append(DASH) 73 | data.append(boundaryData) 74 | data.append(DASH) 75 | data.append(CRLF) 76 | 77 | return .valid(data) 78 | } 79 | 80 | 81 | 82 | public enum DataTransformError: Error { 83 | case contentDispositionError(ContentDisposition.DataTransformError) 84 | case contentTypeError(ContentType.DataTransformError) 85 | case boundaryError(debugInfo: String) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/Name.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | 5 | public struct Name { 6 | public let percentEncodedString: String 7 | 8 | 9 | public init(asPercentEncoded percentEncodedString: String) { 10 | self.percentEncodedString = percentEncodedString 11 | } 12 | 13 | 14 | public static func create(by filename: String) -> ValidationResult { 15 | guard let percentEncodedString = filename.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { 16 | return .invalid(because: .cannotPercentEncode(debugInfo: filename)) 17 | } 18 | 19 | return .valid(Name(asPercentEncoded: percentEncodedString)) 20 | } 21 | 22 | 23 | public enum FailureReason: Error { 24 | case cannotPercentEncode(debugInfo: String) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/MultipartFormDataKit/ValidationResult.swift: -------------------------------------------------------------------------------- 1 | public enum ValidationResult { 2 | case valid(Content) 3 | case invalid(because: FailureReason) 4 | 5 | 6 | public var content: Content? { 7 | switch self { 8 | case let .valid(content): 9 | return content 10 | 11 | case .invalid: 12 | return nil 13 | } 14 | } 15 | 16 | 17 | public var reason: FailureReason? { 18 | switch self { 19 | case .valid: 20 | return nil 21 | case let .invalid(because: reason): 22 | return reason 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import MultipartFormDataKitTests 3 | 4 | XCTMain([ 5 | testCase(MultipartFormDataTests.allTests), 6 | testCase(ContentDispositionTests.allTests), 7 | testCase(ContentTypeTests.allTests), 8 | testCase(FilenameTests.allTests), 9 | testCase(NameTests.allTests), 10 | testCase(MultipartFormDataBuilderTests.allTests), 11 | ]) 12 | -------------------------------------------------------------------------------- /Tests/MultipartFormDataKitTests/CompatibilityTests.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | import MultipartFormDataKit 4 | 5 | 6 | class CompatibilityTests: XCTestCase { 7 | // You can test compatibility by communicating to the actual server by 8 | // disabling this skip flag. If you have no any server that can take 9 | // multipart/form-data, you can use `Assets/CompatibilityTests/Server/index.js`. 10 | // This server can start by the following command: 11 | // 12 | // $ cd Assets/CompatibilityTests/Server/index.js 13 | // $ npm install 14 | // $ node index.js 15 | // Listening on http://localhost:8080 16 | // 17 | let skip = true 18 | let serverURLString = "http://localhost:8080/echo" 19 | 20 | 21 | func testEmpty() throws { 22 | guard !self.skip else { return } 23 | 24 | let multipartFormData = try MultipartFormData.Builder.build( 25 | with: [], 26 | willSeparateBy: RandomBoundaryGenerator.generate() 27 | ) 28 | var request = URLRequest(url: URL(string: self.serverURLString)!) 29 | 30 | request.httpMethod = "POST" 31 | request.addValue(multipartFormData.contentType, forHTTPHeaderField: "Content-Type") 32 | request.httpBody = multipartFormData.body 33 | 34 | self.assertSuccessfulResponse(request: request) 35 | } 36 | 37 | 38 | func testSingle() throws { 39 | guard !self.skip else { return } 40 | 41 | let multipartFormData = try MultipartFormData.Builder.build( 42 | with: [ 43 | ( 44 | name: "example", 45 | filename: "example.txt", 46 | mimeType: MIMEType.textPlain, 47 | data: "EXAMPLE_TXT".data(using: .utf8)! 48 | ), 49 | ], 50 | willSeparateBy: RandomBoundaryGenerator.generate() 51 | ) 52 | var request = URLRequest(url: URL(string: self.serverURLString)!) 53 | 54 | request.httpMethod = "POST" 55 | request.addValue(multipartFormData.contentType, forHTTPHeaderField: "Content-Type") 56 | request.httpBody = multipartFormData.body 57 | 58 | self.assertSuccessfulResponse(request: request) 59 | } 60 | 61 | 62 | func testDouble() throws { 63 | guard !self.skip else { return } 64 | 65 | let multipartFormData = try MultipartFormData.Builder.build( 66 | with: [ 67 | ( 68 | name: "text", 69 | filename: nil, 70 | mimeType: nil, 71 | data: "EXAMPLE_TXT".data(using: .utf8)! 72 | ), 73 | ( 74 | name: "example", 75 | filename: "example.txt", 76 | mimeType: MIMEType.textPlain, 77 | data: "EXAMPLE_TXT".data(using: .utf8)! 78 | ), 79 | ], 80 | willSeparateBy: RandomBoundaryGenerator.generate() 81 | ) 82 | var request = URLRequest(url: URL(string: self.serverURLString)!) 83 | 84 | request.httpMethod = "POST" 85 | request.addValue(multipartFormData.contentType, forHTTPHeaderField: "Content-Type") 86 | request.httpBody = multipartFormData.body 87 | 88 | self.assertSuccessfulResponse(request: request) 89 | } 90 | 91 | 92 | 93 | func assertSuccessfulResponse(request: URLRequest) { 94 | let expectation = self.expectation(description: "awaiting \(self.serverURLString)") 95 | 96 | let task = URLSession.shared.dataTask(with: request) { data, response, error in 97 | guard let data = data, let response = response as? HTTPURLResponse else { 98 | XCTFail(error.debugDescription) 99 | expectation.fulfill() 100 | return 101 | } 102 | 103 | XCTAssertEqual(response.statusCode, 200) 104 | 105 | print(String(data: data, encoding: .utf8)!) 106 | 107 | expectation.fulfill() 108 | } 109 | task.resume() 110 | 111 | self.waitForExpectations(timeout: 10) 112 | } 113 | 114 | 115 | 116 | static var allTests: [(String, (CompatibilityTests) -> () throws -> Void)] { 117 | return [ 118 | ("testEmpty", self.testEmpty), 119 | ("testSingle", self.testSingle), 120 | ("testDouble", self.testDouble), 121 | ] 122 | } 123 | } 124 | 125 | -------------------------------------------------------------------------------- /Tests/MultipartFormDataKitTests/ContentDispositionTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import MultipartFormDataKit 3 | 4 | 5 | class ContentDispositionTests: XCTestCase { 6 | private struct TestCase { 7 | let contentDisposition: ContentDisposition 8 | let expected: String 9 | } 10 | 11 | 12 | func testAsHeader() { 13 | let testCases: [UInt: TestCase] = [ 14 | #line: TestCase( 15 | contentDisposition: ContentDisposition( 16 | name: Name(asPercentEncoded: "name"), 17 | filename: nil 18 | ), 19 | expected: "Content-Disposition: form-data; name=\"name\"" 20 | ), 21 | #line: TestCase( 22 | contentDisposition: ContentDisposition( 23 | name: Name(asPercentEncoded: "name"), 24 | filename: Filename(asPercentEncoded: "filename") 25 | ), 26 | expected: "Content-Disposition: form-data; name=\"name\"; filename=\"filename\"" 27 | ), 28 | ] 29 | 30 | 31 | testCases.forEach { (line, testCase) in 32 | let actual = testCase.contentDisposition.asHeader() 33 | let expected = testCase.expected 34 | 35 | XCTAssertEqual(actual.text, expected) 36 | } 37 | } 38 | 39 | 40 | static var allTests: [(String, (ContentDispositionTests) -> () throws -> Void)] { 41 | return [ 42 | ("testAsHeader", self.testAsHeader), 43 | ] 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Tests/MultipartFormDataKitTests/ContentTypeTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import MultipartFormDataKit 3 | 4 | 5 | class ContentTypeTests: XCTestCase { 6 | private struct TestCase { 7 | let contentType: ContentType 8 | let expected: String 9 | } 10 | 11 | 12 | func testAsHeader() { 13 | let testCases: [UInt: TestCase] = [ 14 | #line: TestCase( 15 | contentType: ContentType( 16 | representing: .textPlain 17 | ), 18 | expected: "Content-Type: text/plain" 19 | ), 20 | #line: TestCase( 21 | contentType: ContentType( 22 | representing: .textPlain, 23 | with: [ 24 | ContentType.Parameter(attribute: "charset", value: "UTF-8"), 25 | ] 26 | ), 27 | expected: "Content-Type: text/plain; charset=\"UTF-8\"" 28 | ), 29 | #line: TestCase( 30 | contentType: ContentType( 31 | representing: .textPlain, 32 | with: [ 33 | ContentType.Parameter(attribute: "attr1", value: "value1"), 34 | ContentType.Parameter(attribute: "attr2", value: "value2"), 35 | ] 36 | ), 37 | expected: "Content-Type: text/plain; attr1=\"value1\"; attr2=\"value2\"" 38 | ), 39 | ] 40 | 41 | 42 | testCases.forEach { (line, testCase) in 43 | let actual = testCase.contentType.asHeader() 44 | let expected = testCase.expected 45 | 46 | XCTAssertEqual(actual.text, expected) 47 | } 48 | } 49 | 50 | 51 | static var allTests: [(String, (ContentTypeTests) -> () throws -> Void)] { 52 | return [ 53 | ("testAsHeader", self.testAsHeader), 54 | ] 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Tests/MultipartFormDataKitTests/FilenameTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import MultipartFormDataKit 3 | 4 | 5 | 6 | class FilenameTests: XCTestCase { 7 | private struct TestCase { 8 | let filename: String 9 | let expected: Filename 10 | } 11 | 12 | 13 | func testInit() { 14 | let testCases: [UInt: TestCase] = [ 15 | #line: TestCase( 16 | filename: "abc123ABC", 17 | expected: Filename(asPercentEncoded: "abc123ABC") 18 | ), 19 | #line: TestCase( 20 | filename: "example.jpg", 21 | expected: Filename(asPercentEncoded: "example.jpg") 22 | ), 23 | #line: TestCase( 24 | filename: "=;\"", 25 | expected: Filename(asPercentEncoded: "=%3B%22") 26 | ), 27 | ] 28 | 29 | 30 | testCases.forEach { (line, testCase) in 31 | let actual = Filename.create(by: testCase.filename) 32 | let expected = testCase.expected 33 | 34 | XCTAssertEqual(actual.content?.percentEncodedString, expected.percentEncodedString) 35 | } 36 | } 37 | 38 | 39 | static var allTests: [(String, (FilenameTests) -> () throws -> Void)] { 40 | return [ 41 | ("testInit", self.testInit) 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Tests/MultipartFormDataKitTests/MultipartFormDataBuilderTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import MultipartFormDataKit 3 | 4 | 5 | class MultipartFormDataBuilderTests: XCTestCase { 6 | func testBuild() throws { 7 | let multipartFormData = try MultipartFormData.Builder.build( 8 | with: [ 9 | ( 10 | name: "example1", 11 | filename: nil, 12 | mimeType: nil, 13 | data: "Hello, World!".data(using: .utf8)! 14 | ), 15 | ( 16 | name: "example2", 17 | filename: "example.txt", 18 | mimeType: MIMEType.textPlain, 19 | data: "EXAMPLE_TXT".data(using: .utf8)! 20 | ), 21 | ], 22 | willSeparateBy: "boundary" 23 | ) 24 | 25 | let expected = [ 26 | "--boundary", 27 | "Content-Disposition: form-data; name=\"example1\"", 28 | "", 29 | "Hello, World!", 30 | "--boundary", 31 | "Content-Disposition: form-data; name=\"example2\"; filename=\"example.txt\"", 32 | "Content-Type: text/plain", 33 | "", 34 | "EXAMPLE_TXT", 35 | "--boundary--", 36 | ].joined(separator: "\r\n") + "\r\n" 37 | 38 | XCTAssertEqual( 39 | multipartFormData.contentType, 40 | "multipart/form-data; boundary=\"boundary\"" 41 | ) 42 | XCTAssertEqual( 43 | String(data: multipartFormData.body, encoding: .utf8)!, 44 | expected 45 | ) 46 | } 47 | 48 | 49 | static var allTests: [(String, (MultipartFormDataBuilderTests) -> () throws -> Void)] { 50 | return [ 51 | ("testBuild", self.testBuild), 52 | ] 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /Tests/MultipartFormDataKitTests/MultipartFormDataTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import MultipartFormDataKit 3 | 4 | class MultipartFormDataTests: XCTestCase { 5 | private struct TestCase { 6 | let multipartFormData: MultipartFormData 7 | let expected: String 8 | } 9 | 10 | 11 | func testAsData() { 12 | let testCases: [UInt: TestCase] = [ 13 | #line: TestCase( 14 | multipartFormData: MultipartFormData( 15 | uniqueAndValidLengthBoundary: "boundary", 16 | body: [ 17 | MultipartFormData.Part( 18 | contentDisposition: ContentDisposition( 19 | name: Name(asPercentEncoded: "field1"), 20 | filename: nil 21 | ), 22 | contentType: nil, 23 | content: "value1".data(using: .utf8)! 24 | ), 25 | MultipartFormData.Part( 26 | contentDisposition: ContentDisposition( 27 | name: Name(asPercentEncoded: "field2"), 28 | filename: Filename(asPercentEncoded: "example.txt") 29 | ), 30 | contentType: ContentType(representing: .textPlain), 31 | content: "value2".data(using: .utf8)! 32 | ), 33 | ] 34 | ), 35 | expected: [ 36 | "--boundary", 37 | "Content-Disposition: form-data; name=\"field1\"", 38 | "", 39 | "value1", 40 | "--boundary", 41 | "Content-Disposition: form-data; name=\"field2\"; filename=\"example.txt\"", 42 | "Content-Type: text/plain", 43 | "", 44 | "value2", 45 | "--boundary--", 46 | ].joined(separator: "\r\n") + "\r\n" 47 | ) 48 | ] 49 | 50 | 51 | testCases.forEach { (line, testCase) in 52 | let actual = String(data: testCase.multipartFormData.asData().content!, encoding: .utf8) 53 | let expected = testCase.expected 54 | 55 | XCTAssertEqual(actual, expected) 56 | } 57 | } 58 | 59 | 60 | static var allTests = [ 61 | ("testAsData", testAsData), 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /Tests/MultipartFormDataKitTests/NameTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import MultipartFormDataKit 3 | 4 | 5 | 6 | class NameTests: XCTestCase { 7 | private struct TestCase { 8 | let filename: String 9 | let expected: Name 10 | } 11 | 12 | 13 | func testInit() { 14 | let testCases: [UInt: TestCase] = [ 15 | #line: TestCase( 16 | filename: "abc123ABC", 17 | expected: Name(asPercentEncoded: "abc123ABC") 18 | ), 19 | #line: TestCase( 20 | filename: "=;\"", 21 | expected: Name(asPercentEncoded: "=%3B%22") 22 | ), 23 | ] 24 | 25 | 26 | testCases.forEach { (line, testCase) in 27 | let actual = Name.create(by: testCase.filename) 28 | let expected = testCase.expected 29 | 30 | XCTAssertEqual(actual.content?.percentEncodedString, expected.percentEncodedString) 31 | } 32 | } 33 | 34 | 35 | static var allTests: [(String, (NameTests) -> () throws -> Void)] { 36 | return [ 37 | ("testInit", self.testInit) 38 | ] 39 | } 40 | } 41 | --------------------------------------------------------------------------------