mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 14:41:29 +01:00
This brings the SOAP server up to date as of 27 July 01 with the developers release code.
This commit is contained in:
parent
f3397a4e27
commit
83086f8900
@ -15,6 +15,19 @@ by Victor Zou (C) 2000-2001 <victor@gigaideas.com.cn>
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* changelog:
|
||||||
|
2001-07-04
|
||||||
|
- abstract type system to support either 1999 or 2001 schema (arg, typing still needs much
|
||||||
|
solidification.)
|
||||||
|
- implemented proxy support, based on sample code from miles lott <milos@speakeasy.net>
|
||||||
|
- much general cleanup of code & cleaned out what was left of original xml-rpc/gigaideas code
|
||||||
|
- implemented a transport argument into send() that allows you to specify different transports
|
||||||
|
(assuming you have implemented the function, and added it to the conditional statement in send()
|
||||||
|
- abstracted the determination of charset in Content-type header
|
||||||
|
2001-07-5
|
||||||
|
- fixed more weird type/namespace issues
|
||||||
|
*/
|
||||||
|
|
||||||
// $path can be a complete endpoint url, with the other parameters left blank:
|
// $path can be a complete endpoint url, with the other parameters left blank:
|
||||||
// $soap_client = new soap_client("http://path/to/soap/server");
|
// $soap_client = new soap_client("http://path/to/soap/server");
|
||||||
class soap_client
|
class soap_client
|
||||||
@ -68,7 +81,7 @@ class soap_client
|
|||||||
function send($msg, $action, $timeout=0)
|
function send($msg, $action, $timeout=0)
|
||||||
{
|
{
|
||||||
// where msg is an soapmsg
|
// where msg is an soapmsg
|
||||||
$msg->debug = $this->debug;
|
$msg->debug_flag = $this->debug_flag;
|
||||||
$this->action = $action;
|
$this->action = $action;
|
||||||
return $this->sendPayloadHTTP10(
|
return $this->sendPayloadHTTP10(
|
||||||
$msg,
|
$msg,
|
||||||
@ -130,7 +143,6 @@ class soap_client
|
|||||||
fclose($fp);
|
fclose($fp);
|
||||||
$this->incoming_payload = $incoming_payload;
|
$this->incoming_payload = $incoming_payload;
|
||||||
// $response is a soapmsg object
|
// $response is a soapmsg object
|
||||||
//$msg->debug_flag = true;
|
|
||||||
$this->response = $msg->parseResponse($incoming_payload);
|
$this->response = $msg->parseResponse($incoming_payload);
|
||||||
$this->debug($msg->debug_str);
|
$this->debug($msg->debug_str);
|
||||||
return $this->response;
|
return $this->response;
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
class soap_parser
|
class soap_parser
|
||||||
{
|
{
|
||||||
function soap_parser($xml='')
|
function soap_parser($xml='',$encoding='UTF-8')
|
||||||
{
|
{
|
||||||
global $soapTypes;
|
global $soapTypes;
|
||||||
|
|
||||||
$this->soapTypes = $soapTypes;
|
$this->soapTypes = $soapTypes;
|
||||||
$this->xml = $xml;
|
$this->xml = $xml;
|
||||||
$this->xml_encoding = "UTF-8";
|
$this->xml_encoding = $encoding;
|
||||||
$this->root_struct = "";
|
$this->root_struct = "";
|
||||||
// options: envelope,header,body,method
|
// options: envelope,header,body,method
|
||||||
|
// determines where in the message we are (envelope,header,body,method)
|
||||||
$this->status = "";
|
$this->status = "";
|
||||||
$this->position = 0;
|
$this->position = 0;
|
||||||
$this->pos_stat = 0;
|
$this->pos_stat = 0;
|
||||||
@ -215,7 +216,8 @@ class soap_parser
|
|||||||
// get type if not set already
|
// get type if not set already
|
||||||
if($this->message[$pos]["type"] == "")
|
if($this->message[$pos]["type"] == "")
|
||||||
{
|
{
|
||||||
if($this->message[$pos]["cdata"] == "" && $this->message[$pos]["children"] != "")
|
// if($this->message[$pos]["cdata"] == "" && $this->message[$pos]["children"] != "")
|
||||||
|
if($this->message[$pos]["children"] != "")
|
||||||
{
|
{
|
||||||
$this->message[$pos]["type"] = "SOAPStruct";
|
$this->message[$pos]["type"] = "SOAPStruct";
|
||||||
}
|
}
|
||||||
@ -282,7 +284,7 @@ class soap_parser
|
|||||||
}
|
}
|
||||||
// set parent back to my parent
|
// set parent back to my parent
|
||||||
$this->parent = $this->message[$pos]["parent"];
|
$this->parent = $this->message[$pos]["parent"];
|
||||||
//$this->debug("parsed $name end, eval_str = '".trim($this->message[$pos]["eval_str"])."' and children = ".$this->message[$pos]["children"]);
|
$this->debug("parsed $name end, type '".$this->message[$pos]["type"]."'eval_str = '".trim($this->message[$pos]["eval_str"])."' and children = ".$this->message[$pos]["children"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// element content handler
|
// element content handler
|
||||||
|
@ -3,9 +3,26 @@
|
|||||||
|
|
||||||
// for example usage, see the test_server.php file.
|
// for example usage, see the test_server.php file.
|
||||||
|
|
||||||
|
/* changelog:
|
||||||
|
2001-07-05
|
||||||
|
- detection of character encoding in Content-Type header. server
|
||||||
|
will now call the soap_parser object with the specified encoding
|
||||||
|
- server will now return the Content-Type header with the sender's encoding type specified
|
||||||
|
must still learn more bout encoding, and figure out what i have to do to be able to
|
||||||
|
make sure that my response is *actually* encoded correctly
|
||||||
|
2001-07-21
|
||||||
|
- force proper error reporting for windows compatibility
|
||||||
|
2001-07-27
|
||||||
|
- get_all_headers() check for windows compatibility
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// make errors handle properly in windows
|
||||||
|
error_reporting(2039);
|
||||||
|
|
||||||
class soap_server
|
class soap_server
|
||||||
{
|
{
|
||||||
function soap_server($data='',$serviceNow=False)
|
function soap_server()
|
||||||
{
|
{
|
||||||
// create empty dispatch map
|
// create empty dispatch map
|
||||||
$this->dispatch_map = array();
|
$this->dispatch_map = array();
|
||||||
@ -13,23 +30,20 @@ class soap_server
|
|||||||
$this->debug_str = '';
|
$this->debug_str = '';
|
||||||
$this->headers = '';
|
$this->headers = '';
|
||||||
$this->request = '';
|
$this->request = '';
|
||||||
$this->result = 'successful';
|
$this->xml_encoding = 'UTF-8';
|
||||||
$this->fault = false;
|
$this->fault = false;
|
||||||
$this->fault_code = '';
|
$this->fault_code = '';
|
||||||
$this->fault_str = '';
|
$this->fault_str = '';
|
||||||
$this->fault_actor = '';
|
$this->fault_actor = '';
|
||||||
|
// for logging interop results to db
|
||||||
if($serviceNow == 1)
|
$this->result = 'successful';
|
||||||
{
|
|
||||||
$this->service($data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parses request and posts response
|
// parses request and posts response
|
||||||
function service($data)
|
function service($data)
|
||||||
{
|
{
|
||||||
// $response is a soap_msg object
|
// $response is a soap_msg object
|
||||||
$response = $this->parseRequest($data);
|
$response = $this->parse_request($data);
|
||||||
$this->debug("parsed request and got an object of this class '".get_class($response)."'");
|
$this->debug("parsed request and got an object of this class '".get_class($response)."'");
|
||||||
$this->debug("server sending...");
|
$this->debug("server sending...");
|
||||||
// pass along the debug string
|
// pass along the debug string
|
||||||
@ -50,8 +64,9 @@ class soap_server
|
|||||||
}
|
}
|
||||||
$header[] = "Server: SOAPx4 Server v0.344359s\r\n";
|
$header[] = "Server: SOAPx4 Server v0.344359s\r\n";
|
||||||
$header[] = "Connection: Close\r\n";
|
$header[] = "Connection: Close\r\n";
|
||||||
$header[] = "Content-Type: text/xml; charset=UTF-8\r\n";
|
$header[] = "Content-Type: text/xml; charset=$this->xml_encoding\r\n";
|
||||||
$header[] = "Content-Length: ".strlen($payload)."\r\n\r\n";
|
$header[] = "Content-Length: ".strlen($payload)."\r\n\r\n";
|
||||||
|
reset($header);
|
||||||
foreach($header as $hdr)
|
foreach($header as $hdr)
|
||||||
{
|
{
|
||||||
header($hdr);
|
header($hdr);
|
||||||
@ -59,44 +74,40 @@ class soap_server
|
|||||||
print $payload;
|
print $payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseRequest($data="")
|
function parse_request($data='')
|
||||||
{
|
{
|
||||||
global $HTTP_SERVER_VARS;
|
global $HTTP_SERVER_VARS;
|
||||||
|
|
||||||
$this->debug("entering parseRequest() on ".date("H:i Y-m-d"));
|
$this->debug("entering parse_request() on ".date("H:i Y-m-d"));
|
||||||
$request_uri = $HTTP_SERVER_VARS["REQUEST_URI"];
|
$request_uri = $HTTP_SERVER_VARS["REQUEST_URI"];
|
||||||
$this->debug("request uri: $request_uri");
|
$this->debug("request uri: $request_uri");
|
||||||
// get headers
|
// get headers
|
||||||
$headers_array = getallheaders();
|
// get headers
|
||||||
|
if(function_exists("getallheaders"))
|
||||||
|
{
|
||||||
|
$this->headers = getallheaders();
|
||||||
foreach($headers_array as $k=>$v)
|
foreach($headers_array as $k=>$v)
|
||||||
{
|
{
|
||||||
$dump .= "$k: $v\r\n";
|
$dump .= "$k: $v\r\n";
|
||||||
}
|
}
|
||||||
$dump .= "\r\n\r\n".$data;
|
// get SOAPAction header
|
||||||
$this->headers = $headers_array;
|
|
||||||
$this->request = $dump;
|
|
||||||
|
|
||||||
// get SOAPAction header -> methodname
|
|
||||||
if($headers_array["SOAPAction"])
|
if($headers_array["SOAPAction"])
|
||||||
{
|
{
|
||||||
$action = str_replace('"','',$headers_array["SOAPAction"]);
|
$this->SOAPAction = str_replace('"','',$headers_array["SOAPAction"]);
|
||||||
if(ereg("^urn:",$action))
|
$this->service = $this->SOAPAction;
|
||||||
|
}
|
||||||
|
// get character encoding
|
||||||
|
if(ereg("=",$headers_array["Content-Type"]))
|
||||||
{
|
{
|
||||||
$this->service = substr($action,4);
|
$this->xml_encoding = str_replace("\"","",substr(strstr($headers_array["Content-Type"],"="),1));
|
||||||
}
|
}
|
||||||
elseif(ereg(".php",$action))
|
elseif(ereg("^text/xml",$headers_array["Content-Type"]))
|
||||||
{
|
{
|
||||||
$this->service = ereg_replace('"|/','',substr(strrchr($action,".php"),4,strlen(strrchr($action,"/"))));
|
$this->xml_encoding = "us-ascii";
|
||||||
}
|
}
|
||||||
$this->debug("got service: $this->service");
|
$this->debug("got encoding: $this->xml_encoding");
|
||||||
}
|
}
|
||||||
else
|
$this->request = $dump."\r\n\r\n".$data;
|
||||||
{
|
|
||||||
// throw a fault if no soapaction
|
|
||||||
$this->debug("ERROR: no SOAPAction header found");
|
|
||||||
}
|
|
||||||
// NOTE:::: throw a fault for no/bad soapaction here?
|
|
||||||
|
|
||||||
// parse response, get soap parser obj
|
// parse response, get soap parser obj
|
||||||
$parser = CreateObject('phpgwapi.soap_parser',$data);
|
$parser = CreateObject('phpgwapi.soap_parser',$data);
|
||||||
// get/set methodname
|
// get/set methodname
|
||||||
@ -251,19 +262,32 @@ class soap_server
|
|||||||
call_user_method($method,$obj);
|
call_user_method($method,$obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* return fault */
|
||||||
/* create soap_val object w/ return values from method, use method signature to determine type */
|
if(get_class($method_response) == "soapmsg")
|
||||||
if(get_class($method_response) != "soapval")
|
|
||||||
{
|
{
|
||||||
$return_val = CreateObject('phpgwapi.soapval',$method,$this->return_type,$method_response);
|
if(eregi("fault",$method_response->value->name))
|
||||||
|
{
|
||||||
|
$this->fault = True;
|
||||||
|
}
|
||||||
|
$return_msg = $method_response;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/* return soapval object */
|
||||||
|
|
||||||
|
if(get_class($method_response) == "soapval")
|
||||||
{
|
{
|
||||||
$return_val = $method_response;
|
$return_val = $method_response;
|
||||||
|
/* create soap_val object w/ return values from method, use method signature to determine type */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$return_val = CreateObject('phpgwapi.soapval',$method,$this->return_type,$method_response);
|
||||||
}
|
}
|
||||||
$this->debug($return_val->debug_str);
|
$this->debug($return_val->debug_str);
|
||||||
/* response object is a soap_msg object */
|
/* response object is a soap_msg object */
|
||||||
$return_msg = CreateObject('phpgwapi.soapmsg',$method."Response",array($return_val),$this->service);
|
$return_msg = CreateObject('phpgwapi.soapmsg',$method."Response",array($return_val),$this->service);
|
||||||
|
}
|
||||||
if($this->debug_flag)
|
if($this->debug_flag)
|
||||||
{
|
{
|
||||||
$return_msg->debug_flag = true;
|
$return_msg->debug_flag = true;
|
||||||
@ -400,7 +424,7 @@ class soap_server
|
|||||||
"faultactor" => $this->fault_actor,
|
"faultactor" => $this->fault_actor,
|
||||||
"faultdetail" => $this->fault_detail.$this->debug_str
|
"faultdetail" => $this->fault_detail.$this->debug_str
|
||||||
),
|
),
|
||||||
"http://schemas.xmlphpgwapi.org/soap/envelope/"
|
"http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class soapmsg
|
|||||||
{
|
{
|
||||||
$ns_string .= " xmlns:$v=\"$k\"";
|
$ns_string .= " xmlns:$v=\"$k\"";
|
||||||
}
|
}
|
||||||
return "<SOAP-ENV:Envelope $ns_string SOAP-ENV:encodingStyle=\"http://schemas.xmlphpgwapi.org/soap/encoding/\">\n"
|
return "<SOAP-ENV:Envelope $ns_string SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
|
||||||
. $payload . "</SOAP-ENV:Envelope>\n";
|
. $payload . "</SOAP-ENV:Envelope>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,20 +72,29 @@ class soapmsg
|
|||||||
{
|
{
|
||||||
$this->debug("Entering parseResponse()");
|
$this->debug("Entering parseResponse()");
|
||||||
//$this->debug(" w/ data $data");
|
//$this->debug(" w/ data $data");
|
||||||
// get rid of headers here
|
// strip headers here
|
||||||
$clean_data = ereg_replace("\r\n","\n", $data);
|
//$clean_data = ereg_replace("\r\n","\n", $data);
|
||||||
if(ereg("^.*\r\n\r\n",$data))
|
if(ereg("^.*\r\n\r\n<",$data))
|
||||||
{
|
{
|
||||||
|
$this->debug("found proper seperation of headers and document");
|
||||||
$this->debug("getting rid of headers, stringlen: ".strlen($data));
|
$this->debug("getting rid of headers, stringlen: ".strlen($data));
|
||||||
$clean_data = ereg_replace("^.*\r\n\r\n","", $data);
|
$clean_data = ereg_replace("^.*\r\n\r\n<","<", $data);
|
||||||
$this->debug("cleaned data, stringlen: ".strlen($clean_data));
|
$this->debug("cleaned data, stringlen: ".strlen($clean_data));
|
||||||
}
|
}
|
||||||
elseif(ereg("^.*\n\n",$data))
|
else
|
||||||
{
|
{
|
||||||
$this->debug("getting rid of headers, stringlen: ".strlen($data));
|
// return fault
|
||||||
$clean_data = ereg_replace("^.*\n\n","", $data);
|
return CreateObject('phpgwapi.soapval',
|
||||||
$this->debug("cleaned data, stringlen: ".strlen($clean_data));
|
'fault',
|
||||||
|
'SOAPStruct',
|
||||||
|
Array(
|
||||||
|
CreateObject('phpgwapi.soapval','faultcode','string','SOAP-MSG'),
|
||||||
|
CreateObject('phpgwapi.soapval','faultstring','string','HTTP Error'),
|
||||||
|
CreateObject('phpgwapi.soapval','faultdetail','string','HTTP headers were not immediately followed by \'\r\n\r\n\'')
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
// if response is a proper http response, and is not a 200
|
// if response is a proper http response, and is not a 200
|
||||||
if(ereg("^HTTP",$clean_data) && !ereg("200$", $clean_data))
|
if(ereg("^HTTP",$clean_data) && !ereg("200$", $clean_data))
|
||||||
{
|
{
|
||||||
@ -101,6 +110,7 @@ class soapmsg
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
$this->debug("about to create parser instance w/ data: $clean_data");
|
$this->debug("about to create parser instance w/ data: $clean_data");
|
||||||
// parse response
|
// parse response
|
||||||
$response = CreateObject('phpgwapi.soap_parser',$clean_data);
|
$response = CreateObject('phpgwapi.soap_parser',$clean_data);
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
// soap value object
|
// soap value object
|
||||||
class soapval
|
class soapval
|
||||||
{
|
{
|
||||||
function soapval($name='',$type=False,$value=-1,$namespace=False,$type_namespace=False)
|
// function soapval($name='',$type=False,$value=-1,$namespace=False,$type_namespace=False)
|
||||||
|
function soapval($name='',$type=False,$value=0,$namespace=False,$type_namespace=False)
|
||||||
{
|
{
|
||||||
global $soapTypes, $typemap, $namespaces, $methodNamespace;
|
global $soapTypes, $typemap, $namespaces, $methodNamespace;
|
||||||
|
|
||||||
@ -74,6 +75,7 @@ class soapval
|
|||||||
}
|
}
|
||||||
$this->type_prefix = $namespaces[$type_namespace];
|
$this->type_prefix = $namespaces[$type_namespace];
|
||||||
}
|
}
|
||||||
|
|
||||||
// if type namespace was not explicitly passed, and we're not in a method struct:
|
// if type namespace was not explicitly passed, and we're not in a method struct:
|
||||||
elseif(!$this->type_prefix && !isset($this->namespace))
|
elseif(!$this->type_prefix && !isset($this->namespace))
|
||||||
{
|
{
|
||||||
@ -218,7 +220,8 @@ class soapval
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elseif(is_array($k) && in_array($k,array_keys($this->soapTypes)))
|
// elseif(is_array($k) && in_array($k,array_keys($this->soapTypes)))
|
||||||
|
elseif(is_array($k,in_array($k,array_keys($this->soapTypes))))
|
||||||
{
|
{
|
||||||
$this->debug("got type '$type' for value '$v' from soapTypes array!");
|
$this->debug("got type '$type' for value '$v' from soapTypes array!");
|
||||||
$type = $k;
|
$type = $k;
|
||||||
@ -382,7 +385,8 @@ class soapval
|
|||||||
{
|
{
|
||||||
if ($type)
|
if ($type)
|
||||||
{
|
{
|
||||||
global $namespaces,$soapTypes,$typemap;
|
// global $namespaces,$soapTypes,$typemap;
|
||||||
|
global $namespaces,$typemap;
|
||||||
|
|
||||||
foreach($typemap as $namespace => $types)
|
foreach($typemap as $namespace => $types)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user