Comments (8)
It looks like chrome is sending \n instead of \r\n as the line delimiter.
Replacing \r\n with \n worked, but is not the proper solution:
(defun websocket-verify-client-headers (output) "Verify the headers from the WEBSOCKET client connection in OUTPUT. Unlike `websocket-verify-headers', this is a quieter routine. We don't want to error due to a bad client, so we just print out messages and a plist containing `:key', the websocket key, `:protocols' and `:extensions'." (block nil (let ((case-fold-search t) (plist)) (unless (string-match "HTTP/1.1" output) (message "Websocket client connection: HTTP/1.1 not found") (return nil)) (unless (string-match "^Host: " output) (message "Websocket client connection: Host header not found") (return nil)) (unless (string-match "^Upgrade: websocket\n" output) (message "Websocket client connection: Upgrade: websocket not found") (return nil)) (if (string-match "^Sec-WebSocket-Key: \\([[:graph:]]+\\)\n" output) (setq plist (plist-put plist :key (match-string 1 output))) (message "Websocket client connect: No key sent") (return nil)) (unless (string-match "^Sec-WebSocket-Version: 13" output) (message "Websocket client connect: Websocket version 13 not found") (return nil)) (when (string-match "^Sec-WebSocket-Protocol:" output) (setq plist (plist-put plist :protocols (websocket-parse-repeated-field output "Sec-Websocket-Protocol")))) (when (string-match "^Sec-WebSocket-Extensions:" output) (setq plist (plist-put plist :extensions (websocket-parse-repeated-field output "Sec-Websocket-Extensions")))) plist))) (defun websocket-server-filter (process output) "This acts on all OUTPUT from websocket clients PROCESS." (message "here") (let* ((ws (process-get process :websocket)) (text (concat (websocket-inflight-input ws) output))) (setf (websocket-inflight-input ws) nil) (cond ((eq (websocket-ready-state ws) 'connecting) ;; check for connection string (let ((end-of-header-pos (let ((pos (string-match "\n\n" text))) (when pos (+ 4 pos))))) (if end-of-header-pos (progn (let ((header-info (websocket-verify-client-headers text))) (if header-info (progn (setf (websocket-accept-string ws) (websocket-calculate-accept (plist-get header-info :key))) (process-send-string process (websocket-get-server-response ws (plist-get header-info :protocols) (plist-get header-info :extensions))) (setf (websocket-ready-state ws) 'open) (websocket-try-callback 'websocket-on-open 'on-open ws)) (message "Invalid client headers found in: %s" output) (process-send-string process "HTTP/1.1 400 Bad Request\r\n\r\n") (websocket-close ws))) (when (> (length text) (+ 1 end-of-header-pos)) (websocket-server-filter process (substring text end-of-header-pos)))) (setf (websocket-inflight-input ws) text)))) ((eq (websocket-ready-state ws) 'open) (websocket-process-input-on-open-ws ws text)) ((eq (websocket-ready-state ws) 'closed) (message "WARNING: Should not have received further input on closed websocket")))))
from emacs-websocket.
Thanks, it might be that we need to be a bit more lenient with different
styles of line breaks. I'll take a look tonight. Thanks for the great bug
report.
On Tue, May 7, 2013 at 9:59 AM, joebo [email protected] wrote:
It looks like chrome is sending \n instead of \r\n as the line delimiter.
Replacing \r\n with \n worked, but is not the proper solution:
(defun websocket-verify-client-headers (output)
"Verify the headers from the WEBSOCKET client connection in OUTPUT.
Unlike websocket-verify-headers', this is a quieter routine. We
don't want to error due to a bad client, so we just print out
messages and a plist containing:key', the websocket key,
:protocols' and:extensions'."
(block nil
(let ((case-fold-search t)
(plist))
(unless (string-match "HTTP/1.1" output)
(message "Websocket client connection: HTTP/1.1 not found")
(return nil))
(unless (string-match "^Host: " output)
(message "Websocket client connection: Host header not found")
(return nil))
(unless (string-match "^Upgrade: websocket\n" output)
(message "Websocket client connection: Upgrade: websocket not found")
(return nil))
(if (string-match "^Sec-WebSocket-Key: ([[:graph:]]+)\n" output)
(setq plist (plist-put plist :key (match-string 1 output)))
(message "Websocket client connect: No key sent")
(return nil))
(unless (string-match "^Sec-WebSocket-Version: 13" output)
(message "Websocket client connect: Websocket version 13 not found")
(return nil))
(when (string-match "^Sec-WebSocket-Protocol:" output)
(setq plist (plist-put plist :protocols (websocket-parse-repeated-field
output
"Sec-Websocket-Protocol"))))
(when (string-match "^Sec-WebSocket-Extensions:" output)
(setq plist (plist-put plist :extensions (websocket-parse-repeated-field
output
"Sec-Websocket-Extensions"))))
plist)))(defun websocket-server-filter (process output)
"This acts on all OUTPUT from websocket clients PROCESS."
(message "here")
(let* ((ws (process-get process :websocket))
(text (concat (websocket-inflight-input ws) output)))
(setf (websocket-inflight-input ws) nil)
(cond ((eq (websocket-ready-state ws) 'connecting)
;; check for connection string
(let ((end-of-header-pos
(let ((pos (string-match "\n\n" text)))
(when pos (+ 4 pos)))))
(if end-of-header-pos
(progn
(let ((header-info (websocket-verify-client-headers text)))
(if header-info
(progn (setf (websocket-accept-string ws)
(websocket-calculate-accept
(plist-get header-info :key)))
(process-send-string
process
(websocket-get-server-response
ws (plist-get header-info :protocols)
(plist-get header-info :extensions)))
(setf (websocket-ready-state ws) 'open)
(websocket-try-callback 'websocket-on-open
'on-open ws))
(message "Invalid client headers found in: %s" output)
(process-send-string process "HTTP/1.1 400 Bad Request\r\n\r\n")
(websocket-close ws)))
(when (> (length text) (+ 1 end-of-header-pos))
(websocket-server-filter process (substring
text
end-of-header-pos))))
(setf (websocket-inflight-input ws) text))))
((eq (websocket-ready-state ws) 'open)
(websocket-process-input-on-open-ws ws text))
((eq (websocket-ready-state ws) 'closed)
(message "WARNING: Should not have received further input on closed
websocket")))))—
Reply to this email directly or view it on GitHubhttps://github.com//issues/30#issuecomment-17543672
.
from emacs-websocket.
Thanks for library!
I've used it to create a simple little script that will trigger a browser
refresh upon saving in emacs - much like livereload or xrefresh.
It's like 10 lines of code :)
It's hacky, but it works:
(require 'websocket)
(setq websocket-mask-frames nil)
;;copies of web-verify-client-headers and websocket-server-filter with
linebreaks changed
(defun on-open (websocket)
(setq Socket websocket))
(setq ws-server
(websocket-server
9999
:on-open 'on-open))
(defun refresh-save-hook ()
(interactive)
(websocket-send-text Socket "foo"))
(add-hook 'after-save-hook 'refresh-save-hook)
Then in my app I just have some code that detects whether it's being served
from localhost and emits this
var ws = new WebSocket("ws://localhost:9999/");
ws.onmessage = function(e) { window.location.reload(); }
On Tue, May 7, 2013 at 5:01 PM, Andrew Hyatt [email protected]:
Thanks, it might be that we need to be a bit more lenient with different
styles of line breaks. I'll take a look tonight. Thanks for the great bug
report.On Tue, May 7, 2013 at 9:59 AM, joebo [email protected] wrote:
It looks like chrome is sending \n instead of \r\n as the line
delimiter.Replacing \r\n with \n worked, but is not the proper solution:
(defun websocket-verify-client-headers (output)
"Verify the headers from the WEBSOCKET client connection in OUTPUT.
Unlike websocket-verify-headers', this is a quieter routine. We
don't want to error due to a bad client, so we just print out
messages and a plist containing:key', the websocket key,
:protocols' and:extensions'."
(block nil
(let ((case-fold-search t)
(plist))
(unless (string-match "HTTP/1.1" output)
(message "Websocket client connection: HTTP/1.1 not found")
(return nil))
(unless (string-match "^Host: " output)
(message "Websocket client connection: Host header not found")
(return nil))
(unless (string-match "^Upgrade: websocket\n" output)
(message "Websocket client connection: Upgrade: websocket not found")
(return nil))
(if (string-match "^Sec-WebSocket-Key: ([[:graph:]]+)\n" output)
(setq plist (plist-put plist :key (match-string 1 output)))
(message "Websocket client connect: No key sent")
(return nil))
(unless (string-match "^Sec-WebSocket-Version: 13" output)
(message "Websocket client connect: Websocket version 13 not found")
(return nil))
(when (string-match "^Sec-WebSocket-Protocol:" output)
(setq plist (plist-put plist :protocols (websocket-parse-repeated-field
output
"Sec-Websocket-Protocol"))))
(when (string-match "^Sec-WebSocket-Extensions:" output)
(setq plist (plist-put plist :extensions (websocket-parse-repeated-field
output
"Sec-Websocket-Extensions"))))
plist)))(defun websocket-server-filter (process output)
"This acts on all OUTPUT from websocket clients PROCESS."
(message "here")
(let* ((ws (process-get process :websocket))
(text (concat (websocket-inflight-input ws) output)))
(setf (websocket-inflight-input ws) nil)
(cond ((eq (websocket-ready-state ws) 'connecting)
;; check for connection string
(let ((end-of-header-pos
(let ((pos (string-match "\n\n" text)))
(when pos (+ 4 pos)))))
(if end-of-header-pos
(progn
(let ((header-info (websocket-verify-client-headers text)))
(if header-info
(progn (setf (websocket-accept-string ws)
(websocket-calculate-accept
(plist-get header-info :key)))
(process-send-string
process
(websocket-get-server-response
ws (plist-get header-info :protocols)
(plist-get header-info :extensions)))
(setf (websocket-ready-state ws) 'open)
(websocket-try-callback 'websocket-on-open
'on-open ws))
(message "Invalid client headers found in: %s" output)
(process-send-string process "HTTP/1.1 400 Bad Request\r\n\r\n")
(websocket-close ws)))
(when (> (length text) (+ 1 end-of-header-pos))
(websocket-server-filter process (substring
text
end-of-header-pos))))
(setf (websocket-inflight-input ws) text))))
((eq (websocket-ready-state ws) 'open)
(websocket-process-input-on-open-ws ws text))
((eq (websocket-ready-state ws) 'closed)
(message "WARNING: Should not have received further input on closed
websocket")))))—
Reply to this email directly or view it on GitHub<
https://github.com/ahyatt/emacs-websocket/issues/30#issuecomment-17543672>.
—
Reply to this email directly or view it on GitHubhttps://github.com//issues/30#issuecomment-17570389
.
from emacs-websocket.
I'm having trouble reproducing this. What operating system are you using?
Also, what version of Chrome? The headers have to be \r\n, it's defined in the HTTP spec: http://tools.ietf.org/html/rfc2616#page-31
So if Chrome is sending \n, then something is wrong with Chrome (or perhaps emacs is losing the \r somehow).
from emacs-websocket.
Windows 7
On Tue, May 7, 2013 at 11:50 PM, Andrew Hyatt [email protected]:
I'm having trouble reproducing this. What operating system are you using?
—
Reply to this email directly or view it on GitHubhttps://github.com//issues/30#issuecomment-17585163
.
from emacs-websocket.
OK, that's what I was suspecting.
Can you test with an emacs started up with -Q?
I'm guessing that you have something (or emacs has something by default) that will convert buffers automatically from one style of line breaks to the other.
from emacs-websocket.
emacs -Q didn't help, but further research turned up that the buffer was likely defaulting to dos encoding (windows default), so I added a line to force it to use unix style for the buffer
from emacs-websocket.
Commit merged in. Thank you for the fix!
from emacs-websocket.
Related Issues (20)
- websocket-frame-text error HOT 1
- Add release tags HOT 3
- Custom headers in handshake HOT 4
- How to handle an error occured in `websocket-outer-filter`? HOT 6
- A single message ws.send(data); comes in as two messages HOT 5
- Speed feedback HOT 10
- Randomly losing connections under emacs-ipython-notebook with version 1.11 HOT 5
- Error (websocket): in callback `on-message': JSON readtable error HOT 4
- Setting case-fold-search to nil results "Incorrect handhake from websocket" error HOT 7
- declares GPL-3+, but provided full-text license is GPL-2+ HOT 3
- Please tag a 1.12 release HOT 1
- Please consider adapting websocket-functional-test.el to use ert-deftest HOT 12
- TLSv1.3 HOT 1
- Branch rename breaks package installation HOT 6
- websocket-test.el: ‘flet’ is an obsolete macro (as of [emacs] 24.3) HOT 3
- websocket-to-bytes signal type error HOT 8
- Support connecting through proxies HOT 7
- infinite failure loop - emacs locked up HOT 18
- error 403 with ein over proxy HOT 14
- Push to ELPA? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from emacs-websocket.