<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='./OpenSocial.xslt' ?>
<?rfc toc="yes"?>
<!DOCTYPE rfc PUBLIC "-//IETF//DTD RFC 2629//EN" "http://xml.resource.org/authoring/rfc2629.dtd">
<rfc ipr="full3978"
     docName="opensocial-wap-extension-specification"
     xmlns:x="http://purl.org/net/xml2rfc/ext">
  <front>
    <title abbrev="WAP-Extension">OpenSocial WAP Extension Specification</title>
    <author fullname='OpenSocial and Gadgets Specification Group'>
   <address>
    <email>opensocial-and-gadgets-spec@googlegroups.com</email>
   </address>
  </author>
    <date month="November"
          year="2010" />
    <area>Mobile</area>
    <keyword>OpenSocial</keyword>
    <keyword>social networking</keyword>
    <keyword>REST</keyword>
    <keyword>XML</keyword>
    <keyword>Extensible Markup Language</keyword>
    <keyword>JSON</keyword>
    <keyword>JavaScript Object Notation</keyword>
    <keyword>Atom</keyword>
  </front>
  <middle>
    <section title="Notation and Conventions">
      <t>Keywords such as, "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
        "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" used in this
        document are to be interpreted as described in
        <xref target="RFC2119">RFC2119</xref>.</t>
      <t>Domain name examples use <xref target="RFC2606">RFC2606</xref>.</t>
    </section>
    <section title="Overview">
      <t>OpenSocial Containers have a standard design that provides JavaScript APIs for enabling rich web applications within a Web browser via an IFrame sandbox. This works well for the typical use case, since most modern web browswers have support JavaScript as well as IFrames. However, when running applications on WAP enabled devices, JavaScript &amp; IFrames are not always available. As it stands today, OpenSocial Gadgets cannot run on most WAP devices.</t>
   		Many people access the Internet via mobile devices. There are even countries where Internet access is more available on mobile devices than PCs.
      <t>The OpenSocial WAP Extension is defines how to support mobile devices which do not support JavaScript or IFrames. An application Requiring this extension uses OpenSocial RESTful APIs to retrieve OpenSocial Data, such as Social Data from a Social Networking Site (SNS.) This document describes an architecture and common features required to enable an OpenSocial WAP Server via this OpenSocial WAP Extension. An implementation wishing to support WAP devices SHOULD support features described in this document.</t>
    </section>
    <section title="Compliance">
      <t>To be considered an OpenSocial WAP Container, a site must fulfill all the requirements for a Social API Server and those specified in this document.</t>
      <section title="Process flow">
        <t>The process flow is visualed in a diagram to better understand the interaction.</t>
        <figure>
            <preamble>Process flow:</preamble>
            <artwork xml:space="preserve">
