diff --git a/toolkit/components/build/nsToolkitCompsCID.h b/toolkit/components/build/nsToolkitCompsCID.h index 57383cfdadb..92ffe624da9 100644 --- a/toolkit/components/build/nsToolkitCompsCID.h +++ b/toolkit/components/build/nsToolkitCompsCID.h @@ -77,6 +77,9 @@ #define NS_URLCLASSIFIERDBSERVICE_CONTRACTID \ "@mozilla.org/url-classifier/dbservice;1" +#define NS_URLCLASSIFIERSTREAMUPDATER_CONTRACTID \ + "@mozilla.org/url-classifier/streamupdater;1" + #define NS_SCRIPTABLEUNESCAPEHTML_CONTRACTID "@mozilla.org/feed-unescapehtml;1" ///////////////////////////////////////////////////////////////////////////// @@ -119,9 +122,15 @@ // {e7f70966-9a37-48d7-8aeb-35998f31090e} #define NS_TYPEAHEADFIND_CID \ { 0xe7f70966, 0x9a37, 0x48d7, { 0x8a, 0xeb, 0x35, 0x99, 0x8f, 0x31, 0x09, 0x0e} } - + +// {5eb7c3c1-ec1f-4007-87cc-eefb37d68ce6} #define NS_URLCLASSIFIERDBSERVICE_CID \ { 0x5eb7c3c1, 0xec1f, 0x4007, { 0x87, 0xcc, 0xee, 0xfb, 0x37, 0xd6, 0x8c, 0xe6} } +// {c2be6dc0-ef1e-4abd-86a2-4f864ddc57f6} +#define NS_URLCLASSIFIERSTREAMUPDATER_CID \ +{ 0xc2be6dc0, 0xef1e, 0x4abd, { 0x86, 0xa2, 0x4f, 0x86, 0x4d, 0xdc, 0x57, 0xf6} } + +// {10f2f5f0-f103-4901-980f-ba11bd70d60d} #define NS_SCRIPTABLEUNESCAPEHTML_CID \ { 0x10f2f5f0, 0xf103, 0x4901, { 0x98, 0x0f, 0xba, 0x11, 0xbd, 0x70, 0xd6, 0x0d} } diff --git a/toolkit/components/build/nsToolkitCompsModule.cpp b/toolkit/components/build/nsToolkitCompsModule.cpp index 17280a95aac..219242a9f53 100644 --- a/toolkit/components/build/nsToolkitCompsModule.cpp +++ b/toolkit/components/build/nsToolkitCompsModule.cpp @@ -56,6 +56,7 @@ #ifdef MOZ_URL_CLASSIFIER #include "nsUrlClassifierDBService.h" +#include "nsUrlClassifierStreamUpdater.h" #endif #ifdef MOZ_FEEDS @@ -84,6 +85,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsTypeAheadFind) #ifdef MOZ_URL_CLASSIFIER NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsUrlClassifierDBService, nsUrlClassifierDBService::GetInstance) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsUrlClassifierStreamUpdater) #endif #ifdef MOZ_FEEDS @@ -132,6 +134,10 @@ static const nsModuleComponentInfo components[] = NS_URLCLASSIFIERDBSERVICE_CID, NS_URLCLASSIFIERDBSERVICE_CONTRACTID, nsUrlClassifierDBServiceConstructor }, + { "Url Classifier Stream Updater", + NS_URLCLASSIFIERSTREAMUPDATER_CID, + NS_URLCLASSIFIERSTREAMUPDATER_CONTRACTID, + nsUrlClassifierStreamUpdaterConstructor }, #endif #ifdef MOZ_FEEDS { "Unescape HTML", diff --git a/toolkit/components/url-classifier/public/Makefile.in b/toolkit/components/url-classifier/public/Makefile.in index 65a2aae5ccb..a0a185bb334 100644 --- a/toolkit/components/url-classifier/public/Makefile.in +++ b/toolkit/components/url-classifier/public/Makefile.in @@ -9,6 +9,7 @@ MODULE = url-classifier XPIDL_MODULE = url-classifier XPIDLSRCS = nsIUrlClassifierDBService.idl \ + nsIUrlClassifierStreamUpdater.idl \ nsIUrlClassifierTable.idl \ nsIUrlListManager.idl \ $(NULL) diff --git a/toolkit/components/url-classifier/public/nsIUrlClassifierDBService.idl b/toolkit/components/url-classifier/public/nsIUrlClassifierDBService.idl index a1362551b4e..c60ad03be3e 100644 --- a/toolkit/components/url-classifier/public/nsIUrlClassifierDBService.idl +++ b/toolkit/components/url-classifier/public/nsIUrlClassifierDBService.idl @@ -49,7 +49,7 @@ interface nsIUrlClassifierCallback : nsISupports { * It provides async methods for querying and updating the database. As the * methods complete, they call the callback function. */ -[scriptable, uuid(88519724-2225-4b4f-8ba7-365b4d138c3a)] +[scriptable, uuid(61759a52-fbbb-4c5e-b1df-fce67b6d10c8)] interface nsIUrlClassifierDBService : nsISupports { /** @@ -67,6 +67,30 @@ interface nsIUrlClassifierDBService : nsISupports * allows us to keep track of the table version in our main thread. */ void updateTables(in ACString updateString, in nsIUrlClassifierCallback c); + + //////////////////////////////////////////////////////////////////////////// + // Incremental update methods. These are named to match similar methods + // in, e.g., nsICryptoHash. + + /** + * Update the table incrementally. + */ + void update(in ACString updateChunk); + + // It would be nice to have an updateFromStream method to round out the + // interface, but it's tricky because of XPCOM proxies. + + /** + * Finish an incremental update. This commits any pending tables and + * calls the callback for each completed table. + */ + void finish(in nsIUrlClassifierCallback c); + + /** + * Cancel an incremental update. This rolls back and pending changes. + * and resets the stream interface. + */ + void cancelStream(); }; /** diff --git a/toolkit/components/url-classifier/public/nsIUrlClassifierStreamUpdater.idl b/toolkit/components/url-classifier/public/nsIUrlClassifierStreamUpdater.idl new file mode 100644 index 00000000000..af26526a7ea --- /dev/null +++ b/toolkit/components/url-classifier/public/nsIUrlClassifierStreamUpdater.idl @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Url Classifier code + * + * The Initial Developer of the Original Code is + * Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tony Chang (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" +#include "nsIUrlClassifierDBService.idl" + +/** + * This is a class to help with the + */ +[scriptable, uuid(45b57a99-0c1a-4096-9d16-c4766d75fbea)] +interface nsIUrlClassifierStreamUpdater : nsISupports +{ + /** + * The Url to download from. Should be plain ascii text. + */ + attribute ACString updateUrl; + + /** + * Try to download updates from updateUrl. Only one instance of this + * runs at a time, so we return false if another instance is already + * running. + */ + boolean downloadUpdates(in nsIUrlClassifierCallback c); +}; diff --git a/toolkit/components/url-classifier/public/nsIUrlListManager.idl b/toolkit/components/url-classifier/public/nsIUrlListManager.idl index 3d4351f4413..3d263291b36 100644 --- a/toolkit/components/url-classifier/public/nsIUrlListManager.idl +++ b/toolkit/components/url-classifier/public/nsIUrlListManager.idl @@ -12,14 +12,15 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is mozilla.org code. + * The Original Code is Url Classifier code * * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Tony Chang (original author) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or diff --git a/toolkit/components/url-classifier/src/Makefile.in b/toolkit/components/url-classifier/src/Makefile.in index 9bbcff298af..705b37827e0 100644 --- a/toolkit/components/url-classifier/src/Makefile.in +++ b/toolkit/components/url-classifier/src/Makefile.in @@ -12,13 +12,15 @@ MOZILLA_INTERNAL_API = 1 FORCE_STATIC_LIB = 1 -REQUIRES = storage \ +REQUIRES = necko \ + storage \ string \ xpcom \ $(NULL) CPPSRCS = \ nsUrlClassifierDBService.cpp \ + nsUrlClassifierStreamUpdater.cpp \ $(NULL) LOCAL_INCLUDES = \ diff --git a/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp b/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp index 5d3d8dcbe88..d6de100d1cd 100644 --- a/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp +++ b/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp @@ -51,11 +51,12 @@ #include "nsIProxyObjectManager.h" #include "nsToolkitCompsCID.h" #include "nsUrlClassifierDBService.h" -#include "nsThreadUtils.h" #include "nsString.h" +#include "nsTArray.h" +#include "nsThreadUtils.h" #include "prlog.h" -#include "prmon.h" +// NSPR_LOG_MODULES=UrlClassifierDbService:5 #if defined(PR_LOGGING) static const PRLogModuleInfo *gUrlClassifierDbServiceLog = nsnull; #define LOG(args) PR_LOG(gUrlClassifierDbServiceLog, PR_LOG_DEBUG, args) @@ -149,13 +150,25 @@ private: // to be created in the background thread (currently mozStorageConnection // isn't thread safe). mozIStorageConnection* mConnection; + + // True if we're in the middle of a streaming update. + PRBool mHasPendingUpdate; + + // For incremental updates, keep track of tables that have been updated. + // When finish() is called, we go ahead and pass these update lines to + // the callback. + nsTArray mTableUpdateLines; + + // We receive data in small chunks that may be broken in the middle of + // a line. So we save the last partial line here. + nsCString mPendingStreamUpdate; }; NS_IMPL_THREADSAFE_ISUPPORTS1(nsUrlClassifierDBServiceWorker, nsIUrlClassifierDBServiceWorker) nsUrlClassifierDBServiceWorker::nsUrlClassifierDBServiceWorker() - : mConnection(nsnull) + : mConnection(nsnull), mHasPendingUpdate(PR_FALSE), mTableUpdateLines() { } nsUrlClassifierDBServiceWorker::~nsUrlClassifierDBServiceWorker() @@ -170,7 +183,8 @@ nsUrlClassifierDBServiceWorker::~nsUrlClassifierDBServiceWorker() NS_IMETHODIMP nsUrlClassifierDBServiceWorker::Exists(const nsACString& tableName, const nsACString& key, - nsIUrlClassifierCallback *c) { + nsIUrlClassifierCallback *c) +{ LOG(("Exists\n")); nsresult rv = OpenDb(); @@ -214,7 +228,8 @@ nsUrlClassifierDBServiceWorker::Exists(const nsACString& tableName, // we call the callback with the table line. NS_IMETHODIMP nsUrlClassifierDBServiceWorker::UpdateTables(const nsACString& updateString, - nsIUrlClassifierCallback *c) { + nsIUrlClassifierCallback *c) +{ LOG(("Updating tables\n")); nsresult rv = OpenDb(); @@ -251,11 +266,14 @@ nsUrlClassifierDBServiceWorker::UpdateTables(const nsACString& updateString, getter_AddRefs(deleteStatement)); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "malformed table line"); if (NS_SUCCEEDED(rv)) { - // If it's a new table, we must have completed the last table. - // Go ahead and post the completion to the UI thread. - // XXX This shouldn't happen before we commit the transaction. - if (lastTableLine.Length() > 0) + // If it's a new table, we may have completed a table. + // Go ahead and post the completion to the UI thread and db. + if (lastTableLine.Length() > 0) { + mConnection->CommitTransaction(); c->HandleEvent(lastTableLine); + + mConnection->BeginTransaction(); + } lastTableLine.Assign(line); } } else { @@ -276,6 +294,109 @@ nsUrlClassifierDBServiceWorker::UpdateTables(const nsACString& updateString, return NS_OK; } +NS_IMETHODIMP +nsUrlClassifierDBServiceWorker::Update(const nsACString& chunk) +{ + LOG(("Update from Stream.")); + nsresult rv = OpenDb(); + if (NS_FAILED(rv)) { + NS_ERROR("Unable to open database"); + return NS_ERROR_FAILURE; + } + + nsCAutoString updateString(mPendingStreamUpdate); + updateString.Append(chunk); + + nsCOMPtr updateStatement; + nsCOMPtr deleteStatement; + nsCAutoString dbTableName; + + // If we're not in the middle of an update, we start a new transaction. + // Otherwise, we need to pick up where we left off. + if (!mHasPendingUpdate) { + mConnection->BeginTransaction(); + mHasPendingUpdate = PR_TRUE; + } else { + PRUint32 numTables = mTableUpdateLines.Length(); + if (numTables > 0) { + const nsDependentCSubstring &line = Substring( + mTableUpdateLines[numTables - 1], 0); + + rv = ProcessNewTable(line, &dbTableName, + getter_AddRefs(updateStatement), + getter_AddRefs(deleteStatement)); + NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "malformed table line"); + } + } + + PRUint32 cur = 0; + PRInt32 next; + while(cur < updateString.Length() && + (next = updateString.FindChar('\n', cur)) != kNotFound) { + const nsDependentCSubstring &line = Substring(updateString, + cur, next - cur); + cur = next + 1; // prepare for next run + + // Skip blank lines + if (line.Length() == 0) + continue; + + if ('[' == line[0]) { + rv = ProcessNewTable(line, &dbTableName, + getter_AddRefs(updateStatement), + getter_AddRefs(deleteStatement)); + NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "malformed table line"); + if (NS_SUCCEEDED(rv)) { + // Add the line to our array of table lines. + mTableUpdateLines.AppendElement(line); + } + } else { + rv = ProcessUpdateTable(line, dbTableName, updateStatement, + deleteStatement); + NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "malformed update line"); + } + } + // Save the remaining string fragment. + mPendingStreamUpdate = Substring(updateString, cur); + LOG(("pending stream update: %s", mPendingStreamUpdate.get())); + + return NS_OK; +} + +NS_IMETHODIMP +nsUrlClassifierDBServiceWorker::Finish(nsIUrlClassifierCallback *c) +{ + if (!mHasPendingUpdate) + return NS_OK; + + LOG(("Finish, committing transaction")); + mConnection->CommitTransaction(); + + for (PRUint32 i = 0; i < mTableUpdateLines.Length(); ++i) { + c->HandleEvent(mTableUpdateLines[i]); + } + mTableUpdateLines.Clear(); + mPendingStreamUpdate.Truncate(); + mHasPendingUpdate = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsUrlClassifierDBServiceWorker::CancelStream() +{ + if (!mHasPendingUpdate) + return NS_OK; + + LOG(("CancelStream, rolling back transaction")); + mConnection->RollbackTransaction(); + + mTableUpdateLines.Clear(); + mPendingStreamUpdate.Truncate(); + mHasPendingUpdate = PR_FALSE; + + return NS_OK; +} + // Allows the main thread to delete the connection which may be in // a background thread. // XXX This could be turned into a single shutdown event so the logic @@ -409,7 +530,8 @@ nsUrlClassifierDBServiceWorker::OpenDb() } nsresult -nsUrlClassifierDBServiceWorker::MaybeCreateTable(const nsCString& aTableName) { +nsUrlClassifierDBServiceWorker::MaybeCreateTable(const nsCString& aTableName) +{ LOG(("MaybeCreateTable %s\n", aTableName.get())); nsCOMPtr createStatement; @@ -426,7 +548,8 @@ nsUrlClassifierDBServiceWorker::MaybeCreateTable(const nsCString& aTableName) { void nsUrlClassifierDBServiceWorker::GetDbTableName(const nsACString& aTableName, - nsCString* aDbTableName) { + nsCString* aDbTableName) +{ aDbTableName->Assign(aTableName); aDbTableName->ReplaceChar('-', '_'); } @@ -568,6 +691,75 @@ nsUrlClassifierDBService::UpdateTables(const nsACString& updateString, return proxy->UpdateTables(updateString, proxyCallback); } +NS_IMETHODIMP +nsUrlClassifierDBService::Update(const nsACString& aUpdateChunk) +{ + NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED); + + nsresult rv; + + // The actual worker uses the background thread. + nsCOMPtr proxy; + rv = NS_GetProxyForObject(gDbBackgroundThread, + NS_GET_IID(nsIUrlClassifierDBServiceWorker), + mWorker, + NS_PROXY_ASYNC, + getter_AddRefs(proxy)); + NS_ENSURE_SUCCESS(rv, rv); + + return proxy->Update(aUpdateChunk); +} + +NS_IMETHODIMP +nsUrlClassifierDBService::Finish(nsIUrlClassifierCallback *c) +{ + NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED); + + nsCOMPtr wrapper = + new nsUrlClassifierCallbackWrapper(c); + NS_ENSURE_TRUE(wrapper, NS_ERROR_OUT_OF_MEMORY); + + nsresult rv; + // The proxy callback uses the current thread. + nsCOMPtr proxyCallback; + rv = NS_GetProxyForObject(NS_PROXY_TO_CURRENT_THREAD, + NS_GET_IID(nsIUrlClassifierCallback), + wrapper, + NS_PROXY_ASYNC, + getter_AddRefs(proxyCallback)); + NS_ENSURE_SUCCESS(rv, rv); + + // The actual worker uses the background thread. + nsCOMPtr proxy; + rv = NS_GetProxyForObject(gDbBackgroundThread, + NS_GET_IID(nsIUrlClassifierDBServiceWorker), + mWorker, + NS_PROXY_ASYNC, + getter_AddRefs(proxy)); + NS_ENSURE_SUCCESS(rv, rv); + + return proxy->Finish(proxyCallback); +} + +NS_IMETHODIMP +nsUrlClassifierDBService::CancelStream() +{ + NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED); + + nsresult rv; + + // The actual worker uses the background thread. + nsCOMPtr proxy; + rv = NS_GetProxyForObject(gDbBackgroundThread, + NS_GET_IID(nsIUrlClassifierDBServiceWorker), + mWorker, + NS_PROXY_ASYNC, + getter_AddRefs(proxy)); + NS_ENSURE_SUCCESS(rv, rv); + + return proxy->CancelStream(); +} + NS_IMETHODIMP nsUrlClassifierDBService::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) diff --git a/toolkit/components/url-classifier/src/nsUrlClassifierStreamUpdater.cpp b/toolkit/components/url-classifier/src/nsUrlClassifierStreamUpdater.cpp new file mode 100644 index 00000000000..ce555b7c67a --- /dev/null +++ b/toolkit/components/url-classifier/src/nsUrlClassifierStreamUpdater.cpp @@ -0,0 +1,209 @@ +//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Url Classifier code + * + * The Initial Developer of the Original Code is + * Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tony Chang (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIURI.h" +#include "nsIUrlClassifierDBService.h" +#include "nsNetUtil.h" +#include "nsStreamUtils.h" +#include "nsToolkitCompsCID.h" +#include "nsUrlClassifierStreamUpdater.h" +#include "prlog.h" + +// NSPR_LOG_MODULES=UrlClassifierStreamUpdater:5 +#if defined(PR_LOGGING) +static const PRLogModuleInfo *gUrlClassifierStreamUpdaterLog = nsnull; +#define LOG(args) PR_LOG(gUrlClassifierStreamUpdaterLog, PR_LOG_DEBUG, args) +#else +#define LOG(args) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Stream listener for incremental download of url tables. + +class nsUrlClassifierStreamUpdater; + +class TableUpdateListener : public nsIStreamListener +{ +public: + TableUpdateListener(nsIUrlClassifierCallback *c); + nsCOMPtr mDBService; + + NS_DECL_ISUPPORTS + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + +private: + ~TableUpdateListener() {}; + + // Callback when table updates complete. + nsCOMPtr mCallback; +}; + +TableUpdateListener::TableUpdateListener(nsIUrlClassifierCallback *c) +{ + mCallback = c; +} + +NS_IMPL_ISUPPORTS2(TableUpdateListener, nsIStreamListener, nsIRequestObserver) + +NS_IMETHODIMP +TableUpdateListener::OnStartRequest(nsIRequest *request, nsISupports* context) +{ + nsresult rv; + if (!mDBService) { + mDBService = do_GetService(NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + } + return NS_OK; +} + +NS_IMETHODIMP +TableUpdateListener::OnDataAvailable(nsIRequest *request, + nsISupports* context, + nsIInputStream *aIStream, + PRUint32 aSourceOffset, + PRUint32 aLength) +{ + LOG(("OnDataAvailable (%d bytes)", aLength)); + + NS_ASSERTION(mDBService != nsnull, "UrlClassifierDBService is null"); + + nsresult rv; + // Copy the data into a nsCString + nsCString chunk; + rv = NS_ConsumeStream(aIStream, aLength, chunk); + NS_ENSURE_SUCCESS(rv, rv); + + LOG(("Chunk (%d): %s\n\n", chunk.Length(), chunk.get())); + + rv = mDBService->Update(chunk); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +NS_IMETHODIMP +TableUpdateListener::OnStopRequest(nsIRequest *request, nsISupports* context, + nsresult aStatus) +{ + LOG(("OnStopRequest status: %d", aStatus)); + + // If we got the whole stream, call Finish to commit the changes. + // Otherwise, call Cancel to rollback the changes. + if (NS_SUCCEEDED(aStatus)) + mDBService->Finish(mCallback); + else + mDBService->CancelStream(); + + nsUrlClassifierStreamUpdater* updater = + NS_STATIC_CAST(nsUrlClassifierStreamUpdater*, context); + NS_ASSERTION(updater != nsnull, "failed to cast context"); + updater->mIsUpdating = PR_FALSE; + + return NS_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// nsIUrlClassiferStreamUpdater implementation +// Handles creating/running the stream listener + +nsUrlClassifierStreamUpdater::nsUrlClassifierStreamUpdater() + : mIsUpdating(PR_FALSE), mUpdateUrl(nsnull) +{ +#if defined(PR_LOGGING) + if (!gUrlClassifierStreamUpdaterLog) + gUrlClassifierStreamUpdaterLog = PR_NewLogModule("UrlClassifierStreamUpdater"); +#endif +} + +NS_IMPL_ISUPPORTS1(nsUrlClassifierStreamUpdater, nsIUrlClassifierStreamUpdater) + +NS_IMETHODIMP +nsUrlClassifierStreamUpdater::GetUpdateUrl(nsACString & aUpdateUrl) +{ + if (mUpdateUrl) { + mUpdateUrl->GetSpec(aUpdateUrl); + } else { + aUpdateUrl.Truncate(); + } + return NS_OK; +} + +NS_IMETHODIMP +nsUrlClassifierStreamUpdater::SetUpdateUrl(const nsACString & aUpdateUrl) +{ + nsresult rv = NS_NewURI(getter_AddRefs(mUpdateUrl), aUpdateUrl); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +NS_IMETHODIMP +nsUrlClassifierStreamUpdater::DownloadUpdates(nsIUrlClassifierCallback *c, + PRBool *_retval) +{ + if (mIsUpdating) { + LOG(("already updating, skipping update")); + *_retval = PR_FALSE; + return NS_OK; + } + + if (!mUpdateUrl) { + NS_ERROR("updateUrl not set"); + return NS_ERROR_NOT_INITIALIZED; + } + + // Ok, try to create the download channel. + nsresult rv; + nsCOMPtr channel; + rv = NS_NewChannel(getter_AddRefs(channel), mUpdateUrl); + NS_ENSURE_SUCCESS(rv, rv); + + if (!mListener) { + mListener = new TableUpdateListener(c); + } + + // Make the request + rv = channel->AsyncOpen(mListener.get(), this); + NS_ENSURE_SUCCESS(rv, rv); + + mIsUpdating = PR_TRUE; + *_retval = PR_TRUE; + + return NS_OK; +} diff --git a/toolkit/components/url-classifier/src/nsUrlClassifierStreamUpdater.h b/toolkit/components/url-classifier/src/nsUrlClassifierStreamUpdater.h new file mode 100644 index 00000000000..89b3eb87945 --- /dev/null +++ b/toolkit/components/url-classifier/src/nsUrlClassifierStreamUpdater.h @@ -0,0 +1,72 @@ +//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-/ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Url Classifier code + * + * The Initial Developer of the Original Code is + * Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tony Chang (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsUrlClassifierStreamUpdater_h_ +#define nsUrlClassifierStreamUpdater_h_ + +#include + +#include "nsCOMPtr.h" +#include "nsIUrlClassifierStreamUpdater.h" +#include "nsIStreamListener.h" + +// Forward declare pointers +class nsIURI; + +class nsUrlClassifierStreamUpdater : public nsIUrlClassifierStreamUpdater +{ +public: + nsUrlClassifierStreamUpdater(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIURLCLASSIFIERSTREAMUPDATER + + PRBool mIsUpdating; + +private: + // No subclassing + ~nsUrlClassifierStreamUpdater() {}; + + // Disallow copy constructor + nsUrlClassifierStreamUpdater(nsUrlClassifierStreamUpdater&); + + nsCOMPtr mUpdateUrl; + nsCOMPtr mListener; +}; + +#endif // nsUrlClassifierStreamUpdater_h_