From 138733ef05cee3c9de8059c85ade203894011f4a Mon Sep 17 00:00:00 2001 From: Hugo Thunnissen Date: Mon, 22 Oct 2018 00:25:11 +0200 Subject: [PATCH] Respect "content-length" header --- stomp.el | 53 ++++++++++++++++--------- test/test.el | 14 ++++++- test/testdata/content_length_frame.txt | Bin 0 -> 65 bytes 3 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 test/testdata/content_length_frame.txt diff --git a/stomp.el b/stomp.el index ec2ae9b..d5a5d2f 100644 --- a/stomp.el +++ b/stomp.el @@ -42,13 +42,19 @@ be deleted from the buffer." (let ((frame (stomp-read-frame buffer))) (cond - (frame (stomp-delete-frame buffer) frame) + (frame (stomp-delete-frame buffer frame) frame) (t nil)))) -(defun stomp-delete-frame (buffer) +(defun stomp-delete-frame (buffer frame) "Delete the top-most messsage in a buffer" (with-current-buffer buffer - (delete-region (point-min) (+ 2 (stomp-find-frame-end-point buffer))))) + (delete-region (point-min) (+ 2 (stomp-find-frame-end-point buffer frame))))) + +(defun stomp-frame-header (header frame) + "Shortcut to access frame headers" + (assoc-default + "content-length" + (alist-get 'headers frame nil) 'string-equal nil)) (defun stomp-read-frame (buffer) "Attempt to read a single frame from a buffer. @@ -57,16 +63,16 @@ frames in the buffer, nil will be returned." (with-current-buffer buffer (let ((frame ()) - (headers-end-point (stomp-find-headers-end-point buffer)) - (frame-end-point (stomp-find-frame-end-point buffer))) + (headers-end-point (stomp-find-headers-end-point buffer))) (goto-char (point-min)) (cond - ((and frame-end-point headers-end-point) + ((and headers-end-point) (map-put frame 'command (current-word)) (map-put frame 'headers (stomp-read-headers buffer headers-end-point)) - ;; TODO: take content-length header into account - ;; This is might be hard to do if the content contains carriage returns. - (map-put frame 'content (buffer-substring (+ 1 headers-end-point) frame-end-point))) + (map-put frame 'content + (buffer-substring + (+ 1 headers-end-point) + (stomp-find-frame-end-point buffer frame headers-end-point)))) (t nil))))) (defun stomp-read-headers (buffer end-point &optional headers) @@ -78,17 +84,28 @@ (cond ((= (line-end-position) end-point) headers) ((> (length header) 2) (throw 'invalid-header nil)) - (t (stomp-read-headers buffer end-point - (map-put headers - (car header) - (replace-regexp-in-string "\\(\n\\|\r\n\\)$" "" (car (last header)))))))))) + (t (stomp-read-headers + buffer + end-point + (map-put headers + (car header) + (replace-regexp-in-string "\\(\n\\|\r\n\\)$" "" (car (last header)))))))))) -(defun stomp-find-frame-end-point (buffer) - "Find the null byte at the end of a STOMP frame" +(defun stomp-find-frame-end-point (buffer frame &optional headers-end-point) + "Find the end point of a STOMP frame at the top of a buffer, + either by using the content-length header or by searching for + the null octet." (with-current-buffer buffer - (goto-char (point-min)) - (search-forward-regexp "\u0000\\|\u0000\r") - (- (point) 1))) + (let ((content-length (stomp-frame-header "content-length" frame)) + (headers-end-point(if headers-end-point + headers-end-point + (stomp-find-headers-end-point buffer)))) + (if content-length + (+ headers-end-point 1 (string-to-number content-length)) + (progn + (goto-char (point-min)) + (search-forward-regexp "\u0000\\|\u0000\r") + (- (point) 1)))))) (defun stomp-find-headers-end-point (buffer) "Find the end of the header part of a STOMP frame." diff --git a/test/test.el b/test/test.el index f07cf8a..9c0d0dd 100755 --- a/test/test.el +++ b/test/test.el @@ -48,12 +48,24 @@ ("some-header" . "value")))) (should (equal (alist-get 'content recieved) "content\r\n")))) +(ert-deftest can-read-fixed-length-frame () + "Can read a frame that has a content-length header correctly" + (with-testing-buffer + "content_length_frame.txt" + (setq recieved (stomp-read-frame (current-buffer))) + + (should (equal (alist-get 'command recieved) "MESSAGE")) + (should (equal (alist-get 'headers recieved) + '(("destination" . "/banana/kiwi") + ("content-length" . "11")))) + (should (equal (alist-get 'content recieved) "jwe\u0000jsiwli\u0000")))) + (ert-deftest can-delete-one-frame () "Can delete the topmost frame in a buffer" (with-testing-buffer "multiple_frames.txt" (let ((buffer (current-buffer))) - (stomp-delete-frame buffer) + (stomp-delete-frame buffer nil) (with-current-buffer buffer (should (equal (buffer-string) "BLA\nsome-header:value\nok:bye\n\ncontent\n\u0000\n")))))) diff --git a/test/testdata/content_length_frame.txt b/test/testdata/content_length_frame.txt new file mode 100644 index 0000000000000000000000000000000000000000..4be6de60fbfa26f3447fac7da2d35868a266acf1 GIT binary patch literal 65 zcmeZu4Gwm6cjZdX&nrpIE78qK%}X!Iurf5{N=Yp)$;?YE$;{8Q(oagv148}m%<@bw SuB`G@hOFYu@|;Wt1}*^Hd=;et literal 0 HcmV?d00001