[cell-phone]   [OpenSocial Container]   [external server]
      |                   | Retrieve Start URL -&gt; |
      | Accept Request -&gt; |                       |
      |                   |   Forward Request -&gt;  |
      |                   |  &lt;- Receive Response  |
      | &lt;- Response Page  |                       |
            </artwork>
          </figure>
      </section>
      <section title="Retrieve Start URL Request">
        <t>An OpenSocial Container MUST be able to fetch a gadget spec XML, and MUST be able to retrieve a Start URL written included in the ModulePrefs.</t>
        <t>A Gadget spec XML SHOULD be retrieved from the URL provided to the Container by the developer. OpenSocial Containers MUST parse the retrieved gadget file, and MUST get the Start URL written in the file. This Start URL is the destination of the first request sent when users launch an application.</t>
	<t>A view for WAP-enabled devices MUST have content type "wap." This is defined in the Gadget spec XML as a Content element which has an attribute "type" &amp; value "wap." The Start URL is the value of the href attribute in the same Content element.</t>
      </section>
      <section title="Accept Request">
        <t>OpenSocial Containers MUST be able to accept requests from the cell-phone, and MUST be able to verify the content and also add necessary information.</t>
        <t>All requests from an application running on a mobile device SHOULD be processed by the OpenSocial Container. The content of the request accepted by the Container SHOULD be verified, and the OpenSocial Container SHOULD remove unnecessary information from the request.</t>
		<t>Requested information about the user MUST conform to section 2.5 of the Social Data specification. The application's unique identifier MUST be added to the request by the OpenSocial Container. There are cases that some information should not be relayed to the application, such a personally-identifable information. In this case, the OpenSocial Container SHOULD remove such information from the request. The OpenSocial Container MAY add additional information about the user to the request so it may leverage their social data.</t>
	</section>
      <section title="Forward Request">
        <t>OpenSocial Containers MUST be able to forward verified requests to an external server.</t>
        <t>If a request includes a URL parameter, the OpenSocial Container will forward the request to the server specified in the URL parameter. If the request does not include a URL parameter, the OpenSocial Container will default the request to the Start URL. At this point, user information and the application identifiers added from the previous phase are sent to the server. To validate the request, the OpenSocial Container SHOULD have a signature in the request.</t>
      </section>
      <section title="Receive Response">
        <t>An OpenSocial Container MUST be able to receive a response including content generated on a developer's external server.</t>
        <t>The received contents will be validated and transformed by the OpenSocial Container. For example, the OpenSocial Container MAY add a header and footer to the content. In addition, the OpenSocial Container MAY replace the URL written in the contents, such as an image, and MAY remove invalid codes (JavaScript code and etc). Furthermore, in order to allow usage of functions with a user flow specific codes SHOULD be replaced by the OpenSocial Container during this phase.</t>
        <t>If an external server has a slow response time, an OpenSocial Container MAY enforce a request timeout. If a response is not received within a reasonable amount of time, the OpenSocial Container will display an error page to the user.</t>
      </section>
      <section title="Response Page">
        <t>The OpenSocial Container MUST send the staic page to the user's mobile device.</t>
        <t>The page which was rendered during the previous phase is then sent from the OpenSocial Container to the user's mobile device. The user may create an action on the page. As a result of this action, a new request is then sent to the OpenSocial Container.</t>
      </section>
    </section>
    <section title="Gadget Spec XML">
      <t>This section describes the Gadget Spec XML of applications for mobile devices.</t>
      <section title="View for cell-phone">
        <t>A view type is defined for applications that render on a mobile device. The view type is called "wap". This view is defined using a Content element in the Gadget spec XML, just like a Gadget view for a typical browser.</t>
        <t>The "wap" is specified as the attribute value of the Content element type. And, the Start URL is specified as the "href" attribute value. The Content element may not contain a body, since the server specified by the Start URL will generate the contents.</t>
        <t>Since the WAP extension is optional, application developers MUST declare the "wap" feature using a "Require" element. If the "wap" feature is not declared, its gadget will not render properly on WAP-enabled devices using the "wap" view type.</t>
      </section>
      <section title="Example">
        <t>
          <figure>
            <artwork xml:space="preserve">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;Module&gt;
  &lt;ModulePrefs title="App for Cell-phone"&gt;
    &lt;Require feature="wap" /&gt;
  &lt;/ModulePrefs&gt;
  &lt;Content view="any" type="wap" href="http://start.url/" /&gt;
&lt;/Module&gt;
            </artwork>
          </figure>
        </t>
      </section>
      <section title="Coexistence">
        <t>The view for cell-phones can co-exist with other views. At the same time, multiple Content elements holding other view attributes can be written in the Gadget spec XML.</t>
        <t>
          <figure>
            <preamble>The following code is an example having two Content elements:</preamble>
            <artwork xml:space="preserve">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;Module&gt;
  &lt;ModulePrefs title="App for Cell-phone"&gt;
    &lt;Require feature="wap" /&gt;
  &lt;/ModulePrefs&gt;
  &lt;Content view="mobile" type="wap" href="http://start.url/" /&gt;
  &lt;Content view="canvas" type="html"&gt;&lt;[CDATA[
    &lt;div&gt;Hello, world!&lt;/div&gt;
  ]]&gt;&lt;/Content&gt;
