server.py :  » Web-Services » ZSI » ZSI-2.0 » interop » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Web Services » ZSI 
ZSI » ZSI 2.0 » interop » server.py
#! /usr/bin/env python
from ZSI import *
from ZSI import _copyright,resolvers,_child_elements,_textprotect
import sys, time, cStringIO as StringIO
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer

from sclasses import Operation,WSDL_DEFINITION,TC_SOAPStruct

class InteropRequestHandler(BaseHTTPRequestHandler):
    server_version = 'ZSI/1.2 OS390/VM5.4 ' + BaseHTTPRequestHandler.server_version

    def send_xml(self, text, code=200):
        '''Send some XML.'''
        self.send_response(code)
        self.send_header('Content-type', 'text/xml; charset="utf-8"')
        self.send_header('Content-Length', str(len(text)))
        self.end_headers()
        self.wfile.write(text)
        self.trace(text, 'SENT')
        self.wfile.flush()

    def send_fault(self, f):
        '''Send a fault.'''
        self.send_xml(f.AsSOAP(), 500)

    def trace(self, text, what):
        '''Log a debug/trace message.'''
        F = self.server.tracefile
        if not F: return
        print >>F, '=' * 60, '\n%s %s %s %s:' % \
            (what, self.client_address, self.path, time.ctime(time.time()))
        print >>F, text
        print >>F, '=' * 60, '\n'
        F.flush()

    def do_QUIT(self):
        '''Quit.'''
        self.server.quitting = 1
        self.log_message('Got QUIT command')
        sys.stderr.flush()
        raise SystemExit

    def do_GET(self):
        '''The GET command.  Always returns the WSDL.'''
        self.send_xml(WSDL_DEFINITION.replace('>>>URL<<<', self.server.url))

    def do_POST(self):
        '''The POST command.'''

        try:
            # SOAPAction header.
            action = self.headers.get('soapaction', None)
            if not action:
                self.send_fault(Fault(Fault.Client,
                                    'SOAPAction HTTP header missing.'))
                return
            if action != Operation.SOAPAction:
                self.send_fault(Fault(Fault.Client,
                    'SOAPAction is "%s" not "%s"' % \
                    (action, Operation.SOAPAction)))
                return

            # Parse the message.
            ct = self.headers['content-type']
            if ct.startswith('multipart/'):
                cid = resolvers.MIMEResolver(ct, self.rfile)
                xml = cid.GetSOAPPart()
                ps = ParsedSoap(xml, resolver=cid.Resolve)
            else:
                cl = int(self.headers['content-length'])
                IN = self.rfile.read(cl)
                self.trace(IN, 'RECEIVED')
                ps = ParsedSoap(IN)
        except ParseException, e:
            self.send_fault(FaultFromZSIException(e))
            return
        except Exception, e:
            # Faulted while processing; assume it's in the header.
            self.send_fault(FaultFromException(e, 1, sys.exc_info()[2]))
            return

        try:
            # Actors?
            a = ps.WhatActorsArePresent()
            if len(a):
                self.send_fault(FaultFromActor(a[0]))
                return

            # Is the operation defined?
            root = ps.body_root
            if root.namespaceURI != Operation.ns:
                self.send_fault(Fault(Fault.Client,
                    'Incorrect namespace "%s"' % root.namespaceURI))
                return
            n = root.localName
            op = Operation.dispatch.get(n, None)
            if not op:
                self.send_fault(Fault(Fault.Client,
                    'Undefined operation "%s"' % n))
                return

            # Scan headers.  First, see if we understand all headers with
            # mustUnderstand set. Then, get the ones intended for us (ignoring
            # others since step 1 insured they're not mustUnderstand).
            for mu in ps.WhatMustIUnderstand():
                if mu not in op.headers:
                    uri, localname = mu
                    self.send_fault(FaultFromNotUnderstood(uri, localname))
                    return
            headers = [ e for e in ps.GetMyHeaderElements()
                        if (e.namespaceURI, e.localName) in op.headers ]
            nsdict={ 'Z': Operation.ns }
            if headers:
                nsdict['E'] = Operation.hdr_ns
                self.process_headers(headers, ps)
            else:
                self.headertext = None

            try:
                results = op.TCin.parse(ps.body_root, ps)
            except ParseException, e:
                self.send_fault(FaultFromZSIException(e))
            self.trace(str(results), 'PARSED')
            if op.convert:
                results = op.convert(results)
            if op.nsdict: nsdict.update(op.nsdict)
            reply = StringIO.StringIO()
            sw = SoapWriter(reply, nsdict=nsdict, header=self.headertext)
            sw.serialize(results, op.TCout,
                    name = 'Z:' + n + 'Response', inline=1)
            sw.close()
            self.send_xml(reply.getvalue())
        except Exception, e:
            # Fault while processing; now it's in the body.
            self.send_fault(FaultFromException(e, 0, sys.exc_info()[2]))
            return

    def process_headers(self, headers, ps):
        '''Process headers, set self.headertext to be what to output.
        '''
        self.headertext = ''
        for h in headers:
            if h.localName == 'echoMeStringRequest':
                s = TC.String().parse(h, ps)
                self.headertext += \
    '<E:echoMeStringResponse>%s</E:echoMeStringResponse>\n' % _textprotect(s)
            elif h.localName == 'echoMeStructRequest':
                tc = TC_SOAPStruct('echoMeStructRequest', inline=1)
                data = tc.parse(h, ps)
                s = StringIO.StringIO()
                sw = SoapWriter(s, envelope=0)
                tc.serialize(sw, data, name='E:echoMeStructResponse')
                sw.close()
                self.headertext += s.getvalue()
            else:
                raise TypeError('Unhandled header ' + h.nodeName)
        pass


class InteropHTTPServer(HTTPServer):
    def __init__(self, me, url, **kw):
        HTTPServer.__init__(self, me, InteropRequestHandler)
        self.quitting = 0
        self.tracefile = kw.get('tracefile', None)
        self.url = url
    def handle_error(self, req, client_address):
        if self.quitting: sys.exit(0)
        HTTPServer.handle_error(self, req, client_address)


import getopt
try:
    (opts, args) = getopt.getopt(sys.argv[1:], 'l:p:t:u:',
                        ('log=', 'port=', 'tracefile=', 'url=') )
except getopt.GetoptError, e:
    print >>sys.stderr, sys.argv[0] + ': ' + str(e)
    sys.exit(1)
if args:
    print >>sys.stderr, sys.argv[0] + ': Usage error.'
    sys.exit(1)

portnum = 1122
tracefile = None
url = None
for opt, val in opts:
    if opt in [ '-l', '--logfile' ]:
        sys.stderr = open(val, 'a')
    elif opt in [ '-p', '--port' ]:
        portnum = int(val)
    elif opt in [ '-t', '--tracefile' ]:
        if val == '-':
            tracefile = sys.stdout
        else:
            tracefile = open(val, 'a')
    elif opt in [ '-u', '--url' ]:
        url = val
ME = ( '', portnum )

if not url:
    import socket
    url = 'http://' + socket.getfqdn()
    if portnum != 80: url += ':%d' % portnum
    url += '/interop.wsdl'

try:
    InteropHTTPServer(ME, url, tracefile=tracefile).serve_forever()
except SystemExit:
    pass
sys.exit(0)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.