Coverage Report

Created: 2025-06-13 06:09

/src/uWebSockets/src/MessageParser.h
Line
Count
Source
1
/*
2
 * Authored by Alex Hultman, 2018-2020.
3
 * Intellectual property of third-party.
4
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
/* Implements the common parser (RFC 822) used in both HTTP and Multipart parsing */
19
20
#ifndef UWS_MESSAGE_PARSER_H
21
#define UWS_MESSAGE_PARSER_H
22
23
#include <string_view>
24
#include <utility>
25
#include <cstring>
26
27
/* For now we have this one here */
28
10.6k
#define MAX_HEADERS 10
29
30
namespace uWS {
31
32
    // should be templated on whether it needs at lest one header (http), or not (multipart)
33
3.06k
    static inline unsigned int getHeaders(char *postPaddedBuffer, char *end, std::pair<std::string_view, std::string_view> *headers) {
34
3.06k
        char *preliminaryKey, *preliminaryValue, *start = postPaddedBuffer;
35
36
10.6k
        for (unsigned int i = 0; i < MAX_HEADERS; i++) {
37
4.21M
            for (preliminaryKey = postPaddedBuffer; (*postPaddedBuffer != ':') & (*(unsigned char *)postPaddedBuffer > 32); *(postPaddedBuffer++) |= 32);
38
10.6k
            if (*postPaddedBuffer == '\r') {
39
2.99k
                if ((postPaddedBuffer != end) & (postPaddedBuffer[1] == '\n') /* & (i > 0) */) { // multipart does not require any headers like http does
40
2.93k
                    headers->first = std::string_view(nullptr, 0);
41
2.93k
                    return (unsigned int) ((postPaddedBuffer + 2) - start);
42
2.93k
                } else {
43
58
                    return 0;
44
58
                }
45
7.64k
            } else {
46
7.64k
                headers->first = std::string_view(preliminaryKey, (size_t) (postPaddedBuffer - preliminaryKey));
47
9.67k
                for (postPaddedBuffer++; (*postPaddedBuffer == ':' || *(unsigned char *)postPaddedBuffer < 33) && *postPaddedBuffer != '\r'; postPaddedBuffer++);
48
7.64k
                preliminaryValue = postPaddedBuffer;
49
7.64k
                postPaddedBuffer = (char *) memchr(postPaddedBuffer, '\r', end - postPaddedBuffer);
50
7.64k
                if (postPaddedBuffer && postPaddedBuffer[1] == '\n') {
51
7.57k
                    headers->second = std::string_view(preliminaryValue, (size_t) (postPaddedBuffer - preliminaryValue));
52
7.57k
                    postPaddedBuffer += 2;
53
7.57k
                    headers++;
54
7.57k
                } else {
55
71
                    return 0;
56
71
                }
57
7.64k
            }
58
10.6k
        }
59
5
        return 0;
60
3.06k
    }
61
62
}
63
64
#endif