commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnue] r8154 - trunk/gnue-appserver/extensions/webfrontend


From: jan
Subject: [gnue] r8154 - trunk/gnue-appserver/extensions/webfrontend
Date: Thu, 9 Feb 2006 09:48:32 -0600 (CST)

Author: jan
Date: 2006-02-09 09:48:31 -0600 (Thu, 09 Feb 2006)
New Revision: 8154

Added:
   trunk/gnue-appserver/extensions/webfrontend/rpcproxy.cgi
Modified:
   trunk/gnue-appserver/extensions/webfrontend/README
   trunk/gnue-appserver/extensions/webfrontend/gnue-forms.js
   trunk/gnue-appserver/extensions/webfrontend/vcXMLRPC.js
Log:
updated webfrontend to work with last production appserver (0.4.3)
add proxy to circumvent removed direct download ability from appserver
correct error handling in vcXMLRPC


Modified: trunk/gnue-appserver/extensions/webfrontend/README
===================================================================
--- trunk/gnue-appserver/extensions/webfrontend/README  2006-02-06 19:33:53 UTC 
(rev 8153)
+++ trunk/gnue-appserver/extensions/webfrontend/README  2006-02-09 15:48:31 UTC 
(rev 8154)
@@ -9,49 +9,39 @@
 -------------
 
 Server side:
-GNUe Appserver (>0.0.4)
+GNUe Appserver (<=0.4.3)  * Changes in CVS after 0.4.3 not adapted yet (switch 
to object rpc)
 GNUe Common (>0.5.0)
 
 client side:
 Mozilla or other Gecko based Browser
-or IE > 5.0
+or IE > 5.0 
 
 (Konqueror or Opera don't work because of missing XMLRPC functionality)
+* IE currently broken
 
 Installation:
 -------------
 
 1. Install GNUe Appserver
 
-2. Copy the contents of this directory into a directory of your choice. 
-   I would recommend: /usr/share/gnue/webfrontend/ for global and
-   ~/gnue/webfrontend/ for a local install.
+2. Setup a webserver and copy the rpcproxyi.cgi script to your webserver.
+   It has to be available at http://<host>/cgi-bin/rpcproxy.cgi .
 
-3. Then add the option 'httpdir' in the [appserver] group of gnue.conf.
-   set it to the path of the directory where you have copied the files to.
-   f.e.
+3. Add the hostname to the list of allowed services in the beginning of the
+   rpcproxy.cgi file.
 
-   [appserver]
-   httpdir = /usr/share/gnue/webfrontend/   or
-   
-   httpdir = ~/gnue/webfrontend/
+4. Add sample.html, gnue-forms.js and vcXMLRPC.js to the same webserver as 
above.
+   (same host + port required)
 
-4. now you can startup appserver passing the option --web-frontend 
-   to enable the builtin http server.
+5. Point your webbrowser to the location of sample.html. Now you should be 
able 
+   to do querys, add and change data.
 
-5. then you can try the webfrontend out by pointing your Gecko based Browser to
-   http://gnue_host:8765/ (depends on xmlrpc settings) and loading sample.html.
-
-
-Further steps:
+Next steps
 --------------
 
 - create new html forms by building GFD files and transform them via 
GNUe-Designer
   (Tools->Extra->Compile Form for GNUe JsForms)
 
-- put normal gfd files in the webfrontend directory and start them via
-  gnue-forms http://gnue_host:8765/myform.gfd
+- modify settings in gnueforms.js, like default user name etc.
 
-- you can modify some settings in gnueforms.js, like default user name etc.
-
-- improve the gnueforms.js
+- improve gnueforms.js

Modified: trunk/gnue-appserver/extensions/webfrontend/gnue-forms.js
===================================================================
--- trunk/gnue-appserver/extensions/webfrontend/gnue-forms.js   2006-02-06 
19:33:53 UTC (rev 8153)
+++ trunk/gnue-appserver/extensions/webfrontend/gnue-forms.js   2006-02-09 
15:48:31 UTC (rev 8154)
@@ -322,40 +322,40 @@
   this.version = '0.0.1';
   this.host=host;
   this.open = function (authentification) {
-    return XMLRPC.call(this.host,'Session.open',authentification);
+    return XMLRPC.call(this.host,'open',authentification);
   };
   this.close = function (session_id,commit) {
-    return XMLRPC.call(this.host,'Session.close',session_id,commit);
+    return XMLRPC.call(this.host,'close',session_id,commit);
   };
   this.commit = function (session_id) {
-    return XMLRPC.call(this.host,'Session.commit',session_id);
+    return XMLRPC.call(this.host,'commit',session_id);
   };
   this.rollback = function (session_id) {
-    return XMLRPC.call(this.host,'Session.rollback',session_id);
+    return XMLRPC.call(this.host,'rollback',session_id);
   };
   this.request = function 
(sessionid,classname,conditions,sortorder,propertylist) {
-    return 
XMLRPC.call(this.host,'Session.request',sessionid,classname,conditions,sortorder,propertylist);
+    return 
XMLRPC.call(this.host,'request',sessionid,classname,conditions,sortorder,propertylist);
   };
   this.count = function (sessionid,listid) {
-    return XMLRPC.call(this.host,'Session.count',sessionid,listid);
+    return XMLRPC.call(this.host,'count',sessionid,listid);
   };
   this.fetch = function (sessionid,listid,start,count) {
-    return XMLRPC.call(this.host,'Session.fetch',sessionid,listid,start,count);
+    return XMLRPC.call(this.host,'fetch',sessionid,listid,start,count);
   };
   this.load = function (sessionid,classname,objids,propertylist) {
-    return 
XMLRPC.call(this.host,'Session.load',sessionid,classname,objids,propertylist);
+    return 
XMLRPC.call(this.host,'load',sessionid,classname,objids,propertylist);
   };
   this.store = function (sessionid,classname,objids,propertylist,data) {
-    return 
XMLRPC.call(this.host,'Session.store',sessionid,classname,objids,propertylist,data);
+    return 
XMLRPC.call(this.host,'store',sessionid,classname,objids,propertylist,data);
   };
   this.call = function (sessionid,classname,objids,methodname,parameters) {
-    return 
XMLRPC.call(this.host,'Session.call',sessionid,classname,objids,methodname,parameters);
+    return 
XMLRPC.call(this.host,'call',sessionid,classname,objids,methodname,parameters);
   };
   this.dodelete = function (sessionid,classname,objids) {
-    return XMLRPC.call(this.host,'Session.delete',sessionid,classname,objids);
+    return XMLRPC.call(this.host,'delete',sessionid,classname,objids);
   };
   this.getFilters = function (language) {
-    return XMLRPC.call(this.host,'Session.getFilters',language);
+    return XMLRPC.call(this.host,'getFilters',language);
   }
 
 }
