Topic: local network access

I'm working on making a Chumby widget that uses uTorrent's JSON API to display the progress of bittorrent downloads on a PC that is on the same network as the Chumby.

After a few hours of experimentation, I've managed to get it to work perfectly when it runs from my USB thumbdrive. Unfortunately, when I upload the widget and assign it to a channel and run it that way, it doesn't work.

Does anybody happen to know exactly what the differences are between running a widget from a thumbdrive and running a widget via a channel? Some of my best ideas for Chumby widgets involve this kind of communication with a computer on the Chumby's local network, so I'd really like to figure this out.

Re: local network access

Very likely a crossdomain.xml file issue. You should look in the wiki to see if you will be able to resolve the issue or not. (More-or-less, Flash isn't going to be able to look at anything on the utorrent web server unless the crossdomain.xml file exists; you may need to ask the utorrent guys to add a crossdomain.xml file to their webserver to allow flash widgets to access the data/api).

Also, now that I've got a physical chumby, an interesting workaround pops up: it might be possible to pass the widget's local webserver off as the RSS host; use a CGI script of somekind to access the local network and act as a proxy. Never underestimate the power of a tiny computer running a webserver. Of course, this is very hacky, and certainly wouldn't work for internet widgets (you can't make any guarentees the local webserver will have the script necessary for the widget to operate), but it's a possible way of getting it to work. As is, Chumby isn't well-configured for local network widgets like the one you're working on.

Hope that helps.

Re: local network access

The uTorrent widget isn't accessing a remote server, it is accessing a web service that is running on a local network PC running uTorrent, so a crossdomain.xml file isn't required. It works just fine without a crossdomain.xml file when I run the widget on the Chumby from the usb thumb drive.

What I'm trying to figure out is why a Chumby widget running from a USB thumbdrive can access computers on the local network but one running on a Chumby channel cannot.

Re: local network access

you still need the crossdomain.xml file because your widget is coming from chumby.com while your service is local to your network (it doesn't matter that you are running the widget on a machine in the network).

when running from the USB drive your are running a "local" widget (local to the chumby) so you don't need the crossdomain file.

Just put this in the document root on your server:

<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>

Re: local network access

Thank you for clarifying. I didn't realize that widgets running on the Chumby from a channel are running from Chumby.com. That's really frustrating. In order to make a service running on my desktop PC accessible to the Chumby I'd have to use port forwarding to expose it to the internet (which creates security problems) and then add a crossdomain.xml file.

Adding a crossdomain.xml file isn't even possible in this case because the service I'm trying to access is integrated into uTorrent and I can't modify how it operates, so I'll have to make a Python script or something that implements a small server that emits a crossdomain.xml file and relays data to/from uTorrent.

Additionally, I imagine that since the widget is running from Chumby.com and communicating over the internet rather than my local network it will waste bandwidth, which isn't desirable.

I don't like this at all. Having the widgets run from Chumby.com practically defeats the whole purpose of having a device like this on the local network, IMO. I guess I'll eschew channels and just run my widgets off of the  device's internal storage or from the USB thumbdrive. I seriously think the entire concept of channels needs to be rethought.

Re: local network access

The widgets are not "running from chumby.com", they're running in the *security domain* chumby.com.  They're actually downloaded into the device and run from there, but within a *security sandbox* that is associated with chumby.com.

This security model is not a function of the chumby device, or channels or anything like that. It's the security model of Flash, and it's there for a really good reason.

Flash movies are untrusted applications with access to the network.  Here's the scenario this is attempting to address:

Let's say your chumby is running behind a firewall, and there are private web servers with sensitive information also running behind that same firewall.  A malicious hacker could put a widget on the chumby service that could scan your local network, collect information from those servers, and upload it to some external server.

The security model is exactly the same as the one used by the desktop Flash browser plugin - we haven't added or removed anything.  A file run from the local device or the Flash IDE has different security privileges, as you've already discovered, since it's assumed you know what you're doing.

Re: local network access

Here's a simple hack for getting around this restriction on your own chumby, done by adding some very simple CGI to the built-in web service to respond with an appropriate crossdomain.xml file and fetch data from external servers.

in file /www/crossdomain.xml, put:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <allow-access-from domain="*"/>
</cross-domain-policy>

in file /www/cgi-bin/proxy, put:

#!/bin/sh
wget --save-headers -O - -o /dev/null $QUERY_STRING

...and mark it executable with 'chmod +x /www/cgi-bin/proxy'.

This creates a local proxy with which you can fetch data from external domains from a widget.  For example:

http://127.0.0.1/cgi-bin/proxy?http://www.google.com

This is a hack, usual caveats apply.  By doing this, you are potentially exposing your local area network to exploits.

If there is a particular service you wish to proxy, my (strong) suggestion is that you modify this script to meet your specific needs so that you minimize your exposure.

Re: local network access

Another easy workaround is to put another .swf on your server and load it into your widget via loadMovie().  This is how I got to reach out to youtube (which doesn't have crossdomain.xml open).  That is, my widget loads a movie on my server... that .swf reads youtube via a proxy on my server.

Re: local network access

phillipk wrote:

Another easy workaround is to put another .swf on your server and load it into your widget via loadMovie().  This is how I got to reach out to youtube (which doesn't have crossdomain.xml open).  That is, my widget loads a movie on my server... that .swf reads youtube via a proxy on my server.

I'm not sure that helps this particular problem, which is granting access to XML feeds from servers on the LAN.

What we might do is implement a local proxy service as I showed above, and give some sort of configuration setting in the Control Panel to allow folks to turn the feature on after warning them about the security implications. The nice thing about this solution is that it doesn't require modifications to the service or running another server to provide the proxy.

Re: local network access

I _think_ you could put your main .swf on the LAN where it would have access to those XML feeds.  Then, the widget you install from chumby.com simply does a loadMovie("fileOnLan.swf").

I've got an example sort of working:
main.swf does loadMovie("http://192.168.1.100/fileOnLan.swf")

Then fileOnLan.swf has access to stuff on its localhost.  That works.

However, (and it's probably just something easy I'm overlooking) but it seems that I then can't get access to public internet feeds (despite them having crossdomain.xml files setup).  It's as if after I do the above trick that Flash defaults to the local-playback rules...  Still working on it though.

Re: local network access

Duane wrote:

What we might do is implement a local proxy service as I showed above, and give some sort of configuration setting in the Control Panel to allow folks to turn the feature on after warning them about the security implications. The nice thing about this solution is that it doesn't require modifications to the service or running another server to provide the proxy.

That sounds like a really good solution.  I think that there is a lot of potential for really useful widgets that access machines on the local network, so it would definitely be nice for users to be able toggle local network accessibility in the control panel.

I've made pretty good progress on the uTorrent widget. Flash isn't exactly an ideal development platform, but it is working better than I expected.

Re: local network access

I'd appreciate some help on this app that, I swear, only works intermittently.  It works from my browser when on the virtual chumby... it works from Flash 7 stand alone player:

--it does a loadMovie( local IP for file on local server:specialport/filename.swf)
That file loads and works as expected

In that file, it goes up to amazon and grabs data. 

The main file and sub file have the allowDomain stuff working right as it works in the browser and I don't get any security warnings when doing a test-movie. 

The mind boggling thing is that it sometimes works, but only for a little while. 

I think it might be a RAM issue.  The stand along player eats up 20 megs but doesn't exceed that.

Any other ideas?

Thanks,
Phillip

Re: local network access

It's probably memory - the player shouldn't get up to 20MB, since we only have 32MB of RAM, and we obviously need some for the operating system and other processes.

What will typically happen as the system runs out of memory is that some of the other processes get killed, and eventually the system grinds to a halt.

What is it that you're doing that uses that much memory?  We typically don't see that amount of memory being used unless the player is being asked to load very large images, or there's some sort of memory leak as a result of some unfortunate Actionscript.

Re: local network access

Yeah, it looks like ram... it seems to still grind to a halt when I use 75x75 images but it works for a little while--say:
http://ec2.images-amazon.com/images/P/B … MBZZZ_.jpg

but it totally doesn't work with 300x300 images:
http://ec2.images-amazon.com/images/P/B … ZZZZZ_.jpg


I was also using the native XPath libraries which could totally the the cause.  I'll test it without those libraries.

Re: local network access

If the issue is that it's not loading some JPEGs, one other possibility is that some of these images are progressive.

FlashLite 2.x, as you know, is based on Flash 7, which does not support progressive JPEGs.  Flash 8 was the first version of the player that supported them.

Re: local network access

Good theory on the progressive JPGs... but that's not it.  It's more intermittant than just some jpgs not working.

I think it's RAM.  Do you have a sense for how much ram is available for the apps?

Re: local network access

The FlashLite Player is configured to allocate 8MB total to the Flash movie, which would be the Control Panel plus whatever widget is currently running.  Because of the particular way the player was implemented on chumby, it's actually somewhat more than that.

Normally, with the widgets we currently offer, the player runs at between 3MB and 8MB depending upon the widget.   For you to have it running at 20MB is an indication that something's probably wrong.

What I suggest you do is run your widget directly from a USB dongle and monitor the memory usage with another ssh session running 'top'.  If you find that it's increasing, then you'll want to look for leaks.  The most common leaks are XML objects allocated within functions and assigned to a local variable (ie 'var x = new XML()'), or the loading of images into movieclips without removing older clips.

Re: local network access

I can't figure out even how to format a usb as VFAT...

I made a super slim version of this app, and while it works for a few hits, it ultimately stops working... I don't think there's any leak (in my app anyway)... see the whole code:

stop()

a_btn.onPress=function(){
    holder_mc.unloadMovie()
    holder_mc.loadMovie("http://ec2.images-amazon.com/images/P/B0000024JN.01._SCLZZZZZZZ_.jpg")
}
b_btn.onPress=function(){
    holder_mc.unloadMovie()
    holder_mc.loadMovie("http://ec2.images-amazon.com/images/P/B000002UUN.01._SCLZZZZZZZ_.jpg")
}
c_btn.onPress=function(){
    holder_mc.unloadMovie()
    holder_mc.loadMovie("http://ec2.images-amazon.com/images/P/B000002TP7.01._SCLZZZZZZZ_.jpg")
}

Re: local network access

OK, I've noticed sometimes that FlashLite doesn't like to have images loaded into the same clip.  Our widgets typically use createEmptyMovieClip() or attachMovie() to create a new container for each image we want to load:

a_btn.onPress=function(){
    holder_mc.removeMovieClip();
    attachMovie('holder','holder_mc',1);
    holder_mc.loadMovie("http://ec2.images-amazon.com/images/P/B0000024JN.01._SCLZZZZZZZ_.jpg")
}

or:

a_btn.onPress=function(){
    holder_mc.removeMovieClip();
    createEmptyMovieClip('holder_mc',1);
    holder_mc.loadMovie("http://ec2.images-amazon.com/images/P/B0000024JN.01._SCLZZZZZZZ_.jpg")
}

Re: local network access

thanks... I can tell this is going to be fun.

Do you know how caching is handled?

Thanks.

Re: local network access

The current player does not cache fetches.

We have a prototype player in house that caches but it's not ready for release - it uses the HTTP "Cache-Control" header to determine how content should be cached, subject to memory constraints.

Re: local network access

The FlashLite documentation explains that for any form of getURL (loadMovie or whatever) you can do only one per frame.
Also you need to wait until the content is loaded.

I have some pretty ugly code for FlashLite 1.x (Flash 4 syntax) that uses button clicks to trigger a load event (just set a variable asking to load something) and do all the loads in a single frame (you can probably do it on an "onEnterFrame" function).

I'll try to post it later tonight.