Improved error response generation. We now keep track of the last
request read on a connection, which allows us to generate the correct type of response in case of an error which is handled through `handle-server-error'. Also added code to correctly escape text that is inserted into error messages. This is also a first step towards preventing cross-scripting attacks through CLASH, although most of the code still has to be audited for unfiltered passing through of user-supplied text.
This commit is contained in:
@ -92,7 +92,8 @@ passed to `make-instance'."))
|
||||
(:documentation
|
||||
"Forward the calculated response object to the connection."))
|
||||
|
||||
|
||||
(defgeneric get-error-response-class-using-server (server connection condition)
|
||||
(:documentation "Calculate the response class for the error response."))
|
||||
|
||||
(defgeneric handle-server-error (server connection condition)
|
||||
(:documentation
|
||||
@ -160,6 +161,13 @@ Server Response-Header."))
|
||||
:status-code status-code
|
||||
args))
|
||||
|
||||
(defmethod get-error-response-class-using-server (server connection condition)
|
||||
(declare (ignore condition))
|
||||
(let ((last-request (connection-last-request connection)))
|
||||
(if last-request
|
||||
(get-response-class-using-server server last-request)
|
||||
(find-class 'response/0.9))))
|
||||
|
||||
;;; Basic 0.9 server
|
||||
|
||||
(defclass http-server/0.9 (simple-http-server)
|
||||
@ -180,16 +188,18 @@ Server Response-Header."))
|
||||
|
||||
(defmethod handle-server-error ((server http-server/0.9) connection condition)
|
||||
(ignore-errors
|
||||
(let ((response (make-instance
|
||||
'response/0.9
|
||||
:server server
|
||||
:status-code
|
||||
+HTTP-Code-Internal-Server-Error+
|
||||
:entity
|
||||
(make-instance 'string-entity
|
||||
:body
|
||||
(format nil
|
||||
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">~%<HTML><HEAD>~%<TITLE>500 Internal Server Error</TITLE>~%</HEAD>~%<BODY>~%<H1>Internal Server Error</H1>~%<P>An internal server error occured:</P>~%<PRE>~%~A~%</PRE>~%</BODY></HTML>" condition)))))
|
||||
(let ((response
|
||||
(make-instance
|
||||
(get-error-response-using-server server connection condition)
|
||||
:server server
|
||||
:status-code +HTTP-Code-Internal-Server-Error+
|
||||
:entity
|
||||
(make-instance 'string-entity
|
||||
:body
|
||||
(format nil
|
||||
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">~%<HTML><HEAD>~%<TITLE>500 Internal Server Error</TITLE>~%</HEAD>~%<BODY>~%<H1>Internal Server Error</H1>~%<P>An internal server error occured:</P>~%<PRE>~%~A~%</PRE>~%</BODY></HTML>"
|
||||
(escape-text-for-html
|
||||
(princ-to-string condition)))))))
|
||||
(write-response server connection response)))
|
||||
(throw 'exit-connection nil))
|
||||
|
||||
@ -228,7 +238,8 @@ Server Response-Header."))
|
||||
(typecase condition
|
||||
(clash-error
|
||||
(apply #'make-instance
|
||||
'response/1.0
|
||||
(get-error-response-class-using-server
|
||||
server connection condition)
|
||||
:server server
|
||||
:status-code (clash-error-code condition)
|
||||
:entity
|
||||
@ -237,20 +248,24 @@ Server Response-Header."))
|
||||
:body
|
||||
(format nil "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">~%<HTML><HEAD>~%<TITLE>~3D ~A</TITLE>~%</HEAD>~%<BODY>~%<H1>~2:*~3D ~A</H1>~%<PRE>~%~A~%</PRE>~%</BODY></HTML>"
|
||||
(clash-error-code condition)
|
||||
(HTTP-Code-Description (clash-error-code condition))
|
||||
condition)
|
||||
(HTTP-Code-Description
|
||||
(clash-error-code condition))
|
||||
(escape-text-for-html
|
||||
(princ-to-string condition)))
|
||||
(clash-error-entity-initargs condition))
|
||||
(clash-error-response-initargs condition)))
|
||||
(error
|
||||
(make-instance
|
||||
'response/1.0
|
||||
(get-error-response-class-using-server
|
||||
server connection condition)
|
||||
:server server
|
||||
:status-code
|
||||
+HTTP-Code-Internal-Server-Error+
|
||||
:status-code +HTTP-Code-Internal-Server-Error+
|
||||
:entity
|
||||
(make-instance 'string-entity
|
||||
:body
|
||||
(format nil
|
||||
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">~%<HTML><HEAD>~%<TITLE>500 Internal Server Error</TITLE>~%</HEAD>~%<BODY>~%<H1>Internal Server Error</H1>~%<P>An internal server error occured:</P>~%<PRE>~%~A~%</PRE>~%</BODY></HTML>" condition)))))))
|
||||
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">~%<HTML><HEAD>~%<TITLE>500 Internal Server Error</TITLE>~%</HEAD>~%<BODY>~%<H1>Internal Server Error</H1>~%<P>An internal server error occured:</P>~%<PRE>~%~A~%</PRE>~%</BODY></HTML>"
|
||||
(escape-text-for-html
|
||||
(princ-to-string condition)))))))))
|
||||
(write-response server connection response)))
|
||||
(throw 'exit-connection nil))
|
||||
|
||||
Reference in New Issue
Block a user