Subversion Repositories Applications.annuaire

Rev

Rev 42 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
42 aurelien 1
<?php
2
 
3
/**
4
 * This module contains the plain non-curl HTTP fetcher
5
 * implementation.
6
 *
7
 * PHP versions 4 and 5
8
 *
9
 * LICENSE: See the COPYING file included in this distribution.
10
 *
11
 * @package Yadis
12
 * @author JanRain, Inc. <openid@janrain.com>
13
 * @copyright 2005 Janrain, Inc.
14
 * @license http://www.gnu.org/copyleft/lesser.html LGPL
15
 */
16
 
17
/**
18
 * Interface import
19
 */
20
require_once "Services/Yadis/HTTPFetcher.php";
21
 
22
/**
23
 * This class implements a plain, hand-built socket-based fetcher
24
 * which will be used in the event that CURL is unavailable.
25
 *
26
 * @package Yadis
27
 */
28
class Services_Yadis_PlainHTTPFetcher extends Services_Yadis_HTTPFetcher {
29
    function get($url, $extra_headers = null)
30
    {
31
        if (!$this->allowedURL($url)) {
32
            trigger_error("Bad URL scheme in url: " . $url,
33
                          E_USER_WARNING);
34
            return null;
35
        }
36
 
37
        $redir = true;
38
 
39
        $stop = time() + $this->timeout;
40
        $off = $this->timeout;
41
 
42
        while ($redir && ($off > 0)) {
43
 
44
            $parts = parse_url($url);
45
 
46
            $specify_port = true;
47
 
48
            // Set a default port.
49
            if (!array_key_exists('port', $parts)) {
50
                $specify_port = false;
51
                if ($parts['scheme'] == 'http') {
52
                    $parts['port'] = 80;
53
                } elseif ($parts['scheme'] == 'https') {
54
                    $parts['port'] = 443;
55
                } else {
56
                    trigger_error("fetcher post method doesn't support " .
57
                                  " scheme '" . $parts['scheme'] .
58
                                  "', no default port available",
59
                                  E_USER_WARNING);
60
                    return null;
61
                }
62
            }
63
 
64
            $host = $parts['host'];
65
 
66
            if ($parts['scheme'] == 'https') {
67
                $host = 'ssl://' . $host;
68
            }
69
 
70
            $user_agent = "PHP Yadis Library Fetcher";
71
 
72
            $headers = array(
73
                             "GET ".$parts['path'].
74
                             (array_key_exists('query', $parts) ?
75
                              "?".$parts['query'] : "").
76
                                 " HTTP/1.0",
77
                             "User-Agent: $user_agent",
78
                             "Host: ".$parts['host'].
79
                                ($specify_port ? ":".$parts['port'] : ""),
80
                             "Port: ".$parts['port']);
81
 
82
            $errno = 0;
83
            $errstr = '';
84
 
85
            if ($extra_headers) {
86
                foreach ($extra_headers as $h) {
87
                    $headers[] = $h;
88
                }
89
            }
90
 
91
            @$sock = fsockopen($host, $parts['port'], $errno, $errstr,
92
                               $this->timeout);
93
            if ($sock === false) {
94
                return false;
95
            }
96
 
97
            stream_set_timeout($sock, $this->timeout);
98
 
99
            fputs($sock, implode("\r\n", $headers) . "\r\n\r\n");
100
 
101
            $data = "";
102
            while (!feof($sock)) {
103
                $data .= fgets($sock, 1024);
104
            }
105
 
106
            fclose($sock);
107
 
108
            // Split response into header and body sections
109
            list($headers, $body) = explode("\r\n\r\n", $data, 2);
110
            $headers = explode("\r\n", $headers);
111
 
112
            $http_code = explode(" ", $headers[0]);
113
            $code = $http_code[1];
114
 
115
            if (in_array($code, array('301', '302'))) {
116
                $url = $this->_findRedirect($headers);
117
                $redir = true;
118
            } else {
119
                $redir = false;
120
            }
121
 
122
            $off = $stop - time();
123
        }
124
 
125
        $new_headers = array();
126
 
127
        foreach ($headers as $header) {
128
            if (preg_match("/:/", $header)) {
129
                list($name, $value) = explode(": ", $header, 2);
130
                $new_headers[$name] = $value;
131
            }
132
 
133
        }
134
 
135
        return new Services_Yadis_HTTPResponse($url, $code, $new_headers, $body);
136
    }
137
 
138
    function post($url, $body, $extra_headers = null)
139
    {
140
        if (!$this->allowedURL($url)) {
141
            trigger_error("Bad URL scheme in url: " . $url,
142
                          E_USER_WARNING);
143
            return null;
144
        }
145
 
146
        $parts = parse_url($url);
147
 
148
        $headers = array();
149
 
150
        $post_path = $parts['path'];
151
        if (isset($parts['query'])) {
152
            $post_path .= '?' . $parts['query'];
153
        }
154
 
155
        $headers[] = "POST ".$post_path." HTTP/1.0";
156
        $headers[] = "Host: " . $parts['host'];
157
        $headers[] = "Content-type: application/x-www-form-urlencoded";
158
        $headers[] = "Content-length: " . strval(strlen($body));
159
 
160
        if ($extra_headers &&
161
            is_array($extra_headers)) {
162
            $headers = array_merge($headers, $extra_headers);
163
        }
164
 
165
        // Join all headers together.
166
        $all_headers = implode("\r\n", $headers);
167
 
168
        // Add headers, two newlines, and request body.
169
        $request = $all_headers . "\r\n\r\n" . $body;
170
 
171
        // Set a default port.
172
        if (!array_key_exists('port', $parts)) {
173
            if ($parts['scheme'] == 'http') {
174
                $parts['port'] = 80;
175
            } elseif ($parts['scheme'] == 'https') {
176
                $parts['port'] = 443;
177
            } else {
178
                trigger_error("fetcher post method doesn't support scheme '" .
179
                              $parts['scheme'] .
180
                              "', no default port available",
181
                              E_USER_WARNING);
182
                return null;
183
            }
184
        }
185
 
186
        if ($parts['scheme'] == 'https') {
187
            $parts['host'] = sprintf("ssl://%s", $parts['host']);
188
        }
189
 
190
        // Connect to the remote server.
191
        $errno = 0;
192
        $errstr = '';
193
 
194
        $sock = fsockopen($parts['host'], $parts['port'], $errno, $errstr,
195
                          $this->timeout);
196
 
197
        if ($sock === false) {
198
            trigger_error("Could not connect to " . $parts['host'] .
199
                          " port " . $parts['port'],
200
                          E_USER_WARNING);
201
            return null;
202
        }
203
 
204
        stream_set_timeout($sock, $this->timeout);
205
 
206
        // Write the POST request.
207
        fputs($sock, $request);
208
 
209
        // Get the response from the server.
210
        $response = "";
211
        while (!feof($sock)) {
212
            if ($data = fgets($sock, 128)) {
213
                $response .= $data;
214
            } else {
215
                break;
216
            }
217
        }
218
 
219
        // Split the request into headers and body.
220
        list($headers, $response_body) = explode("\r\n\r\n", $response, 2);
221
 
222
        $headers = explode("\r\n", $headers);
223
 
224
        // Expect the first line of the headers data to be something
225
        // like HTTP/1.1 200 OK.  Split the line on spaces and take
226
        // the second token, which should be the return code.
227
        $http_code = explode(" ", $headers[0]);
228
        $code = $http_code[1];
229
 
230
        $new_headers = array();
231
 
232
        foreach ($headers as $header) {
233
            if (preg_match("/:/", $header)) {
234
                list($name, $value) = explode(": ", $header, 2);
235
                $new_headers[$name] = $value;
236
            }
237
 
238
        }
239
 
240
        return new Services_Yadis_HTTPResponse($url, $code,
241
                                               $headers, $response_body);
242
    }
243
}
244
 
245
?>