2000-09-26 10:35:26 -04:00
|
|
|
;;; Path handler for uploading Scheme code to the SU web server -*- Scheme -*-
|
2002-08-27 05:03:22 -04:00
|
|
|
|
|
|
|
;;; This file is part of the Scheme Untergrund Networking package.
|
|
|
|
|
|
|
|
;;; Copyright (c) 1995 by Olin Shivers.
|
|
|
|
;;; For copyright information, see the file COPYING which comes with
|
|
|
|
;;; the distribution.
|
|
|
|
|
2000-09-26 10:35:26 -04:00
|
|
|
;;; This is really just an handler example demonstrating how to upload code
|
|
|
|
;;; into the server.
|
|
|
|
|
|
|
|
;;; (do/timeout secs thunk)
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;;; Run THUNK, and gun it down if it hasn't finished in SECS seconds.
|
|
|
|
;;; Returns nothing useful, and THUNK gets executed in a subprocess,
|
|
|
|
;;; so its side-effects are invisible, as well. This is a clever kludge --
|
|
|
|
;;; it uses three subprocesses -- but I don't have interrupts, so I'm hosed.
|
|
|
|
|
|
|
|
(define (do/timeout* secs thunk)
|
|
|
|
(run (begin (let ((timer (fork (lambda () (sleep secs))))
|
|
|
|
(worker (fork thunk)))
|
|
|
|
(receive (process status) (wait-any)
|
|
|
|
(ignore-errors
|
|
|
|
(lambda ()
|
|
|
|
(signal-process (proc:pid (if (eq? worker process)
|
|
|
|
timer
|
|
|
|
worker))
|
|
|
|
signal/kill))))))))
|
|
|
|
(define-syntax do/timeout
|
|
|
|
(syntax-rules ()
|
|
|
|
((do/timeout secs body ...) (do/timeout* secs (lambda () body ...)))))
|
|
|
|
|
2002-09-22 11:41:41 -04:00
|
|
|
;;; The request handler for seval ops.
|
2000-09-26 10:35:26 -04:00
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
(define (seval-handler path req)
|
2002-11-29 09:49:22 -05:00
|
|
|
(let ((request-method (request-method req)))
|
2001-08-20 07:31:03 -04:00
|
|
|
(cond
|
|
|
|
((string=? request-method "POST") ; Could do others also.
|
2002-08-29 04:32:39 -04:00
|
|
|
(seval path req))
|
2004-08-11 10:51:51 -04:00
|
|
|
((or (string=? request-method "HEAD")
|
|
|
|
(string=? request-method "GET"))
|
|
|
|
(make-error-response (status-code method-not-allowed) req
|
|
|
|
"POST"))
|
2002-08-28 11:41:52 -04:00
|
|
|
(else
|
2004-08-11 10:51:51 -04:00
|
|
|
(make-error-response (status-code not-implemented) req)))))
|
|
|
|
|
2000-09-26 10:35:26 -04:00
|
|
|
|
2002-08-28 11:41:52 -04:00
|
|
|
(define (seval path req)
|
2004-08-14 17:58:11 -04:00
|
|
|
(let ((body-length (get-body-length-from-content-length req))) ;;make sure we have a valid Content-length header in request
|
2002-08-28 11:41:52 -04:00
|
|
|
(make-response
|
2003-01-09 10:05:30 -05:00
|
|
|
(status-code ok)
|
|
|
|
#f
|
2002-08-28 11:41:52 -04:00
|
|
|
(time)
|
|
|
|
"text/html"
|
|
|
|
'()
|
2004-08-14 15:07:23 -04:00
|
|
|
(make-reader-writer-body
|
|
|
|
(lambda (iport oport options)
|
2004-08-15 08:44:55 -04:00
|
|
|
(with-fatal-error-handler
|
|
|
|
|
|
|
|
(lambda (c decline)
|
|
|
|
;; no matter what kind of error (might be a server internal error), we emit this webpage:
|
|
|
|
(emit-prolog oport)
|
|
|
|
(with-tag oport html (xmlnsdecl-attr)
|
|
|
|
(newline oport)
|
|
|
|
(with-tag oport head ()
|
|
|
|
(newline oport)
|
|
|
|
(emit-title oport "No Program")
|
2004-08-14 15:07:23 -04:00
|
|
|
(newline oport))
|
2004-08-15 08:44:55 -04:00
|
|
|
(newline oport)
|
|
|
|
(with-tag oport body ()
|
|
|
|
(newline oport)
|
|
|
|
(emit-header oport 1 "No Program")
|
2004-08-14 15:07:23 -04:00
|
|
|
(newline oport)
|
2004-08-15 08:44:55 -04:00
|
|
|
(with-tag oport p ()
|
|
|
|
(display
|
|
|
|
"No program was found in the body of the request.
|
|
|
|
The request's body must be form-url encoded and contain a \"program=<sexp>\" pair."
|
|
|
|
oport)
|
|
|
|
(newline oport))
|
|
|
|
(newline oport))
|
|
|
|
(newline oport)))
|
|
|
|
|
|
|
|
(let ((sexp (read-request-sexp body-length iport)))
|
|
|
|
(http-syslog (syslog-level debug) "read sexp: ~a" sexp)
|
|
|
|
(emit-prolog oport)
|
|
|
|
(with-tag oport html (xmlnsdecl-attr)
|
|
|
|
(newline oport)
|
|
|
|
(with-tag oport head ()
|
|
|
|
(newline oport)
|
|
|
|
(emit-title oport "Scheme program output")
|
|
|
|
(newline oport))
|
|
|
|
(newline oport)
|
|
|
|
|
|
|
|
(with-tag oport body ()
|
|
|
|
(newline oport)
|
|
|
|
(do/timeout
|
|
|
|
10
|
|
|
|
(receive vals
|
|
|
|
;; Do the computation.
|
|
|
|
(begin (emit-header oport 1 "Output from execution")
|
|
|
|
(newline oport)
|
|
|
|
(with-tag oport pre ()
|
|
|
|
(newline oport)
|
|
|
|
(force-output oport); In case we're gunned down.
|
|
|
|
(with-current-output-port oport
|
|
|
|
(eval-safely sexp))))
|
|
|
|
|
|
|
|
;; Pretty-print the returned value(s).;; hier noch mal newline rausschreiben?
|
|
|
|
(emit-header oport 1 "Return value(s)")
|
|
|
|
(with-tag oport pre ()
|
|
|
|
(for-each (lambda (val) (p val oport))
|
|
|
|
vals)))))))))))))
|
2000-09-26 10:35:26 -04:00
|
|
|
|
|
|
|
|
|
|
|
;;; Read an HTTP request entity body from stdin. The Content-length:
|
2004-08-14 15:07:23 -04:00
|
|
|
;;; entity-header field of request REQ tells how many bytes this entity
|
2005-04-06 18:49:50 -04:00
|
|
|
;;; is.
|
|
|
|
|
|
|
|
;;; We assume, that the entity is "form-url encoded" data (see
|
|
|
|
;;; parse-forms.scm for a description of this encoding). This
|
|
|
|
;;; assumption is rather strange - it may safely be made only if
|
|
|
|
;;; there's a "Content-type: application/x-www-form-urlencoded" header.
|
|
|
|
|
|
|
|
;;; Pull out the program=<stuff> string, extract <stuff>,
|
|
|
|
;;; parse that into an s-expression, and return it.
|
2000-09-26 10:35:26 -04:00
|
|
|
|
2004-08-14 15:07:23 -04:00
|
|
|
(define (read-request-sexp bytes iport)
|
|
|
|
(let*
|
|
|
|
((body (read-string bytes iport)) ;;read in bytes chars
|
|
|
|
(parsed-html-form-query (parse-html-form-query body)) ;; and parse them up.
|
|
|
|
(program (cond ((assoc "program" parsed-html-form-query) => cdr)
|
2002-08-29 04:32:39 -04:00
|
|
|
(else (error "No program in entity body.")))))
|
2004-08-14 15:07:23 -04:00
|
|
|
(http-syslog (syslog-level debug)
|
|
|
|
"Seval sexp: ~s" program)
|
|
|
|
(read (make-string-input-port program)))) ;; return first sexp, discard others
|