&lt;/Module&gt;
            </artwork>
          </figure>
        </t>
      </section>
      <section title="Data Pipelining and Proxied Content">
        <t>This wap extension supports Data Pipelining and Proxied Context. For instance, the content element which has the "wap" type can Data Pipelining tags to provide the Viewer, Owner and Friend information to an external server. For example:</t>
        <figure>
            <artwork xml:space="preserve">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;Module&gt;
  &lt;ModulePrefs title="App for Cell-phone"&gt;
    &lt;Require feature="wap" /&gt;
    ...
  &lt;/ModulePrefs&gt;
  &lt;Content view="any" type="wap" href="http://start.url/"&gt;
    &lt;os:PeopleRequest key="vf" userid="@viewer" groupid="@friends" /&gt;
  &lt;/Content&gt;
&lt;/Module&gt;
            </artwork>
        </figure>
        <t>The results of the data pipelining requests will be sent to the URL specified in the href of the &lt;Content&gt; section as POSTed JSON data. This information can be used by an external server to render Social Data.</t>
      </section>
    </section>
    <section title="Request and Response">
      <t>This section describes the request sent from an OpenSocial Container and the expected response.</t>
      <section title="Request">
        <t>The content of the request and the conditions to determine which target server to send requests by the OpenSocial Container are described here.</t>
        <section title="Forwarding target">
          <t>When the OpenSocial Container receives a request from mobile device, the forwarding target URL will differ depending on certain conditions. The conditions are described in the following:</t>
          <texttable align="left">
            <ttcol>Request URL example</ttcol>
            <ttcol>Include url parameter?</ttcol>
            <ttcol>Forwarding target</ttcol>
            <c>http://application.container/app_id</c>
            <c>No</c>
            <c>Start URL written on Gadget Spec XML.</c>
            <c>http://application.container/gadgets/ifr?url=http%3A%2F%2Fexternal.server%2gadget.xml&amp;st=abcdefg&amp;...</c>
            <c>No</c>
            <c>Start URL written on Gadget Spec XML specified by the url parameter included in the query parameters.</c>
            <c>http://application.container/app_id?url=http%3A%2F%2Fexternal.server%2Fpath1%2Fpath2</c>
            <c>Yes</c>
            <c>http://external.server/path1/path2</c>
          </texttable>
        </section>
        <section title="Request patameters">
          <t>The request sent from the mobile device will be forwarded to a developer's external server (Forward Request). The OpenSocial Container will add several parameters to the request while forwarding. Typically the parameters will include Social Data.</t>
          <t>The parameters typically added are the following:</t>
          <texttable align="left">
            <ttcol>Name</ttcol>
            <ttcol>Type</ttcol>
            <ttcol>Description</ttcol>
            <ttcol>Required</ttcol>
            <c>opensocial_owner_id</c>
            <c>Query parameter</c>
            <c>The ID of the user who owns the application accessed by the viewer.</c>
            <c>Yes</c>
            <c>opensocial_app_id</c>
            <c>Query parameter</c>
            <c>The ID of the application which the user is currently using.</c>
            <c>Yes</c>
            <c>opensocial_viewer_id</c>
            <c>Query parameter</c>
            <c>The ID of the user who is currently accessing to the application.</c>
            <c>Optional</c>
            <c>User-Agent</c>
            <c>Request Header</c>
            <c>The identifier to specify the device of the user.</c>
            <c>Yes</c>
            <c>X-Forwarded-For</c>
            <c>Request Header</c>
            <c>The IP address of the access origin.</c>
            <c>Optional</c>
          </texttable>
          <t>The application developer can generate the appropriate content for the device by referencing the User-Agent request header.</t>
          <t>In addition, the OpenSocial Container MAY remove parameters included in the request sent to the mobile device, such as persoanlly-identifiable information. Such information SHOULD be removed by the OpenSocial Container to protect the user's privacy.</t>
          <t>If Data pipelining is used in the Content element, social data will be sent with the above parameters as JSON in POST body.</t>
        </section>
      </section>
      <section title="Response">
        <t>The OpenSocial Container expects to receive XHTML content responses. The format must be parseable by the OpenSocial Container. If the OpenSocial Container cannot parse the contents in XHTML format, the OpenSocial Container will return an error to the external server which generated the contents.</t>
        <t>The user's profile information retrieved from an OpenSocial RESTful API will be included in the contents of the external server. Also, the contents may change accordingly to the User-Agent parameter included in the request.</t>
        <t>Parts of the contents will be replaced by the OpenSocial Container. The purpose is to support User Flow functions and to replace the url parameter.</t>
        <section title="Replacing URLs">
          <t>To ensure that the request from the mobile device always honored by the OpenSocial Container, the OpenSocial Container MUST replace URLs written in the content generated by the external server. Suchs URL include links for navigating around pages (i.e. a tag and form tag.)</t>
          <t>Application developers can write the specific URL they wish to retrieve on the external server as the value of the href or action attribute. For example, the URL is replaced similar to the following.</t>
          <t>Before:</t>
          <figure>
            <artwork xml:space="preserve">
