NS_IMETHODIMP nsSmtpService::NewChannel2(nsIURI *aURI, nsILoadInfo* aLoadInfo, nsIChannel **_retval) { NS_ENSURE_ARG_POINTER(aURI); // create an empty pipe for use with the input stream channel. nsCOMPtr<nsIAsyncInputStream> pipeIn; nsCOMPtr<nsIAsyncOutputStream> pipeOut; nsCOMPtr<nsIPipe> pipe = do_CreateInstance("@mozilla.org/pipe;1"); nsresult rv = pipe->Init(false, false, 0, 0); if (NS_FAILED(rv)) return rv; pipe->GetInputStream(getter_AddRefs(pipeIn)); pipe->GetOutputStream(getter_AddRefs(pipeOut)); pipeOut->Close(); if (aLoadInfo) { return NS_NewInputStreamChannelInternal(_retval, aURI, pipeIn, NS_LITERAL_CSTRING("application/x-mailto"), EmptyCString(), aLoadInfo); } nsCOMPtr<nsIPrincipal> nullPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv); NS_ASSERTION(NS_SUCCEEDED(rv), "CreateInstance of nullprincipal failed."); if (NS_FAILED(rv)) return rv; return NS_NewInputStreamChannel(_retval, aURI, pipeIn, nullPrincipal, nsILoadInfo::SEC_NORMAL, nsIContentPolicy::TYPE_OTHER, NS_LITERAL_CSTRING("application/x-mailto")); }
NS_IMETHODIMP nsAbMDBDirectory::GetDatabaseFile(nsIFile **aResult) { NS_ENSURE_ARG_POINTER(aResult); nsCString fileName; nsresult rv = GetStringValue("filename", EmptyCString(), fileName); NS_ENSURE_SUCCESS(rv, rv); if (fileName.IsEmpty()) return NS_ERROR_NOT_INITIALIZED; nsCOMPtr<nsIFile> dbFile; rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(dbFile)); NS_ENSURE_SUCCESS(rv, rv); rv = dbFile->AppendNative(fileName); NS_ENSURE_SUCCESS(rv, rv); NS_ADDREF(*aResult = dbFile); return NS_OK; }
already_AddRefed<Exception> CreateException(JSContext* aCx, nsresult aRv, const char* aMessage) { // Do we use DOM exceptions for this error code? switch (NS_ERROR_GET_MODULE(aRv)) { case NS_ERROR_MODULE_DOM: case NS_ERROR_MODULE_SVG: case NS_ERROR_MODULE_DOM_XPATH: case NS_ERROR_MODULE_DOM_INDEXEDDB: case NS_ERROR_MODULE_DOM_FILEHANDLE: case NS_ERROR_MODULE_DOM_BLUETOOTH: return DOMException::Create(aRv); default: break; } // If not, use the default. // aMessage can be null, so we can't use nsDependentCString on it. nsRefPtr<Exception> exception = new Exception(nsCString(aMessage), aRv, EmptyCString(), nullptr, nullptr); return exception.forget(); }
void WebBrowserPersistSerializeParent::ActorDestroy(ActorDestroyReason aWhy) { if (mFinish) { MOZ_ASSERT(aWhy != Deletion); // See comment in WebBrowserPersistDocumentParent::ActorDestroy // (or bug 1202887) for why this is deferred. nsCOMPtr<nsIRunnable> errorLater = NewRunnableMethod<nsCOMPtr<nsIWebBrowserPersistDocument>, nsCOMPtr<nsIOutputStream>, nsCString, nsresult>( "nsIWebBrowserPersistWriteCompletion::OnFinish", mFinish, &nsIWebBrowserPersistWriteCompletion::OnFinish, mDocument, mStream, EmptyCString(), NS_ERROR_FAILURE); NS_DispatchToCurrentThread(errorLater); mFinish = nullptr; } }
nsresult sbWatchFolderService::StartWatchingFolder() { // Don't start if the service is not in the |eStarted| state or if the // watch path is empty. if (mWatchPath.IsEmpty() || mServiceState != eStarted) { return NS_OK; } nsresult rv; mFileSystemWatcher = do_CreateInstance("@songbirdnest.com/filesystem/watcher;1", &rv); NS_ENSURE_SUCCESS(rv, rv); if (mFileSystemWatcherGUID.Equals(EmptyCString())) { // Init a new file-system watcher. The session GUID for the new watcher // will be saved in StopWatching(). TRACE(("%s: initiating new FS watcher for [%s]", __FUNCTION__, NS_ConvertUTF16toUTF8(mWatchPath).get())); rv = mFileSystemWatcher->Init(this, mWatchPath, PR_TRUE); NS_ENSURE_SUCCESS(rv, rv); } else { TRACE(("%s: initiating saved session %s", __FUNCTION__, mFileSystemWatcherGUID.get())); rv = mFileSystemWatcher->InitWithSession(mFileSystemWatcherGUID, this); NS_ENSURE_SUCCESS(rv, rv); } rv = mFileSystemWatcher->StartWatching(); NS_ENSURE_SUCCESS(rv, rv); // The service is now watching mServiceState = eWatching; return NS_OK; }
nsresult nsMsgFolderCache::InitExistingDB() { nsresult err = InitMDBInfo(); if (NS_FAILED(err)) return err; err = GetStore()->GetTable(GetEnv(), &m_allFoldersTableOID, &m_mdbAllFoldersTable); if (NS_SUCCEEDED(err) && m_mdbAllFoldersTable) { nsIMdbTableRowCursor* rowCursor = nsnull; err = m_mdbAllFoldersTable->GetTableRowCursor(GetEnv(), -1, &rowCursor); if (NS_SUCCEEDED(err) && rowCursor) { // iterate over the table rows and create nsMsgFolderCacheElements for each. while (PR_TRUE) { nsresult rv; nsIMdbRow* hdrRow; mdb_pos rowPos; rv = rowCursor->NextRow(GetEnv(), &hdrRow, &rowPos); if (NS_FAILED(rv) || !hdrRow) break; rv = AddCacheElement(EmptyCString(), hdrRow, nsnull); hdrRow->Release(); if (NS_FAILED(rv)) return rv; } rowCursor->Release(); } } else err = NS_ERROR_FAILURE; return err; }
void nsPACMan::ProcessPendingQ(nsresult status) { // Now, start any pending queries PRCList *node = PR_LIST_HEAD(&mPendingQ); while (node != &mPendingQ) { PendingPACQuery *query = static_cast<PendingPACQuery *>(node); node = PR_NEXT_LINK(node); if (NS_SUCCEEDED(status)) { // keep the query in the list (so we can complete it from Shutdown if // necessary). status = query->Start(nsIDNSService::RESOLVE_SPECULATE); } if (status == NS_ERROR_DNS_LOOKUP_QUEUE_FULL) { query->OnLookupComplete(NULL, NULL, NS_OK); status = NS_OK; } else if (NS_FAILED(status)) { // remove the query from the list PR_REMOVE_LINK(query); query->Complete(status, EmptyCString()); NS_RELEASE(query); } } }
nsresult nsFontFaceLoader::CheckLoadAllowed(nsIPrincipal* aSourcePrincipal, nsIURI* aTargetURI, nsISupports* aContext) { nsresult rv; if (!aSourcePrincipal) return NS_OK; // check with the security manager nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager(); rv = secMan->CheckLoadURIWithPrincipal(aSourcePrincipal, aTargetURI, nsIScriptSecurityManager::STANDARD); if (NS_FAILED(rv)) { return rv; } // check content policy PRInt16 shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_FONT, aTargetURI, aSourcePrincipal, aContext, EmptyCString(), // mime type nsnull, &shouldLoad, nsContentUtils::GetContentPolicy(), nsContentUtils::GetSecurityManager()); if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) { return NS_ERROR_CONTENT_BLOCKED; } return NS_OK; }
void nsHttpConnectionInfo::CloneAsDirectRoute(nsHttpConnectionInfo **outCI) { if (mRoutedHost.IsEmpty()) { *outCI = Clone(); return; } RefPtr<nsHttpConnectionInfo> clone = new nsHttpConnectionInfo(mOrigin, mOriginPort, EmptyCString(), mUsername, mProxyInfo, mOriginAttributes, mEndToEndSSL); // Make sure the anonymous, insecure-scheme, and private flags are transferred clone->SetAnonymous(GetAnonymous()); clone->SetPrivate(GetPrivate()); clone->SetInsecureScheme(GetInsecureScheme()); clone->SetNoSpdy(GetNoSpdy()); clone->SetBeConservative(GetBeConservative()); clone->SetTlsFlags(GetTlsFlags()); if (!mNetworkInterfaceId.IsEmpty()) { clone->SetNetworkInterfaceId(mNetworkInterfaceId); } clone.forget(outCI); }
nsresult HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI, nsIChannel *newChannel, bool preserveMethod, bool forProxy) { LOG(("HttpBaseChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d forProxy=%d]", this, newChannel, preserveMethod, forProxy)); PRUint32 newLoadFlags = mLoadFlags | LOAD_REPLACE; // if the original channel was using SSL and this channel is not using // SSL, then no need to inhibit persistent caching. however, if the // original channel was not using SSL and has INHIBIT_PERSISTENT_CACHING // set, then allow the flag to apply to the redirected channel as well. // since we force set INHIBIT_PERSISTENT_CACHING on all HTTPS channels, // we only need to check if the original channel was using SSL. if (mConnectionInfo->UsingSSL()) newLoadFlags &= ~INHIBIT_PERSISTENT_CACHING; // Do not pass along LOAD_CHECK_OFFLINE_CACHE newLoadFlags &= ~nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE; newChannel->SetLoadGroup(mLoadGroup); newChannel->SetNotificationCallbacks(mCallbacks); newChannel->SetLoadFlags(newLoadFlags); nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel); if (!httpChannel) return NS_OK; // no other options to set if (preserveMethod) { nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(httpChannel); nsCOMPtr<nsIUploadChannel2> uploadChannel2 = do_QueryInterface(httpChannel); if (mUploadStream && (uploadChannel2 || uploadChannel)) { // rewind upload stream nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream); if (seekable) seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0); // replicate original call to SetUploadStream... if (uploadChannel2) { const char *ctype = mRequestHead.PeekHeader(nsHttp::Content_Type); if (!ctype) ctype = ""; const char *clen = mRequestHead.PeekHeader(nsHttp::Content_Length); PRInt64 len = clen ? nsCRT::atoll(clen) : -1; uploadChannel2->ExplicitSetUploadStream( mUploadStream, nsDependentCString(ctype), len, nsDependentCString(mRequestHead.Method()), mUploadStreamHasHeaders); } else { if (mUploadStreamHasHeaders) { uploadChannel->SetUploadStream(mUploadStream, EmptyCString(), -1); } else { const char *ctype = mRequestHead.PeekHeader(nsHttp::Content_Type); const char *clen = mRequestHead.PeekHeader(nsHttp::Content_Length); if (!ctype) { ctype = "application/octet-stream"; } if (clen) { uploadChannel->SetUploadStream(mUploadStream, nsDependentCString(ctype), atoi(clen)); } } } } // since preserveMethod is true, we need to ensure that the appropriate // request method gets set on the channel, regardless of whether or not // we set the upload stream above. This means SetRequestMethod() will // be called twice if ExplicitSetUploadStream() gets called above. httpChannel->SetRequestMethod(nsDependentCString(mRequestHead.Method())); } // convey the referrer if one was used for this channel to the next one if (mReferrer) httpChannel->SetReferrer(mReferrer); // convey the mAllowPipelining flag httpChannel->SetAllowPipelining(mAllowPipelining); // convey the new redirection limit httpChannel->SetRedirectionLimit(mRedirectionLimit - 1); nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(newChannel); if (httpInternal) { // convey the mForceAllowThirdPartyCookie flag httpInternal->SetForceAllowThirdPartyCookie(mForceAllowThirdPartyCookie); // convey the spdy flag httpInternal->SetAllowSpdy(mAllowSpdy); // update the DocumentURI indicator since we are being redirected. // if this was a top-level document channel, then the new channel // should have its mDocumentURI point to newURI; otherwise, we // just need to pass along our mDocumentURI to the new channel. if (newURI && (mURI == mDocumentURI)) httpInternal->SetDocumentURI(newURI); else httpInternal->SetDocumentURI(mDocumentURI); // if there is a chain of keys for redirect-responses we transfer it to // the new channel (see bug #561276) if (mRedirectedCachekeys) { LOG(("HttpBaseChannel::SetupReplacementChannel " "[this=%p] transferring chain of redirect cache-keys", this)); httpInternal->SetCacheKeysRedirectChain(mRedirectedCachekeys.forget()); } } // transfer application cache information nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel = do_QueryInterface(newChannel); if (appCacheChannel) { appCacheChannel->SetApplicationCache(mApplicationCache); appCacheChannel->SetInheritApplicationCache(mInheritApplicationCache); // We purposely avoid transfering mChooseApplicationCache. } // transfer any properties nsCOMPtr<nsIWritablePropertyBag> bag(do_QueryInterface(newChannel)); if (bag) mPropertyHash.EnumerateRead(CopyProperties, bag.get()); // transfer timed channel enabled status nsCOMPtr<nsITimedChannel> timed(do_QueryInterface(newChannel)); if (timed) timed->SetTimingEnabled(mTimingEnabled); if (forProxy) { // Transfer all the headers from the previous channel // this is needed for any headers that are not covered by the code above // or have been set separately. e.g. manually setting Referer without // setting up mReferrer PRUint32 count = mRequestHead.Headers().Count(); for (PRUint32 i = 0; i < count; ++i) { nsHttpAtom header; const char *value = mRequestHead.Headers().PeekHeaderAt(i, header); httpChannel->SetRequestHeader(nsDependentCString(header), nsDependentCString(value), false); } } return NS_OK; }
NS_IMETHODIMP HttpBaseChannel::SetReferrer(nsIURI *referrer) { ENSURE_CALLED_BEFORE_ASYNC_OPEN(); // clear existing referrer, if any mReferrer = nsnull; mRequestHead.ClearHeader(nsHttp::Referer); if (!referrer) return NS_OK; // check referrer blocking pref PRUint32 referrerLevel; if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) referrerLevel = 1; // user action else referrerLevel = 2; // inline content if (gHttpHandler->ReferrerLevel() < referrerLevel) return NS_OK; nsCOMPtr<nsIURI> referrerGrip; nsresult rv; bool match; // // Strip off "wyciwyg://123/" from wyciwyg referrers. // // XXX this really belongs elsewhere since wyciwyg URLs aren't part of necko. // perhaps some sort of generic nsINestedURI could be used. then, if an URI // fails the whitelist test, then we could check for an inner URI and try // that instead. though, that might be too automatic. // rv = referrer->SchemeIs("wyciwyg", &match); if (NS_FAILED(rv)) return rv; if (match) { nsCAutoString path; rv = referrer->GetPath(path); if (NS_FAILED(rv)) return rv; PRUint32 pathLength = path.Length(); if (pathLength <= 2) return NS_ERROR_FAILURE; // Path is of the form "//123/http://foo/bar", with a variable number of digits. // To figure out where the "real" URL starts, search path for a '/', starting at // the third character. PRInt32 slashIndex = path.FindChar('/', 2); if (slashIndex == kNotFound) return NS_ERROR_FAILURE; // Get the charset of the original URI so we can pass it to our fixed up URI. nsCAutoString charset; referrer->GetOriginCharset(charset); // Replace |referrer| with a URI without wyciwyg://123/. rv = NS_NewURI(getter_AddRefs(referrerGrip), Substring(path, slashIndex + 1, pathLength - slashIndex - 1), charset.get()); if (NS_FAILED(rv)) return rv; referrer = referrerGrip.get(); } // // block referrer if not on our white list... // static const char *const referrerWhiteList[] = { "http", "https", "ftp", "gopher", nsnull }; match = false; const char *const *scheme = referrerWhiteList; for (; *scheme && !match; ++scheme) { rv = referrer->SchemeIs(*scheme, &match); if (NS_FAILED(rv)) return rv; } if (!match) return NS_OK; // kick out.... // // Handle secure referrals. // // Support referrals from a secure server if this is a secure site // and (optionally) if the host names are the same. // rv = referrer->SchemeIs("https", &match); if (NS_FAILED(rv)) return rv; if (match) { rv = mURI->SchemeIs("https", &match); if (NS_FAILED(rv)) return rv; if (!match) return NS_OK; if (!gHttpHandler->SendSecureXSiteReferrer()) { nsCAutoString referrerHost; nsCAutoString host; rv = referrer->GetAsciiHost(referrerHost); if (NS_FAILED(rv)) return rv; rv = mURI->GetAsciiHost(host); if (NS_FAILED(rv)) return rv; // GetAsciiHost returns lowercase hostname. if (!referrerHost.Equals(host)) return NS_OK; } } nsCOMPtr<nsIURI> clone; // // we need to clone the referrer, so we can: // (1) modify it // (2) keep a reference to it after returning from this function // // Use CloneIgnoringRef to strip away any fragment per RFC 2616 section 14.36 rv = referrer->CloneIgnoringRef(getter_AddRefs(clone)); if (NS_FAILED(rv)) return rv; // strip away any userpass; we don't want to be giving out passwords ;-) rv = clone->SetUserPass(EmptyCString()); if (NS_FAILED(rv)) return rv; nsCAutoString spec; rv = clone->GetAsciiSpec(spec); if (NS_FAILED(rv)) return rv; // finally, remember the referrer URI and set the Referer header. mReferrer = clone; mRequestHead.SetHeader(nsHttp::Referer, spec); return NS_OK; }
NS_IMETHODIMP nsAddbookProtocolHandler::NewChannel(nsIURI *aURI, nsILoadInfo *aLoadInfo, nsIChannel **_retval) { nsresult rv; nsCOMPtr<nsIAddbookUrl> addbookUrl = do_QueryInterface(aURI, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = addbookUrl->GetAddbookOperation(&mAddbookOperation); NS_ENSURE_SUCCESS(rv, rv); if (mAddbookOperation == nsIAddbookUrlOperation::InvalidUrl) { nsAutoString errorString; errorString.AssignLiteral("Unsupported format/operation requested for "); nsAutoCString spec; rv = aURI->GetSpec(spec); NS_ENSURE_SUCCESS(rv, rv); errorString.Append(NS_ConvertUTF8toUTF16(spec)); rv = GenerateXMLOutputChannel(errorString, addbookUrl, aURI, aLoadInfo, _retval); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } if (mAddbookOperation == nsIAddbookUrlOperation::AddVCard) { // create an empty pipe for use with the input stream channel. nsCOMPtr<nsIAsyncInputStream> pipeIn; nsCOMPtr<nsIAsyncOutputStream> pipeOut; nsCOMPtr<nsIPipe> pipe = do_CreateInstance("@mozilla.org/pipe;1"); rv = pipe->Init(false, false, 0, 0); NS_ENSURE_SUCCESS(rv, rv); // These always succeed because the pipe is initialized above. MOZ_ALWAYS_SUCCEEDS(pipe->GetInputStream(getter_AddRefs(pipeIn))); MOZ_ALWAYS_SUCCEEDS(pipe->GetOutputStream(getter_AddRefs(pipeOut))); pipeOut->Close(); if (aLoadInfo) { return NS_NewInputStreamChannelInternal( _retval, aURI, pipeIn.forget(), NS_LITERAL_CSTRING("application/x-addvcard"), EmptyCString(), aLoadInfo); } nsCOMPtr<nsIPrincipal> nullPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv); NS_ASSERTION(NS_SUCCEEDED(rv), "CreateInstance of nullprincipal failed."); if (NS_FAILED(rv)) return rv; return NS_NewInputStreamChannel( _retval, aURI, pipeIn.forget(), nullPrincipal, nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, nsIContentPolicy::TYPE_OTHER, NS_LITERAL_CSTRING("application/x-addvcard")); } nsString output; rv = GeneratePrintOutput(addbookUrl, output); if (NS_FAILED(rv)) { output.AssignLiteral("failed to print. url="); nsAutoCString spec; rv = aURI->GetSpec(spec); NS_ENSURE_SUCCESS(rv, rv); output.Append(NS_ConvertUTF8toUTF16(spec)); } rv = GenerateXMLOutputChannel(output, addbookUrl, aURI, aLoadInfo, _retval); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }
nsresult net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) { // NOTE: See also the implementation in nsURLHelperUnix.cpp // This matches it except for the HFS path handling and file // system charset conversion. nsresult rv; nsCOMPtr<nsILocalFile> localFile; rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(localFile)); if (NS_FAILED(rv)) return rv; nsCAutoString directory, fileBaseName, fileExtension, path; PRBool bHFSPath = PR_FALSE; rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension); if (NS_FAILED(rv)) return rv; if (!directory.IsEmpty()) { NS_EscapeURL(directory, esc_Directory|esc_AlwaysCopy, path); // The canonical form of file URLs on OSX use POSIX paths: // file:///path-name. // But, we still encounter file URLs that use HFS paths: // file:///volume-name/path-name // Determine that here and normalize HFS paths to POSIX. nsCAutoString possibleVolName; if (pathBeginsWithVolName(directory, possibleVolName)) { // Though we know it begins with a volume name, it could still // be a valid POSIX path if the boot drive is named "Mac HD" // and there is a directory "Mac HD" at its root. If such a // directory doesn't exist, we'll assume this is an HFS path. FSRef testRef; possibleVolName.Insert("/", 0); if (::FSPathMakeRef((UInt8*)possibleVolName.get(), &testRef, nsnull) != noErr) bHFSPath = PR_TRUE; } if (bHFSPath) { // "%2F"s need to become slashes, while all other slashes need to // become colons. If we start out by changing "%2F"s to colons, we // can reply on SwapSlashColon() to do what we need path.ReplaceSubstring("%2F", ":"); path.Cut(0, 1); // directory begins with '/' SwapSlashColon((char *)path.get()); // At this point, path is an HFS path made using the same // algorithm as nsURLHelperMac. We'll convert to POSIX below. } } if (!fileBaseName.IsEmpty()) NS_EscapeURL(fileBaseName, esc_FileBaseName|esc_AlwaysCopy, path); if (!fileExtension.IsEmpty()) { path += '.'; NS_EscapeURL(fileExtension, esc_FileExtension|esc_AlwaysCopy, path); } NS_UnescapeURL(path); if (path.Length() != strlen(path.get())) return NS_ERROR_FILE_INVALID_PATH; if (bHFSPath) convertHFSPathtoPOSIX(path, path); // assuming path is encoded in the native charset rv = localFile->InitWithNativePath(path); if (NS_FAILED(rv)) return rv; NS_ADDREF(*result = localFile); return NS_OK; }
nsresult nsIndexedToHTML::DoOnStartRequest(nsIRequest* request, nsISupports *aContext, nsCString& aBuffer) { nsresult rv; nsCOMPtr<nsIChannel> channel = do_QueryInterface(request); nsCOMPtr<nsIURI> uri; rv = channel->GetURI(getter_AddRefs(uri)); if (NS_FAILED(rv)) return rv; channel->SetContentType(NS_LITERAL_CSTRING("text/html")); mParser = do_CreateInstance("@mozilla.org/dirIndexParser;1",&rv); if (NS_FAILED(rv)) return rv; rv = mParser->SetListener(this); if (NS_FAILED(rv)) return rv; rv = mParser->OnStartRequest(request, aContext); if (NS_FAILED(rv)) return rv; nsAutoCString baseUri, titleUri; rv = uri->GetAsciiSpec(baseUri); if (NS_FAILED(rv)) return rv; titleUri = baseUri; nsCString parentStr; nsCString buffer; buffer.AppendLiteral("<!DOCTYPE html>\n<html>\n<head>\n"); // XXX - should be using the 300: line from the parser. // We can't guarantee that that comes before any entry, so we'd have to // buffer, and do other painful stuff. // I'll deal with this when I make the changes to handle welcome messages // The .. stuff should also come from the lower level protocols, but that // would muck up the XUL display // - bbaetz bool isScheme = false; bool isSchemeFile = false; if (NS_SUCCEEDED(uri->SchemeIs("ftp", &isScheme)) && isScheme) { // strip out the password here, so it doesn't show in the page title // This is done by the 300: line generation in ftp, but we don't use // that - see above nsAutoCString pw; rv = uri->GetPassword(pw); if (NS_FAILED(rv)) return rv; if (!pw.IsEmpty()) { nsCOMPtr<nsIURI> newUri; rv = uri->Clone(getter_AddRefs(newUri)); if (NS_FAILED(rv)) return rv; rv = newUri->SetPassword(EmptyCString()); if (NS_FAILED(rv)) return rv; rv = newUri->GetAsciiSpec(titleUri); if (NS_FAILED(rv)) return rv; } nsAutoCString path; rv = uri->GetPath(path); if (NS_FAILED(rv)) return rv; if (!path.EqualsLiteral("//") && !path.LowerCaseEqualsLiteral("/%2f")) { rv = uri->Resolve(NS_LITERAL_CSTRING(".."),parentStr); if (NS_FAILED(rv)) return rv; } } else if (NS_SUCCEEDED(uri->SchemeIs("file", &isSchemeFile)) && isSchemeFile) { nsCOMPtr<nsIFileURL> fileUrl = do_QueryInterface(uri); nsCOMPtr<nsIFile> file; rv = fileUrl->GetFile(getter_AddRefs(file)); if (NS_FAILED(rv)) return rv; file->SetFollowLinks(true); nsAutoCString url; rv = net_GetURLSpecFromFile(file, url); if (NS_FAILED(rv)) return rv; baseUri.Assign(url); nsCOMPtr<nsIFile> parent; rv = file->GetParent(getter_AddRefs(parent)); if (parent && NS_SUCCEEDED(rv)) { net_GetURLSpecFromDir(parent, url); if (NS_FAILED(rv)) return rv; parentStr.Assign(url); } // Directory index will be always encoded in UTF-8 if this is file url buffer.AppendLiteral("<meta charset=\"UTF-8\">\n"); } else if (NS_SUCCEEDED(uri->SchemeIs("jar", &isScheme)) && isScheme) { nsAutoCString path; rv = uri->GetPath(path); if (NS_FAILED(rv)) return rv; // a top-level jar directory URL is of the form jar:foo.zip!/ // path will be of the form foo.zip!/, and its last two characters // will be "!/" //XXX this won't work correctly when the name of the directory being //XXX displayed ends with "!", but then again, jar: URIs don't deal //XXX particularly well with such directories anyway if (!StringEndsWith(path, NS_LITERAL_CSTRING("!/"))) { rv = uri->Resolve(NS_LITERAL_CSTRING(".."), parentStr); if (NS_FAILED(rv)) return rv; } } else { // default behavior for other protocols is to assume the channel's // URL references a directory ending in '/' -- fixup if necessary. nsAutoCString path; rv = uri->GetPath(path); if (NS_FAILED(rv)) return rv; if (baseUri.Last() != '/') { baseUri.Append('/'); path.Append('/'); uri->SetPath(path); } if (!path.EqualsLiteral("/")) { rv = uri->Resolve(NS_LITERAL_CSTRING(".."), parentStr); if (NS_FAILED(rv)) return rv; } } buffer.AppendLiteral("<style type=\"text/css\">\n" ":root {\n" " font-family: sans-serif;\n" "}\n" "img {\n" " border: 0;\n" "}\n" "th {\n" " text-align: start;\n" " white-space: nowrap;\n" "}\n" "th > a {\n" " color: inherit;\n" "}\n" "table[order] > thead > tr > th {\n" " cursor: pointer;\n" "}\n" "table[order] > thead > tr > th::after {\n" " display: none;\n" " width: .8em;\n" " margin-inline-end: -.8em;\n" " text-align: end;\n" "}\n" "table[order=\"asc\"] > thead > tr > th::after {\n" " content: \"\\2193\"; /* DOWNWARDS ARROW (U+2193) */\n" "}\n" "table[order=\"desc\"] > thead > tr > th::after {\n" " content: \"\\2191\"; /* UPWARDS ARROW (U+2191) */\n" "}\n" "table[order][order-by=\"0\"] > thead > tr > th:first-child > a ,\n" "table[order][order-by=\"1\"] > thead > tr > th:first-child + th > a ,\n" "table[order][order-by=\"2\"] > thead > tr > th:first-child + th + th > a {\n" " text-decoration: underline;\n" "}\n" "table[order][order-by=\"0\"] > thead > tr > th:first-child::after ,\n" "table[order][order-by=\"1\"] > thead > tr > th:first-child + th::after ,\n" "table[order][order-by=\"2\"] > thead > tr > th:first-child + th + th::after {\n" " display: inline-block;\n" "}\n" "table.remove-hidden > tbody > tr.hidden-object {\n" " display: none;\n" "}\n" "td {\n" " white-space: nowrap;\n" "}\n" "table.ellipsis {\n" " width: 100%;\n" " table-layout: fixed;\n" " border-spacing: 0;\n" "}\n" "table.ellipsis > tbody > tr > td {\n" " padding: 0;\n" " overflow: hidden;\n" " text-overflow: ellipsis;\n" "}\n" "/* name */\n" "/* name */\n" "th:first-child {\n" " padding-inline-end: 2em;\n" "}\n" "/* size */\n" "th:first-child + th {\n" " padding-inline-end: 1em;\n" "}\n" "td:first-child + td {\n" " text-align: end;\n" " padding-inline-end: 1em;\n" "}\n" "/* date */\n" "td:first-child + td + td {\n" " padding-inline-start: 1em;\n" " padding-inline-end: .5em;\n" "}\n" "/* time */\n" "td:first-child + td + td + td {\n" " padding-inline-start: .5em;\n" "}\n" ".symlink {\n" " font-style: italic;\n" "}\n" ".dir ,\n" ".symlink ,\n" ".file {\n" " margin-inline-start: 20px;\n" "}\n" ".dir::before ,\n" ".file > img {\n" " margin-inline-end: 4px;\n" " margin-inline-start: -20px;\n" " max-width: 16px;\n" " max-height: 16px;\n" " vertical-align: middle;\n" "}\n" ".dir::before {\n" " content: url(resource://gre/res/html/folder.png);\n" "}\n" "</style>\n" "<link rel=\"stylesheet\" media=\"screen, projection\" type=\"text/css\"" " href=\"chrome://global/skin/dirListing/dirListing.css\">\n" "<script type=\"application/javascript\">\n" "'use strict';\n" "var gTable, gOrderBy, gTBody, gRows, gUI_showHidden;\n" "document.addEventListener(\"DOMContentLoaded\", function() {\n" " gTable = document.getElementsByTagName(\"table\")[0];\n" " gTBody = gTable.tBodies[0];\n" " if (gTBody.rows.length < 2)\n" " return;\n" " gUI_showHidden = document.getElementById(\"UI_showHidden\");\n" " var headCells = gTable.tHead.rows[0].cells,\n" " hiddenObjects = false;\n" " function rowAction(i) {\n" " return function(event) {\n" " event.preventDefault();\n" " orderBy(i);\n" " }\n" " }\n" " for (var i = headCells.length - 1; i >= 0; i--) {\n" " var anchor = document.createElement(\"a\");\n" " anchor.href = \"\";\n" " anchor.appendChild(headCells[i].firstChild);\n" " headCells[i].appendChild(anchor);\n" " headCells[i].addEventListener(\"click\", rowAction(i), true);\n" " }\n" " if (gUI_showHidden) {\n" " gRows = Array.slice(gTBody.rows);\n" " hiddenObjects = gRows.some(row => row.className == \"hidden-object\");\n" " }\n" " gTable.setAttribute(\"order\", \"\");\n" " if (hiddenObjects) {\n" " gUI_showHidden.style.display = \"block\";\n" " updateHidden();\n" " }\n" "}, \"false\");\n" "function compareRows(rowA, rowB) {\n" " var a = rowA.cells[gOrderBy].getAttribute(\"sortable-data\") || \"\";\n" " var b = rowB.cells[gOrderBy].getAttribute(\"sortable-data\") || \"\";\n" " var intA = +a;\n" " var intB = +b;\n" " if (a == intA && b == intB) {\n" " a = intA;\n" " b = intB;\n" " } else {\n" " a = a.toLowerCase();\n" " b = b.toLowerCase();\n" " }\n" " if (a < b)\n" " return -1;\n" " if (a > b)\n" " return 1;\n" " return 0;\n" "}\n" "function orderBy(column) {\n" " if (!gRows)\n" " gRows = Array.slice(gTBody.rows);\n" " var order;\n" " if (gOrderBy == column) {\n" " order = gTable.getAttribute(\"order\") == \"asc\" ? \"desc\" : \"asc\";\n" " } else {\n" " order = \"asc\";\n" " gOrderBy = column;\n" " gTable.setAttribute(\"order-by\", column);\n" " gRows.sort(compareRows);\n" " }\n" " gTable.removeChild(gTBody);\n" " gTable.setAttribute(\"order\", order);\n" " if (order == \"asc\")\n" " for (var i = 0; i < gRows.length; i++)\n" " gTBody.appendChild(gRows[i]);\n" " else\n" " for (var i = gRows.length - 1; i >= 0; i--)\n" " gTBody.appendChild(gRows[i]);\n" " gTable.appendChild(gTBody);\n" "}\n" "function updateHidden() {\n" " gTable.className = gUI_showHidden.getElementsByTagName(\"input\")[0].checked ?\n" " \"\" :\n" " \"remove-hidden\";\n" "}\n" "</script>\n"); buffer.AppendLiteral("<link rel=\"icon\" type=\"image/png\" href=\""); nsCOMPtr<nsIURI> innerUri = NS_GetInnermostURI(uri); if (!innerUri) return NS_ERROR_UNEXPECTED; nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(innerUri)); //XXX bug 388553: can't use skinnable icons here due to security restrictions if (fileURL) { //buffer.AppendLiteral("chrome://global/skin/dirListing/local.png"); buffer.AppendLiteral("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB" "AAAAAQCAYAAAAf8%2F9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9i" "ZSBJbWFnZVJlYWR5ccllPAAAAjFJREFUeNqsU8uOElEQPffR" "3XQ3ONASdBJCSBxHos5%2B3Bg3rvkCv8PElS78gPkO%2FATj" "QoUdO2ftrJiRh6aneTb9sOpC4weMN6lcuFV16pxDIfI8x12O" "YIDhcPiu2Wx%2B%2FHF5CW1Z6Jyegt%2FTNEWSJIjjGFEUIQ" "xDrFYrWFSzXC4%2FdLvd95pRKpXKy%2BpRFZ7nwaWo1%2BsG" "nQG2260BKJfLKJVKGI1GEEJw7ateryd0v993W63WEwjgxfn5" "obGYzgCbzcaEbdsIggDj8Riu6z6iUk9SYZMSx8W0LMsM%2FS" "KK75xnJlIq80anQXdbEp0OhcPJ0eiaJnGRMEyyPDsAKKUM9c" "lkYoDo3SZJzzSdp0VSKYmfV1co%2Bz580kw5KDIM8RbRfEnU" "f1HzxtQyMAGcaGruTKczMzEIaqhKifV6jd%2BzGQQB5llunF" "%2FM52BizC2K5sYPYvZcu653tjOM9O93wnYc08gmkgg4VAxi" "xfqFUJT36AYBZGd6PJkFCZnnlBxMp38gqIgLpZB0y4Nph18l" "yWh5FFbrOSxbl3V4G%2BVB7T4ajYYxTyuLtO%2BCvWGgJE1M" "c7JNsJEhvgw%2FQV4fo%2F24nbEsX2u1d5sVyn8sJO0ZAQiI" "YnFh%2BxrfLz%2Fj29cBS%2FO14zg3i8XigW3ZkErDtmKoeM" "%2BAJGRMnXeEPGKf0nCD1ydvkDzU9Jbc6OpR7WIw6L8lQ%2B" "4pQ1%2FlPF0RGM9Ns91Wmptk0GfB4EJkt77vXYj%2F8m%2B8" "y%2FkrwABHbz2H9V68DQAAAABJRU5ErkJggg%3D%3D"); } else { //buffer.AppendLiteral("chrome://global/skin/dirListing/remote.png"); buffer.AppendLiteral("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB" "AAAAAQCAYAAAAf8%2F9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9i" "ZSBJbWFnZVJlYWR5ccllPAAAAeBJREFUeNqcU81O20AQ%2Ft" "Z2AgQSYQRqL1UPVG2hAUQkxLEStz4DrXpLpD5Drz31Cajax%" "2Bghhx6qHIJURBTxIwQRwopCBbZjHMcOTrzermPipsSt1Iw0" "3p3ZmW%2B%2B2R0TxhgOD34wjCHZlQ0iDYz9yvEfhxMTCYhE" "QDIZhkxKd2sqzX2TOD2vBQCQhpPefng1ZP2dVPlLLdpL8SEM" "cxng%2Fbs0RIHhtgs4twxOh%2BHjZxvzDx%2F3GQQiDFISiR" "BLFMPKTRMollzcWECrDVhtxtdRVsL9youPxGj%2FbdfFlUZh" "tDyYbYqWRUdai1oQRZ5oHeHl2gNM%2B01Uqio8RlH%2Bnsaz" "JzNwXcq1B%2BiXPHprlEEymeBfXs1w8XxxihfyuXqoHqpoGj" "ZM04bddgG%2F9%2B8WGj87qDdsrK9m%2BoA%2BpbhQTDh2l1" "%2Bi2weNbSHMZyjvNXmVbqh9Fj5Oz27uEoP%2BSTxANruJs9" "L%2FT6P0ewqPx5nmiAG5f6AoCtN1PbJzuRyJAyDBzzSQYvEr" "f06yYxhGXlEa8H2KVGoasjwLx3Ewk858opQWXm%2B%2Fib9E" "QrBzclLLLy89xYvlpchvtixcX6uo1y%2FzsiwHrkIsgKbp%2" "BYWFOWicuqppoNTnStHzPFCPQhBEBOyGAX4JMADFetubi4BS" "YAAAAABJRU5ErkJggg%3D%3D"); } buffer.AppendLiteral("\">\n<title>"); // Everything needs to end in a /, // otherwise we end up linking to file:///foo/dirfile if (!mTextToSubURI) { mTextToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; } nsXPIDLCString encoding; rv = uri->GetOriginCharset(encoding); if (NS_FAILED(rv)) return rv; if (encoding.IsEmpty()) { encoding.AssignLiteral("UTF-8"); } nsXPIDLString unEscapeSpec; rv = mTextToSubURI->UnEscapeAndConvert(encoding, titleUri.get(), getter_Copies(unEscapeSpec)); // unescape may fail because // 1. file URL may be encoded in platform charset for backward compatibility // 2. query part may not be encoded in UTF-8 (see bug 261929) // so try the platform's default if this is file url if (NS_FAILED(rv) && isSchemeFile) { nsCOMPtr<nsIPlatformCharset> platformCharset(do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv)); NS_ENSURE_SUCCESS(rv, rv); nsAutoCString charset; rv = platformCharset->GetCharset(kPlatformCharsetSel_FileName, charset); NS_ENSURE_SUCCESS(rv, rv); rv = mTextToSubURI->UnEscapeAndConvert(charset.get(), titleUri.get(), getter_Copies(unEscapeSpec)); } if (NS_FAILED(rv)) return rv; nsXPIDLString htmlEscSpec; htmlEscSpec.Adopt(nsEscapeHTML2(unEscapeSpec.get(), unEscapeSpec.Length())); nsXPIDLString title; const char16_t* formatTitle[] = { htmlEscSpec.get() }; rv = mBundle->FormatStringFromName(MOZ_UTF16("DirTitle"), formatTitle, sizeof(formatTitle)/sizeof(char16_t*), getter_Copies(title)); if (NS_FAILED(rv)) return rv; // we want to convert string bundle to NCR // to ensure they're shown in any charsets AppendNonAsciiToNCR(title, buffer); buffer.AppendLiteral("</title>\n"); // If there is a quote character in the baseUri, then // lets not add a base URL. The reason for this is that // if we stick baseUri containing a quote into a quoted // string, the quote character will prematurely close // the base href string. This is a fall-back check; // that's why it is OK to not use a base rather than // trying to play nice and escaping the quotes. See bug // 358128. if (!baseUri.Contains('"')) { // Great, the baseUri does not contain a char that // will prematurely close the string. Go ahead an // add a base href, but only do so if we're not // dealing with a resource URI. nsCOMPtr<nsIURI> originalUri; rv = channel->GetOriginalURI(getter_AddRefs(originalUri)); bool wasResource = false; if (NS_FAILED(rv) || NS_FAILED(originalUri->SchemeIs("resource", &wasResource)) || !wasResource) { buffer.AppendLiteral("<base href=\""); nsAdoptingCString htmlEscapedUri(nsEscapeHTML(baseUri.get())); buffer.Append(htmlEscapedUri); buffer.AppendLiteral("\" />\n"); } } else { NS_ERROR("broken protocol handler didn't escape double-quote."); } nsCString direction(NS_LITERAL_CSTRING("ltr")); nsCOMPtr<nsIXULChromeRegistry> reg = mozilla::services::GetXULChromeRegistryService(); if (reg) { bool isRTL = false; reg->IsLocaleRTL(NS_LITERAL_CSTRING("global"), &isRTL); if (isRTL) { direction.AssignLiteral("rtl"); } } buffer.AppendLiteral("</head>\n<body dir=\""); buffer.Append(direction); buffer.AppendLiteral("\">\n<h1>"); const char16_t* formatHeading[] = { htmlEscSpec.get() }; rv = mBundle->FormatStringFromName(MOZ_UTF16("DirTitle"), formatHeading, sizeof(formatHeading)/sizeof(char16_t*), getter_Copies(title)); if (NS_FAILED(rv)) return rv; AppendNonAsciiToNCR(title, buffer); buffer.AppendLiteral("</h1>\n"); if (!parentStr.IsEmpty()) { nsXPIDLString parentText; rv = mBundle->GetStringFromName(MOZ_UTF16("DirGoUp"), getter_Copies(parentText)); if (NS_FAILED(rv)) return rv; buffer.AppendLiteral("<p id=\"UI_goUp\"><a class=\"up\" href=\""); nsAdoptingCString htmlParentStr(nsEscapeHTML(parentStr.get())); buffer.Append(htmlParentStr); buffer.AppendLiteral("\">"); AppendNonAsciiToNCR(parentText, buffer); buffer.AppendLiteral("</a></p>\n"); } if (isSchemeFile) { nsXPIDLString showHiddenText; rv = mBundle->GetStringFromName(MOZ_UTF16("ShowHidden"), getter_Copies(showHiddenText)); if (NS_FAILED(rv)) return rv; buffer.AppendLiteral("<p id=\"UI_showHidden\" style=\"display:none\"><label><input type=\"checkbox\" checked onchange=\"updateHidden()\">"); AppendNonAsciiToNCR(showHiddenText, buffer); buffer.AppendLiteral("</label></p>\n"); } buffer.AppendLiteral("<table>\n"); nsXPIDLString columnText; buffer.AppendLiteral(" <thead>\n" " <tr>\n" " <th>"); rv = mBundle->GetStringFromName(MOZ_UTF16("DirColName"), getter_Copies(columnText)); if (NS_FAILED(rv)) return rv; AppendNonAsciiToNCR(columnText, buffer); buffer.AppendLiteral("</th>\n" " <th>"); rv = mBundle->GetStringFromName(MOZ_UTF16("DirColSize"), getter_Copies(columnText)); if (NS_FAILED(rv)) return rv; AppendNonAsciiToNCR(columnText, buffer); buffer.AppendLiteral("</th>\n" " <th colspan=\"2\">"); rv = mBundle->GetStringFromName(MOZ_UTF16("DirColMTime"), getter_Copies(columnText)); if (NS_FAILED(rv)) return rv; AppendNonAsciiToNCR(columnText, buffer); buffer.AppendLiteral("</th>\n" " </tr>\n" " </thead>\n"); buffer.AppendLiteral(" <tbody>\n"); aBuffer = buffer; return rv; }
nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile, bool aLocal) { // Copied from nsAppFileLocationProvider (more or less) nsresult rv; nsCOMPtr<nsIFile> localDir; #if defined(XP_MACOSX) FSRef fsRef; OSType folderType; if (aLocal) { folderType = kCachedDataFolderType; } else { #ifdef MOZ_THUNDERBIRD folderType = kDomainLibraryFolderType; #else folderType = kApplicationSupportFolderType; #endif } OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef); NS_ENSURE_FALSE(err, NS_ERROR_FAILURE); rv = NS_NewNativeLocalFile(EmptyCString(), true, getter_AddRefs(localDir)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsILocalFileMac> dirFileMac = do_QueryInterface(localDir); NS_ENSURE_TRUE(dirFileMac, NS_ERROR_UNEXPECTED); rv = dirFileMac->InitWithFSRef(&fsRef); NS_ENSURE_SUCCESS(rv, rv); localDir = do_QueryInterface(dirFileMac, &rv); #elif defined(XP_IOS) nsAutoCString userDir; if (GetUIKitDirectory(aLocal, userDir)) { rv = NS_NewNativeLocalFile(userDir, true, getter_AddRefs(localDir)); } else { rv = NS_ERROR_FAILURE; } NS_ENSURE_SUCCESS(rv, rv); #elif defined(XP_WIN) nsString path; if (aLocal) { rv = GetShellFolderPath(CSIDL_LOCAL_APPDATA, path); if (NS_FAILED(rv)) rv = GetRegWindowsAppDataFolder(aLocal, path); } if (!aLocal || NS_FAILED(rv)) { rv = GetShellFolderPath(CSIDL_APPDATA, path); if (NS_FAILED(rv)) { if (!aLocal) rv = GetRegWindowsAppDataFolder(aLocal, path); } } NS_ENSURE_SUCCESS(rv, rv); rv = NS_NewLocalFile(path, true, getter_AddRefs(localDir)); #elif defined(MOZ_WIDGET_GONK) rv = NS_NewNativeLocalFile(NS_LITERAL_CSTRING("/data/b2g"), true, getter_AddRefs(localDir)); #elif defined(XP_UNIX) const char* homeDir = getenv("HOME"); if (!homeDir || !*homeDir) return NS_ERROR_FAILURE; #ifdef ANDROID /* We want (ProfD == ProfLD) on Android. */ aLocal = false; #endif if (aLocal) { // If $XDG_CACHE_HOME is defined use it, otherwise use $HOME/.cache. const char* cacheHome = getenv("XDG_CACHE_HOME"); if (cacheHome && *cacheHome) { rv = NS_NewNativeLocalFile(nsDependentCString(cacheHome), true, getter_AddRefs(localDir)); } else { rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true, getter_AddRefs(localDir)); if (NS_SUCCEEDED(rv)) rv = localDir->AppendNative(NS_LITERAL_CSTRING(".cache")); } } else { rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true, getter_AddRefs(localDir)); } #else #error "Don't know how to get product dir on your platform" #endif NS_IF_ADDREF(*aFile = localDir); return rv; }
nsresult nsHttpTransaction::ParseHead(char *buf, PRUint32 count, PRUint32 *countRead) { nsresult rv; PRUint32 len; char *eol; LOG(("nsHttpTransaction::ParseHead [count=%u]\n", count)); *countRead = 0; NS_PRECONDITION(!mHaveAllHeaders, "oops"); // allocate the response head object if necessary if (!mResponseHead) { mResponseHead = new nsHttpResponseHead(); if (!mResponseHead) return NS_ERROR_OUT_OF_MEMORY; // report that we have a least some of the response if (mActivityDistributor) mActivityDistributor->ObserveActivity( mChannel, NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_START, PR_Now(), LL_ZERO, EmptyCString()); } // if we don't have a status line and the line buf is empty, then // this must be the first time we've been called. if (!mHaveStatusLine && mLineBuf.IsEmpty()) { // tolerate some junk before the status line char *p = LocateHttpStart(buf, PR_MIN(count, 8)); if (!p) { // Treat any 0.9 style response of a put as a failure. if (mRequestHead->Method() == nsHttp::Put) return NS_ERROR_ABORT; mResponseHead->ParseStatusLine(""); mHaveStatusLine = PR_TRUE; mHaveAllHeaders = PR_TRUE; return NS_OK; } if (p > buf) { // skip over the junk *countRead = p - buf; buf = p; } } // otherwise we can assume that we don't have a HTTP/0.9 response. while ((eol = static_cast<char *>(memchr(buf, '\n', count - *countRead))) != nsnull) { // found line in range [buf:eol] len = eol - buf + 1; *countRead += len; // actually, the line is in the range [buf:eol-1] if ((eol > buf) && (*(eol-1) == '\r')) len--; buf[len-1] = '\n'; rv = ParseLineSegment(buf, len); if (NS_FAILED(rv)) return rv; if (mHaveAllHeaders) return NS_OK; // skip over line buf = eol + 1; } // do something about a partial header line if (!mHaveAllHeaders && (len = count - *countRead)) { *countRead = count; // ignore a trailing carriage return, and don't bother calling // ParseLineSegment if buf only contains a carriage return. if ((buf[len-1] == '\r') && (--len == 0)) return NS_OK; rv = ParseLineSegment(buf, len); if (NS_FAILED(rv)) return rv; } return NS_OK; }
void nsHttpTransaction::OnTransportStatus(nsresult status, PRUint64 progress) { LOG(("nsHttpTransaction::OnSocketStatus [this=%x status=%x progress=%llu]\n", this, status, progress)); if (!mTransportSink) return; NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); // Need to do this before the STATUS_RECEIVING_FROM check below, to make // sure that the activity distributor gets told about all status events. if (mActivityDistributor) { // upon STATUS_WAITING_FOR; report request body sent if ((mHasRequestBody) && (status == nsISocketTransport::STATUS_WAITING_FOR)) mActivityDistributor->ObserveActivity( mChannel, NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_BODY_SENT, PR_Now(), LL_ZERO, EmptyCString()); // report the status and progress mActivityDistributor->ObserveActivity( mChannel, NS_HTTP_ACTIVITY_TYPE_SOCKET_TRANSPORT, static_cast<PRUint32>(status), PR_Now(), progress, EmptyCString()); } // nsHttpChannel synthesizes progress events in OnDataAvailable if (status == nsISocketTransport::STATUS_RECEIVING_FROM) return; PRUint64 progressMax; if (status == nsISocketTransport::STATUS_SENDING_TO) { // suppress progress when only writing request headers if (!mHasRequestBody) return; nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mRequestStream); NS_ASSERTION(seekable, "Request stream isn't seekable?!?"); PRInt64 prog = 0; seekable->Tell(&prog); progress = prog; // when uploading, we include the request headers in the progress // notifications. progressMax = mRequestSize; // XXX mRequestSize is 32-bit! } else { progress = LL_ZERO; progressMax = 0; } mTransportSink->OnTransportStatus(nsnull, status, progress, progressMax); }
nsresult CacheStorageService::AddStorageEntry(nsCSubstring const& aContextKey, nsIURI* aURI, const nsACString & aIdExtension, bool aWriteToDisk, bool aCreateIfNotExist, bool aReplace, CacheEntryHandle** aResult) { NS_ENSURE_ARG(aURI); nsresult rv; nsAutoCString entryKey; rv = CacheEntry::HashingKey(EmptyCString(), aIdExtension, aURI, entryKey); NS_ENSURE_SUCCESS(rv, rv); LOG(("CacheStorageService::AddStorageEntry [entryKey=%s, contextKey=%s]", entryKey.get(), aContextKey.BeginReading())); nsRefPtr<CacheEntry> entry; nsRefPtr<CacheEntryHandle> handle; { mozilla::MutexAutoLock lock(mLock); NS_ENSURE_FALSE(mShutdown, NS_ERROR_NOT_INITIALIZED); // Ensure storage table CacheEntryTable* entries; if (!sGlobalEntryTables->Get(aContextKey, &entries)) { entries = new CacheEntryTable(CacheEntryTable::ALL_ENTRIES); sGlobalEntryTables->Put(aContextKey, entries); LOG((" new storage entries table for context %s", aContextKey.BeginReading())); } bool entryExists = entries->Get(entryKey, getter_AddRefs(entry)); // check whether the file is already doomed if (entryExists && entry->IsFileDoomed() && !aReplace) { aReplace = true; } // If truncate is demanded, delete and doom the current entry if (entryExists && aReplace) { entries->Remove(entryKey); LOG((" dooming entry %p for %s because of OPEN_TRUNCATE", entry.get(), entryKey.get())); // On purpose called under the lock to prevent races of doom and open on I/O thread // No need to remove from both memory-only and all-entries tables. The new entry // will overwrite the shadow entry in its ctor. entry->DoomAlreadyRemoved(); entry = nullptr; entryExists = false; } if (entryExists && entry->SetUsingDisk(aWriteToDisk)) { RecordMemoryOnlyEntry(entry, !aWriteToDisk, true /* overwrite */); } // Ensure entry for the particular URL, if not read/only if (!entryExists && (aCreateIfNotExist || aReplace)) { // Entry is not in the hashtable or has just been truncated... entry = new CacheEntry(aContextKey, aURI, aIdExtension, aWriteToDisk); entries->Put(entryKey, entry); LOG((" new entry %p for %s", entry.get(), entryKey.get())); } if (entry) { // Here, if this entry was not for a long time referenced by any consumer, // gets again first 'handles count' reference. handle = entry->NewHandle(); } } handle.forget(aResult); return NS_OK; }
nsresult CacheStorageService::DoomStorageEntry(CacheStorage const* aStorage, nsIURI *aURI, const nsACString & aIdExtension, nsICacheEntryDoomCallback* aCallback) { LOG(("CacheStorageService::DoomStorageEntry")); NS_ENSURE_ARG(aStorage); NS_ENSURE_ARG(aURI); nsAutoCString contextKey; CacheFileUtils::AppendKeyPrefix(aStorage->LoadInfo(), contextKey); nsAutoCString entryKey; nsresult rv = CacheEntry::HashingKey(EmptyCString(), aIdExtension, aURI, entryKey); NS_ENSURE_SUCCESS(rv, rv); nsRefPtr<CacheEntry> entry; { mozilla::MutexAutoLock lock(mLock); NS_ENSURE_FALSE(mShutdown, NS_ERROR_NOT_INITIALIZED); CacheEntryTable* entries; if (sGlobalEntryTables->Get(contextKey, &entries)) { if (entries->Get(entryKey, getter_AddRefs(entry))) { if (aStorage->WriteToDisk() || !entry->IsUsingDiskLocked()) { // When evicting from disk storage, purge // When evicting from memory storage and the entry is memory-only, purge LOG((" purging entry %p for %s [storage use disk=%d, entry use disk=%d]", entry.get(), entryKey.get(), aStorage->WriteToDisk(), entry->IsUsingDiskLocked())); entries->Remove(entryKey); } else { // Otherwise, leave it LOG((" leaving entry %p for %s [storage use disk=%d, entry use disk=%d]", entry.get(), entryKey.get(), aStorage->WriteToDisk(), entry->IsUsingDiskLocked())); entry = nullptr; } } } } if (entry) { LOG((" dooming entry %p for %s", entry.get(), entryKey.get())); return entry->AsyncDoom(aCallback); } LOG((" no entry loaded for %s", entryKey.get())); if (aStorage->WriteToDisk()) { nsAutoCString contextKey; CacheFileUtils::AppendKeyPrefix(aStorage->LoadInfo(), contextKey); rv = CacheEntry::HashingKey(contextKey, aIdExtension, aURI, entryKey); NS_ENSURE_SUCCESS(rv, rv); LOG((" dooming file only for %s", entryKey.get())); nsRefPtr<CacheEntryDoomByKeyCallback> callback( new CacheEntryDoomByKeyCallback(aCallback)); rv = CacheFileIOManager::DoomFileByKey(entryKey, callback); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } if (aCallback) aCallback->OnCacheEntryDoomed(NS_ERROR_NOT_AVAILABLE); return NS_OK; }
static nsresult DoContentSecurityChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo) { nsContentPolicyType contentPolicyType = aLoadInfo->GetExternalContentPolicyType(); nsContentPolicyType internalContentPolicyType = aLoadInfo->InternalContentPolicyType(); nsCString mimeTypeGuess; nsCOMPtr<nsINode> requestingContext = nullptr; switch(contentPolicyType) { case nsIContentPolicy::TYPE_OTHER: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); break; } case nsIContentPolicy::TYPE_SCRIPT: { mimeTypeGuess = NS_LITERAL_CSTRING("application/javascript"); requestingContext = aLoadInfo->LoadingNode(); break; } case nsIContentPolicy::TYPE_IMAGE: { MOZ_ASSERT(false, "contentPolicyType not supported yet"); break; } case nsIContentPolicy::TYPE_STYLESHEET: { mimeTypeGuess = NS_LITERAL_CSTRING("text/css"); requestingContext = aLoadInfo->LoadingNode(); break; } case nsIContentPolicy::TYPE_OBJECT: case nsIContentPolicy::TYPE_DOCUMENT: { MOZ_ASSERT(false, "contentPolicyType not supported yet"); break; } case nsIContentPolicy::TYPE_SUBDOCUMENT: { mimeTypeGuess = NS_LITERAL_CSTRING("text/html"); requestingContext = aLoadInfo->LoadingNode(); MOZ_ASSERT(!requestingContext || requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE, "type_subdocument requires requestingContext of type Document"); break; } case nsIContentPolicy::TYPE_REFRESH: { MOZ_ASSERT(false, "contentPolicyType not supported yet"); break; } case nsIContentPolicy::TYPE_XBL: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); break; } case nsIContentPolicy::TYPE_PING: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); break; } case nsIContentPolicy::TYPE_XMLHTTPREQUEST: { // alias nsIContentPolicy::TYPE_DATAREQUEST: requestingContext = aLoadInfo->LoadingNode(); MOZ_ASSERT(!requestingContext || requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE, "type_xml requires requestingContext of type Document"); // We're checking for the external TYPE_XMLHTTPREQUEST here in case // an addon creates a request with that type. if (internalContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST || internalContentPolicyType == nsIContentPolicy::TYPE_XMLHTTPREQUEST) { mimeTypeGuess = EmptyCString(); } else { MOZ_ASSERT(internalContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE, "can not set mime type guess for unexpected internal type"); mimeTypeGuess = NS_LITERAL_CSTRING(TEXT_EVENT_STREAM); } break; } case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); MOZ_ASSERT(!requestingContext || requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE, "type_subrequest requires requestingContext of type Element"); break; } case nsIContentPolicy::TYPE_DTD: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); MOZ_ASSERT(!requestingContext || requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE, "type_dtd requires requestingContext of type Document"); break; } case nsIContentPolicy::TYPE_FONT: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); break; } case nsIContentPolicy::TYPE_MEDIA: { if (internalContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_TRACK) { mimeTypeGuess = NS_LITERAL_CSTRING("text/vtt"); } else { mimeTypeGuess = EmptyCString(); } requestingContext = aLoadInfo->LoadingNode(); MOZ_ASSERT(!requestingContext || requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE, "type_media requires requestingContext of type Element"); break; } case nsIContentPolicy::TYPE_WEBSOCKET: { MOZ_ASSERT(false, "contentPolicyType not supported yet"); break; } case nsIContentPolicy::TYPE_CSP_REPORT: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); break; } case nsIContentPolicy::TYPE_XSLT: { mimeTypeGuess = NS_LITERAL_CSTRING("application/xml"); requestingContext = aLoadInfo->LoadingNode(); MOZ_ASSERT(!requestingContext || requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE, "type_xslt requires requestingContext of type Document"); break; } case nsIContentPolicy::TYPE_BEACON: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); MOZ_ASSERT(!requestingContext || requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE, "type_beacon requires requestingContext of type Document"); break; } case nsIContentPolicy::TYPE_FETCH: { mimeTypeGuess = EmptyCString(); requestingContext = aLoadInfo->LoadingNode(); break; } case nsIContentPolicy::TYPE_IMAGESET: { MOZ_ASSERT(false, "contentPolicyType not supported yet"); break; } default: // nsIContentPolicy::TYPE_INVALID MOZ_ASSERT(false, "can not perform security check without a valid contentType"); } int16_t shouldLoad = nsIContentPolicy::ACCEPT; nsresult rv = NS_CheckContentLoadPolicy(internalContentPolicyType, aURI, aLoadInfo->LoadingPrincipal(), requestingContext, mimeTypeGuess, nullptr, //extra, &shouldLoad, nsContentUtils::GetContentPolicy(), nsContentUtils::GetSecurityManager()); NS_ENSURE_SUCCESS(rv, rv); if (NS_CP_REJECTED(shouldLoad)) { return NS_ERROR_CONTENT_BLOCKED; } return NS_OK; }
void nsHttpTransaction::Close(nsresult reason) { LOG(("nsHttpTransaction::Close [this=%x reason=%x]\n", this, reason)); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); if (mClosed) { LOG((" already closed\n")); return; } if (mActivityDistributor) { // report the reponse is complete if not already reported if (!mResponseIsComplete) mActivityDistributor->ObserveActivity( mChannel, NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_COMPLETE, PR_Now(), static_cast<PRUint64>(mContentRead.mValue), EmptyCString()); // report that this transaction is closing mActivityDistributor->ObserveActivity( mChannel, NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, NS_HTTP_ACTIVITY_SUBTYPE_TRANSACTION_CLOSE, PR_Now(), LL_ZERO, EmptyCString()); } // we must no longer reference the connection! find out if the // connection was being reused before letting it go. PRBool connReused = PR_FALSE; if (mConnection) connReused = mConnection->IsReused(); mConnected = PR_FALSE; // // if the connection was reset or closed before we wrote any part of the // request or if we wrote the request but didn't receive any part of the // response and the connection was being reused, then we can (and really // should) assume that we wrote to a stale connection and we must therefore // repeat the request over a new connection. // // NOTE: the conditions under which we will automatically retry the HTTP // request have to be carefully selected to avoid duplication of the // request from the point-of-view of the server. such duplication could // have dire consequences including repeated purchases, etc. // // NOTE: because of the way SSL proxy CONNECT is implemented, it is // possible that the transaction may have received data without having // sent any data. for this reason, mSendData == FALSE does not imply // mReceivedData == FALSE. (see bug 203057 for more info.) // if (reason == NS_ERROR_NET_RESET || reason == NS_OK) { if (!mReceivedData && (!mSentData || connReused)) { // if restarting fails, then we must proceed to close the pipe, // which will notify the channel that the transaction failed. if (NS_SUCCEEDED(Restart())) return; } } PRBool relConn = PR_TRUE; if (NS_SUCCEEDED(reason)) { // the server has not sent the final \r\n terminating the header // section, and there may still be a header line unparsed. let's make // sure we parse the remaining header line, and then hopefully, the // response will be usable (see bug 88792). related to that, we may // also have an empty response containing no headers. we should treat // that as an empty HTTP/0.9 response (see bug 300613). if (!mHaveAllHeaders) { char data = '\n'; PRUint32 unused; ParseHead(&data, 1, &unused); } // honor the sticky connection flag... if (mCaps & NS_HTTP_STICKY_CONNECTION) relConn = PR_FALSE; } if (relConn && mConnection) NS_RELEASE(mConnection); mStatus = reason; mTransactionDone = PR_TRUE; // forcibly flag the transaction as complete mClosed = PR_TRUE; // release some resources that we no longer need mRequestStream = nsnull; mReqHeaderBuf.Truncate(); mLineBuf.Truncate(); if (mChunkedDecoder) { delete mChunkedDecoder; mChunkedDecoder = nsnull; } // closing this pipe triggers the channel's OnStopRequest method. mPipeOut->CloseWithStatus(reason); }
nsresult nsHttpTransaction::ParseHead(char *buf, PRUint32 count, PRUint32 *countRead) { nsresult rv; PRUint32 len; char *eol; LOG(("nsHttpTransaction::ParseHead [count=%u]\n", count)); *countRead = 0; NS_PRECONDITION(!mHaveAllHeaders, "oops"); // allocate the response head object if necessary if (!mResponseHead) { mResponseHead = new nsHttpResponseHead(); if (!mResponseHead) return NS_ERROR_OUT_OF_MEMORY; // report that we have a least some of the response if (mActivityDistributor) mActivityDistributor->ObserveActivity( mChannel, NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_START, PR_Now(), LL_ZERO, EmptyCString()); } if (!mHttpResponseMatched) { // Normally we insist on seeing HTTP/1.x in the first few bytes, // but if we are on a persistent connection and the previous transaction // was not supposed to have any content then we need to be prepared // to skip over a response body that the server may have sent even // though it wasn't allowed. if (!mConnection || !mConnection->LastTransactionExpectedNoContent()) { // tolerate only minor junk before the status line mHttpResponseMatched = true; char *p = LocateHttpStart(buf, NS_MIN<PRUint32>(count, 11), true); if (!p) { // Treat any 0.9 style response of a put as a failure. if (mRequestHead->Method() == nsHttp::Put) return NS_ERROR_ABORT; mResponseHead->ParseStatusLine(""); mHaveStatusLine = true; mHaveAllHeaders = true; return NS_OK; } if (p > buf) { // skip over the junk mInvalidResponseBytesRead += p - buf; *countRead = p - buf; buf = p; } } else { char *p = LocateHttpStart(buf, count, false); if (p) { mInvalidResponseBytesRead += p - buf; *countRead = p - buf; buf = p; mHttpResponseMatched = true; } else { mInvalidResponseBytesRead += count; *countRead = count; if (mInvalidResponseBytesRead > MAX_INVALID_RESPONSE_BODY_SIZE) { LOG(("nsHttpTransaction::ParseHead() " "Cannot find Response Header\n")); // cannot go back and call this 0.9 anymore as we // have thrown away a lot of the leading junk return NS_ERROR_ABORT; } return NS_OK; } } } // otherwise we can assume that we don't have a HTTP/0.9 response. NS_ABORT_IF_FALSE (mHttpResponseMatched, "inconsistent"); while ((eol = static_cast<char *>(memchr(buf, '\n', count - *countRead))) != nsnull) { // found line in range [buf:eol] len = eol - buf + 1; *countRead += len; // actually, the line is in the range [buf:eol-1] if ((eol > buf) && (*(eol-1) == '\r')) len--; buf[len-1] = '\n'; rv = ParseLineSegment(buf, len); if (NS_FAILED(rv)) return rv; if (mHaveAllHeaders) return NS_OK; // skip over line buf = eol + 1; if (!mHttpResponseMatched) { // a 100 class response has caused us to throw away that set of // response headers and look for the next response return NS_ERROR_NET_INTERRUPT; } } // do something about a partial header line if (!mHaveAllHeaders && (len = count - *countRead)) { *countRead = count; // ignore a trailing carriage return, and don't bother calling // ParseLineSegment if buf only contains a carriage return. if ((buf[len-1] == '\r') && (--len == 0)) return NS_OK; rv = ParseLineSegment(buf, len); if (NS_FAILED(rv)) return rv; } return NS_OK; }
// called on the socket thread nsresult nsHttpTransaction::HandleContent(char *buf, PRUint32 count, PRUint32 *contentRead, PRUint32 *contentRemaining) { nsresult rv; LOG(("nsHttpTransaction::HandleContent [this=%x count=%u]\n", this, count)); *contentRead = 0; *contentRemaining = 0; NS_ASSERTION(mConnection, "no connection"); if (!mDidContentStart) { rv = HandleContentStart(); if (NS_FAILED(rv)) return rv; // Do not write content to the pipe if we haven't started streaming yet if (!mDidContentStart) return NS_OK; } if (mChunkedDecoder) { // give the buf over to the chunked decoder so it can reformat the // data and tell us how much is really there. rv = mChunkedDecoder->HandleChunkedContent(buf, count, contentRead, contentRemaining); if (NS_FAILED(rv)) return rv; } else if (mContentLength >= nsInt64(0)) { // HTTP/1.0 servers have been known to send erroneous Content-Length // headers. So, unless the connection is persistent, we must make // allowances for a possibly invalid Content-Length header. Thus, if // NOT persistent, we simply accept everything in |buf|. if (mConnection->IsPersistent()) { nsInt64 remaining = mContentLength - mContentRead; nsInt64 count64 = count; *contentRead = PR_MIN(count64, remaining); *contentRemaining = count - *contentRead; } else { *contentRead = count; // mContentLength might need to be increased... nsInt64 position = mContentRead + nsInt64(count); if (position > mContentLength) { mContentLength = position; //mResponseHead->SetContentLength(mContentLength); } } } else { // when we are just waiting for the server to close the connection... // (no explicit content-length given) *contentRead = count; } if (*contentRead) { // update count of content bytes read and report progress... mContentRead += *contentRead; /* when uncommenting, take care of 64-bit integers w/ PR_MAX... if (mProgressSink) mProgressSink->OnProgress(nsnull, nsnull, mContentRead, PR_MAX(0, mContentLength)); */ } LOG(("nsHttpTransaction::HandleContent [this=%x count=%u read=%u mContentRead=%lld mContentLength=%lld]\n", this, count, *contentRead, mContentRead.mValue, mContentLength.mValue)); // check for end-of-file if ((mContentRead == mContentLength) || (mChunkedDecoder && mChunkedDecoder->ReachedEOF())) { // the transaction is done with a complete response. mTransactionDone = PR_TRUE; mResponseIsComplete = PR_TRUE; // report the entire response has arrived if (mActivityDistributor) mActivityDistributor->ObserveActivity( mChannel, NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_COMPLETE, PR_Now(), static_cast<PRUint64>(mContentRead.mValue), EmptyCString()); } return NS_OK; }
NS_IMETHODIMP nsUrlClassifierStreamUpdater::DownloadUpdates( const nsACString &aRequestTables, const nsACString &aRequestBody, const nsACString &aUpdateUrl, nsIUrlClassifierCallback *aSuccessCallback, nsIUrlClassifierCallback *aUpdateErrorCallback, nsIUrlClassifierCallback *aDownloadErrorCallback, bool *_retval) { NS_ENSURE_ARG(aSuccessCallback); NS_ENSURE_ARG(aUpdateErrorCallback); NS_ENSURE_ARG(aDownloadErrorCallback); if (mIsUpdating) { LOG(("Already updating, queueing update %s from %s", aRequestBody.Data(), aUpdateUrl.Data())); *_retval = false; PendingRequest *request = mPendingRequests.AppendElement(); request->mTables = aRequestTables; request->mRequest = aRequestBody; request->mUrl = aUpdateUrl; request->mSuccessCallback = aSuccessCallback; request->mUpdateErrorCallback = aUpdateErrorCallback; request->mDownloadErrorCallback = aDownloadErrorCallback; return NS_OK; } if (aUpdateUrl.IsEmpty()) { NS_ERROR("updateUrl not set"); return NS_ERROR_NOT_INITIALIZED; } nsresult rv; if (!mInitialized) { // Add an observer for shutdown so we can cancel any pending list // downloads. quit-application is the same event that the download // manager listens for and uses to cancel pending downloads. nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService(); if (!observerService) return NS_ERROR_FAILURE; observerService->AddObserver(this, gQuitApplicationMessage, false); mDBService = do_GetService(NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); mInitialized = true; } rv = mDBService->BeginUpdate(this, aRequestTables); if (rv == NS_ERROR_NOT_AVAILABLE) { LOG(("Service busy, already updating, queuing update %s from %s", aRequestBody.Data(), aUpdateUrl.Data())); *_retval = false; PendingRequest *request = mPendingRequests.AppendElement(); request->mTables = aRequestTables; request->mRequest = aRequestBody; request->mUrl = aUpdateUrl; request->mSuccessCallback = aSuccessCallback; request->mUpdateErrorCallback = aUpdateErrorCallback; request->mDownloadErrorCallback = aDownloadErrorCallback; return NS_OK; } if (NS_FAILED(rv)) { return rv; } mSuccessCallback = aSuccessCallback; mUpdateErrorCallback = aUpdateErrorCallback; mDownloadErrorCallback = aDownloadErrorCallback; mIsUpdating = true; *_retval = true; LOG(("FetchUpdate: %s", aUpdateUrl.Data())); //LOG(("requestBody: %s", aRequestBody.Data())); return FetchUpdate(aUpdateUrl, aRequestBody, EmptyCString()); }
nsresult nsMsgTagService::MigrateLabelsToTags() { nsCString prefString; int32_t prefVersion = 0; nsresult rv = m_tagPrefBranch->GetIntPref(TAG_PREF_VERSION, &prefVersion); if (NS_SUCCEEDED(rv) && prefVersion > 1) return rv; else if (prefVersion == 1) { gMigratingKeys = true; // need to convert the keys to lower case nsIMsgTag **tagArray; uint32_t numTags; GetAllTags(&numTags, &tagArray); for (uint32_t tagIndex = 0; tagIndex < numTags; tagIndex++) { nsCAutoString key, color, ordinal; nsAutoString tagStr; nsIMsgTag *tag = tagArray[tagIndex]; tag->GetKey(key); tag->GetTag(tagStr); tag->GetOrdinal(ordinal); tag->GetColor(color); DeleteKey(key); ToLowerCase(key); AddTagForKey(key, tagStr, color, ordinal); } NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(numTags, tagArray); gMigratingKeys = false; } else { nsCOMPtr<nsIPrefBranch> prefRoot(do_GetService(NS_PREFSERVICE_CONTRACTID)); nsCOMPtr<nsIPrefLocalizedString> pls; nsString ucsval; nsCAutoString labelKey("$label1"); for(int32_t i = 0; i < PREF_LABELS_MAX; ) { prefString.Assign(PREF_LABELS_DESCRIPTION); prefString.AppendInt(i + 1); rv = prefRoot->GetComplexValue(prefString.get(), NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(pls)); NS_ENSURE_SUCCESS(rv, rv); pls->ToString(getter_Copies(ucsval)); prefString.Assign(PREF_LABELS_COLOR); prefString.AppendInt(i + 1); nsCString csval; rv = prefRoot->GetCharPref(prefString.get(), getter_Copies(csval)); NS_ENSURE_SUCCESS(rv, rv); rv = AddTagForKey(labelKey, ucsval, csval, EmptyCString()); NS_ENSURE_SUCCESS(rv, rv); labelKey.SetCharAt(++i + '1', 6); } } m_tagPrefBranch->SetIntPref(TAG_PREF_VERSION, 2); return rv; }
bool InternalHeaders::IsForbiddenRequestNoCorsHeader(const nsACString& aName) const { return mGuard == HeadersGuardEnum::Request_no_cors && !IsSimpleHeader(aName, EmptyCString()); }
void SVGAElement::GetReferrerPolicy(nsAString& aPolicy) { GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aPolicy); }
nsresult nsNetscapeProfileMigratorBase::GetProfileDataFromProfilesIni(nsILocalFile* aDataDir, nsIMutableArray* aProfileNames, nsIMutableArray* aProfileLocations) { nsCOMPtr<nsIFile> dataDir; nsresult rv = aDataDir->Clone(getter_AddRefs(dataDir)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsILocalFile> profileIni(do_QueryInterface(dataDir, &rv)); NS_ENSURE_SUCCESS(rv, rv); profileIni->Append(NS_LITERAL_STRING("profiles.ini")); // Does it exist? bool profileFileExists = false; rv = profileIni->Exists(&profileFileExists); NS_ENSURE_SUCCESS(rv, rv); if (!profileFileExists) return NS_ERROR_FILE_NOT_FOUND; nsINIParser parser; rv = parser.Init(profileIni); NS_ENSURE_SUCCESS(rv, rv); nsCAutoString buffer, filePath; bool isRelative; // This is an infinite loop that is broken when we no longer find profiles // for profileID with IsRelative option. for (unsigned int c = 0; true; ++c) { nsCAutoString profileID("Profile"); profileID.AppendInt(c); if (NS_FAILED(parser.GetString(profileID.get(), "IsRelative", buffer))) break; isRelative = buffer.EqualsLiteral("1"); rv = parser.GetString(profileID.get(), "Path", filePath); if (NS_FAILED(rv)) { NS_ERROR("Malformed profiles.ini: Path= not found"); continue; } rv = parser.GetString(profileID.get(), "Name", buffer); if (NS_FAILED(rv)) { NS_ERROR("Malformed profiles.ini: Name= not found"); continue; } nsCOMPtr<nsILocalFile> rootDir; rv = NS_NewNativeLocalFile(EmptyCString(), true, getter_AddRefs(rootDir)); NS_ENSURE_SUCCESS(rv, rv); rv = isRelative ? rootDir->SetRelativeDescriptor(aDataDir, filePath) : rootDir->SetPersistentDescriptor(filePath); if (NS_FAILED(rv)) continue; bool exists = false; rootDir->Exists(&exists); if (exists) { aProfileLocations->AppendElement(rootDir, false); nsCOMPtr<nsISupportsString> profileNameString( do_CreateInstance("@mozilla.org/supports-string;1")); profileNameString->SetData(NS_ConvertUTF8toUTF16(buffer)); aProfileNames->AppendElement(profileNameString, false); } } return NS_OK; }
NS_IMETHODIMP InterceptedChannelBase::SaveTimeStamps() { MOZ_ASSERT(NS_IsMainThread()); nsCOMPtr<nsIChannel> underlyingChannel; nsresult rv = GetChannel(getter_AddRefs(underlyingChannel)); MOZ_ASSERT(NS_SUCCEEDED(rv)); nsCOMPtr<nsITimedChannel> timedChannel = do_QueryInterface(underlyingChannel); MOZ_ASSERT(timedChannel); rv = timedChannel->SetLaunchServiceWorkerStart(mLaunchServiceWorkerStart); MOZ_ASSERT(NS_SUCCEEDED(rv)); rv = timedChannel->SetLaunchServiceWorkerEnd(mLaunchServiceWorkerEnd); MOZ_ASSERT(NS_SUCCEEDED(rv)); rv = timedChannel->SetDispatchFetchEventStart(mDispatchFetchEventStart); MOZ_ASSERT(NS_SUCCEEDED(rv)); rv = timedChannel->SetDispatchFetchEventEnd(mDispatchFetchEventEnd); MOZ_ASSERT(NS_SUCCEEDED(rv)); rv = timedChannel->SetHandleFetchEventStart(mHandleFetchEventStart); MOZ_ASSERT(NS_SUCCEEDED(rv)); rv = timedChannel->SetHandleFetchEventEnd(mHandleFetchEventEnd); MOZ_ASSERT(NS_SUCCEEDED(rv)); nsCOMPtr<nsIChannel> channel; GetChannel(getter_AddRefs(channel)); if (NS_WARN_IF(!channel)) { return NS_ERROR_FAILURE; } bool isNonSubresourceRequest = nsContentUtils::IsNonSubresourceRequest(channel); nsCString navigationOrSubresource = isNonSubresourceRequest ? NS_LITERAL_CSTRING("navigation") : NS_LITERAL_CSTRING("subresource"); nsAutoCString subresourceKey(EmptyCString()); GetSubresourceTimeStampKey(channel, subresourceKey); // We may have null timestamps if the fetch dispatch runnable was cancelled // and we defaulted to resuming the request. if (!mFinishResponseStart.IsNull() && !mFinishResponseEnd.IsNull()) { MOZ_ASSERT(mSynthesizedOrReset != Invalid); Telemetry::HistogramID id = (mSynthesizedOrReset == Synthesized) ? Telemetry::SERVICE_WORKER_FETCH_EVENT_FINISH_SYNTHESIZED_RESPONSE_MS : Telemetry::SERVICE_WORKER_FETCH_EVENT_CHANNEL_RESET_MS; Telemetry::Accumulate(id, navigationOrSubresource, static_cast<uint32_t>((mFinishResponseEnd - mFinishResponseStart).ToMilliseconds())); if (!isNonSubresourceRequest && !subresourceKey.IsEmpty()) { Telemetry::Accumulate(id, subresourceKey, static_cast<uint32_t>((mFinishResponseEnd - mFinishResponseStart).ToMilliseconds())); } } Telemetry::Accumulate(Telemetry::SERVICE_WORKER_FETCH_EVENT_DISPATCH_MS, navigationOrSubresource, static_cast<uint32_t>((mHandleFetchEventStart - mDispatchFetchEventStart).ToMilliseconds())); if (!isNonSubresourceRequest && !subresourceKey.IsEmpty()) { Telemetry::Accumulate(Telemetry::SERVICE_WORKER_FETCH_EVENT_DISPATCH_MS, subresourceKey, static_cast<uint32_t>((mHandleFetchEventStart - mDispatchFetchEventStart).ToMilliseconds())); } if (!mFinishResponseEnd.IsNull()) { Telemetry::Accumulate(Telemetry::SERVICE_WORKER_FETCH_INTERCEPTION_DURATION_MS, navigationOrSubresource, static_cast<uint32_t>((mFinishResponseEnd - mDispatchFetchEventStart).ToMilliseconds())); if (!isNonSubresourceRequest && !subresourceKey.IsEmpty()) { Telemetry::Accumulate(Telemetry::SERVICE_WORKER_FETCH_INTERCEPTION_DURATION_MS, subresourceKey, static_cast<uint32_t>((mFinishResponseEnd - mDispatchFetchEventStart).ToMilliseconds())); } } return rv; }
NS_IMETHODIMP nsSmtpServer::GetPassword(nsACString& aPassword) { if (m_password.IsEmpty() && !m_logonFailed) { // try to avoid prompting the user for another password. If the user has set // the appropriate pref, we'll use the password from an incoming server, if // the user has already logged onto that server. // if this is set, we'll only use this, and not the other prefs // user_pref("mail.smtpserver.smtp1.incomingAccount", "server1"); // if this is set, we'll accept an exact match of user name and server // user_pref("mail.smtp.useMatchingHostNameServer", true); // if this is set, and we don't find an exact match of user and host name, // we'll accept a match of username and domain, where domain // is everything after the first '.' // user_pref("mail.smtp.useMatchingDomainServer", true); nsCString accountKey; bool useMatchingHostNameServer = false; bool useMatchingDomainServer = false; mPrefBranch->GetCharPref("incomingAccount", getter_Copies(accountKey)); nsCOMPtr<nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID); nsCOMPtr<nsIMsgIncomingServer> incomingServerToUse; if (accountManager) { if (!accountKey.IsEmpty()) accountManager->GetIncomingServer(accountKey, getter_AddRefs(incomingServerToUse)); else { nsresult rv; nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); NS_ENSURE_SUCCESS(rv,rv); prefBranch->GetBoolPref("mail.smtp.useMatchingHostNameServer", &useMatchingHostNameServer); prefBranch->GetBoolPref("mail.smtp.useMatchingDomainServer", &useMatchingDomainServer); if (useMatchingHostNameServer || useMatchingDomainServer) { nsCString userName; nsCString hostName; GetHostname(hostName); GetUsername(userName); if (useMatchingHostNameServer) // pass in empty type and port=0, to match imap and pop3. accountManager->FindRealServer(userName, hostName, EmptyCString(), 0, getter_AddRefs(incomingServerToUse)); int32_t dotPos = -1; if (!incomingServerToUse && useMatchingDomainServer && (dotPos = hostName.FindChar('.')) != kNotFound) { hostName.Cut(0, dotPos); nsCOMPtr<nsISupportsArray> allServers; accountManager->GetAllServers(getter_AddRefs(allServers)); if (allServers) { uint32_t count = 0; allServers->Count(&count); uint32_t i; for (i = 0; i < count; i++) { nsCOMPtr<nsIMsgIncomingServer> server = do_QueryElementAt(allServers, i); if (server) { nsCString serverUserName; nsCString serverHostName; server->GetRealUsername(serverUserName); server->GetRealHostName(serverHostName); if (serverUserName.Equals(userName)) { int32_t serverDotPos = serverHostName.FindChar('.'); if (serverDotPos != kNotFound) { serverHostName.Cut(0, serverDotPos); if (serverHostName.Equals(hostName)) { incomingServerToUse = server; break; } } } } } } } } } } if (incomingServerToUse) return incomingServerToUse->GetPassword(aPassword); } aPassword = m_password; return NS_OK; }