diff --git a/lib/drivers/seafile/seafile_api.php b/lib/drivers/seafile/seafile_api.php --- a/lib/drivers/seafile/seafile_api.php +++ b/lib/drivers/seafile/seafile_api.php @@ -59,11 +59,11 @@ protected $config = array(); /** - * HTTP request handle + * HTTP client * - * @var HTTP_Request + * @var GuzzleHttp\Client */ - protected $request; + protected $client = null; /** * Web API URI prefix @@ -106,39 +106,6 @@ $this->url_prefix = preg_replace('|^(https?://[^/]+).*$|i', '\\1', $this->url); } - /** - * - * @param array Configuration for this Request instance, that will be merged - * with default configuration - * - * @return HTTP_Request2 Request object - */ - public static function http_request($config = array()) - { - // remove unknown config, otherwise HTTP_Request will throw an error - $config = array_intersect_key($config, array_flip(array( - 'connect_timeout', 'timeout', 'use_brackets', 'protocol_version', - 'buffer_size', 'store_body', 'follow_redirects', 'max_redirects', - 'strict_redirects', 'ssl_verify_peer', 'ssl_verify_host', - 'ssl_cafile', 'ssl_capath', 'ssl_local_cert', 'ssl_passphrase' - ))); - - // force CURL adapter, this allows to handle correctly - // compressed responses with simple SplObserver registered - $config['adapter'] = 'HTTP_Request2_Adapter_Curl'; - - try { - $request = new HTTP_Request2(); - $request->setConfig($config); - } - catch (Exception $e) { - rcube::raise_error($e, true, false); - return; - } - - return $request; - } - /** * Send HTTP request * @@ -166,29 +133,15 @@ $url = str_replace('/api2/', "/api/v$version/", $url); } - if (!$this->request) { - $this->config['store_body'] = true; - // some methods respond with 301 redirect, we'll not follow them - // also because of https://github.com/haiwen/seahub/issues/288 - $this->config['follow_redirects'] = false; - - $this->request = self::http_request($this->config); - - if (!$this->request) { - $this->status = self::CONNECTION_ERROR; - return; - } - } - - // cleanup - try { - $this->request->setBody(''); - $this->request->setUrl($url); - } - catch (Exception $e) { - rcube::raise_error($e, true, false); - $this->status = self::CONNECTION_ERROR; - return; + if (!$this->client) { + $this->client = new \GuzzleHttp\Client( + [ + 'http_errors' => true, + 'verify' => false, + 'connect_timeout' => 10, + 'timeout' => 300, + ] + ); } if ($this->config['debug']) { @@ -210,49 +163,73 @@ rcube::write_log('console', $log_line); } - $this->request->setMethod($method ?: HTTP_Request2::METHOD_GET); - - if (!empty($get)) { - $_url = $this->request->getUrl(); - $_url->setQueryVariables($get); - $this->request->setUrl($_url); - } + // send request to the SeaFile API server + try { + $headers = [ + 'Accept' => "application/json,text/javascript,*/*", + 'User-Agent' => $_SERVER['HTTP_USER_AGENT'] + ]; - // HTTP_Request2 does not support POST params on PUT requests - if (!empty($post) && $method == 'PUT') { - $body = http_build_query($post, '', '&'); - $body = str_replace('%7E', '~', $body); // support RFC 3986 by not encoding '~' symbol - $post = null; + if ($this->token) { + $headers['Authorization'] = "Token " . $this->token; + } - $this->request->setBody($body); - $this->request->setHeader('content-type', 'application/x-www-form-urlencoded'); - } + $options = []; - if (!empty($post)) { - $this->request->addPostParameter($post); - } - if (!empty($upload)) { - foreach ($upload as $field_name => $file) { - $this->request->addUpload($field_name, $file['data'], $file['name'], $file['type']); + if (!empty($get)) { + $options['query'] = $get; } - } - - if ($this->token) { - $this->request->setHeader('Authorization', "Token " . $this->token); - } - // some HTTP server configurations require this header - $this->request->setHeader('Accept', "application/json,text/javascript,*/*"); + if (!empty($upload)) { + if (!empty($post['target_file'])) { + $filename = basename($post['target_file']); + } else { + $filename = $upload['file']['name']; + } + $multipart = [ + [ + 'headers' => ['Content-Type' => 'application/octet-stream'], + 'name' => 'file', + 'filename' => $filename, + 'contents' => $upload['file']['data'] + ], + [ + 'name' => 'name', + 'contents' => $upload['file']['name'], + ], + [ + 'name' => 'type', + 'contents' => $upload['file']['type'], + ], + ]; + + if (array_key_exists('parent_dir', $post)) { + $multipart[] = [ + 'name' => 'parent_dir', + 'contents' => $post['parent_dir'] + ]; + } + if (array_key_exists('target_file', $post)) { + $multipart[] = [ + 'name' => 'target_file', + 'contents' => $post['target_file'] + ]; + } + $options['multipart'] = $multipart; + } else { + if (!empty($post)) { + $options['form_params'] = $post; + } + } - // proxy User-Agent string - $this->request->setHeader('User-Agent', $_SERVER['HTTP_USER_AGENT']); + if (!empty($headers)) { + $options['headers'] = $headers; + } + $response = $this->client->request($method ?: "GET", $url, $options); - // send request to the SeaFile API server - try { - $response = $this->request->send(); - $this->status = $response->getStatus(); - $body = $response->getBody(); + $this->status = $response->getStatusCode(); + $body = $response->getBody(); } catch (Exception $e) { rcube::raise_error($e, true, false); diff --git a/lib/drivers/seafile/seafile_file_storage.php b/lib/drivers/seafile/seafile_file_storage.php --- a/lib/drivers/seafile/seafile_file_storage.php +++ b/lib/drivers/seafile/seafile_file_storage.php @@ -379,9 +379,6 @@ $created = $this->api->file_upload($repo_id, $fn, $file); - if ($fp) { - fclose($fp); - } if (!$created) { rcube::raise_error(array( @@ -425,9 +422,6 @@ $saved = $this->api->file_update($repo_id, $fn, $file); - if ($fp) { - fclose($fp); - } if (!$saved) { rcube::raise_error(array( @@ -542,7 +536,6 @@ } else if ($fp = fopen('php://output', 'wb')) { $this->save_file_content($link, $fp); - fclose($fp); } } } @@ -1645,9 +1638,24 @@ } $config = array_merge($this->config, array('store_bodies' => true)); - $request = seafile_api::http_request($config); - if (!$request) { + $config = array_intersect_key($config, array_flip(array( + 'connect_timeout', 'timeout', 'use_brackets', 'protocol_version', + 'buffer_size', 'store_body', 'follow_redirects', 'max_redirects', + 'strict_redirects', 'ssl_verify_peer', 'ssl_verify_host', + 'ssl_cafile', 'ssl_capath', 'ssl_local_cert', 'ssl_passphrase' + ))); + + // force CURL adapter, this allows to handle correctly + // compressed responses with simple SplObserver registered + $config['adapter'] = 'HTTP_Request2_Adapter_Curl'; + + try { + $request = new HTTP_Request2(); + $request->setConfig($config); + } + catch (Exception $e) { + rcube::raise_error($e, true, false); return false; }