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 "SPWebInfo.h" 24 : 25 : namespace STAPPLER_VERSIONIZED stappler::web { 26 : 27 0 : void SessionInfo::init(const Value &val) { 28 0 : name = val.getString("name"); 29 0 : key = val.getString("key"); 30 0 : maxAge = TimeInterval(val.getInteger("maxage")); 31 0 : secure = val.getBool("secure"); 32 0 : } 33 : 34 0 : void SessionInfo::setParam(StringView n, StringView v) { 35 0 : if (n.is("name")) { 36 0 : name = v.str<Interface>(); 37 0 : } else if (n.is("key")) { 38 0 : key = v.str<Interface>(); 39 0 : } else if (n.is("maxage")) { 40 0 : maxAge = v.readInteger().get(0); 41 0 : } else if (n.is("secure")) { 42 0 : if (v.is("true") || v.is("on") || v.is("On")) { 43 0 : secure = true; 44 0 : } else if (v.is("false") || v.is("off") || v.is("Off")) { 45 0 : secure = false; 46 : } 47 : } 48 0 : } 49 : 50 0 : void WebhookInfo::init(const Value &val) { 51 0 : name = val.getString("name"); 52 0 : url = val.getString("url"); 53 0 : format = val.getString("format"); 54 0 : extra = val.getValue("extra"); 55 0 : } 56 : 57 0 : void WebhookInfo::setParam(StringView n, StringView v) { 58 0 : if (n.is("name")) { 59 0 : name = v.str<Interface>(); 60 0 : } else if (n.is("url")) { 61 0 : url = v.str<Interface>(); 62 0 : } else if (n.is("format")) { 63 0 : format = v.str<Interface>(); 64 : } else { 65 0 : extra.setString(v.str<Interface>(), n.str<Interface>()); 66 : } 67 0 : } 68 : 69 3125 : RequestInfo RequestInfo::clone(pool_t *pool) { 70 3125 : return perform([&, this] { 71 3125 : RequestInfo ret(*this); 72 : 73 62500 : auto dupString = [&] (StringView &str) { 74 62500 : if (!str.empty()) { 75 16725 : str = str.pdup(pool); 76 : } 77 62500 : }; 78 : 79 3125 : dupString(ret.requestLine); 80 3125 : dupString(ret.protocol); 81 3125 : dupString(ret.methodName); 82 3125 : dupString(ret.statusLine); 83 3125 : dupString(ret.rangeLine); 84 3125 : dupString(ret.documentRoot); 85 3125 : dupString(ret.contentEncoding); 86 3125 : dupString(ret.authType); 87 3125 : dupString(ret.unparserUri); 88 3125 : dupString(ret.filename); 89 3125 : dupString(ret.handler); 90 : 91 3125 : dupString(ret.url.scheme); 92 3125 : dupString(ret.url.user); 93 3125 : dupString(ret.url.password); 94 3125 : dupString(ret.url.host); 95 3125 : dupString(ret.url.port); 96 3125 : dupString(ret.url.path); 97 3125 : dupString(ret.url.query); 98 3125 : dupString(ret.url.fragment); 99 3125 : dupString(ret.url.url); 100 : 101 3125 : if (!ret.queryPath.empty()) { 102 0 : for (auto &it : ret.queryPath) { 103 0 : dupString(const_cast<StringView &>(it)); 104 : } 105 0 : ret.queryPath = ret.queryPath.pdup(pool); 106 : } 107 : 108 6250 : return ret; 109 3125 : }, pool); 110 : } 111 : 112 3125 : RequestMethod getRequestMethod(StringView method) { 113 3125 : if (method == "GET") { return RequestMethod::Get; } 114 825 : else if (method == "HEAD") { return RequestMethod::Get; } 115 800 : else if (method == "PUT") { return RequestMethod::Put; } 116 650 : else if (method == "POST") { return RequestMethod::Post; } 117 150 : else if (method == "DELETE") { return RequestMethod::Delete; } 118 0 : else if (method == "CONNECT") { return RequestMethod::Connect; } 119 0 : else if (method == "OPTIONS") { return RequestMethod::Options; } 120 0 : else if (method == "TRACE") { return RequestMethod::Trace; } 121 0 : else if (method == "PATCH") { return RequestMethod::Patch; } 122 0 : else if (method == "PROPFIND") { return RequestMethod::Propfind; } 123 0 : else if (method == "PROPPATCH") { return RequestMethod::Proppatch; } 124 0 : else if (method == "MKCOL") { return RequestMethod::MkCol; } 125 0 : else if (method == "COPY") { return RequestMethod::Copy; } 126 0 : else if (method == "MOVE") { return RequestMethod::Move; } 127 0 : else if (method == "LOCK") { return RequestMethod::Lock; } 128 0 : else if (method == "UNLOCK") { return RequestMethod::Unlock; } 129 0 : else if (method == "VERSIONCONTROL") { return RequestMethod::VersionControl; } 130 0 : else if (method == "CHECKOUT") { return RequestMethod::Checkout; } 131 0 : else if (method == "UNCHECKOUT") { return RequestMethod::Uncheckout; } 132 0 : else if (method == "CHECKIN") { return RequestMethod::Checkin; } 133 0 : else if (method == "UPDATE") { return RequestMethod::Update; } 134 0 : else if (method == "LABEL") { return RequestMethod::Label; } 135 0 : else if (method == "REPORT") { return RequestMethod::Report; } 136 0 : else if (method == "MKWORKSPACE") { return RequestMethod::MkWorkspace; } 137 0 : else if (method == "MKACTIVITY") { return RequestMethod::MkActivity; } 138 0 : else if (method == "BASELINECONTROL") { return RequestMethod::BaselineControl; } 139 0 : else if (method == "MERGE") { return RequestMethod::Merge; } 140 : 141 0 : return RequestMethod::Invalid; 142 : } 143 : 144 3125 : uint32_t getProtocolVersionNumber(StringView str) { 145 3125 : uint32_t ret = 0; 146 3125 : if (str.is<StringView::Numbers>()) { 147 3125 : ret += str.readInteger(10).get(0) * 1000; 148 : } 149 3125 : if (str.is('.')) { 150 3125 : ++ str; 151 3125 : ret += str.readInteger(10).get(0); 152 : } 153 3125 : return ret; 154 : } 155 : 156 25 : StringView extractCharset(StringView s) { 157 25 : s.skipUntil<StringView::Chars<';'>>(); 158 25 : if (!s.is(';')) { 159 25 : return StringView(); 160 : } 161 : 162 0 : ++ s; 163 : 164 0 : s.skipChars<StringView::CharGroup<CharGroupId::WhiteSpace>>(); 165 0 : while (!s.empty()) { 166 0 : StringView name; 167 0 : StringView value; 168 : 169 0 : name = s.readUntil<StringView::Chars<'='>>(); 170 0 : name.trimChars<StringView::CharGroup<CharGroupId::WhiteSpace>>(); 171 0 : if (s.is('=')) { 172 0 : ++ s; 173 0 : s.skipChars<StringView::CharGroup<CharGroupId::WhiteSpace>>(); 174 0 : if (s.is('"')) { 175 0 : while (s.is('"')) { 176 0 : ++ s; 177 0 : s.skipUntil<StringView::Chars<'"'>>(); 178 0 : if (s.is('"')) { 179 0 : ++ s; 180 0 : s.skipChars<StringView::CharGroup<CharGroupId::WhiteSpace>>(); 181 : } 182 : } 183 0 : s.skipUntil<StringView::Chars<';'>>(); 184 0 : if (s.is(';')) { 185 0 : value = StringView(name.data() + name.size() + 1, s.data() - (name.data() + name.size() + 1)); 186 : } 187 : } else { 188 0 : value = s.readUntil<StringView::Chars<';'>>(); 189 : } 190 : } 191 : 192 0 : if (name == "charset" && !value.empty()) { 193 0 : return value; 194 : } 195 : } 196 0 : return StringView(); 197 : } 198 : 199 6225 : StringView getStatusLine(Status status) { 200 6225 : switch (status) { 201 0 : case HTTP_CONTINUE: return StringView("100 Continue"); break; 202 0 : case HTTP_SWITCHING_PROTOCOLS: return StringView("101 Switching Protocols"); break; 203 0 : case HTTP_PROCESSING: return StringView("102 Processing"); break; 204 2625 : case DONE: return StringView("200 OK"); break; 205 2300 : case HTTP_OK: return StringView("200 OK"); break; 206 300 : case HTTP_CREATED: return StringView("201 Created"); break; 207 0 : case HTTP_ACCEPTED: return StringView("202 Accepted"); break; 208 0 : case HTTP_NON_AUTHORITATIVE: return StringView("203 Non-Authoritative Information"); break; 209 350 : case HTTP_NO_CONTENT: return StringView("204 No Content"); break; 210 0 : case HTTP_RESET_CONTENT: return StringView("205 Reset Content"); break; 211 0 : case HTTP_PARTIAL_CONTENT: return StringView("206 Partial Content"); break; 212 0 : case HTTP_MULTI_STATUS: return StringView("207 Multi-Status"); break; 213 0 : case HTTP_ALREADY_REPORTED: return StringView("208 Already Reported"); break; 214 0 : case HTTP_IM_USED: return StringView("226 IM Used"); break; 215 0 : case HTTP_MULTIPLE_CHOICES: return StringView("300 Multiple Choices"); break; 216 0 : case HTTP_MOVED_PERMANENTLY: return StringView("301 Moved Permanently"); break; 217 0 : case HTTP_MOVED_TEMPORARILY: return StringView("302 Found"); break; 218 325 : case HTTP_SEE_OTHER: return StringView("303 See Other"); break; 219 100 : case HTTP_NOT_MODIFIED: return StringView("304 Not Modified"); break; 220 0 : case HTTP_USE_PROXY: return StringView("305 Use Proxy"); break; 221 0 : case HTTP_TEMPORARY_REDIRECT: return StringView("307 Temporary Redirect"); break; 222 0 : case HTTP_PERMANENT_REDIRECT: return StringView("308 Permanent Redirect"); break; 223 0 : case HTTP_BAD_REQUEST: return StringView("400 Bad Request"); break; 224 50 : case HTTP_UNAUTHORIZED: return StringView("401 Unauthorized"); break; 225 0 : case HTTP_PAYMENT_REQUIRED: return StringView("402 Payment Required"); break; 226 75 : case HTTP_FORBIDDEN: return StringView("403 Forbidden"); break; 227 100 : case HTTP_NOT_FOUND: return StringView("404 Not Found"); break; 228 0 : case HTTP_METHOD_NOT_ALLOWED: return StringView("405 Method Not Allowed"); break; 229 0 : case HTTP_NOT_ACCEPTABLE: return StringView("406 Not Acceptable"); break; 230 0 : case HTTP_PROXY_AUTHENTICATION_REQUIRED: return StringView("407 Proxy Authentication Required"); break; 231 0 : case HTTP_REQUEST_TIME_OUT: return StringView("408 Request Timeout"); break; 232 0 : case HTTP_CONFLICT: return StringView("409 Conflict"); break; 233 0 : case HTTP_GONE: return StringView("410 Gone"); break; 234 0 : case HTTP_LENGTH_REQUIRED: return StringView("411 Length Required"); break; 235 0 : case HTTP_PRECONDITION_FAILED: return StringView("412 Precondition Failed"); break; 236 0 : case HTTP_REQUEST_ENTITY_TOO_LARGE: return StringView("413 Request Entity Too Large"); break; 237 0 : case HTTP_REQUEST_URI_TOO_LARGE: return StringView("414 Request-URI Too Long"); break; 238 0 : case HTTP_UNSUPPORTED_MEDIA_TYPE: return StringView("415 Unsupported Media Type"); break; 239 0 : case HTTP_RANGE_NOT_SATISFIABLE: return StringView("416 Requested Range Not Satisfiable"); break; 240 0 : case HTTP_EXPECTATION_FAILED: return StringView("417 Expectation Failed"); break; 241 0 : case HTTP_MISDIRECTED_REQUEST: return StringView("421 Misdirected Request"); break; 242 0 : case HTTP_UNPROCESSABLE_ENTITY: return StringView("422 Unprocessable Entity"); break; 243 0 : case HTTP_LOCKED: return StringView("423 Locked"); break; 244 0 : case HTTP_FAILED_DEPENDENCY: return StringView("424 Failed Dependency"); break; 245 0 : case HTTP_UPGRADE_REQUIRED: return StringView("426 Upgrade Required"); break; 246 0 : case HTTP_PRECONDITION_REQUIRED: return StringView("428 Precondition Required"); break; 247 0 : case HTTP_TOO_MANY_REQUESTS: return StringView("429 Too Many Requests"); break; 248 0 : case HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE: return StringView("431 Request Header Fields Too Large"); break; 249 0 : case HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: return StringView("451 Unavailable For Legal Reasons"); break; 250 0 : case HTTP_INTERNAL_SERVER_ERROR: return StringView("500 Internal Server Error"); break; 251 0 : case HTTP_NOT_IMPLEMENTED: return StringView("501 Not Implemented"); break; 252 0 : case HTTP_BAD_GATEWAY: return StringView("502 Bad Gateway"); break; 253 0 : case HTTP_SERVICE_UNAVAILABLE: return StringView("503 Service Unavailable"); break; 254 0 : case HTTP_GATEWAY_TIME_OUT: return StringView("504 Gateway Timeout"); break; 255 0 : case HTTP_VERSION_NOT_SUPPORTED: return StringView("505 HTTP Version Not Supported"); break; 256 0 : case HTTP_VARIANT_ALSO_VARIES: return StringView("506 Variant Also Negotiates"); break; 257 0 : case HTTP_INSUFFICIENT_STORAGE: return StringView("507 Insufficient Storage"); break; 258 0 : case HTTP_LOOP_DETECTED: return StringView("508 Loop Detected"); break; 259 0 : case HTTP_NOT_EXTENDED: return StringView("510 Not Extended"); break; 260 0 : case HTTP_NETWORK_AUTHENTICATION_REQUIRED: return StringView("511 Network Authentication Required"); break; 261 0 : default: break; 262 : } 263 0 : return StringView(); 264 : } 265 : 266 : }