Added "Date" field into response headers (#30)

* Added "Date" field into response headers

* Added multi process running (fork process)
This commit is contained in:
Oleg S
2023-03-12 17:58:52 +03:00
committed by GitHub
parent aa2604c531
commit d3ddd6a9f8
4 changed files with 88 additions and 43 deletions

View File

@@ -29,13 +29,17 @@ class _Server():
self.max_chunk_size = None # def value: 256 KiB
self.read_buffer_size = None # def value: 64 KiB
self.nowait = 0
self.num_workers = 1
self.worker_list = [ ]
def init(self, app, host = None, port = None, backlog = None, loglevel = None):
def init(self, app, host = None, port = None, loglevel = None, workers = None):
self.app = app
self.host = host if host else self.host
self.port = port if port else self.port
self.backlog = backlog if backlog else self.backlog
self.loglevel = loglevel if loglevel is not None else self.loglevel
self.num_workers = workers if workers is not None else self.num_workers
if self.num_workers > 1:
return 0
return _fastwsgi.init_server(self)
def set_allow_keepalive(self, value):
@@ -44,7 +48,11 @@ class _Server():
def run(self):
if self.nowait:
if self.num_workers > 1:
raise Exception('Incorrect server options')
return _fastwsgi.run_nowait(self)
if self.num_workers > 1:
return self.multi_run()
ret = _fastwsgi.run_server(self)
self.close()
return ret
@@ -52,35 +60,34 @@ class _Server():
def close(self):
return _fastwsgi.close_server(self)
def multi_run(self, num_workers = None):
if num_workers is not None:
self.num_workers = num_workers
for _ in range(self.num_workers):
pid = os.fork()
if pid > 0:
self.worker_list.append(pid)
print(f"Worker process added with PID: {pid}")
continue
try:
_fastwsgi.init_server(self)
_fastwsgi.run_server(self)
except KeyboardInterrupt:
pass
sys.exit(0)
try:
for _ in range(self.num_workers):
os.wait()
except KeyboardInterrupt:
print("\n" + "Stopping all workers")
for worker in self.worker_list:
os.kill(worker, signal.SIGINT)
return 0
server = _Server()
# -------------------------------------------------------------------------------------
NUM_WORKERS = 4
def run_multi_process_server(app):
workers = []
for _ in range(NUM_WORKERS):
pid = os.fork()
if pid > 0:
workers.append(pid)
print(f"Worker process added with PID: {pid}")
else:
try:
server.init(app)
server.run()
except KeyboardInterrupt:
sys.exit(0)
try:
for _ in range(NUM_WORKERS):
os.wait()
except KeyboardInterrupt:
print("\nStopping all workers")
for worker in workers:
os.kill(worker, signal.SIGINT)
def import_from_string(import_str):
module_str, _, attrs_str = import_str.partition(":")
if not module_str or not attrs_str:
@@ -103,12 +110,6 @@ def import_from_string(import_str):
return module
def print_server_details(host, port):
print(f"\n==== FastWSGI ==== ")
print(f"Host: {host}\nPort: {port}")
print("==================\n")
# -------------------------------------------------------------------------------------
@click.command()
@@ -131,17 +132,15 @@ def run_from_cli(host, port, wsgi_app_import_string, loglevel):
print(f"Error importing WSGI app: {e}")
sys.exit(1)
print_server_details(host, port)
server.init(wsgi_app, host, port, loglevel = loglevel)
print(f"Server listening at http://{host}:{port}")
server.init(wsgi_app, host, port, loglevel)
print(f"FastWSGI server listening at http://{server.host}:{server.port}")
server.run()
# -------------------------------------------------------------------------------------
def run(wsgi_app, host = server.host, port = server.port, backlog = server.backlog, loglevel = server.loglevel):
print_server_details(host, port)
print(f"Running on PID:", os.getpid())
server.init(wsgi_app, host, port, backlog, loglevel)
print(f"Server listening at http://{host}:{port}")
server.run()
# run_multi_process_server(wsgi_app)
def run(wsgi_app, host = None, port = None, loglevel = None, workers = None):
print("FastWSGI server running on PID:", os.getpid())
server.init(wsgi_app, host, port, loglevel, workers)
addon = " multiple workers" if server.num_workers > 1 else ""
print(f"FastWSGI server{addon} listening at http://{server.host}:{server.port}")
server.run()

View File

@@ -1,5 +1,6 @@
#include "common.h"
#include "llhttp.h"
#include <time.h>
void logrepr(int level, PyObject* obj)
{
@@ -63,3 +64,33 @@ const char * get_obj_attr_str(PyObject * obj, const char * name)
}
return PyUnicode_AsUTF8(attr);
}
static const char weekDays[7][4] = { "Sun", "Mon", "Tue", "Wen", "Thu", "Fri", "Sat" };
static const char monthList[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
time_t g_actual_time = 0;
char g_actual_asctime[32] = { 0 };
int g_actual_asctime_len = 0;
int get_asctime(char ** asc_time)
{
time_t curr_time = time(NULL);
if (curr_time == g_actual_time) {
*asc_time = g_actual_asctime;
return g_actual_asctime_len;
}
struct tm * tv = gmtime(&curr_time);
char buf[64];
int len = sprintf(buf, "%s, %d %s %04d %02d:%02d:%02d GMT",
weekDays[tv->tm_wday], tv->tm_mday, monthList[tv->tm_mon],
1900 + tv->tm_year, tv->tm_hour, tv->tm_min, tv->tm_sec);
if (len > 0 && len < 32) {
g_actual_time = curr_time;
g_actual_asctime_len = len;
memcpy(g_actual_asctime, buf, 32);
*asc_time = g_actual_asctime;
return len;
}
*asc_time = "";
return 0;
}

View File

@@ -54,4 +54,6 @@ const char * get_http_status_name(int status);
int64_t get_obj_attr_int(PyObject * obj, const char * name);
const char * get_obj_attr_str(PyObject * obj, const char * name);
int get_asctime(char ** asc_time);
#endif

View File

@@ -592,6 +592,7 @@ int build_response(client_t * client, int flags, int status, const void * header
PyObject** body = client->response.body;
StartResponse * response = NULL;
int64_t body_size = _body_size;
int resp_date_present = 0;
if (flags & RF_HEADERS_PYLIST) {
response = (StartResponse *)headers;
@@ -635,6 +636,10 @@ int build_response(client_t * client, int flags, int status, const void * header
if (strcasecmp(key, "Connection") == 0)
continue; // skip "Connection" header
if (key_len == 4)
if (strcasecmp(key, "Date") == 0)
resp_date_present = 1;
size_t value_len = 0;
const char * value = PyUnicode_AsUTF8AndSize(PyTuple_GET_ITEM(tuple, 1), &value_len);
@@ -650,6 +655,14 @@ int build_response(client_t * client, int flags, int status, const void * header
xbuf_add_str(head, (const char *)headers);
}
if (!resp_date_present) {
char * date_str;
int date_len = get_asctime(&date_str);
xbuf_add(head, "Date: ", 6);
xbuf_add(head, date_str, date_len);
xbuf_add(head, "\r\n", 2);
}
if ((flags & RF_SET_KEEP_ALIVE) != 0 && client->srv->allow_keepalive) {
xbuf_add_str(head, "Connection: keep-alive\r\n");
} else {