|
20 | 20 | :socket-remote-addr
|
21 | 21 | :socket-remote-port
|
22 | 22 | :with-sockaddr)
|
| 23 | + #-woo-no-ssl |
| 24 | + (:import-from :woo.ssl) |
23 | 25 | (:import-from :woo.util
|
24 | 26 | :integer-string-p)
|
25 | 27 | (:import-from :quri
|
|
60 | 62 | (defvar *default-worker-num* nil)
|
61 | 63 |
|
62 | 64 | (defun run (app &key (debug t)
|
63 |
| - (port 5000) (address "127.0.0.1") |
64 |
| - listen ;; UNIX domain socket |
65 |
| - (backlog *default-backlog-size*) fd |
66 |
| - (worker-num *default-worker-num*)) |
| 65 | + (port 5000) (address "127.0.0.1") |
| 66 | + listen ;; UNIX domain socket |
| 67 | + (backlog *default-backlog-size*) fd |
| 68 | + (worker-num *default-worker-num*) |
| 69 | + ssl-key-file |
| 70 | + ssl-cert-file |
| 71 | + ssl-key-password) |
| 72 | + (declare (ignorable ssl-key-password)) |
67 | 73 | (assert (and (integerp backlog)
|
68 | 74 | (plusp backlog)
|
69 | 75 | (<= backlog 128)))
|
|
76 | 82 |
|
77 | 83 | (let ((*app* app)
|
78 | 84 | (*debug* debug)
|
79 |
| - (*listener* nil)) |
| 85 | + (*listener* nil) |
| 86 | + (ssl (or ssl-key-file ssl-cert-file))) |
80 | 87 | (labels ((start-socket (socket)
|
| 88 | + #-woo-no-ssl |
| 89 | + (when ssl |
| 90 | + (woo.ssl:init-ssl-handle socket |
| 91 | + ssl-cert-file |
| 92 | + ssl-key-file |
| 93 | + ssl-key-password)) |
81 | 94 | (setup-parser socket)
|
82 | 95 | (woo.ev.tcp:start-listening-socket socket))
|
83 | 96 | (start-multithread-server ()
|
|
120 | 133 | :fd fd
|
121 | 134 | :sockopt wsock:+SO-REUSEADDR+)))
|
122 | 135 | (wev:close-tcp-server *listener*))))))
|
| 136 | + (when ssl |
| 137 | + #+woo-no-ssl |
| 138 | + (warn "SSL certificate is specified but Woo's SSL feature is off. Ignored.") |
| 139 | + #-woo-no-ssl |
| 140 | + (progn |
| 141 | + (cl+ssl::ensure-initialized) |
| 142 | + (when ssl-key-file |
| 143 | + (setf ssl-key-file |
| 144 | + (uiop:native-namestring |
| 145 | + (or (probe-file ssl-key-file) |
| 146 | + (error "SSL private key file '~A' does not exist." ssl-key-file))))) |
| 147 | + (when ssl-cert-file |
| 148 | + (setf ssl-cert-file |
| 149 | + (uiop:native-namestring |
| 150 | + (or (probe-file ssl-cert-file) |
| 151 | + (error "SSL certificate '~A' does not exist." ssl-cert-file))))))) |
123 | 152 | (if worker-num
|
124 | 153 | (start-multithread-server)
|
125 | 154 | (start-singlethread-server)))))
|
|
346 | 375 | (setf (getf headers :content-length) 0))
|
347 | 376 | (write-response-headers socket status headers (not close))))
|
348 | 377 | (pathname
|
349 |
| - (let* ((fd (wsys:open body)) |
350 |
| - (size #+lispworks (sys:file-size body) |
351 |
| - #+(or sbcl ccl) (fd-file-size fd) |
352 |
| - #-(or sbcl ccl lispworks) (file-size body))) |
353 |
| - (unless (getf headers :content-length) |
354 |
| - (setf (getf headers :content-length) size)) |
355 |
| - (unless (getf headers :content-type) |
356 |
| - (setf (getf headers :content-type) (mimes:mime body))) |
357 |
| - (wev:with-async-writing (socket :write-cb (and close |
358 |
| - (lambda (socket) |
359 |
| - (wev:close-socket socket)))) |
360 |
| - (write-response-headers socket status headers (not close)) |
361 |
| - (woo.ev.socket:send-static-file socket fd size)))) |
| 378 | + (cond |
| 379 | + ((woo.ev.socket:socket-ssl-handle socket) |
| 380 | + (with-open-file (in body :element-type '(unsigned-byte 8)) |
| 381 | + (let ((size (file-length in))) |
| 382 | + (unless (getf headers :content-length) |
| 383 | + (setf (getf headers :content-length) size)) |
| 384 | + (unless (getf headers :content-type) |
| 385 | + (setf (getf headers :content-type) (mimes:mime body))) |
| 386 | + (wev:with-async-writing (socket :write-cb (and close |
| 387 | + (lambda (socket) |
| 388 | + (wev:close-socket socket)))) |
| 389 | + (write-response-headers socket status headers (not close)) |
| 390 | + ;; Future task: Use OpenSSL's SSL_sendfile which uses Kernel TLS. |
| 391 | + ;; TODO: Stop allocating an input buffer every time |
| 392 | + (loop with buffer = (make-array 4096 :element-type '(unsigned-byte 8)) |
| 393 | + for n = (read-sequence buffer in) |
| 394 | + do (wev:write-socket-data socket buffer :end n) |
| 395 | + while (= n 4096)))))) |
| 396 | + (t |
| 397 | + (let* ((fd (wsys:open body)) |
| 398 | + (size #+lispworks (sys:file-size body) |
| 399 | + #+(or sbcl ccl) (fd-file-size fd) |
| 400 | + #-(or sbcl ccl lispworks) (file-size body))) |
| 401 | + (unless (getf headers :content-length) |
| 402 | + (setf (getf headers :content-length) size)) |
| 403 | + (unless (getf headers :content-type) |
| 404 | + (setf (getf headers :content-type) (mimes:mime body))) |
| 405 | + (wev:with-async-writing (socket :write-cb (and close |
| 406 | + (lambda (socket) |
| 407 | + (wev:close-socket socket)))) |
| 408 | + (write-response-headers socket status headers (not close)) |
| 409 | + (woo.ev.socket:send-static-file socket fd size)))))) |
362 | 410 | (list
|
363 | 411 | (wev:with-async-writing (socket :write-cb (and close
|
364 | 412 | (lambda (socket)
|
|
0 commit comments