1<?php
2
3/**
4 * Licensed to Jasig under one or more contributor license
5 * agreements. See the NOTICE file distributed with this work for
6 * additional information regarding copyright ownership.
7 *
8 * Jasig licenses this file to you under the Apache License,
9 * Version 2.0 (the "License"); you may not use this file except in
10 * compliance with the License. You may obtain a copy of the License at:
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 * PHP Version 7
21 *
22 * @file     CAS/Request/CurlRequest.php
23 * @category Authentication
24 * @package  PhpCAS
25 * @author   Adam Franco <afranco@middlebury.edu>
26 * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
27 * @link     https://wiki.jasig.org/display/CASC/phpCAS
28 */
29
30/**
31 * Provides support for performing web-requests via curl
32 *
33 * @class    CAS_Request_CurlRequest
34 * @category Authentication
35 * @package  PhpCAS
36 * @author   Adam Franco <afranco@middlebury.edu>
37 * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
38 * @link     https://wiki.jasig.org/display/CASC/phpCAS
39 */
40class CAS_Request_CurlRequest
41extends CAS_Request_AbstractRequest
42implements CAS_Request_RequestInterface
43{
44
45    /**
46     * Set additional curl options
47     *
48     * @param array $options option to set
49     *
50     * @return void
51     */
52    public function setCurlOptions (array $options)
53    {
54        $this->_curlOptions = $options;
55    }
56    private $_curlOptions = array();
57
58    /**
59     * Send the request and store the results.
60     *
61     * @return bool true on success, false on failure.
62     */
63    protected function sendRequest ()
64    {
65        phpCAS::traceBegin();
66
67        /*********************************************************
68         * initialize the CURL session
69        *********************************************************/
70        $ch = $this->initAndConfigure();
71
72        /*********************************************************
73         * Perform the query
74        *********************************************************/
75        $buf = curl_exec($ch);
76        if ( $buf === false ) {
77            phpCAS::trace('curl_exec() failed');
78            $this->storeErrorMessage(
79                'CURL error #'.curl_errno($ch).': '.curl_error($ch)
80            );
81            $res = false;
82        } else {
83            $this->storeResponseBody($buf);
84            phpCAS::trace("Response Body: \n".$buf."\n");
85            $res = true;
86
87        }
88        // close the CURL session
89        curl_close($ch);
90
91        phpCAS::traceEnd($res);
92        return $res;
93    }
94
95    /**
96     * Internal method to initialize our cURL handle and configure the request.
97     * This method should NOT be used outside of the CurlRequest or the
98     * CurlMultiRequest.
99     *
100     * @return resource|false The cURL handle on success, false on failure
101     */
102    public function initAndConfigure()
103    {
104        /*********************************************************
105         * initialize the CURL session
106        *********************************************************/
107        $ch = curl_init($this->url);
108
109        curl_setopt_array($ch, $this->_curlOptions);
110
111        /*********************************************************
112         * Set SSL configuration
113        *********************************************************/
114        if ($this->caCertPath) {
115            if ($this->validateCN) {
116                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
117            } else {
118                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
119            }
120            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
121            curl_setopt($ch, CURLOPT_CAINFO, $this->caCertPath);
122            phpCAS::trace('CURL: Set CURLOPT_CAINFO ' . $this->caCertPath);
123        } else {
124            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
125            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
126        }
127
128        /*********************************************************
129         * Configure curl to capture our output.
130        *********************************************************/
131        // return the CURL output into a variable
132        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
133
134        // get the HTTP header with a callback
135        curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, '_curlReadHeaders'));
136
137        /*********************************************************
138         * Add cookie headers to our request.
139        *********************************************************/
140        if (count($this->cookies)) {
141            $cookieStrings = array();
142            foreach ($this->cookies as $name => $val) {
143                $cookieStrings[] = $name.'='.$val;
144            }
145            curl_setopt($ch, CURLOPT_COOKIE, implode(';', $cookieStrings));
146        }
147
148        /*********************************************************
149         * Add any additional headers
150        *********************************************************/
151        if (count($this->headers)) {
152            curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
153        }
154
155        /*********************************************************
156         * Flag and Body for POST requests
157        *********************************************************/
158        if ($this->isPost) {
159            curl_setopt($ch, CURLOPT_POST, 1);
160            curl_setopt($ch, CURLOPT_POSTFIELDS, $this->postBody);
161        }
162
163        /*********************************************************
164         * Set User Agent
165         *********************************************************/
166        curl_setopt($ch, CURLOPT_USERAGENT, 'phpCAS/' . phpCAS::getVersion());
167
168        return $ch;
169    }
170
171    /**
172     * Store the response body.
173     * This method should NOT be used outside of the CurlRequest or the
174     * CurlMultiRequest.
175     *
176     * @param string $body body to stor
177     *
178     * @return void
179     */
180    public function _storeResponseBody ($body)
181    {
182        $this->storeResponseBody($body);
183    }
184
185    /**
186     * Internal method for capturing the headers from a curl request.
187     *
188     * @param resource $ch     handle of curl
189     * @param string $header header
190     *
191     * @return int
192     */
193    public function _curlReadHeaders ($ch, $header)
194    {
195        $this->storeResponseHeader($header);
196        return strlen($header);
197    }
198}
199