diff options
author | Lukas Reschke <lukas@owncloud.com> | 2014-09-08 18:46:27 +0200 |
---|---|---|
committer | Lukas Reschke <lukas@owncloud.com> | 2014-09-08 18:46:27 +0200 |
commit | 70abce04827517d4391cc1bb3cd71574fc19724a (patch) | |
tree | a744a503ed1ef283949b3995d04cb58cf0ed1373 /lib | |
parent | ffee4da397d8f74f8e4ce4f479c2a9447e60477c (diff) | |
parent | fa3393674c854e884abf10d3b82dab03aca83c61 (diff) | |
download | nextcloud-server-70abce04827517d4391cc1bb3cd71574fc19724a.tar.gz nextcloud-server-70abce04827517d4391cc1bb3cd71574fc19724a.zip |
Merge pull request #10739 from owncloud/eventsource-public
Add EventSource to the public API
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/appframework/core/api.php | 7 | ||||
-rw-r--r-- | lib/private/eventsource.php | 93 | ||||
-rw-r--r-- | lib/private/server.php | 9 | ||||
-rw-r--r-- | lib/public/ieventsource.php | 34 | ||||
-rw-r--r-- | lib/public/iservercontainer.php | 7 |
5 files changed, 103 insertions, 47 deletions
diff --git a/lib/private/appframework/core/api.php b/lib/private/appframework/core/api.php index ba6b9f95cb2..279f4bf97f7 100644 --- a/lib/private/appframework/core/api.php +++ b/lib/private/appframework/core/api.php @@ -110,12 +110,11 @@ class API implements IApi{ /** - * used to return and open a new eventsource - * @return \OC_EventSource a new open EventSource class + * used to return and open a new event source + * @return \OCP\IEventSource a new open EventSource class */ public function openEventSource(){ - # TODO: use public api - return new \OC_EventSource(); + return \OC::$server->createEventSource(); } /** diff --git a/lib/private/eventsource.php b/lib/private/eventsource.php index 192c1446b5a..53947f3a2f2 100644 --- a/lib/private/eventsource.php +++ b/lib/private/eventsource.php @@ -1,25 +1,10 @@ <?php - /** -* ownCloud -* -* @author Robin Appelman -* @copyright 2012 Robin Appelman icewind1991@gmail.com -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ /** * wrapper for server side events (http://en.wikipedia.org/wiki/Server-sent_events) @@ -27,51 +12,73 @@ * * use server side events with caution, to many open requests can hang the server */ -class OC_EventSource{ +class OC_EventSource implements \OCP\IEventSource { + /** + * @var bool + */ private $fallback; - private $fallBackId=0; - public function __construct() { + /** + * @var int + */ + private $fallBackId = 0; + + /** + * @var bool + */ + private $started = false; + + protected function init() { + if ($this->started) { + return; + } + $this->started = true; + + // prevent php output buffering, caching and nginx buffering OC_Util::obEnd(); header('Cache-Control: no-cache'); header('X-Accel-Buffering: no'); - $this->fallback=isset($_GET['fallback']) and $_GET['fallback']=='true'; - if($this->fallback) { - $this->fallBackId=$_GET['fallback_id']; + $this->fallback = isset($_GET['fallback']) and $_GET['fallback'] == 'true'; + if ($this->fallback) { + $this->fallBackId = (int)$_GET['fallback_id']; header("Content-Type: text/html"); - echo str_repeat('<span></span>'.PHP_EOL, 10); //dummy data to keep IE happy - }else{ + echo str_repeat('<span></span>' . PHP_EOL, 10); //dummy data to keep IE happy + } else { header("Content-Type: text/event-stream"); } - if( !OC_Util::isCallRegistered()) { + if (!OC_Util::isCallRegistered()) { $this->send('error', 'Possible CSRF attack. Connection will be closed.'); $this->close(); exit(); } flush(); - } /** * send a message to the client + * * @param string $type * @param mixed $data * + * @throws \BadMethodCallException * if only one parameter is given, a typeless message will be send with that parameter as data */ - public function send($type, $data=null) { - if(is_null($data)) { - $data=$type; - $type=null; + public function send($type, $data = null) { + if ($data and !preg_match('/^[A-Za-z0-9_]+$/', $type)) { + throw new BadMethodCallException('Type needs to be alphanumeric ('. $type .')'); + } + $this->init(); + if (is_null($data)) { + $data = $type; + $type = null; } - if($this->fallback) { - $fallBackId = OC_Util::sanitizeHTML($this->fallBackId); - $response='<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack(' - .$fallBackId.',"' . $type . '",' . OCP\JSON::encode($data) . ')</script>' . PHP_EOL; + if ($this->fallback) { + $response = '<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack(' + . $this->fallBackId . ',"' . $type . '",' . OCP\JSON::encode($data) . ')</script>' . PHP_EOL; echo $response; - }else{ - if($type) { - echo 'event: ' . $type.PHP_EOL; + } else { + if ($type) { + echo 'event: ' . $type . PHP_EOL; } echo 'data: ' . OCP\JSON::encode($data) . PHP_EOL; } @@ -80,9 +87,9 @@ class OC_EventSource{ } /** - * close the connection of the even source + * close the connection of the event source */ public function close() { - $this->send('__internal__', 'close');//server side closing can be an issue, let the client do it + $this->send('__internal__', 'close'); //server side closing can be an issue, let the client do it } } diff --git a/lib/private/server.php b/lib/private/server.php index 71a098f9074..912d5c4f635 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -518,4 +518,13 @@ class Server extends SimpleContainer implements IServerContainer { } return new CertificateManager($user); } + + /** + * Create a new event source + * + * @return \OCP\IEventSource + */ + function createEventSource() { + return new \OC_EventSource(); + } } diff --git a/lib/public/ieventsource.php b/lib/public/ieventsource.php new file mode 100644 index 00000000000..eb7853c5e90 --- /dev/null +++ b/lib/public/ieventsource.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP; + +/** + * wrapper for server side events (http://en.wikipedia.org/wiki/Server-sent_events) + * includes a fallback for older browsers and IE + * + * use server side events with caution, to many open requests can hang the server + * + * The event source will initialize the connection to the client when the first data is sent + */ +interface IEventSource { + /** + * send a message to the client + * + * @param string $type + * @param mixed $data + * + * if only one parameter is given, a typeless message will be send with that parameter as data + */ + public function send($type, $data = null); + + /** + * close the connection of the event source + */ + public function close(); +} diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index 60b0b497c54..1abf0d9938d 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -235,4 +235,11 @@ interface IServerContainer { * @return \OCP\ICertificateManager */ function getCertificateManager($user = null); + + /** + * Create a new event source + * + * @return \OCP\IEventSource + */ + function createEventSource(); } |