Code Monkey home page Code Monkey logo

drawbridge's Introduction

Drawbridge (HTTP Transport for nREPL)

Clojars Project cljdoc badge Build Status (Travis CI)

HTTP transport support for Clojure’s nREPL implemented as a Ring handler.

Installation

📎
The coordinates of the project changed from cemerick/drawbridge to nrepl/drawbridge in version 0.1.

Drawbridge is available in Clojars. Add this :dependency to your Leiningen project.clj:

[nrepl/drawbridge "0.2.1"]

Or, add this to your Maven project’s pom.xml:

<repository>
  <id>clojars</id>
  <url>http://clojars.org/repo</url>
</repository>

<dependency>
  <groupId>nrepl</groupId>
  <artifactId>drawbridge</artifactId>
  <version>0.2.1</version>
</dependency>
📎
Drawbridge is compatible with Clojure 1.7.0+ and nREPL 0.4+.

Upgrade notes

If you’re upgrading from 0.0.7 keep in mind that the namespaces of the project were changed as following:

  • cemerick.drawbridge -> drawbridge.core

  • cemerick.drawbridge.client -> drawbridge.client

Usage

While nREPL provides a solid REPL backend for Clojure, typical socket-based channels are often unsuitable. Being able to deploy applications that allow for REPL access via HTTP and HTTPS simplifies configuration and can alleviate security concerns, and works around limitations in various deployment environments where traditional socket-based channels are limited or entirely unavailable.

In a Ring web application

Once you have added Drawbridge to your project’s dependencies, just add its Ring handler to your application. For example, if you’re using Compojure for routing and such:

