;;; this is just a snippet to show how to use Qt for POST requests to ;;; a cgi script (using e.g. python for cgi) ;;; ;;; this is here to have an alternative to Lisp solutions, which don't ;;; work well in ECL on some platforms (namely Windows) ;;; ;;; example usage: ;;; ;;; (server-request "booking.py" ;;; (list (cons "from" "2020-08-01") ;;; (cons "to" "2020-08-08"))) ;;; ;;; please note the use of QLET to have all locally created Qt objects deleted ;;; when leaving the function body; ;;; ;;; note also how this is done with function HTTP-PART, where we can't use QLET ;;; inside the function for 'QHttpPart', because we need to return the newly ;;; created Qt object; in this case, QLET is placed in the caller, see: ;;; ;;; (dolist... ;;; (qlet ((part (http-part param))) ;;; (|append|... ;;; ;;; ...and since we are at it, just a reminder: ;;; ;;; as you already should know, QLET is crucial for all only locally used Qt ;;; objects, because it guarantees two things: ;;; - the C++ destructors being called when leaving the QLET body ;;; - not leaving around some garbage (GC through finalizing is only implemen- ;;; ted for return values from Qt function calls) (qrequire :network) ;; for testing, using e.g. python3 -m http.server 8080 --cgi (defparameter *server* "http://localhost:8080/cgi-bin/") (defun http-part (parameter) (let ((part (qnew "QHttpPart"))) (qlet ((name "QVariant(QString)" (format nil "form-data; name=~S" (car parameter)))) (|setHeader| part |QNetworkRequest.ContentDispositionHeader| name) (|setBody| part (x:string-to-bytes (cdr parameter)))) part)) (defun server-request (script &optional parameters) "Make a http POST request to a cgi script, forcing synchronous behaviour, which simplifies things and is preferable in many cases." (start-busy-animation) ; pseudo code (let (response) (qlet ((ev-loop "QEventLoop") (manager "QNetworkAccessManager")) (qconnect manager "finished(QNetworkReply*)" (lambda (reply) (|deleteLater| reply) (let ((err (|error| reply))) (when (= |QNetworkReply.NoError| err) (setf response (qfrom-utf8 (|readAll| reply))))) (|exit| ev-loop))) (qlet ((multi "QHttpMultiPart") (qurl "QUrl(QString)" (x:cc *server* script)) (request "QNetworkRequest(QUrl)" qurl)) (dolist (param parameters) (qlet ((part (http-part param))) (|append| multi part))) (|post| manager request multi) (|exec| ev-loop |QEventLoop.ExcludeUserInputEvents|) (stop-busy-animation) ; pseudo code response))))