&lt;a href="http://external.server/path1/path2"&gt;Click!&lt;/a&gt;

&lt;form action="http://external.server/path1/path2"&gt;
  ...
&lt;/form&gt;
            </artwork>
          </figure>
          <t>After:</t>
          <figure>
            <artwork xml:space="preserve">
&lt;a href="http://application.container/app_id/?url=http%3A%2F%2Fexternal.server%2Fpath1%2Fpath2"&gt;Click!&lt;/a&gt;

&lt;form action="http://application.container/app_id/?url=http%3A%2F%2Fexternal.server%2Fpath1%2Fpath2"&gt;
  ...
&lt;/form&gt;
            </artwork>
          </figure>
        </section>
        <section title="User Flow functions">
          <t>With user flow functions, the specific URL schema written by the application developer will be replaced automatically to the complete URL by the OpenSocial Container. The purpose is to navigate the user to the page prepared by the OpenSocial Container. For example, when using the function to invite friends to an application, the URI schema will be replaced like the following.</t>
          <t>Before:</t>
          <figure>
            <artwork xml:space="preserve">
&lt;a href="invite:friend?callback=http%3A%2F%2Fexternal.server%2Fpath1%2Fpath2"&gt;Invite!&lt;/a&gt;
            </artwork>
          </figure>
          <t>After:</t>
          <figure>
            <artwork xml:space="preserve">
&lt;a href="http://application.container/invite/friend?callback=http%3A%2F%2Fexternal.server%2Fpath1%2Fpath2"&gt;Invite!&lt;/a&gt;
            </artwork>
          </figure>
        </section>
      </section>
    </section>
    <section title="Validation">
      <t>The OpenSocial Container will send a request to generate the contents to an external server. The external server must validate whether the sender of the request is the actual OpenSocial Container.</t>
      <t>Several methods to check the validness of the request exist. The most common method is to validate the request is using a signature. The external server can validate the request by checking the signature added by the OpenSocial Container. HMAC-SHA1, RSA-SHA1 etc, can be applied as methods for generating a signature.</t>
      <t>An example on how to generate a signature with HMAC-SHA1 is introduced in the section, [Generating the signature with OAuth].</t>
    </section>
    <section title="User Flow functions">
      <t>The OpenSocial Container can pages which are pre-built by the OpenSocial Container. For example, if users want to invite friends to an application, the OpenSocial Container will navigate users to a page to select who to invite. After users finish selecting their friends, the OpenSocial Container will bring them back to the application's page. Such function is called 'User Flow functions'.</t>
      <t>Commonly used User Flow functions have been standardized in this specification. In addition, the OpenSocial Container can define a container-specific User Flow function. The URI schema is defined for each User Flow function to navigate users to an already parepared page. The OpenSocial Container MUST replace the URI schema to the page's URL.</t>
      <section title="Format">
        <t>The application developer MUST use the User Flow function under the following format:</t>
        <figure>
          <artwork xml:space="preserve">
