1: <?php
  2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37: 
 38: namespace MOC\Module\Network\Http;
 39: use MOC\Api;
 40: use MOC\Generic\Device\Module;
 41: 
 42:  43:  44: 
 45: class Post implements Module {
 46:      47:  48:  49:  50:  51: 
 52:     public static function InterfaceChangelog() {
 53:         return Api::Core()->Changelog();
 54:     }
 55: 
 56:      57:  58:  59:  60:  61: 
 62:     public static function InterfaceDepending() {
 63:         return Api::Core()->Depending();
 64:     }
 65: 
 66:      67:  68:  69:  70:  71: 
 72:     public static function InterfaceInstance() {
 73:         return new Post();
 74:     }
 75: 
 76:      77:  78:  79:  80:  81: 
 82:     public function Request( $Url, $Data = array() ) {
 83: 
 84:         $Uri = Uri::InterfaceInstance()->Load( $Url );
 85: 
 86:         foreach( (array)$Data as $Key => $Value ) {
 87:             $Uri->UriQuery()->Set( $Key, $Value );
 88:         }
 89: 
 90:         $Header =  "POST ".$Uri->GetPath()." HTTP/1.1\r\n";
 91:         $Header .= "Host: ".$Uri->GetHost()."\r\n";
 92:         $Header .= "Content-Type: ".'application/x-www-form-urlencoded'."\r\n";
 93:         $Header .= "Content-Length: ".strlen( $Uri->UriQuery()->GetQueryString() )."\r\n";
 94:         $Header .= "Connection: close"."\r\n\r\n";
 95: 
 96:         $Body = $Uri->UriQuery()->GetQueryString();
 97: 
 98: 
 99:         $ErrorId = 0;
100:         $ErrorMessage = '';
101:         $Buffer = '';
102: 
103:         Api::Core()->Error()->Reporting()->Display(false)->Debug(false)->Apply();
104: 
105:         if( ( $Socket = fsockopen( $Uri->GetHost(), $Uri->GetPort(), $ErrorId, $ErrorMessage, 15 ) ) ) {
106:             fwrite( $Socket, $Header.$Body );
107:             while( !feof( $Socket ) ) {
108:                 stream_set_timeout( $Socket, 15 );
109:                 if( false === ( $Stream = fread( $Socket, 128 ) ) ) {
110:                     $Buffer = '';
111:                     break;
112:                 } else {
113:                     $Buffer .= $Stream;
114:                 }
115:             }
116:             fclose( $Socket );
117:         }
118: 
119: 
120:         $Buffer = explode( "\r\n\r\n", $Buffer );
121:         $ResponseHeader = explode( "\r\n", array_shift( $Buffer ) );
122:         $ResponseBody = implode( "\r\n\r\n", $Buffer );
123:         if( in_array( 'Transfer-Encoding: chunked', $ResponseHeader ) ) {
124:             $ResponseBody = $this->http_chunked_decode( $ResponseBody );
125:         }
126:         return $ResponseBody;
127:     }
128: 
129:     130: 131: 132: 133: 
134:     private function http_chunked_decode( $Encoded ) {
135:         if( function_exists( 'http_chunked_decode' ) ) {
136:             return http_chunked_decode( $Encoded );
137:         } else {
138:             $Position = 0;
139:             $Length = strlen( $Encoded );
140:             $Decoded = null;
141: 
142:             while(
143:                 ( $Position < $Length )
144:                 && ( $ChunkLength = substr(
145:                     $Encoded, $Position,
146:                         ( $PositionNewLine = strpos( $Encoded, "\n", $Position +1 ) )
147:                         - $Position )
148:                 )
149:             ) {
150:                 $Position = $PositionNewLine + 1;
151:                 $ChunkWidth = hexdec( rtrim( $ChunkLength, "\r\n" ) );
152:                 $Decoded .= substr( $Encoded, $Position, $ChunkWidth );
153:                 $Position = strpos( $Encoded, "\n", $Position + $ChunkWidth ) +1;
154:             }
155:             return $Decoded;
156:         }
157:     }
158: }
159: 
160: 161: 162: 
163: class UriQuery implements Module {
164:     165: 166: 167: 168: 169: 
170:     public static function InterfaceChangelog() {
171:         return Api::Core()->Changelog()->Create( __CLASS__ );
172:     }
173: 
174:     175: 176: 177: 178: 179: 
180:     public static function InterfaceDepending() {
181:         return Api::Core()->Depending();
182:     }
183: 
184:     185: 186: 187: 188: 189: 
190:     public static function InterfaceInstance() {
191:         return new UriQuery();
192:     }
193: 
194:     private $QueryContent = array();
195: 
196:     public function Load( $QueryString ) {
197:         $QueryPartList = explode( '&', $QueryString );
198:         foreach( (array)$QueryPartList as $QueryPart ) {
199:             $Key = substr( $QueryPart, 0, strpos( $QueryPart, '=' ) );
200:             $Value = substr( $QueryPart, strpos( $QueryPart, '=' ) +1 );
201:             $this->QueryContent[$Key] = $Value;
202:         }
203:         return $this;
204:     }
205: 
206:     public function Get( $Key ) {
207:         return $this->QueryContent[$Key];
208:     }
209: 
210:     public function Set( $Key, $Value ) {
211:         $this->QueryContent[$Key] = $Value;
212:         return $this;
213:     }
214: 
215:     public function GetQueryString() {
216:         $QueryString = '';
217:         foreach( (array)$this->QueryContent as $Key => $Value ) {
218:             $QueryString .= '&'.$Key.'='.$Value;
219:         }
220:         return substr( $QueryString, 1 );
221:     }
222: 
223:     224: 225: 
226:     function __toString() {
227:         return $this->GetQueryString();
228:     }
229: }
230: 
231: 232: 233: 
234: class UriScheme implements Module {
235:     236: 237: 238: 239: 240: 
241:     public static function InterfaceChangelog() {
242:         return Api::Core()->Changelog()->Create( __CLASS__ );
243:     }
244: 
245:     246: 247: 248: 249: 250: 
251:     public static function InterfaceDepending() {
252:         return Api::Core()->Depending();
253:     }
254: 
255:     256: 257: 258: 259: 260: 
261:     public static function InterfaceInstance() {
262:         return new UriScheme();
263:     }
264: 
265:     private $UriScheme = '';
266: 
267:     public function Load( $UriScheme ) {
268:         $this->UriScheme = $UriScheme;
269:         return $this;
270:     }
271: 
272:     public function Http() {
273:         $this->UriScheme = 'http';
274:         return $this;
275:     }
276:     public function Https() {
277:         $this->UriScheme = 'https';
278:         return $this;
279:     }
280:     public function Ftp() {
281:         $this->UriScheme = 'ftp';
282:         return $this;
283:     }
284: 
285:     public function GetSchemeString() {
286:         return $this->UriScheme;
287:     }
288: 
289:     290: 291: 
292:     function __toString() {
293:         return $this->GetSchemeString();
294:     }
295: }
296: 
297: 298: 299: 
300: class Uri implements Module {
301: 
302:     303: 304: 305: 306: 307: 
308:     public static function InterfaceChangelog() {
309:         return Api::Core()->Changelog()->Create( __CLASS__ );
310:     }
311: 
312:     313: 314: 315: 316: 317: 
318:     public static function InterfaceDepending() {
319:         return Api::Core()->Depending();
320:     }
321: 
322:     323: 324: 325: 326: 327: 
328:     public static function InterfaceInstance() {
329:         $Instance = new Uri();
330:         $Instance->Scheme = UriScheme::InterfaceInstance()->Http();
331:         $Instance->Query = UriQuery::InterfaceInstance();
332:         return $Instance;
333:     }
334: 
335:     
336:     private $Scheme = null;
337:     private $Host = 'localhost';
338:     private $Port = 80;
339:     private $Path = '/';
340:     
341:     private $Query = null;
342:     private $Fragment = '';
343: 
344:     345: 346: 347: 348: 
349:     public function Load( $UriString ) {
350:         $UriComponentList = parse_url( $UriString );
351:         
352:         if( isset( $UriComponentList['scheme'] ) ) { $this->Scheme = UriScheme::InterfaceInstance()->Load( $UriComponentList['scheme'] ); }
353:         if( isset( $UriComponentList['host'] ) ) { $this->Host = $UriComponentList['host']; }
354:         if( isset( $UriComponentList['port'] ) ) { $this->Port = $UriComponentList['port']; }
355:         if( isset( $UriComponentList['path'] ) ) { $this->Path = $UriComponentList['path']; }
356:         if( isset( $UriComponentList['query'] ) ) { $this->Query = UriQuery::InterfaceInstance()->Load( $UriComponentList['query'] ); }
357:         if( isset( $UriComponentList['fragment'] ) ) { $this->Fragment = $UriComponentList['fragment']; }
358: 
359:         return $this;
360:     }
361: 
362:     public function UriScheme() {
363:         return  $this->Scheme;
364:     }
365:     public function UriQuery() {
366:         return  $this->Query;
367:     }
368: 
369:     public function GetPath() {
370:         return $this->Path;
371:     }
372:     public function GetHost() {
373:         return $this->Host;
374:     }
375:     public function GetPort() {
376:         return $this->Port;
377:     }
378: 
379:     380: 381: 
382:     public function GetUriString() {
383:         return $this->Scheme->GetSchemeString().'://'
384:             .$this->Host
385:             .(!empty($this->Port)?':'.$this->Port:'')
386:             .$this->Path
387:             .(!empty($this->Query)?'?'.$this->Query->GetQueryString():'')
388:             .(!empty($this->Fragment)?'#'.$this->Fragment:'');
389:     }
390: 
391:     392: 393: 
394:     function __toString() {
395:         return $this->GetUriString();
396:     }
397: }
398: