| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -336,7 +336,7 @@
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					             frame-fin frame-optype))
 | 
					 | 
					 | 
					 | 
					             frame-fin frame-optype))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					           (else
 | 
					 | 
					 | 
					 | 
					           (else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            (signal (make-websocket-exception
 | 
					 | 
					 | 
					 | 
					            (signal (make-websocket-exception
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                     (make-property-condition 'unhandled-opcode
 | 
					 | 
					 | 
					 | 
					                     (make-property-condition 'unhandled-optype
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                              'optype frame-optype)))))))))))
 | 
					 | 
					 | 
					 | 
					                                              'optype frame-optype)))))))))))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					(define (valid-utf8-2? s)
 | 
					 | 
					 | 
					 | 
					(define (valid-utf8-2? s)
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -501,6 +501,7 @@ static const uint8_t utf8d[] = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                   (process-fragments fragments optype)))))
 | 
					 | 
					 | 
					 | 
					                   (process-fragments fragments optype)))))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					; TODO does #!optional and #!key work together?
 | 
					 | 
					 | 
					 | 
					; TODO does #!optional and #!key work together?
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					; TODO document websocket state close states
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					(define (close-websocket #!optional (ws (current-websocket))
 | 
					 | 
					 | 
					 | 
					(define (close-websocket #!optional (ws (current-websocket))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                         #!key (close-reason 'normal) (data (make-u8vector 0)))
 | 
					 | 
					 | 
					 | 
					                         #!key (close-reason 'normal) (data (make-u8vector 0)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  (define invalid-close-reason #f)
 | 
					 | 
					 | 
					 | 
					  (define invalid-close-reason #f)
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -632,58 +633,27 @@ static const uint8_t utf8d[] = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    ws))
 | 
					 | 
					 | 
					 | 
					    ws))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					(define (with-websocket proc #!optional (concurrent #f))
 | 
					 | 
					 | 
					 | 
					(define (with-websocket proc #!optional (concurrent #f))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  (parameterize
 | 
					 | 
					 | 
					 | 
					  (define (handle-error close-reason exn)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					   ((current-websocket (websocket-accept concurrent)))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					   (condition-case
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    (begin (proc)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					           (close-websocket)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					           (close-input-port (request-port (current-request)))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					           (close-output-port (response-port (current-response))))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    (exn (websocket protocol-error)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    (set-websocket-state! (current-websocket) 'closing)
 | 
					 | 
					 | 
					 | 
					    (set-websocket-state! (current-websocket) 'closing)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (close-websocket (current-websocket) close-reason: 'protocol-error)
 | 
					 | 
					 | 
					 | 
					    (close-websocket (current-websocket) close-reason: close-reason)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    (unless (port-closed? (request-port (current-request)))
 | 
					 | 
					 | 
					 | 
					    (unless (port-closed? (request-port (current-request)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            (close-input-port (request-port (current-request))))
 | 
					 | 
					 | 
					 | 
					            (close-input-port (request-port (current-request))))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    (unless (port-closed? (response-port (current-response)))
 | 
					 | 
					 | 
					 | 
					    (unless (port-closed? (response-port (current-response)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            (close-output-port (response-port (current-response))))
 | 
					 | 
					 | 
					 | 
					            (close-output-port (response-port (current-response))))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    (when (propagate-common-errors)
 | 
					 | 
					 | 
					 | 
					    (when (propagate-common-errors)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          (signal exn)))
 | 
					 | 
					 | 
					 | 
					          (signal exn)))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    (exn (websocket invalid-data)
 | 
					 | 
					 | 
					 | 
					  (parameterize
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (set-websocket-state! (current-websocket) 'closing)
 | 
					 | 
					 | 
					 | 
					   ((current-websocket (websocket-accept concurrent)))
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (close-websocket (current-websocket) close-reason: 'invalid-data)
 | 
					 | 
					 | 
					 | 
					   (condition-case
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (unless (port-closed? (request-port (current-request)))
 | 
					 | 
					 | 
					 | 
					    (begin (proc)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                 (close-input-port (request-port (current-request))))
 | 
					 | 
					 | 
					 | 
					           (close-websocket)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (unless (port-closed? (response-port (current-response)))
 | 
					 | 
					 | 
					 | 
					           (close-input-port (request-port (current-request)))
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                 (close-output-port (response-port (current-response))))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (when (propagate-common-errors)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					               (signal exn)))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    (exn (websocket connection-timeout)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (set-websocket-state! (current-websocket) 'closing)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (close-websocket (current-websocket) close-reason: 'going-away)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (unless (port-closed? (request-port (current-request)))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                 (close-input-port (request-port (current-request))))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (unless (port-closed? (response-port (current-response)))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                 (close-output-port (response-port (current-response))))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (when (propagate-common-errors)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					               (signal exn)))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    (exn (websocket message-too-large)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (set-websocket-state! (current-websocket) 'closing)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (close-websocket (current-websocket) close-reason: 'message-too-large)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (unless (port-closed? (request-port (current-request)))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                 (close-input-port (request-port (current-request))))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (unless (port-closed? (response-port (current-response)))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                 (close-output-port (response-port (current-response))))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (when (propagate-common-errors)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					               (signal exn)))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    (exn ()
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (close-websocket (current-websocket) close-reason: 1011)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (unless (port-closed? (request-port (current-request)))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                 (close-input-port (request-port (current-request))))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (unless (port-closed? (response-port (current-response)))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					           (close-output-port (response-port (current-response))))
 | 
					 | 
					 | 
					 | 
					           (close-output-port (response-port (current-response))))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         (abort exn)
 | 
					 | 
					 | 
					 | 
					    (exn (websocket protocol-error) (handle-error 'protocol-error exn))
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         ;(signal (make-websocket-exception (make-property-condition 'unexpected-error)))
 | 
					 | 
					 | 
					 | 
					    (exn (websocket invalid-data) (handle-error 'invalid-data exn))
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         ))))
 | 
					 | 
					 | 
					 | 
					    (exn (websocket connection-timeout) (handle-error 'going-away exn))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    (exn (websocket message-too-large) (handle-error 'message-too-large exn))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    (exn () (handle-error 'unexpected-error exn)))))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					(define (with-concurrent-websocket proc)
 | 
					 | 
					 | 
					 | 
					(define (with-concurrent-websocket proc)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  (let ((parent-thread (current-thread)))
 | 
					 | 
					 | 
					 | 
					  (let ((parent-thread (current-thread)))
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
 
 |