(require 'drawbridge.core)

(let [nrepl-handler (drawbridge.core/ring-handler)]
  (ANY "/repl" request (nrepl-handler request)))

With this, any HTTP or HTTPS client can send nREPL messages to the /repl URI, and read responses from the same. Conveniently, any security measures applied within your application will work fine in conjunction with Drawbridge; so, if you configure its route to require authentication or authorization to some application-specific role, those prerequisites will apply just as with any other Ring handler in the same context.

Some things to be aware of when using drawbridge.core/ring-handler:

  • It requires GET and POST requests to be routed to whatever URI to which it is mapped; other request methods result in an HTTP error response.

  • It requires these standard Ring middlewares to function properly:

    • keyword-params

    • nested-params

    • wrap-params

Especially if you are going to be connecting to your webapp’s nREPL endpoint with a client that uses Drawbridge’s own HTTP/HTTPS client transport (see below), this is all you need to know.

If you are interested in the implementation details and semantics, perhaps because you’d like to implement support for Drawbridge in non-Clojure nREPL clients, you’ll want to review the documentation for ring-handler, which contains additional important details.

In Clojure tooling

Drawbridge also provides a client-side nREPL transport implementation for the Ring handler in drawbridge.client/ring-client-transport.

Note that the drawbridge.client namespace implicitly adds implementations to the nrepl.core/url-connect multimethod for "http" and "https" schemes. So, once this namespace is loaded, any tool that uses url-connect will use ring-client-transport for connecting to HTTP and HTTPS nREPL endpoints.

Configuration

The client supports additional HTTP headers, which is useful e.g. for using Bearer authorization to connect to the endpoint. The headers can be set in the nREPL configuration. For example, create .nrepl.edn in the working directory with the contents:

{:drawbridge {:http-headers {:Authorization "Bearer <JWT token>"}}}

TODO

The biggest outstanding issues are around the semantics of how HTTP session (might optionally) map onto nREPL sessions. Right now, they don’t at all, though HTTP sessions are significant insofar as they retain the message queue nREPL will dispatch responses to that are emitted by asynchronous or long-running operations.

Secondarily, supporting nontextual REPL interactions over HTTP has not yet been addressed at all.

Need Help?

The primary support channel for Drawbridge is the Clojurians Slack. Feel free to ask any questions on the #nrepl channel there.

License

Copyright © 2012-2019 Chas Emerick, Bozhidar Batsov and other contributors.

Distributed under the Eclipse Public License, the same as Clojure.

drawbridge's People

Contributors

bbatsov avatar cemerick avatar dakrone avatar dancek avatar eerohele avatar johannesloetzsch avatar mallt avatar sritchie avatar technomancy avatar theprash avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

drawbridge's Issues

Request: Add authentication for client side

First of all, thanks for this awesome project!

I'm currently developing a debugging feature (nrepl-in instead of ssh-in) for a project I'm working in.
For obvious security reasons, I'm setting authentication for nrepl on the server side (using ring-basic-authentication), but currently the drawbridge client doesn't contain authentication options.

With some guidance I could implement this myself.

Thanks in advance

Connecting to a Drawbridge Ring handler fails with ArityException

I have a web app with a Drawbridge Ring handler endpoint athttp://localhost:8000/repl.

I tried connecting to it like this:

(require '[nrepl.core :as nrepl]
         '[drawbridge.client :as client])

(with-open [conn (nrepl/url-connect "http://localhost:8000/repl")]
    (-> (nrepl/client conn 1000)
        (nrepl/message {:op "eval" :code "(+ 2 3)"})
        nrepl/response-values))

That yields this exception:

ArityException Wrong number of args (0) passed to: client/ring-client-transport/read--2318  clojure.lang.AFn.throwArity (AFn.java:429)

It looks like the read function in the Drawbridge client expects a single argument (timeout) while the calling code in nrepl.transport doesn't supply any.

Confusing homepage statement. Is drawbridge obsolete?

Hi cemerick,

The front page states: "Drawbridge is compatible with Clojure 1.2.0 - 1.4.0." (and 1.4 is from 2012)

Whereas I see commits reaching 2015, and Heroku has documentation from February 2016 helping to set drawbridge up in a new project (https://devcenter.heroku.com/articles/debugging-clojure).

Is that really true?

It would be good to either take that comment off, or state more boldly that this is an obsolete project, as I assume I won't be the only one which is confused. For example in this discussion (about an issue that I share) that specific line was quoted: http://stackoverflow.com/questions/20088908/problems-connecting-to-a-clojure-nrepl-with-ring-compojure

In any case, thanks for sharing your work!

connect on https gets 'SSLException Unrecognized SSL message, plaintext connection?'

AUTH_USER=myuser AUTH_PASS=mypass lein repl :connect https://myuser:mypass@localhost:8080/repl
Connecting to nREPL at https://myuser:mypass@localhost:8080/repl
SSLException Unrecognized SSL message, plaintext connection?
	sun.security.ssl.InputRecord.handleUnknownRecord (InputRecord.java:710)
	sun.security.ssl.InputRecord.read (InputRecord.java:527)
	sun.security.ssl.SSLSocketImpl.readRecord (SSLSocketImpl.java:975)
	sun.security.ssl.SSLSocketImpl.performInitialHandshake (SSLSocketImpl.java:1367)
	sun.security.ssl.SSLSocketImpl.startHandshake (SSLSocketImpl.java:1395)
	sun.security.ssl.SSLSocketImpl.startHandshake (SSLSocketImpl.java:1379)
	org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket (SSLConnectionSocketFactory.java:396)
	org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket (SSLConnectionSocketFactory.java:355)
	org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect (DefaultHttpClientConnectionOperator.java:142)
	org.apache.http.impl.conn.BasicHttpClientConnectionManager.connect (BasicHttpClientConnectionManager.java:323)
	org.apache.http.impl.execchain.MainClientExec.establishRoute (MainClientExec.java:381)
	org.apache.http.impl.execchain.MainClientExec.execute (MainClientExec.java:237)
Bye for now!
$ lein --version
Leiningen 2.9.1 on Java 1.8.0_242 OpenJDK 64-Bit Server VM
``

IllegalArgumentException Cannot open <nil> as a Reader.

Trying to connect to Drawbridge with Leiningen 2.9.1.

Dependencies include: [nrepl/nrepl "0.6.0"] [nrepl/drawbridge "0.2.1"]

Plugins include: [nrepl/drawbridge "0.2.1"]

$ lein repl :connect http://127.0.0.1:8080/repl
Connecting to nREPL at http://127.0.0.1:8080/repl
IllegalArgumentException Cannot open <nil> as a Reader.
	clojure.java.io/fn--11490 (io.clj:288)
	clojure.java.io/fn--11490 (io.clj:288)
	clojure.java.io/fn--11392/G--11368--11399 (io.clj:69)
	clojure.java.io/reader (io.clj:102)
	clojure.java.io/reader (io.clj:86)
	drawbridge.client/ring-client-transport/fill--4204 (client.clj:25)
	drawbridge.client/ring-client-transport/http--4208 (client.clj:42)
	nrepl.transport.FnTransport (transport.clj:41)
	nrepl.core/client/this--9259 (core.clj:56)
	clojure.core/comp/fn--5792 (core.clj:2569)
	clojure.core/comp/fn--5792 (core.clj:2569)
	clojure.lang.AFunction$1.doInvoke (AFunction.java:31)
Bye for now!

No obvious problems appear in curl on GET and POST requests:

$ curl -v http://127.0.0.1:8080/repl
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /repl HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 204 No Content
< Server: Aleph/0.4.4
< Connection: Keep-Alive
< Date: Fri, 06 Mar 2020 16:29:51 GMT
< 
* Connection #0 to host 127.0.0.1 left intact
$ curl -v -d "(+ 1 1)" -H "Content-Type: text/plain" http://127.0.0.1:8080/repl
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> POST /repl HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Type: text/plain
> Content-Length: 7
> 
* upload completely sent off: 7 out of 7 bytes
< HTTP/1.1 204 No Content
< Server: Aleph/0.4.4
< Connection: Keep-Alive
< Date: Fri, 06 Mar 2020 16:28:33 GMT
< 
* Connection #0 to host 127.0.0.1 left intact

connection fails with status 401: Is Drawbridge not promoting to HTTPS properly?

I see the following when I try to connect to my app on Heroku. Local connection on http to the dev box is fine, however. Since it says that the protocol is HTTP here I wonder if that's the problem.

$ lein repl :connect https://USER:[email protected]/repl
Connecting to nREPL at https://USER:[email protected]/repl
ExceptionInfo clj-http: status 401 {:cached nil, :request-time 839,
:repeatable? false, :protocol-version {:name "HTTP", :major 1, :minor
1}, :streaming? true, :http-client
#object[org.apache.http.impl.client.InternalHttpClient 0x7573c7b5
"org.apache.http.impl.client.InternalHttpClient@7573c7b5"], :chunked?
false, :type :clj-http.client/unexceptional-status, :reason-phrase
"Unauthorized", :headers {"Server" "Aleph/0.4.4", "Via" "1.1 vegur",
"Content-Type" "text/plain", "X-Content-Type-Options" "nosniff",
"Content-Length" "13", "X-Frame-Options" "DENY",
"Strict-Transport-Security" "max-age=31536000; includeSubDomains",
"Www-Authenticate" "Basic realm=\"restricted area\"", "Connection"
"close", "Date" "Wed, 11 Mar 2020 18:02:20 GMT", "X-Xss-Protection"
"1; mode=block"}, :orig-content-encoding nil, :status 401, :length 13,
:body #object[clj_http.core.proxy$java.io.FilterInputStream$ff19274a
0x717a8a76
"clj_http.core.proxy$java.io.FilterInputStream$ff19274a@717a8a76"],
:trace-redirects []}
	slingshot.support/stack-trace (support.clj:201)
	clj-http.client/exceptions-response (client.clj:245)
	clj-http.client/exceptions-response (client.clj:236)
	clj-http.client/wrap-exceptions/fn--4637 (client.clj:254)
	clj-http.client/wrap-accept/fn--4883 (client.clj:737)
	clj-http.client/wrap-accept-encoding/fn--4890 (client.clj:759)
	clj-http.client/wrap-content-type/fn--4877 (client.clj:720)
	clj-http.client/wrap-form-params/fn--4986 (client.clj:961)
	clj-http.client/wrap-nested-params/fn--5007 (client.clj:995)
	clj-http.client/wrap-flatten-nested-params/fn--5016 (client.clj:1019)
	clj-http.client/wrap-method/fn--4944 (client.clj:895)
	clj-http.cookies/wrap-cookies/fn--1862 (cookies.clj:131)
Bye for now!

Could not locate ring/middleware/head__init.class

When I include [com.cemerick/drawbridge "0.0.4"] in my project dependencies, executing lein run gives me the stacktrace below. I tried the chortles app with drawbridge 0.0.3 and 0.0.4, and it's working fine. But my webapp is using [noir "1.3.0-beta8"]. Could that be the source of the problem?

        ... 
Caused by: java.io.FileNotFoundException: Could not locate ring/middleware/head__init.class or ring/middleware/head.clj on classpath: 
        at clojure.lang.RT.load(RT.java:430)
        at clojure.lang.RT.load(RT.java:398)
        at clojure.core$load$fn__4610.invoke(core.clj:5386)
        at clojure.core$load.doInvoke(core.clj:5385)
        at clojure.lang.RestFn.invoke(RestFn.java:408)
        at clojure.core$load_one.invoke(core.clj:5200)
        at clojure.core$load_lib.doInvoke(core.clj:5237)
        at clojure.lang.RestFn.applyTo(RestFn.java:142)
        at clojure.core$apply.invoke(core.clj:602)
        at clojure.core$load_libs.doInvoke(core.clj:5271)
        at clojure.lang.RestFn.applyTo(RestFn.java:137)
        at clojure.core$apply.invoke(core.clj:604)
        at clojure.core$use.doInvoke(core.clj:5363)
        at clojure.lang.RestFn.invoke(RestFn.java:512)
        at compojure.route$eval23$loading__4505__auto____24.invoke(route.clj:1)
        at compojure.route$eval23.invoke(route.clj:1)
        at clojure.lang.Compiler.eval(Compiler.java:6465)
        ... 95 more

Fails with "java.net.Socket cannot be cast to class java.lang.String"

I want to connect to a remote nREPL server but the invocation fails:

deps.edn:

{:aliases {:repl {:extra-deps {nrepl/nrepl {:mvn/version "0.6.0"} 
                                              nrepl/drawbridge {:mvn/version "0.2.1"}}
           :main-opts  ["-m" "nrepl.cmdline" "--connect" "--transport" 
                               "drawbridge.client/ring-client-transport" 
                               "--port" "55555" "--host"]}}}

command:

clojure -Arepl 10.199.227.33

output:

Execution error (ClassCastException) at clj-http.client/parse-url (client.clj:175).
class java.net.Socket cannot be cast to class java.lang.String (java.net.Socket and java.lang.String are in module java.base of loader 'bootstrap')

See the full output from clojure in this gist: https://gist.github.com/holyjak/7a644ef57bc17807ac18d22d820bbda7

Environment

  • Amazon Linux 2 or OSX
  • JVM java-11-amazon-corretto.x86_64 or java-1.8.0-openjdk

It is quite likely I do something wrong but I have no idea what :(

It works with lein

Using leiningen 2.9 and project.clj:

(defproject repl-client-drawbridge "0.1.0-SNAPSHOT"
  :plugins [[nrepl/drawbridge "0.2.1"]])

this works:

$ lein repl :connect http://10.199.227.33:55555
Connecting to nREPL at http://10.199.227.33:55555
REPL-y 0.4.3, nREPL 0.6.0
Clojure 1.10.1
OpenJDK 64-Bit Server VM 11.0.1+13
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=>

Connection issues referencing cemerick/drawbridge/client

I've managed to setup drawbridge using the dependency below in my project.clj:

[nrepl/drawbridge "0.1.1"]

I believe I can connect to it when I navigate to the /repl address on localhost.

However, if I try:

lein repl :connect http://127.0.0.1:3000/repl

I get:

Connecting to nREPL at http://127.0.0.1:3000/repl
java.io.FileNotFoundException: Could not locate cemerick/drawbridge/client__init.class or cemerick/drawbridge/client.clj on classpath.
 at clojure.lang.RT.load (RT.java:456)
    clojure.lang.RT.load (RT.java:419)
    clojure.core$load$fn__5677.invoke (core.clj:5893)
    clojure.core$load.invokeStatic (core.clj:5892)
    clojure.core$load.doInvoke (core.clj:5876)
    clojure.lang.RestFn.invoke (RestFn.java:408)
    clojure.core$load_one.invokeStatic (core.clj:5697)
    clojure.core$load_one.invoke (core.clj:5692)
    clojure.core$load_lib$fn__5626.invoke (core.clj:5737)
    clojure.core$load_lib.invokeStatic (core.clj:5736)
    clojure.core$load_lib.doInvoke (core.clj:5717)
    clojure.lang.RestFn.applyTo (RestFn.java:142)
    clojure.core$apply.invokeStatic (core.clj:648)
    clojure.core$load_libs.invokeStatic (core.clj:5774)
    clojure.core$load_libs.doInvoke (core.clj:5758)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:648)
    clojure.core$require.invokeStatic (core.clj:5796)
    clojure.core$require.doInvoke (core.clj:5796)
    clojure.lang.RestFn.invoke (RestFn.java:408)
    leiningen.repl$client.invokeStatic (repl.clj:260)
    leiningen.repl$client.invoke (repl.clj:258)
    leiningen.repl$repl.invokeStatic (repl.clj:312)
    leiningen.repl$repl.doInvoke (repl.clj:267)
    clojure.lang.RestFn.invoke (RestFn.java:442)
    clojure.lang.Var.invoke (Var.java:388)
    clojure.lang.AFn.applyToHelper (AFn.java:160)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.core$apply.invokeStatic (core.clj:648)
    clojure.core$apply.invoke (core.clj:641)
    leiningen.core.main$partial_task$fn__4667.doInvoke (main.clj:284)
    clojure.lang.RestFn.applyTo (RestFn.java:139)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:29)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:648)
    clojure.core$apply.invoke (core.clj:641)
    leiningen.core.main$apply_task.invokeStatic (main.clj:334)
    leiningen.core.main$apply_task.invoke (main.clj:320)
    leiningen.core.main$resolve_and_apply.invokeStatic (main.clj:340)
    leiningen.core.main$resolve_and_apply.invoke (main.clj:336)
    leiningen.core.main$_main$fn__4734.invoke (main.clj:420)
    leiningen.core.main$_main.invokeStatic (main.clj:411)
    leiningen.core.main$_main.doInvoke (main.clj:408)
    clojure.lang.RestFn.invoke (RestFn.java:436)
    clojure.lang.Var.invoke (Var.java:388)
    clojure.lang.AFn.applyToHelper (AFn.java:160)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.core$apply.invokeStatic (core.clj:646)
    clojure.main$main_opt.invokeStatic (main.clj:314)
    clojure.main$main_opt.invoke (main.clj:310)
    clojure.main$main.invokeStatic (main.clj:421)
    clojure.main$main.doInvoke (main.clj:384)
    clojure.lang.RestFn.invoke (RestFn.java:482)
    clojure.lang.Var.invoke (Var.java:401)
    clojure.lang.AFn.applyToHelper (AFn.java:171)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.main.main (main.java:37)

