[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10558: Allow users the option of sa
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10558: Allow users the option of saving loaded or streamed media, currently |
Date: |
Thu, 29 Jan 2009 09:45:09 -0700 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 10558
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Thu 2009-01-29 09:45:09 -0700
message:
Allow users the option of saving loaded or streamed media, currently
using a fairly rudimentary an inflexible system of naming files.
The naming system will be improved by using a functor, and the naming
code may be moved somewhere more suitable.
modified:
gui/gtk.cpp
libbase/NetworkAdapter.h
libbase/curl_adapter.cpp
libbase/rc.cpp
libbase/rc.h
libcore/StreamProvider.cpp
libcore/StreamProvider.h
libcore/asobj/NetConnection_as.cpp
libcore/impl.cpp
------------------------------------------------------------
revno: 10555.1.1
committer: Benjamin Wolsey <address@hidden>
branch nick: savemedia
timestamp: Tue 2009-01-27 10:49:22 +0100
message:
Allow saving cached media streams permanently on disk (NetConnection
only at present).
RcInitFile support for target directory and on/off toggle.
GUI support for turning on/of and setting target directory.
Target directory is currently ignored.
Use GnashSystemFileHeaders.h for stat(), dup() includes.
added:
libbase/GnashSystemFileHeaders.h
modified:
gui/gtk.cpp
libbase/NetworkAdapter.h
libbase/curl_adapter.cpp
libbase/rc.cpp
libbase/rc.h
libcore/StreamProvider.cpp
libcore/StreamProvider.h
libcore/asobj/NetConnection_as.cpp
------------------------------------------------------------
revno: 10555.1.2
committer: Benjamin Wolsey <address@hidden>
branch nick: savemedia
timestamp: Tue 2009-01-27 13:39:39 +0100
message:
Use user-specified target directory for saving media streams. Save
rcfile values properly.
modified:
libbase/rc.cpp
libcore/StreamProvider.cpp
------------------------------------------------------------
revno: 10555.1.3
committer: Benjamin Wolsey <address@hidden>
branch nick: savemedia
timestamp: Tue 2009-01-27 13:40:24 +0100
message:
Write values to rcfile, correct typo.
modified:
gui/gtk.cpp
------------------------------------------------------------
revno: 10555.1.4
committer: Benjamin Wolsey <address@hidden>
branch nick: savemedia
timestamp: Tue 2009-01-27 13:40:44 +0100
message:
Correct typo.
modified:
libbase/curl_adapter.cpp
------------------------------------------------------------
revno: 10555.1.5
committer: Benjamin Wolsey <address@hidden>
branch nick: savemedia
timestamp: Tue 2009-01-27 14:53:00 +0100
message:
Split saveMedia into saveStreamingMedia and saveLoadedMedia. Save in
directories based on hostname.
removed:
libbase/GnashSystemFileHeaders.h
added:
libbase/GnashFileUtilities.cpp
libbase/GnashFileUtilities.h
modified:
gui/gtk.cpp
libbase/GnashSystemIOHeaders.h
libbase/Makefile.am
libbase/curl_adapter.cpp
libbase/rc.cpp
libbase/rc.h
libcore/StreamProvider.cpp
libcore/asobj/NetConnection_as.cpp
libcore/asobj/SharedObject_as.cpp
libcore/impl.cpp
------------------------------------------------------------
revno: 10555.1.6
committer: Benjamin Wolsey <address@hidden>
branch nick: savemedia
timestamp: Tue 2009-01-27 17:40:28 +0100
message:
Use StreamProvider to get current NamingPolicy; may be moved somewhere
else eventually.
modified:
libcore/StreamProvider.cpp
libcore/StreamProvider.h
libcore/asobj/NetConnection_as.cpp
libcore/impl.cpp
------------------------------------------------------------
revno: 10555.1.7
committer: Benjamin Wolsey <address@hidden>
branch nick: savemedia
timestamp: Tue 2009-01-27 18:20:50 +0100
message:
Add an overwrite-existing naming policy.
modified:
libcore/StreamProvider.cpp
=== modified file 'gui/gtk.cpp'
--- a/gui/gtk.cpp 2009-01-22 20:10:39 +0000
+++ b/gui/gtk.cpp 2009-01-27 13:53:00 +0000
@@ -931,7 +931,7 @@
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-namespace { // anonimous
+namespace { // anonymous
class PreferencesDialog {
@@ -968,6 +968,9 @@
GtkWidget *urlOpenerText;
GtkWidget *librarySize;
GtkWidget *startStoppedToggle;
+ GtkWidget *mediaDir;
+ GtkWidget *saveStreamingMediaToggle;
+ GtkWidget *saveLoadedMediaToggle;
#ifdef USE_DEBUGGER
GtkWidget *DebuggerToggle;
#endif
@@ -995,7 +998,10 @@
versionText(0),
urlOpenerText(0),
librarySize(0),
- startStoppedToggle(0)
+ startStoppedToggle(0),
+ mediaDir(0),
+ saveStreamingMediaToggle(0),
+ saveLoadedMediaToggle(0)
#ifdef USE_DEBUGGER
,DebuggerToggle(0)
#endif
@@ -1045,17 +1051,40 @@
// For getting from const gchar* to std::string&
std::string tmp;
- if ( prefs->soundToggle )
-
_rcfile.useSound(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prefs->soundToggle)));
-
- if ( prefs->actionDumpToggle )
+ if (prefs->soundToggle) {
+ _rcfile.useSound(gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(prefs->soundToggle)));
+ }
+
+ if (prefs->saveLoadedMediaToggle) {
+ _rcfile.saveLoadedMedia(
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+ prefs->saveLoadedMediaToggle)));
+ }
+
+ if (prefs->saveStreamingMediaToggle) {
+ _rcfile.saveStreamingMedia(
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+ prefs->saveStreamingMediaToggle)));
+ }
+
+ if (prefs->mediaDir) {
+ tmp = gtk_entry_get_text(GTK_ENTRY(prefs->mediaDir));
+ _rcfile.setMediaDir(tmp);
+ }
+
+ if (prefs->actionDumpToggle) {
_rcfile.useActionDump(
-
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prefs->actionDumpToggle)));
-
- if ( prefs->parserDumpToggle )
+ gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(prefs->actionDumpToggle)));
+ }
+
+ if (prefs->parserDumpToggle) {
_rcfile.useParserDump(
-
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prefs->parserDumpToggle)));
-
+ gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(prefs->parserDumpToggle)));
+ }
+
if ( prefs->logfileName ) {
tmp = gtk_entry_get_text(GTK_ENTRY(prefs->logfileName));
_rcfile.setDebugLog(tmp);
@@ -1063,7 +1092,8 @@
if ( prefs->writeLogToggle ) {
_rcfile.useWriteLog(
-
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prefs->writeLogToggle)));
+ gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(prefs->writeLogToggle)));
}
if ( prefs->verbosityScale ) {
@@ -1079,22 +1109,26 @@
if ( prefs->ASCodingErrorToggle ) {
_rcfile.showASCodingErrors(
-
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prefs->ASCodingErrorToggle)));
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+ prefs->ASCodingErrorToggle)));
}
if ( prefs->malformedSWFToggle ) {
_rcfile.showMalformedSWFErrors(
-
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prefs->malformedSWFToggle)));
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+ prefs->malformedSWFToggle)));
}
if ( prefs->localHostToggle ) {
_rcfile.useLocalHost(
-
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prefs->localHostToggle)));
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+ prefs->localHostToggle)));
}
if ( prefs->localDomainToggle ) {
_rcfile.useLocalDomain(
-
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prefs->localDomainToggle)));
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+ prefs->localDomainToggle)));
}
if ( prefs->solLocalDomainToggle ) {
@@ -1374,30 +1408,36 @@
gtk_box_pack_start (GTK_BOX(securityvbox), privacylabel, FALSE, FALSE, 0);
GtkWidget *solsandboxlabel = gtk_label_new (_("Shared objects
directory:"));
- gtk_box_pack_start (GTK_BOX(securityvbox), solsandboxlabel, FALSE, FALSE,
0);
+ gtk_box_pack_start (GTK_BOX(securityvbox), solsandboxlabel, FALSE,
+ FALSE, 0);
gtk_misc_set_alignment (GTK_MISC (solsandboxlabel), 0, 0.5);
_prefs->solSandbox = gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(_prefs->solSandbox),
_rcfile.getSOLSafeDir().c_str());
- gtk_box_pack_start (GTK_BOX(securityvbox), _prefs->solSandbox, FALSE,
FALSE, 0);
+ gtk_entry_set_text(GTK_ENTRY(_prefs->solSandbox),
+ _rcfile.getSOLSafeDir().c_str());
+ gtk_box_pack_start (GTK_BOX(securityvbox), _prefs->solSandbox, FALSE,
+ FALSE, 0);
- _prefs->solReadOnlyToggle = gtk_check_button_new_with_mnemonic (
+ _prefs->solReadOnlyToggle = gtk_check_button_new_with_mnemonic(
_("Do _not write Shared Object files"));
- gtk_box_pack_start (GTK_BOX(securityvbox), _prefs->solReadOnlyToggle,
FALSE, FALSE, 0);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
(_prefs->solReadOnlyToggle),
+ gtk_box_pack_start (GTK_BOX(securityvbox), _prefs->solReadOnlyToggle,
+ FALSE, FALSE, 0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_prefs->solReadOnlyToggle),
_rcfile.getSOLReadOnly());
- _prefs->solLocalDomainToggle = gtk_check_button_new_with_mnemonic (
+ _prefs->solLocalDomainToggle = gtk_check_button_new_with_mnemonic(
_("Only _access local Shared Object files"));
- gtk_box_pack_start (GTK_BOX(securityvbox), _prefs->solLocalDomainToggle,
FALSE, FALSE, 0);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
(_prefs->solLocalDomainToggle),
- _rcfile.getSOLLocalDomain());
+ gtk_box_pack_start(GTK_BOX(securityvbox), _prefs->solLocalDomainToggle,
+ FALSE, FALSE, 0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
+ _prefs->solLocalDomainToggle), _rcfile.getSOLLocalDomain());
_prefs->localConnectionToggle = gtk_check_button_new_with_mnemonic (
_("Disable Local _Connection object"));
- gtk_box_pack_start (GTK_BOX(securityvbox), _prefs->localConnectionToggle,
FALSE, FALSE, 0);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
(_prefs->localConnectionToggle),
- _rcfile.getLocalConnection());
+ gtk_box_pack_start (GTK_BOX(securityvbox), _prefs->localConnectionToggle,
+ FALSE, FALSE, 0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
+ _prefs->localConnectionToggle), _rcfile.getLocalConnection());
}
void
@@ -1409,17 +1449,57 @@
// Media tab title
GtkWidget *mediatablabel = gtk_label_new_with_mnemonic (_("_Media"));
- gtk_notebook_append_page(GTK_NOTEBOOK(_notebook), GTK_WIDGET(mediavbox),
mediatablabel);
+ gtk_notebook_append_page(GTK_NOTEBOOK(_notebook),
+ GTK_WIDGET(mediavbox), mediatablabel);
// Sound
GtkWidget *soundlabel = gtk_label_new (_("<b>Sound</b>"));
gtk_label_set_use_markup (GTK_LABEL (soundlabel), TRUE);
gtk_box_pack_start(GTK_BOX(mediavbox), soundlabel, FALSE, FALSE, 0);
- _prefs->soundToggle = gtk_check_button_new_with_mnemonic (_("Use sound
_handler"));
- gtk_box_pack_start (GTK_BOX(mediavbox), _prefs->soundToggle, FALSE, FALSE,
0);
- // Align button state with rcfile
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (_prefs->soundToggle),
_rcfile.useSound());
+ _prefs->soundToggle = gtk_check_button_new_with_mnemonic(
+ _("Use sound _handler"));
+ gtk_box_pack_start (GTK_BOX(mediavbox), _prefs->soundToggle, FALSE,
+ FALSE, 0);
+ // Align button state with rcfile
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_prefs->soundToggle),
+ _rcfile.useSound());
+
+ // Save Media
+ GtkWidget *savemedia = gtk_label_new(_("<b>Media Streams</b>"));
+ gtk_label_set_use_markup(GTK_LABEL(savemedia), TRUE);
+ gtk_box_pack_start(GTK_BOX(mediavbox), savemedia, FALSE, FALSE, 0);
+
+ // Save streamed media Toggle
+ _prefs->saveStreamingMediaToggle = gtk_check_button_new_with_mnemonic(
+ _("Save media streams to disk"));
+ gtk_box_pack_start (GTK_BOX(mediavbox), _prefs->saveStreamingMediaToggle,
+ FALSE, FALSE, 0);
+ // Align button state with rcfile
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
+ _prefs->saveStreamingMediaToggle), _rcfile.saveStreamingMedia());
+
+ // Save loaded media Toggle
+ _prefs->saveLoadedMediaToggle = gtk_check_button_new_with_mnemonic(
+ _("Save dynamically loaded media to disk"));
+ gtk_box_pack_start (GTK_BOX(mediavbox), _prefs->saveLoadedMediaToggle,
+ FALSE, FALSE, 0);
+ // Align button state with rcfile
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
+ _prefs->saveLoadedMediaToggle), _rcfile.saveLoadedMedia());
+
+ // Directory for saving media
+ GtkWidget *mediastreamslabel = gtk_label_new(_("Saved media directory:"));
+ gtk_box_pack_start(GTK_BOX(mediavbox), mediastreamslabel, FALSE,
+ FALSE, 0);
+ gtk_misc_set_alignment (GTK_MISC (mediastreamslabel), 0, 0.5);
+
+ _prefs->mediaDir = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(_prefs->mediaDir),
+ _rcfile.getMediaDir().c_str());
+ gtk_box_pack_start(GTK_BOX(mediavbox), _prefs->mediaDir, FALSE,
+ FALSE, 0);
+
}
void
@@ -1468,7 +1548,7 @@
"detect your OS</i>"));
gtk_label_set_use_markup (GTK_LABEL (OSadvicelabel), TRUE);
gtk_misc_set_alignment (GTK_MISC (OSadvicelabel), 0, 0.5);
- gtk_box_pack_start(GTK_BOX(playervbox), OSadvicelabel, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(playervbox), OSadvicelabel, FALSE, FALSE, 0);
// URL opener
GtkWidget *urlopenerbox = gtk_hbox_new (FALSE, 2);
@@ -1479,9 +1559,11 @@
gtk_box_pack_start(GTK_BOX(urlopenerbox), urlopenerlabel, FALSE, FALSE, 0);
_prefs->urlOpenerText = gtk_entry_new ();
- gtk_box_pack_start(GTK_BOX(urlopenerbox), _prefs->urlOpenerText, FALSE,
FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(urlopenerbox), _prefs->urlOpenerText, FALSE,
+ FALSE, 0);
// Put text in the entry box
- gtk_entry_set_text(GTK_ENTRY(_prefs->urlOpenerText),
_rcfile.getURLOpenerFormat().c_str());
+ gtk_entry_set_text(GTK_ENTRY(_prefs->urlOpenerText),
+ _rcfile.getURLOpenerFormat().c_str());
// Performance
GtkWidget *performancelabel = gtk_label_new (_("<b>Performance</b>"));
@@ -1497,16 +1579,19 @@
gtk_box_pack_start(GTK_BOX(libraryhbox), librarylabel, FALSE, FALSE, 0);
_prefs->librarySize = gtk_spin_button_new_with_range(0, 100, 1);
- gtk_box_pack_start(GTK_BOX(libraryhbox), _prefs->librarySize, FALSE,
FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(libraryhbox), _prefs->librarySize, FALSE,
+ FALSE, 0);
// Align to _rcfile value:
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(_prefs->librarySize),
_rcfile.getMovieLibraryLimit());
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(_prefs->librarySize),
+ _rcfile.getMovieLibraryLimit());
_prefs->startStoppedToggle = gtk_check_button_new_with_mnemonic (
_("Start _Gnash in pause mode"));
- gtk_box_pack_start (GTK_BOX(playervbox), _prefs->startStoppedToggle,
FALSE, FALSE, 0);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
(_prefs->startStoppedToggle),
+ gtk_box_pack_start(GTK_BOX(playervbox), _prefs->startStoppedToggle,
+ FALSE, FALSE, 0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_prefs->startStoppedToggle),
_rcfile.startStopped());
-} // end of ::addPlayerTab
+}
=== modified file 'libbase/NetworkAdapter.h'
--- a/libbase/NetworkAdapter.h 2009-01-26 09:05:11 +0000
+++ b/libbase/NetworkAdapter.h 2009-01-27 09:49:22 +0000
@@ -47,7 +47,7 @@
//
/// @param url The url to fetch data from.
DSOEXPORT static std::auto_ptr<IOChannel> makeStream(
- const std::string& url);
+ const std::string& url, const std::string& cachefile);
/// \brief
/// Returns a read-only IOChannel that fetches data
@@ -58,7 +58,8 @@
/// @param url The url to post to.
/// @param postdata The url-encoded post data
DSOEXPORT static std::auto_ptr<IOChannel> makeStream(
- const std::string& url, const std::string& postdata);
+ const std::string& url, const std::string& postdata,
+ const std::string& cachefile);
/// \brief
/// Returns a read-only IOChannel that fetches data
@@ -70,8 +71,11 @@
/// @param postdata The url-encoded post data
/// @param headers A RequestHeaders map of custom headers to send.
DSOEXPORT static std::auto_ptr<IOChannel> makeStream(const std::string&
url,
- const std::string& postdata, const RequestHeaders& headers);
-
+ const std::string& postdata, const RequestHeaders& headers,
+ const std::string& cachefile);
+
+
+ typedef std::set<std::string, StringNoCaseLessThan> ReservedNames;
/// Check whether a RequestHeader is permitted.
//
@@ -80,12 +84,13 @@
/// @return true if the name is allowed.
DSOEXPORT static bool isHeaderAllowed(const std::string& headerName)
{
- return (_reservedNames.find(headerName) == _reservedNames.end());
+ const ReservedNames& names = reservedNames();
+ return (names.find(headerName) == names.end());
}
private:
- static std::set<std::string, StringNoCaseLessThan> _reservedNames;
+ static const ReservedNames& reservedNames();
};
=== modified file 'libbase/curl_adapter.cpp'
--- a/libbase/curl_adapter.cpp 2009-01-26 09:05:11 +0000
+++ b/libbase/curl_adapter.cpp 2009-01-27 13:53:00 +0000
@@ -41,7 +41,8 @@
// Stub for warning about access when no libcurl is defined.
std::auto_ptr<IOChannel>
-NetworkAdapter::makeStream(const std::string& /*url*/)
+NetworkAdapter::makeStream(const std::string& /*url*/, const std::string&,
+ const std::string& /*cachefile*/)
{
log_error(_("libcurl is not available, but "
"Gnash has attempted to use the curl adapter"));
@@ -49,14 +50,15 @@
}
std::auto_ptr<IOChannel>
-NetworkAdapter::makeStream(const std::string& url, const std::string& postdata)
+NetworkAdapter::makeStream(const std::string& url, const std::string& postdata,
+ const std::string& cachefile)
{
return makeStream(url);
}
std::auto_ptr<IOChannel>
NetworkAdapter::makeStream(const std::string& url, const std::string& postdata,
- const RequestHeaders& headers)
+ const RequestHeaders& headers, const std::string& cachefile)
{
return makeStream(url);
}
@@ -168,23 +170,28 @@
void exportCookies();
/// Shared handle data locking function
- void lockSharedHandle(CURL* handle, curl_lock_data data,
curl_lock_access access);
+ void lockSharedHandle(CURL* handle, curl_lock_data data,
+ curl_lock_access access);
/// Shared handle data unlocking function
void unlockSharedHandle(CURL* handle, curl_lock_data data);
/// Shared handle locking function
- static void lockSharedHandleWrapper(CURL* handle, curl_lock_data data,
curl_lock_access access, void* userptr)
+ static void lockSharedHandleWrapper(CURL* handle, curl_lock_data data,
+ curl_lock_access access, void* userptr)
{
CurlSession* ci = static_cast<CurlSession*>(userptr);
ci->lockSharedHandle(handle, data, access);
}
/// Shared handle unlocking function
- static void unlockSharedHandleWrapper(CURL* handle, curl_lock_data
data, void* userptr)
+ static void unlockSharedHandleWrapper(CURL* handle, curl_lock_data data,
+ void* userptr)
{
- //data defines what data libcurl wants to unlock, and you must
make sure that only one lick is given at any time for each kind of data.
- //userptr is the pointer you set with CURLSHOPT_USERDATA.
+ // data defines what data libcurl wants to unlock, and you must
+ // make sure that only one lock is given at any time for each kind
+ // of data.
+ // userptr is the pointer you set with CURLSHOPT_USERDATA.
CurlSession* ci = static_cast<CurlSession*>(userptr);
ci->unlockSharedHandle(handle, data);
}
@@ -209,10 +216,12 @@
{
if ( ++retries > 10 )
{
- log_error("Failed cleaning up share handle: %s. Giving
up after %d retries.", curl_share_strerror(code), retries);
+ log_error("Failed cleaning up share handle: %s. Giving
up after "
+ "%d retries.", curl_share_strerror(code), retries);
break;
}
- log_error("Failed cleaning up share handle: %s. Will try again
in a second.", curl_share_strerror(code));
+ log_error("Failed cleaning up share handle: %s. Will try again
in "
+ "a second.", curl_share_strerror(code));
gnashSleep(1000000);
}
_shandle = 0;
@@ -239,50 +248,55 @@
curl_global_init(CURL_GLOBAL_ALL);
_shandle = curl_share_init();
- if ( ! _shandle )
- throw gnash::GnashException("Failure initializing curl share
handle");
+ if (! _shandle) {
+ throw GnashException("Failure initializing curl share handle");
+ }
CURLSHcode ccode;
// Register share locking function
- ccode = curl_share_setopt(_shandle, CURLSHOPT_LOCKFUNC,
lockSharedHandleWrapper);
+ ccode = curl_share_setopt(_shandle, CURLSHOPT_LOCKFUNC,
+ lockSharedHandleWrapper);
if ( ccode != CURLSHE_OK ) {
- throw gnash::GnashException(curl_share_strerror(ccode));
+ throw GnashException(curl_share_strerror(ccode));
}
// Register share unlocking function
- ccode = curl_share_setopt(_shandle, CURLSHOPT_UNLOCKFUNC,
unlockSharedHandleWrapper);
+ ccode = curl_share_setopt(_shandle, CURLSHOPT_UNLOCKFUNC,
+ unlockSharedHandleWrapper);
if ( ccode != CURLSHE_OK ) {
- throw gnash::GnashException(curl_share_strerror(ccode));
+ throw GnashException(curl_share_strerror(ccode));
}
// Activate sharing of cookies and DNS cache
ccode = curl_share_setopt(_shandle, CURLSHOPT_SHARE,
CURL_LOCK_DATA_COOKIE);
if ( ccode != CURLSHE_OK ) {
- throw gnash::GnashException(curl_share_strerror(ccode));
+ throw GnashException(curl_share_strerror(ccode));
}
// Activate sharing of DNS cache (since we're there..)
ccode = curl_share_setopt(_shandle, CURLSHOPT_SHARE,
CURL_LOCK_DATA_DNS);
if ( ccode != CURLSHE_OK ) {
- throw gnash::GnashException(curl_share_strerror(ccode));
+ throw GnashException(curl_share_strerror(ccode));
}
// Pass ourselves as the userdata
ccode = curl_share_setopt(_shandle, CURLSHOPT_USERDATA, this);
if ( ccode != CURLSHE_OK ) {
- throw gnash::GnashException(curl_share_strerror(ccode));
+ throw GnashException(curl_share_strerror(ccode));
}
importCookies();
}
void
-CurlSession::lockSharedHandle(CURL* handle, curl_lock_data data,
curl_lock_access access)
+CurlSession::lockSharedHandle(CURL* handle, curl_lock_data data,
+ curl_lock_access access)
{
UNUSED(handle); // possibly being the 'easy' handle triggering the
request ?
- // data defines what data libcurl wants to lock, and you must make sure
that only one lock is given at any time for each kind of data.
+ // data defines what data libcurl wants to lock, and you must make
+ // sure that only one lock is given at any time for each kind of data.
// access defines what access type libcurl wants, shared or single.
// TODO: see if we may make use of the 'access' parameter
@@ -306,16 +320,17 @@
//log_debug("Share mutex locked");
break;
case CURL_LOCK_DATA_SSL_SESSION:
- gnash::log_error("lockSharedHandle: SSL session locking
unsupported");
+ log_error("lockSharedHandle: SSL session locking "
+ "unsupported");
break;
case CURL_LOCK_DATA_CONNECT:
- gnash::log_error("lockSharedHandle: connect locking
unsupported");
+ log_error("lockSharedHandle: connect locking
unsupported");
break;
case CURL_LOCK_DATA_LAST:
- gnash::log_error("lockSharedHandle: last locking
unsupported ?!");
+ log_error("lockSharedHandle: last locking unsupported
?!");
break;
default:
- gnash::log_error("lockSharedHandle: unknown shared data
%d", data);
+ log_error("lockSharedHandle: unknown shared data %d",
data);
break;
}
}
@@ -325,7 +340,8 @@
{
UNUSED(handle); // possibly being the 'easy' handle triggering the
request ?
- // data defines what data libcurl wants to lock, and you must make sure
that only one lock is given at any time for each kind of data.
+ // data defines what data libcurl wants to lock, and you must make
+ // sure that only one lock is given at any time for each kind of data.
switch (data)
{
case CURL_LOCK_DATA_DNS:
@@ -341,16 +357,18 @@
_shareMutexLock.unlock();
break;
case CURL_LOCK_DATA_SSL_SESSION:
- gnash::log_error("unlockSharedHandle: SSL session
locking unsupported");
+ log_error("unlockSharedHandle: SSL session locking "
+ "unsupported");
break;
case CURL_LOCK_DATA_CONNECT:
- gnash::log_error("unlockSharedHandle: connect locking
unsupported");
+ log_error("unlockSharedHandle: connect locking
unsupported");
break;
case CURL_LOCK_DATA_LAST:
- gnash::log_error("unlockSharedHandle: last locking
unsupported ?!");
+ log_error("unlockSharedHandle: last locking unsupported
?!");
break;
default:
- std::cerr << "unlockSharedHandle: unknown shared data "
<< data << std::endl;
+ std::cerr << "unlockSharedHandle: unknown shared data "
<<
+ data << std::endl;
break;
}
}
@@ -371,7 +389,7 @@
typedef std::map<std::string, std::string> PostData;
/// Open a stream from the specified URL
- CurlStreamFile(const std::string& url);
+ CurlStreamFile(const std::string& url, const std::string& cachefile);
/// Open a stream from the specified URL posting the specified variables
//
@@ -381,10 +399,12 @@
/// @param vars
/// The url-encoded post data.
///
- CurlStreamFile(const std::string& url, const std::string& vars);
+ CurlStreamFile(const std::string& url, const std::string& vars,
+ const std::string& cachefile);
CurlStreamFile(const std::string& url, const std::string& vars,
- const NetworkAdapter::RequestHeaders& headers);
+ const NetworkAdapter::RequestHeaders& headers,
+ const std::string& cachefile);
~CurlStreamFile();
@@ -424,7 +444,7 @@
private:
- void init(const std::string& url);
+ void init(const std::string& url, const std::string& cachefile);
// Use this file to cache data
FILE* _cache;
@@ -501,7 +521,7 @@
void *userp)
{
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("curl write callback called for (%d) bytes",
+ log_debug("curl write callback called for (%d) bytes",
size * nmemb);
#endif
CurlStreamFile* stream = static_cast<CurlStreamFile*>(userp);
@@ -526,7 +546,7 @@
boost::format fmt = boost::format("writing to cache file: requested "
"%d, wrote %d (%s)") %
size % wrote % std::strerror(errno);
- throw gnash::GnashException(fmt.str());
+ throw GnashException(fmt.str());
}
// Set the size of cached data
@@ -545,7 +565,7 @@
if ( ! _running )
{
#if GNASH_CURL_VERBOSE
- gnash::log_debug("Not running: fillCacheNonBlocking returning");
+ log_debug("Not running: fillCacheNonBlocking returning");
#endif
return;
}
@@ -559,7 +579,7 @@
if (mcode != CURLM_OK)
{
- throw gnash::GnashException(curl_multi_strerror(mcode));
+ throw GnashException(curl_multi_strerror(mcode));
}
// handle 404
@@ -573,13 +593,13 @@
{
#if GNASH_CURL_VERBOSE
- gnash::log_debug("fillCache(%d), called, currently cached: %d", size,
_cached);
+ log_debug("fillCache(%d), called, currently cached: %d", size, _cached);
#endif
if ( ! _running || _cached >= size ) {
#if GNASH_CURL_VERBOSE
- if (!_running) gnash::log_debug("Not running: returning");
- else gnash::log_debug("Already enough bytes cached: returning");
+ if (!_running) log_debug("Not running: returning");
+ else log_debug("Already enough bytes cached: returning");
#endif
return;
}
@@ -595,13 +615,13 @@
const long maxSleepUsec = 10000; // 1/100 of a second
const unsigned int userTimeout = static_cast<unsigned int>(
-
gnash::RcInitFile::getDefaultInstance().getStreamsTimeout()*1000);
+
RcInitFile::getDefaultInstance().getStreamsTimeout()*1000);
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("User timeout is %u milliseconds", userTimeout);
+ log_debug("User timeout is %u milliseconds", userTimeout);
#endif
- gnash::WallClockTimer lastProgress; // timer since last progress
+ WallClockTimer lastProgress; // timer since last progress
while (_running)
{
@@ -613,24 +633,24 @@
if (_cached >= size || !_running) break; // || _error ?
#if GNASH_CURL_VERBOSE
- //gnash::log_debug("cached: %d, size: %d", _cached, size);
+ //log_debug("cached: %d, size: %d", _cached, size);
#endif
mcode = curl_multi_fdset(_mhandle, &readfd, &writefd,
&exceptfd, &maxfd);
if (mcode != CURLM_OK) {
// This is a serious error, not just a failure to add
any
// fds.
- throw gnash::GnashException(curl_multi_strerror(mcode));
+ throw GnashException(curl_multi_strerror(mcode));
}
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("Max fd: %d", maxfd);
+ log_debug("Max fd: %d", maxfd);
#endif
// A value of -1 means no file descriptors were added.
if (maxfd < 0) {
#if GNASH_CURL_VERBOSE
- gnash::log_debug("No filedescriptors; breaking");
+ log_debug("No filedescriptors; breaking");
#endif
break;
}
@@ -643,7 +663,7 @@
tv.tv_usec = maxSleepUsec;
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("select() with %d milliseconds timeout",
maxSleepUsec*1000);
+ log_debug("select() with %d milliseconds timeout",
maxSleepUsec*1000);
#endif
// Wait for data on the filedescriptors until a timeout set
@@ -655,18 +675,18 @@
boost::format fmt = boost::format(
"error polling data from connection to %s: %s ")
% _url % strerror(errno);
- throw gnash::GnashException(fmt.str());
+ throw GnashException(fmt.str());
}
if ( ! ret )
{
// timeout
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("select() timed out, elapsed is %u",
+ log_debug("select() timed out, elapsed is %u",
lastProgress.elapsed());
#endif
if (userTimeout && lastProgress.elapsed() > userTimeout)
{
- gnash::log_error(_("Timeout (%u milliseconds) while loading "
+ log_error(_("Timeout (%u milliseconds) while loading "
"from url %s"), userTimeout, _url);
// TODO: should we set _error here ?
return;
@@ -675,7 +695,7 @@
else
{
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("FD activity, resetting progress timer");
+ log_debug("FD activity, resetting progress timer");
#endif
lastProgress.restart();
}
@@ -718,13 +738,13 @@
CURLINFO_RESPONSE_CODE,
&code);
if ( code >= 400 ) {
- gnash::log_error ("HTTP response %ld
from url %s",
+ log_error ("HTTP response %ld from url
%s",
code, _url);
_error = TU_FILE_OPEN_ERROR;
_running = false;
}
else {
- gnash::log_debug ("HTTP response %ld
from url %s",
+ log_debug ("HTTP response %ld from url
%s",
code, _url);
}
@@ -732,7 +752,7 @@
else {
// Transaction failed, pass on curl error.
- gnash::log_error("CURL: %s", curl_easy_strerror(
+ log_error("CURL: %s", curl_easy_strerror(
curl_msg->data.result));
_error = TU_FILE_OPEN_ERROR;
}
@@ -745,7 +765,7 @@
/*private*/
void
-CurlStreamFile::init(const std::string& url)
+CurlStreamFile::init(const std::string& url, const std::string& cachefile)
{
_customHeaders = 0;
@@ -759,11 +779,21 @@
_handle = curl_easy_init();
_mhandle = curl_multi_init();
- /// later on we might want to accept a filename
- /// in the constructor
- _cache = std::tmpfile();
+ const RcInitFile& rcfile = RcInitFile::getDefaultInstance();
+
+ if (!cachefile.empty()) {
+ _cache = std::fopen(cachefile.c_str(), "w+b");
+ if (!_cache) {
+
+ log_error("Could not open specified path as cache file. Using "
+ "a temporary file instead");
+ _cache = std::tmpfile();
+ }
+ }
+ else _cache = std::tmpfile();
+
if ( ! _cache ) {
- throw gnash::GnashException("Could not create temporary cache
file");
+ throw GnashException("Could not create temporary cache file");
}
_cachefd = fileno(_cache);
@@ -772,26 +802,28 @@
// Override cURL's default verification of SSL certificates
// This is insecure, so log security warning.
// Equivalent to curl -k or curl --insecure.
- if (gnash::RcInitFile::getDefaultInstance().insecureSSL())
+ if (rcfile.insecureSSL())
{
- gnash::log_security(_("Allowing connections to SSL sites with
invalid "
- "certificates"));
+ log_security(_("Allowing connections to SSL sites with invalid "
+ "certificates"));
ccode = curl_easy_setopt(_handle, CURLOPT_SSL_VERIFYPEER, 0);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
ccode = curl_easy_setopt(_handle, CURLOPT_SSL_VERIFYHOST, 0);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
}
// Get shared data
- ccode = curl_easy_setopt(_handle, CURLOPT_SHARE,
CurlSession::get().getSharedHandle());
+ ccode = curl_easy_setopt(_handle, CURLOPT_SHARE,
+ CurlSession::get().getSharedHandle());
+
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// Set expiration time for DNS cache entries, in seconds
@@ -804,19 +836,19 @@
//
ccode = curl_easy_setopt(_handle, CURLOPT_DNS_CACHE_TIMEOUT, 60);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
ccode = curl_easy_setopt(_handle, CURLOPT_USERAGENT, "Gnash-" VERSION);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
#ifdef GNASH_CURL_VERBOSE
// for verbose operations
ccode = curl_easy_setopt(_handle, CURLOPT_VERBOSE, 1);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
#endif
@@ -827,13 +859,13 @@
*/
ccode = curl_easy_setopt(_handle, CURLOPT_NOSIGNAL, true);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// set url
ccode = curl_easy_setopt(_handle, CURLOPT_URL, _url.c_str());
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
//curl_easy_setopt(_handle, CURLOPT_NOPROGRESS, false);
@@ -842,18 +874,18 @@
// set write data and function
ccode = curl_easy_setopt(_handle, CURLOPT_WRITEDATA, this);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
ccode = curl_easy_setopt(_handle, CURLOPT_WRITEFUNCTION,
CurlStreamFile::recv);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
ccode = curl_easy_setopt(_handle, CURLOPT_FOLLOWLOCATION, 1);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
//fillCache(32); // pre-cache 32 bytes
@@ -861,23 +893,25 @@
}
/*public*/
-CurlStreamFile::CurlStreamFile(const std::string& url)
+CurlStreamFile::CurlStreamFile(const std::string& url,
+ const std::string& cachefile)
{
log_debug("CurlStreamFile %p created", this);
- init(url);
+ init(url, cachefile);
// CURLMcode ret =
CURLMcode mcode = curl_multi_add_handle(_mhandle, _handle);
if ( mcode != CURLM_OK ) {
- throw gnash::GnashException(curl_multi_strerror(mcode));
+ throw GnashException(curl_multi_strerror(mcode));
}
}
/*public*/
-CurlStreamFile::CurlStreamFile(const std::string& url, const std::string& vars)
+CurlStreamFile::CurlStreamFile(const std::string& url, const std::string& vars,
+ const std::string& cachefile)
{
log_debug("CurlStreamFile %p created", this);
- init(url);
+ init(url, cachefile);
_postdata = vars;
@@ -885,7 +919,7 @@
ccode = curl_easy_setopt(_handle, CURLOPT_POST, 1);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// libcurl needs to access the POSTFIELDS during 'perform' operations,
@@ -894,7 +928,7 @@
// The _postdata member should meet this requirement
ccode = curl_easy_setopt(_handle, CURLOPT_POSTFIELDS,
_postdata.c_str());
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// This is to support binary strings as postdata
@@ -903,7 +937,7 @@
//
ccode = curl_easy_setopt(_handle, CURLOPT_POSTFIELDSIZE,
_postdata.size());
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// Disable sending an Expect: header, as some older HTTP/1.1
@@ -914,21 +948,23 @@
_customHeaders = curl_slist_append(_customHeaders, "Expect:");
ccode = curl_easy_setopt(_handle, CURLOPT_HTTPHEADER, _customHeaders);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
CURLMcode mcode = curl_multi_add_handle(_mhandle, _handle);
if ( mcode != CURLM_OK ) {
- throw gnash::GnashException(curl_multi_strerror(mcode));
+ throw GnashException(curl_multi_strerror(mcode));
}
}
/*public*/
-CurlStreamFile::CurlStreamFile(const std::string& url, const std::string&
vars, const NetworkAdapter::RequestHeaders& headers)
+CurlStreamFile::CurlStreamFile(const std::string& url, const std::string& vars,
+ const NetworkAdapter::RequestHeaders& headers,
+ const std::string& cachefile)
{
log_debug("CurlStreamFile %p created", this);
- init(url);
+ init(url, cachefile);
_postdata = vars;
@@ -957,12 +993,12 @@
ccode = curl_easy_setopt(_handle, CURLOPT_HTTPHEADER, _customHeaders);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
ccode = curl_easy_setopt(_handle, CURLOPT_POST, 1);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// libcurl needs to access the POSTFIELDS during 'perform' operations,
@@ -971,7 +1007,7 @@
// The _postdata member should meet this requirement
ccode = curl_easy_setopt(_handle, CURLOPT_POSTFIELDS,
_postdata.c_str());
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// This is to support binary strings as postdata
@@ -980,12 +1016,12 @@
//
ccode = curl_easy_setopt(_handle, CURLOPT_POSTFIELDSIZE,
_postdata.size());
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
CURLMcode mcode = curl_multi_add_handle(_mhandle, _handle);
if ( mcode != CURLM_OK ) {
- throw gnash::GnashException(curl_multi_strerror(mcode));
+ throw GnashException(curl_multi_strerror(mcode));
}
}
@@ -1009,14 +1045,14 @@
if ( eof() || _error ) return 0;
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug ("read(%d) called", bytes);
+ log_debug ("read(%d) called", bytes);
#endif
fillCache(tell() + bytes);
if ( _error ) return 0; // error can be set by fillCache
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("_cache.tell = %d", tell());
+ log_debug("_cache.tell = %d", tell());
#endif
return std::fread(dst, 1, bytes, _cache);
@@ -1035,7 +1071,7 @@
}
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug ("readNonBlocking(%d) called", bytes);
+ log_debug ("readNonBlocking(%d) called", bytes);
#endif
fillCacheNonBlocking();
@@ -1065,7 +1101,7 @@
bool ret = ( ! _running && feof(_cache) );
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("eof() returning %d", ret);
+ log_debug("eof() returning %d", ret);
#endif
return ret;
@@ -1078,7 +1114,7 @@
int ret = std::ftell(_cache);
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("tell() returning %ld", ret);
+ log_debug("tell() returning %ld", ret);
#endif
return ret;
@@ -1091,7 +1127,7 @@
{
#ifdef GNASH_CURL_WARN_SEEKSBACK
if ( pos < tell() ) {
- gnash::log_debug("Warning: seek backward requested (%ld from
%ld)",
+ log_debug("Warning: seek backward requested (%ld from %ld)",
pos, tell());
}
#endif
@@ -1101,12 +1137,12 @@
if ( _cached < (unsigned int)pos )
{
- gnash::log_error ("Warning: could not cache anough bytes on
seek: %d requested, %d cached", pos, _cached);
+ log_error ("Warning: could not cache anough bytes on seek: %d
requested, %d cached", pos, _cached);
return -1; // couldn't cache so many bytes
}
if (std::fseek(_cache, pos, SEEK_SET) == -1) {
- gnash::log_error("Warning: fseek failed");
+ log_error("Warning: fseek failed");
return -1;
} else {
return 0;
@@ -1128,15 +1164,15 @@
if ( mcode != CURLM_OK )
{
- throw gnash::IOException(curl_multi_strerror(mcode));
+ throw IOException(curl_multi_strerror(mcode));
}
long code;
curl_easy_getinfo(_handle, CURLINFO_RESPONSE_CODE, &code);
if ( code == 404 ) // file not found!
{
- throw gnash::IOException("File not found");
- //gnash::log_error(_("404 response from url %s"),
_url);
+ throw IOException("File not found");
+ //log_error(_("404 response from url %s"), _url);
//_error = TU_FILE_OPEN_ERROR;
//return;
}
@@ -1144,8 +1180,8 @@
}
if (std::fseek(_cache, 0, SEEK_END) == -1) {
- throw gnash::IOException("NetworkAdapter: fseek to end failed");
- //gnash::log_error("Warning: fseek to end failed");
+ throw IOException("NetworkAdapter: fseek to end failed");
+ //log_error("Warning: fseek to end failed");
//return -1;
}
}
@@ -1162,7 +1198,7 @@
}
#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("get_stream_size() returning %lu", _size);
+ log_debug("get_stream_size() returning %lu", _size);
#endif
return _size;
@@ -1200,20 +1236,20 @@
// Configure the fake handle to use the share (shared cookies in
particular..)
ccode = curl_easy_setopt(fakeHandle, CURLOPT_SHARE, getSharedHandle());
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// Configure the fake handle to read cookies from the specified file
ccode = curl_easy_setopt(fakeHandle, CURLOPT_COOKIEFILE, cookiesIn);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// need to pass a non-zero URL string for COOKIEFILE to
// be really parsed
ccode = curl_easy_setopt(fakeHandle, CURLOPT_URL, "");
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// perform, to activate actual cookie file parsing
@@ -1257,13 +1293,13 @@
// Configure the fake handle to use the share (shared cookies in
particular..)
ccode = curl_easy_setopt(fakeHandle, CURLOPT_SHARE, getSharedHandle());
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// Configure the fake handle to write cookies to the specified file
ccode = curl_easy_setopt(fakeHandle, CURLOPT_COOKIEJAR , cookiesOut);
if ( ccode != CURLE_OK ) {
- throw gnash::GnashException(curl_easy_strerror(ccode));
+ throw GnashException(curl_easy_strerror(ccode));
}
// Cleanup, to trigger actual cookie file flushing
@@ -1280,62 +1316,64 @@
//-------------------------------------------
std::auto_ptr<IOChannel>
-NetworkAdapter::makeStream(const std::string& url)
-{
-#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("making curl stream for %s", url);
-#endif
-
- std::auto_ptr<IOChannel> stream;
-
- try {
- stream.reset(new CurlStreamFile(url));
- }
- catch (const std::exception& ex) {
- gnash::log_error("curl stream: %s", ex.what());
- }
- return stream;
-}
-
-std::auto_ptr<IOChannel>
-NetworkAdapter::makeStream(const std::string& url, const std::string& postdata)
-{
-#ifdef GNASH_CURL_VERBOSE
- gnash::log_debug("making curl stream for %s", url);
-#endif
-
- std::auto_ptr<IOChannel> stream;
-
- try {
- stream.reset(new CurlStreamFile(url, postdata));
- }
- catch (const std::exception& ex) {
- gnash::log_error("curl stream: %s", ex.what());
- }
- return stream;
-}
-
-std::auto_ptr<IOChannel>
-NetworkAdapter::makeStream(const std::string& url, const std::string& postdata,
- const RequestHeaders& headers)
-{
-
- std::auto_ptr<IOChannel> stream;
-
- try {
- stream.reset(new CurlStreamFile(url, postdata, headers));
- }
- catch (const std::exception& ex) {
- gnash::log_error("curl stream: %s", ex.what());
+NetworkAdapter::makeStream(const std::string& url, const std::string&
cachefile)
+{
+#ifdef GNASH_CURL_VERBOSE
+ log_debug("making curl stream for %s", url);
+#endif
+
+ std::auto_ptr<IOChannel> stream;
+
+ try {
+ stream.reset(new CurlStreamFile(url, cachefile));
+ }
+ catch (const std::exception& ex) {
+ log_error("curl stream: %s", ex.what());
+ }
+ return stream;
+}
+
+std::auto_ptr<IOChannel>
+NetworkAdapter::makeStream(const std::string& url, const std::string& postdata,
+ const std::string& cachefile)
+{
+#ifdef GNASH_CURL_VERBOSE
+ log_debug("making curl stream for %s", url);
+#endif
+
+ std::auto_ptr<IOChannel> stream;
+
+ try {
+ stream.reset(new CurlStreamFile(url, postdata, cachefile));
+ }
+ catch (const std::exception& ex) {
+ log_error("curl stream: %s", ex.what());
+ }
+ return stream;
+}
+
+std::auto_ptr<IOChannel>
+NetworkAdapter::makeStream(const std::string& url, const std::string& postdata,
+ const RequestHeaders& headers, const std::string& cachefile)
+{
+
+ std::auto_ptr<IOChannel> stream;
+
+ try {
+ stream.reset(new CurlStreamFile(url, postdata, headers,
cachefile));
+ }
+ catch (const std::exception& ex) {
+ log_error("curl stream: %s", ex.what());
}
return stream;
}
-/// Define static member.
-std::set<std::string, StringNoCaseLessThan>
-NetworkAdapter::_reservedNames = boost::assign::list_of
+const NetworkAdapter::ReservedNames&
+NetworkAdapter::reservedNames()
+{
+ static const ReservedNames names = boost::assign::list_of
("Accept-Ranges")
("Age")
("Allow")
@@ -1368,6 +1406,9 @@
("Warning")
("WWW-Authenticate");
+ return names;
+}
+
} // namespace gnash
#endif // def USE_CURL
=== modified file 'libbase/rc.cpp'
--- a/libbase/rc.cpp 2009-01-22 20:10:39 +0000
+++ b/libbase/rc.cpp 2009-01-27 13:53:00 +0000
@@ -101,7 +101,9 @@
// TODO: give a default value, and let 0 mean "disabled" -- 0 currently
is overridden by libbase/shm.cpp
_lcshmkey(0),
_ignoreFSCommand(true),
- _quality(-1)
+ _quality(-1),
+ _saveStreamingMedia(false),
+ _saveLoadedMedia(false)
{
expandPath(_solsandbox);
@@ -418,6 +420,12 @@
continue;
}
+ if (noCaseCompare(variable, "mediaDir") ) {
+ expandPath(value);
+ _mediaCacheDir = value;
+ continue;
+ }
+
if (noCaseCompare(variable, "documentroot") ) {
_wwwroot = value;
continue;
@@ -506,6 +514,12 @@
||
extractNumber(_quality, "quality", variable, value)
||
+ extractSetting(_saveLoadedMedia, "saveLoadedMedia",
+ variable, value)
+ ||
+ extractSetting(_saveStreamingMedia, "saveStreamingMedia",
+ variable, value)
+ ||
extractSetting(_ignoreFSCommand, "ignoreFsCommand", variable,
value)
||
@@ -656,6 +670,8 @@
cmd << "LCTrace " << _lctrace << endl <<
cmd << "LCShmkey " << std::hex << (boost::uint32_t) _lcshmkey << endl <<
cmd << "ignoreFSCommand " << _ignoreFSCommand << endl <<
+ cmd << "saveStreamingMedia " << _saveStreamingMedia << endl <<
+ cmd << "saveLoadedMedia " << _saveLoadedMedia << endl <<
// Strings.
@@ -666,6 +682,7 @@
// debuglog to nothing, only to find it returns to "gnash-debug.log"
// at the next run (even though that's not the way to use it...)
+ cmd << "mediaDir " << _mediaCacheDir << endl <<
cmd << "debuglog " << _log << endl <<
cmd << "documentroot " << _wwwroot << endl <<
cmd << "flashSystemOS " << _flashSystemOS << endl <<
=== modified file 'libbase/rc.h'
--- a/libbase/rc.h 2009-01-22 20:10:39 +0000
+++ b/libbase/rc.h 2009-01-27 13:53:00 +0000
@@ -158,7 +158,9 @@
/// Sets the RcInitFile blacklist of domains to block
//
/// @param list a std::vector of strings containing domains without
protocol
- void setBlacklist (const std::vector<std::string>& list) { _blacklist =
list; }
+ void setBlacklist (const std::vector<std::string>& list) {
+ _blacklist = list;
+ }
/// Return the list of directories to be used as the 'local' sandbox
//
@@ -183,24 +185,42 @@
_localSandboxPath = path;
}
- const std::string& getFlashVersionString() const { return
_flashVersionString; }
- void setFlashVersionString(const std::string& value) { _flashVersionString
= value; }
-
- const std::string& getFlashSystemOS() const { return _flashSystemOS; }
- void setFlashSystemOS(const std::string& value) { _flashSystemOS = value; }
-
- const std::string& getFlashSystemManufacturer() const { return
_flashSystemManufacturer; }
- void setFlashSystemManufacturer(const std::string& value) {
_flashSystemManufacturer = value; }
+ const std::string& getFlashVersionString() const {
+ return _flashVersionString;
+ }
+
+ void setFlashVersionString(const std::string& value) {
+ _flashVersionString = value;
+ }
+
+ const std::string& getFlashSystemOS() const {
+ return _flashSystemOS;
+ }
+
+ void setFlashSystemOS(const std::string& value) {
+ _flashSystemOS = value;
+ }
+
+ const std::string& getFlashSystemManufacturer() const {
+ return _flashSystemManufacturer;
+ }
+
+ void setFlashSystemManufacturer(const std::string& value) {
+ _flashSystemManufacturer = value;
+ }
const std::string& getGstAudioSink() const { return _gstaudiosink; }
+
void setGstAudioSink(const std::string& value) { _gstaudiosink = value; }
int getRetries() const { return _retries; }
+
void setRetries(int x) { _retries = x; }
- /// Return the number of seconds of inactivity before timing out streams
downloads
+ /// The number of seconds of inactivity before timing out streams downloads
double getStreamsTimeout() const { return _streamsTimeout; }
- /// Set the number of seconds of inactivity before timing out streams
downloads
+
+ /// Set seconds of inactivity before timing out streams downloads
void setStreamsTimeout(const double &x) { _streamsTimeout = x; }
/// Get the URL opener command format
@@ -225,25 +245,125 @@
void setSOLSafeDir(const std::string &x) { _solsandbox = x; }
bool getSOLLocalDomain() const { return _sollocaldomain; }
+
void setSOLLocalDomain(bool x) { _sollocaldomain = x; }
+
bool getSOLReadOnly() const { return _solreadonly; }
+
void setSOLReadOnly(bool x) { _solreadonly = x; }
+
bool getLocalConnection() const { return _lcdisabled; }
+
void setLocalConnection(bool x) { _lcdisabled = x; }
+
// Enable tracing all LocalConnection traffic
bool getLCTrace() const { return _lctrace; }
+
void setLCTrace(bool x) { _lctrace = x; }
- //
key_t getLCShmKey() const { return static_cast<key_t>(_lcshmkey); }
+
void setLCShmKey(bool x) { _lcshmkey = x; }
bool ignoreFSCommand() const { return _ignoreFSCommand; }
+
void ignoreFSCommand(bool value) { _ignoreFSCommand = value; }
-
+
+ void saveStreamingMedia(bool value) { _saveStreamingMedia = value; }
+
+ bool saveStreamingMedia() const { return _saveStreamingMedia; }
+
+ void saveLoadedMedia(bool value) { _saveLoadedMedia = value; }
+
+ bool saveLoadedMedia() const { return _saveLoadedMedia; }
+
+ void setMediaDir(const std::string& value) { _mediaCacheDir = value; }
+
+ const std::string& getMediaDir() const { return _mediaCacheDir; }
+
void dump();
protected:
+
+ // A function only for writing path lists to an outstream.
+ void writeList(const PathList& list, std::ostream& o);
+
+ /// Construct only by getDefaultInstance()
+ RcInitFile();
+
+ /// Never destroy (TODO: add a destroyDefaultInstance)
+ ~RcInitFile();
+
+ /// Substitutes user's home directory for ~ on a path string
+ /// according to POSIX standard.
+ ///
+ /// @param path the path to expand.
+ static void expandPath(std::string& path);
+
+ /// \brief
+ /// If variable matches pattern (case-insensitive)
+ /// set var according to value
+ //
+ /// @return true if variable matches pattern, false otherwise
+ /// @param var the variable to change
+ /// @param pattern the pattern for matching
+ /// @variable the variable to match to pattern
+ /// @value the value to adopt if variable matches pattern.
+ static bool extractSetting(bool &var, const std::string& pattern,
+ const std::string &variable, const std::string &value);
+
+ /// \brief
+ /// If variable matches pattern (case-insensitive)
+ /// set num according to value
+ //
+ /// @return true if variable matches pattern, false otherwise
+ /// @param num the variable to change
+ /// @param pattern the pattern for matching
+ /// @variable the variable to match to pattern
+ /// @value the value to adopt if variable matches pattern.
+ template<typename T>
+ static bool extractNumber(T& num, const std::string& pattern,
+ const std::string &variable, const std::string &value)
+ {
+
+ StringNoCaseEqual noCaseCompare;
+
+ if (noCaseCompare(variable, pattern)) {
+ std::istringstream in(value);
+ if (in >> num) return true;
+
+ // If conversion fails, set value to 0 rather than leaving
+ // it as the default.
+ std::cerr << "Conversion overflow in extractNumber: " <<
+ value << std::endl;
+ num = 0;
+ return true;
+ }
+
+ return false;
+ }
+
+ /// \brief
+ /// If variable matches pattern (case-insensitive)
+ /// set out according to value
+ //
+ /// @return true if variable matches pattern, false otherwise
+ /// @param out the variable to change
+ /// @param pattern the pattern for matching
+ /// @variable the variable to match to pattern
+ /// @value the value to adopt if variable matches pattern.
+ static bool extractDouble(double &out, const std::string& pattern,
+ const std::string &variable, const std::string &value);
+
+
+ /// \brief parses a space-separated list into std::vector list
+ //
+ /// @param list the vector to modify or generate.
+ /// @param action either 'set' or 'append': whether to add to or
+ /// clear the vector.
+ /// @param items string of space-separated values. This gets nuked.
+ void parseList(std::vector<std::string>& list, const std::string &action,
+ const std::string &items);
typedef boost::char_separator<char> Sep;
typedef boost::tokenizer< Sep > Tok;
@@ -375,87 +495,11 @@
/// The quality to display SWFs in. -1 to allow the SWF to override.
int _quality;
-protected:
+ bool _saveStreamingMedia;
- // A function only for writing path lists to an outstream.
- void writeList(const PathList& list, std::ostream& o);
-
- /// Construct only by getDefaultInstance()
- RcInitFile();
-
- /// Never destroy (TODO: add a destroyDefaultInstance)
- ~RcInitFile();
-
- /// Substitutes user's home directory for ~ on a path string
- /// according to POSIX standard.
- ///
- /// @param path the path to expand.
- static void expandPath(std::string& path);
-
- /// \brief
- /// If variable matches pattern (case-insensitive)
- /// set var according to value
- //
- /// @return true if variable matches pattern, false otherwise
- /// @param var the variable to change
- /// @param pattern the pattern for matching
- /// @variable the variable to match to pattern
- /// @value the value to adopt if variable matches pattern.
- static bool extractSetting(bool &var, const std::string& pattern,
- const std::string &variable, const std::string &value);
-
- /// \brief
- /// If variable matches pattern (case-insensitive)
- /// set num according to value
- //
- /// @return true if variable matches pattern, false otherwise
- /// @param num the variable to change
- /// @param pattern the pattern for matching
- /// @variable the variable to match to pattern
- /// @value the value to adopt if variable matches pattern.
- template<typename T>
- static bool extractNumber(T& num, const std::string& pattern,
- const std::string &variable, const std::string &value)
- {
-
- StringNoCaseEqual noCaseCompare;
-
- if (noCaseCompare(variable, pattern)) {
- std::istringstream in(value);
- if (in >> num) return true;
-
- // If conversion fails, set value to 0 rather than leaving
- // it as the default.
- std::cerr << "Conversion overflow in extractNumber: " <<
- value << std::endl;
- num = 0;
- return true;
- }
-
- return false;
- }
-
- /// \brief
- /// If variable matches pattern (case-insensitive)
- /// set out according to value
- //
- /// @return true if variable matches pattern, false otherwise
- /// @param out the variable to change
- /// @param pattern the pattern for matching
- /// @variable the variable to match to pattern
- /// @value the value to adopt if variable matches pattern.
- static bool extractDouble(double &out, const std::string& pattern,
- const std::string &variable, const std::string &value);
-
-
- /// \brief parses a space-separated list into std::vector list
- //
- /// @param list the vector to modify or generate.
- /// @param action either 'set' or 'append': whether to add to or
- /// clear the vector.
- /// @param items string of space-separated values. This gets nuked.
- void parseList(std::vector<std::string>& list, const std::string &action,
- const std::string &items);
+ bool _saveLoadedMedia;
+
+ std::string _mediaCacheDir;
};
=== modified file 'libcore/StreamProvider.cpp'
--- a/libcore/StreamProvider.cpp 2009-01-27 12:23:12 +0000
+++ b/libcore/StreamProvider.cpp 2009-01-29 16:45:09 +0000
@@ -35,9 +35,22 @@
#include <map>
#include <string>
#include <vector>
-
-namespace gnash
-{
+#include <boost/algorithm/string/replace.hpp>
+
+namespace gnash {
+
+namespace {
+
+ std::string urlToDirectory(const std::string& path);
+
+ /// Make a unique cachefile name from the supplied name.
+ /// If all possible filenames are taken, return an empty string.
+ std::string incrementalRename(const URL& url);
+
+ /// Make a non-unique cachefile name from the supplied name.
+ /// If the directory cannot be created, return an empty string.
+ std::string overwriteExisting(const URL& url);
+}
StreamProvider&
StreamProvider::getDefaultInstance()
@@ -46,8 +59,15 @@
return inst;
}
+StreamProvider::NamingPolicy
+StreamProvider::currentNamingPolicy() const
+{
+ //return overwriteExisting;
+ return incrementalRename;
+}
+
std::auto_ptr<IOChannel>
-StreamProvider::getStream(const URL& url)
+StreamProvider::getStream(const URL& url, NamingPolicy np)
{
std::auto_ptr<IOChannel> stream;
@@ -72,7 +92,7 @@
else
{
// check security here !!
- if ( ! URLAccessManager::allow(url) ) return stream;
+ if (!URLAccessManager::allow(url)) return stream;
FILE *newin = std::fopen(path.c_str(), "rb");
if (!newin) {
@@ -85,8 +105,9 @@
}
else
{
- if ( URLAccessManager::allow(url) ) {
- stream = NetworkAdapter::makeStream(url.str());
+ if (URLAccessManager::allow(url)) {
+ stream = NetworkAdapter::makeStream(url.str(),
+ np ? np(url) : std::string());
}
// Will return 0 auto_ptr if not allowed.
@@ -96,7 +117,7 @@
std::auto_ptr<IOChannel>
StreamProvider::getStream(const URL& url, const std::string& postdata,
- const NetworkAdapter::RequestHeaders& headers)
+ const NetworkAdapter::RequestHeaders& headers, NamingPolicy np)
{
if (url.protocol() == "file")
@@ -110,7 +131,8 @@
}
if ( URLAccessManager::allow(url) ) {
- return NetworkAdapter::makeStream(url.str(), postdata, headers);
+ return NetworkAdapter::makeStream(url.str(), postdata, headers,
+ np ? np(url) : std::string());
}
return std::auto_ptr<IOChannel>();
@@ -118,7 +140,8 @@
}
std::auto_ptr<IOChannel>
-StreamProvider::getStream(const URL& url, const std::string& postdata)
+StreamProvider::getStream(const URL& url, const std::string& postdata,
+ NamingPolicy np)
{
std::auto_ptr<IOChannel> stream;
@@ -151,8 +174,9 @@
}
else
{
- if ( URLAccessManager::allow(url) ) {
- stream = NetworkAdapter::makeStream(url.str(),
postdata);
+ if (URLAccessManager::allow(url)) {
+ stream = NetworkAdapter::makeStream(url.str(), postdata,
+ np ? np(url) : std::string());
}
// Will return 0 auto_ptr if not allowed.
return stream;
@@ -160,5 +184,97 @@
}
}
+
+namespace {
+
+/// Transform a URL into a directory and create it.
+//
+/// @return an empty string if the directory cannot be created, otherwise
+/// the name of the created directory with a trailing slash.
+/// @param url The path to transform. Anything after the last '/' is ignored.
+std::string
+urlToDirectory(const std::string& path)
+{
+
+ const RcInitFile& rcfile = RcInitFile::getDefaultInstance();
+ const std::string& dir = rcfile.getMediaDir() + "/" + path;
+
+ // Create the user-specified directory if possible.
+ // An alternative would be to use the 'host' part and create a
+ // directory tree.
+ if (!mkdirRecursive(dir)) {
+ // Error
+ return std::string();
+ }
+
+ return dir;
+
+}
+
+std::string
+overwriteExisting(const URL& url)
+{
+ std::string path = url.path().substr(1);
+
+ // Replace all slashes with a _ for a flat directory structure.
+ boost::replace_all(path, "/", "_");
+
+ const std::string& dir = urlToDirectory(url.hostname() + "/");
+
+ if (dir.empty()) return std::string();
+
+ return dir + path;
+}
+
+std::string
+incrementalRename(const URL& url)
+{
+
+ const std::string& path = url.path();
+ assert(!path.empty());
+ assert(path[0] == '/');
+
+ // Find the last dot, but not if it's first in the path (after the
+ // initial '/').
+ std::string::size_type dot = path.rfind('.');
+ if (dot == 1) dot = std::string::npos;
+
+ // Take the path from after the initial '/' to the last '.' for
+ // manipulation. It doesn't matter if dot is npos.
+ std::string pre = path.substr(1, dot - 1);
+
+ // Replace all slashes with a _ for a flat directory structure.
+ boost::replace_all(pre, "/", "_");
+
+ const std::string& suffix = (dot == std::string::npos) ? "" :
+ path.substr(dot);
+
+ // Add a trailing slash.
+ const std::string& dir = urlToDirectory(url.hostname() + "/");
+ if (dir.empty()) return std::string();
+
+ std::ostringstream s(dir + pre + suffix);
+
+ size_t i = 0;
+
+ const size_t m = std::numeric_limits<size_t>::max();
+
+ struct stat st;
+ while (stat(s.str().c_str(), &st) >= 0 && i < m) {
+ s.str("");
+ s << dir << pre << i << suffix;
+ ++i;
+ }
+
+ // If there are no options left, return an empty string.
+ if (i == m) {
+ return std::string();
+ }
+
+ return s.str();
+
+}
+
+} // anonymous namespace
} // namespace gnash
=== modified file 'libcore/StreamProvider.h'
--- a/libcore/StreamProvider.h 2009-01-26 09:03:34 +0000
+++ b/libcore/StreamProvider.h 2009-01-27 16:40:28 +0000
@@ -39,6 +39,8 @@
public:
+ typedef std::string (*NamingPolicy) (const URL&);
+
StreamProvider() {}
virtual ~StreamProvider() {}
@@ -50,7 +52,8 @@
/// On error NULL is returned
/// Derive from this for a CachingStreamProvider
///
- virtual std::auto_ptr<IOChannel> getStream(const URL& url);
+ virtual std::auto_ptr<IOChannel> getStream(const URL& url,
+ NamingPolicy np = 0);
/// Get a stream from the response of a POST operation
//
@@ -67,12 +70,15 @@
///
///
virtual std::auto_ptr<IOChannel> getStream(const URL& url,
- const std::string& postdata);
+ const std::string& postdata, NamingPolicy np = 0);
virtual std::auto_ptr<IOChannel> getStream(const URL& url,
const std::string& postdata,
- const NetworkAdapter::RequestHeaders& headers);
+ const NetworkAdapter::RequestHeaders& headers, NamingPolicy np =
0);
+ /// Return the currently selected policy for converting URL to filename
+ virtual NamingPolicy currentNamingPolicy() const;
+
};
} // namespace gnash
=== modified file 'libcore/asobj/NetConnection_as.cpp'
--- a/libcore/asobj/NetConnection_as.cpp 2009-01-22 20:10:39 +0000
+++ b/libcore/asobj/NetConnection_as.cpp 2009-01-27 16:40:28 +0000
@@ -589,7 +589,8 @@
#endif
queued_count = 0;
- _connection.reset(StreamProvider::getDefaultInstance().getStream(_url,
postdata_str, _headers).release());
+ _connection.reset(StreamProvider::getDefaultInstance().getStream(
+ _url, postdata_str, _headers).release());
_postdata.resize(6);
#ifdef GNASH_DEBUG_REMOTING
@@ -959,7 +960,14 @@
// If name is a full or relative URL passed from NetStream.play(), it
// must be constructed against the base URL, not the NetConnection uri,
// which should always be null in this case.
- return streamProvider.getStream(URL(name, ri.baseURL()));
+ const URL url(name, ri.baseURL());
+
+ const RcInitFile& rcfile = RcInitFile::getDefaultInstance();
+
+ StreamProvider::NamingPolicy cacheNamer = rcfile.saveStreamingMedia() ?
+ streamProvider.currentNamingPolicy() : 0;
+
+ return streamProvider.getStream(url, cacheNamer);
}
=== modified file 'libcore/impl.cpp'
--- a/libcore/impl.cpp 2009-01-22 20:10:39 +0000
+++ b/libcore/impl.cpp 2009-01-27 16:40:28 +0000
@@ -324,8 +324,15 @@
StreamProvider& streamProvider = runInfo.streamProvider();
- if ( postdata ) in = streamProvider.getStream(url, *postdata);
- else in = streamProvider.getStream(url);
+ const RcInitFile& rcfile = RcInitFile::getDefaultInstance();
+
+ StreamProvider::NamingPolicy cacheNamer = rcfile.saveLoadedMedia() ?
+ streamProvider.currentNamingPolicy() : 0;
+
+ if ( postdata ) in = streamProvider.getStream(url, *postdata,
+ cacheNamer);
+ else in = streamProvider.getStream(url, cacheNamer);
+
if ( ! in.get() )
{
log_error(_("failed to open '%s'; can't create movie"), url);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10558: Allow users the option of saving loaded or streamed media, currently,
Benjamin Wolsey <=