| 314 | |
| 315 | template <bool (SC::HttpParser::*Func)(char), SC::HttpParser::Token currentResult> |
| 316 | SC::Result SC::HttpParser::process(Span<const char>& data, size_t& readBytes, Span<const char>& parsedData) |
| 317 | { |
| 318 | const auto initialStart = tokenStart; |
| 319 | const auto initialLength = tokenLength; |
| 320 | const auto bytes = data.data(); |
| 321 | |
| 322 | token = currentResult; |
| 323 | state = State::Parsing; |
| 324 | readBytes = 0; |
| 325 | |
| 326 | bool fastPath = false; |
| 327 | |
| 328 | const size_t dataSize = data.sizeInBytes(); |
| 329 | if (nestedParserCoroutine == 0 and tokenLength == 0 and dataSize > 0) |
| 330 | { |
| 331 | if (Func == &HttpParser::parseHeaderName) |
| 332 | { |
| 333 | const auto found = ::memchr(bytes, ':', dataSize); |
| 334 | if (found != nullptr) |
| 335 | { |
| 336 | const size_t headerLen = static_cast<size_t>(static_cast<const char*>(found) - bytes); |
| 337 | for (size_t idx = 0; idx < numMatches; ++idx) |
| 338 | { |
| 339 | matchingHeaderValid[idx] = false; |
| 340 | if (SC_HTTP_TRACKED_HEADERS[idx].sizeInBytes() == headerLen and |
| 341 | scHttpEqualsIgnoreCaseAscii(SC_HTTP_TRACKED_HEADERS[idx].bytesWithoutTerminator(), bytes, |
| 342 | headerLen)) |
| 343 | { |
| 344 | matchingHeaderValid[idx] = true; |
| 345 | } |
| 346 | } |
| 347 | tokenLength = headerLen; |
| 348 | readBytes = headerLen + 1; |
| 349 | state = State::Result; |
| 350 | fastPath = true; |
| 351 | } |
| 352 | } |
| 353 | else if (Func == &HttpParser::parseHeaderValue) |
| 354 | { |
| 355 | size_t startIndex = 0; |
| 356 | while (startIndex < dataSize and bytes[startIndex] == ' ') |
| 357 | { |
| 358 | startIndex++; |
| 359 | } |
| 360 | const void* const found = |
| 361 | startIndex < dataSize ? ::memchr(bytes + startIndex, '\r', dataSize - startIndex) : nullptr; |
| 362 | if (found != nullptr) |
| 363 | { |
| 364 | const size_t crIndex = static_cast<size_t>(static_cast<const char*>(found) - bytes); |
| 365 | if (crIndex + 1 < dataSize and bytes[crIndex + 1] == '\n') |
| 366 | { |
| 367 | tokenStart += startIndex; |
| 368 | tokenLength = crIndex - startIndex; |
| 369 | readBytes = crIndex + 2; |
| 370 | state = State::Result; |
| 371 | fastPath = true; |
| 372 | } |
| 373 | } |