Skip to content

Commit

Permalink
Avoid browser-detection in JS driver
Browse files Browse the repository at this point in the history
Makes the admin UI use a private API instead.  This way,
Electron clients can just use TcpConnection as the default.
  • Loading branch information
srh committed Oct 30, 2019
1 parent f5526e8 commit 20497b7
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 28 deletions.
3 changes: 3 additions & 0 deletions admin/static/coffee/app.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class Driver
# We want run() to throw an error, in case a user write .run() in a query.
# We'll internally run a query with the method `private_run`
hack_driver: =>
# While we're at it, hack the driver to use HttpConnection.
r.net.Connection._connectionClass = r.net.HttpConnection

TermBase = r.expr(1).constructor.__super__.constructor.__super__
if not TermBase.private_run?
that = @
Expand Down
38 changes: 10 additions & 28 deletions drivers/javascript/net.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ class Connection extends events.EventEmitter
# results.
DEFAULT_TIMEOUT: 20 # In seconds

# The class we use to construct a connection by r.connect. This holds
# TcpConnection, unless it gets assigned by the admin UI.
_connectionClass: null

# #### Connection constructor
constructor: (host, callback) ->
# We need to set the defaults if the user hasn't supplied anything.
Expand Down Expand Up @@ -920,25 +924,12 @@ pbkdf2_cache = {}
# connection to the server.
class TcpConnection extends Connection

# #### TcpConnection isAvailable method
#
# The TcpConnection should never be used by the webui, so we have
# an extra method here that decides whether it's available. This
# is called by the constructor, but also by the `.connect`
# function which uses it to decide what kind of connection to
# create.
@isAvailable: () -> !(process.browser)

# #### TcpConnection constructor method
#
# This sets up all aspects of the connection that relate to
# TCP. Everything else is done in the Connection superclass
# constructor.
constructor: (host, callback) ->
# Bail out early if we happen to be in the browser
unless TcpConnection.isAvailable()
throw new err.ReqlDriverError "TCP sockets are not available in this environment"

# Invoke the superclass's constructor. This initializes the
# attributes `@host`, `@port`, `@db`, `@authKey` and
# `@timeout`, `@outstandingCallbacks`, `@nextToken`, `@open`,
Expand Down Expand Up @@ -1389,12 +1380,6 @@ class HttpConnection extends Connection
# one.
DEFAULT_PROTOCOL: 'http'

# A static method used by `r.connect` to decide which kind of
# connection to create in a given environment. Here we check if
# XHRs are defined. If not, we aren't in the browser and shouldn't
# be using `HttpConnection`
@isAvailable: -> typeof XMLHttpRequest isnt "undefined"

# #### HttpConnection constructor method
#
# This method sets up the XMLHttpRequest object that all
Expand All @@ -1415,7 +1400,7 @@ class HttpConnection extends Connection
# cursors and feeds.
constructor: (host, callback) ->
# A quick check to ensure we can create an `HttpConnection`
unless HttpConnection.isAvailable()
if typeof XMLHttpRequest is "undefined"
throw new err.ReqlDriverError "XMLHttpRequest is not available in this environment"
# Call the superclass constructor. This initializes the
# attributes `@host`, `@port`, `@db`, `@authKey`, `@timeout`,
Expand Down Expand Up @@ -1614,6 +1599,8 @@ class HttpConnection extends Connection
module.exports.isConnection = (connection) ->
return connection instanceof Connection

Connection._connectionClass = TcpConnection

# ## connect
#
# The main function of this module, which is exposed to end users as
Expand Down Expand Up @@ -1651,20 +1638,15 @@ module.exports.connect = varar 0, 2, (hostOrCallback, callback) ->
# Fixing mismatch between drivers
if host.username?
host.user = host.username
create_connection = (host, callback) =>
if TcpConnection.isAvailable()
new TcpConnection host, callback
else if HttpConnection.isAvailable()
new HttpConnection host, callback
else
throw new err.ReqlDriverError "Neither TCP nor HTTP avaiable in this environment"

wrappedCb = (err, result) ->
if (err)
reject(err)
else
resolve(result)
create_connection(host, wrappedCb)
# connectionClass is TcpConnection or HttpConnection
connectionClass = Connection._connectionClass
new connectionClass(host, wrappedCb)
).nodeify callback

# Exposing the connection classes
Expand Down

0 comments on commit 20497b7

Please sign in to comment.