Line data Source code
1 : /** 2 : Copyright (c) 2024 Stappler LLC <admin@stappler.dev> 3 : 4 : Permission is hereby granted, free of charge, to any person obtaining a copy 5 : of this software and associated documentation files (the "Software"), to deal 6 : in the Software without restriction, including without limitation the rights 7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 : copies of the Software, and to permit persons to whom the Software is 9 : furnished to do so, subject to the following conditions: 10 : 11 : The above copyright notice and this permission notice shall be included in 12 : all copies or substantial portions of the Software. 13 : 14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 : THE SOFTWARE. 21 : **/ 22 : 23 : #include "SPWebRequestFilter.h" 24 : 25 : namespace STAPPLER_VERSIONIZED stappler::web { 26 : 27 3125 : size_t RequestFilter::readRequestLine(StringView &r, RequestInfo &req) { 28 3125 : auto source = r; 29 3125 : r.skipChars<StringView::WhiteSpace>(); 30 3125 : auto methodName = r.readChars<StringView::LatinUppercase>(); 31 3125 : auto method = getRequestMethod(methodName); 32 3125 : if (method == RequestMethod::Invalid) { 33 0 : return 0; 34 : } 35 : 36 3125 : r.skipChars<StringView::WhiteSpace>(); 37 : 38 3125 : auto unparsedUrl = r; 39 : 40 3125 : if (!req.url.parse(r)) { 41 0 : return 0; 42 : } 43 : 44 3125 : unparsedUrl = StringView(unparsedUrl.data(), unparsedUrl.size() - r.size()); 45 : 46 3125 : r.skipChars<StringView::WhiteSpace>(); 47 : 48 3125 : StringView protocolName = r.readChars<StringView::LatinUppercase>(); 49 3125 : StringView protocolVersion; 50 3125 : if (r.is('/')) { 51 3125 : ++ r; 52 3125 : protocolVersion = r.readChars<StringView::Alphanumeric, StringView::Chars<'.'>>(); 53 : } 54 : 55 3125 : if (protocolName != "HTTP") { 56 0 : return 0; 57 : } 58 : 59 3125 : protocolName = StringView(protocolName.data(), r.data() - protocolName.data()); 60 : 61 3125 : if (!r.is('\r')) { 62 0 : return 0; 63 : } 64 : 65 3125 : ++ r; 66 3125 : if (r.is('\n')) { 67 3125 : ++ r; 68 : } 69 : 70 3125 : if (methodName == "HEAD") { 71 25 : req.headerRequest = true; 72 : } 73 : 74 3125 : req.requestTime = Time::now(); 75 3125 : req.method = method; 76 3125 : req.methodName = methodName; 77 3125 : req.protocol = protocolName; 78 3125 : req.protocolVersion = getProtocolVersionNumber(protocolVersion); 79 3125 : req.unparserUri = unparsedUrl; 80 : 81 3125 : return r.data() - source.data(); 82 : } 83 : 84 17150 : size_t RequestFilter::readRequestHeader(BytesView &source, StringView &key, StringView &value) { 85 17150 : auto tmp = source; 86 17150 : auto keyData = source.readUntil<uint8_t(':')>(); 87 17150 : key = keyData.toStringView(); 88 17150 : if (!source.is(':') || key.size() != keyData.size()) { 89 25 : return 0; 90 : } 91 : 92 17125 : ++ source; 93 : 94 17125 : auto valueData = source.readUntil<uint8_t('\n')>(); 95 17125 : value = valueData.toStringView(); 96 17125 : if (!source.is('\n') || value.size() != valueData.size()) { 97 0 : return 0; 98 : } 99 : 100 17125 : key.trimChars<StringView::WhiteSpace>(); 101 17125 : value.trimChars<StringView::WhiteSpace>(); 102 17125 : return source.data() - tmp.data(); 103 : } 104 : 105 : /* 106 : RequestFilter::RequestFilter() { } 107 : 108 : bool RequestFilter::readRequestLine(StringView &r) { 109 : while (!r.empty()) { 110 : if (_isWhiteSpace) { 111 : auto tmp = r.readChars<Reader::CharGroup<CharGroupId::WhiteSpace>>(); 112 : _buffer << tmp; 113 : auto tmp2 = tmp.readUntil<Reader::Chars<'\n'>>(); 114 : if (tmp2.is('\n')) { 115 : return true; 116 : } 117 : if (r.empty()) { 118 : return false; 119 : } 120 : _isWhiteSpace = false; 121 : } 122 : if (_subState == RequestState::Protocol) { 123 : _buffer << r.readUntil<Reader::CharGroup<CharGroupId::WhiteSpace>>(); 124 : if (r.is<CharGroupId::WhiteSpace>()) { 125 : _nameBuffer.clear(); 126 : _isWhiteSpace = true; 127 : _subState = State::Code; 128 : } 129 : } else if (_subState == RequestState::Code) { 130 : auto b = r.readChars<Reader::Range<'0', '9'>>(); 131 : _nameBuffer << b; 132 : _buffer << b; 133 : if (r.is<CharGroupId::WhiteSpace>()) { 134 : _nameBuffer << '\0'; 135 : _responseCode = apr_strtoi64(_nameBuffer.data(), NULL, 0); 136 : _isWhiteSpace = true; 137 : _subState = State::Status; 138 : } 139 : } else if (_subState == RequestState::Status) { 140 : auto statusText = r.readUntil<Reader::Chars<'\n'>>(); 141 : _statusText = statusText.str(); 142 : string::trim(_statusText); 143 : _buffer << statusText; 144 : } else { 145 : r.readUntil<Reader::Chars<'\n', '\r'>>(); 146 : } 147 : if (r.is('\n') || r.is('\r')) { 148 : ++ r; 149 : _buffer << r.readChars<Reader::Chars<'\n', '\r'>>(); 150 : _state = State::Headers; 151 : _subState = State::HeaderName; 152 : _isWhiteSpace = true; 153 : return true; 154 : } 155 : } 156 : return false; 157 : } 158 : 159 : bool RequestFilter::readHeaders(StringView &r) { 160 : while (!r.empty()) { 161 : if (_subState == State::HeaderName) { 162 : _nameBuffer << r.readUntil<Reader::Chars<':', '\n'>>(); 163 : if (r.is('\n')) { 164 : r ++; 165 : _state = State::Body; 166 : return true; 167 : } else if (r.is<':'>()) { 168 : r ++; 169 : _isWhiteSpace = true; 170 : _subState = State::HeaderValue; 171 : } 172 : } else if (_subState == State::HeaderValue) { 173 : _buffer << r.readUntil<Reader::Chars<'\n'>>(); 174 : if (r.is('\n')) { 175 : r ++; 176 : 177 : auto key = _nameBuffer.str(); string::trim(key); 178 : auto value = _buffer.str(); string::trim(value); 179 : 180 : _headers.emplace(std::move(key), std::move(value)); 181 : 182 : _buffer.clear(); 183 : _nameBuffer.clear(); 184 : _subState = State::HeaderName; 185 : _isWhiteSpace = true; 186 : } 187 : } 188 : } 189 : return false; 190 : }*/ 191 : 192 : }