blob: b65d8ac6f8f140fcb53c2b4b5c89d121ab72ae0e [file] [log] [blame]
<?php
/*******************************************************************************
* Copyright (c) 2013, 2014, 2015, 2016 Eclipse Foundation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Zak James (zak.james@gmail.com) - Initial implementation
* Denis Roy (Eclipse Foundation)
* Christopher Guindon (Eclipse Foundation) - Refactoring for usability and USS
*******************************************************************************/
require_once(realpath(dirname(__FILE__) . '/../../../system/eclipseenv.class.php'));
/**
* RestClient class
*
* @author chrisguindon
*/
class RestClient extends EclipseEnv {
/**
* Base url for api requests.
* @var string
*/
protected $base_url = "";
/**
* List of headers for subsequent request.
* @var array
*/
protected $header = array();
/**
* List of cookies for subsequent request.
* @var array
*/
protected $cookie = array();
/**
* Proxy value for curl requests
*
* @var string
*/
protected $proxy = '';
/**
* Result of the last request made
*
* @var unknown
*/
protected $result = NULL;
/**
* Oauth2 access_token
*
* @var string
*/
protected $access_token = "";
function __construct(App $App = NULL) {
parent::__construct($App);
// Default headers
$default_headers = array(
'Content-Type' => 'application/json',
'Accept' =>'application/json',
'User-Agent' => 'eclipse/foundation'
);
$this->setHeader($default_headers);
}
/**
* Execute a GET request.
*
* @param string $url
*
* @return Response $data
*/
public function get($url) {
return $this->curl_exec($url);
}
/**
* Execute a POST request.
*
* @param string $url
* @param string $data
*
* @return Response $data
*/
public function post($url, $data = NULL) {
$options[CURLOPT_POST] = TRUE;
$options[CURLOPT_POSTFIELDS] = $data;
return $this->curl_exec($url, $options);
}
/**
* Execute a PUT request.
*
* @param string $url
* @param string $data
*
* @return Response $data
*/
public function put($url, $data = NULL) {
$options[CURLOPT_CUSTOMREQUEST] = 'PUT';
$options[CURLOPT_POSTFIELDS] = $data;
return $this->curl_exec($url, $options);
}
/**
* Execute a DELETE request.
*
* @param string $url
* @param string $data
*
* @return Response $data
*/
public function delete($url) {
$options[CURLOPT_CUSTOMREQUEST] = 'DELETE';
return $this->curl_exec($url, $options);
}
/**
* Execute a PATCH request.
*
* @param string $url
* @param string $data
*
* @return Response $data
*/
public function patch($url, $data) {
$options[CURLOPT_CUSTOMREQUEST] = 'PATCH';
$options[CURLOPT_POSTFIELDS] = $data;
return $this->curl_exec($url, $options);
}
/**
* Get $base_url
*
* @return string $base_url
*/
public function getBaseUrl() {
return $this->base_url;
}
/**
* Set $base_url
* @param string $url
*
* @return string $base_url
*/
public function setBaseUrl($url) {
if (filter_var($url, FILTER_VALIDATE_URL)) {
$this->base_url = $url;
}
return $this->base_url;
}
/**
* Shortcut for the decoded value of the request body
*
* The server must return data in JSON.
*/
public function getRequestBody($json = TRUE) {
$return = new stdClass();
if (isset($this->result->body) && !empty($this->result->body)) {
$return = $this->result->body;
if ($json) {
$return = json_decode(stripslashes($this->result->body));
}
}
return $return;
}
/**
* Get $cookie
* Convert $cookie array into a string
*
* @return string $cookie
*/
public function getCookie() {
return implode('; ', $this->cookie);
}
/**
* Set $cookie
* @param array $cookies
*
* @return bool
*/
public function setCookie($cookies = array()) {
if (!is_array($cookies)) {
return FALSE;
}
foreach ($cookies as $key => $value) {
$this->cookie[$key] = $value;
}
return TRUE;
}
/**
* Get $header
* Remove array key from $header
*
* @return array $header
*/
public function getHeader() {
return array_values($this->header);
}
/**
* Set $header
* @param array $headers
*
* @return bool
*/
public function setHeader($headers = array()) {
if (!is_array($headers)) {
return FALSE;
}
foreach ($headers as $key => $value) {
$this->header[$key] = $key . ': '. $value;
}
return TRUE;
}
/**
* Get access_token
*
* @return string
*/
public function getAccessToken() {
return $this->access_token;
}
/**
* Get access_token
*
* @param string $token
*/
public function setAccessToken($token = "") {
$this->access_token = $token;
$_SESSION['access_token']['uss'] = $token;
}
/**
* Unset $header
* @param string $header
*
* @return bool
*/
public function unsetHeader($header = "") {
if (isset($this->header[$header])) {
unset($this->header[$header]);
return TRUE;
}
return FALSE;
}
/**
* Execute a CURL request
*
* @param string $path
* @param array $options
*
* @return Response $return
*/
protected function curl_exec($path = '', $options = array()) {
$this->result = new stdClass();
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($ch, CURLOPT_FORBID_REUSE, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
//proxy configuration
//curl_setopt($ch, CURLOPT_PROXY, $this->_get_proxy());
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
if ($this->getEnvShortName() === 'local') {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_PROXY, '');
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
}
$options[CURLOPT_URL] = $this->base_url . '/' . $path;
// Use access token if set
if ($token = $this->getAccessToken()) {
$this->setHeader(array('Authorization' => 'Bearer ' . $token));
}
$headers = $this->getHeader();
$cookies = $this->getCookie();
if (!empty($cookies)) {
$headers[] = 'Cookie: ' . $cookies;
}
$options[CURLOPT_HTTPHEADER] = $headers;
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
if (!$result) {
$this->result->error = curl_error($ch);
$this->result->code = 9990;
$this->result->request_error = $result;
curl_close($ch);
return $this->result;
}
$this->result->options = $options;
$this->result->request = curl_getinfo($ch);
$this->result->body = substr($result, $this->result->request['header_size']);
curl_close($ch);
$this->result->headers = array();
$header_text = substr($result, 0, strpos($result, "\r\n\r\n"));
foreach (explode("\r\n", $header_text) as $i => $line) {
if ($i === 0) {
$this->result->headers['http_code'] = $line;
}
else {
list ($key, $value) = explode(': ', $line);
$this->result->headers[$key] = $value;
}
}
$response_array = explode(' ', trim($this->result->headers['http_code']), 3);
$this->result->status_message = '';
$this->result->protocol = $response_array[0];
$this->result->code = $this->result->request['http_code'];
if (isset($response_array[2])) {
$this->result->status_message = $response_array[2];
}
return $this->result;
}
/**
* Get 'Link' header
*
* @param string $link
*
* @return bool/array $links
*/
protected function _getHeaderLink($link = '') {
if (strlen($link) == 0) {
return FALSE;
}
$parts = explode(',', $link);
$links = array();
foreach($parts as $p) {
$section = explode(';', htmlspecialchars_decode($p));
if (count($section) != 2) {
return FALSE;
}
$url = $this->_removeBaseUrlFromUrl(trim(preg_replace("/<(.*)>/", '$1', $section[0])));
$key = trim(preg_replace("/rel=\"(.*)\"/", '$1', $section[1]));
$links[$key] = $url;
}
return $links;
}
/**
* Get next page from pagination
*
* @param Response $data
*
* @return Response $return
*/
public function _getNextPage($data) {
if ($data && isset($data->headers['Link']) && !isset($data->error) && !empty($data->body)) {
$pages = $this->_getHeaderLink($data->headers['Link']);
if (($pages['self'] !== $pages['last']) && !empty($pages['next'])){
if ($data = $this->get($pages['next'])) {
return $data;
}
}
}
return FALSE;
}
/**
* Remove $base_url from $url
* @param string $url
*
* @return string $url
*/
protected function _removeBaseUrlFromUrl($url = '') {
return str_replace($this->getBaseUrl() . '/', '', $url);
}
/**
* Get proxy value
*
* @return string
*/
private function _get_proxy() {
if (empty($this->proxy)) {
$this->_set_proxy();
}
return $this->proxy;
}
/**
* Set eclipse proxy for staging/production
*/
private function _set_proxy(){
if ($this->_get_prefix_domain() === 'www.eclipse.org') {
$this->proxy = 'proxy.eclipse.org:9899';
}
}
}