Respect "content-length" header

master
Hugo Thunnissen 6 years ago
parent f886fe49b8
commit 138733ef05

@ -42,13 +42,19 @@
be deleted from the buffer." be deleted from the buffer."
(let ((frame (stomp-read-frame buffer))) (let ((frame (stomp-read-frame buffer)))
(cond (cond
(frame (stomp-delete-frame buffer) frame) (frame (stomp-delete-frame buffer frame) frame)
(t nil)))) (t nil))))
(defun stomp-delete-frame (buffer) (defun stomp-delete-frame (buffer frame)
"Delete the top-most messsage in a buffer" "Delete the top-most messsage in a buffer"
(with-current-buffer 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) (defun stomp-read-frame (buffer)
"Attempt to read a single frame from a buffer. "Attempt to read a single frame from a buffer.
@ -57,16 +63,16 @@
frames in the buffer, nil will be returned." frames in the buffer, nil will be returned."
(with-current-buffer buffer (with-current-buffer buffer
(let ((frame ()) (let ((frame ())
(headers-end-point (stomp-find-headers-end-point buffer)) (headers-end-point (stomp-find-headers-end-point buffer)))
(frame-end-point (stomp-find-frame-end-point buffer)))
(goto-char (point-min)) (goto-char (point-min))
(cond (cond
((and frame-end-point headers-end-point) ((and headers-end-point)
(map-put frame 'command (current-word)) (map-put frame 'command (current-word))
(map-put frame 'headers (stomp-read-headers buffer headers-end-point)) (map-put frame 'headers (stomp-read-headers buffer headers-end-point))
;; TODO: take content-length header into account (map-put frame 'content
;; This is might be hard to do if the content contains carriage returns. (buffer-substring
(map-put frame 'content (buffer-substring (+ 1 headers-end-point) frame-end-point))) (+ 1 headers-end-point)
(stomp-find-frame-end-point buffer frame headers-end-point))))
(t nil))))) (t nil)))))
(defun stomp-read-headers (buffer end-point &optional headers) (defun stomp-read-headers (buffer end-point &optional headers)
@ -78,17 +84,28 @@
(cond (cond
((= (line-end-position) end-point) headers) ((= (line-end-position) end-point) headers)
((> (length header) 2) (throw 'invalid-header nil)) ((> (length header) 2) (throw 'invalid-header nil))
(t (stomp-read-headers buffer end-point (t (stomp-read-headers
(map-put headers buffer
(car header) end-point
(replace-regexp-in-string "\\(\n\\|\r\n\\)$" "" (car (last header)))))))))) (map-put headers
(car header)
(replace-regexp-in-string "\\(\n\\|\r\n\\)$" "" (car (last header))))))))))
(defun stomp-find-frame-end-point (buffer) (defun stomp-find-frame-end-point (buffer frame &optional headers-end-point)
"Find the null byte at the end of a STOMP frame" "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 (with-current-buffer buffer
(goto-char (point-min)) (let ((content-length (stomp-frame-header "content-length" frame))
(search-forward-regexp "\u0000\\|\u0000\r") (headers-end-point(if headers-end-point
(- (point) 1))) 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) (defun stomp-find-headers-end-point (buffer)
"Find the end of the header part of a STOMP frame." "Find the end of the header part of a STOMP frame."

@ -48,12 +48,24 @@
("some-header" . "value")))) ("some-header" . "value"))))
(should (equal (alist-get 'content recieved) "content\r\n")))) (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 () (ert-deftest can-delete-one-frame ()
"Can delete the topmost frame in a buffer" "Can delete the topmost frame in a buffer"
(with-testing-buffer (with-testing-buffer
"multiple_frames.txt" "multiple_frames.txt"
(let ((buffer (current-buffer))) (let ((buffer (current-buffer)))
(stomp-delete-frame buffer) (stomp-delete-frame buffer nil)
(with-current-buffer buffer (with-current-buffer buffer
(should (equal (buffer-string) "BLA\nsome-header:value\nok:bye\n\ncontent\n\u0000\n")))))) (should (equal (buffer-string) "BLA\nsome-header:value\nok:bye\n\ncontent\n\u0000\n"))))))

Binary file not shown.
Loading…
Cancel
Save