小巧灵活的WebService

Time:2010-02-05 01:40:46. Author:millken. Category:技术. Tags:webservice,作品.

去年写的,已应用的公司的邮件队列管理程序里。
支持数据加密、指定IP访问。

< ?php
//====================================================
//                FileName:        webremote.php
//                Summary:        Web Service
//                Author:                millken
//                LastModifed:2009-06-19 9:51
//                copyright (c)2009 millken@gmail.com
//====================================================
error_reporting(7);
if ( !function_exists( "json_decode" ) )
{
        function json_decode( $content, $assoc = false )
        {
                include_once( "json.php" );
                if ( $assoc )
                {
                        $json = new services_json( SERVICES_JSON_LOOSE_TYPE );
                }
                else
                {
                        $json = new services_json( );
                }
                return $json->decode( $content );
        }
}
if ( !function_exists( "json_encode" ) )
{
        function json_encode( $content )
        {
                include_once( "json.php" );
                $json = new services_json( );
                return $json->encode( $content );
        }
}
class webRemote {
        public $functions = array();
        public $debug_str = '';
        public $headers = array();
        private $config = array();
        private $url = '';
        private $options;
        private $json;
        /*
        Constructor: __construct

        Parameters:
                options - array, see options below

        Options:
                url - url for the RPC calls. Defaults to the current url.
        */

        public function __construct($url='',$options = array()) {
                $this->url = $url;
                $this->options = $options;
                $this->options['debuglevel'] = isset($this->options['debuglevel'])?$this->options['debuglevel'] : 0;
                $this->options['secret-key'] = isset($this->options['secret-key'])?$this->options['secret-key'] : '123456';
                $this->options['connection_timeout'] = isset($this->options['connection_timeout'])?$this->options['connection_timeout'] : 30;
                $this->options['response_timeout'] = isset($this->options['response_timeout'])?$this->options['response_timeout'] : 30;
                $this->config['secret-key'] = isset($this->config['secret-key'])?$this->config['secret-key']:'123456';
                $this->config['allow-ip'] = (isset($this->config['allow-ip']) && is_array($this->config['allow-ip']))?$this->config['allow-ip']:array();
                $this->debug('New webRemote object init.');
                if($this->options['debuglevel']>1) {
                $this->debug('$url='.$this->url);
                $this->debug('$options='.print_r($this->options,true));
                }
        }

        public function call($operation,$params='') {
                $url = parse_url($this->url);
                if(!$url)$this->debug("URL self::$url is not correct.");
                if(!isset($url['port'])){
                        if($url['scheme'] == 'https'){
                                $url['port'] = 443;
                        } else {
                                $url['port'] = 80;
                        }
                }
                if(!empty($params)) {
                        $call['method'] = $operation;
                        $call['params'] = $params;
                        $postdata = $this->rc4(json_encode($call),$this->options['secret-key']);
                        $postdata = 'call='.urlencode(base64_encode($postdata));
                }
                $this->debug("connect connection_timeout {$this->options['connection_timeout']}, response_timeout {$this->options['response_timeout']}, scheme {$url['scheme']}, host {$url['host']}, port {$url['port']}");
                $fp = fsockopen($url['host'], $url['port'], $errno, $errstr, $this->options['connection_timeout']);
                $header =$res = $body = '';
                if (!$fp) {
                        $this->debug('Couldn\'t open socket connection to server :'.$this->url.'>Error ('.$errno.'): '.$errstr);
                } else {
                        $this->debug('socket connected');
                        $out = "POST {$url['path']} HTTP/1.0\r\n";
                        $out .= "Host: {$url['host']}\r\n";
                        $out .= "Content-type: application/x-www-form-urlencoded\r\n";
                        $out .= "Content-Length: " . strlen($postdata) . "\r\n";
                        $out .= "Connection: Close\r\n\r\n";
                        $out .= $postdata;
                        if($this->options['debuglevel']>1) {
                                $this->debug("sent date:\n".$out);
                        }
                        fwrite($fp, $out);
                        socket_set_timeout( $fp, $this->options['response_timeout']);
                        while(!feof($fp)) {
                                $res .= fgets($fp,4096);
                        }
                        fclose($fp);
                        if($res) {
                                $separator = '/\r\n\r\n|\n\n|\r\r/';
                                list($header,$body) = preg_split($separator, $res, 2);
                                $this->headers = $header;
                                unset($header,$res,$out,$postata);
                                $body = rtrim($body,"\r\n");
                                $this->debug("response header:\n".print_r($this->headers,true));
                                $this->debug("response body:\n".print_r($body,true));
                        }else{
                                $this->debug("response is empty");
                        }
                }
                $body = json_decode($body,true);
                return $body;
        }

