Move MAKE-HTTP-ERROR-RESPONSE from HTTPD-CORE to HTTPD-RESPONSES.
Elide REALLY-MAKE-HTTP-ERROR-RESPONSE in the process.
This commit is contained in:
parent
f5b7f76bd6
commit
c97bbfc1db
|
@ -305,147 +305,6 @@
|
||||||
(write-crlf port))
|
(write-crlf port))
|
||||||
headers))
|
headers))
|
||||||
|
|
||||||
(define (time->http-date-string time)
|
|
||||||
(format-date "~A, ~d-~b-~y ~H:~M:~S GMT" (date time 0)))
|
|
||||||
|
|
||||||
;;; (make-http-error-response status-code req [message . extras])
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;; Take an http-error condition, and format it into a response to the client.
|
|
||||||
;;;
|
|
||||||
;;; 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
|
|
||||||
;;; for 400 BAD-REQUEST error report.
|
|
||||||
|
|
||||||
;;; MAKE-HTTP-ERROR-RESPONSE is called from error handlers, so to avoid
|
|
||||||
;;; infinite looping, if an error occurs while it is running, we just
|
|
||||||
;;; silently return. (We no longer need to do this; I have changed
|
|
||||||
;;; WITH-FATAL-ERROR-HANDLER* so that this is not necessary, but I'll
|
|
||||||
;;; leave it in to play it safe.)
|
|
||||||
|
|
||||||
(define (make-http-error-response status-code req . args)
|
|
||||||
(ignore-errors
|
|
||||||
(lambda () ; Ignore errors -- see note above.
|
|
||||||
(apply really-make-http-error-response status-code req args))))
|
|
||||||
|
|
||||||
(define (really-make-http-error-response status-code req . args)
|
|
||||||
(http-log req status-code)
|
|
||||||
|
|
||||||
(let* ((message (and (pair? args) (car args)))
|
|
||||||
(extras (if (pair? args) (cdr args) '()))
|
|
||||||
|
|
||||||
(generic-title (lambda (port)
|
|
||||||
(title-html port
|
|
||||||
(status-code->text status-code))))
|
|
||||||
(close-html (lambda (port)
|
|
||||||
(for-each (lambda (x) (format port "<BR>~s~%" x)) extras)
|
|
||||||
(write-string "</BODY>\n" port)))
|
|
||||||
|
|
||||||
(create-response
|
|
||||||
(lambda (headers writer-proc)
|
|
||||||
(make-response status-code
|
|
||||||
(status-code->text status-code)
|
|
||||||
(time)
|
|
||||||
"text/html"
|
|
||||||
headers
|
|
||||||
(make-writer-body writer-proc)))))
|
|
||||||
|
|
||||||
(cond
|
|
||||||
;; This error response requires two args: message is the new URI: field,
|
|
||||||
;; and the first EXTRA is the older Location: field.
|
|
||||||
((or (= status-code http-status/moved-temp)
|
|
||||||
(= status-code http-status/moved-perm))
|
|
||||||
(create-response
|
|
||||||
(list (cons 'uri message)
|
|
||||||
(cons 'location (car extras)))
|
|
||||||
(lambda (port options)
|
|
||||||
(title-html port "Document moved")
|
|
||||||
(format port
|
|
||||||
"This document has ~A moved to a <A HREF=\"~A\">new location</A>.~%"
|
|
||||||
(if (= status-code http-status/moved-temp) "temporarily" "permanently")
|
|
||||||
message)
|
|
||||||
(close-html port))))
|
|
||||||
|
|
||||||
((= status-code http-status/bad-request)
|
|
||||||
(create-response
|
|
||||||
'()
|
|
||||||
(lambda (port options)
|
|
||||||
(generic-title port)
|
|
||||||
(write-string "<P>Client sent a query that this server could not understand.\n"
|
|
||||||
port)
|
|
||||||
(if message (format port "<BR>~%Reason: ~A~%" message))
|
|
||||||
(close-html port))))
|
|
||||||
|
|
||||||
((= status-code http-status/unauthorized)
|
|
||||||
(create-response
|
|
||||||
(list (cons 'WWW-Authenticate message)) ; Vas is das?
|
|
||||||
(lambda (port options)
|
|
||||||
(title-html port "Authorization Required")
|
|
||||||
(write-string "<P>Browser not authentication-capable or\n" port)
|
|
||||||
(write-string "authentication failed.\n" port)
|
|
||||||
(if message (format port "~a~%" message))
|
|
||||||
(close-html port))))
|
|
||||||
|
|
||||||
((= status-code http-status/forbidden)
|
|
||||||
(create-response
|
|
||||||
'()
|
|
||||||
(lambda (port options)
|
|
||||||
(title-html port "Request not allowed.")
|
|
||||||
(format port
|
|
||||||
"Your client does not have permission to perform a ~A~%"
|
|
||||||
(request:method req))
|
|
||||||
(format port "operation on url ~a.~%" (request:uri req))
|
|
||||||
(if message (format port "<P>~%~a~%" message))
|
|
||||||
(close-html port))))
|
|
||||||
|
|
||||||
((= status-code http-status/not-found)
|
|
||||||
(create-response
|
|
||||||
'()
|
|
||||||
(lambda (port options)
|
|
||||||
(title-html port "URL not found")
|
|
||||||
(write-string
|
|
||||||
"<P>The requested URL was not found on this server.\n"
|
|
||||||
port)
|
|
||||||
(if message (format port "<P>~%~a~%" message))
|
|
||||||
(close-html port))))
|
|
||||||
|
|
||||||
((= status-code http-status/internal-error)
|
|
||||||
(http-syslog (syslog-level error) "internal-error: ~A" message)
|
|
||||||
(create-response
|
|
||||||
'()
|
|
||||||
(lambda (port options)
|
|
||||||
(generic-title port)
|
|
||||||
(format port "The server encountered an internal error or
|
|
||||||
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.~%"
|
|
||||||
(httpd-options-server-admin options))
|
|
||||||
(if message (format port "<P>~%~a~%" message))
|
|
||||||
(close-html port))))
|
|
||||||
|
|
||||||
((= status-code http-status/not-implemented)
|
|
||||||
(create-response
|
|
||||||
'()
|
|
||||||
(lambda (port options)
|
|
||||||
(generic-title port)
|
|
||||||
(format port "This server does not currently implement
|
|
||||||
the requested method (~A).~%"
|
|
||||||
(request:method req))
|
|
||||||
(if message (format port "<P>~a~%" message))
|
|
||||||
(close-html port))))
|
|
||||||
|
|
||||||
(else
|
|
||||||
(http-syslog (syslog-level info) "Skipping unhandled status code ~A.~%" status-code)
|
|
||||||
(create-response
|
|
||||||
'()
|
|
||||||
(lambda (port options)
|
|
||||||
(generic-title port)
|
|
||||||
(close-html port)))))))
|
|
||||||
|
|
||||||
(define (title-html out message)
|
|
||||||
(format out "<HEAD>~%<TITLE>~%~A~%</TITLE>~%</HEAD>~%~%" message)
|
|
||||||
(format out "<BODY>~%<H1>~A</H1>~%" message))
|
|
||||||
|
|
||||||
;;; Return my Internet host name (my fully-qualified domain name).
|
;;; Return my Internet host name (my fully-qualified domain name).
|
||||||
;;; This works only if an actual resolver is behind host-info.
|
;;; This works only if an actual resolver is behind host-info.
|
||||||
;;;
|
;;;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
;;; This file is part of the Scheme Untergrund Networking package.
|
;;; This file is part of the Scheme Untergrund Networking package.
|
||||||
|
|
||||||
|
;;; Copyright (c) 1994 by Brian D. Carlstrom and Olin Shivers.
|
||||||
;;; Copyright (c) 2002 by Mike Sperber.
|
;;; Copyright (c) 2002 by Mike Sperber.
|
||||||
;;; For copyright information, see the file COPYING which comes with
|
;;; For copyright information, see the file COPYING which comes with
|
||||||
;;; the distribution.
|
;;; the distribution.
|
||||||
|
@ -63,3 +64,133 @@
|
||||||
|
|
||||||
(define (status-code->text code)
|
(define (status-code->text code)
|
||||||
(cdr (assv code http-status-text-table)))
|
(cdr (assv code http-status-text-table)))
|
||||||
|
|
||||||
|
;;; (make-http-error-response status-code req [message . extras])
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;; Take an http-error condition, and format it into a response to the client.
|
||||||
|
;;;
|
||||||
|
;;; 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
|
||||||
|
;;; for 400 BAD-REQUEST error report.
|
||||||
|
|
||||||
|
(define (make-http-error-response status-code req . args)
|
||||||
|
(http-log req status-code)
|
||||||
|
|
||||||
|
(let* ((message (and (pair? args) (car args)))
|
||||||
|
(extras (if (pair? args) (cdr args) '()))
|
||||||
|
|
||||||
|
(generic-title (lambda (port)
|
||||||
|
(title-html port
|
||||||
|
(status-code->text status-code))))
|
||||||
|
(close-html (lambda (port)
|
||||||
|
(for-each (lambda (x) (format port "<BR>~s~%" x)) extras)
|
||||||
|
(write-string "</BODY>\n" port)))
|
||||||
|
|
||||||
|
(create-response
|
||||||
|
(lambda (headers writer-proc)
|
||||||
|
(make-response status-code
|
||||||
|
(status-code->text status-code)
|
||||||
|
(time)
|
||||||
|
"text/html"
|
||||||
|
headers
|
||||||
|
(make-writer-body writer-proc)))))
|
||||||
|
|
||||||
|
(cond
|
||||||
|
;; This error response requires two args: message is the new URI: field,
|
||||||
|
;; and the first EXTRA is the older Location: field.
|
||||||
|
((or (= status-code http-status/moved-temp)
|
||||||
|
(= status-code http-status/moved-perm))
|
||||||
|
(create-response
|
||||||
|
(list (cons 'uri message)
|
||||||
|
(cons 'location (car extras)))
|
||||||
|
(lambda (port options)
|
||||||
|
(title-html port "Document moved")
|
||||||
|
(format port
|
||||||
|
"This document has ~A moved to a <A HREF=\"~A\">new location</A>.~%"
|
||||||
|
(if (= status-code http-status/moved-temp) "temporarily" "permanently")
|
||||||
|
message)
|
||||||
|
(close-html port))))
|
||||||
|
|
||||||
|
((= status-code http-status/bad-request)
|
||||||
|
(create-response
|
||||||
|
'()
|
||||||
|
(lambda (port options)
|
||||||
|
(generic-title port)
|
||||||
|
(write-string "<P>Client sent a query that this server could not understand.\n"
|
||||||
|
port)
|
||||||
|
(if message (format port "<BR>~%Reason: ~A~%" message))
|
||||||
|
(close-html port))))
|
||||||
|
|
||||||
|
((= status-code http-status/unauthorized)
|
||||||
|
(create-response
|
||||||
|
(list (cons 'WWW-Authenticate message)) ; Vas is das?
|
||||||
|
(lambda (port options)
|
||||||
|
(title-html port "Authorization Required")
|
||||||
|
(write-string "<P>Browser not authentication-capable or\n" port)
|
||||||
|
(write-string "authentication failed.\n" port)
|
||||||
|
(if message (format port "~a~%" message))
|
||||||
|
(close-html port))))
|
||||||
|
|
||||||
|
((= status-code http-status/forbidden)
|
||||||
|
(create-response
|
||||||
|
'()
|
||||||
|
(lambda (port options)
|
||||||
|
(title-html port "Request not allowed.")
|
||||||
|
(format port
|
||||||
|
"Your client does not have permission to perform a ~A~%"
|
||||||
|
(request:method req))
|
||||||
|
(format port "operation on url ~a.~%" (request:uri req))
|
||||||
|
(if message (format port "<P>~%~a~%" message))
|
||||||
|
(close-html port))))
|
||||||
|
|
||||||
|
((= status-code http-status/not-found)
|
||||||
|
(create-response
|
||||||
|
'()
|
||||||
|
(lambda (port options)
|
||||||
|
(title-html port "URL not found")
|
||||||
|
(write-string
|
||||||
|
"<P>The requested URL was not found on this server.\n"
|
||||||
|
port)
|
||||||
|
(if message (format port "<P>~%~a~%" message))
|
||||||
|
(close-html port))))
|
||||||
|
|
||||||
|
((= status-code http-status/internal-error)
|
||||||
|
(http-syslog (syslog-level error) "internal-error: ~A" message)
|
||||||
|
(create-response
|
||||||
|
'()
|
||||||
|
(lambda (port options)
|
||||||
|
(generic-title port)
|
||||||
|
(format port "The server encountered an internal error or
|
||||||
|
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.~%"
|
||||||
|
(httpd-options-server-admin options))
|
||||||
|
(if message (format port "<P>~%~a~%" message))
|
||||||
|
(close-html port))))
|
||||||
|
|
||||||
|
((= status-code http-status/not-implemented)
|
||||||
|
(create-response
|
||||||
|
'()
|
||||||
|
(lambda (port options)
|
||||||
|
(generic-title port)
|
||||||
|
(format port "This server does not currently implement
|
||||||
|
the requested method (~A).~%"
|
||||||
|
(request:method req))
|
||||||
|
(if message (format port "<P>~a~%" message))
|
||||||
|
(close-html port))))
|
||||||
|
|
||||||
|
(else
|
||||||
|
(http-syslog (syslog-level info) "Skipping unhandled status code ~A.~%" status-code)
|
||||||
|
(create-response
|
||||||
|
'()
|
||||||
|
(lambda (port options)
|
||||||
|
(generic-title port)
|
||||||
|
(close-html port)))))))
|
||||||
|
|
||||||
|
(define (title-html out message)
|
||||||
|
(format out "<HEAD>~%<TITLE>~%~A~%</TITLE>~%</HEAD>~%~%" message)
|
||||||
|
(format out "<BODY>~%<H1>~A</H1>~%" message))
|
||||||
|
|
||||||
|
(define (time->http-date-string time)
|
||||||
|
(format-date "~A, ~d-~b-~y ~H:~M:~S GMT" (date time 0)))
|
||||||
|
|
|
@ -254,9 +254,7 @@
|
||||||
;; Web server
|
;; Web server
|
||||||
|
|
||||||
(define-interface httpd-core-interface
|
(define-interface httpd-core-interface
|
||||||
(export httpd
|
(export httpd))
|
||||||
make-http-error-response
|
|
||||||
time->http-date-string))
|
|
||||||
|
|
||||||
(define-interface httpd-make-options-interface
|
(define-interface httpd-make-options-interface
|
||||||
(export make-httpd-options
|
(export make-httpd-options
|
||||||
|
@ -362,7 +360,10 @@
|
||||||
http-status/not-implemented
|
http-status/not-implemented
|
||||||
http-status/bad-gateway
|
http-status/bad-gateway
|
||||||
http-status/service-unavailable
|
http-status/service-unavailable
|
||||||
http-status/gateway-timeout))
|
http-status/gateway-timeout
|
||||||
|
|
||||||
|
make-http-error-response
|
||||||
|
time->http-date-string))
|
||||||
|
|
||||||
(define-interface httpd-basic-handlers-interface
|
(define-interface httpd-basic-handlers-interface
|
||||||
(export make-request-handler
|
(export make-request-handler
|
||||||
|
@ -751,8 +752,14 @@
|
||||||
|
|
||||||
(define-structure httpd-responses httpd-responses-interface
|
(define-structure httpd-responses httpd-responses-interface
|
||||||
(open scheme
|
(open scheme
|
||||||
|
(subset scsh (format-date write-string time date))
|
||||||
|
syslog
|
||||||
srfi-9
|
srfi-9
|
||||||
defenum-package)
|
defenum-package
|
||||||
|
formats
|
||||||
|
httpd-request
|
||||||
|
httpd-logging
|
||||||
|
httpd-read-options)
|
||||||
(files (httpd response)))
|
(files (httpd response)))
|
||||||
|
|
||||||
(define-structure httpd-basic-handlers httpd-basic-handlers-interface
|
(define-structure httpd-basic-handlers httpd-basic-handlers-interface
|
||||||
|
|
Loading…
Reference in New Issue