void getResourceRequest(ResourceRequest& request, CFURLRequestRef cfRequest) { request = ResourceRequest(CFURLRequestGetURL(cfRequest)); request.setCachePolicy((ResourceRequestCachePolicy)CFURLRequestGetCachePolicy(cfRequest)); request.setTimeoutInterval(CFURLRequestGetTimeoutInterval(cfRequest)); request.setMainDocumentURL(KURL(CFURLRequestGetMainDocumentURL(cfRequest))); if (CFStringRef method = CFURLRequestCopyHTTPRequestMethod(cfRequest)) { request.setHTTPMethod(method); CFRelease(method); } request.setAllowHTTPCookies(CFURLRequestShouldHandleHTTPCookies(cfRequest)); if (CFDictionaryRef headers = CFURLRequestCopyAllHTTPHeaderFields(cfRequest)) { CFIndex headerCount = CFDictionaryGetCount(headers); Vector<const void*, 128> keys(headerCount); Vector<const void*, 128> values(headerCount); CFDictionaryGetKeysAndValues(headers, keys.data(), values.data()); for (int i = 0; i < headerCount; ++i) request.setHTTPHeaderField((CFStringRef)keys[i], (CFStringRef)values[i]); CFRelease(headers); } if (CFDataRef bodyData = CFURLRequestCopyHTTPRequestBody(cfRequest)) { request.setHTTPBody(new FormData(CFDataGetBytePtr(bodyData), CFDataGetLength(bodyData))); CFRelease(bodyData); } else if (CFReadStreamRef bodyStream = CFURLRequestCopyHTTPRequestBodyStream(cfRequest)) { if (FormData* formData = httpBodyFromStream(bodyStream)) request.setHTTPBody(formData); CFRelease(bodyStream); } // FIXME: what to do about arbitrary body streams? }
void ResourceHandleCFURLConnectionDelegateWithOperationQueue::setupRequest(CFMutableURLRequestRef request) { CFURLRef requestURL = CFURLRequestGetURL(request); if (!requestURL) return; m_originalScheme = adoptCF(CFURLCopyScheme(requestURL)); }
CFURLRequestRef ResourceHandleCFURLConnectionDelegateWithOperationQueue::willSendRequest(CFURLRequestRef cfRequest, CFURLResponseRef originalRedirectResponse) { // If the protocols of the new request and the current request match, this is not an HSTS redirect and we don't need to synthesize a redirect response. if (!originalRedirectResponse) { RetainPtr<CFStringRef> newScheme = adoptCF(CFURLCopyScheme(CFURLRequestGetURL(cfRequest))); if (CFStringCompare(newScheme.get(), m_originalScheme.get(), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { CFRetain(cfRequest); return cfRequest; } } RefPtr<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protector(this); dispatch_async(dispatch_get_main_queue(), ^{ if (!protector->hasHandle()) { continueWillSendRequest(nullptr); return; } LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::willSendRequest(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data()); RetainPtr<CFURLResponseRef> redirectResponse = synthesizeRedirectResponseIfNecessary(cfRequest, originalRedirectResponse); ASSERT(redirectResponse); ResourceRequest request = createResourceRequest(cfRequest, redirectResponse.get()); m_handle->willSendRequest(request, redirectResponse.get()); });
CFURLRequestRef ResourceHandleCFURLConnectionDelegateWithOperationQueue::willSendRequest(CFURLRequestRef cfRequest, CFURLResponseRef originalRedirectResponse) { // If the protocols of the new request and the current request match, this is not an HSTS redirect and we don't need to synthesize a redirect response. if (!originalRedirectResponse) { RetainPtr<CFStringRef> newScheme = adoptCF(CFURLCopyScheme(CFURLRequestGetURL(cfRequest))); if (CFStringCompare(newScheme.get(), m_originalScheme.get(), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { CFRetain(cfRequest); return cfRequest; } } ASSERT(!isMainThread()); // FIXME: The block implicitly copies protector object, which is wasteful. We should just call ref(), // capture "this" by pointer value, and use a C++ lambda to prevent other unintentional capturing. RefPtr<ResourceHandleCFURLConnectionDelegateWithOperationQueue> protectedThis(this); dispatch_async(dispatch_get_main_queue(), ^{ if (!protectedThis->hasHandle()) { continueWillSendRequest(nullptr); return; } LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::willSendRequest(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data()); RetainPtr<CFURLResponseRef> redirectResponse = synthesizeRedirectResponseIfNecessary(cfRequest, originalRedirectResponse); ASSERT(redirectResponse); ResourceRequest request = createResourceRequest(cfRequest, redirectResponse.get()); m_handle->willSendRequest(request, redirectResponse.get()); });
void ResourceHandleCFURLConnectionDelegateWithOperationQueue::setupRequest(CFMutableURLRequestRef request) { #if PLATFORM(IOS) CFURLRequestSetShouldStartSynchronously(request, 1); #endif CFURLRef requestURL = CFURLRequestGetURL(request); if (!requestURL) return; m_originalScheme = adoptCF(CFURLCopyScheme(requestURL)); }
void ResourceRequest::doUpdateResourceRequest() { if (!m_cfRequest) { *this = ResourceRequest(); return; } m_url = CFURLRequestGetURL(m_cfRequest.get()); m_cachePolicy = (ResourceRequestCachePolicy)CFURLRequestGetCachePolicy(m_cfRequest.get()); m_timeoutInterval = CFURLRequestGetTimeoutInterval(m_cfRequest.get()); m_firstPartyForCookies = CFURLRequestGetMainDocumentURL(m_cfRequest.get()); if (CFStringRef method = CFURLRequestCopyHTTPRequestMethod(m_cfRequest.get())) { m_httpMethod = method; CFRelease(method); } m_allowCookies = CFURLRequestShouldHandleHTTPCookies(m_cfRequest.get()); if (httpPipeliningEnabled()) m_priority = toResourceLoadPriority(wkGetHTTPPipeliningPriority(m_cfRequest.get())); m_httpHeaderFields.clear(); if (CFDictionaryRef headers = CFURLRequestCopyAllHTTPHeaderFields(m_cfRequest.get())) { CFIndex headerCount = CFDictionaryGetCount(headers); Vector<const void*, 128> keys(headerCount); Vector<const void*, 128> values(headerCount); CFDictionaryGetKeysAndValues(headers, keys.data(), values.data()); for (int i = 0; i < headerCount; ++i) m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]); CFRelease(headers); } m_responseContentDispositionEncodingFallbackArray.clear(); RetainPtr<CFArrayRef> encodingFallbacks(AdoptCF, copyContentDispositionEncodingFallbackArray(m_cfRequest.get())); if (encodingFallbacks) { CFIndex count = CFArrayGetCount(encodingFallbacks.get()); for (CFIndex i = 0; i < count; ++i) { CFStringEncoding encoding = reinterpret_cast<CFIndex>(CFArrayGetValueAtIndex(encodingFallbacks.get(), i)); if (encoding != kCFStringEncodingInvalidId) m_responseContentDispositionEncodingFallbackArray.append(CFStringConvertEncodingToIANACharSetName(encoding)); } } #if ENABLE(CACHE_PARTITIONING) RetainPtr<CFStringRef> cachePartition(AdoptCF, static_cast<CFStringRef>(_CFURLRequestCopyProtocolPropertyForKey(m_cfRequest.get(), wkCachePartitionKey()))); if (cachePartition) m_cachePartition = cachePartition.get(); #endif }
void ResourceRequest::doUpdateResourceRequest() { if (!m_cfRequest) { *this = ResourceRequest(); return; } m_url = CFURLRequestGetURL(m_cfRequest.get()); m_cachePolicy = (ResourceRequestCachePolicy)CFURLRequestGetCachePolicy(m_cfRequest.get()); m_timeoutInterval = CFURLRequestGetTimeoutInterval(m_cfRequest.get()); m_firstPartyForCookies = CFURLRequestGetMainDocumentURL(m_cfRequest.get()); if (CFStringRef method = CFURLRequestCopyHTTPRequestMethod(m_cfRequest.get())) { m_httpMethod = method; CFRelease(method); } m_allowCookies = CFURLRequestShouldHandleHTTPCookies(m_cfRequest.get()); m_httpHeaderFields.clear(); if (CFDictionaryRef headers = CFURLRequestCopyAllHTTPHeaderFields(m_cfRequest.get())) { CFIndex headerCount = CFDictionaryGetCount(headers); Vector<const void*, 128> keys(headerCount); Vector<const void*, 128> values(headerCount); CFDictionaryGetKeysAndValues(headers, keys.data(), values.data()); for (int i = 0; i < headerCount; ++i) m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]); CFRelease(headers); } m_responseContentDispositionEncodingFallbackArray.clear(); RetainPtr<CFArrayRef> encodingFallbacks(AdoptCF, copyContentDispositionEncodingFallbackArray(m_cfRequest.get())); if (encodingFallbacks) { CFIndex count = CFArrayGetCount(encodingFallbacks.get()); for (CFIndex i = 0; i < count; ++i) { CFStringEncoding encoding = reinterpret_cast<CFIndex>(CFArrayGetValueAtIndex(encodingFallbacks.get(), i)); if (encoding != kCFStringEncodingInvalidId) m_responseContentDispositionEncodingFallbackArray.append(CFStringConvertEncodingToIANACharSetName(encoding)); } } m_httpBody = httpBodyFromRequest(m_cfRequest.get()); }
RetainPtr<CFURLResponseRef> ResourceHandleCFURLConnectionDelegate::synthesizeRedirectResponseIfNecessary(CFURLRequestRef newRequest, CFURLResponseRef cfRedirectResponse) { if (cfRedirectResponse) return cfRedirectResponse; CFURLRef newURL = CFURLRequestGetURL(newRequest); RetainPtr<CFStringRef> newScheme = adoptCF(CFURLCopyScheme(newURL)); // If the protocols of the new request and the current request match, this is not an HSTS redirect and we shouldn't synthesize a redirect response. const ResourceRequest& currentRequest = m_handle->currentRequest(); if (currentRequest.url().protocol() == String(newScheme.get())) return nullptr; RetainPtr<CFURLRef> currentURL = currentRequest.url().createCFURL(); RetainPtr<CFHTTPMessageRef> responseMessage = adoptCF(CFHTTPMessageCreateResponse(0, 302, 0, kCFHTTPVersion1_1)); RetainPtr<CFURLRef> newAbsoluteURL = adoptCF(CFURLCopyAbsoluteURL(newURL)); CFHTTPMessageSetHeaderFieldValue(responseMessage.get(), CFSTR("Location"), CFURLGetString(newAbsoluteURL.get())); CFHTTPMessageSetHeaderFieldValue(responseMessage.get(), CFSTR("Cache-Control"), CFSTR("no-store")); RetainPtr<CFURLResponseRef> newResponse = adoptCF(CFURLResponseCreateWithHTTPResponse(0, currentURL.get(), responseMessage.get(), kCFURLCacheStorageNotAllowed)); return newResponse; }
void ResourceRequest::doUpdateResourceRequest() { if (!m_cfRequest) { #if PLATFORM(IOS) // <rdar://problem/9913526> // This is a hack to mimic the subtle behaviour of the Foundation based ResourceRequest // code. That code does not reset m_httpMethod if the NSURLRequest is nil. I filed // <https://bugs.webkit.org/show_bug.cgi?id=66336> to track that. // Another related bug is <https://bugs.webkit.org/show_bug.cgi?id=66350>. Fixing that // would, ideally, allow us to not have this hack. But unfortunately that caused layout test // failures. // Removal of this hack is tracked by <rdar://problem/9970499>. String httpMethod = m_httpMethod; *this = ResourceRequest(); m_httpMethod = httpMethod; #else *this = ResourceRequest(); #endif return; } m_url = CFURLRequestGetURL(m_cfRequest.get()); m_cachePolicy = (ResourceRequestCachePolicy)CFURLRequestGetCachePolicy(m_cfRequest.get()); m_timeoutInterval = CFURLRequestGetTimeoutInterval(m_cfRequest.get()); m_firstPartyForCookies = CFURLRequestGetMainDocumentURL(m_cfRequest.get()); if (CFStringRef method = CFURLRequestCopyHTTPRequestMethod(m_cfRequest.get())) { m_httpMethod = method; CFRelease(method); } m_allowCookies = CFURLRequestShouldHandleHTTPCookies(m_cfRequest.get()); if (resourcePrioritiesEnabled()) m_priority = toResourceLoadPriority(CFURLRequestGetRequestPriority(m_cfRequest.get())); m_httpHeaderFields.clear(); if (CFDictionaryRef headers = CFURLRequestCopyAllHTTPHeaderFields(m_cfRequest.get())) { CFIndex headerCount = CFDictionaryGetCount(headers); Vector<const void*, 128> keys(headerCount); Vector<const void*, 128> values(headerCount); CFDictionaryGetKeysAndValues(headers, keys.data(), values.data()); for (int i = 0; i < headerCount; ++i) m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]); CFRelease(headers); } m_responseContentDispositionEncodingFallbackArray.clear(); RetainPtr<CFArrayRef> encodingFallbacks = adoptCF(copyContentDispositionEncodingFallbackArray(m_cfRequest.get())); if (encodingFallbacks) { CFIndex count = CFArrayGetCount(encodingFallbacks.get()); for (CFIndex i = 0; i < count; ++i) { CFStringEncoding encoding = reinterpret_cast<CFIndex>(CFArrayGetValueAtIndex(encodingFallbacks.get(), i)); if (encoding != kCFStringEncodingInvalidId) m_responseContentDispositionEncodingFallbackArray.append(CFStringConvertEncodingToIANACharSetName(encoding)); } } #if ENABLE(CACHE_PARTITIONING) RetainPtr<CFStringRef> cachePartition = adoptCF(static_cast<CFStringRef>(_CFURLRequestCopyProtocolPropertyForKey(m_cfRequest.get(), wkCachePartitionKey()))); if (cachePartition) m_cachePartition = cachePartition.get(); #endif }