<commit_before>#! /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

config = {
    'echons': 'http://soapinterop.org/echoheader/'
}

class InteropRequestHandler(BaseHTTPRequestHandler):
    server_version = 'ZSI/1.2 ' + 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')
	    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':
		print h
		s = TC.String().parse(h, ps)
		self.headertext += \
    '<E:echoMeStringResponse>%s</E:echoMeStringResponse>\n' % _textprotect(s)
	    elif h.localName == 'echoMeStructRequest':
		# Using mutable/inline to avoid a callback is a hack.
		tc = TC_SOAPStruct('echoMeStructRequest', mutable=1, 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.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<commit_msg>Remove debugging print; send usage errors to stderr<commit_after>#! /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

config = {
    'echons': 'http://soapinterop.org/echoheader/'
}

class InteropRequestHandler(BaseHTTPRequestHandler):
    server_version = 'ZSI/1.2 ' + 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')
	    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':
		# Using mutable/inline to avoid a callback is a hack.
		tc = TC_SOAPStruct('echoMeStructRequest', mutable=1, 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
{'fraction_non_alphanumeric': 0.14559354062875796, 'fraction_numerical': 0.0060127125923380865, 'mean_word_length': 3.5766509433962264, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 14}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2092980', 'n_tokens_mistral': 4459, 'n_tokens_neox': 4130, 'n_words': 987}