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

Revision 2, 14.6 KB checked in by niltonneto, 17 years ago (diff)

Removida todas as tags usadas pelo CVS ($Id, $Source).
Primeira versão no CVS externo.

  • 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                                        for($request_body = '',Reset($values),$value=0;$value<count($values);Next($values),$value++)
268                                        {
269                                                if($value>0)
270                                                {
271                                                        $request_body .= '&';
272                                                }
273                                                $request_body.=Key($values).'='.UrlEncode($values[Key($values)]);
274                                        }
275                                        $headers['Content-type'] = 'application/x-www-form-urlencoded';
276                                }
277                        }
278                        if(strlen($this->proxy_host_name) == 0)
279                        {
280                                $request_uri = $this->request_uri;
281                        }
282                        else
283                        {
284                                $request_uri = 'http://'.$this->host_name.($this->host_port==80 ? '' : ':'.$this->host_port).$this->request_uri;
285                        }
286                        if(($success = $this->PutLine($this->request_method.' '.$request_uri.' HTTP/'.$this->protocol_version)))
287                        {
288                                if(($body_length = strlen($request_body)))
289                                {
290                                        $headers['Content-length'] = $body_length;
291                                }
292                                for($host_set=0,Reset($headers),$header=0;$header<count($headers);Next($headers),$header++)
293                                {
294                                        $header_name  = Key($headers);
295                                        $header_value = $headers[$header_name];
296                                        if(@is_array($header_value))
297                                        {
298                                                for(Reset($header_value),$value=0;$value<count($header_value);Next($header_value),$value++)
299                                                {
300                                                        if(!$success = $this->PutLine("$header_name: ".$header_value[Key($header_value)]))
301                                                        {
302                                                                break 2;
303                                                        }
304                                                }
305                                        }
306                                        else
307                                        {
308                                                if(!$success = $this->PutLine("$header_name: $header_value"))
309                                                {
310                                                        break;
311                                                }
312                                        }
313                                        if(strtolower(Key($headers)) == 'host')
314                                        {
315                                                $this->request_host = strtolower($header_value);
316                                                $host_set = 1;
317                                        }
318                                }
319                                if($success)
320                                {
321                                        if(!$host_set)
322                                        {
323                                                $success = $this->PutLine('Host: '.$this->host_name);
324                                                $this->request_host = strtolower($this->host_name);
325                                        }
326                                        if(count($this->cookies) && IsSet($this->cookies[0]))
327                                        {
328                                                $now = gmdate('Y-m-d H-i-s');
329                                                for($cookies = array(),$domain=0,Reset($this->cookies[0]);$domain<count($this->cookies[0]);Next($this->cookies[0]),$domain++)
330                                                {
331                                                        $domain_pattern = Key($this->cookies[0]);
332                                                        $match = strlen($this->request_host)-strlen($domain_pattern);
333                                                        if($match >= 0 &&
334                                                                !strcmp($domain_pattern,substr($this->request_host,$match)) &&
335                                                                ($match == 0 || $domain_pattern[0] == '.' || $this->request_host[$match-1] == '.'))
336                                                        {
337                                                                for(Reset($this->cookies[0][$domain_pattern]),$path_part=0;$path_part<count($this->cookies[0][$domain_pattern]);Next($this->cookies[0][$domain_pattern]),$path_part++)
338                                                                {
339                                                                        $path = Key($this->cookies[0][$domain_pattern]);
340                                                                        if(strlen($this->request_uri) >= strlen($path) && substr($this->request_uri,0,strlen($path)) == $path)
341                                                                        {
342                                                                                for(Reset($this->cookies[0][$domain_pattern][$path]),$cookie = 0;$cookie<count($this->cookies[0][$domain_pattern][$path]);Next($this->cookies[0][$domain_pattern][$path]),$cookie++)
343                                                                                {
344                                                                                        $cookie_name = Key($this->cookies[0][$domain_pattern][$path]);
345                                                                                        $expires     = $this->cookies[0][$domain_pattern][$path][$cookie_name]['expires'];
346                                                                                        if($expires == '' || strcmp($now,$expires)<0)
347                                                                                        {
348                                                                                                $cookies[$cookie_name] = $this->cookies[0][$domain_pattern][$path][$cookie_name];
349                                                                                        }
350                                                                                }
351                                                                        }
352                                                                }
353                                                        }
354                                                }
355                                                for(Reset($cookies),$cookie=0;$cookie<count($cookies);Next($cookies),$cookie++)
356                                                {
357                                                        $cookie_name = Key($cookies);
358                                                        if(!($success = $this->PutLine('Cookie: '.UrlEncode($cookie_name).'='.$cookies[$cookie_name]['value'].';')))
359                                                        {
360                                                                break;
361                                                        }
362                                                }
363                                        }
364                                        if($success)
365                                        {
366                                                if($success)
367                                                {
368                                                        $success = $this->PutLine('');
369                                                        if($body_length && $success)
370                                                        {
371                                                                $success = $this->PutData($request_body);
372                                                        }
373                                                }
374                                        }
375                                }
376                        }
377                        if(!$success)
378                        {
379                                return('5 could not send the HTTP request');
380                        }
381                        $this->state = 'RequestSent';
382                        return('');
383                }
384
385                function ReadReplyHeaders(&$headers)
386                {
387                        switch($this->state)
388                        {
389                                case 'Disconnected':
390                                        return('1 connection was not yet established');
391                                case 'Connected':
392                                        return('2 request was not sent');
393                                case 'RequestSent':
394                                        break;
395                                default:
396                                        return('3 can not get request headers in the current connection state');
397                        }
398                        $headers = array();
399                        $this->content_length = $this->read_length = 0;
400                        $this->content_length_set = 0;
401                        for(;;)
402                        {
403                                $line = $this->GetLine();
404                                if(!is_string($line))
405                                {
406                                        return('4 could not read request reply');
407                                }
408                                if($line == '')
409                                {
410                                        $this->state = 'GotReplyHeaders';
411                                        return('');
412                                }
413                                $header_name  = strtolower(strtok($line,':'));
414                                $header_value = Trim(Chop(strtok("\r\n")));
415                                if(IsSet($headers[$header_name]))
416                                {
417                                        if(is_string($headers[$header_name]))
418                                        {
419                                                $headers[$header_name] = array($headers[$header_name]);
420                                        }
421                                        $headers[$header_name][] = $header_value;
422                                }
423                                else
424                                {
425                                        $headers[$header_name] = $header_value;
426                                }
427                                switch($header_name)
428                                {
429                                        case 'content-length':
430                                        $this->content_length = (int)$headers[$header_name];
431                                        $this->content_length_set = 1;
432                                        break;
433                                        case 'set-cookie':
434                                        if($this->support_cookies)
435                                        {
436                                                $cookie_name  = trim(strtok($headers[$header_name],'='));
437                                                $cookie_value = strtok(';');
438                                                $domain = $this->request_host;
439                                                $path = '/';
440                                                $expires = '';
441                                                $secure = 0;
442                                                while(($name=strtolower(trim(strtok('=')))) != '')
443                                                {
444                                                        $value=UrlDecode(strtok(';'));
445                                                        switch($name)
446                                                        {
447                                                                case 'domain':
448                                                                        if($value == '' || !strpos($value,'.',$value[0] == '.'))
449                                                                        {
450                                                                                break;
451                                                                        }
452                                                                        $domain = strtolower($value);
453                                                                        break;
454                                                                case 'path':
455                                                                        if($value != '' && $value[0] == '/')
456                                                                        {
457                                                                                $path = $value;
458                                                                        }
459                                                                        break;
460                                                                case 'expires':
461                                                                        if(ereg("^((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))
462                                                                        {
463                                                                                $year = (int)$matches[5];
464                                                                                if($year<1900)
465                                                                                {
466                                                                                        $year += ($year<70 ? 2000 : 1900);
467                                                                                }
468                                                                                $expires = "$year-".$this->months[$matches[4]].'-'.$matches[3].' '.$matches[6].':'.$matches[7].':'.$matches[8];
469                                                                        }
470                                                                        break;
471                                                                case 'secure':
472                                                                        $secure = 1;
473                                                                        break;
474                                                        }
475                                                }
476                                                $this->cookies[$secure][$domain][$path][$cookie_name] = array(
477                                                        'name'    => $cookie_name,
478                                                        'value'   => $cookie_value,
479                                                        'domain'  => $domain,
480                                                        'path'    => $path,
481                                                        'expires' => $expires,
482                                                        'secure'  => $secure
483                                                );
484                                        }
485                                }
486                        }
487                }
488
489                function ReadReplyBody(&$body,$length)
490                {
491                        switch($this->state)
492                        {
493                                case 'Disconnected':
494                                        return('1 connection was not yet established');
495                                case 'Connected':
496                                        return('2 request was not sent');
497                                case 'RequestSent':
498                                        if(($error = $this->ReadReplyHeaders(&$headers)) != '')
499                                        {
500                                                return($error);
501                                        }
502                                        break;
503                                case 'GotReplyHeaders':
504                                        break;
505                                default:
506                                        return('3 can not get request headers in the current connection state');
507                        }
508                        $body = '';
509                        if($this->content_length_set)
510                        {
511                                $length = min($this->content_length-$this->read_length,$length);
512                        }
513                        if($length>0 && !$this->EndOfInput() && ($body = $this->ReadBytes($length)) == '')
514                        {
515                                return('4 could not get the request reply body');
516                        }
517                        return('');
518                }
519
520                function GetPersistentCookies(&$cookies)
521                {
522                        $now = gmdate('Y-m-d H-i-s');
523                        $cookies = array();
524                        for($secure_cookies = 0,Reset($this->cookies);$secure_cookies<count($this->cookies);Next($this->cookies),$secure_cookies++)
525                        {
526                                $secure = Key($this->cookies);
527                                for($domain = 0,Reset($this->cookies[$secure]);$domain<count($this->cookies[$secure]);Next($this->cookies[$secure]),$domain++)
528                                {
529                                        $domain_pattern = Key($this->cookies[$secure]);
530                                        for(Reset($this->cookies[$secure][$domain_pattern]),$path_part=0;$path_part<count($this->cookies[$secure][$domain_pattern]);Next($this->cookies[$secure][$domain_pattern]),$path_part++)
531                                        {
532                                                $path=Key($this->cookies[$secure][$domain_pattern]);
533                                                for(Reset($this->cookies[$secure][$domain_pattern][$path]),$cookie=0;$cookie<count($this->cookies[$secure][$domain_pattern][$path]);Next($this->cookies[$secure][$domain_pattern][$path]),$cookie++)
534                                                {
535                                                        $cookie_name = Key($this->cookies[$secure][$domain_pattern][$path]);
536                                                        $expires     = $this->cookies[$secure][$domain_pattern][$path][$cookie_name]['expires'];
537                                                        if($expires != '' && strcmp($now,$expires)<0)
538                                                        {
539                                                                $cookies[$secure][$domain_pattern][$path][$cookie_name] = $this->cookies[$secure][$domain_pattern][$path][$cookie_name];
540                                                        }
541                                                }
542                                        }
543                                }
544                        }
545                }
546        }
Note: See TracBrowser for help on using the repository browser.