FetchResponseData* FetchResponseData::createCORSFilteredResponse( const HTTPHeaderSet& exposedHeaders) const { DCHECK_EQ(m_type, DefaultType); // "A CORS filtered response is a filtered response whose type is |CORS|, // header list excludes all headers in internal response's header list, // except those whose name is either one of `Cache-Control`, // `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, and // `Pragma`, and except those whose name is one of the values resulting from // parsing `Access-Control-Expose-Headers` in internal response's header // list." FetchResponseData* response = new FetchResponseData(CORSType, m_status, m_statusMessage); response->setURLList(m_urlList); for (size_t i = 0; i < m_headerList->size(); ++i) { const FetchHeaderList::Header* header = m_headerList->list()[i].get(); const String& name = header->first; const bool explicitlyExposed = exposedHeaders.contains(name); if (isOnAccessControlResponseHeaderWhitelist(name) || (explicitlyExposed && !FetchUtils::isForbiddenResponseHeaderName(name))) { if (explicitlyExposed) response->m_corsExposedHeaderNames.add(name); response->m_headerList->append(name, header->second); } } response->m_buffer = m_buffer; response->m_mimeType = m_mimeType; response->m_internalResponse = const_cast<FetchResponseData*>(this); return response; }
FetchResponseData* FetchResponseData::clone(ScriptState* scriptState) { FetchResponseData* newResponse = create(); newResponse->m_type = m_type; if (m_terminationReason) { newResponse->m_terminationReason = WTF::wrapUnique(new TerminationReason); *newResponse->m_terminationReason = *m_terminationReason; } newResponse->setURLList(m_urlList); newResponse->m_status = m_status; newResponse->m_statusMessage = m_statusMessage; newResponse->m_headerList = m_headerList->clone(); newResponse->m_mimeType = m_mimeType; newResponse->m_responseTime = m_responseTime; newResponse->m_cacheStorageCacheName = m_cacheStorageCacheName; newResponse->m_corsExposedHeaderNames = m_corsExposedHeaderNames; switch (m_type) { case BasicType: case CORSType: ASSERT(m_internalResponse); ASSERT(m_buffer == m_internalResponse->m_buffer); ASSERT(m_internalResponse->m_type == DefaultType); newResponse->m_internalResponse = m_internalResponse->clone(scriptState); m_buffer = m_internalResponse->m_buffer; newResponse->m_buffer = newResponse->m_internalResponse->m_buffer; break; case DefaultType: { ASSERT(!m_internalResponse); if (m_buffer) { BodyStreamBuffer* new1 = nullptr; BodyStreamBuffer* new2 = nullptr; m_buffer->tee(&new1, &new2); m_buffer = new1; newResponse->m_buffer = new2; } break; } case ErrorType: ASSERT(!m_internalResponse); ASSERT(!m_buffer); break; case OpaqueType: case OpaqueRedirectType: ASSERT(m_internalResponse); ASSERT(!m_buffer); ASSERT(m_internalResponse->m_type == DefaultType); newResponse->m_internalResponse = m_internalResponse->clone(scriptState); break; } return newResponse; }
FetchResponseData* FetchResponseData::createOpaqueRedirectFilteredResponse() const { DCHECK_EQ(m_type, DefaultType); // "An opaque filtered response is a filtered response whose type is // 'opaqueredirect', status is 0, status message is the empty byte sequence, // header list is the empty list, body is null, and cache state is 'none'." // // https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect FetchResponseData* response = new FetchResponseData(OpaqueRedirectType, 0, ""); response->setURLList(m_urlList); response->m_internalResponse = const_cast<FetchResponseData*>(this); return response; }
FetchResponseData* FetchResponseData::createBasicFilteredResponse() const { DCHECK_EQ(m_type, DefaultType); // "A basic filtered response is a filtered response whose type is |basic|, // header list excludes any headers in internal response's header list whose // name is `Set-Cookie` or `Set-Cookie2`." FetchResponseData* response = new FetchResponseData(BasicType, m_status, m_statusMessage); response->setURLList(m_urlList); for (size_t i = 0; i < m_headerList->size(); ++i) { const FetchHeaderList::Header* header = m_headerList->list()[i].get(); if (FetchUtils::isForbiddenResponseHeaderName(header->first)) continue; response->m_headerList->append(header->first, header->second); } response->m_buffer = m_buffer; response->m_mimeType = m_mimeType; response->m_internalResponse = const_cast<FetchResponseData*>(this); return response; }