diff --git a/Makefile.am b/Makefile.am index bad9ce7..d4916fb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,6 +7,7 @@ pkgmoduledir=$(datarootdir)/guile/site/2.0/$(PACKAGE) dist_pkgmodule_DATA = \ src/cuirass/base.scm \ src/cuirass/database.scm \ + src/cuirass/http.scm \ src/cuirass/ui.scm \ src/cuirass/utils.scm @@ -34,6 +35,7 @@ TESTS = \ tests/base.scm \ ## tests/basic.sh # takes too long to execute tests/database.scm \ + tests/http.scm \ tests/ui.scm \ tests/utils.scm diff --git a/configure.ac b/configure.ac index 660a117..ad6f4be 100644 --- a/configure.ac +++ b/configure.ac @@ -23,6 +23,7 @@ AS_IF([test -z "$ac_cv_path_GUILD"], [AC_MSG_ERROR(['guild' program cannot be found.])]) GUILE_MODULE_REQUIRED([guix]) +GUILE_MODULE_REQUIRED([json]) GUILE_MODULE_REQUIRED([sqlite3]) AC_CONFIG_FILES([Makefile diff --git a/src/cuirass/http.scm b/src/cuirass/http.scm new file mode 100644 index 0000000..459dba9 --- /dev/null +++ b/src/cuirass/http.scm @@ -0,0 +1,75 @@ +;;; http.scm -- HTTP API +;;; Copyright © 2016 Mathieu Lirzin +;;; +;;; This file is part of Cuirass. +;;; +;;; Cuirass is free software: you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation, either version 3 of the License, or +;;; (at your option) any later version. +;;; +;;; Cuirass is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with Cuirass. If not, see . + +(define-module (cuirass http) + #:use-module (cuirass database) + #:use-module (cuirass utils) + #:use-module (ice-9 hash-table) + #:use-module (ice-9 match) + #:use-module (json) + #:use-module (web request) + #:use-module (web response) + #:use-module (web server) + #:use-module (web uri) + #:export (spec->json-string + run-cuirass-server)) + +;;; +;;; JSON format. +;;; + +(define (object->json-scm obj) + "Prepare OBJ for JSON usage." + (cond ((string? obj) obj) + ((number? obj) obj) + ((boolean? obj) obj) + ((null? obj) obj) + ((symbol? obj) (symbol->string obj)) + ((keyword? obj) (object->json-scm (keyword->symbol obj))) + ((alist? obj) (alist->hash-table (map object->json-scm obj))) + ((pair? obj) (cons (object->json-scm (car obj)) + (object->json-scm (cdr obj)))) + (else (object->string obj)))) + +(define* (spec->json-string spec #:key pretty) + "Return SPEC as a JSON object." + (scm->json-string (object->json-scm spec) #:pretty pretty)) + + +;;; +;;; Web server. +;;; + +(define (request-path-components request) + (split-and-decode-uri-path (uri-path (request-uri request)))) + +(define (not-found request) + (values (build-response #:code 404) + (string-append "Resource not found: " + (uri->string (request-uri request))))) + +(define (url-handler request body) + (match (request-path-components request) + (((or "jobsets" "specifications") . rest) + (values '((content-type . (application/json))) + (with-database db + (spec->json-string (car (db-get-specifications db)))))) + (_ (not-found request)))) + +(define (run-cuirass-server) + (run-server url-handler)) diff --git a/tests/http.scm b/tests/http.scm new file mode 100644 index 0000000..09601a9 --- /dev/null +++ b/tests/http.scm @@ -0,0 +1,33 @@ +;;; http.scm -- tests for (cuirass http) module +;;; Copyright © 2016 Mathieu Lirzin +;;; +;;; This file is part of Cuirass. +;;; +;;; Cuirass is free software: you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation, either version 3 of the License, or +;;; (at your option) any later version. +;;; +;;; Cuirass is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with Cuirass. If not, see . + +(use-modules (cuirass http) + (srfi srfi-64)) + +(test-begin "http") + +(test-equal "spec->json-string" + "{\"boolean\" : false,\"string\" : \"guix\",\"alist\" : {\"subset\" : \"hello\"},\"list\" : [1, \"2\", \"three\"],\"symbol\" : \"hydra-jobs\",\"number\" : 1}" + (spec->json-string '((#:number . 1) + (string . "guix") + ("symbol" . hydra-jobs) + (#:alist (subset . "hello")) + (list 1 "2" #:three) + ("boolean" . #f)))) + +(test-end)