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: