def _encodeScalar(self, scalar, name=None): valueType, string = self._encode(scalar) if valueType == None: self._encodeObject(string) else: if valueType == "xsd:base64Binary": string = base64.encodestring(string) else: string = _escape(string) self._append("<scalar") valueType = _escape(valueType, 1) if valueType != "": if name != None: name = _escape(name, 1) self._append(" name=\"%s\" type=\"%s\">" % (name, valueType)) else: self._append(" type=\"%s\">" % valueType) else: if name != None: name = _escape(name, 1) self._append(" name=\"%s\">" % name) else: self._append(">") self._append(string) self._append("</scalar>\n")
def _encodeArray(self, array, name=None): self._track(array) self._append("<array") if name != None: name = _escape(name, 1) self._append(" name=\"%s\">\n" % name) else: self._append(">\n") for object in array: self._encodeObject(object) self._append("</array>\n")
def _encodeIndex(self, index, name=None): self._track(index) self._append("<index") if name != None: name = _escape(name, 1) self._append(" name=\"%s\">\n" % name) else: self._append(">\n") for key in index.keys(): if type(key) not in _stringTypes: raise RuntimeError("dictionary keys must be strings") self._encodeObject(index[key], key) self._append("</index>\n")
def _encodeScalar(self, value, name=None): if RemoteService._nil and type(value) == types.NoneType: if name != None: self._append("<member>\n") self._append("<name>") self._append(_escape(name)) self._append("</name>\n") self._append("<value>") self._append("<nil/>") self._append("</value>\n") if name != None: self._append("</member>\n") else: valueType, string = self._encode(value) if valueType == None: self._encodeObject(string) else: if name != None: self._append("<member>\n") self._append("<name>") self._append(_escape(name)) self._append("</name>\n") valueType = self._translate(valueType) if valueType == "boolean": string = str(int(string in ["1", "true", "True"])) elif valueType == "base64": string = base64.encodestring(string) elif valueType == "dateTime.iso8601": string = _escape("%s%s%s" % (string[0:4], string[5:7], string[8:])) else: string = _escape(string) self._append("<value>") self._append("<" + valueType + ">") self._append(string) self._append("</" + valueType + ">") self._append("</value>\n") if name != None: self._append("</member>\n")
def _encodeStruct(self, struct, name=None): self._track(struct) if name != None: self._append("<member>\n") self._append("<name>") self._append(_escape(name)) self._append("</name>\n") self._append("<value>\n") self._append("<struct>\n") for key in struct.keys(): if type(key) not in _stringTypes: raise RuntimeError("dictionary keys must be strings") self._encodeObject(struct[key], key) self._append("</struct>\n") self._append("</value>\n") if name != None: self._append("</member>\n")
def _encodeArray(self, array, name=None): self._track(array) if name != None: self._append("<member>\n") self._append("<name>") self._append(_escape(name)) self._append("</name>\n") self._append("<value>\n") self._append("<array>\n") self._append("<data>\n") for object in array: self._encodeObject(object) self._append("</data>\n") self._append("</array>\n") self._append("</value>\n") if name != None: self._append("</member>\n")
def execute(self): try: if os.environ["REQUEST_METHOD"] != "POST": self._error(400,"Only POST method supported.") return ct = string.split(os.environ.get("CONTENT_TYPE","text/xml"),';')[0] if ct != "text/xml": self._error(400,"Invalid content type.") return length = int(os.environ["CONTENT_LENGTH"]) content = sys.stdin.read(length) ps = ZSI.ParsedSoap(content) data = ZSI._child_elements(ps.body_root) if len(data) == 0: params = [] else: try: tc = ZSI.TC.Any() params = [] for e in data: params.append(tc.parse(e,ps)) except ZSI.EvaluateException: raise method = ps.body_root.localName result = self.dispatch(method,params) result = [result] reply = StringIO.StringIO() ZSI.SoapWriter(reply).serialize(result, ZSI.TC.Any(aslist=1,pname=method + 'Response')) body = reply.getvalue() print "Status: 200" print "Content-Type: text/xml" print "Content-Length: %d" % len(body) print sys.stdout.write(body) except SystemExit: pass except ServiceFailure, exception: result = {} result["error"] = exception.error result["description"] = exception.description result["origin"] = exception.origin result["details"] = exception.details detail = FAULT_DETAIL % (SCHEMA_URI, exception.error,_escape(exception.description), _escape(exception.origin),_escape(exception.details)) if exception.origin == "netsvc" and \ (exception.error == netrpc.SERVER_METHOD_UNAVAILABLE or \ exception.error == netrpc.SERVER_PARAMETERS_INCORRECT or \ exception.error == netrpc.SERVER_REQUEST_DECODING_ERROR): fault = ZSI.Fault(ZSI.Fault.Client, "Request Failed",None,detail,None) else: fault = ZSI.Fault(ZSI.Fault.Server, "Request Failed",None,detail,None) body = fault.AsSOAP() print "Status: 500" print "Content-Type: text/xml" print "Content-Length: %d" % len(body) print sys.stdout.write(body)
result["details"] = exception.details detail = FAULT_DETAIL % (SCHEMA_URI, exception.error,_escape(exception.description), _escape(exception.origin),_escape(exception.details)) if exception.origin == "netsvc" and \ (exception.error == netrpc.SERVER_METHOD_UNAVAILABLE or \ exception.error == netrpc.SERVER_PARAMETERS_INCORRECT or \ exception.error == netrpc.SERVER_REQUEST_DECODING_ERROR): fault = ZSI.Fault(ZSI.Fault.Client, "Request Failed",None,detail,None) else: fault = ZSI.Fault(ZSI.Fault.Server, "Request Failed",None,detail,None) body = fault.AsSOAP() print "Status: 500" print "Content-Type: text/xml" print "Content-Length: %d" % len(body) print sys.stdout.write(body) except: self._error(500,_escape(exceptionDetails())) def asCGI(callback): _CGI(callback).execute()
def call(self, method, params): try: if RemoteService._debug: RemoteService._request = "" RemoteService._response = "" if self._type != "http": error = CLIENT_SERVICE_ADDRESS_INVALID description = CLIENT_SERVICE_ADDRESS_INVALID_MESSAGE origin = "netrpc.xmlrpc" details = self._url raise AddressInvalid(error, description, origin, details) try: body = self._encoder.convert(params, "request") template = '<?xml version="1.0"?>\n<methodCall>\n' \ '<methodName>%s</methodName>\n' \ '<params>\n%s</params>\n</methodCall>\n' body = template % (_escape(method), body) except ServiceFailure: raise except: error = CLIENT_REQUEST_ENCODING_ERROR description = CLIENT_REQUEST_ENCODING_ERROR_MESSAGE origin = "netrpc.xmlrpc" details = exceptionDescription() raise ServiceFailure(error, description, origin, details) try: request = httplib.HTTP(self._host) request.putrequest("POST", self._path) request.putheader("Host", self._host) request.putheader("Connection", "Close") request.putheader("Content-Type", "text/xml") request.putheader("Content-Length", str(len(body))) request.putheader("User-Agent", "OSE/XML-RPC") if self._login != None and self._password != None: info = "%s:%s" % (self._login, self._password) info = base64.encodestring(info) info = "Basic %s" % string.strip(info) request.putheader("Authorization", info) request.endheaders() if RemoteService._debug: headers = "POST %s HTTP/1.0" % self._path headers = "%s\nHost: %s" % (headers, self._host) headers = "%s\nConnection: Close" % headers headers = "%s\nContent-Type: text/xml" % headers headers = "%s\nContent-Length: %s" % (headers, str(len(body))) headers = "%s\nUser-Agent: OSE/XML-RPC" % headers RemoteService._request = headers + "\n\n" + body request.send(body) except socket.error, exception: error = CLIENT_SERVICE_UNAVAILABLE description = CLIENT_SERVICE_UNAVAILABLE_MESSAGE origin = "netrpc.xmlrpc" details = exceptionDescription() raise ServiceUnavailable(error, description, origin, details) error, description, headers = request.getreply() if RemoteService._debug: RemoteService._response = "HTTP/1.0 %d %s\r\n" % (error, description) for line in headers.headers: RemoteService._response = RemoteService._response + line RemoteService._response = string.replace( RemoteService._response, "\r\n", "\n") if error != 200: origin = "netrpc.xmlrpc" response = request.getfile() # This alone was loosing data # under Mac OS for some reason. #details = response.read() details = "" content = [] while 1: try: # Large read was still loosing # data under Mac OS. Small read # works okay though. Strange!!! data = response.read(64) if data: content.append(data) else: break except: break details = string.join(content, '') if RemoteService._debug: RemoteService._response = RemoteService._response + "\n" + details response.close() if error == 401: raise AuthenticationFailure(error, description, origin, details) elif error == 404: raise ServiceUnavailable(error, description, origin, details) else: raise TransportFailure(error, description, origin, details) error = CLIENT_RESPONSE_HEADERS_INVALID description = CLIENT_RESPONSE_HEADERS_INVALID_MESSAGE origin = "netrpc.xmlrpc" if not headers.has_key("content-type"): details = "The Content-Type header does not exist." raise ServiceFailure(error, description, origin, details) if headers["content-type"] != "text/xml": details = "Unexpected value of %s for Content-Type." details = details % ` headers["content-type"] ` raise ServiceFailure(error, description, origin, details) if not headers.has_key("content-length"): details = "The Content-Length header does not exist." raise ServiceFailure(error, description, origin, details) try: expect = int(headers["content-length"]) except: details = "Content length not an integer, but %s." details = details % ` headers["content-length"] ` raise ServiceFailure(error, description, origin, details) try: response = request.getfile() decoder = _Decoder(self._decode) actual = 0 if RemoteService._debug: RemoteService._response = RemoteService._response + "\n" while 1: content = response.read(4096) if not content: break actual = actual + len(content) if RemoteService._debug: RemoteService._response = RemoteService._response + content decoder.feed(content) if expect != actual: error = CLIENT_RESPONSE_HEADERS_INVALID description = CLIENT_RESPONSE_HEADERS_INVALID_MESSAGE origin = "netrpc.xmlrpc" details = "Length of content was %d, expected %d." details = details % (actual, expect) raise ServiceFailure(error, description, origin, details) type, method, result = decoder.result() response.close() except ServiceFailure: raise except: error = CLIENT_RESPONSE_DECODING_ERROR description = CLIENT_RESPONSE_DECODING_ERROR_MESSAGE origin = "netrpc.xmlrpc" details = exceptionDescription() raise ServiceFailure(error, description, origin, details) if type not in ["response", "failure"]: error = CLIENT_RESPONSE_DECODING_ERROR description = CLIENT_RESPONSE_DECODING_ERROR_MESSAGE origin = "netrpc.xmlrpc" raise ServiceFailure(error, description, origin) if type == "failure": try: error = result["faultCode"] description = result["faultString"] origin = "" details = "" lines = string.split(description, '\n') if len(lines) != 0: try: index = string.index(lines[0], " -- ") except: pass else: origin = lines[0][0:index] description = lines[0][index + 4:] for index in range(1, len(lines)): if lines[index] == "": details = string.join( lines[index + 1:], "\n") break else: description = "%s\n%s" % (description, lines[index]) try: index = string.rindex(description, prelude1) details = description[index + len(prelude1):] description = description[0:index] except: pass try: index = string.rindex(description, prelude2) origin = description[index + len(prelude2):] description = description[0:index] except: pass except: error = CLIENT_RESPONSE_DECODING_ERROR description = CLIENT_RESPONSE_DECODING_ERROR_MESSAGE origin = "netrpc.xmlrpc" details = exceptionDescription() raise ServiceFailure(error, description, origin, details) raise ServiceFailure(error, description, origin, details) else: return result