Пример #1
0
void DataConsumerTee::create(ExecutionContext* executionContext, PassOwnPtr<FetchDataConsumerHandle> src, OwnPtr<FetchDataConsumerHandle>* dest1, OwnPtr<FetchDataConsumerHandle>* dest2)
{
    RefPtr<BlobDataHandle> blobDataHandle = src->obtainReader(nullptr)->drainAsBlobDataHandle(FetchDataConsumerHandle::Reader::AllowBlobWithInvalidSize);
    if (blobDataHandle) {
        *dest1 = FetchBlobDataConsumerHandle::create(executionContext, blobDataHandle);
        *dest2 = FetchBlobDataConsumerHandle::create(executionContext, blobDataHandle);
        return;
    }

    OwnPtr<WebDataConsumerHandle> webDest1, webDest2;
    DataConsumerTee::create(executionContext, static_cast<PassOwnPtr<WebDataConsumerHandle>>(std::move(src)), &webDest1, &webDest2);
    *dest1 = createFetchDataConsumerHandleFromWebHandle(std::move(webDest1));
    *dest2 = createFetchDataConsumerHandleFromWebHandle(std::move(webDest2));
    return;
}
PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::lock(ExecutionContext* executionContext)
{
    ASSERT(!isLocked());
    ++m_lockLevel;
    m_reader = nullptr;
    OwnPtr<FetchDataConsumerHandle> handle = m_handle.release();
    if (ReadableStream::Closed == m_stream->stateInternal())
        return createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumerHandle());
    if (ReadableStream::Errored == m_stream->stateInternal())
        return createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorDataConsumerHandle());

    TrackExceptionState exceptionState;
    m_streamReader = m_stream->getBytesReader(executionContext, exceptionState);
    return handle.release();
}
Пример #3
0
FetchResponseData* FetchResponseData::clone(ExecutionContext* executionContext)
{
    FetchResponseData* newResponse = create();
    newResponse->m_type = m_type;
    if (m_terminationReason) {
        newResponse->m_terminationReason = adoptPtr(new TerminationReason);
        *newResponse->m_terminationReason = *m_terminationReason;
    }
    newResponse->m_url = m_url;
    newResponse->m_status = m_status;
    newResponse->m_statusMessage = m_statusMessage;
    newResponse->m_headerList = m_headerList->clone();
    newResponse->m_mimeType = m_mimeType;

    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(executionContext);
        m_buffer = m_internalResponse->m_buffer;
        newResponse->m_buffer = newResponse->m_internalResponse->m_buffer;
        break;
    case DefaultType: {
        ASSERT(!m_internalResponse);
        if (m_buffer) {
            OwnPtr<WebDataConsumerHandle> handle1, handle2;
            DataConsumerTee::create(executionContext, m_buffer->releaseHandle(executionContext), &handle1, &handle2);
            m_buffer = new BodyStreamBuffer(createFetchDataConsumerHandleFromWebHandle(handle1.release()));
            newResponse->m_buffer = new BodyStreamBuffer(createFetchDataConsumerHandleFromWebHandle(handle2.release()));
        }
        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(executionContext);
        break;
    }
    return newResponse;
}
std::unique_ptr<FetchDataConsumerHandle> FetchBlobDataConsumerHandle::create(ExecutionContext* executionContext, PassRefPtr<BlobDataHandle> blobDataHandle)
{
    if (!blobDataHandle)
        return createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumerHandle());

    return wrapUnique(new FetchBlobDataConsumerHandle(executionContext, blobDataHandle, new DefaultLoaderFactory));
}
PassOwnPtr<FetchDataConsumerHandle> FetchBlobDataConsumerHandle::create(ExecutionContext* executionContext, PassRefPtr<BlobDataHandle> blobDataHandle, LoaderFactory* loaderFactory)
{
    if (!blobDataHandle)
        return createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumerHandle());

    return adoptPtr(new FetchBlobDataConsumerHandle(executionContext, blobDataHandle, loaderFactory));
}
Пример #6
0
Response* Response::create(ScriptState* scriptState, ScriptValue bodyValue, const Dictionary& init, ExceptionState& exceptionState)
{
    v8::Local<v8::Value> body = bodyValue.v8Value();
    ScriptValue reader;
    v8::Isolate* isolate = scriptState->isolate();
    ExecutionContext* executionContext = scriptState->executionContext();

    OwnPtr<FetchDataConsumerHandle> bodyHandle;
    String contentType;
    if (bodyValue.isUndefined() || bodyValue.isNull()) {
        // Note: The IDL processor cannot handle this situation. See
        // https://crbug.com/335871.
    } else if (V8Blob::hasInstance(body, isolate)) {
        Blob* blob = V8Blob::toImpl(body.As<v8::Object>());
        bodyHandle = FetchBlobDataConsumerHandle::create(executionContext, blob->blobDataHandle());
        contentType = blob->type();
    } else if (V8ArrayBuffer::hasInstance(body, isolate)) {
        bodyHandle = FetchFormDataConsumerHandle::create(V8ArrayBuffer::toImpl(body.As<v8::Object>()));
    } else if (V8ArrayBufferView::hasInstance(body, isolate)) {
        bodyHandle = FetchFormDataConsumerHandle::create(V8ArrayBufferView::toImpl(body.As<v8::Object>()));
    } else if (V8FormData::hasInstance(body, isolate)) {
        RefPtr<EncodedFormData> formData = V8FormData::toImpl(body.As<v8::Object>())->encodeMultiPartFormData();
        // Here we handle formData->boundary() as a C-style string. See
        // FormDataEncoder::generateUniqueBoundaryString.
        contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + formData->boundary().data();
        bodyHandle = FetchFormDataConsumerHandle::create(executionContext, formData.release());
    } else if (RuntimeEnabledFeatures::responseConstructedWithReadableStreamEnabled() && ReadableStreamOperations::isReadableStream(scriptState, bodyValue)) {
        bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, bodyValue);
        reader = ReadableStreamOperations::getReader(scriptState, bodyValue, exceptionState);
        if (exceptionState.hadException()) {
            reader = ScriptValue();
            bodyHandle = createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorDataConsumerHandle());
            exceptionState.clearException();
        } else {
            bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, reader);
        }
    } else {
        String string = toUSVString(isolate, body, exceptionState);
        if (exceptionState.hadException())
            return nullptr;
        bodyHandle = FetchFormDataConsumerHandle::create(string);
        contentType = "text/plain;charset=UTF-8";
    }
    // TODO(yhirano): Add the URLSearchParams case.
    Response* response = create(executionContext, bodyHandle.release(), contentType, ResponseInit(init, exceptionState), exceptionState);
    if (!exceptionState.hadException() && !reader.isEmpty()) {
        // Add a hidden reference so that the weak persistent in the
        // ReadableStreamDataConsumerHandle will be valid as long as the
        // Response is valid.
        v8::Local<v8::Value> wrapper = toV8(response, scriptState);
        if (wrapper.IsEmpty()) {
            exceptionState.throwTypeError("Cannot create a Response wrapper");
            return nullptr;
        }
        ASSERT(wrapper->IsObject());
        V8HiddenValue::setHiddenValue(scriptState, wrapper.As<v8::Object>(), V8HiddenValue::readableStreamReaderInResponse(scriptState->isolate()), reader.v8Value());
    }
    return response;
}
FetchRequestData* FetchRequestData::pass(ScriptState* scriptState)
{
    FetchRequestData* request = FetchRequestData::cloneExceptBody();
    if (m_buffer) {
        request->m_buffer = m_buffer;
        m_buffer = new BodyStreamBuffer(scriptState, createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumerHandle()));
        m_buffer->closeAndLockAndDisturb();
    }
    return request;
}
FetchRequestData* FetchRequestData::pass(ExecutionContext* executionContext)
{
    FetchRequestData* request = FetchRequestData::cloneExceptBody();
    if (m_buffer) {
        request->m_buffer = m_buffer;
        m_buffer = new BodyStreamBuffer(createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumerHandle()));
        m_buffer->stream()->setIsDisturbed();
    }
    return request;
}
void FetchManager::Loader::didReceiveResponse(unsigned long, const ResourceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle)
{
    ASSERT(handle);

    m_responseHttpStatusCode = response.httpStatusCode();

    // Recompute the tainting if the request was redirected to a different
    // origin.
    if (!SecurityOrigin::create(response.url())->isSameSchemeHostPort(m_request->origin().get())) {
        switch (m_request->mode()) {
        case WebURLRequest::FetchRequestModeSameOrigin:
            ASSERT_NOT_REACHED();
            break;
        case WebURLRequest::FetchRequestModeNoCORS:
            m_request->setResponseTainting(FetchRequestData::OpaqueTainting);
            break;
        case WebURLRequest::FetchRequestModeCORS:
        case WebURLRequest::FetchRequestModeCORSWithForcedPreflight:
            m_request->setResponseTainting(FetchRequestData::CORSTainting);
            break;
        }
    }
    FetchResponseData* responseData = FetchResponseData::createWithBuffer(BodyStreamBuffer::create(createFetchDataConsumerHandleFromWebHandle(handle)));
    responseData->setStatus(response.httpStatusCode());
    responseData->setStatusMessage(response.httpStatusText());
    for (auto& it : response.httpHeaderFields())
        responseData->headerList()->append(it.key, it.value);
    responseData->setURL(response.url());
    responseData->setMIMEType(response.mimeType());

    FetchResponseData* taintedResponse = responseData;
    switch (m_request->tainting()) {
    case FetchRequestData::BasicTainting:
        taintedResponse = responseData->createBasicFilteredResponse();
        break;
    case FetchRequestData::CORSTainting:
        taintedResponse = responseData->createCORSFilteredResponse();
        break;
    case FetchRequestData::OpaqueTainting:
        taintedResponse = responseData->createOpaqueFilteredResponse();
        break;
    }
    Response* r = Response::create(m_resolver->executionContext(), taintedResponse);
    r->headers()->setGuard(Headers::ImmutableGuard);
    m_resolver->resolve(r);
    m_resolver.clear();
}