changes to make-error-response:
(1)no special treatment of first "optional" argument - rationale: a different number of args is required depending on the specific error code (2)use close-html to write out all _effectively_ optional args (3)generated html-pages are valid XHTML 1.0 Strict (4)require header Allow for 405 errors (5)more exact descriptions of errors in generated html-pages TODO: handle calls of make-error-response with too little args
This commit is contained in:
		
							parent
							
								
									63e4761c58
								
							
						
					
					
						commit
						7c7be57a22
					
				|  | @ -142,149 +142,139 @@ | ||||||
| 	      (else | 	      (else | ||||||
| 	       (loop (+ i 1))))))) | 	       (loop (+ i 1))))))) | ||||||
| 	 | 	 | ||||||
| ;;; (make-error-response status-code req [message . extras]) | ;;; (make-error-response status-code req [extras]) | ||||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||||
| ;;; | ;;; | ||||||
| ;;; As a special case, request REQ is allowed to be #f, meaning we haven't | ;;; As a special case, request REQ is allowed to be #f, meaning we haven't | ||||||
| ;;; even had a chance to parse and construct the request. This is only used | ;;; even had a chance to parse and construct the request. This is only used | ||||||
| ;;; for 400 BAD-REQUEST error report. | ;;; for 400 BAD-REQUEST error report. | ||||||
| 
 | 
 | ||||||
