      1: <?php
      2:
      3: namespace SMSApi\Proxy\Http;
      4:
      5: use SMSApi\Api\Action\AbstractAction;
      6: use SMSApi\Exception\ProxyException;
      7: use SMSApi\Proxy\Uri;
      8:
      9: abstract class AbstractHttp
     10: {
     11:     protected $protocol;
     12:     protected $host;
     13:     protected $port;
     14:     protected $boundary = '**RGRG87VFSGF86796GSD**';
     15:     protected $method = "POST";
     16:     protected $timeout = 5;
     17:     protected $maxRedirects = 1;
     18:
     19:     /**
     20:      * @deprecated - no usages
     21:      */
     22:     protected $uri;
     23:
     24:     /**
     25:      * @deprecated - no usages
     26:      */
     27:     protected $file;
     28:
     29:     /**
     30:      * @deprecated - no usages
     31:      */
     32:     protected $userAgent = "SMSAPI";
     33:
     34:     /**
     35:      * @deprecated - no usages
     36:      */
     37:     protected $headers = array();
     38:
     39:     public function __construct( $host ) {
     40:
     41:         $tmp = explode( "://", $host );
     42:
     43:         if ( isset( $tmp[ 0 ] ) ) {
     44:             $this->protocol = $tmp[ 0 ];
     45:             if ( $this->protocol == "http" ) {
     46:                 $this->port = 80;
     47:             } else if ( $this->protocol == "https" ) {
     48:                 $this->port = 443;
     49:             }
     50:         }
     51:
     52:         if ( isset( $tmp[ 1 ] ) ) {
     53:             $this->host = $tmp[ 1 ];
     54:         }
     55:     }
     56:
     57:     public function getHost()
     58:     {
     59:         return $this->host;
     60:     }
     61:
     62:     public function getPort()
     63:     {
     64:         return $this->port;
     65:     }
     66:
     67:     public function getProtocol()
     68:     {
     69:         return $this->protocol;
     70:     }
     71:
     72:     public function execute(AbstractAction $action)
     73:     {
     74:         try {
     75:             $uri = $action->uri();
     76:             $file = $action->file();
     77:
     78:             if ($uri == null) {
     79:                 throw new ProxyException("Invalid URI");
     80:             }
     81:
     82:             $url = $this->prepareRequestUrl($uri);
     83:
     84:             $query = $uri->getQuery();
     85:
     86:             $response = $this->makeRequest($url, $query, $file);
     87:
     88:             $this->checkCode($response['code']);
     89:
     90:             if (empty($response['output'])) {
     91:                 throw new ProxyException('Error fetching remote content empty');
     92:             }
     93:         } catch (\Exception $e) {
     94:             throw new ProxyException($e->getMessage());
     95:         }
     96:
     97:         return $response['output'];
     98:     }
     99:
    100:     abstract protected function makeRequest($url, $query, $file);
    101:
    102:     protected function checkCode($code)
    103:     {
    104:         if ($code AND $code < 200 OR $code > 299) {
    105:             throw new ProxyException('Error fetching remote');
    106:         }
    107:     }
    108:
    109:     protected function detectFileMimeType( $file ) {
    110:         $type = null;
    111:
    112:         if ( function_exists( 'finfo_open' ) ) {
    113:             $fo = finfo_open( FILEINFO_MIME );
    114:             if ( $fo ) {
    115:                 $type = finfo_file( $fo, $file );
    116:             }
    117:         } elseif ( function_exists( 'mime_content_type' ) ) {
    118:             $type = mime_content_type( $file );
    119:         }
    120:
    121:         if ( !$type ) {
    122:             $type = 'application/octet-stream';
    123:         }
    124:
    125:         return $type;
    126:     }
    127:
    128:     protected function encodeFormData( $boundary, $name, $value, $filename = null, $headers = array( ) ) {
    129:         $ret = "--{$boundary}\r\n" .
    130:             'Content-Disposition: form-data; name="' . $name . '"';
    131:
    132:         if ( $filename ) {
    133:             $ret .= '; filename="' . $filename . '"';
    134:         }
    135:         $ret .= "\r\n";
    136:
    137:         foreach ( $headers as $hname => $hvalue ) {
    138:             $ret .= "{$hname}: {$hvalue}\r\n";
    139:         }
    140:         $ret .= "\r\n";
    141:         $ret .= "{$value}\r\n";
    142:
    143:         return $ret;
    144:     }
    145:
    146:     protected function prepareFileContent( $filename ) {
    147:
    148:         $file[ 'formname' ] = 'file';
    149:         $file[ 'data' ] = file_get_contents( $filename );
    150:         $file[ 'filename' ] = basename( $filename );
    151:         $file[ 'ctype' ] = $this->detectFileMimeType( $filename );
    152:         $fhead = array( 'Content-Type' => $file[ 'ctype' ] );
    153:
    154:         $body = $this->encodeFormData( $this->boundary, $file[ 'formname' ], $file[ 'data' ], $file[ 'filename' ], $fhead );
    155:
    156:         $body .= "--{$this->boundary}--\r\n";
    157:
    158:         return $body;
    159:     }
    160:
    161:     protected function renderQueryByBody( $query, $body ) {
    162:
    163:         $tmpBody = "";
    164:
    165:         if ( !empty( $query ) && !empty( $body ) ) {
    166:             $params = array( );
    167:             parse_str( $query, $params );
    168:             foreach ( $params as $k2 => $v2 ) {
    169:                 $tmpBody .= $this->encodeFormData( $this->boundary, $k2, $v2 );
    170:             }
    171:         } else {
    172:             $tmpBody = $query;
    173:         }
    174:
    175:         if ( !empty( $body ) ) {
    176:             $tmpBody .= $body;
    177:         }
    178:
    179:         return $tmpBody;
    180:     }
    181:
    182:     /**
    183:      * @param Uri $uri
    184:      * @return string
    185:      */
    186:     protected function prepareRequestUrl(Uri $uri)
    187:     {
    188:         $url = $uri->getSchema() . "://" . $uri->getHost() . $uri->getPath();
    189:         return $url;
    190:     }
    191:
    192:     /**
    193:      * @param $file
    194:      * @return string
    195:      */
    196:     protected function prepareRequestBody($file)
    197:     {
    198:         $body = "";
    199:
    200:         if ($this->isFileValid($file)) {
    201:             $body = $this->prepareFileContent($file);
    202:         }
    203:
    204:         return $body;
    205:     }
    206:
    207:     private function isFileValid($file)
    208:     {
    209:         return !empty($file) && file_exists($file);
    210:     }
    211:
    212:     /**
    213:      * @param $file
    214:      * @return array
    215:      */
    216:     protected function prepareRequestHeaders($file)
    217:     {
    218:         $headers = array();
    219:
    220:         $headers['User-Agent'] = 'SMSApi';
    221:         $headers['Accept'] = '';
    222:
    223:         if ($this->isFileValid($file)) {
    224:             $headers['Content-Type'] = 'multipart/form-data; boundary=' . $this->boundary;
    225:         } else {
    226:             $headers['Content-Type'] = 'application/x-www-form-urlencoded';
    227:         }
    228:
    229:         return $headers;
    230:     }
    231: }
    232: