mirror of
https://github.com/urlysses/1991.git
synced 2024-11-26 03:28:06 +11:00
Add basic CRUD support.
TODO: + Make content-type available. + Make sure multipart/form-data works (not sure?). + Clean up recent code additions.
This commit is contained in:
parent
424aced3ec
commit
d775fd9ae6
86
1991.fs
86
1991.fs
@ -11,6 +11,10 @@ include unix/socket.fs
|
|||||||
while 2over nip /string
|
while 2over nip /string
|
||||||
r> 1+ >r
|
r> 1+ >r
|
||||||
repeat 2drop 2drop r> ;
|
repeat 2drop 2drop r> ;
|
||||||
|
: -leading ( addr len -- addr' len' )
|
||||||
|
begin over c@ bl = while 1 /string repeat ;
|
||||||
|
: trim ( addr len -- addr' len')
|
||||||
|
-leading -trailing ;
|
||||||
: exchange ( a1 a2 -- )
|
: exchange ( a1 a2 -- )
|
||||||
2dup c@ swap c@ rot c! swap c! ;
|
2dup c@ swap c@ rot c! swap c! ;
|
||||||
: reverse ( caddr u -- ) \ reverse a string
|
: reverse ( caddr u -- ) \ reverse a string
|
||||||
@ -65,6 +69,20 @@ pubvar tmpQueryString
|
|||||||
+s \ adding our new query values.
|
+s \ adding our new query values.
|
||||||
set-tmp-query-string ;
|
set-tmp-query-string ;
|
||||||
|
|
||||||
|
\ Request body
|
||||||
|
pubvar requestBody
|
||||||
|
: set-request-body ( addr u -- )
|
||||||
|
requestBody 2! ;
|
||||||
|
: get-request-body ( -- addr u )
|
||||||
|
requestBody 2@ ;
|
||||||
|
|
||||||
|
\ Request method
|
||||||
|
pubvar requestMethod
|
||||||
|
: set-request-method ( addr u -- )
|
||||||
|
requestMethod 2! ;
|
||||||
|
: get-request-method ( -- addr u )
|
||||||
|
requestMethod 2@ ;
|
||||||
|
|
||||||
\ User-defined routing
|
\ User-defined routing
|
||||||
wordlist constant routes
|
wordlist constant routes
|
||||||
pubvar reqroute
|
pubvar reqroute
|
||||||
@ -317,8 +335,35 @@ s" image/x-icon" filetype: ico
|
|||||||
2swap content-type \ Set content-type
|
2swap content-type \ Set content-type
|
||||||
s+ ; \ Join
|
s+ ; \ Join
|
||||||
|
|
||||||
|
: get-content-length ( addr u -- clen )
|
||||||
|
s" Content-Length:" search if
|
||||||
|
2dup s\" \n" search drop nip -
|
||||||
|
s" Content-Length:" nip /string
|
||||||
|
trim
|
||||||
|
s>number?
|
||||||
|
2drop
|
||||||
|
else
|
||||||
|
2drop
|
||||||
|
0
|
||||||
|
then ;
|
||||||
|
|
||||||
|
: read-request-body ( socket u -- )
|
||||||
|
\ Takes the socket and the length of the
|
||||||
|
\ body (Content-Length).
|
||||||
|
here swap aligned read-socket
|
||||||
|
set-request-body ;
|
||||||
: read-request ( socket -- addr u )
|
: read-request ( socket -- addr u )
|
||||||
pad 4096 read-socket ;
|
\ Returns the request header
|
||||||
|
\ but also collects the request body.
|
||||||
|
dup >r
|
||||||
|
pad 4096 read-socket
|
||||||
|
r> dup 2over rot drop
|
||||||
|
get-content-length ?dup if
|
||||||
|
read-request-body
|
||||||
|
else
|
||||||
|
s" " set-request-body
|
||||||
|
drop
|
||||||
|
then ;
|
||||||
|
|
||||||
: send-response ( addr u socket -- )
|
: send-response ( addr u socket -- )
|
||||||
dup >r write-socket r> close-socket ;
|
dup >r write-socket r> close-socket ;
|
||||||
@ -356,8 +401,42 @@ s" image/x-icon" filetype: ico
|
|||||||
: 404content-type txt ;
|
: 404content-type txt ;
|
||||||
: 404html s" 404" ;
|
: 404html s" 404" ;
|
||||||
|
|
||||||
|
: valid-method? ( addr u -- addr' u' bool )
|
||||||
|
2dup s" GET" search if
|
||||||
|
2nip
|
||||||
|
-1
|
||||||
|
s" GET" set-request-method
|
||||||
|
exit
|
||||||
|
then
|
||||||
|
2drop
|
||||||
|
|
||||||
|
2dup s" POST" search if
|
||||||
|
2nip
|
||||||
|
-1
|
||||||
|
s" POST" set-request-method
|
||||||
|
exit
|
||||||
|
then
|
||||||
|
2drop
|
||||||
|
|
||||||
|
2dup s" PUT" search if
|
||||||
|
2nip
|
||||||
|
-1
|
||||||
|
s" PUT" set-request-method
|
||||||
|
exit
|
||||||
|
then
|
||||||
|
2drop
|
||||||
|
|
||||||
|
2dup s" DELETE" search if
|
||||||
|
2nip
|
||||||
|
-1
|
||||||
|
s" DELETE" set-request-method
|
||||||
|
exit
|
||||||
|
then
|
||||||
|
2drop
|
||||||
|
0 ;
|
||||||
|
|
||||||
: either-resolve ( addr u -- resolveaddr resolveu )
|
: either-resolve ( addr u -- resolveaddr resolveu )
|
||||||
s" GET" search if
|
valid-method? if
|
||||||
s" html" get-filetype set-content-type \ reset the request's content-type
|
s" html" get-filetype set-content-type \ reset the request's content-type
|
||||||
requested-route
|
requested-route
|
||||||
2dup find-route dup if
|
2dup find-route dup if
|
||||||
@ -374,7 +453,8 @@ s" image/x-icon" filetype: ico
|
|||||||
then
|
then
|
||||||
then
|
then
|
||||||
200 get-content-type set-header +s
|
200 get-content-type set-header +s
|
||||||
rdrop exit then ;
|
rdrop exit
|
||||||
|
then ;
|
||||||
|
|
||||||
: or-404 ( addr u -- 404addr 404u )
|
: or-404 ( addr u -- 404addr 404u )
|
||||||
2drop
|
2drop
|
||||||
|
@ -8,6 +8,6 @@ A server-side web framework written in Forth.
|
|||||||
+ [x] file-serving if no user-defined routes match. Search "public/" dir
|
+ [x] file-serving if no user-defined routes match. Search "public/" dir
|
||||||
unless otherwise specified by user.
|
unless otherwise specified by user.
|
||||||
+ [x] query arguments
|
+ [x] query arguments
|
||||||
+ [ ] PUT, POST, DELETE
|
+ [x] PUT, POST, DELETE
|
||||||
+ [x] templating
|
+ [x] templating
|
||||||
+ [x] fuzzy-/pattern-match-enabled user routes (e.g., /something/*/wildcard)?
|
+ [x] fuzzy-/pattern-match-enabled user routes (e.g., /something/*/wildcard)?
|
||||||
|
70
examples/public/crud.html
Normal file
70
examples/public/crud.html
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>GET, PUT, POST, DELETE</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<input type="submit" value="GET" id="get">
|
||||||
|
<input type="submit" value="POST" id="post">
|
||||||
|
<input type="submit" value="PUT" id="put">
|
||||||
|
<input type="submit" value="DELETE" id="delete">
|
||||||
|
<script type="text/javascript">
|
||||||
|
// https://gist.github.com/EtienneR/2f3ab345df502bd3d13e
|
||||||
|
(function () {
|
||||||
|
function onload () {
|
||||||
|
var rt = xhr.responseText;
|
||||||
|
console.log(rt, xhr.readyState, xhr.status);
|
||||||
|
}
|
||||||
|
var url = "/api/v1/users";
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
var get = document.querySelector("#get");
|
||||||
|
var post = document.querySelector("#post");
|
||||||
|
var put = document.querySelector("#put");
|
||||||
|
var del = document.querySelector("#delete");
|
||||||
|
|
||||||
|
// GET
|
||||||
|
get.onclick = function () {
|
||||||
|
xhr.open("GET", url + "/1", true);
|
||||||
|
xhr.onload = onload;
|
||||||
|
xhr.send(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
// POST
|
||||||
|
// TODO: 201 status
|
||||||
|
post.onclick = function () {
|
||||||
|
var data = {};
|
||||||
|
data.firstname = "Aaaa";
|
||||||
|
data.lastname = "Bbbb";
|
||||||
|
var json = JSON.stringify(data);
|
||||||
|
xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", url + "/1", true);
|
||||||
|
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");
|
||||||
|
xhr.onload = onload;
|
||||||
|
xhr.send(json);
|
||||||
|
};
|
||||||
|
|
||||||
|
// PUT
|
||||||
|
put.onclick = function () {
|
||||||
|
var data = {};
|
||||||
|
data.firstname = "Aaaa2";
|
||||||
|
data.lastname = "Bbbb2";
|
||||||
|
var json = JSON.stringify(data);
|
||||||
|
xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("PUT", url + "/2", true);
|
||||||
|
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");
|
||||||
|
xhr.onload = onload;
|
||||||
|
xhr.send(json);
|
||||||
|
};
|
||||||
|
|
||||||
|
// DELETE
|
||||||
|
del.onclick = function () {
|
||||||
|
xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("DELETE", url + "/2", true);
|
||||||
|
xhr.onload = onload;
|
||||||
|
xhr.send(null);
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user