| 102 | } |
| 103 | |
| 104 | optional<string> ParseMultipartData(string const & binaryData) |
| 105 | { |
| 106 | // Fast check multipart/form-data format (content starts with boundary string |
| 107 | // and boundary string must starts with two dashes --) |
| 108 | if (binaryData.size() < 2 || binaryData[0] != '-' || binaryData[1] != '-') |
| 109 | return nullopt; |
| 110 | |
| 111 | // Parse multipart headers |
| 112 | string lineDelimiter("\r\n"); |
| 113 | size_t offset = 0; |
| 114 | |
| 115 | bool hasContentTypeHeader = false; |
| 116 | bool hasContentDispositionHeader = false; |
| 117 | |
| 118 | string expectedContentType("Content-Type: application/zip"); |
| 119 | string expectedContentDispositionPrefix("Content-Disposition: form-data; name=\"file\";"); |
| 120 | |
| 121 | string boundary = ParseString(binaryData, lineDelimiter, offset); |
| 122 | for (string header = ParseString(binaryData, lineDelimiter, offset); !header.empty(); |
| 123 | header = ParseString(binaryData, lineDelimiter, offset)) |
| 124 | { |
| 125 | if (expectedContentType == header) |
| 126 | hasContentTypeHeader = true; |
| 127 | if (expectedContentDispositionPrefix.compare(0, string::npos, header, 0, expectedContentDispositionPrefix.size()) == |
| 128 | 0) |
| 129 | { |
| 130 | hasContentDispositionHeader = true; |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | if (!hasContentTypeHeader && !hasContentDispositionHeader) |
| 135 | return nullopt; |
| 136 | |
| 137 | // Parse file content until boundary |
| 138 | return ParseString(binaryData, boundary, offset); |
| 139 | } |
| 140 | |
| 141 | bool HasZipSignature(string const & binaryData) |
| 142 | { |