Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client with :ajax fails with Assert failed: (string? prefixed-pstr) #95

Closed
martinhynar opened this issue Jan 16, 2015 · 11 comments
Closed

Comments

@martinhynar
Copy link

Hi,

I have client that wants to communicate with backend over Ajax. I first configured the client part with :type :auto and on my local machine it ended up to be always :ws but then I realized that the target Apache is 2.2 which is missing WebSockets support, so I changed to :type :ajax. Until that, all client/server communication was just fine, but with :ajax I immediately started to receive bellow exception. Note that there is still no Apache. It is just lein run, starting http-kit.

2015-Jan-16 11:41:28 +0100 localhost INFO [app.ui-backend.websockets] - Client connected :client-4f912139
Fri Jan 16 11:41:33 CET 2015 [worker-1] ERROR - POST /ws
java.lang.AssertionError: Assert failed: (string? prefixed-pstr)
    at taoensso.sente$unpack.invoke(sente.clj:242)
    at taoensso.sente$make_channel_socket_BANG_$fn__13809.invoke(sente.clj:440)
    at app.rest.routes$fn__16923.invoke(routes.clj:226)
        ...

I thought it is complaining about non-prefixed message id, but I am sending this [:app/login {:username "" :password ""}].

On server side, I use Stuart Sierra's component library and I enrich each request coming in with some references to components. The wrapper function is bellow. In fact, ws is map containing ajax-post-fn function that is called on the request later in POST /ws route.

(defn wrap-app-component [f ws]
  (fn [req] (f (assoc req ::ws ws))))

I tried to read body from the failing POST request, and it has following form:

_=1421407295204&ppstr=%2B%5B%5B%3Aapp%2Flogin%20%7B%3Ausername%20%22test%22%2C%20%3Apassword%20%22%22%7D%5D%200%5D&csrf-token=6f279a6a-87b4-4a5a-b4a4-67b5be2ab936

I am using sente "1.2.0" and http-kit "2.1.19". Tried also sente "1.3.0RC2", same result.

@ptaoussanis
Copy link
Member

Hi Martin,

Could you please try the Sente reference example over Ajax (it randomly selects :ajax or :ws) and let me know if you're still seeing the same problem on your system? Thanks!

@martinhynar
Copy link
Author

The reference example work just fine. For both :ws and :ajax I saw clients popping up.

@ptaoussanis
Copy link
Member

Can you try run lein clean (or remove your target/ dir) and try your own project again?

@martinhynar
Copy link
Author

Still the same.
I feel like there is something missing in the request when it is passed to ajax-post-fn. I printed it to console:

{:remote-addr "127.0.0.1",
 :headers
 {"origin" "http://localhost:8080",
  "x-requested-with" "XMLHTTPRequest",
  "host" "localhost:8080",
  "user-agent"
  "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
  "content-type" "application/x-www-form-urlencoded; charset=UTF-8",
  "cookie" "ring-session=a84692cf-f878-4b99-b229-8620f287ae2c",
  "content-length" "165",
  "referer" "http://localhost:8080/ui",
  "connection" "keep-alive",
  "accept" "*/*",
  "accept-language" "en-US,en;q=0.8,cs;q=0.6",
  "accept-encoding" "gzip, deflate"},
 :async-channel #<AsyncChannel /127.0.0.1:8080<->/127.0.0.1:35818>,
 :server-port 8080,
 :content-length 165,
 :websocket? false,
 :content-type "application/x-www-form-urlencoded",
 :character-encoding "UTF-8",
 :uri "/ws",
 :server-name "localhost",
 :query-string nil,
 :body #<BytesInputStream BytesInputStream[len=165]>,
 :scheme :http,
 :request-method :post}

I see no :params key. The :ppstr which is read from params in ajax-post-fn is taken from there. Am I missing some wrapper that will populate it from body data?

@ptaoussanis
Copy link
Member

I see no :params key. The :ppstr which is read from params in ajax-post-fn is taken from there. Am I missing some wrapper that will populate it from body data?

That's a good catch. Are you using Ring's wrap-params and wrap-keyword-params middleware? If not, you should be seeing a warning being logged on the server side.

@martinhynar
Copy link
Author

That was it!

I was missing both wrappers and they have to be in that specific order of application, first wrap-params then wrap-keyword-params. (just for the record, if somebody ever tackles the same problem)

I saw that warning when I was trying with sente '1.3.0-RC2' but it was missing with "1.2.0" and I got feeling that it is because of some new functionality.

Thanks for helping!

@ptaoussanis
Copy link
Member

No problem, happy you've got it working :-)

@seancorfield
Copy link
Collaborator

Just FYI, this caught me out too when Ring's site wrapper was deprecated. I wonder if it's worth Sente providing a minimum default wrapper?

@ptaoussanis
Copy link
Member

@seancorfield Hey Sean, what version did you have the trouble with? v1.3+ issues a warning when the necessary middleware is missing.

@seancorfield
Copy link
Collaborator

The warning's easy to miss tho' - as shown above. It was a while back but I think what happened was that I updated Ring, found site was missing (or deprecated? I don't recall) and it took me a while to figure out what Sente needed in order to function correctly. If Sente requires it, why not throw an exception?

@ptaoussanis
Copy link
Member

If Sente requires it, why not throw an exception?

This is true ;-) Will make the change tomorrow. Appreciate the input!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants