DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 15.6 Loading Remote Content by Proxy

15.6.1 Problem

You want to load content into your Flash movie from another domain and are prevented from doing so by Flash's security sandbox.

15.6.2 Solution

Use a proxy script on the server to overcome the domain restrictions.

15.6.3 Discussion

Flash's security sandbox prevents you from loading content into your Flash movies from other domains indiscriminately. You can load .swf files, JPEGs, and MP3s from the same domain (or subdomain), and you can also load .swf files from a trusting domain. However, if you need to load content that is not in the same domain, and it is not a trusted .swf file, you have at least three options:

  • Copy the content to the same domain. This is the simplest solution if it is possible for you to implement.

  • Create a DNS entry within your own domain such that the remote server is mapped to a machine name within the same domain. For example, you can create a DNS entry such that www.remotedomain.com maps to remotedomain.localdomain.com within your own domain. This solution requires that you have administrator access and DNS knowledge.

  • Create and use a proxy script that downloads the remote content to the local server (either in memory or to disk) on the fly and then returns the local copy to the Flash movie.

Included in this recipe are instructions for creating proxy scripts for ColdFusion, Perl, .NET, and PHP.

If you use ColdFusion, you can write a proxy script with just a few lines of code. Be aware that for this to work, the <cfcontent> tag must be enabled on the server. Some web hosts disable this tag for security purposes. To create a ColdFusion proxy script, complete the following steps:

  1. Create a new CFML document named getMyContent.cfm.

  2. Add the following code to the document:

    <!--- Make sure the code is single-threaded so that the requested content 
          from one client doesn't get sent to another by mistake. --->
    <cflock timeout="10" type="exclusive">
    
      <!--- Get the remote content and save it to the server --->
      <cfhttp url="#URL.url#" method="get" path="#ExpandPath("./")#"></cfhttp>
      
      <!--- Display the content that has been saved. Delete the file afterward. --->
      <cfcontent file="#ExpandPath(GetFileFromPath(Url.url))#" deletefile="yes" 
    type="#cfhttp.mimetype#">
    </cflock>
  3. Save the document and upload it to your server.

  4. Refer to the testing instructions at the end of this recipe, following the alternative language implementations.

If Perl is your choice for server-side scripting, you can create a proxy script by completing the following steps:

  1. Create a new Perl script document named getMyContent.cgi.

  2. Add the following code to the document:

    #!/usr/bin/perl
    
    # Proxy for Flash to bypass sandbox security limitations
    # Supports GET and POST CGI methods
    # Arun Bhalla (bhalla@arun.groogroo.com) 2002.07.15
    
    use CGI qw/-oldstyle_urls/;
    use HTTP::Request::Common;
    use LWP::UserAgent;
    
    my $cgi = new CGI;
    my $ua  = new LWP::UserAgent;
    my $location;
    my $method;
    
    if ($cgi->param(  )) {
        # extract the location (URL) and method values from the parameter list 
        $location = $cgi->param('location');
        $method = $cgi->param('method');
        $cgi->delete('location');
        $cgi->delete('method');
    }
    
    $method = uc($method) || 'GET';
    my $res;
    
    if ($method eq 'GET') {
        if ($location =~ /\?/) {
        $location .= '&' . $cgi->query_string;
        } else {
        $location .= '?' . $cgi->query_string;
        }
          
        $req = HTTP::Request->new(GET => $location);
    } elsif ($method eq 'POST') {
        $req = HTTP::Request->new(POST => $location);
        $req->content_type($cgi->content_type(  ) || 
                   'application/x-www-form-urlencoded');
        $req->content($cgi->query_string);
    }
    
    my $res = $ua->request($req);
    print $res->headers_as_string, "\n", $res->content;(
  3. Save the document and upload it to your server.

  4. Refer to the testing instructions at the end of this recipe, following the alternative language implementations.

If you are using ASP.NET, follow these steps:

  1. Create a new ASPX document named getMyContent.aspx.

  2. Add the following code to the document:

    <%@ Page Language="C#" %>
    <%
    
    // First, get the content from the remote domain.
    System.Net.HttpWebRequest webRequest =
            (System.Net.HttpWebRequest)System.Net.WebRequest.Create(
             (string)Request.QueryString["url"]);
    System.Net.HttpWebResponse webResponse = 
            (System.Net.HttpWebResponse)webRequest.GetResponse(  );
    System.IO.Stream inStream = webResponse.GetResponseStream(  );
    
    // Next, read the content into an array of bytes.
    byte[] buffer = new byte[(int)webResponse.ContentLength];
    inStream.Read(buffer, 0, (int)webResponse.ContentLength);
    
    // Next, set the appropriate content type and write the data as binary output.
    Response.ContentType = webResponse.ContentType;
    Response.BinaryWrite(buffer);
    
    // Finally, close everything that is still open.
    inStream.Close(  );
    webResponse.Close(  );
    %>
  3. Save the document and upload it to your server.

  4. Refer to the testing instructions at the end of this recipe, following the alternative language implementations.

If you are using PHP, follow these steps:

  1. Create a new PHP document named getMyContent.php.

  2. Add the following code to the document:

    <?php
      // Stop Script from Timing Out.        
      set_time_limit(0);
    
      // Check for variable "url" in querystring.
      if ($_GET['url']) {
        $fp = fopen ($_GET['url'], "r");
        $file = "";
        while (!feof($fp)) {
    
          // Read Target File in chunks of 4 KB (4096 bytes).
          $file .= fgets($fp, 4096); 
        }
        fclose($fp);
    
        // Send File Data to Flash
        echo $file;
      }
    ?>
  3. See the following testing instructions.

To test the script in your chosen language, run it from a web browser. Regardless of the language implementation, the script expects a parameter named url that specifies the location of the data to copy to the proxy server.

For example, if the CFML script is being served at http://www.mydomain.com/getMyContent.cfm and the content that you want to retrieve is at http://www.remotedomain.com/sound.mp3, you can test the script in the browser using:

http://www.mydomain.com/getMyContent.cfm?url=http://www.remotedomain.com/sound.mp3

This should retrieve the MP3 and play it in the browser window (if you have the appropriate player).

Similarly, you can test the Perl script in a browser using the following URL syntax:

http://www.mydomain.com/cgi-bin/getMyContent.cgi?url=http://www.remotedomain.com/sound.mp3.

You can test the ASP.NET script in a browser using the following URL syntax:

http://www.mydomain.com/getMyContent.aspx?url=http://www.remotedomain.com/sound.mp3.

You can test the PHP script in a browser using the following URL syntax:

http://www.mydomain.com/getMyContent.php?url=http://www.remotedomain.com/sound.mp3.

Regardless of which language implementation you choose, you use it in the same manner. When you invoke the loadMovie( ) or loadSound( ) method from your Flash movie, instead of passing the URL to the remote asset, pass the URL to the proxy script that is running on the same domain and append the URL of the remote asset as a query string. For example:

myMovieClip.loadMovie("http://localhost/getMyContent.aspx?
url=http://www.remotedomain.com/someSwf.swf");

When you use a proxy script, be aware that the content can take even longer to load into the Player than it would if the content is loaded directly. The reason is that the asset has to first download to the proxy server, then to the Player.

15.6.4 See Also

Recipe 15.2, Recipe 15.4, and Recipe 17.4

    [ Team LiB ] Previous Section Next Section