Open joewalnes opened 9 years ago
+1 - it would allow to write middleware for really simple shell scripts which can be executed on each request - simple way to extend websocketd functionality with any kind of language, if script execution is based only on STDIN/OUT and exit code ;-)
several ideas on this:
cache
, throttle
, path_rewrite
, rewrite_message_structure
)handlers
subdirectorywebsocketd --middlewaredir=handlers
Another way to add middleware tasks is to pass a list of programs to websocketd; it would call them exactly like a pipeline on the shell:
./service | ./logger | ./compression | ./format_converter | ./path_rewriter
would be plugged into websocketd with
websocketd ./service ./logger ./compression ./format_converter ./path_rewriter
There might be a way to pass that pipeline command directly to websocketd, but it would require some escaping/quoting/subshell-wrangling that makes bash a headache at times.
Yes, as you said pipelines are something that's already possible with current websocketd, something like
websocketd bash -c './script | ./script'
Similarly you can create bunch of scripts that implement calls using "middleware" and put it to series of files and use --dir for them. So really there is no feature if we stay in line protocol mode.
I think what Joe had in mind is more HTTP-ish handlers, which may be working before/after script is called and have access to context of the HTTP request...
Say it's CGI scripts, we may have "onConnect", "onDisconnect" scripts for now... Should there be others? Each script modifies context of the request. onConnect can set HTTP headers which passed to main script as CONNECT_HEADERNAME variables. There could be only one onConnect so if you need multiple you write wrapper execute scripts you need and figure what to return, it's not a websocketd problem to figure merge strategy.
onDisconnect gets executed with additional HTTP headers in request signifying all those variables (X_CONNECT_HEADER_NAME), used protocol, script command, exit code, reason for disconnect, bytes received/sent from client, and maybe others...
I can spec it more and even write it into code... Just need more support on "where it could be helpful"
I don't think we can have more handlers... IMO all compression of websocket exchange should be done in websocketd itself, I see large problems to keep chain of piped scripts together under websocketd management, IMO it's unnecessary when you can outsource it to bash running them in way you want. So middleware for changing messages and/or filtering input is down to user's responsibilities... Please find example where I might be wrong. I just feel it could be implemented in three stages...
onConnect additionally may have option to prohibit protocol upgrade by not returning 1xx / 2xx response... Not sure on that.
We need to form middleware API here....
What actual things websocket knows that it can share with middleware about webclient to script link that's worth sharing....
What actions we want to allow API to do to either end of those links?
Is there good inspiration middlewares in unix world that we know?
Would this break the UNIX philosophy of "Write programs that do one thing and do it well....." ... ?
Maybe follow what Git does for credential helpers. Define an interface that websocketd will send a program, and that program is expected to return certain responses. For example, you could define an "input" interface that would take the same CGI variables in the environment, some representation of the connection (toml perhaps) on stdin, and be expected to set error code and/or format its output in a certain way, which websocketd will then interpret. Same for output. Then you can pass on on the command line websocketd -input ./auth.sh -output ./cache-control.sh ./example
I'd like to be able to add middleware handlers. These are roughly equivalent to Rack or WSGI Middleware, Java Filters, etc.
Apps can configure a stack of 0 to N handlers that get invoked on each request. The can do things like modify inbound/outbound content (headers, websocket messages, static/cgi pages, etc).
Use cases:
I haven't fleshed out details for exactly how this should work, but in the spirit of websocketd, it would be ideal if each of these middleware components was a user defined executable that could be written in any language. Some of them may be short lived (e.g. path rewriting), whereas others may live for the complete lifetime of the connection (e.g. message compress).