dom96 / jester Goto Github PK
View Code? Open in Web Editor NEWA sinatra-like web framework for Nim.
License: MIT License
A sinatra-like web framework for Nim.
License: MIT License
Nim Compiler Version 0.13.1 (2016-02-24) [Linux: amd64]
jester-0.1.0
My error is
radio_server.nim(36, 1) template/generic instantiation from here
lib/core/macros.nim(316, 70) template/generic instantiation from here
lib/pure/asyncdispatch.nim(1254, 8) Error: 'cb' is not GC-safe as it accesses 'nameIterVar' which is a global using GC'ed memory
radio_server.nim is my own file which contains this string N36
routes:
I compiled with jester-0.1.0 and nim 0.12.1.
I didn't change my code since previous nim version.
Thank you
Hi, is there a way to get the parameters of a request with type application/x-www-form-urlencoded
? Or should one parse them by hand? I think that should a pretty standard way to pass form parameters
import jester
for i in settings(43):
echo 5
I would like to use a custom 404 response.
Maybe like this?
import jester, asyncdispatch
errorpages:
pagenotfound:
resp "nothing found"
routes:
get "/":
resp "hello, world!"
runForever()
your documentation only shows basic examples for responding with "hello world" stuff, and your book focuses on server rendered applications. however, some people (such as i) would like to build single page apps and build a backend api with jester. can you provide some documentation examples for sending status codes for example, because i tried doing status = 200
and it failed which was very confusing because it requires an HttpCode which cannot be found on google. now i'm using status = Http400
but i'm getting a 404 instead. still struggling on to find out how to do a simple status code :( please try to cater for api developers rather than just for server rendered apps, i'm sure most of the apps built these days are SPAs anyway...
I haven't found a good way to serve static files with Access-Control-Allow-Origin header. Would be nice to have some hooks to post-process response along with its headers.
I'm trying this
resp "12345"
and this
resp "123456"
Only the second one works.
Also I'm not sure I have the latest sources of jester, I use nimble
When serving statically, say URL "foo%20bar.file", it should look for "foo bar.file" in filesystem.
Example code to illustrate (it fails for me on win7, don't know about other Linux/Mac)
import jester, asyncdispatch, htmlgen
import strutils, sequtils
var
tseq = @[@["Hello","World"],@["bad","result"],@["Needs a","fix"]]
proc doTest(): string =
var
thed = ""
tbod = ""
result = ""
for rNr,r in pairs(tseq): # for each row (a seq[string])
var x: seq[string] = r
if rNr == 0: # header row
x = r.mapIt(th(it)) # THIS FAILS
#x.applyIt(th(it)) # THIS WORKS
thed = x.join(" ") # str join wrapped th elements
else:
# add row wrapped in tr, with each element tt wrapped
#x = r.mapIt(td(it)) # THIS FAILS
x.applyIt(td(it)) # THIS WORKS
tbod &= tr(x.join(" "))
result = table(thead(thed), tbody(tbod))
proc test2(): string = "test data"
echo html(body(doTest()))
routes:
get "/test2":
resp html(body(test2())) # works
get "/test1":
resp html(body(doTest())) # doesn't work if contains mapIt()
runForever()
errors like:
nimcache\compiler_bug1.c: In function 'matchiter_250403':
nimcache\compiler_bug1.c:949:26: error: request for member 'ClEnv' in something not a structure or union
LOC26 = dotest_250060.ClEnv? dotest_250060.ClPrc(dotest_250060.ClEnv):((TMP1315)(dotest_250060.ClPrc))();
^
nimcache\compiler_bug1.c:949:47: error: request for member 'ClPrc' in something not a structure or union
LOC26 = dotest_250060.ClEnv? dotest_250060.ClPrc(dotest_250060.ClEnv):((TMP1315)(dotest_250060.ClPrc))();
^
nimcache\compiler_bug1.c:949:67: error: request for member 'ClEnv' in something not a structure or union
LOC26 = dotest_250060.ClEnv? dotest_250060.ClPrc(dotest_250060.ClEnv):((TMP1315)(dotest_250060.ClPrc))();
^
nimcache\compiler_bug1.c:949:99: error: request for member 'ClPrc' in something not a structure or union
LOC26 = dotest_250060.ClEnv? dotest_250060.ClPrc(dotest_250060.ClEnv):((TMP1315)(dotest_250060.ClPrc))();
NimBuild for example couldn't serve the full theindex.html file.
My code is as follows, open multiple browser windows, access program written by Jester the same address, submits the query to it, code to query the database statements, depending on the query condition, query time, ranging from the length of, why the browser window to send the request is the execution order, rather than asynchronous execution.
import db_odbc
import jester, asyncdispatch, htmlgen, asyncnet
settings:
port = Port(5000)
appName = "/book"
bindAddr = "127.0.0.1"
routes:
get "/":
resp "Forbidden access!"
post "/":
resp "Forbidden access!"
post "/cx":
var mysql="select goods.goodsid,goods.categoryid,goods.barcode,goods.goodslname,goods.adviceprice,"
mysql.add "goods.cbsj,goods.bb,shopstock.qty from goods left join shopstock on goods.goodsid=shopstock.goodsid where 1=1"
var isbn,sm,cbs:string
isbn=""
sm=""
cbs=""
isbn=request.formData.getOrDefault("t_isbn").body
sm=request.formData.getOrDefault("t_sm").body
cbs=request.formData.getOrDefault("t_cbs").body
if isbn=="" and sm=="" and cbs=="":
resp "nokey","text/html;charset=gb2312"
else:
if isbn!="":
mysql.add " and goods.barcode='" & isbn & "'"
if sm!="":
mysql.add " and goods.goodslname like '%" & sm & "%'"
if cbs!="":
mysql.add " and goods.bb like '%" & cbs & "%'"
var theDb = open("dbpos", "dbcxj", "dbcxj", "dbpos")
var myrows :seq[Row] = @[]
myrows=theDb.getAllRows(sql(mysql))
theDb.close()
resp $myrows,"text/html;charset=gb2312"
runForever()
There doesn't seem to be an indication of which version of nim to be used for the new-async version of Jester.
Request for feature: middlewares, much like other frameworks do them. The basic principle is:
You have a chain of handler instances, each responding to a method that takes, at the very least, the request, a way to respond to the request, and the next handler as parameters.
They are called in sequence; each handler is responsible for calling into the next one. This results in a nested call chain, and allows each registered handler to:
And many more usecases. A good search term for more information and examples would be "rack middleware".
I'm not 100% sure, but it seems like that. I tried to compile just:
import jester
with
$ nim cpp test.nim
The error is:
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
The full log is:
config/nim.cfg(53, 3) Hint: added path: '/root/.babel/pkgs/' [Path]
config/nim.cfg(54, 3) Hint: added path: '/root/.nimble/pkgs/nimble-0.6.0' [Path]
config/nim.cfg(54, 3) Hint: added path: '/root/.nimble/pkgs/jester-0.1.0' [Path]
config/nim.cfg(54, 3) Hint: added path: '/root/.nimble/pkgs/' [Path]
Hint: used config file '/opt/Nim/config/nim.cfg' [Conf]
Hint: system [Processing]
Hint: test [Processing]
Hint: jester [Processing]
Hint: asynchttpserver [Processing]
Hint: strtabs [Processing]
Hint: os [Processing]
Hint: strutils [Processing]
Hint: parseutils [Processing]
Hint: times [Processing]
Hint: posix [Processing]
Hint: hashes [Processing]
Hint: asyncnet [Processing]
Hint: asyncdispatch [Processing]
Hint: oids [Processing]
Hint: endians [Processing]
Hint: tables [Processing]
Hint: math [Processing]
Hint: macros [Processing]
Hint: rawsockets [Processing]
Hint: unsigned [Processing]
Hint: net [Processing]
Hint: selectors [Processing]
Hint: epoll [Processing]
lib/pure/asyncdispatch.nim(1410, 7) Hint: Processing recvLine as an async proc. [User]
lib/pure/asyncdispatch.nim(1410, 7) Hint: Processing connect as an async proc. [User]
lib/pure/asyncdispatch.nim(1410, 7) Hint: Processing recv as an async proc. [User]
lib/pure/asyncdispatch.nim(1410, 7) Hint: Processing send as an async proc. [User]
lib/pure/asyncdispatch.nim(1410, 7) Hint: Processing recvLineInto as an async proc. [User]
lib/pure/asyncdispatch.nim(1410, 7) Hint: Processing recvLine as an async proc. [User]
lib/pure/asyncnet.nim(405, 12) Hint: 'addNLIfEmpty' is declared but not used [XDeclaredButNotUsed]
Hint: uri [Processing]
lib/pure/asyncdispatch.nim(1410, 7) Hint: Processing processClient as an async proc. [User]
lib/pure/asynchttpserver.nim(152, 12) Hint: 'value' is declared but not used [XDeclaredButNotUsed]
lib/pure/asynchttpserver.nim(152, 7) Hint: 'key' is declared but not used [XDeclaredButNotUsed]
lib/pure/asyncdispatch.nim(1410, 7) Hint: Processing serve as an async proc. [User]
Hint: re [Processing]
Hint: pcre [Processing]
Hint: rtarrays [Processing]
Hint: scgi [Processing]
Hint: sockets [Processing]
lib/pure/scgi.nim(35, 8) Warning: sockets is deprecated [Deprecated]
Hint: asyncio [Processing]
lib/pure/asyncio.nim(11, 8) Warning: sockets is deprecated [Deprecated]
lib/pure/scgi.nim(35, 40) Warning: asyncio is deprecated [Deprecated]
Hint: cookies [Processing]
Hint: mimetypes [Processing]
Hint: md5 [Processing]
Hint: patterns [Processing]
Hint: errorpages [Processing]
Hint: htmlgen [Processing]
Hint: utils [Processing]
Hint: cgi [Processing]
lib/pure/asyncdispatch.nim(1410, 7) Hint: Processing sendHeaders as an async proc. [User]
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
I use Docker container with nim built from master:
$ docker run -it --rm -v `pwd`:/src -p 5000:5000 coopernurse/docker-nim sh
/src # nimble install jester
/src # apk add --update g++ libgc++
/src # nim cpp test.nim
When I use nim c test.nim
it works fine!
The required version note in the README reads: Note: Jester requires Nim version 0.11.2.
. This might be confusing as it suggests that Jester only works for that single version of Nim. Consider changing it to Note: Jester requires Nim version >0.11.2.
or Note: Jester requires Nim version 0.11.2 or above.
I'm trying your framework with the moustachu lib and a html file and it's cool.
Indeed, moustachu is an implementation of mustach that allow you to pass parameters on rendering.
Furthermore the developers could use javascript or css (for exemple) into the rendering file.
Sorry for my english
I cannot route like this
post "something?action=ololo":
because ? is not valid escape sequence.
Triple string are not working also.
I looked at patterns.nim and it seems that it is really impossible to route something
like that.
Me to do a program with the jester, in get block using resp to the client returns the data, when a small amount of data, the client can receive a normal. Why the amount of data is very big, such as a tens of KB, the client will not receive?
In many scenarios one has different exceptions that maps into say 400, 404 etc. It would be nice to see a way to maybe register a exceptionHandler or something at the top level.
After installing with nimble install jester
the example mentioned in the readme fails to compile. Same with the git checkout:
jester.nim(183, 44) Info: instantiation from here
jester.nim(188, 73) Error: undeclared identifier: '^'
The readme mentions 0.10.0 should be enough. Why do I have the feeling your modules rarely work with stable compiler versions…
May I'm doing something wrong but when I serve big files (< 1GB) the memory consumption raises very high very fast.
Example code:
get "/@filename":
var filename = @"filename"
var file = readFile(filename)
resp(file, "application")
This seems also the case when I serve the big files inside the public folder.
I tried to run the very first code example in the wiki, and got the following error on my macbook pro,
/.nimble/pkgs/jester-0.1.0/private/errorpages.nim(7, 22) Error: got 0, but expected 1 argument(s)
any hint?
I have no idea how I managed to do this here:
DEBUG get /last_aired
DEBUG 200 OK {Content-Length: 16, Content-Type: {
"episode":
{
"is_movie": false,
"name": "Spice Up Your Life",
"air_date": 1465659000,
"episode": 12,
"season": 6
}
}}
Would be nice to silence logging, that's useful for example during test or benchmarks
Not sure whether this is Jester problem or Nim problem...
Compilation fails if routes macro is used inside a function, and a value, local to this function (or an argument), is used in one of the branches.
Source:
import jester, asyncdispatch
proc startServer() =
let state = 1
routes:
get "/":
echo state
resp "OK"
results in this:
CC: test_jester
CC: stdlib_system
CC: jester_jester
CC: stdlib_asynchttpserver
Error: execution of an external compiler program 'gcc -c -w -I/home/dmitry/work/nim/lib -o /home/dmitry/work/tmp/nimcache/test_jester.o /home/dmitry/work/tmp/nimcache/test_jester.c' failed with exit code: 256
/home/dmitry/work/tmp/nimcache/test_jester.c: In function ‘startserver_240001’:
/home/dmitry/work/tmp/nimcache/test_jester.c:1066:2: error: incompatible type for argument 1 of ‘serve_238873’
serve_238873(LOC3, settings);
^
In file included from /home/dmitry/work/tmp/nimcache/test_jester.c:9:0:
/home/dmitry/work/tmp/nimcache/test_jester.c:399:17: note: expected ‘TY238875’ but argument is of type ‘TY240205’
N_NIMCALL(void, serve_238873)(TY238875 match, SettingsHEX3Aobjecttype237032* settings);
^
/home/dmitry/work/nim/lib/nimbase.h:215:44: note: in definition of macro ‘N_NIMCALL’
# define N_NIMCALL(rettype, name) rettype name /* no modifier */
Using devel Nim version, Ubuntu, gcc 4.8.5
test code:
import jester, asyncdispatch
routes:
get "/":
let foo = $request.params
echo foo
resp """<form method=post action=/foo><input type=text name=bla><input type=submit value=.></form>"""
post "/foo":
let foo = $request.params
echo foo
resp """<p>Done. <a href="/">back</a></p>"""
runForever()
Steps to reproduce:
/
in the browserback
/
still gets the POST parameter of /foo
.Hi, I'm trying to build a simple file upload with jester and it works with text files but when I upload a image the image is corrupted through ascii conversion.
Here my code:
import os, re, jester, asyncdispatch, htmlgen, asyncnet
routes:
get "/":
var html = ""
for file in walkFiles("*.*"):
html.add "<li>" & file & "</li>"
html.add "<form action=\"upload\" method=\"post\"enctype=\"multipart/form-data\">"
html.add "<input type=\"file\" name=\"file\"value=\"file\">"
html.add "<input type=\"submit\" value=\"Submit\" name=\"submit\">"
html.add "</form>"
resp(html)
post "/upload":
writeFile("test.png", request.formData["file"].body)
resp(request.formData["file"].body)
runForever()
Is there a way to save it in binary? Also I'm not shure if the conversion happens while I save the file or while the file gets transmitted.
Greetings Jakob
Hi, sorry for the silly request but I thought I should at least suggest you guys join the Todo-Backend.
It would be nice to have an example and/or tutorial on how to use Jester with nimrod's filters for html (and CSS) templates.
This will be useful for people experimenting with Jester.
dom96, I haven't seen jester before. very cool!
There is one problem with the current internal design tho - since handlers have to return the response body, it's not possible for a handler to complete asynchronously. Imagine what will happen if a handler needs to talk to several other services over the network to build the response - this communication must be blocking, jester needs to spawn 1 thread per request (not cool) and ultimately it's better if the requests are carried out in parallel.
To allow async mode, it's better if the handler type is proc (TRequest, TResponse)
, where the TResponse holds a reference to the output stream. Ideally, the handler will be written as a coroutine once we have these in nimrod. This will be similar to the deferred generators in python's twisted framework and the new await keyword in C# 5 (await is really just a syntax sugar for a framework built around async futures and coroutines), but even this will be based on the same low-level proc (req, res) handlers.
How about adding a sugar to write streaming response with "Transfer-Encoding": "chunked"
?
import strutils, math
proc sendChunk*(response: jester.Response, data: string): Future[void] =
let dataLen = len(data)
let sizeLen = Positive(floor(log2(toFloat(dataLen)) / 4 + 1))
response.send(toHex(BiggestInt(dataLen), sizeLen) & "\r\n" & data & "\r\n")
proc endChunk*(response: jester.Response): Future[void] =
response.send("0\r\n\r\n")
Test example:
routes:
get "/":
var headers = newStringTable({
"Content-Type": "text/plain",
"Transfer-Encoding": "chunked"
})
await response.sendHeaders(Http202, headers)
await sleepAsync(1000)
await response.sendChunk("hello")
await sleepAsync(1000)
await response.sendChunk(" world")
await sleepAsync(1000)
await response.sendChunk("AAAAAAAAAAAAAAAAAAAAA")
await sleepAsync(1000)
await response.endChunk()
How fast is this compared to the original sinatra framework in ruby since this is compiled to c it should atleast be 1000x faster right?
I don't know how exactly this works behind the scenes, but it seems terribly slow at the moment, compared to a dumb httpserver. Here is the code tested, with nim [file] c -r --checks:off --opt:speed >/dev/null
:
import jester, asyncdispatch, htmlgen
routes:
const r = h1 "hello world"
get "/":
resp r
runForever()
and
import strutils, sockets, httpserver
proc handleRequest(client: Socket, path, query: string): bool {.procvar.} =
client.send("<h1>hello world</h1>")
client.close
run(handleRequest, Port(5000))
And here are the benchmarks for ab -n10000 -c400 http://localhost:5000/
:
# Jester
Concurrency Level: 400
Time taken for tests: 13.004 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 840000 bytes
HTML transferred: 200000 bytes
Requests per second: 768.98 [#/sec] (mean)
Time per request: 520.171 [ms] (mean)
Time per request: 1.300 [ms] (mean, across all concurrent requests)
Transfer rate: 63.08 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 18 227.7 0 3004
Processing: 49 67 173.7 55 10387
Waiting: 6 67 173.6 55 10387
Total: 52 86 364.7 55 10387
Percentage of the requests served within a certain time (ms)
50% 55
66% 56
75% 57
80% 58
90% 60
95% 62
98% 79
99% 129
100% 10387 (longest request)
# httpserver
Concurrency Level: 400
Time taken for tests: 0.438 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 200000 bytes
HTML transferred: 0 bytes
Requests per second: 22855.89 [#/sec] (mean)
Time per request: 17.501 [ms] (mean)
Time per request: 0.044 [ms] (mean, across all concurrent requests)
Transfer rate: 446.40 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 1 2 1.2 2 13
Processing: 1 3 0.9 3 9
Waiting: 1 3 0.8 3 7
Total: 3 6 1.7 5 18
Percentage of the requests served within a certain time (ms)
50% 5
66% 5
75% 5
80% 5
90% 8
95% 9
98% 10
99% 16
100% 18 (longest request)
The mean time per request is 520ms vs 17ms, so a 30x slowdown. Now, I get that Jester is supposed to do much more than a dumb httpserver, but 30x seems way off for me. Do you know why this is happening or whether it's going to get better?
I looked into the code and think that I would like to contribute some changes to add functionalities based around headers.
But at first: I am not sure if that is really in the scope of Jester (and where to stop). I don't know "sinatra". I just develop our companies own framework since 1997 and it is opinionated but very flexible about how stuff works. It evolved 18 years and as such is still very compact and backward compatible to the version from 10 years ago. Which I mention because "the scope" of Jester could be equal to that, which is based on practical experience with many mostly database focused projects.
My main targets would be extending the current code in a way that headers are not something which is handled "just in the end" of handling a request.
I also believe that "status code" has not really a lot to do with the content you send. Many "error code" responses could have a nice HTML page or for example json content.
As another example: There are a lot of different and meaningful ways of redirection besides 303 so this needs to be a parameter (with a sensible default).
Content-Type... well I love to server images, csv, pdf, json dynamically generated through the framework. HTML is just one thing which will profit from extended header handling (for example it is really nice to have e-tags to decide if an image needs to be recreated).
Basically headers should be "collected" throughout the processing and there should be some practicable functionality implemented around HTTP "caching" (which does not cache anything). Disabling the default header handling should be optional, as there are always sensitive defaults!
If those changes are in the scope for Jester I can try to improve the headers and some other stuff. I am not sure how much time I can invest because I can't move our projects to Jester and Nim. Mostly because our codebase is just to big. But there may be a way to "integrate" stuff which I don't see right now. Besides that I may find a project which could be based on jester in the near future.
It would be nice to have a better way to do authentication vs having to write the same code pr route over and over.
The followying code is built on nim 0.13:
import jester,asyncdispatch settings: port = Port(8081) staticDir = "./static" routes: get "/attachment/@id": echo "attachment=" & @"id" attachment "pages/login.html" #error occurred resp "done" when isMainModule: echo "starting web server ..." runForever()
when browser:
http://localhost:8081/attachment/1
eror occurred on page:
Detail: Traceback (most recent call last) gist.nim(18) gist asyncdispatch.nim(1617) runForever asyncdispatch.nim(446) poll asyncdispatch.nim(722) :anonymous asyncdispatch.nim(213) complete asyncdispatch.nim(1257) cb asyncnet.nim(320) recvLineIntoIter asyncdispatch.nim(222) complete asyncdispatch.nim(1262) cb asyncdispatch.nim(260) callback= asyncdispatch.nim(1262) cb asyncdispatch.nim(260) callback= asyncdispatch.nim(1262) cb asyncdispatch.nim(260) callback= asyncdispatch.nim(1262) cb asyncdispatch.nim(260) callback= asyncdispatch.nim(1262) cb asyncdispatch.nim(260) callback= asyncdispatch.nim(1262) cb asyncdispatch.nim(260) callback= asyncdispatch.nim(1262) cb asyncdispatch.nim(260) callback= asyncdispatch.nim(1257) cb asynchttpserver.nim(238) processClientIter jester.nim(330) :anonymous jester.nim(301) handleHTTPRequest asyncdispatch.nim(1270) handleRequest asyncdispatch.nim(1257) cb jester.nim(265) handleRequestIter asyncdispatch.nim(1270) match asyncdispatch.nim(1257) cb jester.nim(444) matchIter strtabs.nim(109) [] key not found: Content-Type
What happened?
Error:
could not load: pcre.dll
Error: execution of an external program failed
I have pcre64.dll in c:/Nim/bin/ directory, link this one should work.
When I try to perform POST request with Ajax, the server hangs eating 94% to 100% of the CPU core on Ubuntu 14.10.
Here's client's script, which works (GET
request, and if we change it to POST
, jester hangs):
jQuery.ajax({
contentType: 'application/json',
dataType: 'json',
data: {
userId: document.getElementById('user-id').value
},
type: 'GET',
url: '/handle-this',
success: function(data) {
switch (data["result"]) {
case -2:
alert("malformed json");
case -1:
alert("Bad session id");
case 0:
alert("Success");
}
},
error: function() {
alert("Error saving cheat response");
}
});
and the server handler:
echo request.params # Prints: {:}
try:
sessId = request.params["userId"]
echo sessId
except:
respJson Http200, """{"result": -1}"""
Everything works fine with GET
request (parameters are parsed and passed into handler), and does not work with POST
request, parameters are empty and the server hangs at sessId = request.params["userId"]
line.
It seems that Jester does not work with the devel version of nim (pulled from devel branch of github). Trying to start example (from readme.md of Jester) I got:
Original stack trace in serve:
Traceback (most recent call last)
macros.nim(309) example
jester.nim(326) serve
asyncdispatch.nim(1225) serve
asyncdispatch.nim(1212) cb
asynchttpserver.nim(254) serveIter
asyncnet.nim(443) bindAddr
rawsockets.nim(210) getAddrInfo
os.nim(280) raiseOSError
Continuing...
Traceback (most recent call last)
macros.nim(309) example
jester.nim(326) serve
asyncdispatch.nim(282) asyncCheck
asyncdispatch.nim(224) callback=
asyncdispatch.nim(286) :anonymous
Error: unhandled exception: Invalid value for ai_flags No such file or directory [Exception]
I'm on FreeBSD 10.1 x64, Jester is reinstalled using nimble - no changes.
https://gist.github.com/Heartmender/59250eddb8e20252541c for my code and the compiler output.
My goal is to have things like materialize be slipstreamed into the server binary with the correct cache-control flags set so that it only has to serve the base css/javascript files once.
replacing:
const
materializeCSS = staticRead "public/css/materialize.min.css"
routes:
get "/static/css/materialize.min.css":
headers["Cache-Control"] = "public, max-age=31536000"
resp materializeCSS, "text/css"
with:
const
materializeCSS = staticRead "public/css/materialize.min.css"
template cachedFile(path, contents, mimetype: string) =
get path:
headers["Cache-Control"] = "public, mapath-age=31536000"
resp contents, mimetype
routes:
cachedFile "/static/css/materialize.min.css", materializeCSS, "text/css"
The template gets discarded and the resulting static constants get thrown out of the binary at compile.
Hello:
I would like to divide a rest api project with jester into different src files:
Ex:
main.nim
import jester, asyncdispatch
import another_part
routes:
get "/":
resp """ {"status": "ok"} """, "application/json"
another_part.nim
import jester, asyncdispatch
routes:
get "/anotherpart":
resp """ {"status": "ok"} """, "application/json"
The current behaviour is that on running like this it will try to open two web servers with the same port.
An error has occured in one of your routes.
Detail: Traceback (most recent call last)
forum.nim(1328) forum
asyncdispatch.nim(1617) runForever
asyncdispatch.nim(1032) poll
asyncdispatch.nim(1149) cb
asyncdispatch.nim(213) complete
asyncdispatch.nim(1257) cb
os.nim(1159) recvLineIntoIter
asyncdispatch.nim(222) complete
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1262) cb
asyncdispatch.nim(260) callback=
asyncdispatch.nim(1257) cb
asynchttpserver.nim(238) processClientIter
jester.nim(328) :anonymous
jester.nim(299) handleHTTPRequest
asyncdispatch.nim(1270) handleRequest
asyncdispatch.nim(1257) cb
jester.nim(263) handleRequestIter
asyncdispatch.nim(1270) match
asyncdispatch.nim(1257) cb
forum.nim(1095) matchIter
forum.nim(458) reply
strtabs.nim(109) []
key not found: subject
Hi the walkDirRec function doesn't seem to work in a GET request.
If I do this
import os, re, jester, asyncdispatch, htmlgen, asyncnet
routes:
get "/":
var html = ""
html.add "<form action=\"upload\" method=\"post\"enctype=\"multipart/form-data\">"
html.add "<input type=\"file\" name=\"file\"value=\"file\">"
html.add "<input type=\"submit\" value=\"Submit\" name=\"submit\">"
html.add "</form>"
html.add "<h3>Folder</h3>"
for file in walkDirRec("./"):
html.add "<li><a href=\"" &file & "\">" & file & "</li>"
resp(html)
runForever()
i get
/nimcache/posix.c:103:18: error: invalid application of 'sizeof' to an incomplete type 'DIR' (aka 'struct __dirstream')
NTI103214.size = sizeof(DIR);
^ ~~~~~
/usr/include/dirent.h:127:16: note: forward declaration of 'struct __dirstream'
typedef struct __dirstream DIR;
^
1 error generated.
Error: execution of an external program failed
Am I doing something wrong or is this a bug?
Greetings Jakob
Jester is making jokes at http://localhost:8080
GET /
Traceback (most recent call last)
main.nim(78) main
main.nim(56) updateLoop
asyncio.nim(631) poll
asyncio.nim(214) asyncSockHandleRead
httpserver.nim(495) :anonymous
jester.nim(429) :anonymous
jester.nim(348) handleHTTPRequest
jester.nim(249) handleRequest
jester.nim(124) statusContent
jester.nim(119) sendHeaders
jester.nim(104) trySendEx
system.nim(2555) hiddenRaiseAssert
system.nim(1844) raiseAssert
Error: unhandled exception: not j.isAsync [EAssertionFailed]
Jester finishes his performance.
With the latest changes to HTTP headers, Jester does not work on latest Nim stable
I get the following error when trying to build the very first example from the README:
/home/demizer/.babel/pkgs/jester-0.1.0/jester.nim(346, 15) Info: instantiation from here
/home/demizer/.babel/pkgs/jester-0.1.0/jester.nim(244, 44) Error: type mismatch: got (TSocket) but expected 'PAsyncSocket'
I'm new to nimrod so I have no idea how to get past this.
I am using nimrod, babel, and jester from git. All compiled a few hours ago on Arch Linux.
When sendHeaders is called, it currently expects an HTTP response code, and a PStringTable of headers; it would be nice if the response code defaulted to HTTP 200 OK, and there was an overload for "sendHeaders" that automatically sent up the built-up response headers (i.e. headers["content-type"] = "text/html") if the user does not provide a PStringTable.
when hostOs == "linux":
{.passL: "-pthread".}
import asyncdispatch
import jester
import locks
routes:
get "/":
let st = newStringTable()
try:
let x = st["x"]
except:
echo "NOt FOUND x"
let mytab = newStringTable({"key1": "val1", "key2": "val2"},
modeCaseInsensitive)
echo "MYTAB: ", mytab
try:
let x = st["x"]
except:
echo "NOt FOUND x"
let mytab = newStringTable({"key1": "val1", "key2": "val2"},
modeCaseInsensitive)
echo "MYTAB: ", mytab
resp Http200, """{"result": -1}"""
settings.port = Port(4000)
runForever()
Steps to reproduce:
nim c -r main.nim
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.