Download presentation
Presentation is loading. Please wait.
Published byUriel Harriman Modified over 9 years ago
1
Compiling Web Scripts for Apache Jacob Matthews Luke Hoban Robby Findler Rice University
2
The Goal (Version 1) Write a CGI program like this: (let ((n (read-from-web “Type a number: ”)) (m (read-from-web “and another: ”))) (display-to-web “The sum is: ” (+ n m)))
3
(let ((n (read-from-web “Type a number: ”)) (m (read-from-web “And another: ”))) (display-to-web “The sum is: ” (+ n m)))
4
(let ((n (read-from-web “Type a number: ”)) (m (read-from-web “And another: ”))) (display-to-web “The sum is: ” (+ n m)))
5
(let ((n (read-from-web “Type a number: ”)) (m (read-from-web “And another: ”))) (display-to-web “The sum is: ” (+ n m)))
6
(let ((n (read-from-web “Type a number: ”)) (m (read-from-web “And another: ”))) (display-to-web “The sum is: ” (+ n m)))
7
(let ((n (read-from-web “Type a number: ”)) (m (read-from-web “And another: ”))) (display-to-web “The sum is: ” (+ n m)))
8
(let ((n (read-from-web “Type a number: ”)) (m (read-from-web “And another: ”))) (display-to-web “The sum is: ” (+ n m)))
9
(let ((n (read-from-web “Type a number: ”)) (m (read-from-web “And another: ”))) (display-to-web “The sum is: ” (+ n m)))
10
An Observation (let ((n (read-from-web “Type a number: ”)) (m (read-from-web “and another: ”))) (display-to-web “The sum is: ” (+ n m)))
11
An Observation (let ((n (read-from-web “Type a number: ”)) (m (read-from-web “and another: ”))) (display-to-web “The sum is: ” (+ n m))) n = 4 If we have the red and the blue box, we can resume the program at that point as many times as we want.
12
CPS Form There’s already a standard transformation that does what we want! CPS conversion, lambda-lifting, and closure conversion give us red boxes at every point and arrows connecting them (let ((n (read-from-web “Type a number: ”)) (m (read-from-web “and another: ”))) (display-to-web “The sum is: ” (+ n m)))
13
Read-from-web (let ((n (read-from-web “Type a number: ”)) (m (read-from-web “and another: ”))) (display-to-web “The sum is: ” (+ n m))) n = 4 <INPUT TYPE=“hidden” NAME=“environment” VALUE=“n=4”> <INPUT TYPE=“hidden” NAME=“What’s Left?” VALUE=“A B C”>
14
So what can we handle? §Creating, invoking, and passing closures Creating and passing other basic values (cons, vector, string, etc) Basic control constructs ( if, let, cond, etc.) §call/cc
15
What can’t we handle? §variable assignment §mutable values §generative structures §exception handling §dynamic evaluation §input/output ports §threads §integration with native code §…§…
16
Plus … §… we have to be efficient! §… we have to be secure!
17
Variable Assignment (let ((sum 0)) (let loop () (let ((i (read-from-web "Type a number"))) (set! sum (+ sum i)) (loop))))
18
Variable Assignment (let ((sum 0)) (let loop () (let ((i (read-from-web "Type a number"))) (set! sum (+ sum i)) (loop)))) sum = 9
19
Variable Assignment (let ((sum 0)) (let loop () (let ((i (read-from-web "Type a number"))) (set! sum (+ sum i)) (loop))))
20
Variable Assignment (let ((sum 0)) (let loop () (let ((i (read-from-web "Type a number"))) (set! sum (+ sum i)) (loop))))
21
Variable Assignment (let ((sum 0)) (let loop () (let ((i (read-from-web "Type a number"))) (set! sum (+ sum i)) (loop))))
22
Variable Assignment (let ((sum 0)) (let loop () (let ((i (read-from-web "Type a number"))) (set! sum (+ sum i)) (loop))))
23
Variable Assignment (let ((sum 0)) (let loop () (let ((i (read-from-web "Type a number"))) (set! sum (+ sum i)) (loop)))) sum = 12 But then, the user hits the ‘Back’ button...
24
Variable Assignment (let ((sum 0)) (let loop () (let ((i (read-from-web "Type a number"))) (set! sum (+ sum i)) (loop)))) sum = 9 sum = 9, not 12!
25
Variable Assignment (let ((sum 0)) (let loop () (let ((i (read-from-web "Type a number"))) (set! sum (+ sum i)) (loop)))) sum = 9
26
Variable Assignment (let ((sum (box 0))) (let loop () (let ((i (read-from-web "Type a number"))) (set-box! sum (+ sum i)) (loop)))) a = 9 sum = [a]
27
Variable Assignment (let ((sum (box 0))) (let loop () (let ((i (read-from-web "Type a number"))) (set-box! sum (+ sum i)) (loop)))) a = 9
28
Variable Assignment (let ((sum (box 0))) (let loop () (let ((i (read-from-web "Type a number"))) (set-box! sum (+ sum i)) (loop)))) a = 12
29
Variable Assignment (let ((sum (box 0))) (let loop () (let ((i (read-from-web "Type a number"))) (set-box! sum (+ sum i)) (loop)))) a = 12
30
Variable Assignment (let ((sum (box 0))) (let loop () (let ((i (read-from-web "Type a number"))) (set-box! sum (+ sum i)) (loop)))) a = 12
31
Variable Assignment (let ((sum 0)) (let loop () (let ((i (read-from-web "Type a number"))) (set! sum (+ sum i)) (loop)))) a = 12 If the user hits the back button now, everything still works! sum = [a]
32
So where does the purple box go? §We need some place that’s associated with a particular user, but not a particular web page §Browser cookies might work
33
Mutable Values H do we handle other mutable values like cons cells, hash tables, and vectors?
34
Mutable Values (let ([lst '(#f)]) (let loop () (let ((r (read-from-web "Type a value"))) (append! lst (list r)) (loop))))
35
Mutable Values (let ([lst '(#f)]) (let loop () (let ((r (read-from-web "Type a value"))) (append! lst (list r)) (loop)))) lst = (cons #f ‘()) Same problem, different primitive
36
Mutable Values (let ([lst '(#f)]) (let loop () (let ((r (read-from-web "Type a value"))) (append! lst (list r)) (loop)))) lst = (cons [a] [b]) a = #f b = ‘()
37
Mutable Values But if we add to the purple box every time we make a list, we’ll have problems: §Even lists that never need to be saved get added §The purple box is never garbage-collected §There are too many constructors anyway!
38
Mutable Values §So instead, we get lazy! §Only add or update the purple box when we actually call read-from-web
39
Mutable Values (let ([lst '(#f)]) (let loop () (let ((r (read-from-web "Type a value"))) (append! lst (list r)) (loop)))) lst = (cons #f ‘())
40
Mutable Values (let ([lst '(#f)]) (let loop () (let ((r (read-from-web "Type a value"))) (append! lst (list r)) (loop)))) lst = (cons [a] [b]) a = #f b = ‘() In fact, we add all new mutable values reachable from the environment
41
But Won’t the Store Still Be Too Big? §Yes! §Even worse: the store never shrinks! §Cookies aren’t feasible §For now, put (some of) the store on the server
42
Security As it stands, attackers can make up anything as the blue and purple information!
43
Security (if (valid? (read-from-web "Password:”)) (display-secret-page) (display-error-page))
44
Security (if (valid? (read-from-web "Password:”)) (display-secret-page) (display-error-page)) The attacker can’t choose the red boxes, but can choose where the arrows point …
45
Security (if (valid? (read-from-web "Password:”)) (display-secret-page) (display-error-page)) … And that’s bad enough!
46
Security A solution: §Encrypt the contents of the hidden fields and the cookies §Keep a secret key only on the server
47
Efficiency §We’ve got too many red boxes! §They make the program larger §More arrows means larger values in the hidden fields and longer page download times
48
A Solution §“Full” CPS is too much - we don’t need all the red boxes!
49
Efficiency (let ((n (read-from-web “Type a number: ”)) (m (read-from-web “and another: ”))) (display-to-web “The sum is: ” (+ n m))) The program never reaches (+ n m) without going directly on to display-to-web …
50
Efficiency (let ((n (read-from-web “Type a number: ”)) (m (read-from-web “and another: ”))) (display-to-web “The sum is: ” (+ n m))) … so we can combine the two boxes!
51
Security (if (valid? (read-from-web "Password:”)) (display-secret-page) (display-error-page)) This also helps with security: No guarantees The attacker can’t name the display- secret-page box anymore
52
Conclusions §Even in a real language, we can compile direct-style programs into CGI style so they can run on Apache §It’s important to try out theories by scaling them to real-sized applications
53
Thank You!
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.