nsresult MultipartFileImpl::GetInternalStream(nsIInputStream** aStream) { nsresult rv; *aStream = nullptr; nsCOMPtr<nsIMultiplexInputStream> stream = do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1"); NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE); uint32_t i; for (i = 0; i < mBlobImpls.Length(); i++) { nsCOMPtr<nsIInputStream> scratchStream; FileImpl* blobImpl = mBlobImpls.ElementAt(i).get(); rv = blobImpl->GetInternalStream(getter_AddRefs(scratchStream)); NS_ENSURE_SUCCESS(rv, rv); rv = stream->AppendStream(scratchStream); NS_ENSURE_SUCCESS(rv, rv); } stream.forget(aStream); return NS_OK; }
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<FileImpl> blobImpl; rv = NS_GetBlobForBlobURI(uri, getter_AddRefs(blobImpl)); FileImpl* blob = static_cast<FileImpl*>(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.ErrorCode(); } 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.ErrorCode(); } 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.ErrorCode(); } } nsCOMPtr<nsIInputStream> stream; rv = blob->GetInternalStream(getter_AddRefs(stream)); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(); return rv; } 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("file")) { } else if (scheme.LowerCaseEqualsLiteral("http") || scheme.LowerCaseEqualsLiteral("https")) { return HttpFetch(); } return FailWithNetworkError(); }