| 908 | } |
| 909 | |
| 910 | void HttpAsyncFileServer::Stream::MultipartListener::onData(AsyncBufferView::ID bufferID) |
| 911 | { |
| 912 | AsyncReadableStream& readable = connection->request.getReadableStream(); |
| 913 | AsyncBuffersPool& buffers = readable.getBuffersPool(); |
| 914 | |
| 915 | Span<const char> data; |
| 916 | SC_HTTP_ASSERT_RELEASE(buffers.getReadableData(bufferID, data)); |
| 917 | |
| 918 | size_t readBytes; |
| 919 | Span<const char> parsedData; |
| 920 | |
| 921 | while (not data.empty() and stream->multipartParser.state != HttpMultipartParser::State::Finished) |
| 922 | { |
| 923 | SC_HTTP_ASSERT_RELEASE(stream->multipartParser.parse(data, readBytes, parsedData)); |
| 924 | |
| 925 | const bool streamedBody = |
| 926 | stream->multipartParser.token == HttpMultipartParser::Token::PartBody and parsedData.sizeInBytes() > 0; |
| 927 | if (streamedBody and currentFd.isValid()) |
| 928 | { |
| 929 | SC_HTTP_ASSERT_RELEASE(currentFd.write(parsedData)); |
| 930 | } |
| 931 | |
| 932 | bool tokenProcessed = false; |
| 933 | if (stream->multipartParser.state != HttpMultipartParser::State::Parsing) |
| 934 | { |
| 935 | tokenProcessed = true; |
| 936 | switch (stream->multipartParser.token) |
| 937 | { |
| 938 | case HttpMultipartParser::Token::Boundary: { |
| 939 | if (currentFd.isValid()) |
| 940 | { |
| 941 | (void)currentFd.close(); |
| 942 | } |
| 943 | currentHeaderName = {}; |
| 944 | partHeaders.reset(); |
| 945 | } |
| 946 | break; |
| 947 | |
| 948 | case HttpMultipartParser::Token::HeaderName: { |
| 949 | currentHeaderName = {parsedData, false, StringEncoding::Ascii}; |
| 950 | } |
| 951 | break; |
| 952 | |
| 953 | case HttpMultipartParser::Token::HeaderValue: { |
| 954 | SC_HTTP_ASSERT_RELEASE( |
| 955 | partHeaders.addHeader(currentHeaderName, {parsedData, false, StringEncoding::Ascii})); |
| 956 | if (partHeaders.isFile() and not partHeaders.hasSafeFileName()) |
| 957 | { |
| 958 | rejectedFileName = true; |
| 959 | } |
| 960 | } |
| 961 | break; |
| 962 | |
| 963 | case HttpMultipartParser::Token::PartHeaderEnd: { |
| 964 | if (partHeaders.isSafeFile()) |
| 965 | { |
| 966 | (void)currentFilePath.assign(server->directory.view()); |
| 967 | (void)currentFilePath.append("/"); |
nothing calls this directly
no test coverage detected