-
Notifications
You must be signed in to change notification settings - Fork 0
/
http_server.py
124 lines (107 loc) · 3.53 KB
/
http_server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/env python3
# this serves a simple queue so that 2 to 3 teams can communicate
#
# https://docs.cherrypy.org/en/latest/tutorials.html#tutorial-6-what-about-my-javascripts-css-and-images
# https://stackoverflow.com/questions/3743769/how-to-receive-json-in-a-post-request-in-cherrypy
import os.path
import sys
import cherrypy
import json
from datetime import datetime
from http_util import IP_ADDRESS, IP_PORT
from threading import Lock
import logging
dt_pattern = '%Y-%m-%d %H:%M:%S'
fifo = {} # key is primarily a serial number, but other non-numeric keys are allowed
index = 0 # index that is used to store and retrieve a value. This unique
# and is passed to the various clients
debugging = False
count = 0
lock = Lock()
def get_time_stamp():
s = datetime.now().strftime(dt_pattern)
return s
class IndexPage:
@cherrypy.expose
def index(self):
with open("res/index.html", "r") as f:
s = f.read()
return s
@cherrypy.expose
def echo(self, text='whatever'):
return(text)
@cherrypy.expose
def reset_fifo(self):
global fifo, index
lock.acquire()
fifo = {}
lock.release()
@cherrypy.expose
@cherrypy.tools.json_out()
@cherrypy.tools.json_in()
def fifo_in(self):
global index, fifo
lock.acquire()
value = cherrypy.request.json # already converted to Python dict
index += 1
if debugging:
print(f'fifo_in POST value ({index})', value)
else:
print(f'[{get_time_stamp()}] ' +
f'POST /fifo_in: ({index}, {str(value)[:55]}...)')
d = {index: value}
fifo.update(d)
# Responses are serialized to JSON (because of the json_out decorator)
result = {"index": index}
lock.release()
return result
@cherrypy.expose
@cherrypy.tools.json_out()
def fifo_out(self, index=None):
# assume that index (integer) is the item being requested
# fifo_out returns all dictionary items that are equal and newer
global count
lock.acquire()
count += 1
keys = sorted(fifo.keys())
index = int(index)
result = {k: fifo[k] for k in keys if k >= index}
if debugging and result:
print(f'server.fifo_out ({count}, {index})', result)
elif result:
print(f'[{get_time_stamp()}] ' +
f'GET /fifo_out: ({index}, {str(result)[:55]}...)')
lock.release()
return result
#mainconf = os.path.join(os.path.dirname(__file__), 'main.conf')
conf = {
'global':{
'server.socket_host': IP_ADDRESS,
'server.socket_port': IP_PORT,
'server.thread_pool': 10
},
'/': {
'tools.sessions.on': True,
'tools.staticdir.root': os.path.abspath(os.getcwd())
},
'/static': {
'tools.staticdir.on': True,
'tools.staticdir.dir': './res'
}
}
class IgnoreURLFilter(logging.Filter):
# used to suppress the many repeated "GET" requests
def __init__(self, ignore):
self.ignore = ignore
def filter(self, record):
msg = record.getMessage()
return self.ignore not in msg
def main(arg = None):
my_app = IndexPage()
app = cherrypy.tree.mount(my_app, "/", conf) # config=mainconf ?
app.log.access_log.addFilter(IgnoreURLFilter('GET /fifo_out'))
app.log.access_log.addFilter(IgnoreURLFilter('POST /fifo_in'))
cherrypy.engine.start()
return
if __name__ == "__main__":
main(sys.argv)