source: trunk/phpgwapi/inc/class.http.inc.php @ 7673

Revision 7673, 15.1 KB checked in by douglasz, 11 years ago (diff)

Ticket #3236 - Correcoes para Performance: Function Within Loop Declaration.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2  /**************************************************************************\
3  * eGroupWare API - HTTP protocol class                                     *
4  * http://www.egroupware.org/api                                            *
5  * ------------------------------------------------------------------------ *
6  * This is not part of eGroupWare, but is used by eGroupWare.               *
7  * ------------------------------------------------------------------------ *
8  * This program is free software; you can redistribute it and/or modify it  *
9  * under the terms of the GNU General Public License as published by the    *
10  * Free Software Foundation; either version 2 of the License, or (at your   *
11  * option) any later version.                                               *
12  \**************************************************************************/
13
14
15        class http
16        {
17                var $host_name = '';
18                var $host_port = 80;
19                var $proxy_host_name = '';
20                var $proxy_host_port = 80;
21
22                var $request_method = 'GET';
23                var $user_agent = 'Manuel Lemos HTTP class test script';
24                var $request_uri = '';
25                var $protocol_version = '1.0';
26                var $debug = 0;
27                var $support_cookies = 1;
28                var $cookies = array();
29
30                /* private variables - DO NOT ACCESS */
31
32                var $state = 'Disconnected';
33                var $connection = 0;
34                var $content_length = 0;
35                var $read_length = 0;
36                var $request_host = '';
37                var $months = array(
38                        'Jan' => '01',
39                        'Feb' => '02',
40                        'Mar' => '03',
41                        'Apr' => '04',
42                        'May' => '05',
43                        'Jun' => '06',
44                        'Jul' => '07',
45                        'Aug' => '08',
46                        'Sep' => '09',
47                        'Oct' => '10',
48                        'Nov' => '11',
49                        'Dec' => '12'
50                );
51
52                /* Private methods - DO NOT CALL */
53
54                function OutputDebug($message)
55                {
56                        echo $message,"\n";
57                }
58
59                function GetLine()
60                {
61                        for($line='';;)
62                        {
63                                if(feof($this->connection) || !($part=fgets($this->connection,100)))
64                                {
65                                        return(0);
66                                }
67                                $line.=$part;
68                                $length=strlen($line);
69                                if($length>=2 && substr($line,$length-2,2)=="\r\n")
70                                {
71                                        $line=substr($line,0,$length-2);
72                                        if($this->debug)
73                                        {
74                                                $this->OutputDebug("< $line");
75                                        }
76                                        return($line);
77                                }
78                        }
79                }
80
81                function PutLine($line)
82                {
83                        if($this->debug)
84                        {
85                                $this->OutputDebug("> $line");
86                        }
87                        return(fputs($this->connection,"$line\r\n"));
88                }
89
90                function PutData($data)
91                {
92                        if($this->debug)
93                        {
94                                $this->OutputDebug("> $data");
95                        }
96                        return(fputs($this->connection,$data));
97                }
98
99                function Readbytes($length)
100                {
101                        if($this->debug)
102                        {
103                                if(($bytes=fread($this->connection,$length))!="")
104                                {
105                                        $this->OutputDebug("< $bytes");
106                                }
107                                return($bytes);
108                        }
109                        else
110                        {
111                                return(fread($this->connection,$length));
112                        }
113                }
114
115                function EndOfInput()
116                {
117                        return(feof($this->connection));
118                }
119
120                function Connect($host_name,$host_port)
121                {
122                        if($this->debug)
123                        {
124                                $this->OutputDebug("Connecting to $host_name...");
125                        }
126                        if(($this->connection=fsockopen($host_name,$host_port,&$error))==0)
127                        {
128                                switch($error)
129                                {
130                                        case -3:
131                                                return('-3 socket could not be created');
132                                        case -4:
133                                                return('-4 dns lookup on hostname "'.$host_name.'" failed');
134                                        case -5:
135                                                return('-5 connection refused or timed out');
136                                        case -6:
137                                                return('-6 fdopen() call failed');
138                                        case -7:
139                                                return('-7 setvbuf() call failed');
140                                        default:
141                                                return($error.' could not connect to the host "'.$host_name.'"');
142                                }
143                        }
144                        else
145                        {
146                                if($this->debug)
147                                {
148                                        $this->OutputDebug("Connected to $host_name");
149                                }
150                                $this->state='Connected';
151                                return("");
152                        }
153                }
154
155                function Disconnect()
156                {
157                        if($this->debug)
158                        {
159                                $this->OutputDebug('Disconnected from '.$this->host_name);
160                        }
161                        fclose($this->connection);
162                        return('');
163                }
164
165                /* Public methods */
166
167                function Open($arguments)
168                {
169                        if($this->state!='Disconnected')
170                        {
171                                return('1 already connected');
172                        }
173                        if(IsSet($arguments['HostName']))
174                        {
175                                $this->host_name=$arguments['HostName'];
176                        }
177                        if(IsSet($arguments['HostPort']))
178                        {
179                                $this->host_port=$arguments['HostPort'];
180                        }
181                        if(IsSet($arguments['ProxyHostName']))
182                        {
183                                $this->proxy_host_name=$arguments['ProxyHostName'];
184                        }
185                        if(IsSet($arguments['ProxyHostPort']))
186                        {
187                                $this->proxy_host_port=$arguments['ProxyHostPort'];
188                        }
189                        if(strlen($this->proxy_host_name)==0)
190                        {
191                                if(strlen($this->host_name)==0)
192                                {
193                                        return('2 it was not specified a valid hostname');
194                                }
195                                $host_name = $this->host_name;
196                                $host_port = $this->host_port;
197                        }
198                        else
199                        {
200                                $host_name = $this->proxy_host_name;
201                                $host_port = $this->proxy_host_port;
202                        }
203                        $error = $this->Connect($host_name,$host_port);
204                        if(strlen($error)==0)
205                        {
206                                $this->state = 'Connected';
207                        }
208                        return($error);
209                }
210
211                function Close()
212                {
213                        if($this->state == 'Disconnected')
214                        {
215                                return('1 already disconnected');
216                        }
217                        $error = $this->Disconnect();
218                        if(strlen($error) == 0)
219                        {
220                                $this->state = 'Disconnected';
221                        }
222                        return($error);
223                }
224
225                function SendRequest($arguments)
226                {
227                        switch($this->state)
228                        {
229                                case 'Disconnected':
230                                        return('1 connection was not yet established');
231                                case 'Connected':
232                                        break;
233                                default:
234                                        return('2 can not send request in the current connection state');
235                        }
236                        if(IsSet($arguments['RequestMethod']))
237                        {
238                                $this->request_method = $arguments['RequestMethod'];
239                        }
240                        if(IsSet($arguments['User-Agent']))
241                        {
242                                $this->user_agent = $arguments['User-Agent'];
243                        }
244                        if(strlen($this->request_method) == 0)
245                        {
246                                return('3 it was not specified a valid request method');
247                        }
248                        if(IsSet($arguments['RequestURI']))
249                        {
250                                $this->request_uri = $arguments['RequestURI'];
251                        }
252                        if(strlen($this->request_uri) == 0 || substr($this->request_uri,0,1) != '/')
253                        {
254                                return('4 it was not specified a valid request URI');
255                        }
256                        $request_body = '';
257                        $headers=(IsSet($arguments['Headers']) ? $arguments['Headers'] : array());
258                        if($this->request_method == 'POST')
259                        {
260                                if(IsSet($arguments['PostValues']))
261                                {
262                                        $values = $arguments['PostValues'];
263                                        if(!@is_array($values))
264                                        {
265                                                return('5 it was not specified a valid POST method values array');
266                                        }
267                    $values_count = count($values);
268                                        for($request_body = '',Reset($values),$value=0;$value<$values_count;Next($values),$value++)
269                                        {
270                                                if($value>0)
271                                                {
272                                                        $request_body .= '&';
273                                                }
274                                                $request_body.=Key($values).'='.UrlEncode($values[Key($values)]);
275                                        }
276                                        $headers['Content-type'] = 'application/x-www-form-urlencoded';
277                                }
278                        }
279                        if(strlen($this->proxy_host_name) == 0)
280                        {
281                                $request_uri = $this->request_uri;
282                        }
283                        else
284                        {
285                                $request_uri = 'http://'.$this->host_name.($this->host_port==80 ? '' : ':'.$this->host_port).$this->request_uri;
286                        }
287                        if(($success = $this->PutLine($this->request_method.' '.$request_uri.' HTTP/'.$this->protocol_version)))
288                        {
289                                if(($body_length = strlen($request_body)))
290                                {
291                                        $headers['Content-length'] = $body_length;
292                                }
293                                for($host_set=0,Reset($headers),$header=0;$header<count($headers);Next($headers),$header++)
294                                {
295                                        $header_name  = Key($headers);
296                                        $header_value = $headers[$header_name];
297                                        if(@is_array($header_value))
298                                        {
299                        $header_value_count = count($header_value);
300                                                for(Reset($header_value),$value=0;$value<$header_value_count;Next($header_value),$value++)
301                                                {
302                                                        if(!$success = $this->PutLine("$header_name: ".$header_value[Key($header_value)]))
303                                                        {
304                                                                break 2;
305                                                        }
306                                                }
307                                        }
308                                        else
309                                        {
310                                                if(!$success = $this->PutLine("$header_name: $header_value"))
311                                                {
312                                                        break;
313                                                }
314                                        }
315                                        if(strtolower(Key($headers)) == 'host')
316                                        {
317                                                $this->request_host = strtolower($header_value);
318                                                $host_set = 1;
319                                        }
320                                }
321                                if($success)
322                                {
323                                        if(!$host_set)
324                                        {
325                                                $success = $this->PutLine('Host: '.$this->host_name);
326                                                $this->request_host = strtolower($this->host_name);
327                                        }
328                                        if(count($this->cookies) && IsSet($this->cookies[0]))
329                                        {
330                                                $now = gmdate('Y-m-d H-i-s');
331                        $cookies_count = count($this->cookies[0]);
332                                                for($cookies = array(),$domain=0,Reset($this->cookies[0]);$domain<$cookies_count;Next($this->cookies[0]),$domain++)
333                                                {
334                                                        $domain_pattern = Key($this->cookies[0]);
335                                                        $match = strlen($this->request_host)-strlen($domain_pattern);
336                                                        if($match >= 0 &&
337                                                                !strcmp($domain_pattern,substr($this->request_host,$match)) &&
338                                                                ($match == 0 || $domain_pattern[0] == '.' || $this->request_host[$match-1] == '.'))
339                                                        {
340                                $cookies_count = count($this->cookies[0][$domain_pattern]);
341                                                                for(Reset($this->cookies[0][$domain_pattern]),$path_part=0;$path_part<$cookies_count;Next($this->cookies[0][$domain_pattern]),$path_part++)
342                                                                {
343                                                                        $path = Key($this->cookies[0][$domain_pattern]);
344                                                                        if(strlen($this->request_uri) >= strlen($path) && substr($this->request_uri,0,strlen($path)) == $path)
345                                                                        {
346                                        $cookies_count = count($this->cookies[0][$domain_pattern][$path]);
347                                                                                for(Reset($this->cookies[0][$domain_pattern][$path]),$cookie = 0;$cookie<$cookies_count;Next($this->cookies[0][$domain_pattern][$path]),$cookie++)
348                                                                                {
349                                                                                        $cookie_name = Key($this->cookies[0][$domain_pattern][$path]);
350                                                                                        $expires     = $this->cookies[0][$domain_pattern][$path][$cookie_name]['expires'];
351                                                                                        if($expires == '' || strcmp($now,$expires)<0)
352                                                                                        {
353                                                                                                $cookies[$cookie_name] = $this->cookies[0][$domain_pattern][$path][$cookie_name];
354                                                                                        }
355                                                                                }
356                                                                        }
357                                                                }
358                                                        }
359                                                }
360                        $cookies_count = count($cookies);
361                                                for(Reset($cookies),$cookie=0;$cookie<$cookies_count;Next($cookies),$cookie++)
362                                                {
363                                                        $cookie_name = Key($cookies);
364                                                        if(!($success = $this->PutLine('Cookie: '.UrlEncode($cookie_name).'='.$cookies[$cookie_name]['value'].';')))
365                                                        {
366                                                                break;
367                                                        }
368                                                }
369                                        }
370                                        if($success)
371                                        {
372                                                if($success)
373                                                {
374                                                        $success = $this->PutLine('');
375                                                        if($body_length && $success)
376                                                        {
377                                                                $success = $this->PutData($request_body);
378                                                        }
379                                                }
380                                        }
381                                }
382                        }
383                        if(!$success)
384                        {
385                                return('5 could not send the HTTP request');
386                        }
387                        $this->state = 'RequestSent';
388                        return('');
389                }
390
391                function ReadReplyHeaders(&$headers)
392                {
393                        switch($this->state)
394                        {
395                                case 'Disconnected':
396                                        return('1 connection was not yet established');
397                                case 'Connected':
398                                        return('2 request was not sent');
399                                case 'RequestSent':
400                                        break;
401                                default:
402                                        return('3 can not get request headers in the current connection state');
403                        }
404                        $headers = array();
405                        $this->content_length = $this->read_length = 0;
406                        $this->content_length_set = 0;
407                        for(;;)
408                        {
409                                $line = $this->GetLine();
410                                if(!is_string($line))
411                                {
412                                        return('4 could not read request reply');
413                                }
414                                if($line == '')
415                                {
416                                        $this->state = 'GotReplyHeaders';
417                                        return('');
418                                }
419                                $header_name  = strtolower(strtok($line,':'));
420                                $header_value = Trim(Chop(strtok("\r\n")));
421                                if(IsSet($headers[$header_name]))
422                                {
423                                        if(is_string($headers[$header_name]))
424                                        {
425                                                $headers[$header_name] = array($headers[$header_name]);
426                                        }
427                                        $headers[$header_name][] = $header_value;
428                                }
429                                else
430                                {
431                                        $headers[$header_name] = $header_value;
432                                }
433                                switch($header_name)
434                                {
435                                        case 'content-length':
436                                        $this->content_length = (int)$headers[$header_name];
437                                        $this->content_length_set = 1;
438                                        break;
439                                        case 'set-cookie':
440                                        if($this->support_cookies)
441                                        {
442                                                $cookie_name  = trim(strtok($headers[$header_name],'='));
443                                                $cookie_value = strtok(';');
444                                                $domain = $this->request_host;
445                                                $path = '/';
446                                                $expires = '';
447                                                $secure = 0;
448                                                while(($name=strtolower(trim(strtok('=')))) != '')
449                                                {
450                                                        $value=UrlDecode(strtok(';'));
451                                                        switch($name)
452                                                        {
453                                                                case 'domain':
454                                                                        if($value == '' || !strpos($value,'.',$value[0] == '.'))
455                                                                        {
456                                                                                break;
457                                                                        }
458                                                                        $domain = strtolower($value);
459                                                                        break;
460                                                                case 'path':
461                                                                        if($value != '' && $value[0] == '/')
462                                                                        {
463                                                                                $path = $value;
464                                                                        }
465                                                                        break;
466                                                                case 'expires':
467                                                                        if(preg_match('/^((Mon|Monday|Tue|Tuesday|Wed|Wednesday|Thu|Thursday|Fri|Friday|Sat|Saturday|Sun|Sunday), )?([0-9]{2})\\-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\-([0-9]{2,4}) ([0-9]{2})\\:([0-9]{2})\\:([0-9]{2}) GMT$/',$value,$matches))
468                                                                        {
469                                                                                $year = (int)$matches[5];
470                                                                                if($year<1900)
471                                                                                {
472                                                                                        $year += ($year<70 ? 2000 : 1900);
473                                                                                }
474                                                                                $expires = "$year-".$this->months[$matches[4]].'-'.$matches[3].' '.$matches[6].':'.$matches[7].':'.$matches[8];
475                                                                        }
476                                                                        break;
477                                                                case 'secure':
478                                                                        $secure = 1;
479                                                                        break;
480                                                        }
481                                                }
482                                                $this->cookies[$secure][$domain][$path][$cookie_name] = array(
483                                                        'name'    => $cookie_name,
484                                                        'value'   => $cookie_value,
485                                                        'domain'  => $domain,
486                                                        'path'    => $path,
487                                                        'expires' => $expires,
488                                                        'secure'  => $secure
489                                                );
490                                        }
491                                }
492                        }
493                }
494
495                function ReadReplyBody(&$body,$length)
496                {
497                        switch($this->state)
498                        {
499                                case 'Disconnected':
500                                        return('1 connection was not yet established');
501                                case 'Connected':
502                                        return('2 request was not sent');
503                                case 'RequestSent':
504                                        if(($error = $this->ReadReplyHeaders(&$headers)) != '')
505                                        {
506                                                return($error);
507                                        }
508                                        break;
509                                case 'GotReplyHeaders':
510                                        break;
511                                default:
512                                        return('3 can not get request headers in the current connection state');
513                        }
514                        $body = '';
515                        if($this->content_length_set)
516                        {
517                                $length = min($this->content_length-$this->read_length,$length);
518                        }
519                        if($length>0 && !$this->EndOfInput() && ($body = $this->ReadBytes($length)) == '')
520                        {
521                                return('4 could not get the request reply body');
522                        }
523                        return('');
524                }
525
526                function GetPersistentCookies(&$cookies)
527                {
528                        $now = gmdate('Y-m-d H-i-s');
529                        $cookies = array();
530                        for($secure_cookies = 0,Reset($this->cookies);$secure_cookies<count($this->cookies);Next($this->cookies),$secure_cookies++)
531                        {
532                                $secure = Key($this->cookies);
533                $cookies_count = count($this->cookies[$secure]);
534                                for($domain = 0,Reset($this->cookies[$secure]);$domain<$cookies_count;Next($this->cookies[$secure]),$domain++)
535                                {
536                                        $domain_pattern = Key($this->cookies[$secure]);
537                    $cookies_count = count($this->cookies[$secure][$domain_pattern]);
538                                        for(Reset($this->cookies[$secure][$domain_pattern]),$path_part=0;$path_part<$cookies_count;Next($this->cookies[$secure][$domain_pattern]),$path_part++)
539                                        {
540                                                $path=Key($this->cookies[$secure][$domain_pattern]);
541                        $cookies_count = count($this->cookies[$secure][$domain_pattern][$path]);
542                                                for(Reset($this->cookies[$secure][$domain_pattern][$path]),$cookie=0;$cookie<$cookies_count;Next($this->cookies[$secure][$domain_pattern][$path]),$cookie++)
543                                                {
544                                                        $cookie_name = Key($this->cookies[$secure][$domain_pattern][$path]);
545                                                        $expires     = $this->cookies[$secure][$domain_pattern][$path][$cookie_name]['expires'];
546                                                        if($expires != '' && strcmp($now,$expires)<0)
547                                                        {
548                                                                $cookies[$secure][$domain_pattern][$path][$cookie_name] = $this->cookies[$secure][$domain_pattern][$path][$cookie_name];
549                                                        }
550                                                }
551                                        }
552                                }
553                        }
554                }
555        }
Note: See TracBrowser for help on using the repository browser.