@@ -737,7 +737,8 @@
       if (rpc_addr==undefined) {
         // autodetect connection
         rpc_addr=location.protocol+location.host;
-       proxy="";
+        rpc_addr="http://"+location.host+":8765/";;
+       proxy="http://"+location.host+"/cgi-bin/rpcproxy.cgi";;
       }
       //  3. if that doesnt work, ask user
       // TODO: Implement fetchrpc addr+login test loop

Added: trunk/gnue-appserver/extensions/webfrontend/rpcproxy.cgi
===================================================================
--- trunk/gnue-appserver/extensions/webfrontend/rpcproxy.cgi    2006-02-06 
19:33:53 UTC (rev 8153)
+++ trunk/gnue-appserver/extensions/webfrontend/rpcproxy.cgi    2006-02-09 
15:48:31 UTC (rev 8154)
@@ -0,0 +1,275 @@
+#!/usr/bin/perl 
+################################################################################
+#  rpcproxy.cgi (1.41)
+#  00:18 2001-08-31
+#  Copyright (c) 2001, Saltstorm.net <address@hidden>
+#  License : GNU GPL (http://www.gnu.org/licenses/gpl.txt)
+#
+################################################################################
+#      Simple XML-RPC proxy-hack for side-stepping client-side security
+#      restrictions when using the 'XMLHttpRequest' object in Moz�lla 0.8.2+ 
+#      and MSIE's 5+ 'Microsoft.XMLHTTP' object, thus giving possibilities of
+#      accessing public services hosted on remote domains. 
+#
+#      The Mozilla browser ships with a native XMLHttpRequest object making it
+#      possible to implement HTTP request functionality from within a page 
using
+#      javascript.     This object is very much alike the 'Microsoft.XMLHTTP' 
object
+#      bundled with MS Internet Explorer 5+ in terms of the API design, but has
+#      a different     security context. While MSIE's 'Microsoft.XMLHTTP' 
availability
+#      is based on "Security Zones" and "Trusted Sites", Mozilla has taken 
another
+#      security approach, whereas you can only issue XMLHttpRequests to the 
same
+#      domain:port from where the parent document originated. While some might 
say
+#      this is feasible in regards for the variuos cross-site scripting 
exploits,
+#      other find it very frustrating as they can't access/incorporate services
+#      from the outside world into their web-apps without having to depend on
+#      a through and through serverside solution.
+#
+#      This piece came about as Ruben Daniels from Virtual Cowboys
+#      (http://www.virtualcowboys.com) and I concurrently were struggling with
+#      client-side Javascript implementations of XML-RPC clients. We found 
ourselves
+#      very annoyed with these restrictions as we couldn't take advantage of 
the
+#      increasing number of great RPC-services outthere, so I decided to knock
+#      up this rpc-proxy to overcome this shortcoming.
+#
+#      The idea is very simple. Once placed on your server, it will take a POST
+#      request coming in from the local domain and pass it along as-is to the 
real
+#      RPC-server and then proxy back the response to the client. As of 
version 1.40
+#      rpcproxy will even gzip-compress the proxied XML response-stream to 
make it
+#      far more manageable in terms of bandwidth. A vanilla XML-document can be
+#      reduced with up to some 90% of its original size simply by compressing 
it.
+#      Gzip-encoded documents are supported by MSIE and Mozilla out-of-the-box,
+#      so you don't have to care more about it, other than that you have gained
+#      9/10's of bandwidth. If you are on a slow connection that makes a big
+#      difference. But the most important thing here, a request like this,
+#      as far as Mozilla and MSIE concerns, no security exception was raised
+#      since the request was seemingly served at the local domain.
+#
+#      MS Explorer 5+ note.
+#      
-----------------------------------------------------------------------------
+#      While utilizing rpcproxy.cgi as a proxy for Mozilla XMLHttpRequests is 
crucial
+#      for making non-local HTTP requests, it also have the effect to MSIE in 
the
+#      matter that the 'Microsoft.XMLHTTP' object also consider requests to the
+#      current domain:port as safe and will gladly go for it WITHOUT having the
+#      current domain present in the list of "Trusted sites" in security 
settings.
+#
+#
+#      Setting up.
+#      
-----------------------------------------------------------------------------
+#      Obviously, since this thing is written in PERL, you'll need an
+#      PERL-interpreter on your server. If you are on a *nix/Linux system you 
most
+#      certainly have one there by default. If running on a Win32 system
+#      (e.g Win NT/2k) there is great distribution of PERL available freely at
+#      http://www.activestate.com. 
+#
+#
+#      1. Put this script accessible from your HTTP-server and make sure it is
+#      marked executable. (e.g /cgi-bin/...)
+#
+#      2. Modify the topmost line of this script to match the path to your PERL
+#      executable. (on most Win32 boxes '#!perl' should be sufficient)
+#
+#      3. Making sure it is setup alright, open up your favorite browser and
+#      try to request it. (http://www.mydomain.tld/cgi-bin/rpcproxy.cgi)
+#      If nothing happens, (a HTTP 204 response) all should be fine.
+#      If you get a 40x or even a 500/501 you should step back and re-check  
+#      step 1 and 2 again.
+#
+#      4. Now, the world of remote RPC-services is yours...
+#      Of course you need to know a fair piece of the DOM, XML and the XML-RPC
+#      service specification, but that is horse of different color not covered
+#      here. To get you started, a client-side example:
+#
+#      // Mozilla 0.8.2+
+#      var sRPCService = 'http://rpc.remote.tld/object/method';
+#      var sRPCProxy = 'http://www.local.tld/cgi-bin/rpcproxy.cgi';
+#      var oXML = new XMLHttpRequest();
+#      oXML.open('POST', sRPCProxy, false);
+#      oXML.setRequestHeader('X-Proxy-Request', sRPCService);
+#      oXML.setRequestHeader('X-Compress-Response', 'gzip');
+#      oXML.send([object XMLDomDocument]);
+#      var oDomDoc = oXML.responseXML;
+#      // ... do stuff with oDomDoc ...
+#
+#      // to make the above snippet runnable in MSIE 5+ (Win32) you just
+#      // need to change the assignment of the 'oXML' variable as follows:
+#      var oXML = new ActiveXObject('Microsoft.XMLHTTP');
+#  
+#
+#      ! About security !
+#      
-----------------------------------------------------------------------------
+#      This script will only proxy POST requests having a HTTP header named
+#      'X-Proxy-Request' containing the URL to the real rpc-service. If this
+#      header isn't present OR the service-URL isn't in the list of allowed
+#      services, rpcproxy will blackhole the request and respond with a
+#      simple HTTP status 204.
+#
+#
+#      Resources.
+#      
-----------------------------------------------------------------------------
+#      XML-RPC Home Page.
+#       http://www.xml-rpc.com
+#      XML-RPC HOWTO
+#       http://xmlrpc-c.sourceforge.net/xmlrpc-howto/xmlrpc-howto.html
+#      Core JavaScript Guide 1.5
+#       
http://developer.netscape.com/docs/manuals/js/core/jsguide15/contents.html
+#      
+#       news://comp.lang.javascript
+#      secnews.netscape.com
+#       news://netscape.devs-javascript
+#       news://netscape.public.mozilla.dom
+#
+#      
----------------------------------------------------------------------------
+#      2001-08-26, Thomas Loo / Saltstorm 
+#      address@hidden | http://www.saltstorm.net
+################################################################################
+
+use strict;
+use Compress::Zlib;
+use HTTP::Request;
+use LWP::UserAgent;
+use URI::Escape;
+#use CGI::Carp qw(fatalsToBrowser);
+
+
+## User definables 
#############################################################
+#
+# Enable/Disable (1/0) logging of the requests/responses
+my $log_traffic = 0;
+
+# remote request timeout in seconds.
+my $rpc_service_timeout = 15;
+
+# this name must match the header name set on the client side.
+my $magic_header_name = "X-Proxy-Request";
+
+# the name of the header that decides if the response should be gzip 
compressed.
+my $do_gzip_header_name = "X-Compress-Response";
+
+# to prevent this script from being used as a general proxy by a malicious
+# user, requests to the following services will only be passed through.
+my @allowed_services = (
+       "http://www.oreillynet.com/meerkat/xml-rpc/server.php";,
+       "http://www.stuffeddog.com/speller/speller-rpc.cgi";,
+       "http://plant.blogger.com/api/RPC2";,
+        "http://localhost:8765/";,
+       # ...additional services here...
+       );
+###############################################################################
+
+       my ($mhn, $reqbody, $do_proxy_request);
+       ($mhn = uc $magic_header_name) =~ tr/-/_/;
+       my $remote_rpc_server = $ENV{'HTTP_' . $mhn} || '';
+       ($mhn = $do_gzip_header_name) =~ tr/-/_/;
+       my $do_gzip = ($ENV{'HTTP_' . $mhn}) ? 1 : 0;
+       
+       # try match the supplied service URL with one in the allowed-list.
+       foreach(@allowed_services){
+         $do_proxy_request = 1 and last if /^$remote_rpc_server$/i;
+         }
+       
+       # kill off any request of type non-POST or having a missing 
$magic_header or
+       # not being present in the allowed-list.
+       print "Status: 204 No Response\r\n\r\n" and exit
+        unless ($ENV{REQUEST_METHOD} eq 'POST' && length($remote_rpc_server) > 
0 && $do_proxy_request);
+
+       # create a new user-agen blend it with the original user-agent string 
and set the timeout.
+       my $ua = new LWP::UserAgent;
+       $ua->agent($ENV{HTTP_USER_AGENT});
+       $ua->timeout($rpc_service_timeout);
+
+       # create a new URI object
+       my $ruri = URI->new($remote_rpc_server);
+       
+       # create a new HTTP header object.
+       my $rhd = new HTTP::Headers(
+         Content_Length => read(STDIN, $reqbody, $ENV{CONTENT_LENGTH}),
+         Content_Type => $ENV{CONTENT_TYPE},
+         # Host => ($ruri->port == 80 ? $ruri->host : $ruri->host_port),
+         Referer => $ENV{HTTP_REFERER},
+         X_Forwarded_For => $ENV{REMOTE_ADDR});
+ 
+       # create the remote rpc request
+       my $rreq = new HTTP::Request($ENV{REQUEST_METHOD}, $ruri, $rhd, 
$reqbody);
+
+       if($log_traffic){
+         open (REQLOG, ">>rpcproxy-request.log") || die $!;
+         print REQLOG $rreq->as_string, "\r\n", ("-" x 79), "\r\n";
+         close REQLOG;
+         }
+
+       # trig the rpc 
+       my $rres = $ua->request($rreq);
+       
+       # !! This is THE weirdest thing !!
+       # For MSIE's XMLDOM-parser to pick up large (+60 KB) proxied responses
+       # from this script and actually have it recognized as a text/xml stream
+       # it appears binmode STDOUT must be set when run from a Win-box.
+       # This is totally beyond me since xml/text content is 100% ASCII.
+       # Small XML-files blends in fine without binmode, but the DOM parser
+       # totally bombs out on big ones with parseErrors all over the place...
+       # If anyone could fill in the blanks here and explain this MSIE feature
+       # for me I'd be most grateful, since it took me about 4 hours to
+       # figure this one out.
+       binmode STDOUT if ($^O =~ /Win32/i || $do_gzip || 
$rres->headers->content_encoding);
+
+       # alles ok ? ...then shove the result from the remote rpc-call
+       # back to the client as-is. (gzip-encoded if requested)
+       if($rres->is_success && $rres->code == 200){
+         my $already_encoded = $rres->headers->content_encoding;
+         $rres->headers->content_encoding('gzip')
+          if($do_gzip && !$already_encoded && $rres->headers->content_length > 
1024);
+         $rres->headers->expires($rres->headers->date);
+
+         my $body = ($do_gzip && !$already_encoded && 
$rres->headers->content_length > 1024 ?
+          Compress::Zlib::memGzip($rres->content) : $rres->content);
+
+         $rres->headers->content_length(length($body));
+
+         print $rres->headers->as_string, "\r\n", $body;
+
+         if($log_traffic){
+           open (RESLOG, ">>rpcproxy-response.log") || die $!;
+           print RESLOG $rres->headers->as_string, "\r\n", $body, "\r\n", ("-" 
x 79), "\r\n";
+           close RESLOG;
+           }
+         }
+
+       # something has gone wrong, bring aforth a faultpage instead.
+       else {
+         my $faultbody = get_faultpage($remote_rpc_server, $rres->code);
+         my $res = new HTTP::Headers(
+           Server => $ENV{SERVER_SOFTWARE},
+           Connection => 'close',
+        Content_Length => length($faultbody),
+        Content_Type => 'text/xml',
+               Expires => HTTP::Date::time2str(time - 3600 * 24));     
+         print $res->as_string, "\r\n", $faultbody;
+         }
+
+
+sub get_faultpage {
+       my $server = shift;
+       my $status_code = shift || "Timed out";
+
+       return <<XML_BODY
+<?xml version="1.0"?>
+               <methodResponse>
+                <fault>
+                 <value>
+                  <struct>
+                   <member>
+                    <name>faultCode</name>
+                    <value><int>65535</int></value>
+                   </member>
+                   <member>
+                    <name>faultString</name>
+                    <value><string>rpcproxy error [$server \: $status_code] 
</string></value>
+                   </member>
+                  </struct>
+                 </value>
+                </fault>
+               </methodResponse>
+XML_BODY
+       }
+
+       exit;


Property changes on: trunk/gnue-appserver/extensions/webfrontend/rpcproxy.cgi
___________________________________________________________________
Name: svn:executable
   + *

Modified: trunk/gnue-appserver/extensions/webfrontend/vcXMLRPC.js
===================================================================
--- trunk/gnue-appserver/extensions/webfrontend/vcXMLRPC.js     2006-02-06 
19:33:53 UTC (rev 8153)
+++ trunk/gnue-appserver/extensions/webfrontend/vcXMLRPC.js     2006-02-09 
15:48:31 UTC (rev 8154)
@@ -361,8 +361,12 @@
                        case "value":
                                child = this.getNode(data, [0]);
                                return (!child) ? ((data.firstChild) ? new 
String(data.firstChild.nodeValue) : "") : this.toObject(child);
-
                                break;
+                               
+                       case "nil":
+                               return undefined 
+                               break;
+                               
                        default:
                                this.handleError(new Error("Malformed XMLRPC 
Message: " + data.tagName));
                                return false;
@@ -591,12 +595,12 @@
                        //Check for XMLRPC Errors
                        rpcErr = dom.getElementsByTagName("fault");
                        if(rpcErr.length > 0){
-                         alert("Error occured:"+http.responseText);
-                         return false
-                         alert(rpcErr[0].firstChild);
-                               rpcErr = this.toObject(rpcErr[0]);
-                               alert(rpcErr)
-                               this.handleError(new Error(rpcErr.faultCode, 
rpcErr.faultString));
+                           rpcErr=rpcErr[0].firstChild  // skip textnodes and 
find first element node
+                           while (rpcErr.nodeType!=rpcErr.ELEMENT_NODE){
+                              rpcErr=rpcErr.nextSibling;
+                           }
+                               rpcErr = this.toObject(rpcErr);
+                               this.handleError(new Error("RPC Fault: 
("+rpcErr.faultCode+") "+rpcErr.faultString));
                                return false
                        }
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]