[URI-schema]?[parameter1=value1]&amp;[parameter2=value2]&amp;...
          </artwork>
        </figure>
        <t>The following format can also be used when using a form tag of HTML:</t>
        <figure>
          <artwork xml:space="preserve">
&lt;form action="[URI-schema]"&gt;
  &lt;input type="hidden" name="[parameter1]" value="[value1]" /&gt;
  &lt;input type="hidden" name="[parameter2]" value="[value2]" /&gt;
  ...
&lt;/form&gt;
          </artwork>
        </figure>
      </section>
      <section title="Required parameters">
        <t>The required parameters for all User Flow functions are the following:</t>
        <texttable align="left">
          <ttcol>Name</ttcol>
          <ttcol>Description</ttcol>
          <c>callback</c>
          <c>The URL of the redirecting target to go back after completing the User Flow function. This URL MUST be URI-escaped.</c>
        </texttable>
	<t>If the OpenSocial Container wants to return the result of the process to the application, the result value is added as the query parameter to the URL specified by the callback parameter.</t>
      </section>
      <section title="Standard functions">
	<t>This section decribes commonly supported User Flow functions.</t>
	<section title="Invitation">
	  <t>URI schema: invite:friends</t>
	  <t>Description: The OpenSocial Container navigates users to the page where they can select friends they want to invite to the application.</t>
	  <t>Parameters:</t>
	  <texttable align="left">
	    <ttcol>Name</ttcol>
	    <ttcol>Type</ttcol>
	    <ttcol>Description</ttcol>
	    <c>callback</c>
	    <c>String</c>
	    <c>The target URL to return the user to the application after selecting friends by the user.</c>
	  </texttable>
	  <t>Result values:</t>
	  <texttable align="left">
	    <ttcol>Name</ttcol>
	    <ttcol>Type</ttcol>
	    <ttcol>Description</ttcol>
	    <c>invite_member</c>
	    <c>User IDs separated by commna.</c>
	    <c>The user's IDs which the user selected to invite.</c>
	  </texttable>
	  <t>Example:</t>
	  <figure>
	    <artwork xml:space="preserve">
Request:
  &lt;a href="invite:friends?callback=http%3A%2F%2Fexternal.server%2Fpath1%2Fpath2"&gt;Invite!&lt;/a&gt;

Redirecting target URL:
  http://external.server/path1/path2?invite_member=123,456,789
	    </artwork>
	  </figure>
	</section>
      </section>
    </section>
  </middle>
  <back>
    <references>
      <reference anchor="RFC2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author initials="S."
                  surname="Bradner"
                  fullname="Scott Bradner">
            <organization abbrev="HarvardU">Harvard University</organization>
          </author>
          <date month="March"
                year="1997" />
        </front>
        <seriesInfo name="RFC"
                    value="2119" />
      </reference>
      <reference anchor="RFC2606">
        <front>
          <title>Reserved Top Level DNS Names</title>
          <author initials="D."
                  surname="Eastlake"
                  fullname="Donald E. Eastlake 3rd">
            <organization abbrev="IBM">IBM</organization>
          </author>
          <author initials="A."
                  surname="Panitz"
                  fullname="Aliza R. Panitz" />
          <date month="June"
                year="1999" />
        </front>
        <seriesInfo name="RFC"
                    value="2606" />
      </reference>
      <reference anchor="OAuth-Consumer-Request"
                 target="http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/2/spec.html">
        <front>
          <title>Using OAuth for Consumer Request</title>
          <date month="September"
                year="2008" />
        </front>
      </reference>
    </references>
  </back>
</rfc>
