From c193d6f867e33db7e1aca34a18491ffeacd3e638 Mon Sep 17 00:00:00 2001 From: Andrew Hyatt Date: Sun, 12 Nov 2017 23:50:52 -0500 Subject: [PATCH 1/2] Add ability for clients to pass custom headers. --- websocket-test.el | 14 +++++++++----- websocket.el | 19 ++++++++++++++----- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/websocket-test.el b/websocket-test.el index 604eb87..772477b 100644 --- a/websocket-test.el +++ b/websocket-test.el @@ -207,18 +207,22 @@ (host localpart secure) "")) (should (equal (concat base-headers "\r\n") (websocket-create-headers "ws://www.example.com/path" - "key" nil nil))) + "key" nil nil nil))) (should (equal (concat base-headers "Sec-WebSocket-Protocol: protocol\r\n\r\n") (websocket-create-headers "ws://www.example.com/path" - "key" '("protocol") nil))) + "key" '("protocol") nil nil))) (should (equal (concat base-headers "Sec-WebSocket-Extensions: ext1; a; b=2, ext2\r\n\r\n") (websocket-create-headers "ws://www.example.com/path" "key" nil '(("ext1" . ("a" "b=2")) - ("ext2")))))) + ("ext2")) nil))) + (should (equal + (concat base-headers "Foo: bar\r\nBaz: boo\r\n") + (websocket-create-headers "ws://www.example.com/path" + "key" nil nil '(("Foo" . "bar") ("Baz" . "boo")))))) (flet ((url-cookie-generate-header-lines (host localpart secure) (should (equal host "www.example.com:123")) @@ -226,7 +230,7 @@ (should secure) "Cookie: foo=bar\r\n")) (should (equal (websocket-create-headers "wss://www.example.com:123/path" - "key" nil nil) + "key" nil nil nil) (concat "Host: www.example.com:123\r\n" "Upgrade: websocket\r\n" @@ -237,7 +241,7 @@ (should (string-match "Host: www.example.com:123\r\n" - (websocket-create-headers "ws://www.example.com:123/path" "key" nil nil))))) + (websocket-create-headers "ws://www.example.com:123/path" "key" nil nil nil))))) (ert-deftest websocket-process-headers () (flet ((url-cookie-handle-set-cookie diff --git a/websocket.el b/websocket.el index e468795..a98344b 100644 --- a/websocket.el +++ b/websocket.el @@ -610,7 +610,7 @@ connecting or open." (cl-defun websocket-open (url &key protocols extensions (on-open 'identity) (on-message (lambda (_w _f))) (on-close 'identity) (on-error 'websocket-default-error-handler) - (nowait nil)) + (nowait nil) (custom-header-alist nil)) "Open a websocket connection to URL, returning the `websocket' struct. The PROTOCOL argument is optional, and setting it will declare to the server that this client supports the protocols in the list @@ -684,6 +684,11 @@ describing the problem with the frame. `nowait': If NOWAIT is non-nil, return without waiting for the connection to complete. Default nil. + +`custom-headers-alist': An alist of custom headers to pass to the +server. The car is the header name, the cdr is the header value. +These are different from the extensions because it is not related +to the websocket protocol. " (let* ((name (format "websocket to %s" url)) (url-struct (url-generic-parse-url url)) @@ -739,7 +744,8 @@ Default nil. (websocket-debug websocket "Sending handshake, key: %s, acceptance: %s" key (websocket-accept-string websocket)) (process-send-string conn - (websocket-create-headers url key protocols extensions)) + (websocket-create-headers + url key protocols extensions custom-header-alist)) (websocket-debug websocket "Websocket opened") websocket)) @@ -907,9 +913,10 @@ connection, which should be kept in order to pass to (not (eq 'closed (websocket-ready-state websocket)))) (websocket-try-callback 'websocket-on-close 'on-close websocket))))))) -(defun websocket-create-headers (url key protocol extensions) - "Create connections headers for the given URL, KEY, PROTOCOL and EXTENSIONS. -These are defined as in `websocket-open'." +(defun websocket-create-headers (url key protocol extensions custom-headers-alist) + "Create connections headers for the given URL, KEY, PROTOCOL, and EXTENSIONS. +Additionally, the CUSTOM-HEADERS-ALIST is passed from the client. +All these parameters are defined as in `websocket-open'." (let* ((parsed-url (url-generic-parse-url url)) (host-port (if (url-port-if-non-default parsed-url) (format "%s:%s" (url-host parsed-url) (url-port parsed-url)) @@ -940,6 +947,8 @@ These are defined as in `websocket-open'." (mapconcat 'identity (cdr ext) "; ")))) extensions ", "))) (when cookie-header cookie-header) + (mapconcat (lambda (cons) (format "%s: %s" (car cons) (cdr cons))) + custom-headers-alist "\r\n") "\r\n") host-port key From 058e8f46962f99b5c63824aec99ad81b295f1a7b Mon Sep 17 00:00:00 2001 From: Andrew Hyatt Date: Mon, 13 Nov 2017 23:40:34 -0500 Subject: [PATCH 2/2] Fix issue with missing \r\n when using custom headers. --- websocket-test.el | 2 +- websocket.el | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/websocket-test.el b/websocket-test.el index 772477b..cfb2db0 100644 --- a/websocket-test.el +++ b/websocket-test.el @@ -220,7 +220,7 @@ '(("ext1" . ("a" "b=2")) ("ext2")) nil))) (should (equal - (concat base-headers "Foo: bar\r\nBaz: boo\r\n") + (concat base-headers "Foo: bar\r\nBaz: boo\r\n\r\n") (websocket-create-headers "ws://www.example.com/path" "key" nil nil '(("Foo" . "bar") ("Baz" . "boo")))))) (flet ((url-cookie-generate-header-lines diff --git a/websocket.el b/websocket.el index a98344b..f175bf6 100644 --- a/websocket.el +++ b/websocket.el @@ -947,8 +947,9 @@ All these parameters are defined as in `websocket-open'." (mapconcat 'identity (cdr ext) "; ")))) extensions ", "))) (when cookie-header cookie-header) - (mapconcat (lambda (cons) (format "%s: %s" (car cons) (cdr cons))) - custom-headers-alist "\r\n") + (concat (mapconcat (lambda (cons) (format "%s: %s" (car cons) (cdr cons))) + custom-headers-alist "\r\n") + (when custom-headers-alist "\r\n")) "\r\n") host-port key