Re: How to simple exit in CGI?

Pascal Bourguignon <[email protected]> Thu, 30 Mar 2017 22:10:48 +0200
Newsgroups gmane.lisp.clisp.general
Message-ID <[email protected]>
> On 30 Mar 2017, at 19:04, Jean Louis <[email protected]> wrote:
> 
> Thank you for helping.
> 
> I found solution, as jasom on IRC, told me to check for
> *standard-input* by using listen.
> 
> So, now I can run the CGI without POST and without GET parameters, and
> without getting blocked, as Lisp is not waiting any more.
> 
> In the mean time I am learning ASDF.
> 
> Jean
> 
> (load "/home/data1/protected/lisp/quicklisp.lisp")
> (ql:quickload "alexandria")
> 
> (defun main (&optional (arguments *args*))
>  (if (listen *standard-input*)
>    (progn 
>      (headers)
>      (print "Standard input here"))
>    (progn
>      (headers)
>      (print "No standard input")))
> 
>  ;; (declare (ignore arguments))
>  ;; (unless (listen *standard-input*)
>  ;;   ;;              (getenv "QUERY_STRING"))
>  ;;   (let ((url "http://localhost")
>  ;;         (query (or (getenv "QUERY_STRING")
>  ;;                    (alexandria:read-stream-content-into-string *standard-input*))))))
>  ;; (format t "Status: 302 Found~%Location: ~a~%~%" url)
> 
>  (finish-output)
>  (exit 0))



Neither using LISTEN or directly READ-SEQUENCE are good solutions.
Either one will work only by chance.

LISTEN in particular will fail, if for whatever reason, the web server didn’t start writing the PUT data or POST parameters to the CGI pipe, when the CGI calls LISTEN.  I guess the same is true with READ-SEQUENCE: it won’t read an end-of-file if the web server doesn’t close that pipe.

And let me you ask the question: what reason does the web server have to close that pipe if it didn’t have to write anything to it, because it was a GET request?

The correct solution, as always, is to read the documentation, specifically, the RFC 3875 <https://tools.ietf.org/html/rfc3875>
Or you may browse the Wikipedia summary, and find out that the CGI specifies that the environment variable REQUEST_METHOD will indicate whether it’s a GET, a PUT, a POST or whatever else.  You must test this before trying to read stdin!


(defun main (&optional (arguments *args*))
  (let ((method (getenv "REQUEST_METHOD")))
    (cond ((or (string= method "PUT")
               (string= method "POST"))
           (headers)
           (print "Standard input here"))
          ((string= method "GET")
           (headers)
           (print "No standard input"))
          (t
           (headers)
           (print "Method not handled")))))



-- 
__Pascal J. Bourguignon__



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
clisp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/clisp-list