File:  [mozdev] / books / www / chapters / ch12.html
Revision 1.15: download - view: text, annotated - select for diffs - revision graph
Fri Apr 4 16:27:40 2003 UTC (16 years, 7 months ago) by cdn
Branches: MAIN
CVS tags: HEAD
ahem

    1:     <link rel="prev" href="http://books.mozdev.org/chapters/ch11.html" />
    2:     <link rel="next" href="http://books.mozdev.org/chapters/appa.html" />
    3: 
    4:     <style type="text/css">
    5:       div.c26 {font-weight: bold; text-align: center}
    6:       div.c25 {text-align: center}
    7:     </style>
    8: 
    9:     <h2>Chapter 12</h2>
   10:     <h1><a name="77066"></a> Remote Applications</h1>
   11:     <p>Remote applications developed with Mozilla use an
   12:     application without having to endure a full download process.
   13:     Given the fundamental similarities of Mozilla and standard web
   14:     content, a remote Mozilla application can work much like a
   15:     regular web page. For example, you can point people to your
   16:     project at http://<i><a href=
   17:     "http://www.foobar.com/myApp.xul">www.foobar.com/myApp.xul</a></i>,
   18:     and if they use Mozilla (or a browser that is built with
   19:     Mozilla, such as Netscape 7), the browser window becomes the
   20:     application. Serving an application in this way allows you to
   21:     use most features of a locally installed Mozilla program and
   22:     gives you unique options that aren't otherwise available. These
   23:     options are discussed in this chapter.</p>
   24:     <p>This chapter explores this alternative distribution method
   25:     and compares it to how an installable application is built.
   26:     Generally, there is no difference between these two types of
   27:     applications other than how they are delivered. However, you
   28:     should be aware of the difficulties encountered when using
   29:     remote applications.</p>
   30:     <p>One of the most important aspects of remote applications for
   31:     Mozilla is the XPFE environment, or more specifically, the use
   32:     of XUL/XBL, JavaScript, and CSS. Using the XPFE in remote
   33:     application development offers more possibilities than, for
   34:     example, just embedding Gecko into your application. It is the
   35:     focus of this chapter.</p>
   36:     <h2><a name="77067"></a> Directions in Remote Application
   37:     Development</h2>
   38:     <p>Currently, remote 
   39:     <!--INDEX development:remote applications, overview --> 
   40:     <!--INDEX remote applications:overview --> 
   41:     <!--INDEX applications:remote, development --> Mozilla
   42:     applications are not prevalent because development focuses on
   43:     making the client applications as stable and efficient as
   44:     possible. Therefore, this area of Mozilla development is
   45:     largely speculative. This chapter argues that remote
   46:     applications are worth looking at more closely.</p>
   47:     <p>One advantage a remote Mozilla application has over a client
   48:     application is that a developer doesn't have to worry about an
   49:     installer. Also, all users have access to the latest version of
   50:     your application. Because the application is stored centrally
   51:     on a server instead of on the local computer of everyone who
   52:     tries your program, when you update it, you make an update
   53:     available to all users.</p>
   54:     <p>Remote software applications might be 
   55:     <!--INDEX hosting remote applications --> 
   56:     <!--INDEX networks, hosting remote applications --> hosted in a
   57:     centralized point on the network, on multiple nodes, or on any
   58:     random node in a Peer to Peer (P2P) fashion. It's even possible
   59:     to have a whole suite of remote Mozilla applications hosted on
   60:     several computers combined into one coherent package. <a href=
   61:     "#77002">Figure 12-1</a> shows one scenario for a simple
   62:     distributed Mozilla application.</p>
   63:     <div class="c25">
   64:       <img src="foo.gif">
   65:     </div>
   66:     <p><i>Figure 12-1: <a name="77002"></a></i> <i>Distributed
   67:     remote Mozilla application</i></p>
   68:     <p>Currently, one of the remote application's biggest
   69:     disadvantages is that it has very restricted JavaScript 
   70:     <!--INDEX privileges:remote applications:JavaScript --> 
   71:     <!--INDEX JavaScript:privileges, remote applications -->
   72:     privileges. Here, privileges refer to the ability to carry out
   73:     certain functionalities on the local system. As many
   74:     high-profile "worm" viruses emerge routinely these days,
   75:     security <!--INDEX security:remote applications -->
   76:     restrictions on downloadable scripts and applications are
   77:     understandable. Some of the most high-profile malicious scripts
   78:     access the local file system. This is not a problem unique to
   79:     the Mozilla environment, but it is something to be aware of
   80:     when planning and implementing a remote application.</p>
   81:     <p>To improve security, Mozilla automatically limits what
   82:     JavaScript has access to on your computer when the executed
   83:     scripts come from a computer other than the local one. One
   84:     workaround uses signed scripts, as described in the <a href=
   85:     "#77088">"Creating Signed Remote Applications</a>" section
   86:     later in this chapter. You can also have users set a special
   87:     preference to enable universal XPConnect privileges to both
   88:     local and remote files. To learn how to open up the security
   89:     sandbox in this way, see the section <a href="#77095">"Expanded
   90:     Privileges in Mozilla</a>" later in this chapter.</p>
   91:     <h2><a name="77068"></a> Basic Remote Application Example</h2>
   92:     <p>The <!--INDEX remote applications:XUL example --> 
   93:     <!--INDEX XUL (XML-based User-interface Language):remote application example -->
   94:     simple XUL file in <a href="#77026">Example 12-1</a> uses the
   95:     user's local skin information to create a toolbar-type
   96:     interface for a file that can be loaded from the server. This
   97:     successful effect depends on whether your server is configured
   98:     with the correct Multipart Internet Mail Extension (MIME) type
   99:     (see the later section <a href="#77071">"Server
  100:     Configuration</a>"). The <tt>id</tt> on the buttons are taken
  101:     from the navigator skin, so the look of the remote file changes
  102:     when the user switches themes and remains consistent with the
  103:     look of the browser itself.</p>
  104:     <p><i>Example 12-1: <a name="77026"></a></i> <i>Remote XUL
  105:     example</i></p>
  106: <pre>
  107:  &lt;?xml version="1.0"?&gt;
  108:  &lt;?xml-stylesheet href="chrome://global/skin/" type="text/css"?&gt;
  109:  &lt;?xml-stylesheet href="chrome://navigator/skin/" type="text/css"?&gt;
  110:  &lt;window id="remote_example"
  111:      xmlns="<a href=
  112: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
  113:      title="Simple Remote Example"&gt;
  114:    &lt;hbox&gt;
  115:      &lt;button label="XFlies" class="button-toolbar" id="page-proxy-button"&lt;/td&gt;/&gt;
  116:      &lt;button label="Reptiles" class="button-toolbar" /&gt;
  117:      &lt;button label="Bugs" class="button-toolbar" /&gt;
  118:    &lt;/hbox&gt;
  119:  &lt;/window&gt;
  120: </pre>
  121:     <p>As you can see in <a href="#77026">Example 12-1</a>, the
  122:     markup of a remote XUL file is like that of a XUL file that is
  123:     part of a local system's installed application. <a href=
  124:     "#77004">Figure 12-2</a> shows the XUL file presented using
  125:     both Classic and Modern themes.</p>
  126:     <div class="c25">
  127:       <img src="foo.gif">
  128:     </div>
  129:     <p><i>Figure 12-2: <a name="77004"></a></i> <i>Remote XUL
  130:     file-accessing skin</i></p>
  131:     <p>The XUL in <a href="#77026">Example 12-1</a> is minimal, but
  132:     it does show that the <i>chrome://</i> URLs are accessible to
  133:     the remote file and that the CSS and image resources available
  134:     in the chrome's skin subdirectories can be accessed remotely.
  135:     The image on the first button is picked up from a local JAR
  136:     file, as accessed through chrome by using the button's
  137:     <tt>page-proxy-button id</tt>. A more elegant application would
  138:     use toolbars, menus, and other widgets to create a
  139:     full-featured application UI.</p>
  140:     <h3><a name="77069"></a> Case Study: Snake (a.k.a.
  141:     Hiss-zilla)</h3>
  142:     <p>In this 
  143:     <!--INDEX remote applications:case studies, gaming --> 
  144:     <!--INDEX games:remote applications, case studies --> section,
  145:     we look at an application that is stripped down and based on a
  146:     basic concept but still useful. This application shows the
  147:     potential of remote application development. This case study
  148:     discusses a full-featured game that is played over the
  149:     Internet. <a href="#77006">Figure 12-3</a> below shows a sample
  150:     screenshot of Hiss-zilla.</p>
  151:     <div class="c25">
  152:       <img src="foo.gif">
  153:     </div>
  154:     <p><i>Figure 12-3: <a name="77006"></a></i> <i>Hiss-zilla, a
  155:     remote game</i></p>
  156:     <p>A direct link to a remote XUL file provides access to the
  157:     game, as seen in the location bar of the browser in <a href=
  158:     "#77006">Figure 12-3</a>. The game's rules are straightforward.
  159:     Click on the New Game button or use N on the keyboard to begin,
  160:     use arrow keys to change direction, and use the character P to
  161:     pause the game. To play a game of Hiss-zilla or to take a
  162:     closer look at the code, see the project page <i><a href=
  163:     "http://games.mozdev.org/action/snake/">http://games.mozdev.org/action/snake/</a></i>.</p>
  164:     <p>The complete package includes all files associated with an
  165:     XPFE application, including a XUL file, a stylesheet, images,
  166:     and JavaScript files. The files and their descriptions are as
  167:     follows:</p>
  168:     <dl>
  169:       <dt>snake.xul</dt>
  170:       <dd>Contains the window definition and the top level of the
  171:       application with the game grid, visual text, and application
  172:       buttons.</dd>
  173:       <dt>snake.js</dt>
  174:       <dd>Contains the functionality for the game including the
  175:       snake's movement and the eating of the food.</dd>
  176:       <dt>snake.css</dt>
  177:       <dd>Contains styling for the UI features and inclusion of
  178:       some images.</dd>
  179:       <dt>screen.js</dt>
  180:       <dd>Enables full screen mode in the game.</dd>
  181:       <dt>Image files</dt>
  182:       <dd>Miscellaneous images that represent parts of the snake's
  183:       body as it moves in different directions and the food that it
  184:       eats.</dd>
  185:     </dl>
  186:     <p>The Snake application will be developed further later in the
  187:     chapter in the context of signed scripts. You will see new
  188:     features that allow you to run the game in full-screen mode and
  189:     to store the scores. These features illustrate different
  190:     concepts relevant to remote applications.</p>
  191:     <blockquote>
  192:       <hr>
  193:       <b>Mozilla Gaming</b> 
  194:       <p>Hiss-zilla is not the only example of a game created with
  195:       Mozilla. Others, such as Mozinvaders, Mozteroids, PAGMAN, and
  196:       Xultris use JavaScript and Mozilla's rendering engine to
  197:       recreate two-dimensional arcade games from the 80s and early
  198:       90s. Links to most games are available at <i><a href=
  199:       "http://games.mozdev.org/">http://games.mozdev.org/</a></i>.</p>
  200:       <p>Many of these games were created to see how far the
  201:       application development capabilities of Mozilla could be
  202:       pushed. PAGMAN in particular was designed as a test case to
  203:       see what was possible; the result was almost identical to the
  204:       original PacMan game. The creation of PAGMAN was documented
  205:       in an article that provides more information about how the
  206:       game came about and was developed. You can find the
  207:       <i>Building a Game in Mozilla</i> article at <i><a href=
  208:       "http://www.oreillynet.com/pub/a/network/2000/06/30/magazine/mozilla_game.html">
  209:       http://www.oreillynet.com/pub/a/network/2000/06/30/magazine/mozilla_game.html</a></i>.</p>
  210:       <p>Although all of these games are freely available as open
  211:       source projects, not all of them work with Mozilla 1.0. Many
  212:       were created while Mozilla was still in development, so games
  213:       that worked on pre-1.0 releases of Mozilla need additional
  214:       development to work today. The good news is that if you are
  215:       just dying to play Mozteroids or Xultris, you can take what
  216:       you have learned in this book and update the projects so
  217:       everyone can enjoy them.</p>
  218:       <hr>
  219:     </blockquote>
  220:     <h2><a name="77070"></a> Setting Up XPFE for Remote
  221:     Applications</h2>
  222:     <p>Remote Mozilla 
  223:     <!--INDEX remote applications:XPFE:overview --> 
  224:     <!--INDEX XPFE:remote applications:overview --> applications
  225:     are limited because they cannot access and use some of the rich
  226:     functionality provided in XPCOM interfaces. Unless you make the
  227:     privilege change described in this section, access to 
  228:     <!--INDEX XPCOM:remote applications, enabling --> 
  229:     <!--INDEX privileges:XPCOM, enabling for remote applications -->
  230:     <!--INDEX remote applications:XPCOM, enabling --> XPCOM via
  231:     XPConnect in your web page or remote application is forbidden.
  232:     This privilege modification set up by the remote application
  233:     developer grants complete access to the Mozilla functionality,
  234:     to resources in the chrome, and to the host system via the
  235:     Mozilla components that handle such tasks as File I/O. Of
  236:     course, making this change means that the files on your server
  237:     could be read, written to, or deleted, which is why rights are
  238:     restricted by default. We recommend that you grant this
  239:     extended privilege only when you do not have valuable data on
  240:     the server or if you have taken steps to ensure that the data
  241:     cannot be accessed.</p>
  242:     <p>The privilege, called <!--INDEX Universal XPConnect -->
  243:     Universal XPConnect, can be turned on from the 
  244:     <!--INDEX Privilege Manager, remote applications --> Privilege
  245:     Manager, which is a property of the <tt>netscape.security</tt>
  246:     object. <a href="#77028">Example 12-2</a> shows a script that
  247:     turns this privilege on and then uses new found privilege to
  248:     create XPCOM component instance.</p>
  249:     <p><i>Example 12-2: <a name="77028"></a></i> <i>Enabling
  250:     universal XPConnect</i></p>
  251: <pre>
  252:  &lt;script type="application/x-JavaScript"&gt;
  253:  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  254:  var Simple=new Components.Constructor("@mozilla.org/js_simple_component;1", "nsISimple");
  255:  var s = new Simple( );
  256:  for(var list in s)
  257:  document.write(list+"&lt;br&gt;\n");
  258:  &lt;/script&gt;
  259: </pre>
  260:     <p>You can also turn on this privilege in your profile user
  261:     preference file with the following line:</p>
  262: <pre>
  263: enablePrivilege("UniversalXPConnect");
  264: </pre>
  265:     <blockquote>
  266:       <div class="c26">
  267:         NOTE
  268:       </div>
  269:       <p>A script with this kind of plate-cleaning power can only
  270:       be run successfully when it's executed locally, as from a
  271:       local XUL file with a <tt>&lt;DEFANGED_script&gt;</tt>
  272:       element. To open up XPConnect remotely with JavaScript like
  273:       this, you have to use a signed script (see the section <a
  274:       href="#77088">"Creating Signed Remote Applications</a>" in
  275:       this chapter).</p>
  276:     </blockquote>
  277:     <p>Once this privilege is enabled, remote XUL applications can
  278:     run as if they are local. Remote files can use any Mozilla
  279:     component, reuse skin resources, XBL widgets, and whatever else
  280:     the browser uses.</p>
  281:     <h3><a name="77071"></a> Server Configuration</h3>
  282:     <p>Proper configuration 
  283:     <!--INDEX XUL (XML-based User-interface Language):remote applications, MIME type configuration -->
  284:     <!--INDEX remote applications:XPFE:XUL MIME type configuration -->
  285:     <!--INDEX XPFE:remote applications:XUL MIME type configuration -->
  286:     of <!--INDEX configuring servers, remote applications and --> 
  287:     <!--INDEX servers for remote applications, XUL MIME type configuration -->
  288:     the XUL MIME type on your web server is necessary to serve
  289:     remote Mozilla applications successfully. The trick is to
  290:     ensure that the server recognizes the XUL file type and knows
  291:     how to serve it properly. By default, most web servers serve
  292:     files with such unrecognized extensions as <i>text/plain</i>.
  293:     By adding the type <i>application/vnd.mozilla.xul+xml</i> to
  294:     your server's configuration, you can make sure that the server
  295:     matches the file extension and sends this MIME type in the HTTP
  296:     header to the browser. To serve up static XUL pages from your
  297:     web server, you need to add this line to your <i>mime.types</i>
  298:     file if it hasn't been added already:</p>
  299: <pre>
  300: application/vnd.mozilla.xul+xml  &lt;TAB&gt; xul
  301: </pre>
  302:     <p>This is how you can configure Apache MIME types to serve
  303:     static XUL pages. Note that the <i>mime.types</i> file requires
  304:     that you separate the type from the suffix. The format is:</p>
  305: <pre>
  306: mime type &lt;tab&gt; extension.
  307: </pre>
  308:     <p>After the type is added to the server, the browser
  309:     recognizes this header as an XUL file and parses, renders, and
  310:     creates the appropriate DOM. If your server isn't configured to
  311:     recognize this MIME type, then users see the contents of your
  312:     file as source only-a plain text complete with all the
  313:     formatting.</p>
  314:     <p>Now that your web server is configured correctly, you can
  315:     add a sample XUL file (such as the file in <a href=
  316:     "#77030">Example 12-3</a>) to your web site to make sure things
  317:     are running properly. You should name the file
  318:     <i>remote.xul</i> and save it in your web site's root directory
  319:     for testing.</p>
  320:     <p><i>Example 12-3: <a name="77030"></a></i> <i>A sample static
  321:     XUL file</i></p>
  322: <pre>
  323:  &lt;?xml version="1.0"?&gt;
  324:  &lt;!DOCTYPE window&gt;
  325:  &lt;window
  326:    id = "remote"
  327:    xmlns = "<a href=
  328: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
  329:    title = "A Remote Image"
  330:    style = "min-width:282px; min-height:137px;"
  331:    orient = "vertical"&gt;
  332:    &lt;image src="<a href=
  333: "http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</a>" /&gt;
  334:  &lt;/window&gt;
  335: </pre>
  336:     <p>You can now view this window by launching it as a chrome
  337:     file from Mozilla as follows:</p>
  338: <pre>
  339: ./mozilla -chrome <a href=
  340: "http://my.domain/remote.xul">http://my.domain/remote.xul</a>
  341: </pre>
  342:     <p>Or you can also load it up by simply entering the URL in
  343:     your browser location bar as follows::</p>
  344: <pre>
  345: <a href=
  346: "http://my.domain/remote.xul">http://my.domain/remote.xul</a>
  347: </pre>
  348:     <h2><a name="77072"></a> Generated Content</h2>
  349:     <p>Today par <!--INDEX remote applications:dynamic content -->
  350:     t of the Web is driven by dynamically generated content. This
  351:     content is primarily stored in databases, which is used by an
  352:     application or middle layer to format the data to HTML. The web
  353:     server then sends the content to the browser. The browser
  354:     receives the web page as the end result and has no knowledge
  355:     that the page was generated on the server-just that it is a
  356:     properly formatted HTML file. By using these same conventional
  357:     principals, we can send generated or database-driven XUL, CSS,
  358:     or JavaScript to Mozilla. Because XUL is a document that
  359:     creates a UI, this widget drawing capability opens up a whole
  360:     new world to web application development.</p>
  361:     <p>If you are a web developer creating database-driven
  362:     applications, you will quickly see the limitations of using a
  363:     simple markup like HTML-for example, being constrained to the
  364:     content area of a browser for which you cannot manage all of
  365:     the application interface's "real estate." Using a browser
  366:     window for your application is a common enough practice, but
  367:     you still don't have the application-level widgets of most
  368:     client-side applications when you use HTML. This section shows
  369:     that using XUL files created by scripting languages allows you
  370:     to create windows and applications that move out of the browser
  371:     window and into the full-featured application space. Mozilla's
  372:     origins, after all, are as a web browser and suite of Internet
  373:     applications, and the latest technologies in the XPFE toolkit
  374:     go that extra step to allow the presentation of UI information
  375:     over the wire.</p>
  376:     <h3><a name="77073"></a> Generating Content with Scripting
  377:     Languages</h3>
  378:     <p>This section 
  379:     <!--INDEX remote applications:dynamic content:scripting languages -->
  380:     <!--INDEX scripting:remote applications:dynamic content -->
  381:     discusses the basic mechanics of server-generated content. In
  382:     most cases, the actual content is static-although the server
  383:     application creates the page dynamically, the content itself is
  384:     not input. It is also not created dynamically by other methods,
  385:     such as using JavaScript to manipulate the client's document
  386:     after it loads from the server.</p>
  387:     <p>To generate server-generated content, you need to use a
  388:     scripting language. We explore the use of three different
  389:     options: PHP, Perl, and Python. PHP is probably the most
  390:     natural language for this application because it has its
  391:     origins in serving up dynamic HTML, but you can play around
  392:     with your favorite language and determine whether it has the
  393:     appropriate capabilities for this environment. To use various
  394:     scripting languages with Mozilla, you need a working knowledge
  395:     of their capabilities; the scope of this book doesn't provide
  396:     programming information for the selected scripting
  397:     languages.</p>
  398:     <h4><a name="77074"></a> PHP</h4>
  399:     <p>When <!--INDEX PHP remote applications --> 
  400:     <!--INDEX remote applications:dynamic content:PHP --> 
  401:     <!--INDEX scripting:remote applications:PHP --> users of your
  402:     application may not have configured their browser to support
  403:     the correct MIME type, you can use the PHP header function to
  404:     send the browser the correct type.</p>
  405:     <p>Remember that when using XUL with PHP, you need to edit your
  406:     <i>php.ini</i> file on the server and change the default
  407:     configuration to:</p>
  408: <pre>
  409: short_open_tag  =   Off
  410: </pre>
  411:     <p>By default, this configuration is set to "On." When "Off,"
  412:     this setting tells the PHP interpreter to parse only the files
  413:     with escape tag identifiers, such as <tt>&lt;?php ?&gt;</tt>
  414:     (and not <tt>&lt;? ?&gt;</tt>, which are used by XML). This
  415:     process is separate from the XML parsing process that occurs
  416:     when Mozilla receives and tries to render the generated
  417:     content. If you don't change the <i>.ini</i> file, you will see
  418:     an error like this:</p>
  419: <pre>
  420: Parse error: parse error in /usr/local/share/doc/apache/remote_xul.php on line 2
  421: </pre>
  422:     <p>This error occurs when PHP sees your XUL syntax as invalid
  423:     PHP code.</p>
  424:     <p>Once PHP is properly configured to handle XUL files, you're
  425:     ready to go. To start out with something simple, use the code
  426:     in <a href="#77032">Example 12-4</a> to produce a simple XUL
  427:     window with the xFly logo by using PHP. Be sure to save the
  428:     file with a <i>.php</i> extension.</p>
  429:     <p><i>Example 12-4: <a name="77032"></a></i> <i>Using PHP to
  430:     generate the correct XUL MIME type</i></p>
  431: <pre>
  432:  &lt;?php header( "Content-type: application/vnd.mozilla.xul+xml" ); ?&gt;
  433:  &lt;&lt;/td&gt;?xml version="1.0"?&gt;
  434:  &lt;!DOCTYPE window&gt;
  435:  &lt;window
  436:      id     = "remote"
  437:      xmlns  = "<a href=
  438: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
  439:      title  = "A Remote Image"
  440:      style  = "min-width:282px; min-height:137px;"
  441:      orient = "vertical"&gt;
  442:    &lt;image src="<a href=
  443: "http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</a>" /&gt;
  444:  &lt;/window&gt;
  445: </pre>
  446:     <p>Also remember that a space below the PHP tag results in a
  447:     parse error in Mozilla. The next example shows the PHP header
  448:     and the XML declaration at the start of the PHP file. The space
  449:     between the two renders it invalid:</p>
  450: <pre>
  451: &lt;?php header( "Content-type: application/vnd.mozilla.xul+xml" ); ?&gt;
  452: &lt;?xml version="1.0"?&gt;
  453: </pre>
  454:     <p>After PHP parses its content on the server, the rest of the
  455:     document is sent to Mozilla on the client. Put this file
  456:     (<tt>remote_xul.php</tt>) somewhere in your document root on
  457:     the server with PHP installed and launch it from Mozilla like
  458:     this:</p>
  459: <pre>
  460: ./mozilla -chrome <a href=
  461: "http://my.domain/remote_xul.php">http://my.domain/remote_xul.php</a>
  462: </pre>
  463:     <p>The window defined in <a href="#77032">Example 12-4</a> now
  464:     appears, displaying the image. You can take advantage of this
  465:     relatively straightforward technique to serve up more
  466:     feature-rich user interfaces, inclusive of buttons, menus, and
  467:     any other pieces of XUL that are needed.</p>
  468:     <h4><a name="77075"></a> Perl</h4>
  469:     <p>Although <!--INDEX Perl:remote applications --> 
  470:     <!--INDEX remote applications:dynamic content:Perl --> 
  471:     <!--INDEX scripting:remote applications:Perl --> PHP is rising
  472:     in popularity, Perl is still a very popular web-scripting
  473:     language. Perl is often used to drive back end web applications
  474:     with CGI scripts. To process Perl scripts, no extra
  475:     configuration is needed once you have the Perl interpreter set
  476:     up to run in a web server environment. If, for example, you're
  477:     already using Perl to serve up dynamic HTML pages, you're all
  478:     set. Otherwise, you should grab a distribution of Perl (<i><a
  479:     href="http://perl.com/">http://perl.com/</a></i>) and set up
  480:     the paths to the binary files in your server scripts. This
  481:     procedure is done by placing the path in the header, otherwise
  482:     known as the <i>shebang line</i>. This script usually takes a
  483:     form similar to <tt>#!/usr/local/bin/perl</tt> or
  484:     <tt>#!/usr/bin/perl</tt>. You must also make sure that the
  485:     server knows where the Perl executable is, which involves
  486:     including the path to it in the systems <tt>PATH</tt>
  487:     environment variable. Depending on the platform and the web
  488:     server you use, other environments may need to be set.</p>
  489:     <p><a href="#77034">Example 12-5</a> shows a simple CGI script
  490:     that generates a minimal amount of XUL for display in the
  491:     browser. Perl is useful for this task because you can set up
  492:     several possible scripts and call selected ones, depending on
  493:     what choices the user makes. You can even have different forks
  494:     in the same script that displays different widgets or data. For
  495:     example, imagine that your remote XUL application is an online
  496:     travel planner. You would display maps, information, and links
  497:     to resources based on the user's geographic location or
  498:     preferences for destinations they entered earlier.</p>
  499:     <p><i>Example 12-5: <a name="77034"></a></i> <i>A simple
  500:     Perl-generated XUL file</i></p>
  501: <pre>
  502:  #!/usr/bin/perl
  503:  print "Content-type: application/vnd.mozilla.xul+xml";
  504:  print qq{
  505:  &lt;?xml version="1.0"?&gt;
  506:  &lt;!DOCTYPE window&amp;gt;
  507:  &lt;window
  508:    id = "remote"
  509:    xmlns = "<a href=
  510: "http://www.mozilla.org/keym">http://www.mozilla.org/keym</a>
  511:    style = "min-width:282px; min-height:137px;"
  512:    orient = "vertical"&gt;
  513:    &lt;image src="<a href=
  514: "http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</a>"/&gt;
  515:  &lt;/window&gt;
  516:  };
  517: </pre>
  518:     <p>In <a href="#77034">Example 12-5</a>, the MIME type must be
  519:     specified as part of the first line in the CGI script after the
  520:     <i>shebang line</i>, and rest of the script is the XUL code
  521:     used by Mozilla. Although this example does not display real
  522:     dynamic content (such as the kind you get from CGI forms or
  523:     other user-supplied data), it shows how you can interpolate
  524:     dynamic data into a simple CGI application model.</p>
  525:     <h4><a name="77076"></a> Python</h4>
  526:     <p>Like <!--INDEX Python:remote applications --> 
  527:     <!--INDEX remote applications:dynamic content:Python --> 
  528:     <!--INDEX scripting:remote 
  529:     applications:Python --> Perl, Python provides modules that make
  530:     it easy to create CGI applications that generate content
  531:     dynamically. Python is already an important language in the
  532:     Mozilla environment because of the <i>PyXPCOM</i> bindings
  533:     discussed in <a href="ch08.html#77048">Chapter 8</a>.</p>
  534:     <p>If Python is a language that you like to code in, using it
  535:     in a remote XUL environment would also make sense. Python
  536:     combines the features of a lower-level language like
  537:     object-oriented class and function design with the flexibility
  538:     and simplicity of a scripting language. The latter feature
  539:     (ease of use) is relative to a language like C++. <a href=
  540:     "#77036">Example 12-6</a> shows how to use Python to create a
  541:     simple form consisting of three checkboxes.</p>
  542:     <p><i>Example 12-6: <a name="77036"></a></i> <i>A
  543:     Python-generated dynamically updated form</i></p>
  544: <pre>
  545:  #!/usr/local/bin/python
  546:  import cgi
  547:  form = cgi.FieldStorage( )
  548:  print """Content-type: application/vnd.mozilla.xul+xml\n
  549:  &lt;?xml version=\"1.0\"?&gt;
  550:   &lt;!DOCTYPE window&gt;
  551:   &lt;window
  552:     id = "remote"
  553:     xmlns = "<a href=
  554: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
  555:     title = "listbox"
  556:     style = "min-width:282px; min-height:137px;"
  557:     orient = "vertical"&gt;
  558:    &lt;box&gt;"""
  559:  print '  &lt;checkbox label="%s" /&gt;' % form&lt;/td&gt;['op1'].value
  560:  print '  &lt;checkbox label="%s" /&gt;' % form&lt;/td&gt;['op2'].value
  561:    print ' &lt;checkbox label="%s" /&gt;' % form&lt;/td&gt;['op3'].value
  562:    print """&lt;/box&gt;
  563:    &lt;/window&gt;"""
  564: </pre>
  565:     <p>In this example, the CGI module is loaded with the Python
  566:     <tt>import</tt> statement, and the form object is initialized
  567:     so that data input to the page in the form of URL
  568:     <tt>?name=value</tt> pairs create the XUL content
  569:     dynamically.</p>
  570:     <p><a href="#77036">Example 12-6</a> takes a URL, such as <i><a
  571:     href=
  572:     "http://www.brownhen.com/cgi-bin/xulgen?opt1=peter?opt2=paul?opt3=mary">
  573:     http://www.brownhen.com/cgi-bin/xulgen?opt1=peter?opt2=paul?opt3=mary</a></i>,
  574:     and displays a checkbox for each value of the named form
  575:     fields. The content type is printed before the XUL content to
  576:     tell the web server what to pass when the script produces its
  577:     output.</p>
  578:     <h3><a name="77077"></a> Generating Content from a
  579:     Database</h3>
  580:     <p>One of the 
  581:     <!--INDEX remote applications:dynamic content:database generated -->
  582:     <!--INDEX databases:remote applications, dynamic content -->
  583:     important facets of dynamically generated content is
  584:     interaction with a database to store and retrieve values for
  585:     the user. For example, a public forum or subscription-based
  586:     service could have a client that is written in XUL and requires
  587:     authentication of users. Having such a client could require
  588:     some form of database lookup. This section covers a simple
  589:     example that uses data stored in a database to generate a XUL
  590:     tree. We will use PHP to retrieve the data from the SQL-driven
  591:     database and format it into XUL. Theoretically, this database
  592:     could be any relational model, such as Oracle or MySQL.</p>
  593:     <p><a href="#77038">Example 12-7</a> generates a simple tree
  594:     listing with the columns "User" and "Project." The SQL script
  595:     creates a table called "sample" and then inserts value pairs
  596:     into the table. To use this type content generation, your
  597:     database must be set up to handle table creation and dynamic
  598:     updating via SQL calls.</p>
  599:     <p><i>Example 12-7: <a name="77038"></a></i> <i>SQL script with
  600:     User and Project data</i></p>
  601: <pre>
  602:  # table to be inserted into database
  603:  CREATE TABLE sample (
  604:    User char(16) NOT NULL default '',
  605:    Project char(32) NOT NULL default ''
  606:  );
  607:  INSERT INTO sample VALUES ('Bob','moz_bob');
  608:  INSERT INTO sample VALUES ('Joe','skinner');
  609:  INSERT INTO sample VALUES ('Bret','bretzilla');
  610:  INSERT INTO sample VALUES ('Sally','mozstream');
  611: </pre>
  612:     <p>The code in <a href="#77038">Example 12-7</a> creates a
  613:     table with two fields, "User" and "Project." It then inserts
  614:     four records into the newly created table in the database by
  615:     using <tt>INSERT</tt> <tt>INTO</tt> calls. Now the script has
  616:     tangible data to query.</p>
  617:     <p><a href="#77040">Example 12-8</a> shows the creation of a
  618:     simple XUL tree with PHP and a MySQL database. The "User" and
  619:     "Project" columns display the data in the table.</p>
  620:     <p><i>Example 12-8: <a name="77040"></a></i> <i>XUL generated
  621:     from database</i></p>
  622: <pre>
  623:  &lt;?php header( "Content-type: application/vnd.mozilla.xul+xml" ); ?&gt;
  624:  &lt;?xml version="1.0"?&gt;
  625:  &lt;?php
  626:    // connect code
  627:    $host           = "127.0.0.1";
  628:    $user           = "nobody";
  629:    $database       = "test";
  630:    $password       = "mypass";
  631:    $connect        =  mysql_connect($host, $user, $password);
  632:    mysql_select_db($database);
  633:    $query          = "SELECT * FROM sample ORDER BY User";
  634:    $result         = mysql_query($query, $connect);
  635:    $e              = mysql_error( );
  636:    if($e)
  637:      print  "ERROR:projects: $e";
  638:    $row            = mysql_num_rows($result);
  639:  ?&gt;
  640:  &lt;!DOCTYPE window&gt;
  641:  &lt;window
  642:    id = "remote"
  643:    xmlns = "<a href=
  644: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
  645:    title = "A Remote Image" style = "min-width:282px; min-height:137px;"&gt;
  646:    &lt;image src="<a href=
  647: "http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</a>" /&gt;
  648:    &lt;hbox&gt;
  649:      &lt;tree&gt;
  650:        &lt;treecols&gt;
  651:          &lt;treecol id="userCol" label="User" /&gt;
  652:          &lt;treecol id="projectCol" label="Project" flex="1"/&gt;
  653:        &lt;/treecols&gt;
  654:        &lt;treechildren&gt;
  655:          &lt;?php
  656:            // generate data from db
  657:            for($i=0;$i&lt;$row;$i++) {
  658:              $user    = mysql_result($result, $i, "User");
  659:              $project = mysql_result($result, $i, "Project");
  660:              print "&lt;treeitem container=\"true\" open=\"true\"&gt;\n";
  661:              print "&lt;treerow&gt;\n";
  662:              print "&lt;treecell label=\"".ucwords($user)."\" /&gt;";
  663:              print "&lt;treecell label=\"".ucwords($project)."\" flex=\"1\"/&gt;";
  664:              print "&lt;/treerow&gt;\n";
  665:              print "&lt;/treeitem&gt;\n";
  666:            }
  667:          ?&gt;
  668:         &lt;/treechildren&gt;
  669:      &lt;/tree&gt;
  670:      &lt;spacer flex="1" /&gt;
  671:   &lt;/hbox&gt;
  672:  &lt;/window&gt;
  673: </pre>
  674:     <p>The PHP header method is placed at the top of the file to
  675:     properly format the output as XUL. The PHP MySQL APIs prepare
  676:     the code for connection to a MySQL database. Finally, a loop is
  677:     used to print out the stored data's <tt>treerows</tt> and
  678:     <tt>treecells</tt>.</p>
  679:     <p>This kind of operation provides insight into the
  680:     possibilities of using remote XUL when you have information
  681:     stored in a database. Many web applications already do this via
  682:     HTML forms and other mechanisms, but Mozilla's XPFE toolkit
  683:     provides a richer widget set than HTML to display and retrieve
  684:     information (see the section <a href="ch03.html#77114">"Form
  685:     Controls" in Chapter 3</a>).</p>
  686:     <p>Some XUL widgets are created specifically to display complex
  687:     tabular data such as <tt>&lt;tree&gt;</tt>, and some widgets
  688:     provide user selection such as <tt>&lt;checkbox&gt;</tt>,
  689:     <tt>&lt;radio&gt;</tt>, and <tt>&lt;textbox&gt;</tt>, plus the
  690:     CSS used for controlling presentation. All of these widgets can
  691:     be generated on the fly from the database and used to accept
  692:     user-inputted information.</p>
  693:     <h3><a name="77078"></a> Localizing Remote Applications</h3>
  694:     <p>Unfortunately, <!--INDEX remote applications:localizing --> 
  695:     <!--INDEX localizing remote applications --> localizing remote
  696:     applications is a not as straightforward since there is no
  697:     http: protocol equivalent for chrome:-included locales. You
  698:     could use <i>HTTP/1.1</i> content negotiation to serve the
  699:     users-preferred language, but Mozilla 1.0 does not read DTD
  700:     files over the wire. To overcome this problem, use server-side
  701:     page processing. For example, this code includes the DTD by
  702:     using PHP:</p>
  703: <pre>
  704: &lt;!DOCTYPE window [
  705: &lt;?php require(PROJECT_PATH."/online/locale/xfly.dtd"); ?&gt;
  706: ]&gt;
  707: </pre>
  708:     <p>Therefore, the served page looks like this:</p>
  709: <pre>
  710: &lt;!DOCTYPE window [
  711: &lt;!ENTITY fileMenu.label        "File"&gt;
  712: &lt;!ENTITY fileMenu.accesskey    "f"&gt;
  713: ...
  714: ]&gt;
  715: </pre>
  716:     <p>The only caveat for this approach is that you need a method
  717:     to filter the entities, depending on which language is loaded.
  718:     Obtaining a method could be done by reading in the locale and
  719:     outputting the entities or by calling a separate script. This
  720:     overhead is not necessarily high, as multiple files exist for
  721:     multiple languages in a client distribution. A remote
  722:     application would require the same process, but in a different
  723:     format.</p>
  724:     <h2><a name="77079"></a> Certificate Authorities and Digital
  725:     Signatures</h2>
  726:     <p>Instead 
  727:     <!--INDEX security:remote applications:Certificate Authorities and digital signatures -->
  728:     <!--INDEX remote applications:Certificate Authorities --> 
  729:     <!--INDEX remote applications:digital signatures --> 
  730:     <!--INDEX Certificate Authorities:remote applications --> 
  731:     <!--INDEX digital signatures, remote applications --> of
  732:     changing the Universal XPConnect privileges (see <a href=
  733:     "#77070">"Setting Up XPFE for Remote Applications</a>" earlier
  734:     in this chapter), you could create signed remote applications
  735:     that can be granted access to users' computers. A signed
  736:     application means that the application has a digital signature,
  737:     which verifies that a file or group of files was created by the
  738:     person or organization from which you download and that they
  739:     are trustworthy. In essence, if you trust the person or
  740:     organization signing the files, then you trust the files
  741:     themselves.</p>
  742:     <p>Digital signatures originate from a certificate authority
  743:     (CA), an organization that claims responsibility for any
  744:     digital signature it creates. CAs act as gatekeepers by
  745:     allowing only people who the organization trusts to create
  746:     digital signatures. Large CAs like 
  747:     <!--INDEX Certificate Authorities: Verisign;Verisign -->
  748:     Verisign, whose certificates come preinstalled in many web
  749:     browsers, enforce validity through large fees. For example, if
  750:     you can afford $600, then you are an organization with whom the
  751:     CA would be glad to associate. That $600 then also buys your
  752:     application respectability with user's web browsers. You can
  753:     see the CAs that come with the Mozilla browser by going to
  754:     Privacy &amp; Security &gt; Certificates in your preferences
  755:     panel and then by selecting the Manage Certificates option. Of
  756:     the different types of CAs-there's a type for SSL connections,
  757:     for example, and another one for S/MIME-the 
  758:     <!--INDEX Netscape:Object Signing certificate --> Netscape
  759:     Object Signing certificate is what matters for signed
  760:     applications.</p>
  761:     <p>Fortunately, to get your remote applications signed by a CA,
  762:     you don't have to pay for a Verisign Netscape Object Signing CA
  763:     because other options are available. You can use the MozDev CA,
  764:     for example, and even create your own. The next section tells
  765:     you how use Mozilla tools to become your own certificate
  766:     authority so you can sign your own applications and those of
  767:     other Mozilla developers. The <a href="#77088">"Creating Signed
  768:     Remote Applications</a>" section later in this chapter uses the
  769:     MozDev CA to discuss both avenues.</p>
  770:     <h3><a name="77080"></a> Mozilla Network Security Services
  771:     (NSS)</h3>
  772:     <p>The Mozilla <!--INDEX NSS (Network Security Service) --> 
  773:     <!--INDEX Certificate Authorities:NSS --> Network Security
  774:     Services tools, which are described in detail at 
  775:     <!--INDEX web sites:NSS --> <i><a href=
  776:     "http://www.mozilla.org/projects/security/pki/nss/">http://www.mozilla.org/projects/security/pki/nss/</a></i>,
  777:     allow you to become your own Netscape Object Signing CA. By
  778:     becoming your own Netscape Signing CA, you can distribute
  779:     signing certificates to Mozilla application developers. You can
  780:     obtain the tools via a simplified distribution of NSS for
  781:     Windows and Linux at <i><a href=
  782:     "http://certs.mozdev.org">http://certs.mozdev.org</a></i>.
  783:     These tools allow you to become a CA and to package signed
  784:     remote Mozilla applications. Finally, the commands for CertUtil
  785:     work the same way on Windows, Linux, and any other OS on which
  786:     you run CertUtil.</p>
  787:     <h3><a name="77081"></a> CA Certificates, Signing Certificates,
  788:     and the Certificate Chain</h3>
  789:     <p>A certificate 
  790:     <!--INDEX Certificate Authorities:distribution certificates:requirements -->
  791:     represents an organization in a official digital form. It
  792:     provides fields for the organization's name, contact
  793:     information, date of issue, and an expiration date. There are
  794:     also two keys: a private and a public key.</p>
  795:     <p>To become a CA, you need to create two certificates for
  796:     yourself: a "root certificate" and a "distribution
  797:     certificate." Once you set up these certificates, you can issue
  798:     signing certificates, which create digital signatures. <a href=
  799:     "#77008">Figure 12-4</a> shows the chain of relationships
  800:     between certificates.</p>
  801:     <div class="c25">
  802:       <img src="foo.gif">
  803:     </div>
  804:     <p><i>Figure 12-4: <a name="77008"></a></i> <i>A 
  805:     <!--INDEX Netscape:Object Signing certificate --> Netscape
  806:     Object Signing certificate chain</i></p>
  807:     <p>The distribution certificate is based on the root
  808:     certificate's public key. You can then create signing
  809:     certificates from the distribution certificate, using its
  810:     public key that it handles automatically by NSS. Finally, the
  811:     digital signatures derived from the signing certificate can
  812:     sign applications using NSS.</p>
  813:     <h3><a name="77082"></a> Setting Up a Certificate
  814:     Authority</h3>
  815:     <p>Using the CertUtil tool 
  816:     <!--INDEX Certificate Authorities:setting up --> 
  817:     <!--INDEX security:Certificate Authorities:setting up --> that
  818:     comes with NSS, you need to create a root certificate and a
  819:     distribution certificate for yourself to become a CA. The
  820:     CertUtil tool is located in the NSS installation's <i>bin</i>
  821:     directory and can be run from anywhere in a console window. In
  822:     the next few sections, we walk through the steps necessary to
  823:     accomplish this process.</p>
  824:     <h4><a name="77083"></a> Creating a certificate database</h4>
  825:     <p>Mozilla 
  826:     <!--INDEX Certificate Authorities:certificate database --> 
  827:     <!--INDEX certificate database, creating --> 
  828:     <!--INDEX databases:certificate, creating --> 
  829:     <!--INDEX security:Certificate Authorities:certificate database -->
  830:     comes with a prefilled certificate database that contains
  831:     information about certificates from Verisign and other CAs
  832:     (found in the file <i>cert7.db</i> in the user profile
  833:     directory), which you can modify. However, starting with a
  834:     blank database is better because it avoids the possibility of
  835:     corruption.</p>
  836:     <p>At the prompt, create a new database by using the
  837:     <tt>-N</tt> and <tt>-d</tt> options for CertUtil:</p>
  838: <pre>
  839: C:\NSS\bin&gt;certutil -N -d .
  840: </pre>
  841:     <p>Enter a password for the database. You need to reenter this
  842:     password every time you issue or change certificates. CertUtil
  843:     creates the files <i>cert7.db</i>, <i>key3.db</i>, and
  844:     <i>secmod.db</i> in the same directory as CertUtil. You can
  845:     delete the <i>key3.db</i> and <i>secmod.db</i> files because
  846:     they do not pertain to certificate creation or
  847:     modification.</p>
  848:     <h4><a name="77084"></a> Creating the root CA certificate</h4>
  849:     <p>The root 
  850:     <!--INDEX Certificate Authorities:root certificate, creating -->
  851:     <!--INDEX security:Certificate Authorities:root certificate, creating -->
  852:     <!--INDEX root certificates, creating --> 
  853:     <!--INDEX certificates:root, creating --> certificate is the
  854:     foundation for the certificate chain and should not be shared
  855:     with anyone outside your organization. You may want to consider
  856:     storing the database or exported certificate on a floppy disk
  857:     for safe keeping. If it gets lost or stolen, you need to make a
  858:     new one and all your users will need to use new certificates
  859:     and resign their applications.</p>
  860:     <p>Once you create <i>cert7.db</i>, CertUtil can process the
  861:     Root CA Certificate into it, using the following and
  862:     substituting the name of your CA for mozdev.org:</p>
  863: <pre>
  864: C:\NSS\bin&gt;certutil -S -s "CN=mozdev.org, O=mozdev.org" -n "mozdev.org"
  865: -t ",,C" -x -d . -1 -2 -5
  866: </pre>
  867:     <p>Enter a password at the prompt and proceed by making the
  868:     menu choices shown in <a href="#77042">Example 12-9</a>.</p>
  869:     <p><i>Example 12-9: <a name="77042"></a></i> <i>Creating a root
  870:     certificate</i></p>
  871: <pre>
  872:  Generating key.  This may take a few moments...
  873:                            0 - Digital Signature
  874:                            1 - Non-repudiation
  875:                            2 - Key encipherment
  876:                            3 - Data encipherment
  877:                            4 - Key agreement
  878:                            5 - Cert signing key
  879:                            6 - CRL signing key
  880:                            Other to finish
  881:  5
  882:                            0 - Digital Signature
  883:                            1 - Non-repudiation
  884:                            2 - Key encipherment
  885:                            3 - Data encipherment
  886:                            4 - Key agreement
  887:                            5 - Cert signing key
  888:                            6 - CRL signing key
  889:                            Other to finish
  890:  9
  891:  Is this a critical extension &lt;/td&gt;[y/n]?
  892:  n
  893:  Is this a CA certificate &lt;/td&gt;[y/n]?
  894:  y
  895:  Enter the path length constraint, enter to skip &lt;/td&gt;[&lt;0 for unlimited path]:
  896:  Is this a critical extension &lt;/td&gt;[y/n]?
  897:  n
  898:                            0 - SSL Client
  899:                            1 - SSL Server
  900:                            2 - S/MIME
  901:                            3 - Object Signing
  902:                            4 - Reserved for futuer use
  903:                            5 - SSL CA
  904:                            6 - S/MIME CA
  905:                            7 - Object Signing CA
  906:                            Other to finish
  907:  7
  908:                            0 - SSL Client
  909:                            1 - SSL Server
  910:                            2 - S/MIME
  911:                            3 - Object Signing
  912:                            4 - Reserved for futuer use
  913:                            5 - SSL CA
  914:                            6 - S/MIME CA
  915:                            7 - Object Signing CA
  916:                            Other to finish
  917:  9
  918:  Is this a critical extension &lt;/td&gt;[y/n]?
  919:  n
  920: </pre>
  921:     <p>The mozdev.org Root CA Certificate resides in
  922:     <i>cert7.db</i>. You can export it to a file for safekeeping as
  923:     follows:</p>
  924: <pre>
  925: C:\NSS\bin&gt;certutil -L -d . -n "mozdev.org" -a -o mozdev.cacert
  926: </pre>
  927:     <p>This code will yield an ASCII representation of the
  928:     certificate.</p>
  929:     <h4><a name="77085"></a> Creating a distribution CA
  930:     certificate</h4>
  931:     <p>Next you must 
  932:     <!--INDEX Certificate Authorities:distribution certificates:creating -->
  933:     <!--INDEX security:Certificate Authorities:distribution certificates, creating -->
  934:     <!--INDEX distribution certificates:creating --> 
  935:     <!--INDEX certificates:distribution:creating --> create a
  936:     distribution certificate. This certificate will be installed
  937:     into the user's Mozilla web browser so Mozilla can verify
  938:     related signed remote Mozilla applications. Start the
  939:     certificate by typing the following code at the prompt and
  940:     substituting the name of your CA for "mozdev.org":</p>
  941: <pre>
  942: C:\NSS\bin&gt;certutil -S -n "certs.mozdev.org"
  943: -s "CN=certs.mozdev.org, O=certs.mozdev.org" -c "mozdev.org" -v 96
  944: -t ",,C" -d . -1 -2 -5
  945: </pre>
  946:     <p>Enter a password at the prompt and make the menu choices
  947:     shown in <a href="#77044">Example 12-10</a>. Example 12-10<a
  948:     name="77044"></a> <i>Creating a distribution
  949:     certificate</i></p>
  950: <pre>
  951:  Generating key.  This may take a few moments...
  952:                            0 - Digital Signature
  953:                            1 - Non-repudiation
  954:                            2 - Key encipherment
  955:                            3 - Data encipherment
  956:                            4 - Key agreement
  957:                            5 - Cert signning key
  958:                            6 - CRL signning key
  959:                            Other to finish
  960:  5
  961:                            0 - Digital Signature
  962:                            1 - Non-repudiation
  963:                            2 - Key encipherment
  964:                            3 - Data encipherment
  965:                            4 - Key agreement
  966:                            5 - Cert signning key
  967:                            6 - CRL signning key
  968:                            Other to finish
  969:  9
  970:  Is this a critical extension &lt;/td&gt;[y/n]?
  971:  n
  972:  Is this a CA certificate &lt;/td&gt;[y/n]?
  973:  y
  974:  Enter the path length constraint, enter to skip &lt;/td&gt;[&lt;0 for unlimited path]:
  975:  Is this a critical extension &lt;/td&gt;[y/n]?
  976:  n
  977:                            0 - SSL Client
  978:                            1 - SSL Server
  979:                            2 - S/MIME
  980:                            3 - Object Signing
  981:                            4 - Reserved for futuer use
  982:                            5 - SSL CA
  983:                            6 - S/MIME CA
  984:                            7 - Object Signing CA
  985:                            Other to finish
  986:  7
  987:                            0 - SSL Client
  988:                            1 - SSL Server
  989:                            2 - S/MIME
  990:                            3 - Object Signing
  991:                            4 - Reserved for futuer use
  992:                            5 - SSL CA
  993:                            6 - S/MIME CA
  994:                            7 - Object Signing CA
  995:                            Other to finish
  996:  9
  997:  Is this a critical extension &lt;/td&gt;[y/n]?
  998:  n
  999: </pre>
 1000:     <p>Note the differences between this process and that used to
 1001:     create the root certificate. The distribution certificate is
 1002:     not self-signed, so to create it, you must reference the
 1003:     mozdev.org Root CA Certificate in the initial command. Also,
 1004:     the <tt>-v 96</tt> option indicates that the certificate is
 1005:     good for 96 months.</p>
 1006:     <p>Once you've created the distribution certificate, export it
 1007:     using the following command (for which "certs.mozdev.org" is
 1008:     the name of your CA):</p>
 1009: <pre>
 1010: C:\NSS\bin&gt;certutil -L -d . -n "certs.mozdev.org" -a -o certs_mozdev.cacert
 1011: </pre>
 1012:     <p>Keep track of the resulting file because you will need to
 1013:     upload it to your web site later so browsers can install
 1014:     it.</p>
 1015:     <h3><a name="77086"></a> Issuing Signing Certificates</h3>
 1016:     <p>Once you <!--INDEX signing certificates:issuing --> 
 1017:     <!--INDEX certificates:signing:issuing --> 
 1018:     <!--INDEX Certificate Authorities:signing certificates, issuing -->
 1019:     <!--INDEX security:Certificate Authorities:issuing signing certificates -->
 1020:     create the two root and distribution certificates for your
 1021:     organization, you are a certificate authority, much like
 1022:     VeriSign. You decide who gets the privilege of a signing
 1023:     certificate and issue them accordingly. Signing certificates
 1024:     should not be reused for different people. When you want to
 1025:     give out a signing certificate, you should create a new one by
 1026:     using CertUtil and make a copy of the exported certificate for
 1027:     yourself to keep and catalog.</p>
 1028:     <p>To create a signing certificate, use the following command
 1029:     and substitute the name of your CA for "mozdev.org":</p>
 1030: <pre>
 1031: C:\NSS\bin&gt;certutil -S -n "certs.mozdev.org/signing"
 1032: -s "CN=certs.mozdev.org/signing, O=certs.mozdev.org" -c "certs.mozdev.org" -v 96 -t ",,C" -d . -1 -2 -5
 1033: </pre>
 1034:     <p>Enter a password at the prompt and make the menu choices
 1035:     shown in <a href="#77046">Example 12-11</a>. Example 12-11<a
 1036:     name="77046"></a> <i>Create a signing certificate</i></p>
 1037: <pre>
 1038:  Generating key.  This may take a few moments...
 1039:                            0 - Digital Signature
 1040:                            1 - Non-repudiation
 1041:                            2 - Key encipherment
 1042:                            3 - Data encipherment
 1043:                            4 - Key agreement
 1044:                            5 - Cert signning key
 1045:                            6 - CRL signning key
 1046:                            Other to finish
 1047:  0
 1048:                            0 - Digital Signature
 1049:                            1 - Non-repudiation
 1050:                            2 - Key encipherment
 1051:                            3 - Data encipherment
 1052:                            4 - Key agreement
 1053:                            5 - Cert signning key
 1054:                            6 - CRL signning key
 1055:                            Other to finish
 1056:  5
 1057:                            0 - Digital Signature
 1058:                            1 - Non-repudiation
 1059:                            2 - Key encipherment
 1060:                            3 - Data encipherment
 1061:                            4 - Key agreement
 1062:                            5 - Cert signning key
 1063:                            6 - CRL signning key
 1064:                            Other to finish
 1065:  9
 1066:  Is this a critical extension &lt;/td&gt;[y/n]?
 1067:  n
 1068:  Is this a CA certificate &lt;/td&gt;[y/n]?
 1069:  n
 1070:  Enter the path length constraint, enter to skip &lt;/td&gt;[&lt;0 for unlimited path]:
 1071:  Is this a critical extension &lt;/td&gt;[y/n]?
 1072:  n
 1073:                            0 - SSL Client
 1074:                            1 - SSL Server
 1075:                            2 - S/MIME
 1076:                            3 - Object Signing
 1077:                            4 - Reserved for futuer use
 1078:                            5 - SSL CA
 1079:                            6 - S/MIME CA
 1080:                            7 - Object Signing CA
 1081:                            Other to finish
 1082:  3
 1083:                            0 - SSL Client
 1084:                            1 - SSL Server
 1085:                            2 - S/MIME
 1086:                            3 - Object Signing
 1087:                            4 - Reserved for futuer use
 1088:                            5 - SSL CA
 1089:                            6 - S/MIME CA
 1090:                            7 - Object Signing CA
 1091:                            Other to finish
 1092:  9
 1093:  Is this a critical extension &lt;/td&gt;[y/n]?
 1094:  n
 1095: </pre>
 1096:     <p>In <a href="#77046">Example 12-11</a>, the
 1097:     <i>certs.mozdev.org/signing</i> certificate references the
 1098:     <i>certs.mozdev.org</i> CA certificate. The Digital Signature
 1099:     option is also set so a signed remote Mozilla application can
 1100:     be compiled from the certificate.</p>
 1101:     <p>Export the signing certificate with the following
 1102:     command:</p>
 1103: <pre>
 1104: C:\NSS\bin&gt;certutil -L -d . -n "certs.mozdev.org/signing" -a
 1105: -o eric.cacert
 1106: </pre>
 1107:     <p>You can send the resulting file to the person who requested
 1108:     the Signing Certificate. That person can then use it to create
 1109:     signed remote applications, as described later in this chapter
 1110:     in the <a href="#77092">"Signing the application</a>"
 1111:     section.</p>
 1112:     <h3><a name="77087"></a> Distributing Distribution
 1113:     Certificates</h3>
 1114:     <p>The distribution 
 1115:     <!--INDEX distribution certificates:distributing --> 
 1116:     <!--INDEX certificates:distribution:distributing --> 
 1117:     <!--INDEX Certificate Authorities:distribution certificates:distributing -->
 1118:     <!--INDEX security:Certificate Authorities:distributing distribution certificates -->
 1119:     certificate (<i>certs_mozdev.cacert</i> in <a href=
 1120:     "#77044">Example 12-10</a>) must be installed into a user's
 1121:     Mozilla web browser before she can use signed applications that
 1122:     come from certificates you've distributed. It's best to state
 1123:     clearly on the web site hosting these signed remote Mozilla
 1124:     applications that the distribution certificate is needed. If
 1125:     you distribute many different signing certificates, and they
 1126:     are used by all signed remote Mozilla applications, then all
 1127:     applications can use that same distribution certificate (as
 1128:     they do with Verisign's and other certificate authorities).</p>
 1129:     <p>To allow users to install the distribution certificate,
 1130:     create a link to the certificate file on your web page:</p>
 1131: <pre>
 1132: &lt;a href="certs_mozdev.cacert"&gt;Install the MozDev CA Certificate&lt;/a&gt;
 1133: </pre>
 1134:     <p>Also make sure that your web server uses the MIME type
 1135:     <tt>application/x-x509-ca-cert</tt> for <i>.cacert</i>
 1136:     files.</p>
 1137:     <p>If the web server is set up correctly, the user will get a
 1138:     dialog box that looks like <a href="#77010">Figure 12-5</a>.
 1139:     Tell the user to select the options for "web sites" and
 1140:     "software developers."</p>
 1141:     <div class="c25">
 1142:       <img src="foo.gif">
 1143:     </div>
 1144:     <p><i>Figure 12-5: <a name="77010"></a></i> <i>Downloading a
 1145:     certificate window</i></p>
 1146:     <p>After the certificate is installed, it will appear in the
 1147:     Certificate Manager, as shown in <a href="#77012">Figure
 1148:     12-6</a>. The Certificate Manager can be accessed via the
 1149:     global Mozilla preferences (Edit &gt; Preferences &gt; Privacy
 1150:     &amp; Security &gt; Certificates). Mozilla is then ready to run
 1151:     signed remote Mozilla applications bearing signatures from your
 1152:     certificate authority.</p>
 1153:     <div class="c25">
 1154:       <img src="foo.gif">
 1155:     </div>
 1156:     <p><i>Figure 12-6: <a name="77012"></a></i> <i>Certificate
 1157:     manager with a certs.mozdev.org CA certificate</i></p>
 1158:     <h2><a name="77088"></a> Creating Signed Remote
 1159:     Applications</h2>
 1160:     <p>Security in Mozilla's 
 1161:     <!--INDEX remote applications:signed --> 
 1162:     <!--INDEX security:remote applications:signed --> web browser
 1163:     is designed to meet today's advanced scripting needs in a
 1164:     secure manner. Mozilla is a much more secure browser than past
 1165:     Netscape 4.x and Internet Explorer releases because it has a
 1166:     better sense of what remote scripts can and cannot do.</p>
 1167:     <p>Because of Mozilla's approach toward potentially insecure
 1168:     applications, if you decide to serve up your own application
 1169:     remotely, remember that you will not have automatic access to
 1170:     the chrome in the way you do when you have a registered,
 1171:     locally installed Mozilla application. Unless you sign your
 1172:     application or have the user turn on a special preference (see
 1173:     <a href="#77070">"Setting Up XPFE for Remote
 1174:     Applications</a>"), services like XPConnect will not be
 1175:     available.</p>
 1176:     <p>In Mozilla, you can bundle any number of files into a JAR
 1177:     archive (which, you'll recall from <a href=
 1178:     "ch06.html#77063">Chapter 6</a>, is just a zip file with a JAR
 1179:     suffix) and designate the archive as an object that can be
 1180:     signed. This designation makes it very easy to produce an
 1181:     entire signed and secure remote Mozilla application because it
 1182:     stores your application in a single file type that Mozilla
 1183:     already treats as a separate package.</p>
 1184:     <p>This section provides an overview of the signed script
 1185:     technology and shows you how to create signed applications that
 1186:     live on the server but take full advantage of the user's local
 1187:     chrome, including Mozilla components.</p>
 1188:     <h3><a name="77089"></a> certs.mozdev.org CA Certificate</h3>
 1189:     <p>Before users <!--INDEX installation:certificates --> 
 1190:     <!--INDEX certificates:installing --> 
 1191:     <!--INDEX remote applications:certificates:installing --> 
 1192:     <!--INDEX security:remote applications:installing certificates -->
 1193:     can load signed applications, a CA certificate must be
 1194:     installed into their installed copy of Mozilla. Once this
 1195:     certificate is installed in a browser, all MozDev-signed
 1196:     applications can work with this certificate. This setup makes
 1197:     things easier on users who access many of these signed
 1198:     applications because they do not have to install a new
 1199:     certificate for each one. Also, if the user wants to use
 1200:     applications from other certificate authorities, they need to
 1201:     install a distribution certificate from that certificate
 1202:     authority.</p>
 1203:     <p>Installing the certificate is easy. Just provide the users
 1204:     with a regular link on a web page-for example, <i><a href=
 1205:     "http://certs.mozdev.org/certs_mozdev.cacert">http://certs.mozdev.org/certs_mozdev.cacert</a></i>.
 1206:     When loading this page, a dialog box pops up and asks the user
 1207:     to install the certificate. See the <a href=
 1208:     "#77093">"Distributing the application</a>" section later in
 1209:     this chapter for more information about this process.</p>
 1210:     <h3><a name="77090"></a> Signing Certificates</h3>
 1211:     <p>As a Mozilla <!--INDEX signing certificates --> 
 1212:     <!--INDEX certificates:signing --> 
 1213:     <!--INDEX remote applications:certificates:signing --> 
 1214:     <!--INDEX security:remote applications:signing certificates -->
 1215:     application developer, you can obtain a common MozDev signing
 1216:     certificate and release a signed application that puts your
 1217:     application on par with other signed MozDev applications. If
 1218:     you consider your application mission-critical, however, you
 1219:     should go to a trusted CA such as Verisign. Mozilla already
 1220:     supports the VeriSign 
 1221:     <!--INDEX Netscape:Object Signing certificate --> Netscape
 1222:     Object Signing CA, and discriminating users may find it more
 1223:     acceptable. A few other CAs listed in Mozilla's Certificate
 1224:     Manager may support Netscape Object Signing, so researching
 1225:     these options further may be worthwhile.</p>
 1226:     <p>To get a <i>certs.mozdev.org/signing</i> certificate, send
 1227:     email to <i><a href=
 1228:     "MAILTO:cert-request@mozdev.org">cert-request@mozdev.org</a></i>.
 1229:     In return, you will receive a <i>.cacert</i> file that will be
 1230:     used to sign your remote Mozilla application.</p>
 1231:     <p>SignTool (part of the NSS tool sets) takes a directory of
 1232:     files, zips them up into a JAR archive (refer to the section <a
 1233:     href="#77092">"Signing the application</a>" later in this
 1234:     chapter to see how to do this), and signs the archive using the
 1235:     certificate you specify.</p>
 1236:     <blockquote>
 1237:       <div class="c26">
 1238:         NOTE
 1239:       </div>
 1240:       <p>SignTool comes with the latest release of NSS, Version
 1241:       3.4.1. On <i><a href=
 1242:       "http://certs.mozdev.org">http://certs.mozdev.org</a></i>,
 1243:       limited functionality versions of NSS contain SignTool for
 1244:       Windows and Linux that you can use instead for the processes
 1245:       in this book.</p>
 1246:     </blockquote>
 1247:     <p>Use CertUtil to set up a database for SignTool. Next, run
 1248:     some commands to set up the certificate environment:</p>
 1249: <pre>
 1250: C:\NSS\bin&gt;certutil -N -d .
 1251: C:\NSS\bin&gt;certutil -A -n "certs.mozdev.org/signing" -t ",,C"
 1252: -i eric.cacert -d .
 1253: </pre>
 1254:     <p>The first command creates an empty <i>cert7.db</i> file
 1255:     where certificates can be stored. The second imports your
 1256:     Signing Certificate into the database. SignTool can use only
 1257:     certificates that reside in a database, which is the reason for
 1258:     this process.</p>
 1259:     <h3><a name="77091"></a> Creating and Signing the
 1260:     Application</h3>
 1261:     <p>When someone <!--INDEX installation:certificates --> 
 1262:     <!--INDEX certificates:installing --> 
 1263:     <!--INDEX remote applications:certificates:installing --> 
 1264:     <!--INDEX security:remote applications:installing certificates -->
 1265:     obtains a private key (which is part of a Signing Certificate),
 1266:     they can encrypt their scripts and produce a public key. The
 1267:     relationship of the private key and the public key is called a 
 1268:     <!--INDEX private-public key pairs --> private-public key pair.
 1269:     Using this relationship, you can create a signed Mozilla
 1270:     application and make it available to users in three steps:</p>
 1271:     <ol>
 1272:       <li>
 1273:         Build the application itself, including the XUL, CSS,
 1274:         JavaScript, and whatever else you use to create the Mozilla
 1275:         application.
 1276:         <p>For this section, let's assume that you already created
 1277:         the XUL and JavaScript for the application and have all the
 1278:         files and directories together.</p>
 1279:       </li>
 1280:       <li>
 1281:         Archive and sign the application. SignTool takes care of
 1282:         both steps simultaneously, putting your application files
 1283:         in a JAR with a digital signature to validate everything.
 1284:         <p>The signing process described next in <a href=
 1285:         "#77092">"Signing the application</a>" deals entirely with
 1286:         SignTool.</p>
 1287:       </li>
 1288:       <li>Distribute your application (see the later section <a
 1289:       href="#77093">"Distributing the application</a>").</li>
 1290:     </ol>
 1291:     <h4><a name="77092"></a> Signing the application</h4>
 1292:     <p>Security is <!--INDEX remote applications:signing --> 
 1293:     <!--INDEX security:remote applications:signing --> 
 1294:     <!--INDEX signing applications --> not simple. Security
 1295:     technologists and vendors work hard to make sure that evildoers
 1296:     cannot abuse their encryption schemes, keys, and other tricks.
 1297:     Tools like SignTool can hide some of this complexity from you.
 1298:     When you sign an application, you create a digital signature in
 1299:     the archive that is based on the relationship of the files
 1300:     being signed, as <a href="#77014">Figure 12-7</a>
 1301:     illustrates.</p>
 1302:     <div class="c25">
 1303:       <img src="foo.gif">
 1304:     </div>
 1305:     <p><i>Figure 12-7: <a name="77014"></a></i> <i>SignTool's
 1306:     processes for creating a signed application</i></p>
 1307:     <p>SignTool automates these steps for you, so you don't worry
 1308:     about them. However, knowing these processes and seeing how
 1309:     these transactions take place can be useful, especially since
 1310:     using signed applications with Mozilla doesn't always work as
 1311:     expected and long-term directions for signed applications in
 1312:     Mozilla are uncertain. This uncertainty makes long-term
 1313:     deployment of signed remote Mozilla applications a risky
 1314:     option.</p>
 1315:     <p>To start off your remote Mozilla signed application
 1316:     development, you can do something as simple as place one XUL
 1317:     and one JavaScript file in a single directory. Then move it
 1318:     into a NSS <i>bin</i> directory such as <i>C:\NSS\bin</i> and
 1319:     issue the command:</p>
 1320: <pre>
 1321: C:\NSS\bin&gt;signtool -d . -k"certs.mozdev.org/signing"
 1322: -p"password_of_database" -Z"myapp.jar" myappfiles/
 1323: </pre>
 1324:     <p>The <tt>-d</tt> option is where the certificate database
 1325:     resides and <tt>-k</tt> is the certificate name.</p>
 1326:     <h4><a name="77093"></a> Distributing the application</h4>
 1327:     <p>Once the file is 
 1328:     <!--INDEX remote applications:distributing --> 
 1329:     <!--INDEX distribution:remote applications --> created from the
 1330:     <tt>-Z</tt> option (e.g., <i>myapp.jar</i> from the example
 1331:     above), you can put it online. On the application's web page,
 1332:     note that the application is signed and put a link to <i><a
 1333:     href=
 1334:     "http://certs.mozdev.org/certs_mozdev.cacert">http://certs.mozdev.org/certs_mozdev.cacert</a></i>
 1335:     so users can install the necessary MozDev certificate if they
 1336:     do not have it.</p>
 1337:     <p>To access the application online, you must use a special URL
 1338:     format. This format looks like <i>jar:<a href=
 1339:     "http://certs.mozdev.org/myapp.jar">http://certs.mozdev.org/myapp.jar</a>!/myapp.xul</i>
 1340:     and points into the JAR at the main application file. This URL
 1341:     is difficult to type, so it may be wise to link it for user
 1342:     access or set up a redirected URL to that address, as shown in
 1343:     <a href="#77048">Example 12-12</a>. Example 12-12<a name=
 1344:     "77048"></a> <i>Sample redirect into a signed
 1345:     application</i></p>
 1346: <pre>
 1347:  &lt;HTML&gt;
 1348:  &lt;HEAD&gt;
 1349:    &lt;META HTTP-EQUIV="REFRESH" CONTENT="0;
 1350:          URL= jar:<a href=
 1351: "http://certs.mozdev.org/sample.jar">http://certs.mozdev.org/sample.jar</a>!/sample.xul"&gt;
 1352:  &lt;/HEAD&gt;
 1353:  &lt;/HTML&gt;
 1354: </pre>
 1355:     <h3><a name="77094"></a> Receiving a Signed Application</h3>
 1356:     <p>As shown in <!--INDEX remote applications:receiving --> 
 1357:     <!--INDEX security:remote applications:receiving --> <a href=
 1358:     "#77016">Figure 12-8</a>, when Mozilla receives a JAR, it must
 1359:     check it for validity before displaying the contents. A public
 1360:     key in <i>certs_mozdev.cacert</i> must be used along with the
 1361:     digital signature to make sure that the contents are not
 1362:     tampered with and that the signature is valid.</p>
 1363:     <div class="c25">
 1364:       <img src="foo.gif">
 1365:     </div>
 1366:     <p><i>Figure 12-8: <a name="77016"></a></i> <i>Receiving a
 1367:     signed application</i></p>
 1368:     <blockquote>
 1369:       <div class="c26">
 1370:         WARNING
 1371:       </div>
 1372:       <p>When you are 
 1373:       <!--INDEX JAR (Java Archive) files:remote applications --> 
 1374:       <!--INDEX remote applications:updating, JAR files and -->
 1375:       developing a signed remote Mozilla application, clear a JAR's
 1376:       cache before trying to reload an updated version of it.
 1377:       Clearing the cache can be done most easily by restarting
 1378:       Mozilla. If you or your users do not do clear it, the
 1379:       consumer of the application will probably wind up with a
 1380:       blank screen.</p>
 1381:     </blockquote>
 1382:     <h2><a name="77095"></a> Expanded Privileges in Mozilla</h2>
 1383:     <p>While the security aspect 
 1384:     <!--INDEX privileges:remote applications --> 
 1385:     <!--INDEX remote applications:privileges --> 
 1386:     <!--INDEX security:remote applications:privileges --> of signed
 1387:     objects is nice, the ability to make remote Java-Script do just
 1388:     about anything is even better for web developers because it
 1389:     avoids the perceived complexity of languages like C++. Also,
 1390:     JavaScript, along with Perl and PHP, has always been a
 1391:     preferred language in the web environment.</p>
 1392:     <p>Knowing that Internet Explorer no longer has a huge
 1393:     advantage when it comes to remote browser-based applications is
 1394:     also nice, since JavaScript and XPCOM in Mozilla provide a
 1395:     framework very similar to ActiveX. They also provide web page
 1396:     scripting in which you can create and use components from a web
 1397:     page or web application.</p>
 1398:     <p><a href="#77022">Table 12-1</a> shows the expanded
 1399:     privileges available to signed scripts. Signed applications are
 1400:     granted these privileges as a matter of course.</p>
 1401:     <p><i>Table 12-1: <a name="77022"></a></i> <i>Expanded
 1402:     privileges available to signed scripts</i></p>
 1403:     <tt>navigator.preference</tt>method.<tt>navigator.preference</tt>method.<i>
 1404:     UniversalPreferencesRead/Write</i>.)<tt>window.open</tt>of
 1405:     <i>file://</i>URLs. Makes the browser upload files from the
 1406:     user's hard drive by using <tt>&lt;input type="file"&gt;</tt>.
 1407:     <table width="100%" border="1">
 1408:       <tr>
 1409:         <td><b>Privilege</b></td>
 1410:         <td><b>Purpose</b></td>
 1411:       </tr>
 1412:       <tr>
 1413:         <td>UniversalBrowserRead</td>
 1414:         <td>Reads sensitive browser data. This reading allows the
 1415:         script to pass the same origin check when reading from any
 1416:         document.</td>
 1417:       </tr>
 1418:       <tr>
 1419:         <td>UniversalBrowserWrite</td>
 1420:         <td>Modifies sensitive browser data. This modification
 1421:         allows the script to pass the same origin check when
 1422:         writing to any document.</td>
 1423:       </tr>
 1424:       <tr>
 1425:         <td>UniversalXPConnect</td>
 1426:         <td>Gives unrestricted access to browser APIs using
 1427:         XPConnect.</td>
 1428:       </tr>
 1429:       <tr>
 1430:         <td>UniversalPreferencesRead</td>
 1431:         <td>Reads preferences using the</td>
 1432:       </tr>
 1433:       <tr>
 1434:         <td>UniversalPreferencesWrite</td>
 1435:         <td>Allows you to set preferences using the</td>
 1436:       </tr>
 1437:       <tr>
 1438:         <td>CapabilityPreferencesAccess</td>
 1439:         <td>Allows you to read/set the preferences that define
 1440:         security policies, including which privileges are granted
 1441:         and denied to scripts. (You also need</td>
 1442:       </tr>
 1443:       <tr>
 1444:         <td>UniversalFileRead</td>
 1445:         <td>Handles</td>
 1446:       </tr>
 1447:     </table>
 1448:     <p>The JavaScript features require expanded privileges and the
 1449:     target used to access each feature. Unsigned scripts cannot do
 1450:     the following:</p>
 1451:     <ul>
 1452:       <li>Use an about: format URL other than <i>about:blank</i>;
 1453:       requires <i>Universal-BrowserRead</i>.</li>
 1454:       <li>Use the history object to find out what other sites the
 1455:       user visited or how many other sites the user visited in this
 1456:       session. Doing so requires <i>Universal-BrowserRead</i>.</li>
 1457:       <li>When using navigator object, get the preference value by
 1458:       using the preference method. Getting such a value requires
 1459:       <i>UniversalPreferencesRead</i>.</li>
 1460:       <li>Set the preference value using the preference method;
 1461:       getting this value requires
 1462:       <i>UniversalPreferencesWrite</i>.</li>
 1463:       <li>Add or remove the directory bar, location bar, menu bar,
 1464:       personal bar, scroll bar, status bar, or toolbar. These are
 1465:       done using the window object and require
 1466:       <i>UniversalBrowserWrite</i>.</li>
 1467:       <li>Use the methods and properties in the <a href=
 1468:       "#77024">Table 12-2</a> under the indicated
 1469:       circumstances.</li>
 1470:     </ul>
 1471:     <p><i>Table 12-2: <a name="77024"></a></i> <i>Expanded
 1472:     privileges available to signed scripts</i></p>
 1473:     <i>captureEvents</i>.* Creates a window smaller than 100 x 100
 1474:     pixels or larger than the screen can accommodate by using
 1475:     <i>innerWidth</i>, <i>innerHeight,</i><i>outerWidth</i>, and
 1476:     <i>outerHeight</i>.
 1477:     <table width="100%" border="1">
 1478:       <tr>
 1479:         <td><b>Method / property</b></td>
 1480:         <td><b>Description</b></td>
 1481:       </tr>
 1482:       <tr>
 1483:         <td>EnableExternalCapture</td>
 1484:         <td>Captures events in pages loaded from different servers.
 1485:         Follow this method with</td>
 1486:       </tr>
 1487:       <tr>
 1488:         <td>Close</td>
 1489:         <td>Unconditionally closes a browser window.</td>
 1490:       </tr>
 1491:       <tr>
 1492:         <td>moveBy, moveTo</td>
 1493:         <td>Moves a window off of the screen.</td>
 1494:       </tr>
 1495:       <tr>
 1496:         <td>Open</td>
 1497:       </tr>
 1498:     </table>
 1499:     <p>* Places a window offscreen by using <i>screenX</i> and
 1500:     <i>screenY</i>. * Creates a window without a titlebar by using
 1501:     <tt>titlebar=no</tt>. * Uses <i>alwaysRaised</i>,
 1502:     <i>alwaysLowered</i>, or z-lock for any setting.</p>
 1503:     <table width="100%" border="1">
 1504:       <tr>
 1505:         <td>resizeTo, resizeBy</td>
 1506:         <td>Resizes a window smaller than 100 x 100 pixels or
 1507:         larger than the screen can accommodate.</td>
 1508:       </tr>
 1509:       <tr>
 1510:         <td>innerWidth, innerHeight</td>
 1511:         <td>Sets the inner width of a window to a size smaller than
 1512:         100 x 100 or larger than the screen can accommodate.</td>
 1513:       </tr>
 1514:     </table>
 1515:     <p>This snippet of code shows how to use the privilege manager
 1516:     in JavaScript:</p>
 1517: <pre>
 1518: netscape.security.PrivilegeManager.
 1519:       enablePrivilege("UniversalBrowserWrite");
 1520: window.titlebar=no;
 1521: </pre>
 1522:     <p>You can pass any privilege listed in <a href="#77022">Table
 1523:     12-1</a> to the <tt>enablePrivilege</tt> method, which is
 1524:     accessed through the
 1525:     <tt>netscape.security.PrivilegeManager</tt> object. This object
 1526:     is recognized globally. In this example, the code hides the
 1527:     titlebar via the window object.</p>
 1528:     <p>Security is extremely important, so it is important that
 1529:     some means of granting special privileges to trusted scripts
 1530:     for accessing Mozilla components be available. In essence,
 1531:     signed scripts are Mozilla's version of ActiveX.</p>
 1532:     <p>The parallels become even more apparent when you consider
 1533:     access to XPConnect as one of the security model's main
 1534:     boundaries. Just as ActiveX makes COM available in IE, signing
 1535:     makes XPCOM available in remote Mozilla applications. Given all
 1536:     that is possible in XPCOM, this chapter leaves what can be
 1537:     archived with remote Mozilla applications and XPConnect up to
 1538:     your imagination.</p>
 1539:     <h2><a name="77096"></a> Signed Remote Snake Game</h2>
 1540:     <p>In this section, we look at an enhanced version of the Snake
 1541:     game presented earlier in the chapter. The enhanced version
 1542:     uses XPConnect to provide a total full-screen display of the
 1543:     game on the Windows platform as a remote application.</p>
 1544:     <h3><a name="77097"></a> How to Expand Mozilla to Full
 1545:     Screen</h3>
 1546:     <p>The best way to <!--INDEX full-screen mode, enabling --> 
 1547:     <!--INDEX remote applications:Snake game:expanding to full screen -->
 1548:     <!--INDEX Snake game:expanding to full screen --> 
 1549:     <!--INDEX games:expanding to full screen --> expand Mozilla to
 1550:     a full screen mode is through full-screen functions provided in
 1551:     an instance of <i>navigator.xul</i>. These functions run in the
 1552:     Windows build of Mozilla via the Full Screen item in the View
 1553:     menu. These functions also work in Linux and Mac, but do not
 1554:     provide 100% full-screen mode, as some menus and titlebars
 1555:     still show.</p>
 1556:     <p>The problem here is the current window's
 1557:     <i>navigator.xul</i> document, which needs to be accessed to
 1558:     get these full-screen functions. A document loaded in that
 1559:     window just can't use something like <i>window.parent</i> to
 1560:     get to it, so another route must be found.</p>
 1561:     <p>This route runs through the <i>nsIWindowMediator</i>
 1562:     interface by the way of XPConnect. It gives access to the
 1563:     current browser window's <i>navigator.xul</i> document's window
 1564:     object. <a href="#77050">Example 12-13</a> includes the code
 1565:     for this window access process, along with the functions used
 1566:     to create the full-screen effect. Example 12-13<a name=
 1567:     "77050"></a> <i>Function for switching screen modes</i></p>
 1568: <pre>
 1569:  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 1570:  const MEDIATOR_CONTRACTID="@mozilla.org/appshell/window-mediator;1";
 1571:  const nsIWindowMediator=Components.interfaces.nsIWindowMediator;
 1572:  var windowManager=
 1573:      Components.classes&lt;/td&gt;[MEDIATOR_CONTRACTID].getService(nsIWindowMediator);
 1574:  var hideSidebar=true;
 1575:  var isRegular=true;
 1576:  function switchScreen( )
 1577:  {
 1578:    if(isRegular)
 1579:    {
 1580:      try {
 1581:        netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 1582:        mainWindow = windowManager.getMostRecentWindow("navigator:browser");
 1583:      }
 1584:      catch(e) {
 1585:        alert(e);
 1586:      }
 1587:      if(mainWindow.sidebar_is_hidden( ))
 1588:        hideSidebar=false;
 1589:      if(hideSidebar)
 1590:        mainWindow.SidebarShowHide( );
 1591:      mainWindow.BrowserFullScreen( );
 1592:      window.fullScreen=true;
 1593:      window.locationbar.visible=false;
 1594:      window.toolbar.visible=false;
 1595:      isRegular=false;
 1596:    }
 1597:    else
 1598:    {
 1599:      try {
 1600:          netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 1601:        mainWindow = windowManager.getMostRecentWindow("navigator:browser");
 1602:      }
 1603:      catch(e) {
 1604:        alert(e);
 1605:      }
 1606:      window.locationbar.visible=true;
 1607:      window.toolbar.visible=true;
 1608:      if(hideSidebar)
 1609:        mainWindow.SidebarShowHide( );
 1610:      mainWindow.BrowserFullScreen( );
 1611:      isRegular=true;
 1612:    }
 1613:  }
 1614: </pre>
 1615:     <p><tt>windowManager</tt>, which is spawned by XPConnect,
 1616:     creates the <i>mainWindow</i> variable. By using the
 1617:     <tt>getMostRecentWindow</tt> function for
 1618:     <tt>navigator:browser</tt>, the Mozilla application window you
 1619:     currently use becomes available. Next, tests are made in code
 1620:     for the window status determine if it is regular or full
 1621:     screen. Appropriate action can then be made by calling the
 1622:     <tt>SidebarShowHide</tt> function.</p>
 1623:     <p>As you can see in <a href="#77050">Example 12-13</a>, code
 1624:     for hiding the toolbar and location bar is also present. This
 1625:     code is accomplished not by the <i>mainWindow</i> created
 1626:     through XPConnect, but by the existing window object:</p>
 1627: <pre>
 1628: window.locationbar.visible=false;
 1629: window.toolbar.visible=false;
 1630: </pre>
 1631:     <p>Using both the <tt>mainWindow</tt> and <tt>window</tt>
 1632:     objects allows the creation of a full-screen remote Mozilla
 1633:     application by allowing XPConnect privileges. <a href=
 1634:     "#77018">Figure 12-9</a> shows the result on Windows-a total
 1635:     full screen for a signed remote Mozilla game!</p>
 1636:     <div class="c25">
 1637:       <img src="foo.gif">
 1638:     </div>
 1639:     <p><i>Figure 12-9: <a name="77018"></a></i> <i>Snake game in
 1640:     full-screen mode on Windows</i></p>
 1641:     <h2><a name="77098"></a> Mozilla's XML Extras and SOAP</h2>
 1642:     <p>Mozilla has built functions called <!--INDEX XML Extras --> 
 1643:     <!--INDEX web sites:XML Extras --> XML Extras that allow the
 1644:     use of XML as data in both JavaScript and C++. Such functions
 1645:     are an XML Serializer, XMLHttpRequest, XML Parser, SOAP-based
 1646:     RPC, and XML Persistence. You can find more information about
 1647:     these functions, along with examples, at <i><a href=
 1648:     "http://www.mozilla.org/xmlextras/">http://www.mozilla.org/xmlextras/</a></i>.</p>
 1649:     <p>The following sections assume that you are familiar with
 1650:     SOAP and .NET. If not, some good O'Reilly books available on
 1651:     these subjects can help get you started.</p>
 1652:     <h3><a name="77099"></a> Mozilla, SOAP, and .NET</h3>
 1653:     <p>In this section, SOAP is used to access data in a .NET web
 1654:     service, therefore allowing the Snake game to have features
 1655:     such as a saved game score, a retrieved game score, and a list
 1656:     of high scores.</p>
 1657:     <blockquote>
 1658:       <div class="c26">
 1659:         NOTE
 1660:       </div>
 1661:       <p>As of Mozilla 1.0, the SOAP functions of Mozilla do not
 1662:       work in signed scripts. This bug will be corrected in the
 1663:       future. All JavaScript using SOAP functions in this section
 1664:       is loaded externally of the signed JAR. These SOAP functions
 1665:       do not require enhanced privileges.</p>
 1666:     </blockquote>
 1667:     <h3><a name="77100"></a> Setting Up a .NET Web Service</h3>
 1668:     <p>The easiest <!--INDEX Snake game:.NET web service --> 
 1669:     <!--INDEX .NET web service, setting up[NET web service, setting up] -->
 1670:     <!--INDEX remote applications:Snake game:setting up .Net web service -->
 1671:     <!--INDEX games:Snake:setting up .NET web service --> way 
 1672:     <!--INDEX SOAP:.NET web service, setting up[SOAP:NET web service, setting up] -->
 1673:     to create a .NET web service is through Visual Studio.NET,
 1674:     which provides a template for creating these services. <a href=
 1675:     "#77052">Example 12-14</a> shows a bare minimum of C# code used
 1676:     to compile the functions that return a value to the Snake
 1677:     game.</p>
 1678:     <p>Obviously, a full implementation would need a database to
 1679:     store these scores. For this section, seeing how the interfaces
 1680:     work for these SOAP functions is more important. Example
 1681:     12-14<a name="77052"></a> <i>Minimal .NET web service</i></p>
 1682: <pre>
 1683:  using System;
 1684:  using System.Collections;
 1685:  using System.ComponentModel;
 1686:  using System.Data;
 1687:  using System.Diagnostics;
 1688:  using System.Web;
 1689:  using System.Web.Services;
 1690:  namespace SnakeService
 1691:  {
 1692:      &lt;/td&gt;[WebServiceAttribute (Namespace="uri:SnakeScore")]
 1693:      public class SnakeService : System.Web.Services.WebService
 1694:      {
 1695:          public SnakeService( )
 1696:          {
 1697:              InitializeComponent( );
 1698:          }
 1699:          #region Component Designer generated code
 1700:          private IContainer components = null;
 1701:          private void InitializeComponent( ){}
 1702:          protected override void Dispose( bool disposing )
 1703:          {
 1704:              if(disposing &amp;&amp; components != null)
 1705:              {
 1706:                  components.Dispose( );
 1707:              }
 1708:              base.Dispose(disposing);
 1709:          }
 1710:          #endregion
 1711:          &lt;/td&gt;[WebMethod]
 1712:          public string SaveScore(string PlayerName, string Score)
 1713:          {
 1714:              return "Save of score successful.";
 1715:          }
 1716:           &lt;/td&gt;[WebMethod]
 1717:          public string GetScore(string PlayerName)
 1718:          {
 1719:              int Score = 990;
 1720:              return Score.ToString( );
 1721:          }
 1722:          &lt;/td&gt;[WebMethod]
 1723:          public string GetHighScores( )
 1724:          {
 1725:              return "EDM 1000,SLK 200,BRP 10";
 1726:          }
 1727:      }
 1728:  }
 1729: </pre>
 1730:     <p>The most important part of <a href="#77052">Example
 1731:     12-14</a> is the <tt>WebServiceAttribute</tt> because it sets
 1732:     up a URI reference to the <tt>SnakeService</tt> object. When a
 1733:     request is sent from the Snake game to the .NET
 1734:     <tt>SnakeService</tt>, <tt>uri:SnakeScore</tt> becomes the name
 1735:     for the object providing functions for getting and setting the
 1736:     game's score.</p>
 1737:     <p>In <a href="#77052">Example 12-14</a>, all the parameter and
 1738:     return values are of the <tt>string</tt> type. Considering the
 1739:     brevity of this example, expanding it would not be hard.
 1740:     Functions using other objects and database connections would
 1741:     really make it a true web application.</p>
 1742:     <h3><a name="77101"></a> .NET WSDL</h3>
 1743:     <p>.NET automatically <!--INDEX WSDL, generating --> 
 1744:     <!--INDEX Snake game:WSDL, generating --> 
 1745:     <!--INDEX games:Snake:generating WSDL --> generates WSDL
 1746:     interfaces inside a web service. Mozilla SOAP doesn't need to
 1747:     reference a WDSL file to make SOAP transactions.</p>
 1748:     <p><a href="#77054">Example 12-15</a> is a portion of the WDSL
 1749:     that .NET generates and is the specific portion that relates
 1750:     directly to sending raw SOAP calls to the
 1751:     <tt>SnakeService</tt>. Also, only the definitions for the
 1752:     <tt>GetScore</tt> function are in this abbreviated definition.
 1753:     Example 12-15<a name="77054"></a> <i>Abbreviated WSDL as
 1754:     produced by .NET web service.</i></p>
 1755: <pre>
 1756:  &lt;?xml version="1.0" encoding="utf-8"?&gt;
 1757:  &lt;definitions
 1758:     xmlns:http="<a href=
 1759: "http://schemas.xmlsoap.org/wsdl/http/">http://schemas.xmlsoap.org/wsdl/http/</a>"
 1760:     xmlns:soap="<a href=
 1761: "http://schemas.xmlsoap.org/wsdl/soap/">http://schemas.xmlsoap.org/wsdl/soap/</a>"
 1762:     xmlns:s="<a href=
 1763: "http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>" xmlns:s0="uri:SnakeScore"
 1764:     xmlns:soapenc="<a href=
 1765: "http://schemas.xmlsoap.org/soap/encoding/">http://schemas.xmlsoap.org/soap/encoding/</a>"
 1766:     xmlns:tm="<a href=
 1767: "http://microsoft.com/wsdl/mime/textMatching/">http://microsoft.com/wsdl/mime/textMatching/</a>"
 1768:     xmlns:mime="<a href=
 1769: "http://schemas.xmlsoap.org/wsdl/mime/">http://schemas.xmlsoap.org/wsdl/mime/</a>"
 1770:     targetNamespace="uri:SnakeScore"
 1771:     xmlns="<a href=
 1772: "http://schemas.xmlsoap.org/wsdl/">http://schemas.xmlsoap.org/wsdl/</a>"&gt;
 1773:    &lt;types&gt;
 1774:      &lt;s:schema elementFormDefault="qualified"
 1775:                targetNamespace="uri:SnakeScore"&gt;
 1776:        &lt;s:element name="GetScore"&gt;
 1777:          &lt;s:complexType&gt;
 1778:            &lt;s:sequence&gt;
 1779:              &lt;s:element minOccurs="0" maxOccurs="1" name="PlayerName"
 1780:                         type="s:string" /&gt;
 1781:            &lt;/s:sequence&gt;
 1782:          &lt;/s:complexType&gt;
 1783:        &lt;/s:element&gt;
 1784:        &lt;s:element name="GetScoreResponse"&gt;
 1785:          &lt;s:complexType&gt;
 1786:            &lt;s:sequence&gt;
 1787:              &lt;s:element minOccurs="0" maxOccurs="1" name="GetScoreResult"
 1788:                         type="s:string" /&gt;
 1789:            &lt;/s:sequence&gt;
 1790:          &lt;/s:complexType&gt;
 1791:        &lt;/s:element&gt;
 1792:      &lt;/s:schema&gt;
 1793:    &lt;/types&gt;
 1794:    &lt;message name="GetScoreSoapIn"&gt;
 1795:      &lt;part name="parameters" element="s0:GetScore" /&gt;
 1796:    &lt;/message&gt;
 1797:    &lt;message name="GetScoreSoapOut"&gt;
 1798:      &lt;part name="parameters" element="s0:GetScoreResponse" /&gt;
 1799:    &lt;/message&gt;
 1800:    &lt;portType name="SnakeServiceSoap"&gt;
 1801:      &lt;operation name="GetScore"&gt;
 1802:        &lt;input message="s0:GetScoreSoapIn" /&gt;
 1803:        &lt;output message="s0:GetScoreSoapOut" /&gt;
 1804:      &lt;/operation&gt;
 1805:    &lt;/portType&gt;
 1806:    &lt;binding name="SnakeServiceSoap" type="s0:SnakeServiceSoap"&gt;
 1807:      &lt;soap:binding transport="<a href=
 1808: "http://schemas.xmlsoap.org/soap/http">http://schemas.xmlsoap.org/soap/http</a>"
 1809:                    style="document" /&gt;
 1810:      &lt;operation name="GetScore"&gt;
 1811:        &lt;soap:operation soapAction="uri:SnakeScore/GetScore"
 1812:                        style="document" /&gt;
 1813:        &lt;input&gt;
 1814:          &lt;soap:body use="literal" /&gt;
 1815:        &lt;/input&gt;
 1816:        &lt;output&gt;
 1817:          &lt;soap:body use="literal" /&gt;
 1818:        &lt;/output&gt;
 1819:      &lt;/operation&gt;
 1820:    &lt;/binding&gt;
 1821:    &lt;service name="SnakeService"&gt;
 1822:      &lt;port name="SnakeServiceSoap" binding="s0:SnakeServiceSoap"&gt;
 1823:        &lt;soap:address
 1824:           location="<a href=
 1825: "http://localhost/SnakeService/SnakeService.asmx">http://localhost/SnakeService/SnakeService.asmx</a>" /&gt;
 1826:      &lt;/port&gt;
 1827:    &lt;/service&gt;
 1828:  &lt;/definitions&gt;
 1829: </pre>
 1830:     <p>The most important thing to notice in this WSDL is the
 1831:     <tt>soapAction</tt>. In <a href="#77054">Example 12-15</a>,
 1832:     <tt>uri:SnakeScore/GetScore</tt> is defined as the identifier
 1833:     for the <tt>SnakeScore</tt> object's <tt>GetScore</tt>
 1834:     function. This identifier makes the call to this function in <a
 1835:     href="#77062">Example 12-19</a>.</p>
 1836:     <h3><a name="77102"></a> SOAP Call XML Formats</h3>
 1837:     <p>When .NET and <!--INDEX SOAP:XML formats --> 
 1838:     <!--INDEX XML (Extensible Markup Language):SOAP call formats -->
 1839:     Mozilla serialize SOAP calls, they produce different XML
 1840:     formats. The namespace prefixes differ, and Mozilla produces
 1841:     more of these namespaces in its version of the SOAP message.
 1842:     However, the code comparison in Examples 12-16 and 12-17 mean
 1843:     fundamentally the same thing. Thus, .NET and Mozilla are able
 1844:     to communicate. Example 12-16<a name="77056"></a> <i>XML format
 1845:     for SOAP calls of Mozilla</i></p>
 1846: <pre>
 1847:  &lt;env:Envelope
 1848:     xmlns:env="<a href=
 1849: "http://schemas.xmlsoap.org/soap/envelope/">http://schemas.xmlsoap.org/soap/envelope/</a>"
 1850:     xmlns:enc="<a href=
 1851: "http://schemas.xmlsoap.org/soap/encoding/">http://schemas.xmlsoap.org/soap/encoding/</a>"
 1852:     env:encodingStyle="<a href=
 1853: "http://schemas.xmlsoap.org/soap/encoding/">http://schemas.xmlsoap.org/soap/encoding/</a>"
 1854:     xmlns:xs="<a href=
 1855: "http://www.w3.org/1999/XMLSchema">http://www.w3.org/1999/XMLSchema</a>"
 1856:     xmlns:xsi="<a href=
 1857: "http://www.w3.org/1999/XMLSchema-instance">http://www.w3.org/1999/XMLSchema-instance</a>"&gt;
 1858:    &lt;env:Header/&gt;
 1859:    &lt;env:Body&gt;
 1860:      &lt;a0:SaveScore xmlns:a0="uri:SnakeScore"&gt;
 1861:        &lt;PlayerName xsi:type="xs:string"&gt;EDM&lt;/PlayerName&gt;
 1862:        &lt;Score xsi:type="xs:string"&gt;10&lt;/Score&gt;
 1863:      &lt;/a0:SaveScore&gt;
 1864:    &lt;/env:Body&gt;
 1865:  &lt;/env:Envelope&gt;
 1866: </pre>
 1867:     Example 12-17<a name="77058"></a> <i>.NET format for SOAP calls
 1868:     of Mozilla</i> 
 1869: <pre>
 1870:  &lt;soap:Envelope
 1871:     xmlns:xsi="<a href=
 1872: "http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"
 1873:     xmlns:xsd="<a href=
 1874: "http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>"
 1875:     xmlns:soap="<a href=
 1876: "http://schemas.xmlsoap.org/soap/envelope/">http://schemas.xmlsoap.org/soap/envelope/</a>"&gt;
 1877:    &lt;soap:Body&gt;
 1878:      &lt;SaveScore xmlns="uri:SnakeScore"&gt;
 1879:        &lt;PlayerName&gt;EDM&lt;/PlayerName&gt;
 1880:        &lt;Score&gt;10&lt;/Score&gt;
 1881:      &lt;/SaveScore&gt;
 1882:    &lt;/soap:Body&gt;
 1883:  &lt;/soap:Envelope&gt;
 1884: </pre>
 1885:     <p>Realizing these formatting differences in Examples 12-16 and
 1886:     12-17 is important because if you develop with SOAP by using
 1887:     .NET and Mozilla, you are bound to run across variations in
 1888:     your future software projects. Luckily the W3C has set a
 1889:     standard that Mozilla and Microsoft adheres to.</p>
 1890:     <h3><a name="77103"></a> Adding SnakeService SOAP to Snake</h3>
 1891:     <p>Developers <!--INDEX JavaScript:SOAP and --> 
 1892:     <!--INDEX SOAP:JavaScript and --> use built-in methods to just
 1893:     write JavaScript and use SOAP easily. There is no need for
 1894:     enhanced privileges because nothing could affect the client
 1895:     adversely. However, there are some limitations on how SOAP
 1896:     JavaScript is used.</p>
 1897:     <p>Mozilla sets one level of security 
 1898:     <!--INDEX security:SOAP and JavaScript --> with the SOAP
 1899:     function by requiring that the web service and the JavaScript
 1900:     file that makes the SOAP functions access that service be on
 1901:     the same domain. For example, you will not encounter problems
 1902:     when running everything as localhost (as shown in the
 1903:     examples). If you try to move the JavaScript files to
 1904:     mozdev.org, though, they will no longer work.</p>
 1905:     <p>Another limitation of the SOAP functions is that they can't
 1906:     be used directly in XUL documents. However, a hack, discussed
 1907:     in the next section, can get around this limitation.</p>
 1908:     <h3><a name="77104"></a> Make SOAP Functions Work in XUL
 1909:     Documents</h3>
 1910:     <p>The best way to <!--INDEX SOAP:functions:XUL documents --> 
 1911:     <!--INDEX functions:SOAP:XUL documents --> 
 1912:     <!--INDEX XUL (XML-based User-interface Language):SOAP functions -->
 1913:     circumvent the SOAP-in-XUL-documents problem in Mozilla 1.0
 1914:     (and probably 1.1) is to initially load the JavaScript file
 1915:     containing the SOAP functions from an HTML file, as shown in <a
 1916:     href="#77060">Example 12-18</a>. Example 12-18<a name=
 1917:     "77060"></a> <i>Preloading scores.js into cache with an HTML
 1918:     association</i></p>
 1919: <pre>
 1920:  &lt;html&gt;
 1921:  &lt;head&gt;
 1922:    &lt;script src="<a href=
 1923: "http://localhost/nss/bin/scores.js">http://localhost/nss/bin/scores.js</a>"&gt;&lt;/script&gt;
 1924:  &lt;/head&gt;
 1925:  &lt;body&gt;
 1926:    &lt;script&gt;
 1927:  window.location.href="jar:<a href=
 1928: "http://localhost/nss/bin/snake.jar">http://localhost/nss/bin/snake.jar</a>!/scores.xul";
 1929:    &lt;/script&gt;
 1930:  &lt;/body&gt;
 1931:  &lt;/html&gt;
 1932: </pre>
 1933:     <p>As stated earlier, <i>scores.js</i> (containing the SOAP
 1934:     functions) must exist outside the JAR file. It is loaded up
 1935:     into cache with this HTML document, and then the page redirects
 1936:     to the XUL file that has the SOAP function user interface. That
 1937:     JavaScript file is already loaded up in cache and will work
 1938:     fine.</p>
 1939:     <p>Remember that doing this is a hack, but later versions of
 1940:     Mozilla that fix the SOAP-in-XUL-document problem would still
 1941:     not break this code.</p>
 1942:     <h3><a name="77105"></a> Examining SOAP Functions for
 1943:     Snake</h3>
 1944:     <p><a href="#77062">Example 12-19</a> shows 
 1945:     <!--INDEX SOAP:functions:Snake game --> 
 1946:     <!--INDEX functions:SOAP:Snake game --> 
 1947:     <!--INDEX Snake game:SOAP functions --> 
 1948:     <!--INDEX games:Snake:SOAP functions --> how to create two
 1949:     functions (<tt>SaveScore</tt> and <tt>SaveScoreResponse</tt>)
 1950:     to handle SOAP transactions with the previously examined .NET
 1951:     web service. Example 12-19<a name="77062"></a> <i>SaveScore
 1952:     SOAP function</i></p>
 1953: <pre>
 1954:  const soapVersion  = 0; // Version 1.1
 1955:  const object       = "uri:SnakeScore";
 1956:  const transportURI = "<a href=
 1957: "http://localhost/SnakeService/SnakeService.asmx">http://localhost/SnakeService/SnakeService.asmx</a>";
 1958:  // SAVE PLAYER SCORE
 1959:  function SaveScore( )
 1960:  {
 1961:    var Score = window.opener.document.getElementById("currentscore").getAttribute("value");
 1962:    var PlayerName  = document.getElementById("saveInitials").value;
 1963:    var method  = "SaveScore";
 1964:    var headers = new Array( );
 1965:    var params  = new Array(new SOAPParameter(PlayerName,"PlayerName"),
 1966:                  new SOAPParameter(Score,"Score"));
 1967:    var call = new SOAPCall( );
 1968:    call.transportURI = transportURI;
 1969:    call.actionURI = object+"/"+method;
 1970:    call.encode(soapVersion,method,object,headers.length,headers,params.length,params);
 1971:    var currentRequest = call.asyncInvoke(SaveScoreResponse);
 1972:  }
 1973:  function SaveScoreResponse(resp,call,status)
 1974:  {
 1975:    // Display confirmation
 1976:    // Part of content of SOAP message returned
 1977:    alert(resp.body.firstChild.firstChild.firstChild.data);
 1978:  }
 1979: </pre>
 1980:     <p>The <tt>object</tt> defined here is the same as the
 1981:     namespace defined in <a href="#77052">Example 12-14</a>. Again,
 1982:     this snake score object (<tt>uri:SnakeScore</tt>) is simply an
 1983:     identifier to that exact web service. The <tt>transportURI</tt>
 1984:     is the location of the web service. As you can see here, it
 1985:     runs localhost along with the files for the Snake remote
 1986:     Mozilla application. Moving into the actual <tt>SaveScore</tt>
 1987:     function, a <tt>PlayerName</tt> is pulled from a
 1988:     <tt>&lt;textbox&gt;</tt> in the XUL.</p>
 1989:     <p>The <tt>method</tt> is the name of the function in the .NET
 1990:     web service with which this code will communicate.
 1991:     <tt>headers</tt> is an empty array because no SOAP headers are
 1992:     needed for this simple example. Two <tt>SOAPParameter</tt>s are
 1993:     also defined here in an array, and they are just simple
 1994:     strings. Moving on down the code in <a href="#77062">Example
 1995:     12-19</a>, a new <tt>SOAPCall( )</tt> is defined into the call
 1996:     variable. Two URIs are set up for this <tt>SOAPCall</tt>
 1997:     object: <tt>call.transportURI</tt> and <tt>call.actionURI</tt>,
 1998:     which combines an object and a method into one string. The next
 1999:     two lines, <tt>encode</tt> and <tt>asyncInvoke</tt> the
 2000:     <tt>SOAPCall</tt> and the encoded XML message, as shown in
 2001:     Examples <a href="#77056">12-16</a> and <a href=
 2002:     "#77058">12-17</a>, are sent to the .NET web service. When a
 2003:     response is received, the <tt>SaveScoreResponse</tt> function
 2004:     is called.</p>
 2005:     <p>Currently, a hack is used in <tt>SaveScoreResponse</tt> so a
 2006:     DOM property accesses the XML of the returned SOAP message.
 2007:     This implementation is not the best way, but the optimal way
 2008:     doesn't currently work. Here is an easy version of the
 2009:     code:</p>
 2010: <pre>
 2011: ret = resp.getParameters(false, new Array( ));
 2012: alert(ret[0]);
 2013: </pre>
 2014:     <p>If you put this code in <tt>SaveScoreResponse</tt> and it
 2015:     works, it could replace the code in Examples 12-16 and 12-17.
 2016:     You need to play around with these different SOAP functions and
 2017:     see what works for you. Again, the code just shown does not
 2018:     work in Mozilla 1.0, but will hopefully work in all future
 2019:     versions of Mozilla.</p>
 2020:     <p><a href="#77064">Example 12-20</a> shows the code for
 2021:     GetResponse and GetHighScores. Compare the JavaScript code to
 2022:     the code and WSDL in Examples 12-14 and 12-15 to see how they
 2023:     all work together. Example 12-20<a name="77064"></a> <i>Code
 2024:     for GetScore and GetHighScores</i></p>
 2025: <pre>
 2026:  // GET PLAYER SCORE
 2027:  var ScoreElement; // Make this accessible to GetScoreResponse
 2028:  function GetScore( )
 2029:  {
 2030:    ScoreElement = window.opener.document.getElementById("currentscore");
 2031:    var PlayerName = document.getElementById("getInitials").value;
 2032:    var method  = "GetScore";
 2033:    var headers = new Array( );
 2034:    var params  = new Array(new SOAPParameter(PlayerName,"PlayerName"));
 2035:    var call = new SOAPCall( );
 2036:    call.transportURI = transportURI;
 2037:    call.actionURI = object+"/"+method;
 2038:    call.encode(soapVersion,method,object,headers.length,headers,params.length,params);
 2039:    var currentRequest = call.asyncInvoke(GetScoreResponse);
 2040:  }
 2041:  function GetScoreResponse(resp,call,status)
 2042:  {
 2043:    ScoreElement.setAttribute("value",resp.body.firstChild.firstChild.firstChild.data);
 2044:    alert("Your score has been reinstated. You can now return to the game.");
 2045:  }
 2046:  // GET HIGH SCORES
 2047:  function GetHighScores( )
 2048:  {
 2049:    var method  = "GetHighScores";
 2050:    var headers = new Array( );
 2051:    var params  = new Array( );
 2052:    var call = new SOAPCall( );
 2053:    call.transportURI = transportURI;
 2054:    call.actionURI = object+"/"+method;
 2055:    call.encode(soapVersion,method,object,headers.length,headers,params.length,params);
 2056:    var currentRequest = call.asyncInvoke(GetHighScoresResponse);
 2057:  }
 2058:  function GetHighScoresResponse(resp,call,status)
 2059:  {
 2060:    alert(resp.body.firstChild.firstChild.firstChild.data);
 2061:  }
 2062: </pre>
 2063:     <p><a href="#77020">Figure 12-10</a> shows how the XUL
 2064:     interface to these functions in <a href="#77064">Example
 2065:     12-20</a> is designed. Here the score is replaced with "990,"
 2066:     as this number is pulled from the code shown in <a href=
 2067:     "#77052">Example 12-14</a>.</p>
 2068:     <div class="c25">
 2069:       <img src="foo.gif">
 2070:     </div>
 2071:     Figure 12-10<a name="77020"></a> <i>Result of using the
 2072:     GetScore function</i> 
 2073:     <h2><a name="77106"></a> Looking Forward</h2>
 2074:     <p>This chapter focuses on just one of many new trends outside
 2075:     of the original project mandate that emerged in the Mozilla
 2076:     developer community. Now that Mozilla 1.0 is released, its
 2077:     future direction will be shaped by the community itself, and
 2078:     Mozilla will become whatever the community would like it to
 2079:     be.</p>
 2080:     <p>Remote applications are definitely one area of Mozilla
 2081:     development that will get more attention as Mozilla matures.
 2082:     Other areas that will probably also be noticed include
 2083:     development tools (some existing development tools are
 2084:     discussed in <a href="appb.html#78077">Appendix B</a>),
 2085:     embedding, SVG support, and XSLT support.</p>
 2086:     <p>Remember that Mozilla is open to new ideas and is always
 2087:     looking for contributions. If you can think of a way to improve
 2088:     Mozilla, or if you think of something that should be added,
 2089:     become a part of the community and help expand the
 2090:     possibilities of Mozilla and all Mozilla applications.</p>
 2091:     <hr>
 2092:     <br>
 2093:     <br>
 2094:     File a <a href=
 2095:     "http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a>
 2096:     for chapter 12. 
 2097:     <?php $hide_text_control=1; $post_to_list=NO; $author='reviewers@mozdev.org'; // require(NOTES); ?>

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>