removed old /view and /upload endpoints, moved api to root path

This commit is contained in:
Alex Grintsvayg 2017-08-02 15:50:17 -04:00
parent 02d4444780
commit cc5b626a54
5 changed files with 28 additions and 161 deletions

View file

@ -22,7 +22,7 @@ at anytime.
* *
### Deprecated ### Deprecated
* * The API will no longer be served at the /lbryapi path. It will now be at the root.
* *
### Changed ### Changed
@ -45,6 +45,8 @@ at anytime.
### Removed ### Removed
* Removed TempBlobManager * Removed TempBlobManager
* Removed old /view and /upload API paths
*
## [0.14.2] - 2017-07-24 ## [0.14.2] - 2017-07-24

View file

@ -169,7 +169,7 @@ class Daemon(AuthJSONRPCServer):
'daemon_stop', 'status', 'version', 'daemon_stop', 'status', 'version',
] ]
def __init__(self, root, analytics_manager): def __init__(self, analytics_manager):
AuthJSONRPCServer.__init__(self, conf.settings['use_auth_http']) AuthJSONRPCServer.__init__(self, conf.settings['use_auth_http'])
self.db_dir = conf.settings['data_dir'] self.db_dir = conf.settings['data_dir']
self.download_directory = conf.settings['download_directory'] self.download_directory = conf.settings['download_directory']

View file

@ -9,7 +9,6 @@ from jsonrpc.proxy import JSONRPCProxy
from lbrynet import analytics from lbrynet import analytics
from lbrynet import conf from lbrynet import conf
from lbrynet.core import utils, system_info from lbrynet.core import utils, system_info
from lbrynet.daemon.auth.client import LBRYAPIClient
from lbrynet.daemon.DaemonServer import DaemonServer from lbrynet.daemon.DaemonServer import DaemonServer
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -89,16 +88,15 @@ def start():
def update_settings_from_args(args): def update_settings_from_args(args):
cli_settings = {} conf.settings.update({
cli_settings['use_auth_http'] = args.useauth 'use_auth_http': args.useauth,
cli_settings['wallet'] = args.wallet 'wallet': args.wallet,
conf.settings.update(cli_settings, data_types=(conf.TYPE_CLI,)) }, data_types=(conf.TYPE_CLI,))
@defer.inlineCallbacks @defer.inlineCallbacks
def start_server_and_listen(use_auth, analytics_manager, max_tries=5): def start_server_and_listen(use_auth, analytics_manager):
"""The primary entry point for launching the daemon. """
Args: Args:
use_auth: set to true to enable http authentication use_auth: set to true to enable http authentication
analytics_manager: to send analytics analytics_manager: to send analytics

View file

@ -1,37 +1,41 @@
import logging import logging
import os import os
from twisted.web import server, guard from twisted.web import server, guard, resource
from twisted.internet import defer, reactor, error from twisted.internet import defer, reactor, error
from twisted.cred import portal from twisted.cred import portal
from lbrynet import conf from lbrynet import conf
from lbrynet.daemon.Daemon import Daemon from lbrynet.daemon.Daemon import Daemon
from lbrynet.daemon.Resources import LBRYindex, HostedEncryptedFile, EncryptedFileUpload
from lbrynet.daemon.auth.auth import PasswordChecker, HttpPasswordRealm from lbrynet.daemon.auth.auth import PasswordChecker, HttpPasswordRealm
from lbrynet.daemon.auth.util import initialize_api_key_file from lbrynet.daemon.auth.util import initialize_api_key_file
from lbrynet.daemon.DaemonRequest import DaemonRequest from lbrynet.daemon.DaemonRequest import DaemonRequest
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class IndexResource(resource.Resource):
def getChild(self, name, request):
request.setHeader('cache-control', 'no-cache, no-store, must-revalidate')
request.setHeader('expires', '0')
return self if name == '' else resource.Resource.getChild(self, name, request)
class DaemonServer(object): class DaemonServer(object):
def __init__(self, analytics_manager=None): def __init__(self, analytics_manager=None):
self._api = None self._daemon = None
self.root = None self.root = None
self.server_port = None self.server_port = None
self.analytics_manager = analytics_manager self.analytics_manager = analytics_manager
def _setup_server(self, use_auth): def _setup_server(self, use_auth):
ui_path = os.path.join(conf.settings.ensure_data_dir(), "lbry-ui", "active") self.root = IndexResource()
self.root = LBRYindex(ui_path) self._daemon = Daemon(self.analytics_manager)
self._api = Daemon(self.root, self.analytics_manager) self.root.putChild("", self._daemon)
self.root.putChild("view", HostedEncryptedFile(self._api)) # TODO: DEPRECATED, remove this and just serve the API at the root
self.root.putChild("upload", EncryptedFileUpload(self._api)) self.root.putChild(conf.settings['API_ADDRESS'], self._daemon)
self.root.putChild(conf.settings['API_ADDRESS'], self._api)
lbrynet_server = server.Site(get_site_base(use_auth, self.root)) lbrynet_server = get_site_base(use_auth, self.root)
lbrynet_server.requestFactory = DaemonRequest lbrynet_server.requestFactory = DaemonRequest
try: try:
@ -46,7 +50,7 @@ class DaemonServer(object):
@defer.inlineCallbacks @defer.inlineCallbacks
def start(self, use_auth): def start(self, use_auth):
yield self._setup_server(use_auth) yield self._setup_server(use_auth)
yield self._api.setup() yield self._daemon.setup()
@defer.inlineCallbacks @defer.inlineCallbacks
def stop(self): def stop(self):
@ -59,10 +63,10 @@ class DaemonServer(object):
def get_site_base(use_auth, root): def get_site_base(use_auth, root):
if use_auth: if use_auth:
log.info("Using authenticated API") log.info("Using authenticated API")
return create_auth_session(root) root = create_auth_session(root)
else: else:
log.info("Using non-authenticated API") log.info("Using non-authenticated API")
return server.Site(root) return server.Site(root)
def create_auth_session(root): def create_auth_session(root):

