flask-socketio: limit transport to websocket only - flask-socketio

in flask-socketio, is it possible to force the transport to be only web socket?
According to the original protocol:
https://github.com/socketio/engine.io
transports (<Array> String): transports to allow connections to (['polling', 'websocket'])
My goal would be to get rid of the original HTTP call.
Best,

See this post - Socket.io 1.x: use WebSockets only?
It looks like you can't get rid of the original HTTP call, but you can tell the client not to use long-polling.
var socket = io({transports: ['websocket']});
I can't find a way to disable it from the server-side with Flask-SocketIO.

According to the documentation of Flask-SoskcetIO you can use async_mode to set async_mode. if you installed eventlet or gevent with gevent-websocket the websocket would be used first.
async_mode: The asynchronous model to use. See the Deployment
section in the documentation for a description of the
available options. Valid async modes are
``threading``, ``eventlet``, ``gevent`` and
``gevent_uwsgi``. If this argument is not given,
``eventlet`` is tried first, then ``gevent_uwsgi``,
then ``gevent``, and finally ``threading``. The
first async mode that has all its dependencies installed
is then one that is chosen.

Related

Difference between http and HttpClient in Dart

I'm trying to understand the difference between the http package and the HttpClient class in the dart:io library. My purpose is to known when I should use which. I see both of them used to apparently do the same thing.
I've seen these Q&As:
Choosing between package:html, dart:html, dart:io (class HttpClient) and package:http APIs to fetch HTTP resources
How to make HTTPS request using HttpClient in dart?
In a Dart console application, is there a library for an HTTP Request that doesnt require DOM access?
How to do POST in Dart command line HttpClient
This is what I think is true so far but my understanding is fuzzy:
http is high level and HttpClient is low level (source)
http can make post requests but HttpClient can't (source)
both http and HttpClient (with HttpClientRequest) can make GET and POST requests (source)
both http and HttpClient can be used on the client and the server
So to sum it up, I would say that each one can do anything that the other can as well, but it is easier to use the http package since this one is more high-level. Is that summary correct?
The http package is an abstraction over dart:io and dart:html.
So if you want to share code between browser and other platforms that makes HTTP requests, then it's best to use the http package. Then the code will just work everywhere.
If you don't care about the browser use what API you like best. In Flutter the http package just wraps dart:io's HttpClient.

Is it possible for a Prosody server to make an HTTP request to an external API

The Prosody server has several modules that allow it to respond to HTTP requests.
For example, mod_http_rest allows me to make a POST request on port 5280 with an XMPP stanza as the payload, and the Prosody server responds by sending that stanza on its way.
However, I am looking for a module that would do the opposite: i.e. take an XMPP message received by the usual means, and make an HTTP POST request to a specified server with that message as the payload.
I can't seem to find any module that will do this. Is there such a thing?
If not, is there any functionality available in the Prosody API that would allow such a module to be written?
Alternatively, are there good reasons why this might be a bad idea?
To answer your question, yes, it's possible for Prosody to make HTTP requests to external services.
The module you describe (take XMPP and forward it over HTTP) did not exist, but there's little reason for it not to. So I just published a module that provides this feature: https://modules.prosody.im/mod_component_http.html
I dont known if there is a module already for that but there is a way to achieve it yourself. I made my own module some months back for specific purposes and I used net.http which as the Docs say:
Is an API for making non-blocking HTTP requests to remote servers.
So you should check the Docs from here so you can use it like:
local req = require "net.http"
req.request( URL, opts, callBack )
Where opts are your options in json, and callBack is a function that defines what you want to do with the response.
I hope it helps.

Meteor http get retrieving only a subset of headers

