Email.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license, |
  9. // | that is bundled with this package in the file LICENSE, and is |
  10. // | available at through the world-wide-web at |
  11. // | http://www.php.net/license/2_02.txt. |
  12. // | If you did not receive a copy of the PHP license and are unable to |
  13. // | obtain it through the world-wide-web, please send a note to |
  14. // | license@php.net so we can mail you a copy immediately. |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Email.php,v 1.10 2003/05/18 00:57:40 shane Exp $
  20. //
  21. require_once 'SOAP/Server.php';
  22. require_once 'SOAP/Client.php';
  23. require_once 'SOAP/Transport.php';
  24. require_once 'Mail/mimeDecode.php';
  25. /**
  26. * SOAP_Server_Email
  27. * SOAP Server Class
  28. *
  29. * implements Email SOAP Server
  30. * http://www.pocketsoap.com/specs/smtpbinding/
  31. *
  32. * class overrides the default HTTP server, providing the ability
  33. * to parse an email message and execute soap calls.
  34. * this class DOES NOT pop the message, the message, complete
  35. * with headers, must be passed in as a parameter to the service
  36. * function call
  37. *
  38. * @access public
  39. * @version $Id: Email.php,v 1.10 2003/05/18 00:57:40 shane Exp $
  40. * @package SOAP::Server
  41. * @author Shane Caraveo <shane@php.net>
  42. */
  43. class SOAP_Server_Email extends SOAP_Server {
  44. var $headers = array();
  45. function SOAP_Server_Email($send_response = TRUE)
  46. {
  47. parent::SOAP_Server();
  48. $this->send_response = $send_response;
  49. }
  50. /**
  51. * remove http headers from response
  52. *
  53. * TODO: use PEAR email classes
  54. *
  55. * @return boolean
  56. * @access private
  57. */
  58. function _parseEmail(&$data)
  59. {
  60. if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $data, $match)) {
  61. if (preg_match_all('/^(.*?):\s+(.*)$/m', $match[1], $matches)) {
  62. $hc = count($matches[0]);
  63. for ($i = 0; $i < $hc; $i++) {
  64. $this->headers[strtolower($matches[1][$i])] = trim($matches[2][$i]);
  65. }
  66. }
  67. if (!stristr($this->headers['content-type'],'text/xml')) {
  68. $this->_raiseSoapFault('Invalid Content Type','','','Client');
  69. return FALSE;
  70. }
  71. if (strcasecmp($this->headers['content-transfer-encoding'],'base64')==0) {
  72. // join lines back together
  73. $enctext = preg_replace("/[\r|\n]/", '', $match[2]);
  74. $data = base64_decode($enctext);
  75. #} else if (strcasecmp($this->headers['content-transfer-encoding'],'quoted-printable')==0) {
  76. # $data = $match[2];
  77. #} else {
  78. # $this->_raiseSoapFault('Invalid Content-Transfer-Encoding','','','Client');
  79. # return FALSE;
  80. #}
  81. } else {
  82. $data = $match[2];
  83. }
  84. // if no content, return false
  85. return strlen($this->request) > 0;
  86. }
  87. $this->_raiseSoapFault('Invalid Email Format','','','Client');
  88. return FALSE;
  89. }
  90. function client(&$data)
  91. {
  92. $attachments = array();
  93. # if neither matches, we'll just try it anyway
  94. if (stristr($data,'Content-Type: application/dime')) {
  95. $this->_decodeDIMEMessage($data,$this->headers,$attachments);
  96. $useEncoding = 'DIME';
  97. } else if (stristr($data,'MIME-Version:')) {
  98. // this is a mime message, lets decode it.
  99. #$data = 'Content-Type: '.stripslashes($_SERVER['CONTENT_TYPE'])."\r\n\r\n".$data;
  100. $this->_decodeMimeMessage($data,$this->headers,$attachments);
  101. $useEncoding = 'Mime';
  102. } else {
  103. // the old fallback, but decodeMimeMessage handles things fine.
  104. $this->_parseEmail($data);
  105. }
  106. // get the character encoding of the incoming request
  107. // treat incoming data as UTF-8 if no encoding set
  108. if (!$this->soapfault && !$this->_getContentEncoding($this->headers['content-type'])) {
  109. $this->xml_encoding = SOAP_DEFAULT_ENCODING;
  110. // an encoding we don't understand, return a fault
  111. $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8','','','Server');
  112. }
  113. if ($this->soapfault) {
  114. return $this->soapfault->getFault();
  115. }
  116. $client =& new SOAP_Client(NULL);
  117. return $client->__parse($data, $this->xml_encoding, $this->attachments);
  118. }
  119. function service(&$data, $endpoint = '', $send_response = TRUE, $dump = FALSE)
  120. {
  121. $this->endpoint = $endpoint;
  122. $attachments = array();
  123. $headers = array();
  124. # if neither matches, we'll just try it anyway
  125. if (stristr($data,'Content-Type: application/dime')) {
  126. $this->_decodeDIMEMessage($data,$this->headers,$attachments);
  127. $useEncoding = 'DIME';
  128. } else if (stristr($data,'MIME-Version:')) {
  129. // this is a mime message, lets decode it.
  130. #$data = 'Content-Type: '.stripslashes($_SERVER['CONTENT_TYPE'])."\r\n\r\n".$data;
  131. $this->_decodeMimeMessage($data,$this->headers,$attachments);
  132. $useEncoding = 'Mime';
  133. } else {
  134. // the old fallback, but decodeMimeMessage handles things fine.
  135. $this->_parseEmail($data);
  136. }
  137. // get the character encoding of the incoming request
  138. // treat incoming data as UTF-8 if no encoding set
  139. if (!$response && !$this->_getContentEncoding($this->headers['content-type'])) {
  140. $this->xml_encoding = SOAP_DEFAULT_ENCODING;
  141. // an encoding we don't understand, return a fault
  142. $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8','','','Server');
  143. $response = $this->getFaultMessage();
  144. }
  145. if ($this->soapfault) {
  146. $response = $this->soapfault->message();
  147. } else {
  148. $soap_msg = $this->parseRequest($data,$attachments);
  149. // handle Mime or DIME encoding
  150. // XXX DIME Encoding should move to the transport, do it here for now
  151. // and for ease of getting it done
  152. if (count($this->__attachments)) {
  153. if ($useEncoding == 'Mime') {
  154. $soap_msg = $this->_makeMimeMessage($soap_msg);
  155. } else {
  156. // default is dime
  157. $soap_msg = $this->_makeDIMEMessage($soap_msg);
  158. $header['Content-Type'] = 'application/dime';
  159. }
  160. if (PEAR::isError($soap_msg)) {
  161. return $this->raiseSoapFault($soap_msg);
  162. }
  163. }
  164. if (is_array($soap_msg)) {
  165. $response = $soap_msg['body'];
  166. if (count($soap_msg['headers'])) {
  167. $headers = $soap_msg['headers'];
  168. }
  169. } else {
  170. $response = $soap_msg;
  171. }
  172. }
  173. if ($this->send_response) {
  174. if ($dump) {
  175. print $response;
  176. } else {
  177. $from = array_key_exists('reply-to',$this->headers) ? $this->headers['reply-to']:$this->headers['from'];
  178. # XXX what if no from?????
  179. $soap_transport =& SOAP_Transport::getTransport('mailto:'.$from, $this->response_encoding);
  180. $from = $this->endpoint ? $this->endpoint : $this->headers['to'];
  181. $headers['In-Reply-To']=$this->headers['message-id'];
  182. $options = array('from' => $from, 'subject'=> $this->headers['subject'], 'headers' => $headers);
  183. $soap_transport->send($response, $options);
  184. }
  185. }
  186. }
  187. }
  188. ?>