void BlobResourceHandle::notifyResponseOnSuccess() { ASSERT(isMainThread()); bool isRangeRequest = m_rangeOffset != kPositionNotSpecified; ResourceResponse response(firstRequest().url(), m_blobData->contentType(), m_totalRemainingSize, String()); response.setHTTPStatusCode(isRangeRequest ? httpPartialContent : httpOK); response.setHTTPStatusText(isRangeRequest ? httpPartialContentText : httpOKText); response.setHTTPHeaderField(HTTPHeaderName::ContentType, m_blobData->contentType()); response.setHTTPHeaderField(HTTPHeaderName::ContentLength, String::number(m_totalRemainingSize)); if (isRangeRequest) response.setHTTPHeaderField(HTTPHeaderName::ContentRange, ParsedContentRange(m_rangeOffset, m_rangeEnd, m_totalSize).headerValue()); // FIXME: If a resource identified with a blob: URL is a File object, user agents must use that file's name attribute, // as if the response had a Content-Disposition header with the filename parameter set to the File's name attribute. // Notably, this will affect a name suggested in "File Save As". // BlobResourceHandle cannot be used with downloading, and doesn't even wait for continueDidReceiveResponse. // It's currently client's responsibility to know that didReceiveResponseAsync cannot be used to convert a // load into a download or blobs. if (usesAsyncCallbacks()) client()->didReceiveResponseAsync(this, WTFMove(response)); else client()->didReceiveResponse(this, WTFMove(response)); }
void NetworkDataTaskBlob::didReceiveResponse(Error errorCode) { LOG(NetworkSession, "%p - NetworkDataTaskBlob::didReceiveResponse(%u)", this, static_cast<unsigned>(errorCode)); Ref<NetworkDataTaskBlob> protectedThis(*this); ResourceResponse response(m_firstRequest.url(), errorCode != Error::NoError ? "text/plain" : m_blobData->contentType(), errorCode != Error::NoError ? 0 : m_totalRemainingSize, String()); switch (errorCode) { case Error::NoError: { bool isRangeRequest = m_rangeOffset != kPositionNotSpecified; response.setHTTPStatusCode(isRangeRequest ? httpPartialContent : httpOK); response.setHTTPStatusText(isRangeRequest ? httpPartialContentText : httpOKText); response.setHTTPHeaderField(HTTPHeaderName::ContentType, m_blobData->contentType()); response.setHTTPHeaderField(HTTPHeaderName::ContentLength, String::number(m_totalRemainingSize)); if (isRangeRequest) response.setHTTPHeaderField(HTTPHeaderName::ContentRange, ParsedContentRange(m_rangeOffset, m_rangeEnd, m_totalSize).headerValue()); // FIXME: If a resource identified with a blob: URL is a File object, user agents must use that file's name attribute, // as if the response had a Content-Disposition header with the filename parameter set to the File's name attribute. // Notably, this will affect a name suggested in "File Save As". break; } case Error::RangeError: response.setHTTPStatusCode(httpRequestedRangeNotSatisfiable); response.setHTTPStatusText(httpRequestedRangeNotSatisfiableText); break; case Error::SecurityError: response.setHTTPStatusCode(httpNotAllowed); response.setHTTPStatusText(httpNotAllowedText); break; default: response.setHTTPStatusCode(httpInternalError); response.setHTTPStatusText(httpInternalErrorText); break; } m_client->didReceiveResponseNetworkSession(WTFMove(response), [this, protectedThis = WTFMove(protectedThis), errorCode](PolicyAction policyAction) { LOG(NetworkSession, "%p - NetworkDataTaskBlob::didReceiveResponse completionHandler (%u)", this, static_cast<unsigned>(policyAction)); if (m_state == State::Canceling || m_state == State::Completed) { clearStream(); return; } if (errorCode != Error::NoError) { didFinish(); return; } switch (policyAction) { case PolicyAction::PolicyUse: m_buffer.resize(bufferSize); read(); break; case PolicyAction::PolicyIgnore: break; case PolicyAction::PolicyDownload: download(); break; } }); }