-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.rkt
145 lines (124 loc) · 3.98 KB
/
server.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
;instructions for when you inevitably forget
;run racket server.rkt from the command line
;go to http://127.0.0.1:8080/dinosaur
;make sure the anatomy file doesn't use render (or ideally print)
#lang racket
(require racket/list
web-server/http
web-server/servlet-env
web-server/dispatch
web-server/http/bindings
json
"structs/point.rkt"
"bone.rkt"
"parameter.rkt"
"json.rkt")
(require "anatomyFiles/dinosaur.rkt"
(prefix-in presets: "anatomyFiles/dinosaur-presets.rkt"))
(define (response
#:code [code/kw 200]
#:message [message/kw "OK"]
#:seconds [seconds/kw (current-seconds)]
#:mime [mime/kw #f]
#:headers [headers/kw (list
(make-header #"Access-Control-Allow-Origin"
#"*"))]
#:body [body/kw empty])
(define mime
(cond ((string? mime/kw)
(string->bytes/utf-8 mime/kw))
((bytes? mime/kw)
mime/kw)
(else
#f)))
(define message
(cond ((bytes? message/kw)
message/kw)
((string? message/kw)
(string->bytes/utf-8 message/kw))
(else
#f)))
(define body
(cond ((string? body/kw)
(list (string->bytes/utf-8 body/kw)))
((bytes? body/kw)
(list body/kw))
((list? body/kw)
body/kw)
(#t
body/kw)))
(response/full
code/kw
message
seconds/kw
mime
headers/kw
body))
(define (raw-request-bindings->parameter-hash bindings)
(define newParams (make-hash))
(for ([param bindings])
(hash-set! newParams
(string->symbol (bytes->string/utf-8 (binding-id param)))
(string->number (bytes->string/utf-8 (binding:form-value param)))))
newParams)
(define (request-parameters-exist? req-params params)
(andmap (lambda (param)
(member param (hash-keys (get-field parameters params))))
(hash-keys req-params)))
(define (request-parameters-values-valid? req-params params)
(andmap (lambda (param)
(is-valid-parameter-value? (hash-ref (get-field parameters params) (car param)) (cdr param)))
(hash->list req-params)))
(define (get-dinosaur req)
(define newParams (raw-request-bindings->parameter-hash (request-bindings/raw req)))
(cond
[(not (request-parameters-exist? newParams Parameters))
(invalid-parameter-response)]
[(not (request-parameters-values-valid? newParams Parameters))
(invalid-parameter-value-response)]
[else
(reset-parameters! Parameters)
(set-parameters! Parameters newParams)
(recalculate)
(response #:body (jsexpr->bytes (bone->json illium))
#:mime "application/json")]))
(define (get-parameters req)
(response #:body (jsexpr->bytes (parameters->json Parameters))
#:mime "application/json"))
(define (get-presets req)
(define json (map (lambda (preset-name preset-getter)
(hasheq preset-name (preset-getter)))
presets:presets presets:preset-getters))
(response #:body (jsexpr->bytes json)
#:mime "application/json"))
(define (not-found req)
(response #:code 404
#:message "Not Found"))
(define (bad-request)
(response #:code 400
#:message "Bad Request"))
(define (invalid-parameter-response)
(response #:code 400
#:message "Invalid parameter"))
(define (invalid-parameter-value-response)
(response #:code 400
#:message "Invalid parameter value"))
(define (internal-server-error)
(response #:code 500
#:message "Internal Server Error"))
(define-values (go _)
(dispatch-rules
[("dinosaur") #:method "get" get-dinosaur]
[("parameters") #:method "get" get-parameters]
[("presets") #:method "get" get-presets]
[else not-found]))
(define port (if (getenv "PORT")
(string->number (getenv "PORT"))
8080))
(module+ main
(serve/servlet
go
#:port port
#:listen-ip #f
#:command-line? #t
#:servlet-regexp #rx""))