Moving libraries
This commit is contained in:
		
						commit
						936e34a373
					
				|  | @ -0,0 +1,7 @@ | |||
| */README.html | ||||
| *.swp | ||||
| *.swo | ||||
| *.tgz | ||||
| tmp | ||||
| *.log | ||||
| 
 | ||||
|  | @ -0,0 +1,44 @@ | |||
| pipeline { | ||||
|     agent { | ||||
|         dockerfile { | ||||
|             label 'docker-x86_64' | ||||
|             filename 'Dockerfile.jenkins' | ||||
|             args '--user=root --privileged -v /var/run/docker.sock:/var/run/docker.sock' | ||||
|             reuseNode true | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     options { | ||||
|         disableConcurrentBuilds() | ||||
|         buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '10')) | ||||
|     } | ||||
| 
 | ||||
|     parameters { | ||||
|         string(name: 'LIBRARIES', defaultValue: 'cgi', description: '') | ||||
|     } | ||||
| 
 | ||||
|     stages { | ||||
|         stage('Tests') { | ||||
|             steps { | ||||
|                 script { | ||||
|                     def implementations = sh(script: 'compile-r7rs --list-r7rs-schemes', returnStdout: true).split() | ||||
| 
 | ||||
|                     params.LIBRARIES.split().each { LIBRARY -> | ||||
|                         stage("${LIBRARY}") { | ||||
|                             parallel implementations.collectEntries { SCHEME -> | ||||
|                                 [(SCHEME): { | ||||
|                                     stage("${SCHEME}") { | ||||
|                                         catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { | ||||
|                                             sh "make SCHEME=${SCHEME} clean test-docker" | ||||
|                                             archiveArtifacts artifacts: 'tmp/*/*.log', fingerprint: true | ||||
|                                         } | ||||
|                                     } | ||||
|                                 }] | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,56 @@ | |||
| .SILENT: build install test test-docker clean ${TMPDIR} | ||||
| SCHEME=chibi | ||||
| LIBRARY=cgi | ||||
| AUTHOR=Retropikzel | ||||
| 
 | ||||
| LIBRARY_FILE=retropikzel/${LIBRARY}.sld | ||||
| VERSION=$(shell cat retropikzel/${LIBRARY}/VERSION) | ||||
| DESCRIPTION=$(shell head -n1 retropikzel/${LIBRARY}/README.md) | ||||
| README=retropikzel/${LIBRARY}/README.html | ||||
| TESTFILE=retropikzel/${LIBRARY}/test.scm | ||||
| 
 | ||||
| PKG=${AUTHOR}-${LIBRARY}-${VERSION}.tgz | ||||
| TMPDIR=tmp/${SCHEME} | ||||
| 
 | ||||
| DOCKERIMG=${SCHEME}:head | ||||
| ifeq "${SCHEME}" "chicken" | ||||
| DOCKERIMG="chicken:5" | ||||
| endif | ||||
| 
 | ||||
| all: build | ||||
| 
 | ||||
| build: retropikzel/${LIBRARY}/LICENSE retropikzel/${LIBRARY}/VERSION | ||||
| 	echo "<pre>$$(cat retropikzel/${LIBRARY}/README.md)</pre>" > ${README} | ||||
| 	snow-chibi package --version=${VERSION} --authors=${AUTHOR} --doc=${README} --description="${DESCRIPTION}" ${LIBRARY_FILE} | ||||
| 
 | ||||
| install: | ||||
| 	snow-chibi install --impls=${SCHEME} ${SNOW_CHIBI_ARGS} ${PKG} | ||||
| 
 | ||||
| uninstall: | ||||
| 	-snow-chibi remove --impls=${SCHEME} ${PKG} | ||||
| 
 | ||||
| ${TMPDIR}: | ||||
| 	@mkdir -p ${TMPDIR} | ||||
| 	@cp ${TESTFILE} ${TMPDIR}/ | ||||
| 	@mkdir -p ${TMPDIR}/retropikzel | ||||
| 	@cp -r retropikzel/${LIBRARY} ${TMPDIR}/retropikzel/ | ||||
| 	@cp -r retropikzel/${LIBRARY}.s* ${TMPDIR}/retropikzel/ | ||||
| 
 | ||||
| test: ${TMPDIR} | ||||
| 	echo "Hello" | ||||
| 	cd ${TMPDIR} && COMPILE_R7RS=${SCHEME} compile-r7rs -I . -o test test.scm | ||||
| 	cd ${TMPDIR} && ./test | ||||
| 
 | ||||
| test-docker: ${TMPDIR} | ||||
| 	docker build --build-arg IMAGE=${DOCKERIMG} --build-arg SCHEME=${SCHEME} --tag=scheme-library-test-${SCHEME} -f Dockerfile.test . 2> ${TMPDIR}/docker.log || cat ${TMPDIR}/docker.log | ||||
| 	docker run -v "${PWD}:/workdir" -w /workdir -t scheme-library-test-${SCHEME} \
 | ||||
| 		sh -c "make SCHEME=${SCHEME} SNOW_CHIBI_ARGS=--always-yes build install test; chmod -R 755 ${TMPDIR}" | ||||
| 
 | ||||
| clean: | ||||
| 	find . -name "README.html" -delete | ||||
| 	find . -name "*.log" -delete | ||||
| 	rm -rf ${TMPDIR} | ||||
| 	rm -rf *.tgz | ||||
| 
 | ||||
| clean-all: | ||||
| 	rm -rf tmp | ||||
|  | @ -0,0 +1,316 @@ | |||
| (define stdin (open-binary-input-file "/dev/fd/0")) | ||||
| (define buffer-size 4000) | ||||
| (define temporary-directory (if (get-environment-variable "SCHEME_CGI_TMP_PATH") | ||||
|                               (get-environment-variable "SCHEME_CGI_TMP_PATH") | ||||
|                               "/tmp")) | ||||
| (define file-move-buffer-size 4000) | ||||
| (define encode-replacements | ||||
|   (list (list " " "%20") | ||||
|         (list " " "+") | ||||
|         (list "!" "%21") | ||||
|         (list "#" "%23") | ||||
|         (list "$" "%24") | ||||
|         (list "%" "%25") | ||||
|         (list "&" "%26") | ||||
|         (list "'" "%27") | ||||
|         (list "(" "%28") | ||||
|         (list ")" "%29") | ||||
|         (list "*" "%2A") | ||||
|         (list "+" "%2B") | ||||
|         (list "," "%2C") | ||||
|         (list "/" "%2F") | ||||
|         (list ":" "%3A") | ||||
|         (list ";" "%3B") | ||||
|         (list "=" "%3D") | ||||
|         (list "?" "%3F") | ||||
|         (list "@" "%40") | ||||
|         (list "[" "%5B") | ||||
|         (list "]" "%5D") | ||||
|         (list "<" "%3C") | ||||
|         (list ">" "%3E") | ||||
|         (list "\\" "%5C") | ||||
|         (list "\"" "%22") | ||||
|         (list "\n" "%0A") | ||||
|         (list "\r" "%0D"))) | ||||
| (define decode-replacements (map reverse encode-replacements)) | ||||
| 
 | ||||
| (define make-temp-filename | ||||
|   (lambda (filename) | ||||
|     (letrec* ((dev-random (open-binary-input-file "/dev/random")) | ||||
|               (min-byte (char->integer #\a)) | ||||
|               (max-byte (char->integer #\z)) | ||||
|               (max-length 10) | ||||
|               (looper (lambda (result count) | ||||
|                         (if (>= count max-length) | ||||
|                           result | ||||
|                           (let ((byte (read-u8 dev-random))) | ||||
|                             (if (and (> byte min-byte) (< byte max-byte)) | ||||
|                               (looper (bytevector-append result | ||||
|                                                          (bytevector byte)) | ||||
|                                       (+ count 1)) | ||||
|                               (looper result count)))))) | ||||
|               (result (string-append (utf8->string (looper (bytevector) 0)) | ||||
|                                      "_" | ||||
|                                      (utf8->string (looper (bytevector) 0)) | ||||
|                                      "_" | ||||
|                                      filename))) | ||||
|       (close-port dev-random) | ||||
|       result))) | ||||
| 
 | ||||
| #;(define headers->string | ||||
|   (lambda (headers) | ||||
|     (apply string-append (map | ||||
|                            (lambda (key-value) | ||||
|                              (string-append (car key-value) ": " (cdr key-value) "\r\n")) | ||||
|                            headers)))) | ||||
| 
 | ||||
| (define get-replacement | ||||
|   (lambda (key mode) | ||||
|     (let ((r (if (string=? mode "encode") | ||||
|                (assoc key encode-replacements) | ||||
|                (assoc key decode-replacements)))) | ||||
|       (if r (car (cdr r)) key)))) | ||||
| 
 | ||||
| (define endecode | ||||
|   (lambda (mode s) | ||||
|     (if (not s) | ||||
|       "" | ||||
|       (letrec ((s-length (string-length s)) | ||||
|                (looper | ||||
|                  (lambda (i result) | ||||
|                    (if (< i s-length) | ||||
|                      (let ((key-length (if (and (string=? mode "decode") | ||||
|                                                 (string=? (string-copy s i (+ i 1)) "%") | ||||
|                                                 (> s-length (+ i 2))) | ||||
|                                          3 | ||||
|                                          1))) | ||||
|                        (looper (+ i key-length) | ||||
|                                (string-append result | ||||
|                                               (get-replacement | ||||
|                                                 (string-copy s i (+ i key-length)) | ||||
|                                                 mode)))) | ||||
|                      result)))) | ||||
|         (looper 0 ""))))) | ||||
| 
 | ||||
| (define string-split | ||||
|   (lambda (str mark) | ||||
|     (let* ((str-l (string->list str)) | ||||
|            (res (list)) | ||||
|            (last-index 0) | ||||
|            (index 0) | ||||
|            (splitter (lambda (c) | ||||
|                        (cond ((char=? c mark) | ||||
|                               (begin | ||||
|                                 (set! res (append res (list (string-copy str last-index index)))) | ||||
|                                 (set! last-index (+ index 1)))) | ||||
|                              ((equal? (length str-l) (+ index 1)) | ||||
|                               (set! res (append res (list (string-copy str last-index (+ index 1))))))) | ||||
|                        (set! index (+ index 1))))) | ||||
|       (for-each splitter str-l) | ||||
|       res))) | ||||
| 
 | ||||
| (define split-http-parameters | ||||
|   (lambda (body) | ||||
|     (cond ((or (not (string? body)) | ||||
|                (string=? "" body)) | ||||
|            (list)) | ||||
|           (else (let ((bodylist (string->list body))) | ||||
|                   (map (lambda (p) | ||||
|                          (cons (string->symbol (list-ref p 0)) | ||||
|                                (if (> (length p) 1) | ||||
|                                  (list-ref p 1) | ||||
|                                  ""))) | ||||
|                        (map (lambda (x) (string-split x #\=)) | ||||
|                             (string-split (list->string bodylist) | ||||
|                                           #\&)))))))) | ||||
| 
 | ||||
| 
 | ||||
| (define read-until-eof | ||||
|   (lambda (port result) | ||||
|     (let ((c (read-bytevector buffer-size port))) | ||||
|       (if (eof-object? c) | ||||
|         (utf8->string result) | ||||
|         (read-until-eof port (bytevector-append result c)))))) | ||||
| 
 | ||||
| (define read-binary-port-until | ||||
|   (lambda (port result until) | ||||
|     (let ((byte (read-u8 port))) | ||||
|       (if (or (eof-object? byte) | ||||
|               (= byte until)) | ||||
|         result | ||||
|         (read-binary-port-until port (bytevector-append result | ||||
|                                                         (bytevector byte)) | ||||
|                                 until))))) | ||||
| 
 | ||||
| (define read-bytevector-line | ||||
|   (lambda (port) | ||||
|     (let* ((result (utf8->string (read-binary-port-until port | ||||
|                                                          (bytevector) | ||||
|                                                          (char->integer #\newline)))) | ||||
|            (result-length (string-length result)) | ||||
|            (ends-in-return? (and (> result-length 0) | ||||
|                                  (char=? (string-ref result (- result-length 1)) | ||||
|                                          #\return)))) | ||||
|       (cond ((= result-length 0) "") | ||||
|             (ends-in-return? (string-copy result 0 (- result-length 1))) | ||||
|             (else result))))) | ||||
| 
 | ||||
| (define string-filter | ||||
|   (lambda (str filter) | ||||
|     (let ((result (list))) | ||||
|       (string-for-each | ||||
|         (lambda (c) | ||||
|           (if (filter c) | ||||
|             (set! result (append result (list c))))) | ||||
|         str) | ||||
|       (list->string result)))) | ||||
| 
 | ||||
| (define headers (map (lambda (p) | ||||
|                        (cons (string->symbol (car p)) | ||||
|                              (cdr p))) | ||||
|                      (get-environment-variables))) | ||||
| (define content-type-pair (if (assoc 'CONTENT_TYPE headers) | ||||
|                             (assoc 'CONTENT_TYPE headers) | ||||
|                             (cons "Content-Type" "text/html"))) | ||||
| (define content-type-data (string-split (cdr content-type-pair) #\;)) | ||||
| (define content-type (list-ref content-type-data 0)) | ||||
| (define request-method (if (assoc 'REQUEST_METHOD headers) | ||||
|                          (cdr (assoc 'REQUEST_METHOD headers)) | ||||
|                          "GET")) | ||||
| 
 | ||||
| (define query-string (if (assoc 'QUERY_STRING headers) | ||||
|                        (cdr (assoc 'QUERY_STRING headers)) | ||||
|                        "")) | ||||
| (define parameters (list)) | ||||
| (define cookies (let ((cookie-string (get-environment-variable "HTTP_COOKIE"))) | ||||
|                   (if cookie-string | ||||
|                     (split-http-parameters cookie-string) | ||||
|                     (list)))) | ||||
| (define body "") | ||||
| (define files (list)) | ||||
| 
 | ||||
| (define breaker (char->integer #\-)) | ||||
| 
 | ||||
| 
 | ||||
| (define request | ||||
|   (list (cons 'headers headers) | ||||
|         (cons 'parameters parameters) | ||||
|         (cons 'cookies cookies) | ||||
|         (cons 'body body) | ||||
|         (cons 'files files))) | ||||
| 
 | ||||
| (define (get from key) | ||||
|   (let ((value (assoc (if (string? key) | ||||
|                         (string->symbol (endecode "encode" key)) | ||||
|                         key) | ||||
|                       from))) | ||||
|     (if value (cdr value) #f))) | ||||
| (define (get-file file) | ||||
|   (let ((value (assoc (endecode "encode" (if (symbol? file) | ||||
|                                            (symbol->string file) | ||||
|                                            file)) | ||||
|                       files))) | ||||
|     (if value (cdr value) #f))) | ||||
| (define (move-file from to) | ||||
|   (letrec* ((input (open-binary-input-file from)) | ||||
|             (output (open-binary-output-file to)) | ||||
|             (looper (lambda (bytes) | ||||
|                       (when (not (eof-object? bytes)) | ||||
|                         (write-bytevector bytes output) | ||||
|                         (looper (read-bytevector file-move-buffer-size input)))))) | ||||
|     (looper (read-bytevector file-move-buffer-size input)) | ||||
|     (close-port input) | ||||
|     (close-port output))) | ||||
| 
 | ||||
| (define (cgi) request) | ||||
| 
 | ||||
| (define cgi-exit | ||||
|   (lambda args | ||||
|     (for-each (lambda (file) | ||||
|                 (let ((path (cdr file))) | ||||
|                   (when (file-exists? path) | ||||
|                     (delete-file path)))) | ||||
|               files) | ||||
|     (if (null? args) | ||||
|       (exit 0) | ||||
|       (exit (car args))))) | ||||
| 
 | ||||
| (cond ((and content-type-pair (string=? content-type "multipart/form-data")) | ||||
|        (letrec* ((boundary (string->utf8 (string-append (list-ref (string-split | ||||
|                                                                     (list-ref content-type-data 1) #\=) 1)))) | ||||
|                  (boundary-length (bytevector-length boundary)) | ||||
|                  (content (letrec ((looper (lambda (bytes result) | ||||
|                                              (if (eof-object? bytes) | ||||
|                                                result | ||||
|                                                (looper (read-bytevector buffer-size stdin) | ||||
|                                                        (bytevector-append result bytes)))))) | ||||
|                             (looper (read-bytevector buffer-size stdin) | ||||
|                                     (bytevector)))) | ||||
|                  (header-content-length (string->number (cdr (assoc 'CONTENT_LENGTH headers)))) | ||||
|                  (content-length (bytevector-length content)) | ||||
|                  (content-mark 0) | ||||
|                  (looper (lambda (index) | ||||
|                            (cond ((< index (- content-length 4)) | ||||
|                                   (if (and (= breaker (bytevector-u8-ref content index)) | ||||
|                                            (= breaker (bytevector-u8-ref content (+ index 1))) | ||||
|                                            (equal? boundary (bytevector-copy content (+ index 2) (+ index 2 boundary-length)))) | ||||
|                                     (let* ((part (bytevector-copy content content-mark index)) | ||||
|                                            (part-length (bytevector-length part)) | ||||
|                                            (part-port (open-input-bytevector part)) | ||||
|                                            (part-headers-length 0) | ||||
|                                            (part-headers (letrec ((loop (lambda (line result) | ||||
|                                                                           (if (or (eof-object? line) (string=? line "")) | ||||
|                                                                             (map (lambda (p) (string-split p #\:)) result) | ||||
|                                                                             (begin | ||||
|                                                                               (set! part-headers-length (+ part-headers-length | ||||
|                                                                                                            (string-length line) | ||||
|                                                                                                            2)) | ||||
|                                                                               (loop (read-bytevector-line part-port) | ||||
|                                                                                     (append result (list line)))))))) | ||||
|                                                            (loop (read-bytevector-line part-port) (list))))) | ||||
|                                       (if (and (not (null? part-headers)) | ||||
|                                                (assoc "Content-Disposition" part-headers)) | ||||
|                                         (let* ((content-disposition | ||||
|                                                  (map | ||||
|                                                    (lambda (str) | ||||
|                                                      (let ((split (string-split str #\=))) | ||||
|                                                        (cons (string-filter (list-ref split 0) (lambda (c) (not (char=? c #\space)))) | ||||
|                                                              (if (= (length split) 2) | ||||
|                                                                (string-filter (list-ref split 1) (lambda (c) (not (char=? c #\")))) | ||||
|                                                                "")))) | ||||
|                                                    (string-split (car (cdr (assoc "Content-Disposition" part-headers))) #\;))) | ||||
|                                                (filename (assoc "filename" content-disposition))) | ||||
|                                           (if (not filename) | ||||
|                                             (set! parameters | ||||
|                                               (append parameters | ||||
|                                                       (list | ||||
|                                                         (cons (cdr (assoc "name" content-disposition)) | ||||
|                                                               (utf8->string (bytevector-copy content | ||||
|                                                                                              (+ (+ content-mark part-headers-length) 2) | ||||
|                                                                                              (- index 2))))))) | ||||
|                                             (let* ((tmp-file-path (string-append temporary-directory | ||||
|                                                                                  "/" | ||||
|                                                                                  (make-temp-filename (cdr filename)))) | ||||
|                                                    (tmp-file-port (begin (when (file-exists? tmp-file-path) | ||||
|                                                                            (delete-file tmp-file-path)) | ||||
|                                                                          (open-binary-output-file tmp-file-path)))) | ||||
|                                               (write-bytevector (bytevector-copy content | ||||
|                                                                                  (+ (+ content-mark part-headers-length) 2) | ||||
|                                                                                  (- index 2)) | ||||
|                                                                 tmp-file-port) | ||||
|                                               (close-port tmp-file-port) | ||||
|                                               (set! files (append files (list | ||||
|                                                                           (cons (cdr (assoc "name" content-disposition)) | ||||
|                                                                                 tmp-file-path)))))) | ||||
|                                           (set! content-mark index))) | ||||
|                                       (looper (+ index boundary-length))) | ||||
|                                     (looper (+ index 1)))))))) | ||||
|          (looper 0))) | ||||
|       (else (let ((raw-body (if (string=? request-method "POST") | ||||
|                               (read-until-eof stdin (bytevector)) | ||||
|                               ""))) | ||||
|               (set! parameters (split-http-parameters (if (string=? request-method "POST") | ||||
|                                                         raw-body | ||||
|                                                         query-string))) | ||||
|               (when (string=? request-method "POST") | ||||
|                 (set! body raw-body))))) | ||||
|  | @ -0,0 +1,12 @@ | |||
| (define-library | ||||
|   (retropikzel cgi) | ||||
|   (import (scheme base) | ||||
|           (scheme time) | ||||
|           (scheme read) | ||||
|           (scheme write) | ||||
|           (scheme file) | ||||
|           (scheme char) | ||||
|           (scheme process-context)) | ||||
|   (export cgi | ||||
|           cgi-exit) | ||||
|   (include "cgi.scm")) | ||||
|  | @ -0,0 +1,135 @@ | |||
| R7RS Scheme library for Common Gateway Interface | ||||
| 
 | ||||
| If you dont know what CGI is, in short server runs your Scheme script and | ||||
| displays it's output as a webpage. Also checkout | ||||
| [https://git.sr.ht/~retropikzel/scheme-php](https://git.sr.ht/~retropikzel/scheme-php). | ||||
| 
 | ||||
| [Project](https://sr.ht/~retropikzel/scheme-cgi/) | ||||
| 
 | ||||
| [Repository](https://git.sr.ht/~retropikzel/scheme-cgi) | ||||
| 
 | ||||
| [Issue tracker](https://todo.sr.ht/~retropikzel/scheme-cgi) | ||||
| 
 | ||||
| ## Caveats | ||||
| 
 | ||||
| - Works only on unix as it reads from /dev/fd/0 and /dev/random. | ||||
| 
 | ||||
| ## Buggy on implementations | ||||
| 
 | ||||
| - Does not work with mit-scheme | ||||
|     - For some reason mit-scheme exits when it reads eof-object from standard | ||||
|     input | ||||
| - STklos | ||||
|     - No output for some reason | ||||
| 
 | ||||
| ## How to use | ||||
| 
 | ||||
| Example using Gauche in Docker. | ||||
| 
 | ||||
| lighttpd.conf: | ||||
| 
 | ||||
|     server.document-root = "/workdir" | ||||
|     server.port = 3000 | ||||
|     server.modules += ("mod_cgi", "mod_dirlisting") | ||||
|     cgi.assign = (".scm"  => "/usr/bin/scheme-script") | ||||
|     dir-listing.activate = "enable" | ||||
| 
 | ||||
| Dockerfile: | ||||
| 
 | ||||
|     FROM schemers/gauche | ||||
|     RUN apt-get update && apt-get install -y --no-install-recommends lighttpd | ||||
|     WORKDIR /workdir | ||||
|     EXPOSE 3000 | ||||
|     COPY lighttpd.conf /lighttpd.conf | ||||
|     RUN echo "#!/bin/sh" > /usr/bin/scheme-script | ||||
|     RUN echo "exec gosh -r7 -I ./snow \$@" >> /usr/bin/scheme-script | ||||
|     RUN chmod +x /usr/bin/scheme-script | ||||
|     ENTRYPOINT ["/usr/sbin/lighttpd", "-D", "-f", "/lighttpd.conf"] | ||||
| 
 | ||||
| hello.scm: | ||||
| 
 | ||||
|     (import (scheme base) | ||||
|             (scheme write) | ||||
|             (retropikzel cgi)) | ||||
| 
 | ||||
|     (display "Content-type: text/html") | ||||
|     (display "\r\n") | ||||
|     (display "\r\n") | ||||
|     (display "Hello") | ||||
|     (display "</br>") | ||||
| 
 | ||||
|     (display "Request: ") | ||||
|     (write (get-request)) | ||||
|     (display "</br>") | ||||
|     (cgi-exit) | ||||
| 
 | ||||
| Run: | ||||
| 
 | ||||
|     docker build . --tag=scheme-cgi | ||||
|     docker run -it -v ${PWD}:/workdir -p 3000:3000 scheme-cgi | ||||
| 
 | ||||
| Then navigate with your browser to http://127.0.0.1:3000 | ||||
| 
 | ||||
| ## Documentation | ||||
| 
 | ||||
| ### Reference | ||||
| 
 | ||||
| **get-request** | ||||
| 
 | ||||
| Returns the whole request as association list. | ||||
| 
 | ||||
| **get-header** _name_ | ||||
| 
 | ||||
| Name can be symbol or a string. Returns the value of given header or #f. | ||||
| 
 | ||||
| **get-headers** | ||||
| 
 | ||||
| Returns association list of all headers. | ||||
| 
 | ||||
| **get-parameter** _name_ | ||||
| 
 | ||||
| Name can be symbol or a string. Returns the value of given parameter or #f. | ||||
| 
 | ||||
| **get-parameters** | ||||
| 
 | ||||
| Returns association list of all parameters. | ||||
| 
 | ||||
| **get-cookie** _name_ | ||||
| 
 | ||||
| Returns the value of given cookie or #f if. | ||||
| 
 | ||||
| **get-cookies** | ||||
| 
 | ||||
| Returns association list of all cookies. | ||||
| 
 | ||||
| **get-file** _filename_ | ||||
| 
 | ||||
| Filename is a symbol or a string. Returns the path of given file from files or #f. | ||||
| 
 | ||||
| Uploaded files are stored in /tmp, with randomly generated prefix on their | ||||
| name. They are not deleted unless cgi-exit is called. Use **move-file** to move | ||||
| them into preferred location. | ||||
| 
 | ||||
| **get-files** | ||||
| 
 | ||||
| Returns association list of all files. | ||||
| 
 | ||||
| **move-file** _from_ _to_ | ||||
| 
 | ||||
| Moves a file from _from_ path to _to_ path. | ||||
| 
 | ||||
| **get-body** | ||||
| 
 | ||||
| Returns the request body. | ||||
| 
 | ||||
| **cgi-exit**</br> | ||||
| **cgi-exit** _code_ | ||||
| 
 | ||||
| Does necessary cleanup and exits the script. Code is a number, if it is given | ||||
| then that is used as exit code. | ||||
| 
 | ||||
| ### Environment variables | ||||
| 
 | ||||
| **SCHEME\_CGI\_TMP\_PATH** | ||||
| 
 | ||||
| Path to where uploaded files are stored. Default is /tmp. | ||||
|  | @ -0,0 +1 @@ | |||
| 1.0.1 | ||||
|  | @ -0,0 +1,12 @@ | |||
| (import (scheme base) | ||||
|         (scheme write) | ||||
|         (scheme file) | ||||
|         (scheme process-context) | ||||
|         (retropikzel cgi) | ||||
|         (srfi 64)) | ||||
| 
 | ||||
| (test-begin "cgi") | ||||
| 
 | ||||
| (display "Hello") | ||||
| 
 | ||||
| (test-end "cgi") | ||||
		Loading…
	
		Reference in New Issue