View file

@ -1,137 +0,0 @@
import logging
import os
import shutil
import json
import tempfile
from twisted.web import server, static, resource
from twisted.internet import defer, error
from lbrynet import conf
from lbrynet.daemon.FileStreamer import EncryptedFileStreamer
log = logging.getLogger(__name__)
class NoCacheStaticFile(static.File):
def _set_no_cache(self, request):
request.setHeader('cache-control', 'no-cache, no-store, must-revalidate')
request.setHeader('expires', '0')
def render_GET(self, request):
self._set_no_cache(request)
return static.File.render_GET(self, request)
class LBRYindex(resource.Resource):
def __init__(self, ui_dir):
resource.Resource.__init__(self)
self.ui_dir = ui_dir
isLeaf = False
def _delayed_render(self, request, results):
request.write(str(results))
request.finish()
def getChild(self, name, request):
request.setHeader('cache-control', 'no-cache, no-store, must-revalidate')
request.setHeader('expires', '0')
if name == '':
return self
return resource.Resource.getChild(self, name, request)
def render_GET(self, request):
return NoCacheStaticFile(os.path.join(self.ui_dir, "index.html")).render_GET(request)
class HostedEncryptedFile(resource.Resource):
def __init__(self, api):
self._api = api
resource.Resource.__init__(self)
def _make_stream_producer(self, request, stream):
path = os.path.join(self._api.download_directory, stream.file_name)
producer = EncryptedFileStreamer(request, path, stream, self._api.lbry_file_manager)
request.registerProducer(producer, streaming=True)
d = request.notifyFinish()
d.addErrback(self._responseFailed, d)
return d
def is_valid_request_name(self, request):
return (
request.args['name'][0] != 'lbry' and
request.args['name'][0] not in self._api.waiting_on.keys())
def render_GET(self, request):
request.setHeader("Content-Security-Policy", "sandbox")
if 'name' in request.args.keys():
if self.is_valid_request_name(request):
name = request.args['name'][0]
d = self._api.jsonrpc_get(name=name)
d.addCallback(lambda response: response['stream_hash'])
d.addCallback(lambda sd_hash: self._api._get_lbry_file_by_sd_hash(sd_hash))
d.addCallback(lambda lbry_file: self._make_stream_producer(request, lbry_file))
elif request.args['name'][0] in self._api.waiting_on.keys():
request.redirect(
conf.settings.get_ui_address() + "/?watch=" + request.args['name'][0]
)
request.finish()
else:
request.redirect(conf.settings.get_ui_address())
request.finish()
return server.NOT_DONE_YET
def _responseFailed(self, err, call):
call.addErrback(lambda err: err.trap(error.ConnectionDone))
call.addErrback(lambda err: err.trap(defer.CancelledError))
call.addErrback(lambda err: log.info("Error: " + str(err)))
call.cancel()
class EncryptedFileUpload(resource.Resource):
"""
Accepts a file sent via the file upload widget in the web UI, saves
it into a temporary dir, and responds with a JSON string containing
the path of the newly created file.
"""
def __init__(self, api):
self._api = api
def render_POST(self, request):
origfilename = request.args['file_filename'][0]
# Temp file created by request
uploaded_file = request.args['file'][0]
newpath = move_to_temp_dir_and_restore_filename(uploaded_file, origfilename)
self._api.uploaded_temp_files.append(newpath)
return json.dumps(newpath)
def move_to_temp_dir_and_restore_filename(uploaded_file, origfilename):
newdirpath = tempfile.mkdtemp()
newpath = os.path.join(newdirpath, origfilename)
if os.name == "nt":
# TODO: comment on why shutil.move doesn't work?
move_win(uploaded_file.name, newpath)
else:
shutil.move(uploaded_file.name, newpath)
return newpath
def move_win(from_path, to_path):
shutil.copy(from_path, to_path)
# TODO Still need to remove the file
# TODO deal with pylint error in cleaner fashion than this
try:
from exceptions import WindowsError as win_except
except ImportError as e:
log.error("This shouldn't happen")
win_except = Exception
try:
os.remove(from_path)
except win_except as e:
pass