server.scm 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. (import
  2. (class java.io IOException OutputStream FilterInputStream)
  3. (class java.net InetSocketAddress)
  4. (class com.sun.net.httpserver HttpExchange HttpHandler HttpServer)
  5. (macduffie sxml)
  6. (macduffie json))
  7. (include "./canvas.js")
  8. (define complete-history '())
  9. (define buffer-list '())
  10. (define index-page ::String
  11. (sxml->xml
  12. `(html
  13. (head
  14. (title "Turtle Canvas"))
  15. (body
  16. (div
  17. (|@| (style "position: relative;"))
  18. (canvas
  19. (|@| (id "BgCanvas")
  20. (width "1000")
  21. (height "1000")
  22. (style "position: absolute; left: 0; top: 0; z-index: 0;")))
  23. (canvas
  24. (|@| (id "LineCanvas")
  25. (width "1000")
  26. (height "1000")
  27. (style "position: absolute; left: 0; top: 0; z-index: 1;")))
  28. (canvas
  29. (|@| (id "TurtleCanvas")
  30. (width "1000")
  31. (height "1000")
  32. (style "position: absolute; left: 0; top: 0; z-index: 2;"))))
  33. (script
  34. (|@| (src "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js")))
  35. (script
  36. (|@| (src "/draw.js")))))))
  37. (define not-found ::String "404NOTFOUND")
  38. (define (make-handler content-type ::String body-proc)
  39. (define-class result (HttpHandler)
  40. ((handle (t ::HttpExchange))
  41. ((t:getResponseHeaders):set "Content-Type" content-type)
  42. (let ()
  43. (define os ::OutputStream #!null)
  44. (define request-method (t:getRequestMethod))
  45. (define request-headers (t:getRequestHeaders))
  46. (define request-body (t:getRequestBody))
  47. (define body ::String (body-proc request-method request-headers request-body))
  48. (define response ::byte[] (body:getBytes))
  49. (cond
  50. ((string=? body not-found)
  51. (set! body "")
  52. (set! response (body:getBytes))
  53. (t:sendResponseHeaders 404 0))
  54. (else
  55. (t:sendResponseHeaders 200 response:length)))
  56. (set! os (t:getResponseBody))
  57. (os:write response)
  58. (os:close))))
  59. result)
  60. (define (api-new-id!)
  61. (set! buffer-list (append buffer-list (list complete-history)))
  62. (number->string (length buffer-list)))
  63. (define (api-push-buffer! s)
  64. (let ((p (open-input-string s)))
  65. (let ((input-result (read p)))
  66. (close-input-port p)
  67. (set! complete-history (cons input-result complete-history))
  68. (set! buffer-list (map (lambda (buff) (cons input-result buff)) buffer-list))
  69. "true\n")))
  70. (define (api-pull-buffer! s)
  71. (define n -1)
  72. (let ((p (open-input-string s)))
  73. (let ((input-result (read p)))
  74. (close-input-port p)
  75. (when (integer? input-result) (set! n input-result))
  76. (let ((result (list-ref buffer-list (- (length buffer-list) n))))
  77. (list-set! buffer-list (- (length buffer-list) n) '())
  78. (json-write-string (list->vector (reverse result)))))))
  79. (define (api-clear-buffer!)
  80. (set! complete-history '())
  81. (set! buffer-list (make-list (length buffer-list) '())))
  82. (define (filter-input-stream->string fis ::FilterInputStream)
  83. (define b ::byte[] (byte[] length: 1000))
  84. (fis:read b)
  85. (String b))
  86. (define NewIdHandler (make-handler "application/json; charset=UTF-8" (lambda (method headers body)
  87. (if (string=? method "POST")
  88. (api-new-id!)
  89. not-found))))
  90. (define PushBufferHandler (make-handler "application/json; charset=UTF-8" (lambda (method headers body)
  91. (if (string=? method "POST")
  92. (api-push-buffer! (filter-input-stream->string body))
  93. not-found))))
  94. (define PullBufferHandler (make-handler "application/json; charset=UTF-8" (lambda (method headers body)
  95. (if (string=? method "POST")
  96. (api-pull-buffer! (filter-input-stream->string body))
  97. not-found))))
  98. (define ClearBufferHandler (make-handler "application/json; charset=UTF-8" (lambda (method headers body)
  99. (if (string=? method "POST")
  100. (api-clear-buffer!)
  101. not-found))))
  102. (define FrontendHandler (make-handler "text/html; charset=UTF-8" (lambda (method headers body) index-page)))
  103. (define ScriptingHandler (make-handler "application/javascript; charset=UTF-8" (lambda (method headers body) script-page)))
  104. (define server ::HttpServer (HttpServer:create (InetSocketAddress 43334) 0))
  105. (server:createContext "/api/NewId" (NewIdHandler))
  106. (server:createContext "/api/PushBuffer" (PushBufferHandler))
  107. (server:createContext "/api/PullBuffer" (PullBufferHandler))
  108. (server:createContext "/api/ClearBuffer" (ClearBufferHandler))
  109. (server:createContext "/index.html" (FrontendHandler))
  110. (server:createContext "/" (FrontendHandler))
  111. (server:createContext "/draw.js" (ScriptingHandler))
  112. (server:setExecutor #!null)
  113. (server:start)