Marcus Estes's blog

  • Meet Donor Rally, A Drupal Distro for Social Fundraising

    Aug 17, 2010

    Today OpenSourcery announces the release of Donor Rally, an open source Drupal distribution that nonprofit organizations can use to raise money on the web. This is a developer release, and Drupal geeks can begin the tire-kicking process by downloading the project's source code on GitHub now.

    This project has allowed OpenSourcery another chance to follow through on one of our central goals as a company: to share open source software developed for one nonprofit organization with the rest of the nonprofit community. Today, on the day of Donor Rally's birth as a public open source project, I'd like to take a moment a moment to relate the story about how it came to be.

    In early 2009 we were contacted by the San Francisco Food Bank to discuss the possibility of attempting something truly radical: using Drupal to move a mission-critical fundraising campaign completely to the web.

    The Food From the Bar campaign website was launched in February of 2010. It allowed the San Francisco Food Bank to utilize their social networks, both physical and virtual, to spread the word about their mission. And by June of this year, it had collected over $300,000.00 in web-based donations.

    OpenSourcery licenses all of our client projects under the terms of the GPL, and it wasn't long before we started contemplating how this software could be used to benefit other organizations. Then a personal connection at one of our favorite organizations, 826 Seattle, gave us our first chance to spread the Donor Rally love. (Huge thanks to Sarah B., who was instrumental in this leg of the project.) 826 Seattle is a division of a parent organization co-founded by Dave Eggers to give underprivileged youths access to creative writing programs of the sort that had been previously reserved for only the most privileged private academies.

    826 Seattle was planning an ambitious, grassroots fundraising campaign called Dance Your Cash Off that invited participants to raise money for the organization on the condition that they would enter a dance marathon hosted by 826. This proved to be a perfect opportunity to re-tool the codebase originally developed for the San Francisco Food Bank to help 826 Seattle bring their efforts to the social web. Because we developed the original codebase using Features, abstracting out functionality unique to the food bank (such as food donation) was a nearly trivial task. After less than 20 hours of labor, we launched DanceYourCashOff.org.

    Staff members and fans of 826 Seattle were then able to use the website to raise $17,000, more than 70% of their original fundraising goal. And thanks to Drupal's administration capabilities, they spent only a few hours of staff time to co-ordinate the entire campaign.

    Since then, employees of OpenSourcery have spent every Thursday afternoon sitting around a table out in the sun over a company-subsidized pitcher (or 2) of beer, working together to improve the Donor Rally codebase. Which brings us to today's developer release. Donor Rally has now been packaged into a free, general-purpose application to help any nonprofit organize a social fundraising campaign of their own. The theme is a subtheme of Zen, and hasn't yet been given a polish coat. But this should be a good starting place for a developer to use to help out his or her favorite nonprofit. To learn more, visit the Donor Rally project page on OpenSourcery.

  • Taking the Gloves Off XMLHttpRequest

    Aug 03, 2009

    Pow!Remember how the rapid enlightment around the potential of AJAX changed the web, and how swiftly it did so? It was 2004 / 2005, and though XMLHttpRequest had been viable for long before that, it took an advanced implementation of it by a few high profile web apps (notably, Gmail), combined with a meme-friendly naming, followed by swift support by the W3C and the major browsers to set web developers worldwide to work on rebuilding the web to deliver a decidedly more dynamic and desktop-software-like experience.

    AJAX has always been hampered by an important restriction: due to the same-orgin policy implemented by the browsers (to prevent cross-site scripting attacks), XMLHttpRequest can only issue requests to resources on the same domain that it orginates from.

    But oh what a world it would be if apps were empowered to make http requests to whichever domain they pleased. Recently, thanks to a new W3C standard and some ingenious hacks, the prospect of cross-orgin resource sharing (CORS) is becoming a reality.

    Please Share

    Please share... Rather than let the threat of XSS attacks prevent us all from enjoying the benefits of cross-site resource sharing, the wise owls at the W3C recently published a recomendation that would allow site publishers to opt-in to cross site requests. And the wise, oh let's say foxes, at the Mozilla foundation incorporated it whole-hog into Firefox 3.5. It's also in Safari 4, Chrome 2, and it may even see some traction in IE 8, though to no one's surprise Microsoft has their own idea about how to implement the standard.

    That's not everybody. But someday soon, it may be close enough.

    How it Works

    CORS capability is established in the http headers. When the browser makes an http request, a compliant browser now includes an "Origin" header that tells the remote site where the request orginated from.

    I'm going to use an example from the Mozilla docs to demonstrate. Here's the request in JS:

     

    var invocation = new XMLHttpRequest();
    var url = 'http://bar.other/resources/public-data/';
         
         function callOtherDomain(){
            if(invocation)
            {
                invocation.open('GET', url, true);
                invocation.onreadystatechange = handler;
                invocation.send();
            }

    Let's look at the headers and see how a nice server should respond:

    GET /resources/public-data/ HTTP/1.1
    Host: bar.other
    User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 300
    Connection: keep-alive
    Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
    Origin: http://foo.example
    
    
    HTTP/1.1 200 OK
    Date: Mon, 01 Dec 2008 00:23:53 GMT
    Server: Apache/2.0.61 
    Access-Control-Allow-Origin: *
    Keep-Alive: timeout=2, max=100
    Connection: Keep-Alive
    Transfer-Encoding: chunked
    Content-Type: application/xml
    
    [XML Data]

    The first chunk before the linebreak is what Firefox sends the server. Notice the origin value. The header reponse from the server follows. And the magic is in the "Access-Control-Allow-Origin: *" bit. Access-Control-Allow-Origin is the server part of the handshake demanded by the new standard. The wildcard value here allows access from any domain, but it's easy to restrict to a whitelist of trusted domains.

    This method will allow for GET or POST methods with content types of application/x-www-form-urlencoded, multipart/form-data, and text/plain. For other requests or more nuanced relationships to the server, the standard gets more complex. (See Pre-flighted requests and Requests with credentials.)

    CORS for the Rest of Them

    Portland local Jesse Hallett revently spoke to a Javascript user group about these recent developments in cross orgin resource sharing and to address the prospect of trying to pragmatically implement XHR now, he introduced flXHR, a client-side proxy implemented in Flash (from a vendor that's historically proven to be a little too adventurous about this CORS business for their own good).

    flXHR works by redirecting Http requests through an invisible flash movie, which makes the cross site request under the more permissive aucpices of the flash environment, and then sends the response back to the Javascript client.

    But if that sounds a little hairy, and if you only need to make GET requests, look into JSONp or CSSHttpRequest.

    So, the gloves are off. Now what are you going to swing at?