HTTPRelay
[ class tree: HTTPRelay ] [ index: HTTPRelay ] [ all elements ]

Source for file HTTPRelay.php

Documentation is available at HTTPRelay.php

  1. <?php
  2. /**
  3.  * Project: HTTPRelay :: HTTP Relay class<br>
  4.  * File:    HTTPRelay.php
  5.  *
  6.  * HTTPRelay 패키지는 HTTP 요청을 간단하게 하거나 또는 HTTP
  7.  * 요청을 다른 서버로 Relay를 하기 위한 기능을 제공한다.
  8.  *
  9.  * 예제:
  10.  * {@example HTTPRelay/tests/test.php}
  11.  *
  12.  * @category    HTTP
  13.  * @package     HTTPRelay
  14.  * @author      JoungKyun.Kim <http://oops.org>
  15.  * @copyright   (c) 2018, OOPS.org
  16.  * @license     BSD License
  17.  * @link        http://pear.oops.org/package/HTTPRelay
  18.  * @since       File available since release 0.0.1
  19.  * @filesource
  20.  */
  21.  
  22. /**
  23.  * import myException API
  24.  */
  25. @require_once 'myException.php';
  26.  
  27. /**
  28.  * HTTPRelay 패키지는 HTTP 요청을 간단하게 하거나 또는 HTTP
  29.  * 요청을 다른 서버로 Relay를 하기 위한 기능을 제공한다.
  30.  *
  31.  * 예제:
  32.  * {@example HTTPRelay/tests/test.php}
  33.  *
  34.  * @package HTTPRelay
  35.  */
  36. Class HTTPRelay {
  37.     // {{{ properities
  38.     /**
  39.      * Default User Agent
  40.      */
  41.     const UAGENT 'OOPS HTTP Relay Wrapper 1.0';
  42.     /**#@+
  43.      * @access public
  44.      */
  45.     /**
  46.      * 에러 발생시에 에러 메시지 저장
  47.      * @var string 
  48.      */
  49.     static public $error = '';
  50.     /**
  51.      * HTTP 요청 정보 결과 저장
  52.      *
  53.      * 1.0.5 부터는 30x 반환시에 redirect를 내부 처리를 하며,
  54.      * 이 경우, $info는 2차 배열로 referer의 info 정보를 보관한다.
  55.      *
  56.      * @var array 
  57.      */
  58.     public $info = null;
  59.     /**
  60.      * Post data encoding type
  61.      *
  62.      * Post data를 어떤 방식으로 인코딩 할지를 결정한다.
  63.      * 'url-encode'와 'form-data' 둘 중의 하나로 지정을 해야 한다.
  64.      * Post data에 파일 전송을 하기 위해서는 무조건 'form-data'로
  65.      * 지정을 해야 한다.
  66.      *
  67.      * @var string 
  68.      */
  69.     public $posttype = 'url-encode';
  70.     /**
  71.      * print debug messages to stderr
  72.      *
  73.      * 디버그 메시지를 stderr로 출력한다.
  74.      *
  75.      * @var array 
  76.      */
  77.     public $debug = false;
  78.     /**#@-*/
  79.     /**
  80.      * User Define Header
  81.      *
  82.      * 사용자 Request header를 배열로 지정한다.
  83.      * 배열 키는 Header Name으로 지정하며, 배열값에는 Header의 값을 지정한다.
  84.      * 배열값을 '-'으로 지정을 하면, 빈 값으로 처리를 한다.
  85.      *
  86.      * {@example HTTPRelay/tests/test-relay.php 30 1}
  87.      *
  88.      * @access private
  89.      * @var array 
  90.      */
  91.     private $header array ();
  92.     /**
  93.      * Number of recursive calls
  94.      *
  95.      * redirect 시에 무한 루프를 방지하기 위한 counter
  96.      *
  97.      * @access private
  98.      * @var integer 
  99.      */
  100.     private $reno 0;
  101.     // }}}
  102.  
  103.     // {{{ +-- public __construct ($header = null)
  104.     /**
  105.      * HTTPRelay 초기화
  106.      *
  107.      * 예제:
  108.      * {@example HTTPRelay/tests/test-relay.php 23 6}
  109.      *
  110.      * @access public
  111.      * @param array $header (optional) 사용자 정의 HTTP Header
  112.      *    - Key는 Header 이름이어야 하며 '-'는 '_'로 표기한다.
  113.      *    - Heder값이 없어야 할 경우에는 값을 '-'로 넣어준다.
  114.      *    - Key값에 POSTTYPE을 지정할 경우, Post encoding 방식을
  115.      *      직접 지정이 가능하다. 이 경우 POSTTYPE은 HTTP Header
  116.      *      에 영향을 주지 않으며, 값으로는 'form-data'와 'url-encode'
  117.      *      중에 지정할 수 있다. POSTTYPE은 제거될 예정이니 $posttype
  118.      *      property를 직접 설정하여야 한다.
  119.      *
  120.      */
  121.     function __construct ($header null{
  122.         $this->error = &self::$error;
  123.  
  124.         // deprecated soon
  125.         if $header['POSTTYPE'{
  126.             switch ($header['POSTTYPE']{
  127.                 case 'form-data' :
  128.                 case 'url-encode' :
  129.                     $this->posttype = $header['POSTTYPE'];
  130.             }
  131.             unset ($header['POSTTYPE']);
  132.         }
  133.         // deprecated soon
  134.  
  135.         if is_array ($header) )
  136.             $this->header &$header;
  137.     }
  138.     // }}}
  139.  
  140.     // {{{ +-- public (stdClass) head ($to, $tmout = 60, $httphost = '', $recursion = false)
  141.     /**
  142.      * HTTP/1.1 HEAD 요청
  143.      *
  144.      * 예제:
  145.      * {@example HTTPRelay/tests/test-head.php}
  146.      *
  147.      * @access public
  148.      * @return stdClass 
  149.      * @param  string $to        요청할 URL
  150.      * @param  int    $tmout     (optional) timeout 값
  151.      * @param  string $httphost  (optional) HTTP/1.1 Host Header. 지정을 하지 않을 경우
  152.      *                            $to의 도메인으로 지정됨
  153.      * @param  boolean $recursion redirec 처리를 위한 재귀 호출 구분 변수 (1.0.5)
  154.      * @since 1.0.2
  155.      */
  156.     public function head ($to$tmout 60$httphost ''$recursion false{
  157.         $to trim ($to);
  158.         if $to {
  159.             self::$error 'Empty request url';
  160.             return false;
  161.         }
  162.  
  163.         if is_resource ($c curl_init ()) ) {
  164.             self:$error 'Failed initialize';
  165.             return false;
  166.         }
  167.  
  168.         $this->header['Host'self::http_host ($to$httphost);
  169.  
  170.         if $this->debug {
  171.             fprintf (STDERR"** Request URL  : %s\n"$to);
  172.             fprintf (STDERR"** Request Host : %s\n"$this->header['Host']);
  173.         }
  174.  
  175.         # header information
  176.         $header self::http_header ();
  177.  
  178.         if $this->debug )
  179.             fprintf (STDERR"** Header SET   :\n%s\n"print_r ($headertrue));
  180.  
  181.         curl_setopt ($cCURLOPT_URL$to);
  182.         curl_setopt ($cCURLOPT_TIMEOUT$tmout);
  183.         curl_setopt ($cCURLOPT_NOPROGRESS1);
  184.         curl_setopt ($cCURLOPT_RETURNTRANSFER1);
  185.         curl_setopt (
  186.             $cCURLOPT_USERAGENT,
  187.             $this->header['User_Agent'$this->header['User_Agent'self::UAGENT
  188.         );
  189.         curl_setopt ($cCURLOPT_HEADER1);
  190.         curl_setopt ($cCURLOPT_NOBODY1);
  191.         curl_setopt ($cCURLOPT_HTTPHEADER$header);
  192.         curl_setopt ($cCURLOPT_FAILONERROR1);
  193.         curl_setopt ($cCURLINFO_HEADER_OUT1);
  194.         if preg_match ('/^https:/'$to) )
  195.             curl_setopt($cCURLOPT_SSL_VERIFYPEERfalse);
  196.  
  197.         $data curl_exec ($c);
  198.         $info $this->set_return_info ($c);
  199.  
  200.         if curl_errno ($c) ) {
  201.             self::$error curl_error ($c);
  202.             curl_close ($c);
  203.             return false;
  204.         }
  205.  
  206.         curl_close ($c);
  207.  
  208.         if $recursion === true )
  209.             return trim ($data);
  210.  
  211.         if $info->http_code 400 && $info->redirect_url {
  212.             unset ($data);
  213.             $info->call_method = __FUNCTION__;
  214.             if ( ($data $this->redirect_call ($info$tmout$httphost)) === false )
  215.                 return false;
  216.         }
  217.  
  218.         $r new stdClass;
  219.         $content preg_split ('/\r\n/'trim ($data));
  220.         foreach $content as $v {
  221.             $v trim ($v);
  222.             if preg_match ('!^HTTP/([0-9.]+) ([0-9]+) (.*)!'$v$matches) ) {
  223.                 $r->{'VERSION'$matches[1];
  224.                 $r->{'RETURN-CODE'$matches[2];
  225.                 $r->{'RETURN-MSG'$matches[3];
  226.                 continue;
  227.             }
  228.             $tmp preg_split ('/:[\s]+/'$v);
  229.             $r->{$tmp[0]$tmp[1];
  230.         }
  231.  
  232.         return $r;
  233.     }
  234.     // }}}
  235.  
  236.     // {{{ +-- public (string) fetch ($to, $tmout = 60, $httphost = '', $post = null, $recursion = false)
  237.     /**
  238.      * HTML 요청의 결과를 반환한다.
  239.      *
  240.      * 예제:
  241.      * {@example HTTPRelay/tests/test.php}
  242.      *
  243.      * @access public
  244.      * @return string 
  245.      * @param  string $to        요청할 URL
  246.      * @param  int    $tmout     (optional) timeout 값
  247.      * @param  string $httphost  (optional) HTTP/1.1 Host Header. 지정을 하지 않을 경우
  248.      *                            $to의 도메인으로 지정됨
  249.      * @param  array  $post      (optional) Post방식으로 요청시 전송할 Post data
  250.      * @param  boolean $recursion redirec 처리를 위한 재귀 호출 구분 변수 (1.0.5)
  251.      */
  252.     public function fetch ($to$tmout 60$httphost ''$post null$recursion false{
  253.         if $recursion )
  254.             $this->reno 0;
  255.  
  256.         $to trim ($to);
  257.         if $to {
  258.             self::$error 'Empty request url';
  259.             return false;
  260.         }
  261.  
  262.         if is_resource ($c curl_init ()) ) {
  263.             self:$error 'Failed initialize';
  264.             return false;
  265.         }
  266.  
  267.         $this->header['Host'self::http_host ($to$httphost);
  268.  
  269.         if $this->debug {
  270.             fprintf (STDERR"** Request URL  : %s\n"$to);
  271.             fprintf (STDERR"** Request Host : %s\n"$this->header['Host']);
  272.         }
  273.  
  274.         # header information
  275.         $header self::http_header ();
  276.  
  277.         if $this->debug )
  278.             fprintf (STDERR"** Header SET   :\n%s\n"print_r ($headertrue));
  279.  
  280.         curl_setopt ($cCURLOPT_URL$to);
  281.         curl_setopt ($cCURLOPT_TIMEOUT$tmout);
  282.         curl_setopt ($cCURLOPT_NOPROGRESS1);
  283.         curl_setopt ($cCURLOPT_RETURNTRANSFER1);
  284.         curl_setopt (
  285.             $cCURLOPT_USERAGENT,
  286.             $this->header['User_Agent'$this->header['User_Agent'self::UAGENT
  287.         );
  288.         curl_setopt ($cCURLOPT_HEADER0);
  289.         curl_setopt ($cCURLOPT_NOBODY0);
  290.         curl_setopt ($cCURLOPT_HTTPHEADER$header);
  291.         curl_setopt ($cCURLOPT_FAILONERROR1);
  292.         curl_setopt ($cCURLINFO_HEADER_OUT1);
  293.         if preg_match ('/^https:/'$to) )
  294.             curl_setopt($cCURLOPT_SSL_VERIFYPEERfalse);
  295.  
  296.         if $post && is_array ($post) ) {
  297.             curl_setopt ($cCURLOPT_POST1);
  298.             if $this->posttype == 'url-encode' )
  299.                 $post http_build_query ($post);
  300.             curl_setopt ($cCURLOPT_POSTFIELDS$post);
  301.         }
  302.  
  303.         $data curl_exec ($c);
  304.         $info $this->set_return_info ($c);
  305.  
  306.         if curl_errno ($c) ) {
  307.             self::$error curl_error ($c);
  308.             curl_close ($c);
  309.             return false;
  310.         }
  311.  
  312.         curl_close ($c);
  313.  
  314.         if $info->http_code 400 && $info->redirect_url {
  315.             unset ($data);
  316.             $info->call_method = __FUNCTION__;
  317.             if ( ($data $this->redirect_call ($info$tmout$httphost$post)) === false )
  318.                 return false;
  319.         }
  320.  
  321.         return trim ($data);
  322.     }
  323.     // }}}
  324.  
  325.     // {{{ +-- public (string) relay ($to, $tmout = 60, $httphost = '', $recursion = false)
  326.     /**
  327.      * HTML 요청을 다른 호스트로 중계를 한다.
  328.      *
  329.      * 예제:
  330.      * {@example HTTPRelay/tests/test.php}
  331.      *
  332.      * @access public
  333.      * @return string 
  334.      * @param  string $to        중계할 URL
  335.      * @param  int    $tmout     (optional) timeout 값
  336.      * @param  string $httphost  (optional) HTTP/1.1 Host Header. 지정을 하지 않을 경우
  337.      *                            $to의 도메인으로 지정됨
  338.      * @param  boolean $recursion redirec 처리를 위한 재귀 호출 구분 변수 (1.0.5)
  339.      */
  340.     public function relay ($to$tmout 60$httphost ''$recursion false{
  341.         $to trim ($to);
  342.         if $to {
  343.             self::$error 'Empty request url';
  344.             return false;
  345.         }
  346.  
  347.         if is_resource ($c curl_init ()) ) {
  348.             self:$error 'Failed initialize';
  349.             return false;
  350.         }
  351.  
  352.  
  353.         $this->header['Host'self::http_host ($to$httphost);
  354.  
  355.         if $this->debug {
  356.             fprintf (STDERR"** Request URL  : %s\n"$to);
  357.             fprintf (STDERR"** Request Host : %s\n"$this->header['Host']);
  358.         }
  359.  
  360.         # basic information
  361.         $uri trim ($_SERVER['QUERY_STRING']);
  362.  
  363.         if $uri )
  364.             $uri '?' $uri;
  365.  
  366.         # header information
  367.         $header self::http_header ();
  368.  
  369.         if $this->debug )
  370.             fprintf (STDERR"** Header SET   :\n%s\n"print_r ($headertrue));
  371.  
  372.         curl_setopt ($cCURLOPT_URL$to $uri);
  373.         curl_setopt ($cCURLOPT_TIMEOUT$tmout);
  374.         curl_setopt ($cCURLOPT_NOPROGRESS1);
  375.         curl_setopt ($cCURLOPT_RETURNTRANSFER1);
  376.         curl_setopt (
  377.             $cCURLOPT_USERAGENT,
  378.             $this->header['User_Agent'$this->header['User_Agent'self::UAGENT
  379.         );
  380.         curl_setopt ($cCURLOPT_HEADER0);
  381.         curl_setopt ($cCURLOPT_NOBODY0);
  382.         curl_setopt ($cCURLOPT_HTTPHEADER$header);
  383.         curl_setopt ($cCURLOPT_FAILONERROR1);
  384.         curl_setopt ($cCURLINFO_HEADER_OUT1);
  385.         if preg_match ('/^https:/'$to) )
  386.             curl_setopt($cCURLOPT_SSL_VERIFYPEERfalse);
  387.  
  388.         self::relay_post ($c);
  389.  
  390.         $data curl_exec ($c);
  391.         $info $this->set_return_info ($c);
  392.  
  393.         if curl_errno ($c) ) {
  394.             self::$error curl_error ($c);
  395.             curl_close ($c);
  396.             return false;
  397.         }
  398.  
  399.         curl_close ($c);
  400.  
  401.         if $info->http_code 400 && $info->redirect_url {
  402.             unset ($data);
  403.             $info->call_method = __FUNCTION__;
  404.             if ( ($data $this->redirect_call ($info$tmout$httphost)) === false )
  405.                 return false;
  406.         }
  407.  
  408.         return trim ($data);
  409.     }
  410.     // }}}
  411.  
  412.     // {{{ +-- private (mixed) redirect_call (void)
  413.     /**
  414.      * @access private
  415.      * @return mixed 
  416.      */
  417.     private function redirect_call ({
  418.         if ++$this->reno {
  419.             self::$error 'Overflows 10 times redirectioins!';
  420.             return false;
  421.         }
  422.  
  423.         $arg func_get_args ();
  424.  
  425.         $to &$arg[0]->redirect_url;
  426.         $narg array ($to$arg[1]$arg[2]);
  427.         if $arg[0]->call_method == 'fetch' {
  428.             $narg[3$arg[3];
  429.             $narg[4true;
  430.         else
  431.             $narg[3true;
  432.  
  433.         if $this->debug )
  434.             fprintf (STDERR"\n** Redirect Host: %s\n"$to);
  435.  
  436.         $this->header['Referer'$arg[0]->url;
  437.  
  438.         $callback_func array ($this$arg[0]->call_method);
  439.         unset ($arg);
  440.         if ( ($data call_user_func_array ($callback_func$narg)) === false )
  441.             return false;
  442.  
  443.         return $data;
  444.     }
  445.     // }}}
  446.  
  447.     // {{{ +-- private (stdClass) set_return_info ($c)
  448.     /**
  449.      * @access private
  450.      * @return stdClass 
  451.      */
  452.     private function set_return_info ($c{
  453.         if is_resource ($c) )
  454.             return new stdClass;
  455.  
  456.         $info curl_getinfo ($c);
  457.  
  458.         if $this->reno == )
  459.             $this->info $info;
  460.         else if $this->reno == {
  461.             $old $this->info;
  462.             unset ($this->info);
  463.             $this->info[0$old;
  464.             $this->info[1$info;
  465.         else
  466.             $this->info[$this->reno$info;
  467.  
  468.         return (object) $info;
  469.     }
  470.     // }}}
  471.  
  472.     // {{{ +-- private (array) http_header (void)
  473.     /**
  474.      * 사용자 정의 헤더와 기본 헤더를 셋팅 한다.
  475.      *
  476.      * @access private
  477.      * @return array 
  478.      */
  479.     private function http_header ({
  480.         foreach $this->header as $name => $val {
  481.             if $name == 'User_Agent' )
  482.                 continue;
  483.  
  484.             self::set_header ($header$name$val);
  485.         }
  486.  
  487.         if isset ($this->header['Expect']) )
  488.             self::set_header ($header'Expect''-');
  489.             
  490.         if $this->header['Accept_Language')
  491.             self::set_header ($header'Accept-Language''ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4');
  492.  
  493.         if $this->header['Connection')
  494.             self::set_header ($header'Connection''close');
  495.  
  496.         if $relay {
  497.         }
  498.         self::client_ip_set ($header);
  499.  
  500.         return $header;
  501.     }
  502.     // }}}
  503.  
  504.     // {{{ +-- private (void) set_header (&$h, $d, $v)
  505.     /**
  506.      * 헤더를 셋팅한다. 헤더 값이 '-'로 지정이 될 경우, 해당 헤더는
  507.      * 빈 값을 가지는 헤더로 처리를 한다.
  508.      *
  509.      * @access private
  510.      * @return void 
  511.      * @param array 헤더를 저장할 변수
  512.      * @param string 헤더 이름
  513.      * @param string 헤더 값. '-' 값을 가지면, 빈 값을 가지는 헤더라는 의미로 처리된다.
  514.      */
  515.     private function set_header (&$h$d$v{
  516.         if trim ($d|| trim ($v) )
  517.             return;
  518.  
  519.         $d @trim ($d);
  520.         $v @trim ($v);
  521.  
  522.         if $v == '-' )
  523.             $v '';
  524.  
  525.         $d preg_replace ('/_/''-'$d);
  526.  
  527.         $h[$d ': ' $v;
  528.     }
  529.     // }}}
  530.  
  531.     // {{{ +-- private (string) http_host ($t, $h)
  532.     /**
  533.      * HTTP/1.1 Host header에서 사용할 hostname을 구한다.
  534.      * Hostname (2번째 인자)가 따로 지정되지 않으면 주어진 Full URL(1번째 인자)
  535.      * 에서 hostname을 구한다.
  536.      *
  537.      * @access private
  538.      * @return string 
  539.      * @param string   전체 URL
  540.      * @param string   HTTP/1.1 Host header 값
  541.      */
  542.     private function http_host ($t$h ''{
  543.         if $h{
  544.             $src array ('!^https?://!i''!/.*!');
  545.             $dsc array ('''');
  546.             $h preg_replace ($src$dsc$t);
  547.         }
  548.  
  549.         return $h;
  550.     }
  551.     // }}}
  552.  
  553.     // {{{ +-- private (void) relay_post (&$c)
  554.     /**
  555.      * Post로 넘어온 Data를 relay하기 위한 post data template
  556.      *
  557.      * @access private
  558.      * @return void 
  559.      * @param resource CURL resource
  560.      */
  561.     private function relay_post (&$c{
  562.         if $_SERVER['REQUEST_METHOD'!= 'POST' )
  563.             return;
  564.  
  565.         $post array ();
  566.  
  567.         if is_array ($_FILES['file']) ) {
  568.             $post['file'"@{$_FILES['file']['tmp_name']}";
  569.             $this->posttype 'form-data';
  570.         }
  571.         $post array_merge ($post$_POST);
  572.  
  573.         if $this->posttype == 'url-encode' )
  574.             $post http_build_query ($post);
  575.  
  576.         curl_setopt ($cCURLOPT_POST1);
  577.         curl_setopt ($cCURLOPT_POSTFIELDS$post);
  578.     }
  579.     // }}}
  580.  
  581.     // {{{ +-- private (void) client_ip_set (&$h, $ip = null)
  582.     /**
  583.      * Relay를 위한 Client IP 주소 설정
  584.      *
  585.      * @access private
  586.      * @return void 
  587.      * @param array 헤더 저장 변수
  588.      * @param string (optional) IP 주소
  589.      */
  590.     private function client_ip_set (&$h$ip null{
  591.         if php_sapi_name (== 'cli' )
  592.             return;
  593.  
  594.         if $ip == null )
  595.             $v $_SERVER['HTTP_X_FORWARDED_FOR'$_SERVER['HTTP_X_FORWARDED_FOR'$_SERVER['REMOTE_ADDR'];
  596.         else {
  597.             if $_SERVER['HTTP_X_FORWARDED_FOR')
  598.                 $v $ip ', ' $_SERVER['HTTP_X_FORWARDED_FOR'];
  599.             else
  600.                 $v $ip ', ' $_SERVER['REMOTE_ADDR'];
  601.         }
  602.  
  603.         if $v )
  604.             self::set_header ($h'X-Forwarded-For'$v);
  605.     }
  606.     // }}}
  607. }
  608.  
  609. // {{{ +-- public HTTPRelay_REQUIRES (void)
  610. /**
  611.  * HTTRelay 패키지에서 필요한 의존성을 검사한다.
  612.  *
  613.  * @access public
  614.  * @return void 
  615.  */
  616. function HTTPRelay_REQUIRES ({
  617.     $br PHP_EOL;
  618.     if PHP_SAPI != 'cli' )
  619.         $br '<br>' PHP_EOL;
  620.     $brbr $br $br;
  621.  
  622.     if class_exists ('myException') ) {
  623.         $msg $brbr .
  624.             '-------------------------------------------------' $brbr .
  625.             'HTTPRelay ERROR!' $brbr .
  626.             'HTTPRelay class needs oops/myException pear package' $br .
  627.             'You can get myException pear package at' $br .
  628.             'http://mirror.oops.org/pub/oops/php/pear/myException/' $br .
  629.             'Also you can install with pear command as follow command' $br .
  630.             'shell> pear channel-discover pear.oops.org' $br .
  631.             'shell> pear install oops/myException' $brbr .
  632.             '-------------------------------------------------' $brbr;
  633.         throw new Exception ($msgE_USER_ERROR);
  634.     }
  635.  
  636.     if extension_loaded ('curl') ) {
  637.         $br PHP_EOL;
  638.         if PHP_SAPI != 'cli' )
  639.             $br '<br>' PHP_EOL;
  640.         $brbr $br $br;
  641.  
  642.         $msg $brbr .
  643.             '-------------------------------------------------' $brbr .
  644.             'HTTPRelay ERROR!' $br .
  645.             'HTTPRelay class needs curl extension' $brbr .
  646.             '-------------------------------------------------' $brbr;
  647.         throw new myException ($msgE_USER_ERROR);
  648.     }
  649. }
  650. // }}}
  651.  
  652. /*
  653.  * Local variables:
  654.  * tab-width: 4
  655.  * c-basic-offset: 4
  656.  * End:
  657.  * vim: set filetype=php noet sw=4 ts=4 fdm=marker:
  658.  * vim600: noet sw=4 ts=4 fdm=marker
  659.  * vim<600: noet sw=4 ts=4
  660.  */
  661. ?>

Documentation generated on Tue, 14 May 2019 02:00:07 +0900 by phpDocumentor 1.4.4