[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r9582: Fix 404 handling with non-blo
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r9582: Fix 404 handling with non-blocking read (well, kind-of). |
Date: |
Tue, 12 Aug 2008 15:11:56 +0200 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 9582
committer: Sandro Santilli <address@hidden>
branch nick: trunk
timestamp: Tue 2008-08-12 15:11:56 +0200
message:
Fix 404 handling with non-blocking read (well, kind-of).
Improve remoting by dropping any string_table lookups and properly
handle 404.
modified:
libbase/curl_adapter.cpp
libcore/asobj/NetConnection.cpp
libcore/namedStrings.cpp
libcore/namedStrings.h
------------------------------------------------------------
revno: 9580.1.1
committer: Sandro Santilli <address@hidden>
branch nick: mybranch
timestamp: Tue 2008-08-12 14:53:44 +0200
message:
Add PROP_ON_RESULT
modified:
libcore/namedStrings.cpp
libcore/namedStrings.h
------------------------------------------------------------
revno: 9580.1.2
committer: Sandro Santilli <address@hidden>
branch nick: mybranch
timestamp: Tue 2008-08-12 14:58:45 +0200
message:
Handle 404 or other http errors when doing non-blocking reads
modified:
libbase/curl_adapter.cpp
------------------------------------------------------------
revno: 9580.1.3
committer: Sandro Santilli <address@hidden>
branch nick: mybranch
timestamp: Tue 2008-08-12 14:59:08 +0200
message:
Handle IO errors by invoking NetConnection.onStatus
modified:
libcore/asobj/NetConnection.cpp
=== modified file 'libbase/curl_adapter.cpp'
--- a/libbase/curl_adapter.cpp 2008-07-10 16:36:19 +0000
+++ b/libbase/curl_adapter.cpp 2008-08-12 12:58:45 +0000
@@ -444,6 +444,9 @@
// Will call libcurl routines to fetch data.
void fillCache(long unsigned size);
+ // Process pending curl messages (handles 404)
+ void processMessages();
+
// Filling the cache as much as possible w/out blocking.
// Will call libcurl routines to fetch data.
void fillCacheNonBlocking();
@@ -532,6 +535,9 @@
{
throw gnash::GnashException(curl_multi_strerror(mcode));
}
+
+ // handle 404
+ processMessages();
}
@@ -573,12 +579,12 @@
while (_running)
{
- fillCacheNonBlocking();
+ fillCacheNonBlocking(); // NOTE: will handle 404
// Do this here to avoid calling select()
// when we have enough bytes anyway, or
// we reached EOF
- if (_cached >= size || !_running) break;
+ if (_cached >= size || !_running) break; // || _error ?
#if GNASH_CURL_VERBOSE
//gnash::log_debug("cached: %d, size: %d", _cached, size);
@@ -655,11 +661,22 @@
}
+ // Processing messages is already done by fillCacheNonBlocking,
+ // so we might likely avoid it here.
+ processMessages();
+
+}
+
+/*private*/
+void
+CurlStreamFile::processMessages()
+{
CURLMsg *curl_msg;
// The number of messages left in the queue (not used by us).
int msgs;
- while ((curl_msg = curl_multi_info_read(_mhandle, &msgs))) {
+ while ((curl_msg = curl_multi_info_read(_mhandle, &msgs)))
+ {
// Only for completed transactions
if (curl_msg->msg == CURLMSG_DONE) {
@@ -696,7 +713,6 @@
}
}
-
}
=== modified file 'libcore/asobj/NetConnection.cpp'
--- a/libcore/asobj/NetConnection.cpp 2008-08-12 09:59:57 +0000
+++ b/libcore/asobj/NetConnection.cpp 2008-08-12 12:59:08 +0000
@@ -46,6 +46,8 @@
#include "amf.h"
#include "SimpleBuffer.h"
#include "timers.h"
+#include "namedStrings.h"
+
using namespace amf;
namespace gnash {
@@ -504,8 +506,8 @@
int reply_start;
int reply_end;
int queued_count;
- uint8_t am_ticking;
unsigned int ticker;
+
public:
AMFQueue(NetConnection& nc, URL url)
:
@@ -517,7 +519,7 @@
reply_start(0),
reply_end(0),
queued_count(0),
- am_ticking(0)
+ ticker(0)
{
// leave space for header
postdata.append("\000\000\000\000\000\000", 6);
@@ -527,12 +529,12 @@
stop_ticking();
}
- void enqueue(SimpleBuffer &amf, std::string identifier,
boost::intrusive_ptr<as_object> callback) {
+ void enqueue(const SimpleBuffer &amf, const std::string& identifier,
boost::intrusive_ptr<as_object> callback) {
push_amf(amf);
push_callback(identifier, callback);
//log_aserror("NetConnection::call(): called with a non-object
as the callback");
};
- void enqueue(SimpleBuffer &amf) {
+ void enqueue(const SimpleBuffer &amf) {
push_amf(amf);
};
@@ -542,8 +544,10 @@
// it handles all networking for NetConnection::call() and dispatches
// callbacks when needed
void tick() {
+
log_debug("tick running");
- if(connection) {
+ if(connection)
+ {
log_debug("have connection");
int read = connection->readNonBlocking(reply.data() +
reply_end, NCCALLREPLYMAX - reply_end);
if(read > 0) {
@@ -564,126 +568,143 @@
// FIXME make this parse on other conditions,
including: 1) when
// the buffer is full, 2) when we have a "length in
bytes" value
// thas is satisfied
+
+ if(connection->get_error())
+ {
+ log_debug("connection is in error condition,
calling NetConnection.onStatus");
+ reply_start = 0;
+ reply_end = 0;
+
+ // FIXME: should only call NetConnection's
onStatus
+ // if the IOChannel is in error
condition.
+ // (tipically 404).
+ // When the response is empty, just
nothing happens.
+ _nc.callMethod(NSV::PROP_ON_STATUS, as_value());
+ return;
+ }
- if(connection->eof() && reply_end > 8) {
- log_debug("hit eof");
- boost::int16_t si;
- boost::uint16_t li;
- boost::uint8_t *b = reply.data() + reply_start;
- boost::uint8_t *end = reply.data() + reply_end;
+ if(connection->eof() )
+ {
+ if ( reply_end > 8)
+ {
+ log_debug("hit eof");
+ boost::int16_t si;
+ boost::uint16_t li;
+ boost::uint8_t *b = reply.data() +
reply_start;
+ boost::uint8_t *end = reply.data() +
reply_end;
- // parse header
- b += 2; // skip version indicator and client id
- si = readNetworkShort(b); b += 2; // number of
headers
- uint8_t headers_ok = 1;
- if(si != 0)
- {
- log_debug("NetConnection::call(): amf
headers section parsing");
- as_value tmp;
- for(int i = si; i > 0; --i)
+ // parse header
+ b += 2; // skip version indicator and
client id
+ si = readNetworkShort(b); b += 2; //
number of headers
+ uint8_t headers_ok = 1;
+ if(si != 0)
{
- if(b + 2 > end) {
- headers_ok = 0;
- break;
- }
- si = readNetworkShort(b); b +=
2; // name length
- if(b + si > end) {
- headers_ok = 0;
- break;
- }
- b += si;
- if ( b + 5 > end ) {
- headers_ok = 0;
- break;
- }
- b += 5; // skip past bool and
length long
- if( !amf0_read_value(b, end,
tmp) )
+
log_debug("NetConnection::call(): amf headers section parsing");
+ as_value tmp;
+ for(int i = si; i > 0; --i)
{
- headers_ok = 0;
- break;
- }
- log_debug("Header value %s",
tmp);
- }
- }
-
- if(headers_ok == 1) {
-
- si = readNetworkShort(b); b += 2; //
number of replies
-
- // TODO consider counting number of
replies we
- // actually parse and doing something
if it
- // doesn't match this value (does it
matter?
- if(si > 0) {
- // parse replies until we get a
parse error or we reach the end of the buffer
- while(b < end) {
- if(b + 2 > end) break;
- si =
readNetworkShort(b); b += 2; // reply length
- if(si < 11) {
-
log_error("NetConnection::call(): reply message name too short");
- break;
- }
- if(b + si > end) break;
- // TODO check that the
last 9 bytes are "/onResult"
- // this should either
split on the 2nd / or require onResult or onStatus
- std::string
id(reinterpret_cast<char*>(b), si - 9);
- b += si;
-
- // parse past unused
string in header
- if(b + 2 > end) break;
- si =
readNetworkShort(b); b += 2; // reply length
- if(b + si > end) break;
- b += si;
-
- // this field is
supposed to hold the
- // total number of
bytes in the rest of
- // this particular
reply value, but
- // openstreetmap.org
(which works great
- // in the adobe player)
sends
- // 0xffffffff. So we
just ignore it
- if(b + 4 > end) break;
- li =
readNetworkLong(b); b += 4; // reply length
-
- log_debug("about to
parse amf value");
- // this updates b to
point to the next unparsed byte
- as_value reply_as_value;
- if ( !
amf0_read_value(b, end, reply_as_value) )
+ if(b + 2 > end) {
+ headers_ok = 0;
+ break;
+ }
+ si =
readNetworkShort(b); b += 2; // name length
+ if(b + si > end) {
+ headers_ok = 0;
+ break;
+ }
+ b += si;
+ if ( b + 5 > end ) {
+ headers_ok = 0;
+ break;
+ }
+ b += 5; // skip past
bool and length long
+ if( !amf0_read_value(b,
end, tmp) )
{
-
log_error("parse amf failed");
- // this will
happen if we get
- // bogus data,
or if the data runs
- // off the end
of the buffer
- // provided, or
if we get data we
- // don't know
how to parse
+ headers_ok = 0;
break;
}
- log_debug("parsed amf");
-
- // update variable to
show how much we've parsed
- reply_start = b -
reply.data();
-
- // if actionscript
specified a callback object, call it
-
boost::intrusive_ptr<as_object> callback = pop_callback(id);
- if(callback) {
-
log_debug("calling callback");
-
string_table::key callback_method = callback -> getVM() . getStringTable() .
find(std::string("onResult"));
- // FIXME check
if above line can fail and we have to react
-
callback->callMethod(callback_method, reply_as_value);
-
log_debug("callback called");
- } else {
-
log_debug("couldn't find callback object");
+ log_debug("Header value
%s", tmp);
+ }
+ }
+
+ if(headers_ok == 1) {
+
+ si = readNetworkShort(b); b +=
2; // number of replies
+
+ // TODO consider counting
number of replies we
+ // actually parse and doing
something if it
+ // doesn't match this value
(does it matter?
+ if(si > 0) {
+ // parse replies until
we get a parse error or we reach the end of the buffer
+ while(b < end) {
+ if(b + 2 > end)
break;
+ si =
readNetworkShort(b); b += 2; // reply length
+ if(si < 11) {
+
log_error("NetConnection::call(): reply message name too short");
+ break;
+ }
+ if(b + si >
end) break;
+ // TODO check
that the last 9 bytes are "/onResult"
+ // this should
either split on the 2nd / or require onResult or onStatus
+ std::string
id(reinterpret_cast<char*>(b), si - 9);
+ b += si;
+
+ // parse past
unused string in header
+ if(b + 2 > end)
break;
+ si =
readNetworkShort(b); b += 2; // reply length
+ if(b + si >
end) break;
+ b += si;
+
+ // this field
is supposed to hold the
+ // total number
of bytes in the rest of
+ // this
particular reply value, but
+ //
openstreetmap.org (which works great
+ // in the adobe
player) sends
+ // 0xffffffff.
So we just ignore it
+ if(b + 4 > end)
break;
+ li =
readNetworkLong(b); b += 4; // reply length
+
+
log_debug("about to parse amf value");
+ // this updates
b to point to the next unparsed byte
+ as_value
reply_as_value;
+ if ( !
amf0_read_value(b, end, reply_as_value) )
+ {
+
log_error("parse amf failed");
+ // this
will happen if we get
+ //
bogus data, or if the data runs
+ // off
the end of the buffer
+ //
provided, or if we get data we
+ //
don't know how to parse
+ break;
+ }
+
log_debug("parsed amf");
+
+ // update
variable to show how much we've parsed
+ reply_start = b
- reply.data();
+
+ // if
actionscript specified a callback object, call it
+
boost::intrusive_ptr<as_object> callback = pop_callback(id);
+ if(callback) {
+
log_debug("calling callback");
+ //
FIXME check if above line can fail and we have to react
+
callback->callMethod(NSV::PROP_ON_RESULT, reply_as_value);
+
log_debug("callback called");
+ } else {
+
log_debug("couldn't find callback object");
+ }
}
}
}
}
- }
+ else
+ {
+ log_error("Response from remoting
service < 8 bytes");
+ }
- if(connection->eof()) {
log_debug("deleting connection");
connection.reset();
reply_start = 0;
reply_end = 0;
-
- // FIXME send onStatus callback to any callback
objects from this batch (must change some code to distinguish somehow)
}
}
@@ -717,9 +738,8 @@
private:
void start_ticking() {
- if(am_ticking) {
- return;
- }
+
+ if(ticker) return;
boost::intrusive_ptr<builtin_function> ticker_as = \
new builtin_function(&AMFQueue::amfqueue_tick_wrapper);
@@ -727,10 +747,8 @@
unsigned long delayMS = 500; // FIXME crank up to 50 or so
timer->setInterval(*ticker_as, delayMS, &_nc);
ticker = _nc.getVM().getRoot().add_interval_timer(timer, true);
-
- am_ticking = 1;
}
- void push_amf(SimpleBuffer &amf) {
+ void push_amf(const SimpleBuffer &amf) {
log_debug("pushing amf");
postdata.append(amf.data(), amf.size());
queued_count++;
@@ -738,13 +756,11 @@
start_ticking();
}
void stop_ticking() {
- if(!am_ticking) {
- return;
- }
+ if(ticker) return;
_nc.getVM().getRoot().clear_interval_timer(ticker);
- am_ticking = 0;
+ ticker=0;
}
- void push_callback(std::string id, boost::intrusive_ptr<as_object>
callback) {
+ void push_callback(const std::string& id,
boost::intrusive_ptr<as_object> callback) {
callbacks.insert(std::pair<std::string,
boost::intrusive_ptr<as_object> >(id, callback));
}
boost::intrusive_ptr<as_object> pop_callback(std::string id) {
@@ -958,15 +974,14 @@
as_value response;
if ( amf0_read_value(b, end, response) )
{
- string_table::key callbackMethod =
asCallback -> getVM() . getStringTable() . find(std::string("onResult"));
- asCallback->callMethod(callbackMethod,
response);
+
asCallback->callMethod(NSV::PROP_ON_RESULT, response);
}
else
{
// TODO construct an object with info
about the failure to pass to onStatus
// see:
http://livedocs.adobe.com/fms/2/docs/00000742.html
- //string_table::key callbackMethod =
asCallback->getVM().getStringTable().find(std::string("onStatus"));
-
//asCallback->callMethod(callbackMethod, TODO);
+ log_unimpl("NetConnection.call() :
triggering responder's onStatus on decoding error");
+
//asCallback->callMethod(NSV::PROP_ON_STATUS, TODO);
}
}
}
=== modified file 'libcore/namedStrings.cpp'
--- a/libcore/namedStrings.cpp 2008-07-21 09:56:09 +0000
+++ b/libcore/namedStrings.cpp 2008-08-12 12:53:44 +0000
@@ -94,6 +94,7 @@
string_table::svt( "onKillFocus", NSV::PROP_ON_KILL_FOCUS ),
string_table::svt( "onSelect", NSV::PROP_ON_SELECT ),
string_table::svt( "onStatus", NSV::PROP_ON_STATUS ),
+ string_table::svt( "onResult", NSV::PROP_ON_RESULT ),
string_table::svt( "onMetaData", NSV::PROP_ON_META_DATA ),
string_table::svt( "onSockClose", NSV::PROP_ON_SOCK_CLOSE ),
string_table::svt( "onSockConnect", NSV::PROP_ON_SOCK_CONNECT ),
=== modified file 'libcore/namedStrings.h'
--- a/libcore/namedStrings.h 2008-07-21 09:56:09 +0000
+++ b/libcore/namedStrings.h 2008-08-12 12:53:44 +0000
@@ -112,6 +112,7 @@
PROP_ON_KILL_FOCUS,
PROP_ON_SELECT,
PROP_ON_STATUS,
+ PROP_ON_RESULT,
PROP_ON_META_DATA,
PROP_ON_SOCK_CLOSE,
PROP_ON_SOCK_CONNECT,
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r9582: Fix 404 handling with non-blocking read (well, kind-of).,
Sandro Santilli <=