/* * Copyright (C) 2009 Google Inc. All rights reserved. * Copyright (C) 2022 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "HTTPHeaderMap.h" #include #include #include static StringView extractCookieName(const StringView& cookie) { auto nameEnd = cookie.find('='); if (nameEnd == notFound) return String(); return cookie.substring(0, nameEnd); } namespace WebCore { HTTPHeaderMap::HTTPHeaderMap() { } HTTPHeaderMap HTTPHeaderMap::isolatedCopy() const& { HTTPHeaderMap map; map.m_commonHeaders = crossThreadCopy(m_commonHeaders); map.m_uncommonHeaders = crossThreadCopy(m_uncommonHeaders); map.m_setCookieHeaders = crossThreadCopy(m_setCookieHeaders); return map; } HTTPHeaderMap HTTPHeaderMap::isolatedCopy() && { HTTPHeaderMap map; map.m_commonHeaders = crossThreadCopy(WTFMove(m_commonHeaders)); map.m_uncommonHeaders = crossThreadCopy(WTFMove(m_uncommonHeaders)); map.m_setCookieHeaders = crossThreadCopy(WTFMove(m_setCookieHeaders)); return map; } String HTTPHeaderMap::get(const String& name) const { HTTPHeaderName headerName; if (findHTTPHeaderName(name, headerName)) return get(headerName); return getUncommonHeader(name); } String HTTPHeaderMap::getUncommonHeader(const String& name) const { auto index = m_uncommonHeaders.findIf([&](auto& header) { return equalIgnoringASCIICase(header.key, name); }); return index != notFound ? m_uncommonHeaders[index].value : String(); } #if USE(CF) void HTTPHeaderMap::set(CFStringRef name, const String& value) { // Fast path: avoid constructing a temporary String in the common header case. if (auto* nameCharacters = CFStringGetCStringPtr(name, kCFStringEncodingASCII)) { unsigned length = CFStringGetLength(name); HTTPHeaderName headerName; if (findHTTPHeaderName(StringView(nameCharacters, length), headerName)) set(headerName, value); else setUncommonHeader(String(nameCharacters, length), value); return; } set(String(name), value); } #endif // USE(CF) void HTTPHeaderMap::set(const String& name, const String& value) { HTTPHeaderName headerName; if (findHTTPHeaderName(name, headerName)) { set(headerName, value); return; } setUncommonHeader(name, value); } void HTTPHeaderMap::setUncommonHeader(const String& name, const String& value) { auto index = m_uncommonHeaders.findIf([&](auto& header) { return equalIgnoringASCIICase(header.key, name); }); if (index == notFound) m_uncommonHeaders.append(UncommonHeader { name, value }); else m_uncommonHeaders[index].value = value; } void HTTPHeaderMap::setUncommonHeaderCloneName(const StringView name, const String& value) { auto index = m_uncommonHeaders.findIf([&](auto& header) { return equalIgnoringASCIICase(header.key, name); }); if (index == notFound) { LChar* ptr = nullptr; auto nameCopy = WTF::String::createUninitialized(name.length(), ptr); memcpy(ptr, name.characters8(), name.length()); m_uncommonHeaders.append(UncommonHeader { nameCopy, value }); } else m_uncommonHeaders[index].value = value; } void HTTPHeaderMap::add(const String& name, const String& value) { HTTPHeaderName headerName; if (findHTTPHeaderName(name, headerName)) { add(headerName, value); return; } auto index = m_uncommonHeaders.findIf([&](auto& header) { return equalIgnoringASCIICase(header.key, name); }); if (index == notFound) m_uncommonHeaders.append(UncommonHeader { name, value }); else m_uncommonHeaders[index].value = makeString(m_uncommonHeaders[index].value, ", ", value); } void HTTPHeaderMap::append(const String& name, const String& value) { ASSERT(!contains(name)); HTTPHeaderName headerName; if (findHTTPHeaderName(name, headerName)) { if (headerName == HTTPHeaderName::SetCookie) m_setCookieHeaders.append(value); else m_commonHeaders.append(CommonHeader { headerName, value }); } else { m_uncommonHeaders.append(UncommonHeader { name, value }); } } bool HTTPHeaderMap::addIfNotPresent(HTTPHeaderName headerName, const String& value) { if (contains(headerName)) return false; m_commonHeaders.append(CommonHeader { headerName, value }); return true; } bool HTTPHeaderMap::contains(const String& name) const { HTTPHeaderName headerName; if (findHTTPHeaderName(name, headerName)) return contains(headerName); return m_uncommonHeaders.findIf([&](auto& header) { return equalIgnoringASCIICase(header.key, name); }) != notFound; } bool HTTPHeaderMap::remove(const String& name) { HTTPHeaderName headerName; if (findHTTPHeaderName(name, headerName)) return remove(headerName); return m_uncommonHeaders.removeFirstMatching([&](auto& header) { return equalIgnoringASCIICase(header.key, name); }); } String HTTPHeaderMap::get(HTTPHeaderName name) const { if (name == HTTPHeaderName::SetCookie) { unsigned count = m_setCookieHeaders.size(); switch (count) { case 0: return String(); case 1: return m_setCookieHeaders[0]; default: { StringBuilder builder; builder.reserveCapacity(m_setCookieHeaders[0].length() * count + (count - 1)); builder.append(m_setCookieHeaders[0]); for (unsigned i = 1; i < count; ++i) { builder.append(", "_s); builder.append(m_setCookieHeaders[i]); } return builder.toString(); } } } auto index = m_commonHeaders.findIf([&](auto& header) { return header.key == name; }); return index != notFound ? m_commonHeaders[index].value : String(); } void HTTPHeaderMap::set(HTTPHeaderName name, const String& value) { if (name == HTTPHeaderName::SetCookie) { auto cookieName = extractCookieName(value); size_t length = m_setCookieHeaders.size(); const auto& cookies = m_setCookieHeaders.data(); for (size_t i = 0; i < length; ++i) { if (extractCookieName(cookies[i]) == cookieName) { m_setCookieHeaders[i] = value; return; } } m_setCookieHeaders.append(value); return; } auto index = m_commonHeaders.findIf([&](auto& header) { return header.key == name; }); if (index == notFound) m_commonHeaders.append(CommonHeader { name, value }); else m_commonHeaders[index].value = value; } bool HTTPHeaderMap::contains(HTTPHeaderName name) const { if (name == HTTPHeaderName::SetCookie) return !m_setCookieHeaders.isEmpty(); return m_commonHeaders.findIf([&](auto& header) { return header.key == name; }) != notFound; } bool HTTPHeaderMap::remove(HTTPHeaderName name) { if (name == HTTPHeaderName::SetCookie) { bool any = m_setCookieHeaders.size() > 0; m_setCookieHeaders.clear(); return any; } return m_commonHeaders.removeFirstMatching([&](auto& header) { return header.key == name; }); } void HTTPHeaderMap::add(HTTPHeaderName name, const String& value) { if (name == HTTPHeaderName::SetCookie) { m_setCookieHeaders.append(value); return; } auto index = m_commonHeaders.findIf([&](auto& header) { return header.key == name; }); if (index != notFound) m_commonHeaders[index].value = makeString(m_commonHeaders[index].value, ", ", value); else m_commonHeaders.append(CommonHeader { name, value }); } } // namespace WebCore ion value='feat/remove-astro-image-backup'>feat/remove-astro-image-backup Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
AgeCommit message (Expand)AuthorFilesLines
2024-04-02[ci] update lockfile (#10551)Gravatar Houston (Bot) 15-1051/+1165
2024-04-01[ci] formatGravatar Arsh 4-17/+19
2024-04-02community onboarding: codebase documentation around runtime (#10612)Gravatar Arsh 8-39/+150
2024-04-01[ci] formatGravatar Ben Holmes 3-3/+3
2024-04-01db: Better error messages when querying remote (#10636)Gravatar Ben Holmes 6-32/+69
2024-04-01Give proper error when seed missing default export (#10635)Gravatar Matthew Phillips 2-1/+6
2024-04-01[ci] formatGravatar Matthew Phillips 2-4/+4
2024-04-01Make ASTRO_DATABASE_FILE work with file paths (#10631)Gravatar Matthew Phillips 4-4/+43
2024-04-01Make `@astrojs/markdown-remark` a dep in `@astrojs/markdoc` (#10632)Gravatar Bjorn Lu 3-4/+9
2024-04-01[ci] formatGravatar Ben Holmes 1-2/+2
2024-04-01db: Seed on dev server startup (#10599)Gravatar Ben Holmes 3-11/+54
2024-04-01Remove deprecated APIs from `@astrojs/markdown-remark` (#10629)Gravatar Bjorn Lu 7-81/+23
2024-04-01Lazy loaded shiki languages during syntax highlighting (#10618)Gravatar James Garbutt 16-110/+169
2024-04-01Move nft warnings behind verbose logging (#10609)Gravatar Matthew Phillips 2-2/+7
2024-04-01Fixes issue with head content being pushed into body (#10608)Gravatar Matthew Phillips 3-7/+12
2024-04-01feat: rework child rendering to use class (#10624)Gravatar James Garbutt 2-33/+51
2024-04-01refactor: Drop Preact compat hack, remove incorrect alias (#10585)Gravatar Ryan Christian 2-8/+7
2024-04-01[ci] formatGravatar ktym4a 1-1/+1
2024-04-01fix(starlog): Correct layout syntax. (#10627)Gravatar ktym4a 2-7/+7
2024-04-01fix: use ReadableStream for response object if deno (#10495)Gravatar Satya Rohith 3-2/+13
2024-03-29Remove the ssr external for vue (#10601)Gravatar Tyler van der Hoeven 2-1/+5
2024-03-29reset history title after push/replace but prior to assignment to location (#...Gravatar Martin Trapp 2-1/+6
2024-03-29fix: dont error on nullish prop values in jsx runtime (#10584)Gravatar duanwilliam 2-1/+6
2024-03-28[ci] release (#10598)astro@4.5.12@astrojs/vercel@7.5.0@astrojs/markdoc@0.9.3@astrojs/internal-helpers@0.4.0@astrojs/db@0.9.8Gravatar Houston (Bot) 6-50/+52
2024-03-28[ci] formatGravatar TK 1-2/+2
2024-03-28feat: allow dynamic route segments in isr.exclude array (#10513)Gravatar TK 5-3/+69
2024-03-28[ci] formatGravatar Houston (Bot) 2-3/+3
2024-03-28[ci] release (#10597)Gravatar Houston (Bot) 37-66/+89
2024-03-28db: Rework index config with generated index names (#10589)Gravatar Ben Holmes 6-68/+344