Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * This file contains the class moodle_google_curlio.
19
 *
20
 * @package core_google
21
 * @copyright 2013 Frédéric Massart
22
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
defined('MOODLE_INTERNAL') || die();
26
 
27
require_once($CFG->libdir . '/filelib.php');
28
 
29
/**
30
 * Class moodle_google_curlio.
31
 *
32
 * The initial purpose of this class is to add support for our
33
 * class curl in Google_IO_Curl. It mostly entirely overrides it.
34
 *
35
 * @package core_google
36
 * @copyright 2013 Frédéric Massart
37
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
*/
39
class moodle_google_curlio extends Google_IO_Curl {
40
 
41
    /** @var array associate array of constant value and their name. */
42
    private static $constants = null;
43
 
44
    /** @var array options. */
45
    private $options = array();
46
 
47
    /**
48
     * Send the request via our curl object.
49
     *
50
     * @param curl $curl prepared curl object.
51
     * @param Google_HttpRequest $request The request.
52
     * @return string result of the request.
53
     */
54
    private function do_request($curl, $request) {
55
        $url = $request->getUrl();
56
        $method = $request->getRequestMethod();
57
        switch (strtoupper($method)) {
58
            case 'POST':
59
                $ret = $curl->post($url, $request->getPostBody());
60
                break;
61
            case 'GET':
62
                $ret = $curl->get($url);
63
                break;
64
            case 'HEAD':
65
                $ret = $curl->head($url);
66
                break;
67
            case 'PUT':
68
                $ret = $curl->put($url);
69
                break;
70
            default:
71
                throw new coding_exception('Unknown request type: ' . $method);
72
                break;
73
        }
74
        return $ret;
75
    }
76
 
77
    /**
78
     * Execute an API request.
79
     *
80
     * This is a copy/paste from the parent class that uses Moodle's implementation
81
     * of curl. Portions have been removed or altered.
82
     *
83
     * @param Google_Http_Request $request the http request to be executed
84
     * @return Google_Http_Request http request with the response http code, response
85
     * headers and response body filled in
86
     * @throws Google_IO_Exception on curl or IO error
87
     */
88
    public function executeRequest(Google_Http_Request $request) {
89
        $curl = new curl();
90
 
91
        if ($request->getPostBody()) {
92
            $curl->setopt(array('CURLOPT_POSTFIELDS' => $request->getPostBody()));
93
        }
94
 
95
        $requestHeaders = $request->getRequestHeaders();
96
        if ($requestHeaders && is_array($requestHeaders)) {
97
            $curlHeaders = array();
98
            foreach ($requestHeaders as $k => $v) {
99
                $curlHeaders[] = "$k: $v";
100
            }
101
            $curl->setopt(array('CURLOPT_HTTPHEADER' => $curlHeaders));
102
        }
103
 
104
        $curl->setopt(array('CURLOPT_URL' => $request->getUrl()));
105
 
106
        $curl->setopt(array('CURLOPT_CUSTOMREQUEST' => $request->getRequestMethod()));
107
        $curl->setopt(array('CURLOPT_USERAGENT' => $request->getUserAgent()));
108
 
109
        $curl->setopt(array('CURLOPT_FOLLOWLOCATION' => false));
110
        $curl->setopt(array('CURLOPT_SSL_VERIFYPEER' => true));
111
        $curl->setopt(array('CURLOPT_RETURNTRANSFER' => true));
112
        $curl->setopt(array('CURLOPT_HEADER' => true));
113
 
114
        if ($request->canGzip()) {
115
            $curl->setopt(array('CURLOPT_ENCODING' => 'gzip,deflate'));
116
        }
117
 
118
        $curl->setopt($this->options);
119
        $respdata = $this->do_request($curl, $request);
120
 
121
        $infos = $curl->get_info();
122
        $respheadersize = $infos['header_size'];
123
        $resphttpcode = (int) $infos['http_code'];
124
        $curlerrornum = $curl->get_errno();
125
        $curlerror = $curl->error;
126
 
127
        if ($curlerrornum != CURLE_OK) {
128
            throw new Google_IO_Exception($curlerror);
129
        }
130
 
131
        list($responseHeaders, $responseBody) = $this->parseHttpResponse($respdata, $respheadersize);
132
        return array($responseBody, $responseHeaders, $resphttpcode);
133
    }
134
 
135
    /**
136
     * Set curl options.
137
     *
138
     * We overwrite this method to ensure that the data passed meets
139
     * the requirement of our curl implementation and so that the keys
140
     * are strings, and not curl constants.
141
     *
142
     * @param array $optparams Multiple options used by a cURL session.
143
     * @return void
144
     */
145
    public function setOptions($optparams) {
146
        $safeparams = array();
147
        foreach ($optparams as $name => $value) {
148
            if (!is_string($name)) {
149
                $name = $this->get_option_name_from_constant($name);
150
            }
151
            $safeparams[$name] = $value;
152
        }
153
        $this->options = $options + $this->options;
154
    }
155
 
156
    /**
157
     * Set the maximum request time in seconds.
158
     *
159
     * Overridden to use the right option key.
160
     *
161
     * @param $timeout in seconds
162
     */
163
    public function setTimeout($timeout) {
164
        // Since this timeout is really for putting a bound on the time
165
        // we'll set them both to the same. If you need to specify a longer
166
        // CURLOPT_TIMEOUT, or a tigher CONNECTTIMEOUT, the best thing to
167
        // do is use the setOptions method for the values individually.
168
        $this->options['CURLOPT_CONNECTTIMEOUT'] = $timeout;
169
        $this->options['CURLOPT_TIMEOUT'] = $timeout;
170
    }
171
 
172
    /**
173
     * Get the maximum request time in seconds.
174
     *
175
     * Overridden to use the right option key.
176
     *
177
     * @return timeout in seconds.
178
     */
179
    public function getTimeout() {
180
       return $this->options['CURLOPT_TIMEOUT'];
181
    }
182
 
183
    /**
184
     * Return the name of an option based on the constant value.
185
     *
186
     * @param int $constant value of a CURL constant.
187
     * @return string name of the constant if found, or throws exception.
188
     * @throws coding_exception when the constant is not found.
189
     * @since Moodle 2.5
190
     */
191
    public function get_option_name_from_constant($constant) {
192
        if (is_null(self::$constants)) {
193
            $constants = get_defined_constants(true);
194
            $constants = isset($constants['curl']) ? $constants['curl'] : array();
195
            $constants = array_flip($constants);
196
            self::$constants = $constants;
197
        }
198
        if (isset(self::$constants[$constant])) {
199
            return self::$constants[$constant];
200
        }
201
        throw new coding_exception('Unknown curl constant value: ' . $constant);
202
    }
203
 
204
}