| (define (make-error-response code req . args) |  | ||||||
|   (let* ((message (and (pair? args) (car args))) |  | ||||||
| 	 (extras  (if (pair? args) (cdr args) '())) |  | ||||||
| 
 | 
 | ||||||
| 	 (generic-title (lambda (port) | 
 | ||||||
| 			  (title-html port | (define (make-error-response code req . extras) | ||||||
| 				      (status-code-message code)))) |   (let*   | ||||||
| 	 (send-message (lambda (port) |        ((generic-title (lambda (port) | ||||||
| 			 (if message  | 			(title-html port | ||||||
| 			     (format port "<BR>~%Further Information: ~A<BR>~%" message)))) | 				    (status-code-message code)))) | ||||||
| 	 (close-html (lambda (port) |        (close-html (lambda (port args) | ||||||
| 		       (for-each (lambda (x) (format port "<BR>~s~%" x)) extras) | 		     (if (not (null? args)) | ||||||
| 		       (write-string "</BODY>\n" port))) | 			 (format port "<br/>~%Further Information:~%")) | ||||||
|  | 		     (for-each (lambda (x) (format port "<br/>~%~s~%" x)) args) | ||||||
|  | 		     (write-string "</p>\n</body>\n</html>\n" port))) | ||||||
| 			 | 			 | ||||||
| 	 (create-response |        (create-response | ||||||
| 	  (lambda (headers writer-proc) | 	(lambda (headers writer-proc) | ||||||
| 	    (make-response code | 	  (make-response code | ||||||
| 			   #f | 			 #f | ||||||
| 			   (time) | 			 (time) | ||||||
| 			   "text/html" | 			 "text/html" | ||||||
| 			   headers | 			 headers | ||||||
| 			   (make-writer-body writer-proc))))) | 			 (make-writer-body writer-proc))))) | ||||||
| 
 | 
 | ||||||
|     (cond |     (cond | ||||||
|      ;; This error response requires one arg: |      ;; This error response requires one arg: | ||||||
|      ;; message is the Location field.  |      ;; the value of the Location field header, | ||||||
|      ;; the Location field's field value must be a single absolute URI |      ;; which must be a single absolute URI | ||||||
|      ((or (eq? code (status-code found));302 |      ((or (eq? code (status-code found));302 | ||||||
| 	  (eq? code (status-code see-other));303 | 	  (eq? code (status-code see-other));303 | ||||||
| 	  (eq? code (status-code temp-redirect));307 | 	  (eq? code (status-code temp-redirect));307 | ||||||
| 	  (eq? code (status-code moved-perm)));301 | 	  (eq? code (status-code moved-perm)));301 | ||||||
|       (create-response |       (create-response | ||||||
|        (list (cons 'location message)) |        (list (cons 'location (car extras))) | ||||||
|        (lambda (port options) |        (lambda (port options) | ||||||
| 	 (title-html port "Document moved") | 	 (title-html port "Document moved") | ||||||
| 	 (format port | 	 (format port | ||||||
| 		 "This document has ~A moved to a <A HREF=\"~A\">new location</A>.~%" | 		 "This document has ~A moved to a <a href=\"~A\">new location</a>.~%" | ||||||
| 		 (if (eq? code (status-code moved-perm)) | 		 (if (eq? code (status-code moved-perm)) | ||||||
| 		     "permanently" | 		     "permanently" | ||||||
| 		     "temporarily") | 		     "temporarily") | ||||||
| 		 message) | 		 (car extras)) | ||||||
| 	 (close-html port)))) | 	 (close-html port (cdr extras))))) | ||||||
| 
 | 
 | ||||||
|      ((eq? code (status-code bad-request)) |      ((eq? code (status-code bad-request))  | ||||||
|       (create-response |       (create-response  | ||||||
|        '() |        '() | ||||||
|        (lambda (port options) |        (lambda (port options)  | ||||||
| 	 (generic-title port) | 	 (generic-title port)  | ||||||
| 	 (write-string "<P>Client sent a query that this server could not understand.\n" | 	 (write-string "The request the client sent could not be understood by this server due to malformed syntax.\n Report to client maintainer.\n" port)  | ||||||
| 		       port) | 	 (close-html port extras)))) | ||||||
| 	 (send-message port) |  | ||||||
| 	 (close-html port)))) |  | ||||||
| 
 | 
 | ||||||
|  |      ;; This error response requires two args: | ||||||
|  |      ;; the first one is the disallowed method; | ||||||
|  |      ;; the second one is the value of the Allow field header, | ||||||
|  |      ;; which must be a list of valid methods for the requested resource | ||||||
|      ((eq? code (status-code method-not-allowed)) |      ((eq? code (status-code method-not-allowed)) | ||||||
|       (create-response |       (create-response | ||||||
|        '() |        (list (cons 'allow (cadr extras))) | ||||||
|        (lambda (port options) |        (lambda (port options) | ||||||
| 	 (generic-title port) | 	 (generic-title port) | ||||||
| 	 (write-string "<P>Method not allowed.\n" port) | 	 (format port "The method ~A is not allowed on the requested resource.~%" (car extras)) | ||||||
| 	 (send-message port) | 	 (close-html port (cddr extras))))) | ||||||
| 	 (close-html port)))) |  | ||||||
| 
 | 
 | ||||||
|  |      ;; This error response requires one arg: | ||||||
|  |      ;; the value of the WWW-Authenticate header field, | ||||||
|  |      ;; which must be a challenge (as described in RFC 2617) | ||||||
|      ((eq? code (status-code unauthorized)) |      ((eq? code (status-code unauthorized)) | ||||||
|       (create-response |       (create-response | ||||||
|        (list (cons 'WWW-Authenticate message)) ; Vas is das?  |        (list (cons 'WWW-Authenticate (car extras)))  | ||||||
|        ;; Vas das is? See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.47 |  | ||||||
|        ;; message should be a challenge(?) |  | ||||||
|        (lambda (port options) |        (lambda (port options) | ||||||
| 	 (title-html port "Authorization Required") | 	 (title-html port "Authentication Required") | ||||||
| 	 (write-string "<P>Browser not authentication-capable or\n" port) | 	 (write-string "Client not authentication-capable or authentication failed.\n" port) | ||||||
| 	 (write-string "authentication failed.\n" port) | 	 (close-html port (cdr extras))))) | ||||||
| 	 (send-message port) |  | ||||||
| 	 (close-html port)))) |  | ||||||
| 
 | 
 | ||||||
|      ((eq? code (status-code forbidden)) |      ((eq? code (status-code forbidden)) | ||||||
|       (create-response |       (create-response | ||||||
|        '() |        '() | ||||||
|        (lambda (port options) |        (lambda (port options) | ||||||
| 	 (title-html port "Request not allowed.") | 	 (title-html port "Request not allowed.") | ||||||
| 	 (format port  | 	 (write-string "The request the client sent is not allowed.\n" port) | ||||||
| 		 "Your client does not have permission to perform a ~A~%" | 	 (close-html port extras)))) | ||||||
| 		 (request-method req)) |  | ||||||
| 	 (format port "operation on url ~a.~%" (request-uri req)) |  | ||||||
| 	 (send-message port) |  | ||||||
| 	 (close-html port)))) |  | ||||||
|         |         | ||||||
|      ((eq? code (status-code not-found)) |      ((eq? code (status-code not-found)) | ||||||
|       (create-response |       (create-response | ||||||
|        '() |        '() | ||||||
|        (lambda (port options) |        (lambda (port options) | ||||||
| 	 (title-html port "URL not found") | 	 (title-html port "Resource not found") | ||||||
| 	 (write-string  | 	 (write-string "The requested resource was not found on this server.\n" port) | ||||||
| 	  "<P>The requested URL was not found on this server.\n" | 	 (close-html port extras)))) | ||||||
| 	  port) |  | ||||||
| 	 (send-message port) |  | ||||||
| 	 (close-html port)))) |  | ||||||
| 
 | 
 | ||||||
|      ((eq? code (status-code internal-error)) |      ((eq? code (status-code internal-error)) | ||||||
|       (create-response |       (create-response | ||||||
|        '() |        '() | ||||||
|        (lambda (port options) |        (lambda (port options) | ||||||
| 	 (generic-title port) | 	 (generic-title port) | ||||||
| 	 (format port "The server encountered an internal error or | 	 (format port "This server encountered an internal error or misconfiguration and was unable to complete your request.~%<br/>~%Please inform the server administrator ~A of the circumstances leading to the error, and the time it occured.~%" | ||||||
| misconfiguration and was unable to complete your request. |  | ||||||
| <P> |  | ||||||
| Please inform the server administrator, ~A, of the circumstances leading to |  | ||||||
| the error, and time it occured.~%" |  | ||||||
| 		 (or (httpd-options-server-admin options) | 		 (or (httpd-options-server-admin options) | ||||||
| 		     "[no mail address available]")) | 		     "[no mail address available]")) | ||||||
| 	 (send-message port) | 	 (close-html port extras)))) | ||||||
| 	 (close-html port)))) | 
 | ||||||
|        |      ;; This error response requires one arg: | ||||||
|  |      ;; the unimplemented method | ||||||
|      ((eq? code (status-code not-implemented)) |      ((eq? code (status-code not-implemented)) | ||||||
|       (create-response |       (create-response | ||||||
|        '() |        '() | ||||||
|        (lambda (port options) |        (lambda (port options) | ||||||
| 	 (generic-title port) | 	 (generic-title port) | ||||||
| 	 (format port "This server does not currently implement  | 	 (format port "This server does not recognize or does not implement the requested method \"~A\".~%" | ||||||
| the requested method (~A).~%" | 		 (car extras)) | ||||||
| 		 (request-method req)) | 	 (close-html port (cdr extras))))) | ||||||
| 	 (send-message port) |  | ||||||
| 	 (close-html port)))) |  | ||||||
| 
 | 
 | ||||||
|      ((eq? code (status-code bad-gateway)) |      ((eq? code (status-code bad-gateway)) | ||||||
|       (create-response |       (create-response | ||||||
|        '() |        '() | ||||||
|        (lambda (port options) |        (lambda (port options) | ||||||
| 	 (generic-title port) | 	 (generic-title port) | ||||||
| 	 (format port "An error occured while waiting for the  | 	 (format port "This server recieved an invalid response from the upstream server it accessed in attempting to fulfill the request.~%") | ||||||
| response of a gateway.~%") | 	 (close-html port extras))))))) | ||||||
| 	 (send-message port) |  | ||||||
| 	 (close-html port))))))) |  | ||||||
| 
 | 
 | ||||||
| (define (title-html out message) | (define (title-html out message) | ||||||
|   (format out "<HEAD>~%<TITLE>~%~A~%</TITLE>~%</HEAD>~%~%" message) |   ;;produce valid XHTML 1.0 Strict | ||||||
|   (format out "<BODY>~%<H1>~A</H1>~%" message)) |   (write-string  | ||||||
|  |    "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?> | ||||||
|  |    <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"> | ||||||
|  |       <html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n" out) | ||||||
|  |   (format out "<head>~%<title>~%~A~%</title>~%</head>~%~%" message) | ||||||
|  |   (format out "<body>~%<h1>~A</h1>~%<p>~%" message)) | ||||||
| 
 | 
 | ||||||
| ;; Creates a redirect response. The server will serve the new file | ;; Creates a redirect response. The server will serve the new file | ||||||
| ;; indicated by NEW-LOCATION. NEW-LOCATION must be uri-encoded and | ;; indicated by NEW-LOCATION. NEW-LOCATION must be uri-encoded and | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 vibr
						vibr