PageRenderTime 561ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/asdf-systems/acl-compat/acl-ssl-streams.lisp

https://bitbucket.org/mt/biobike
Lisp | 293 lines | 131 code | 42 blank | 120 comment | 6 complexity | ea439aea3c755c33b42ff3bdc8f61d4c MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause
  1. ;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Package: CL-USER; -*-
  2. ;;;
  3. ;;; Filename: gray-streams-integration.lisp
  4. ;;; Author: Jochen Schmidt <jsc@dataheaven.de>
  5. ;;; Description: Integrate ssl-sockets with the lisp
  6. ;;; stream system using gray-streams.
  7. ;;;
  8. (in-package :ssl)
  9. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  10. ;;; Gray Streams integration ;;;
  11. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  12. (defclass ssl-stream-mixin ()
  13. ((ssl-socket :accessor ssl-socket :initarg :ssl-socket)))
  14. (defclass binary-ssl-stream
  15. (ssl-stream-mixin
  16. gray-stream:fundamental-binary-input-stream
  17. gray-stream:fundamental-binary-output-stream)
  18. ())
  19. (defclass character-ssl-stream
  20. (ssl-stream-mixin
  21. gray-stream:fundamental-character-input-stream
  22. gray-stream:fundamental-character-output-stream)
  23. ())
  24. (defmethod #-cormanlisp gray-stream::stream-element-type #+cormanlisp gray-stream::stream-stream-element-type ((socket-stream binary-ssl-stream))
  25. '(unsigned-byte 8))
  26. (defmethod #-cormanlisp gray-stream::stream-element-type #+cormanlisp gray-stream::stream-stream-element-type ((socket-stream character-ssl-stream))
  27. 'character)
  28. (defmethod gray-stream:stream-line-column ((socket-stream character-ssl-stream))
  29. nil)
  30. (defmethod gray-stream:stream-line-column ((socket-stream binary-ssl-stream))
  31. nil)
  32. (defmethod gray-stream:stream-listen ((socket-stream ssl-stream-mixin))
  33. (with-slots (ssl-socket) socket-stream
  34. (> (ssl-internal:ssl-pending (ssl-internal:ssl-socket-handle ssl-socket)) 0)))
  35. (defmethod gray-stream:stream-read-byte ((socket-stream binary-ssl-stream))
  36. (with-slots (ssl-socket) socket-stream
  37. (ssl-internal:ssl-socket-read-byte ssl-socket)))
  38. (defmethod gray-stream:stream-write-byte ((socket-stream binary-ssl-stream) byte)
  39. (with-slots (ssl-socket) socket-stream
  40. (ssl-internal:ssl-socket-write-byte byte ssl-socket)))
  41. #|
  42. (defmethod gray-stream:stream-read-char ((socket-stream character-ssl-stream))
  43. (with-slots (ssl-socket) socket-stream
  44. (ssl-internal:ssl-socket-read-char ssl-socket)))
  45. (defmethod gray-stream:stream-read-char ((socket-stream binary-ssl-stream))
  46. (with-slots (ssl-socket) socket-stream
  47. (ssl-internal:ssl-socket-read-char ssl-socket)))
  48. |#
  49. ; Bivalent
  50. (defmethod gray-stream:stream-read-char ((socket-stream ssl-stream-mixin))
  51. (with-slots (ssl-socket) socket-stream
  52. (ssl-internal:ssl-socket-read-char ssl-socket)))
  53. (defmethod gray-stream:stream-read-char-no-hang ((socket-stream character-ssl-stream))
  54. (when (listen socket-stream)
  55. (with-slots (ssl-socket) socket-stream
  56. (ssl-internal:ssl-socket-read-char ssl-socket))))
  57. #|
  58. (defmethod gray-stream:stream-write-char ((socket-stream character-ssl-stream) char)
  59. (with-slots (ssl-socket) socket-stream
  60. (ssl-internal:ssl-socket-write-char char ssl-socket)))
  61. (defmethod gray-stream:stream-write-char ((socket-stream binary-ssl-stream) char)
  62. (with-slots (ssl-socket) socket-stream
  63. (ssl-internal:ssl-socket-write-char char ssl-socket)))
  64. |#
  65. ; Bivalent
  66. (defmethod gray-stream:stream-write-char ((socket-stream ssl-stream-mixin) char)
  67. (with-slots (ssl-socket) socket-stream
  68. (ssl-internal:ssl-socket-write-char char ssl-socket)))
  69. ; Bivalent
  70. (defmethod gray-stream:stream-force-output ((socket-stream ssl-stream-mixin))
  71. (with-slots (ssl-socket) socket-stream
  72. (ssl-internal:flush-output-buffer ssl-socket)))
  73. (defmethod gray-stream:stream-finish-output ((socket-stream ssl-stream-mixin))
  74. (with-slots (ssl-socket) socket-stream
  75. (ssl-internal:flush-output-buffer ssl-socket)))
  76. (defmethod gray-stream:stream-clear-output ((socket-stream ssl-stream-mixin))
  77. (with-slots (ssl-socket) socket-stream
  78. (with-slots (ssl-internal::output-offset) ssl-socket
  79. (setf ssl-internal::output-offset 0))))
  80. (defmethod gray-stream:stream-clear-input ((socket-stream ssl-stream-mixin))
  81. (with-slots (ssl-socket) socket-stream
  82. (with-slots (ssl-internal::input-avail ssl-internal::input-offset) ssl-socket
  83. (setf ssl-internal::input-avail 0)
  84. (setf ssl-internal::input-offset 0))))
  85. (defmethod #-cormanlisp common-lisp:close #+cormanlisp gray-stream:stream-close ((socket-stream ssl-stream-mixin) &key abort)
  86. (with-slots (ssl-socket) socket-stream
  87. (unless abort
  88. (ssl-internal:flush-output-buffer ssl-socket))
  89. (ssl-internal:close-ssl-socket ssl-socket)))
  90. #|
  91. (defmethod gray-stream:stream-force-output ((socket-stream character-ssl-stream))
  92. (with-slots (ssl-socket) socket-stream
  93. (ssl-internal:flush-output-buffer ssl-socket)))
  94. (defmethod gray-stream:stream-finish-output ((socket-stream character-ssl-stream))
  95. (with-slots (ssl-socket) socket-stream
  96. (ssl-internal:flush-output-buffer ssl-socket)))
  97. (defmethod gray-stream:stream-clear-output ((socket-stream character-ssl-stream))
  98. (with-slots (ssl-socket) socket-stream
  99. (with-slots (ssl-internal::output-offset) ssl-socket
  100. (setf ssl-internal::output-offset 0))))
  101. (defmethod gray-stream:stream-clear-input ((socket-stream character-ssl-stream))
  102. (with-slots (ssl-socket) socket-stream
  103. (with-slots (ssl-internal::input-avail ssl-internal::input-offset) ssl-socket
  104. (setf ssl-internal::input-avail 0)
  105. (setf ssl-internal::input-offset 0))))
  106. (defmethod gray-stream:stream-read-sequence ((socket-stream character-ssl-stream) sequence start end)
  107. (let* ((len (length sequence))
  108. (chars (- (min (or end len) len) start)))
  109. ;(format t "Read ~A chars from index ~A on.~%" chars start) (force-output t)
  110. (loop for i upfrom start
  111. repeat chars
  112. for char = (progn ;(format t "Read char on index ~A~%" i)
  113. ;(force-output t)
  114. (let ((c (gray-streams:stream-read-char socket-stream)))
  115. ;(format t "The element read was ~A~%" c)
  116. c))
  117. if (eq char :eof) do (progn ;(format t "premature return on index ~A~%" i)
  118. ;(force-output t)
  119. (return-from gray-streams:stream-read-sequence i))
  120. do (setf (elt sequence i) char))
  121. ;(format t "Normal return on index ~A~%" (+ start chars)) (force-output t)
  122. (+ start chars)))
  123. |#
  124. ;;
  125. ;; Why this argument ordering in CMUCL? LW has (stream sequence start end)
  126. ;; It would be interesting to know why it is a particular good idea to
  127. ;; reinvent APIs every second day in an incompatible way.... *grrr*
  128. ;;
  129. #+cmu
  130. (defmethod gray-stream:stream-read-sequence ((socket-stream character-ssl-stream) (sequence sequence) &optional start end)
  131. (let* ((len (length sequence))
  132. (chars (- (min (or end len) len) start)))
  133. (loop for i upfrom start
  134. repeat chars
  135. for char = (gray-stream:stream-read-char socket-stream)
  136. if (eq char :eof) do (return-from gray-stream:stream-read-sequence i)
  137. do (setf (elt sequence i) char))
  138. (+ start chars)))
  139. #+cmu
  140. (defmethod gray-stream:stream-read-sequence ((socket-stream binary-ssl-stream) (sequence sequence) &optional start end)
  141. (let* ((len (length sequence))
  142. (chars (- (min (or end len) len) start)))
  143. (loop for i upfrom start
  144. repeat chars
  145. for char = (gray-stream:stream-read-byte socket-stream)
  146. if (eq char :eof) do (return-from gray-stream:stream-read-sequence i)
  147. do (setf (elt sequence i) char))
  148. (+ start chars)))
  149. #|
  150. (defmethod gray-stream:stream-read-sequence ((socket-stream binary-ssl-stream) sequence start end)
  151. (let* ((len (length sequence))
  152. (chars (- (min (or end len) len) start)))
  153. ;(format t "Read ~A chars from index ~A on.~%" chars start) (force-output t)
  154. (loop for i upfrom start
  155. repeat chars
  156. for char = (progn ;(format t "Read char on index ~A~%" i)
  157. ;(force-output t)
  158. (let ((c (gray-streams:stream-read-byte socket-stream)))
  159. ;(format t "The element read was ~A~%" c)
  160. c))
  161. if (eq char :eof) do (progn ;(format t "premature return on index ~A~%" i)
  162. ;(force-output t)
  163. (return-from gray-streams:stream-read-sequence i))
  164. do (setf (elt sequence i) char))
  165. ;(format t "Normal return on index ~A~%" (+ start chars)) (force-output t)
  166. (+ start chars)))
  167. |#
  168. #| Alternative implementation?
  169. (defmethod stream:stream-read-sequence ((socket-stream character-ssl-stream) sequence start end)
  170. (let* ((len (length sequence))
  171. (chars (- (min (or end len) len) start)))
  172. (format t "Read ~A chars from index ~A on.~%" chars start) (force-output t)
  173. (loop for i upfrom start
  174. repeat chars
  175. for char = (progn (format t "Read char on index ~A~%" i)
  176. (force-output t)
  177. (let ((c (stream:stream-read-char socket-stream)))
  178. (format t "The element read was ~A~%" c) c))
  179. if (eq char :eof) do (progn (format t "premature return on index ~A~%" i)
  180. (force-output t)
  181. (return-from stream:stream-read-sequence i))
  182. do (setf (elt sequence i) char))
  183. (format t "Normal return on index ~A~%" (+ start chars)) (force-output t)
  184. (+ start chars)))
  185. |#
  186. #|
  187. (defmethod common-lisp:close ((socket-stream character-ssl-stream) &key abort)
  188. (with-slots (ssl-socket) socket-stream
  189. (unless abort
  190. (ssl-internal:flush-output-buffer ssl-socket))
  191. (ssl-internal:close-ssl-socket ssl-socket)))
  192. |#
  193. #+lispworks
  194. (declaim (inline %reader-function-for-sequence))
  195. #+lispworks
  196. (defun %reader-function-for-sequence (sequence)
  197. (typecase sequence
  198. (string #'read-char)
  199. ((array unsigned-byte (*)) #'read-byte)
  200. ((array signed-byte (*)) #'read-byte)
  201. (otherwise #'read-byte)))
  202. #+lispworks
  203. (declaim (inline %writer-function-for-sequence))
  204. #+lispworks
  205. (defun %writer-function-for-sequence (sequence)
  206. (typecase sequence
  207. (string #'write-char)
  208. ((array unsigned-byte (*)) #'write-byte)
  209. ((array signed-byte (*)) #'write-byte)
  210. (otherwise #'write-byte)))
  211. ;; Bivalent socket support for READ-SEQUENCE / WRITE-SEQUENCE
  212. #+lispworks
  213. (defmethod gray-stream:stream-read-sequence ((stream ssl-stream-mixin) sequence start end)
  214. (stream::read-elements stream sequence start end (%reader-function-for-sequence sequence)))
  215. #+lispworks
  216. (defmethod gray-stream:stream-write-sequence ((stream ssl-stream-mixin) sequence start end)
  217. (stream::write-elements stream sequence start end (typecase sequence
  218. (string t)
  219. ((array unsigned-byte (*)) nil)
  220. ((array signed-byte (*)) nil)
  221. (otherwise nil))))
  222. #+lispworks
  223. (in-package :acl-socket)
  224. #+lispworks
  225. (defmethod remote-host ((socket ssl::ssl-stream-mixin))
  226. (comm:get-socket-peer-address (ssl-internal::ssl-socket-fd (ssl::ssl-socket socket))))
  227. #+lispworks
  228. (defmethod remote-port ((socket ssl::ssl-stream-mixin))
  229. (multiple-value-bind (host port)
  230. (comm:get-socket-peer-address (ssl-internal::ssl-socket-fd (ssl::ssl-socket socket)))
  231. (declare (ignore host))
  232. port))
  233. #+lispworks
  234. (defmethod local-host ((socket ssl::ssl-stream-mixin))
  235. (multiple-value-bind (host port)
  236. (comm:get-socket-address (ssl-internal::ssl-socket-fd (ssl::ssl-socket socket)))
  237. (declare (ignore port))
  238. host))
  239. #+lispworks
  240. (defmethod local-port ((socket ssl::ssl-stream-mixin))
  241. (multiple-value-bind (host port)
  242. (comm:get-socket-address (ssl-internal::ssl-socket-fd (ssl::ssl-socket socket)))
  243. (declare (ignore host))
  244. port))