Is the clojars jar file referencing it by any chance?

SocketException Connection reset

For some reason connecting takes a lot of time (20-40 minutes) and right after that it fails with the exception SocketException Connection reset.
Could someone advice on how to investigate/debug this issue?

lein repl :connect https://<host>/repl
Connecting to nREPL at https://<host>/repl
SocketException Connection reset
        java.net.SocketInputStream.read (SocketInputStream.java:186)
        java.net.SocketInputStream.read (SocketInputStream.java:140)
        sun.security.ssl.SSLSocketInputRecord.read (SSLSocketInputRecord.java:448)
        sun.security.ssl.SSLSocketInputRecord.decode (SSLSocketInputRecord.java:165)
        sun.security.ssl.SSLTransport.decode (SSLTransport.java:108)
        sun.security.ssl.SSLSocketImpl.decode (SSLSocketImpl.java:1152)
        sun.security.ssl.SSLSocketImpl.readHandshakeRecord (SSLSocketImpl.java:1063)
        sun.security.ssl.SSLSocketImpl.startHandshake (SSLSocketImpl.java:402)
        org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket (SSLConnectionSocketFactory.java:436)
        org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket (SSLConnectionSocketFactory.java:384)
        org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect (DefaultHttpClientConnectionOperator.java:142)
        org.apache.http.impl.conn.BasicHttpClientConnectionManager.connect (BasicHttpClientConnectionManager.java:313)
Bye for now!

If I curl the endpoint, it responds instantly

curl -X GET "https://<host>/repl" -H  "x-token: some_token_here"
[

]%       

Failure connecting over https

When connecting over https to a server running on heroku the following error happens:

Connecting to nREPL at https://user:[email protected]/repl
SSLException Received fatal alert: internal_error
	sun.security.ssl.Alerts.getSSLException (Alerts.java:208)
	sun.security.ssl.Alerts.getSSLException (Alerts.java:154)
	sun.security.ssl.SSLSocketImpl.recvAlert (SSLSocketImpl.java:2023)
	sun.security.ssl.SSLSocketImpl.readRecord (SSLSocketImpl.java:1125)
	sun.security.ssl.SSLSocketImpl.performInitialHandshake (SSLSocketImpl.java:1375)
	sun.security.ssl.SSLSocketImpl.startHandshake (SSLSocketImpl.java:1403)
	sun.security.ssl.SSLSocketImpl.startHandshake (SSLSocketImpl.java:1387)
	org.apache.http.conn.ssl.SSLSocketFactory.connectSocket (SSLSocketFactory.java:543)
	org.apache.http.conn.ssl.SSLSocketFactory.connectSocket (SSLSocketFactory.java:409)
	org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection (DefaultClientConnectionOperator.java:177)
	org.apache.http.impl.conn.ManagedClientConnectionImpl.open (ManagedClientConnectionImpl.java:304)
	org.apache.http.impl.client.DefaultRequestDirector.tryConnect (DefaultRequestDirector.java:611)
