nsresult FetchDriver::ContinueFetch(bool aCORSFlag) { workers::AssertIsOnMainThread(); nsAutoCString url; mRequest->GetURL(url); nsCOMPtr<nsIURI> requestURI; nsresult rv = NS_NewURI(getter_AddRefs(requestURI), url, nullptr, nullptr); if (NS_WARN_IF(NS_FAILED(rv))) { return FailWithNetworkError(); } // Begin Step 4 of the Fetch algorithm // https://fetch.spec.whatwg.org/#fetching // FIXME(nsm): Bug 1039846: Add CSP checks nsAutoCString scheme; rv = requestURI->GetScheme(scheme); if (NS_WARN_IF(NS_FAILED(rv))) { return FailWithNetworkError(); } rv = mPrincipal->CheckMayLoad(requestURI, false /* report */, false /* allowIfInheritsPrincipal */); if ((!aCORSFlag && NS_SUCCEEDED(rv)) || (scheme.EqualsLiteral("data") && mRequest->SameOriginDataURL()) || scheme.EqualsLiteral("about")) { return BasicFetch(); } if (mRequest->Mode() == RequestMode::Same_origin) { return FailWithNetworkError(); } if (mRequest->Mode() == RequestMode::No_cors) { mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_OPAQUE); return BasicFetch(); } if (!scheme.EqualsLiteral("http") && !scheme.EqualsLiteral("https")) { return FailWithNetworkError(); } bool corsPreflight = false; if (mRequest->Mode() == RequestMode::Cors_with_forced_preflight || (mRequest->UnsafeRequest() && (!mRequest->HasSimpleMethod() || !mRequest->Headers()->HasOnlySimpleHeaders()))) { corsPreflight = true; } mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_CORS); return HttpFetch(true /* aCORSFlag */, corsPreflight); }
nsresult FetchDriver::Fetch(AbortSignal* aSignal, FetchDriverObserver* aObserver) { AssertIsOnMainThread(); #ifdef DEBUG MOZ_ASSERT(!mFetchCalled); mFetchCalled = true; #endif mObserver = aObserver; Telemetry::Accumulate(Telemetry::SERVICE_WORKER_REQUEST_PASSTHROUGH, mRequest->WasCreatedByFetchEvent()); // FIXME(nsm): Deal with HSTS. MOZ_RELEASE_ASSERT(!mRequest->IsSynchronous(), "Synchronous fetch not supported"); UniquePtr<mozilla::ipc::PrincipalInfo> principalInfo(new mozilla::ipc::PrincipalInfo()); nsresult rv = PrincipalToPrincipalInfo(mPrincipal, principalInfo.get()); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } mRequest->SetPrincipalInfo(std::move(principalInfo)); // If the signal is aborted, it's time to inform the observer and terminate // the operation. if (aSignal) { if (aSignal->Aborted()) { Abort(); return NS_OK; } Follow(aSignal); } rv = HttpFetch(mRequest->GetPreferredAlternativeDataType()); if (NS_FAILED(rv)) { FailWithNetworkError(rv); } // Any failure is handled by FailWithNetworkError notifying the aObserver. return NS_OK; }
void CameraSubsystem::Tick(size_t tick) { // if capture is true then we should grab an image from the camera and display it if ( m_httpcapture == true ) { HttpFetch("http://localhost:8080/cam_1.jpg","camera.jpg"); IplImage *img = cvLoadImage("camera.jpg"); cvShowImage("camera",img); cvWaitKey(1); } if ( m_localcapture == true ) { VideoCapture camera(0); Mat camImage; camera >> camImage; imshow("camera", camImage); }
nsresult FetchDriver::ContinueFetch(bool aCORSFlag) { workers::AssertIsOnMainThread(); MainFetchOp nextOp = SetTaintingAndGetNextOp(aCORSFlag); if (nextOp.mType == NETWORK_ERROR) { return FailWithNetworkError(); } if (nextOp.mType == BASIC_FETCH) { return BasicFetch(); } if (nextOp.mType == HTTP_FETCH) { return HttpFetch(nextOp.mCORSFlag, nextOp.mCORSPreflightFlag); } MOZ_ASSERT_UNREACHABLE("Unexpected main fetch operation!"); return FailWithNetworkError(); }
nsresult FetchDriver::BasicFetch() { nsAutoCString url; mRequest->GetURL(url); nsCOMPtr<nsIURI> uri; nsresult rv = NS_NewURI(getter_AddRefs(uri), url, nullptr, nullptr); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } nsAutoCString scheme; rv = uri->GetScheme(scheme); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } if (scheme.LowerCaseEqualsLiteral("about")) { if (url.EqualsLiteral("about:blank")) { nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); ErrorResult result; response->Headers()->Append(NS_LITERAL_CSTRING("content-type"), NS_LITERAL_CSTRING("text/html;charset=utf-8"), result); MOZ_ASSERT(!result.Failed()); nsCOMPtr<nsIInputStream> body; rv = NS_NewCStringInputStream(getter_AddRefs(body), EmptyCString()); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } response->SetBody(body); BeginResponse(response); return SucceedWithResponse(); } return FailWithNetworkError(); } if (scheme.LowerCaseEqualsLiteral("blob")) { nsRefPtr<BlobImpl> blobImpl; rv = NS_GetBlobForBlobURI(uri, getter_AddRefs(blobImpl)); BlobImpl* blob = static_cast<BlobImpl*>(blobImpl.get()); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); ErrorResult result; uint64_t size = blob->GetSize(result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.StealNSResult(); } nsAutoString sizeStr; sizeStr.AppendInt(size); response->Headers()->Append(NS_LITERAL_CSTRING("Content-Length"), NS_ConvertUTF16toUTF8(sizeStr), result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.StealNSResult(); } nsAutoString type; blob->GetType(type); response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), NS_ConvertUTF16toUTF8(type), result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.StealNSResult(); } nsCOMPtr<nsIInputStream> stream; blob->GetInternalStream(getter_AddRefs(stream), result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.StealNSResult(); } response->SetBody(stream); BeginResponse(response); return SucceedWithResponse(); } if (scheme.LowerCaseEqualsLiteral("data")) { nsAutoCString method; mRequest->GetMethod(method); if (method.LowerCaseEqualsASCII("get")) { nsresult rv; nsCOMPtr<nsIProtocolHandler> dataHandler = do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "data", &rv); if (NS_WARN_IF(NS_FAILED(rv))) { return FailWithNetworkError(); } nsCOMPtr<nsIChannel> channel; rv = dataHandler->NewChannel(uri, getter_AddRefs(channel)); if (NS_WARN_IF(NS_FAILED(rv))) { return FailWithNetworkError(); } nsCOMPtr<nsIInputStream> stream; rv = channel->Open(getter_AddRefs(stream)); if (NS_WARN_IF(NS_FAILED(rv))) { return FailWithNetworkError(); } // nsDataChannel will parse the data URI when it is Open()ed and set the // correct content type and charset. nsAutoCString contentType; if (NS_SUCCEEDED(channel->GetContentType(contentType))) { nsAutoCString charset; if (NS_SUCCEEDED(channel->GetContentCharset(charset)) && !charset.IsEmpty()) { contentType.AppendLiteral(";charset="); contentType.Append(charset); } } else { NS_WARNING("Could not get content type from data channel"); } nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); ErrorResult result; response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), contentType, result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.StealNSResult(); } response->SetBody(stream); BeginResponse(response); return SucceedWithResponse(); } return FailWithNetworkError(); } if (scheme.LowerCaseEqualsLiteral("http") || scheme.LowerCaseEqualsLiteral("https") || scheme.LowerCaseEqualsLiteral("app")) { return HttpFetch(); } return FailWithNetworkError(); }
nsresult FetchDriver::ContinueFetch(bool aCORSFlag) { workers::AssertIsOnMainThread(); nsAutoCString url; mRequest->GetURL(url); nsCOMPtr<nsIURI> requestURI; nsresult rv = NS_NewURI(getter_AddRefs(requestURI), url, nullptr, nullptr); if (NS_WARN_IF(NS_FAILED(rv))) { return FailWithNetworkError(); } // CSP/mixed content checks. int16_t shouldLoad; rv = NS_CheckContentLoadPolicy(mRequest->ContentPolicyType(), requestURI, mPrincipal, mDocument, // FIXME(nsm): Should MIME be extracted from // Content-Type header? EmptyCString(), /* mime guess */ nullptr, /* extra */ &shouldLoad, nsContentUtils::GetContentPolicy(), nsContentUtils::GetSecurityManager()); if (NS_WARN_IF(NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad))) { // Disallowed by content policy. return FailWithNetworkError(); } // Begin Step 4 of the Fetch algorithm // https://fetch.spec.whatwg.org/#fetching nsAutoCString scheme; rv = requestURI->GetScheme(scheme); if (NS_WARN_IF(NS_FAILED(rv))) { return FailWithNetworkError(); } rv = mPrincipal->CheckMayLoad(requestURI, false /* report */, false /* allowIfInheritsPrincipal */); if ((!aCORSFlag && NS_SUCCEEDED(rv)) || (scheme.EqualsLiteral("data") && mRequest->SameOriginDataURL()) || scheme.EqualsLiteral("about")) { return BasicFetch(); } if (mRequest->Mode() == RequestMode::Same_origin) { return FailWithNetworkError(); } if (mRequest->Mode() == RequestMode::No_cors) { mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_OPAQUE); return BasicFetch(); } if (!scheme.EqualsLiteral("http") && !scheme.EqualsLiteral("https")) { return FailWithNetworkError(); } bool corsPreflight = false; if (mRequest->Mode() == RequestMode::Cors_with_forced_preflight || (mRequest->UnsafeRequest() && (!mRequest->HasSimpleMethod() || !mRequest->Headers()->HasOnlySimpleHeaders()))) { corsPreflight = true; } mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_CORS); return HttpFetch(true /* aCORSFlag */, corsPreflight); }
nsresult FetchDriver::BasicFetch() { nsAutoCString url; mRequest->GetURL(url); nsCOMPtr<nsIURI> uri; nsresult rv = NS_NewURI(getter_AddRefs(uri), url, nullptr, nullptr); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } nsAutoCString scheme; rv = uri->GetScheme(scheme); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } if (scheme.LowerCaseEqualsLiteral("about")) { if (url.EqualsLiteral("about:blank")) { nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); ErrorResult result; response->Headers()->Append(NS_LITERAL_CSTRING("content-type"), NS_LITERAL_CSTRING("text/html;charset=utf-8"), result); MOZ_ASSERT(!result.Failed()); nsCOMPtr<nsIInputStream> body; rv = NS_NewCStringInputStream(getter_AddRefs(body), EmptyCString()); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } response->SetBody(body); BeginResponse(response); return SucceedWithResponse(); } return FailWithNetworkError(); } if (scheme.LowerCaseEqualsLiteral("blob")) { nsRefPtr<BlobImpl> blobImpl; rv = NS_GetBlobForBlobURI(uri, getter_AddRefs(blobImpl)); BlobImpl* blob = static_cast<BlobImpl*>(blobImpl.get()); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); ErrorResult result; uint64_t size = blob->GetSize(result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.StealNSResult(); } nsAutoString sizeStr; sizeStr.AppendInt(size); response->Headers()->Append(NS_LITERAL_CSTRING("Content-Length"), NS_ConvertUTF16toUTF8(sizeStr), result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.StealNSResult(); } nsAutoString type; blob->GetType(type); response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), NS_ConvertUTF16toUTF8(type), result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.StealNSResult(); } nsCOMPtr<nsIInputStream> stream; blob->GetInternalStream(getter_AddRefs(stream), result); if (NS_WARN_IF(result.Failed())) { FailWithNetworkError(); return result.StealNSResult(); } response->SetBody(stream); BeginResponse(response); return SucceedWithResponse(); } if (scheme.LowerCaseEqualsLiteral("data")) { nsAutoCString method; mRequest->GetMethod(method); if (method.LowerCaseEqualsASCII("get")) { // Use nsDataHandler directly so that we can extract the content type. // XXX(nsm): Is there a way to acquire the charset without such tight // coupling with the DataHandler? nsIProtocolHandler does not provide // anything similar. nsAutoCString contentType, contentCharset, dataBuffer, hashRef; bool isBase64; rv = nsDataHandler::ParseURI(url, contentType, contentCharset, isBase64, dataBuffer, hashRef); if (NS_SUCCEEDED(rv)) { ErrorResult result; nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); if (!contentCharset.IsEmpty()) { contentType.Append(";charset="); contentType.Append(contentCharset); } response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), contentType, result); if (!result.Failed()) { nsCOMPtr<nsIInputStream> stream; rv = NS_NewCStringInputStream(getter_AddRefs(stream), dataBuffer); if (NS_SUCCEEDED(rv)) { response->SetBody(stream); BeginResponse(response); return SucceedWithResponse(); } } } } return FailWithNetworkError(); } if (scheme.LowerCaseEqualsLiteral("http") || scheme.LowerCaseEqualsLiteral("https") || scheme.LowerCaseEqualsLiteral("app")) { return HttpFetch(); } return FailWithNetworkError(); }