In my Meteor (1.2) application, I make a client-side HTTP.get call over https to a remote server supporting CORS.
var getUrl= "https://remoteserver/;
HTTP.call('GET', getUrl , {}, function (error, response) {
console.log (response);
}
Now, the issue is that set-cookie string is present in HTTP headers of the response of such HTTP call in Chrome's DevTools' Network tab.
However when I call console.log (response) , they're not included. Actually only these 3 properties are printed in response['headers']:
Content-Type
cache-control
last-modified
Digging more in, I found out on Meteor Docs that
Cookies are deliberately excluded from the headers as they are a security risk for this transport. For details and alternatives, see the SockJS documentation.
Now, on the linked SockJS docs, it says that
Basically - cookies are not suited for SockJS model. If you want to authorise a session - provide a unique token on a page, send it as a first thing over SockJS connection and validate it on the server side. In essence, this is how cookies work.
I found this this answer about sockJS but it looks outdated an not specific to Meteor.
The remote server expects me to use cookie-set header, so I have no choice. Also, for established scalability reasons, the HTTP.call must be done client-side (server-side was not an issue at all)
What solution / workaround can I adopt?
This package looks to be designed to help in situations like this, though I have not used it:
https://atmospherejs.com/dandv/http-more

Atmosphere - Need to modify ws URL before connection

I need to modify the ws url before it establishes a websocket connection.
I'm using #ManagedService in the server code and subscribing from client side using $.atmosphere.subscribe(request).
I've the following setup:
Cyberoam firewall --> Apache httpd(mod_proxy_ajp,mod_jk for load balancing) --> Glassfish
Primary Transport --> WebSocket
Fallback Transport --> long-polling
Problem I'm facing:
The Cyberoam firewall is having a limitation (in WAF) that the max characters in GET URL cannot exceeds 50 chars. But when I hit the subscribe in atmosphere, it is constructing the URL with all the X-Atmosphere-.. params along with it.
For e.g ws://localhost:8080/chat?X-Atmosphere-tracking-id=5ebed4c5-0b90-4166-88b2-9f273719ab75&X-Atmosphere-Framework=2.2.1-jquery&X-Atmosphere-Transport=websocket&Content-Type=application/json&X-atmo-protocol=true") which clearly exceeds the allowable limits.
I just need to know whether I can somehow construct the URL in my server code appending all the necessary headers and params before it connects?
Yes, I have set the attachHeadersAsQueryString:false while making the initial request, and obviously it doesn't connect with missing headers information while doing a WebSocket connection.
Any suggestions/thoughts would be greatly appreciated.
Thank You.
Use request.attachHeadersAsQueryString = false so mo query string will be passed. You may need to upgrade to the latest version of Javascript
https://github.com/Atmosphere/atmosphere-javascript
-- Jeanfrancois (Atmosphere's lead)

How do server-sent events actually work?

So I understand the concept of server-sent events (EventSource):
A client connects to an endpoint via EventSource
Client just listens to messages sent from the endpoint
The thing I'm confused about is how it works on the server. I've had a look at different examples, but the one that comes to mind is Mozilla's: http://hacks.mozilla.org/2011/06/a-wall-powered-by-eventsource-and-server-sent-events/
Now this may be just a bad example, but it kinda makes sense how the server side would work, as I understand it:
Something changes in a datastore, such as a database
A server-side script polls the datastore every Nth second
If the polling script notices a change, a server-sent event is fired to the clients
Does that make sense? Is that really how it works from a barebones perspective?
The HTML5 doctor site has a great write-up on server-sent events, but I'll try to provide a (reasonably) short summary here as well.
Server-sent events are, at its core, a long running http connection, a special mime type (text/event-stream) and a user agent that provides the EventSource API. Together, these make the foundation of a unidirectional connection between a server and a client, where messages can be sent from server to client.
On the server side, it's rather simple. All you really need to do is set the following http headers:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Be sure to respond with the code 200 and not 204 or any other code, as this will cause compliant user agents to disconnect. Also, make sure to not end the connection on the server side. You are now free to start pushing messages down that connection. In nodejs (using express), this might look something like the following:
app.get("/my-stream", function(req, res) {
res.status(200)
.set({ "content-type" : "text/event-stream"
, "cache-control" : "no-cache"
, "connection" : "keep-alive"
})
res.write("data: Hello, world!\n\n")
})
On the client, you just use the EventSource API, as you noted:
var source = new EventSource("/my-stream")
source.addEventListener("message", function(message) {
console.log(message.data)
})
And that's it, basically.
Now, in practice, what actually happens here is that the connection is kept alive by the server and the client by means of a mutual contract. The server will keep the connection alive for as long as it sees fit. Should it want to, it may terminate the connection and respond with a 204 No Content next time the client tries to connect. This will cause the client to stop trying to reconnect. I'm not sure if there's a way to end the connection in a way that the client is told not to reconnect at all, thereby skipping the client trying to reconnect once.
As mentioned client will keep the connection alive as well, and try to reconnect if it is dropped. The algorithm to reconnect is specified in the spec, and is fairly straight forward.
One super important bit that I've so far barely touched on however is the mime type. The mime type defines the format of the message coming down the connecting. Note however that it doesn't dictate the format of the contents of the messages, just the structure of the messages themselves. The mime type is extremely straight forward. Messages are essentially key/value pairs of information. The key must be one of a predefined set:
id - the id of the message
data - the actual data
event - the event type
retry - milleseconds the user agent should wait before retrying a failed connection
Any other keys should be ignored. Messages are then delimited by the use of two newline characters: \n\n
The following is a valid message: (last new line characters added for verbosity)
data: Hello, world!
\n
The client will see this as: Hello, world!.
As is this:
data: Hello,
data: world!
\n
The client will see this as: Hello,\nworld!.
That pretty much sums up what server-sent events are: a long running non-cached http connection, a mime type and a simple javascript API.
For more information, I strongly suggest reading the specification. It's small and describes things very well (although the requirements of the server side could possibly be summarized a bit better.) I highly suggest reading it for the expected behavior with certain http status codes, for instance.
You also need to make sure to call res.flushHeaders(), otherwise Node.js won't send the HTTP headers until you call res.end(). See this tutorial for a complete example.

Resources