Bye for now!

The drawbridge handler middleware looks like this:

(defn wrap-drawbridge [handler]
  (let [repl-handler (-> (drawbridge/ring-handler)
                         (keyword-params/wrap-keyword-params)
                         (nested-params/wrap-nested-params)
                         (params/wrap-params)
                         (session/wrap-session)
                         (basic/wrap-basic-authentication authenticated?)
                         (ssl/wrap-forwarded-scheme)
                         (proxy-headers/wrap-forwarded-remote-addr))]
    (fn [request]
      (if (= repl-uri (:uri request))
        (repl-handler request)
        (handler request)))))

Any idea what I'm doing wrong?

EDIT: simplified the code as much as possible.

Keep client and server in separate namespaces

Leiningen pulls in drawbridge for the purposes of connecting to a drawbridge repl as a client. I'd like to add an :exclusions entry for ring since it's not needed for our purposes, but then we won't be able to load the drawbridge namespace since the client and server are in the same place.

I can do a pull request that moves ring-client-transport into the cemerick.drawbridge.client namespace if you agree.

Switch CI to CircleCI

Seems Drawbridge is the only nREPL project that's still using Travis. We'll have to update the build to mirror the rest of the projects in nREPL org.

Drawbridge should ship a copy of the EPL license in LICENSE

One requirement for licensing code under the EPL is that "a copy of this Agreement [the EPL] must be included with each copy of the Program." [0]. Unfortunately drawbridge does not comply with this requirement even though its project.clj claims that it is licensed under the EPL.

Please fix this issue and release a new version of drawbridge as it is not legally distributable in its current form.

[0] http://www.eclipse.org/legal/epl-v10.html → 3. REQUIREMENTS

clobbers ring sessions

drawbridge should merge sessions to play nice with other consumers of sessions like friend

GET floods

I'm not sure where this could be coming from-- repl-y, lein, drawbridge, nrepl, or something else-- but I saw it using drawbridge so I'll report it here and hope for the best.

When doing a very simple compojure hello world following the drawbridge README, and then connecting via:

lein repl :connect http://localhost:8080/repl

Everything seems functional, but a packet sniff shows that the server is getting pummeled by empty GET requests to that URL, every 8ms.

The GETs seem identical, and take this form:

GET /repl HTTP/1.1
Connection: close
accept-encoding: gzip, deflate
cookie: ring-session=e868f195-cc61-4e4b-9dc0-619446e17ffa
Content-Length: 0
Host: localhost:8080
User-Agent: Apache-HttpClient/4.2.2 (java 1.5)

HTTP/1.1 200 OK
Date: Mon, 28 Jan 2013 00:53:17 GMT
Content-Type: application/json;charset=ISO-8859-1
Connection: close
Server: Jetty(7.6.1.v20120215)

