| 113 | } |
| 114 | |
| 115 | Result HttpMultipartContentDispositionView::parse(StringSpan headerValue) |
| 116 | { |
| 117 | *this = {}; |
| 118 | |
| 119 | StringSpan header = HttpMultipartInternal::trim(headerValue); |
| 120 | const char* data = header.bytesWithoutTerminator(); |
| 121 | const size_t length = header.sizeInBytes(); |
| 122 | SC_TRY_MSG(not header.isEmpty(), "Multipart Content-Disposition is empty"); |
| 123 | |
| 124 | size_t cursor = 0; |
| 125 | while (cursor < length and data[cursor] != ';') |
| 126 | { |
| 127 | cursor++; |
| 128 | } |
| 129 | disposition = HttpMultipartInternal::trim({{data, cursor}, false, header.getEncoding()}); |
| 130 | SC_TRY_MSG(not disposition.isEmpty(), "Multipart Content-Disposition disposition is empty"); |
| 131 | |
| 132 | while (cursor < length) |
| 133 | { |
| 134 | if (data[cursor] == ';') |
| 135 | { |
| 136 | cursor++; |
| 137 | } |
| 138 | const size_t itemStart = cursor; |
| 139 | while (cursor < length and data[cursor] != ';') |
| 140 | { |
| 141 | cursor++; |
| 142 | } |
| 143 | StringSpan item = |
| 144 | HttpMultipartInternal::trim({{data + itemStart, cursor - itemStart}, false, header.getEncoding()}); |
| 145 | if (item.isEmpty()) |
| 146 | { |
| 147 | continue; |
| 148 | } |
| 149 | |
| 150 | const char* itemData = item.bytesWithoutTerminator(); |
| 151 | size_t equals = static_cast<size_t>(-1); |
| 152 | for (size_t idx = 0; idx < item.sizeInBytes(); ++idx) |
| 153 | { |
| 154 | if (itemData[idx] == '=') |
| 155 | { |
| 156 | equals = idx; |
| 157 | break; |
| 158 | } |
| 159 | } |
| 160 | if (equals == static_cast<size_t>(-1)) |
| 161 | { |
| 162 | continue; |
| 163 | } |
| 164 | |
| 165 | StringSpan key = HttpMultipartInternal::trim({{itemData, equals}, false, item.getEncoding()}); |
| 166 | StringSpan value = HttpMultipartInternal::trim( |
| 167 | {{itemData + equals + 1, item.sizeInBytes() - equals - 1}, false, item.getEncoding()}); |
| 168 | value = HttpMultipartInternal::unquote(value); |
| 169 | if (HttpMultipartInternal::equalsIgnoreCase(key, "name")) |
| 170 | { |
| 171 | name = value; |
| 172 | hasName = true; |
no test coverage detected