forked from mirrors/kore
flesh out the python stuff a bit more.
This commit is contained in:
parent
7bc8bb42e2
commit
3d3d705b98
|
@ -1,5 +1,9 @@
|
|||
Kore python module example.
|
||||
|
||||
This application requires kore to be built with PYTHON=1.
|
||||
|
||||
It mixes native code (dso) with python code.
|
||||
|
||||
Run:
|
||||
```
|
||||
$ kore run
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
# python configuration
|
||||
|
||||
load ./python.so onload
|
||||
|
||||
# import both python modules.
|
||||
python_import src/index.py onload
|
||||
python_import src/websockets.py
|
||||
|
||||
#bind 127.0.0.1 8888 c_on_connect
|
||||
bind 127.0.0.1 8888
|
||||
|
||||
tls_dhparam dh2048.pem
|
||||
|
@ -25,21 +26,30 @@ domain * {
|
|||
certfile cert/server.crt
|
||||
certkey cert/server.key
|
||||
|
||||
# Mix page handlers between native and python.
|
||||
static / page
|
||||
static /c cpage
|
||||
static /b minimal
|
||||
static /json json_parse
|
||||
static /state state_test
|
||||
static /ws ws_connect
|
||||
|
||||
# Use the builtin asset_serve_* to serve frontend HTML.
|
||||
static /wspage asset_serve_frontend_html
|
||||
|
||||
static /auth page auth
|
||||
|
||||
params get / {
|
||||
#
|
||||
# On the native page handler, use a python validator.
|
||||
#
|
||||
params get /c {
|
||||
validate id v_p_id
|
||||
}
|
||||
|
||||
params get /c {
|
||||
#
|
||||
# On the python page handler, use a native validator.
|
||||
#
|
||||
params get / {
|
||||
validate id v_id
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,50 @@
|
|||
# Simplistic kore example
|
||||
#
|
||||
# Copyright (c) 2017 Joris Vink <joris@coders.se>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
# This is a simple python module that can be loaded into Kore.
|
||||
# It demonstrates some basic abilities to deal with HTTP requests.
|
||||
|
||||
# Pull in the kore stuff.
|
||||
import kore
|
||||
|
||||
# Pull in python JSON parsing.
|
||||
import json
|
||||
|
||||
#
|
||||
# A validator that the configuration for this application uses to determine
|
||||
# if a request fulfills the requirements to pass an authentication block.
|
||||
#
|
||||
# See the configuration for more.
|
||||
#
|
||||
def python_auth(req, data):
|
||||
# print("python auth called %s" % data)
|
||||
kore.log(kore.LOG_NOTICE, "python auth called %s" % data)
|
||||
return kore.RESULT_OK
|
||||
|
||||
#
|
||||
# Define a validator that kore can use via the configuration to validate
|
||||
# something before allowing access to it.
|
||||
#
|
||||
def python_validator(req, data):
|
||||
print("python validator called %s" % data)
|
||||
kore.log(kore.LOG_NOTICE, "python validator called %s" % data)
|
||||
return kore.RESULT_OK
|
||||
|
||||
#
|
||||
# This function is called when our python module is loaded/unloaded.
|
||||
# The action param is kore.MODULE_LOAD or kore.MODULE_UNLOAD respectively.
|
||||
#
|
||||
def onload(action):
|
||||
kore.log(kore.LOG_INFO, "FOOBAR python onload called with %d" % action)
|
||||
return kore.RESULT_OK
|
||||
|
@ -21,22 +55,33 @@ def kore_onload():
|
|||
def kore_preload():
|
||||
print("kore_preload called")
|
||||
|
||||
#
|
||||
# Test page handler that displays some debug information as well as
|
||||
# fetches the "xframe" header from the request and logs it if present.
|
||||
#
|
||||
# If the request is a POST then we read the body up to 1024 bytes in
|
||||
# one go and display the result and bytes read in the log.
|
||||
#
|
||||
# If it's a GET request attempts to find the "id" argument and presents
|
||||
# it to the user.
|
||||
#
|
||||
def page(req):
|
||||
print("%s path is %s - host is %s" % (req, req.path, req.host))
|
||||
print("connection is %s" % req.connection)
|
||||
kore.log(kore.LOG_INFO,
|
||||
"%s path is %s - host is %s" % (req, req.path, req.host))
|
||||
kore.log(kore.LOG_INFO, "connection is %s" % req.connection)
|
||||
xframe = req.request_header("xframe")
|
||||
if xframe != None:
|
||||
print("xframe header present %s" % xframe)
|
||||
kore.log(kore.LOG_INFO, "xframe header present: '%s'" % xframe)
|
||||
if req.method == kore.METHOD_POST:
|
||||
try:
|
||||
length, body = req.body_read(1024)
|
||||
print("POST and got %d bytes! (%s)" %
|
||||
kore.log(kore.LOG_INFO, "POST and got %d bytes! (%s)" %
|
||||
(length, body.decode("utf-8")))
|
||||
except RuntimeError as r:
|
||||
print("oops runtime error %s" % r)
|
||||
kore.log(kore.LOG_INFO, "oops runtime error %s" % r)
|
||||
req.response(500, b'')
|
||||
except:
|
||||
print("oops other error")
|
||||
kore.log(kore.LOG_INFO, "oops other error")
|
||||
req.response(500, b'')
|
||||
else:
|
||||
req.response_header("content-type", "text/plain")
|
||||
|
@ -45,35 +90,43 @@ def page(req):
|
|||
req.populate_get()
|
||||
id = req.argument("id")
|
||||
if id != None:
|
||||
print("got id of %s" % id)
|
||||
kore.log(kore.LOG_INFO, "got id of %s" % id)
|
||||
req.response_header("content-type", "text/plain")
|
||||
req.response(200, "hello 1234".encode("utf-8"))
|
||||
return kore.RESULT_OK
|
||||
|
||||
#
|
||||
# Handler that parses the incoming body as JSON and dumps out some things.
|
||||
#
|
||||
def json_parse(req):
|
||||
if req.method != kore.METHOD_PUT:
|
||||
req.response(400, b'')
|
||||
return kore.RESULT_OK
|
||||
|
||||
data = json.loads(req.body)
|
||||
print("loaded json %s" % data)
|
||||
kore.log(kore.LOG_INFO, "loaded json %s" % data)
|
||||
if data["hello"] == 123:
|
||||
print("hello is 123!")
|
||||
kore.log(kore.LOG_INFO, "hello is 123!")
|
||||
|
||||
req.response(200, "ok".encode("utf-8"))
|
||||
return kore.RESULT_OK
|
||||
|
||||
#
|
||||
# Handler that stores some python state in req.state that it reuses
|
||||
# once the handler is called again by the event loop (after having
|
||||
# returned RESULT_RETRY to the event loop).
|
||||
#
|
||||
def state_test(req):
|
||||
# If we don't have a state this is the first time we're called.
|
||||
if req.state is None:
|
||||
print("state_test: first time")
|
||||
kore.log(kore.LOG_INFO, "state_test: first time")
|
||||
req.state = "hello world"
|
||||
|
||||
# Tell Kore to call us again next event loop.
|
||||
return kore.RESULT_RETRY
|
||||
|
||||
# We have been called before.
|
||||
print("state_test: second time, with %s" % req.state)
|
||||
kore.log(kore.LOG_INFO, "state_test: second time, with %s" % req.state)
|
||||
req.response(200, req.state.encode("utf-8"))
|
||||
|
||||
# We *MUST* reset state back to None before returning RESULT_OK
|
||||
|
@ -81,6 +134,9 @@ def state_test(req):
|
|||
|
||||
return kore.RESULT_OK
|
||||
|
||||
#
|
||||
# Small handler, returns 200 OK.
|
||||
#
|
||||
def minimal(req):
|
||||
req.response(200, b'')
|
||||
return kore.RESULT_OK
|
||||
|
|
|
@ -1,28 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Joris Vink <joris@coders.se>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <kore/kore.h>
|
||||
#include <kore/http.h>
|
||||
|
||||
/*
|
||||
* Just some examples of things that can be mixed with python modules.
|
||||
*/
|
||||
|
||||
int onload(int);
|
||||
int cpage(struct http_request *);
|
||||
void c_on_connect(struct connection *);
|
||||
int c_validator(struct http_request *, void *);
|
||||
|
||||
int
|
||||
c_validator(struct http_request *req, void *data)
|
||||
{
|
||||
printf("c_validator called!\n");
|
||||
kore_log(LOG_NOTICE, "c_validator(): called!");
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
void
|
||||
c_on_connect(struct connection *c)
|
||||
{
|
||||
printf("c_on_connect!\n");
|
||||
}
|
||||
|
||||
int
|
||||
onload(int action)
|
||||
{
|
||||
printf("C onload called!\n");
|
||||
kore_log(LOG_NOTICE, "onload called from native");
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
|
@ -30,9 +43,7 @@ int
|
|||
cpage(struct http_request *req)
|
||||
{
|
||||
http_populate_get(req);
|
||||
|
||||
//printf("cpage called\n");
|
||||
http_response(req, 200, NULL, 0);
|
||||
http_response(req, 200, "native", 6);
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,58 @@
|
|||
# using kore websockets via python.
|
||||
#
|
||||
# Copyright (c) 2017 Joris Vink <joris@coders.se>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
# Using kore websockets via python.
|
||||
|
||||
import kore
|
||||
|
||||
#
|
||||
# Our connection callback, gets called for each new websocket connection.
|
||||
#
|
||||
def onconnect(c):
|
||||
kore.log(kore.LOG_INFO, "%s: py connected" % c)
|
||||
|
||||
#
|
||||
# Each websocket arriving on a connection triggers this function.
|
||||
#
|
||||
# It receives the connection object, the opcode (TEXT/BINARY) and the
|
||||
# actual data received.
|
||||
#
|
||||
# In this example we use the websocket_broadcast() method from kore to
|
||||
# simply relay the message to all other connection clients.
|
||||
#
|
||||
def onmessage(c, op, data):
|
||||
kore.websocket_broadcast(c, op, data, kore.WEBSOCKET_BROADCAST_GLOBAL)
|
||||
|
||||
#
|
||||
# Called for every connection that goes byebye.
|
||||
#
|
||||
def ondisconnect(c):
|
||||
kore.log(kore.LOG_INFO, "%s: py disconnecting" % c)
|
||||
|
||||
#
|
||||
# The /ws connection handler. It establishes the websocket connection
|
||||
# after a request was made for it.
|
||||
#
|
||||
# Note that the websocket_handshake() method for the request takes 3
|
||||
# parameters which are the connection callback, message callback and
|
||||
# disconnect callback.
|
||||
#
|
||||
# These are given as strings to Kore which will then resolve them
|
||||
# in all modules which means you can give native callbacks here as well.
|
||||
#
|
||||
def ws_connect(req):
|
||||
try:
|
||||
req.websocket_handshake("onconnect", "onmessage", "ondisconnect")
|
||||
|
|
Loading…
Reference in New Issue