[

]

There are POSTs amongst this haystack that have acutal forms and their evaluation results, so it's working. But that's a lot of SPAM packets, apparently just no-ops, and, every 8ms seems a bit excessive.

This is using Leiningen 2.0.0-RC2 on Java 1.7.0_03 OpenJDK 64-Bit Server VM, and drawbridge 0.0.6.

Drawbridge sessions can't be serialized

When I try to use drawbidge with clj-redis-session, I get this error on connection

java.lang.IllegalArgumentException: No method in multimethod 'print-dup' for dispatch value: class clojure.tools.nrepl.transport.QueueTransport.

Would it make sense to add something to the docs about how you need to be using an in-memory session store? OR, better yet, Drawbridge would handle its own session store, if this is a requirement.

dependency resolution issue after lein2 clean

replication: with lein2 and after doing lein2 clean, then lein2 run and it outputs:
Exception in thread "main" java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate ring/middleware/head__init.class or ring/middleware/head.clj on classpath:

suggestion: drawbridge needs its dependency "ring-core" updated to at least "1.1.0".

How to use Drawbridge from Cursive?

I've got Drawbridge set-up server-side on Heroku. The /repl responds correctly, but how do I use this from a client-side REPL, specifically using IntelliJ + Cursive?

When I create a remote REPL endpoint with, I get an UnknownHostException:

"https://my-project-123.herokuapp.com/repl:80" - class java.net.UnknownHostException:
https://my-project-123.herokuapp.com/repl
"Error connecting to https://my-project-123.herokuapp.com/repl:80 -
class java.net.UnknownHostException: https://my-project-123.herokuapp.com/repl

Project dependencies are a bit old

In my environment, I need drawbridge to put a special auth token header on every request (a secret-key JWT). This was accomplished by loading clj-http and changing the default middleware. I needed to go look at the code for the clj-http 0.3.6 since it no longer matches the docs in that area.

clj-http 0.3.6 is from five years ago. That is one old dependency. Any reason drawbridge's dependencies are so far out of date?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.