        public function register($function) {
                $this->functions[] = $function;
        }

        public function config($cfg=array()) {
                $this->config['secret-key'] = isset($cfg['secret-key'])?$cfg['secret-key']:'123456';
                $this->config['allow-ip'] = isset($cfg['allow-ip'])?$cfg['allow-ip']:array();
        }

        public function error($errno, $errstr){
                $this->response(array('error' => $errstr));
        }

        private function debug($string) {
                if($this->options['debuglevel']>0) {
                        $tod = gettimeofday();
                        $sec = $tod['sec'];
                        $usec = $tod['usec'];
                        $this->debug_str .=  strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec) .'>' . get_class($this) . ": $string\n";
                }
        }

        public function getDebug() {
                if($this->debug_str == '') {
                        return 'Incorrect model.';
                }else{
                        return nl2br($this->debug_str);
                }
        }
        private function response($data){
                die(json_encode($data));
        }

        public function service(){
                global $_POST;
                set_error_handler(array($this, 'error'), E_ALL);
                if(!empty($_POST['call'])) {
                        try {
                                if($this->config['allow-ip']) {
                                        if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
                                                $onlineip = getenv('HTTP_CLIENT_IP');
                                        } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
                                                $onlineip = getenv('HTTP_X_FORWARDED_FOR');
                                        } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
                                                $onlineip = getenv('REMOTE_ADDR');
                                        } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
                                                $onlineip = $_SERVER['REMOTE_ADDR'];
                                        }

                                        preg_match("/[\d\.]{7,15}/", $onlineip, $onlineipmatches);
                                        $onlineip = $onlineipmatches[0] ? $onlineipmatches[0] : 'unknown';
                                        unset($onlineipmatches);
                                        if(!in_array($onlineip,$this->config['allow-ip'])) throw new Exception("your ip has been banned .");
                                }
                                $call = $this->rc4(base64_decode($_POST['call']),$this->config['secret-key']);
                                $call = json_decode($call, true);
                                if(!is_array($call) || empty($call)) throw new Exception("secret-key is not correct.");
                                $method = $call['method'];
                                $params = $call['params'];
                                $callback = null;
                                if (is_string($method)){ // function
                                        if(!in_array($method, $this->functions)) throw new Exception("Function $function is not registered.");
                                        $callback = $method;
                                }
                                if(!is_callable($callback, false, $callable)) throw new Exception("Method is not callable.");
                                $result = call_user_func($callback, $params);
                                $this->response($result);
                        } catch (Exception $e) {
                                $this->error(1, $e->getMessage());
                        }
                }
                restore_error_handler();
        }

        private function rc4($pt, $key='') {
                $s = range(0, 255);
                $ct = '';
                for ($j=$i=0; $i<256; $i++) {
                        $j = ($j + $s[$i] + ord($key[$i % strlen($key)])) % 256;
                        $x = $s[$i];
                        $s[$i] = $s[$j];
                        $s[$j] = $x;
                }
                for ($i=$j=$y=0; $y

1 个评论

  1. rillrz
    2010-03-26 14:55:28
    SXvJOO omrhzrsrcqhr, [url=http://mupnxkmkzydh.com/]mupnxkmkzydh[/url], [link=http://kjuasdxqhzwx.com/]kjuasdxqhzwx[/link], http://ivjnvedawmdq.com/

有什么要说的?





* 所有字段必须填写.

关于我:

陈震(millken) 男 26岁 高级程序员

湖南石门人,现混迹于上海。

联系方式:millken#gmail.com

开放分类