mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a8850ffe5 | ||
|
|
e640f812ba | ||
|
|
75ea170472 | ||
|
|
1b14b1926e | ||
|
|
edaed7ab01 | ||
|
|
6cceece3d7 | ||
|
|
2add03edb8 | ||
|
|
7aab9bae51 | ||
|
|
46c2c1d885 | ||
|
|
544e97fac0 | ||
|
|
265a700498 | ||
|
|
a657b4b0aa | ||
|
|
ac97c8cf34 | ||
|
|
545f3ee608 | ||
|
|
fcd1a36420 | ||
|
|
47a8ab3da9 | ||
|
|
c4375a8e7a | ||
|
|
a6c5bd3bb3 | ||
|
|
d53127e8cf | ||
|
|
851dd987ab | ||
|
|
cf582af970 | ||
|
|
d0ec331b6b | ||
|
|
cc75f5f7b3 | ||
|
|
3d08b7fdd0 | ||
|
|
7a92449fc3 | ||
|
|
4b3c34469d | ||
|
|
55bf34561e | ||
|
|
7e79dc0405 | ||
|
|
d3053523ab | ||
|
|
e32185cc14 | ||
|
|
8e3e3cf27b | ||
|
|
e2cea376e8 | ||
|
|
2a27b66d96 | ||
|
|
522717ca99 | ||
|
|
5ee106170b | ||
|
|
d62f04a5a6 | ||
|
|
eefe5048b2 | ||
|
|
8f792fde2d | ||
|
|
d8ef2d8300 | ||
|
|
e69dd5cb6a | ||
|
|
8acd57d87e |
@@ -40,3 +40,5 @@ fb168b0b86169219aa9b8e40f0caa6297cf34dbc 0.9.9-rc1
|
||||
a2b8f25fd17ed7424d1470a287d0b3144d2a12c8 1.0-rc6
|
||||
a3ca2e8e27c5c12c44ba0cacb4de4cb51377f184 1.0-rc7
|
||||
365e2514cc19f0366365318f12a1d63113b02924 1.0-rc8
|
||||
5da6fe43a8c29056bc9442c684615e11a3699795 1.0-rc9
|
||||
af490b8c30f83bc5fb6f3837a760981474647755 1.0-rc10
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
*** december 2011 ***
|
||||
|
||||
* 1.0 [20111230]
|
||||
|
||||
- adaptive process spawning (--cheaper option)
|
||||
- new control options --stop, --reload, --suspend, --resume, --pause
|
||||
- stats framework
|
||||
- new subscription system
|
||||
- support for mime types in static file serving
|
||||
- posix capablities support
|
||||
- uWSGI mules and farms
|
||||
- support for multiple --touch-reload options
|
||||
- new logging subsystem
|
||||
- new custom locking subsystem
|
||||
- process name handling
|
||||
- better (and faster) HTTP parser
|
||||
- perl and python threading improvements
|
||||
- new plugins: rrdtool, carbon, cgi, php
|
||||
- various improvements in the Rack/ruby plugin
|
||||
- Linux KSM support
|
||||
- refactored ping and nagios plugins
|
||||
- support for signals in lazy mode
|
||||
- optimized static-file serving
|
||||
- support for linux unshare()
|
||||
|
||||
*** august 2011 ***
|
||||
|
||||
* 0.9.9 [20110829]
|
||||
|
||||
@@ -27,7 +27,7 @@ plugins =
|
||||
bin_name = uwsgi
|
||||
append_version =
|
||||
plugin_dir = .
|
||||
embedded_plugins = python, ping, cache, nagios, rrdtool, carbon, rpc, fastrouter, http, ugreen, signal
|
||||
embedded_plugins = python, ping, cache, nagios, rrdtool, carbon, rpc, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket
|
||||
as_shared_library = false
|
||||
|
||||
locking = auto
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#include <Python.h>
|
||||
|
||||
void uwsgi_cgi_load_python() {
|
||||
|
||||
Py_Initialize();
|
||||
}
|
||||
|
||||
void uwsgi_cgi_run_python(char *filename) {
|
||||
|
||||
char **e, *p;
|
||||
PyObject *k, *env_value;
|
||||
|
||||
FILE *fp = fopen(filename, "r");
|
||||
|
||||
PySys_SetArgv(1, &filename);
|
||||
|
||||
PyObject *os_module = PyImport_ImportModule("os");
|
||||
if (os_module) {
|
||||
PyObject *os_module_dict = PyModule_GetDict(os_module);
|
||||
PyObject *py_environ = PyDict_GetItemString(os_module_dict, "environ");
|
||||
if (py_environ) {
|
||||
for (e = environ; *e != NULL; e++) {
|
||||
p = strchr(*e, '=');
|
||||
if (p == NULL) continue;
|
||||
|
||||
k = PyString_FromStringAndSize(*e, (int)(p-*e));
|
||||
if (k == NULL) {
|
||||
PyErr_Print();
|
||||
continue;
|
||||
}
|
||||
|
||||
env_value = PyString_FromString(p+1);
|
||||
if (env_value == NULL) {
|
||||
PyErr_Print();
|
||||
Py_DECREF(k);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PyObject_SetItem(py_environ, k, env_value)) {
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
Py_DECREF(k);
|
||||
Py_DECREF(env_value);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PyRun_AnyFileEx(fp, filename, 1);
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
import mmap
|
||||
import os
|
||||
import struct
|
||||
import array
|
||||
import time
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
class Cache:
|
||||
|
||||
def __init__(self, filename, cache_slots, block_size=65536, sample_sleep=1):
|
||||
|
||||
self.block_size = block_size
|
||||
self.cache_slots = cache_slots
|
||||
|
||||
self.key_size = 2048
|
||||
self.item_size = 2 + 2 + 4 + 8 + 8 + 8 + 8 + 8 + self.key_size
|
||||
self.block_size_start = self.item_size * self.cache_slots
|
||||
|
||||
fd = os.open(filename, os.O_RDONLY)
|
||||
self.cache_store = mmap.mmap(fd, 0, mmap.MAP_SHARED, mmap.PROT_READ)
|
||||
|
||||
self.sample_sleep = sample_sleep
|
||||
self.samples = 0
|
||||
self.history = []
|
||||
self.cache_full = 0
|
||||
self.cache_empty = 0
|
||||
self.cache_items = 0
|
||||
self.block_sizes = 0
|
||||
|
||||
def store_read_item_block(self, position):
|
||||
pos = self.cache_store.tell()
|
||||
# uwsgi cache stores cache entries first and then the blocks
|
||||
self.cache_store.seek(self.block_size_start + (position * self.block_size))
|
||||
buf = self.cache_store.read(self.block_size)
|
||||
self.cache_store.seek(pos)
|
||||
return buf
|
||||
|
||||
def store_read_item(self, position):
|
||||
buf = self.cache_store.read(self.item_size)
|
||||
fields = struct.unpack_from('@HHIQQQQQ2048c', buf)
|
||||
key = array.array('c', fields[8:self.key_size+8]).tostring().rstrip('\x00')
|
||||
|
||||
if [x for x in key if x!= '\x00']:
|
||||
buf = self.store_read_item_block(position)
|
||||
value = array.array('c', buf).tostring().rstrip('\x00')
|
||||
else:
|
||||
value = ''
|
||||
return (position, key, value, len(value))
|
||||
|
||||
def read(self):
|
||||
data = [self.store_read_item(i) for i in range(self.cache_slots)]
|
||||
self.cache_store.seek(0)
|
||||
self.update_stats(data)
|
||||
if self.sample_sleep:
|
||||
time.sleep(self.sample_sleep)
|
||||
return data
|
||||
|
||||
def update_stats(self, data):
|
||||
# data is a list of (position, key, value, len(value)) tuples
|
||||
items = len([1 for x in data if x[3] > 0])
|
||||
self.cache_items += items
|
||||
full, empty = items == self.cache_slots, items == 0
|
||||
if full:
|
||||
self.cache_full += 1
|
||||
if empty:
|
||||
self.cache_empty += 1
|
||||
self.samples += 1
|
||||
block_sizes = sum([x[3] for x in data])
|
||||
self.block_sizes += block_sizes
|
||||
self.history.append({'full': full, 'empty': empty, 'data': data, \
|
||||
'items': items, 'block_sizes': block_sizes})
|
||||
|
||||
def dump(self):
|
||||
return {
|
||||
'samples': self.samples,
|
||||
'history': self.history,
|
||||
'cache_slots': self.cache_slots,
|
||||
'sample_sleep': self.sample_sleep,
|
||||
'cache_empty': self.cache_empty,
|
||||
'cache_full': self.cache_full,
|
||||
'cache_items': self.cache_items,
|
||||
'block_sizes': self.block_sizes,
|
||||
}
|
||||
|
||||
def show_dump(self):
|
||||
d = self.dump()
|
||||
print
|
||||
print "Recorded %d samples (%d second(s) sleep between samples)" % \
|
||||
(d['samples'], d['sample_sleep'])
|
||||
print "Cache empty %d times, full %d times, %.2f items on average" % \
|
||||
(d['cache_empty'], d['cache_full'], d['cache_items'] / d['samples'])
|
||||
print "Block size average size: %d bytes" % \
|
||||
(d['block_sizes'] / d['cache_items'] * 8)
|
||||
print "Data in cache average: %d bytes" % \
|
||||
(d['block_sizes'] / d['samples'] * 8)
|
||||
|
||||
def main(options):
|
||||
cache = Cache(options.cache_store, options.cache_slots, options.block_size,
|
||||
options.sleep_time)
|
||||
print "Recording..."
|
||||
while True:
|
||||
try:
|
||||
data = cache.read()
|
||||
except KeyboardInterrupt:
|
||||
cache.show_dump()
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = OptionParser()
|
||||
parser.add_option("-s", "--cache-slots", dest="cache_slots", type="int",
|
||||
help="Slots available in the cache, uwsgi cache option")
|
||||
parser.add_option("-c", "--cache-store", dest="cache_store", default="uwsgi.cache",
|
||||
help="The filename of the cache store, uwsgi cache-store option. Default: uwsgi.cache")
|
||||
parser.add_option("-b", "--block-size", dest="block_size", default=65536, type="int",
|
||||
help="The size of the cache block, uwsgi cache-blocksize option. Default: 65536")
|
||||
parser.add_option("-t", "--sleep-time", dest="sleep_time", default=1, type="int",
|
||||
help="The time to sleep between each sample. Default: 1")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
if not options.cache_slots:
|
||||
parser.error('Option -s / --cache-slots is mandatory')
|
||||
main(options)
|
||||
@@ -314,7 +314,9 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size, ui
|
||||
break;
|
||||
}
|
||||
free(oe);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("putenv %s\n", ne);
|
||||
#endif
|
||||
|
||||
if (putenv(ne)) {
|
||||
uwsgi_error("putenv()");
|
||||
@@ -615,10 +617,8 @@ reconnect:
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (uwsgi.emperor_stats && uwsgi.emperor_stats_fd > -1) {
|
||||
if (interesting_fd == uwsgi.emperor_stats_fd) {
|
||||
emperor_send_stats(uwsgi.emperor_stats_fd);
|
||||
}
|
||||
else if (uwsgi.emperor_stats && uwsgi.emperor_stats_fd > -1 && interesting_fd == uwsgi.emperor_stats_fd) {
|
||||
emperor_send_stats(uwsgi.emperor_stats_fd);
|
||||
}
|
||||
else {
|
||||
ui_current = emperor_get_by_fd(interesting_fd);
|
||||
|
||||
@@ -224,3 +224,47 @@ void get_memusage(uint64_t *rss, uint64_t *vsz) {
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_register_logger(char *name, ssize_t (*func)(struct uwsgi_logger *, char *, size_t)) {
|
||||
|
||||
struct uwsgi_logger *ul = uwsgi.loggers, *old_ul;
|
||||
|
||||
if (!ul) {
|
||||
uwsgi.loggers = uwsgi_malloc(sizeof(struct uwsgi_logger));
|
||||
ul = uwsgi.loggers;
|
||||
}
|
||||
else {
|
||||
while(ul) {
|
||||
old_ul = ul;
|
||||
ul = ul->next;
|
||||
}
|
||||
|
||||
ul = uwsgi_malloc(sizeof(struct uwsgi_logger));
|
||||
old_ul->next = ul;
|
||||
}
|
||||
|
||||
ul->name = name;
|
||||
ul->func = func;
|
||||
ul->next = NULL;
|
||||
ul->configured = 0;
|
||||
ul->fd = -1;
|
||||
ul->data = NULL;
|
||||
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("[uwsgi-logger] registered \"%s\"\n", ul->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct uwsgi_logger *uwsgi_get_logger(char *name) {
|
||||
struct uwsgi_logger *ul = uwsgi.loggers;
|
||||
|
||||
while(ul) {
|
||||
if (!strcmp(ul->name, name)) {
|
||||
return ul;
|
||||
}
|
||||
ul = ul->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -330,6 +330,22 @@ void uwsgi_send_stats(int fd) {
|
||||
stats_send("\"cwd\": \"%s\",\n", cwd);
|
||||
free(cwd);
|
||||
|
||||
if (uwsgi.daemons) {
|
||||
fprintf(output, "\"daemons\": [\n");
|
||||
struct uwsgi_daemon *ud = uwsgi.daemons;
|
||||
while(ud) {
|
||||
fprintf(output, "\t{ \"cmd\": \"%s\", \"pid\": %d, \"respawns\": %llu }",
|
||||
ud->command, (int) ud->pid, (unsigned long long) ud->respawns-1);
|
||||
if (ud->next)
|
||||
fprintf(output, ",\n");
|
||||
else {
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
ud = ud->next;
|
||||
}
|
||||
fprintf(output, "],\n");
|
||||
}
|
||||
|
||||
fprintf(output, "\"workers\": [\n");
|
||||
|
||||
for (i = 0; i < uwsgi.numproc; i++) {
|
||||
|
||||
@@ -94,7 +94,9 @@ check:
|
||||
linkpath_buf[linkpath_size] = '\0';
|
||||
strcpy(linkpath, linkpath_buf);
|
||||
} while ((linkpath_size = readlink(linkpath, linkpath_buf, 1023)) > 0);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%s\n", linkpath);
|
||||
#endif
|
||||
free(plugin_entry_symbol);
|
||||
up = dlsym(plugin_handle, plugin_entry_symbol);
|
||||
char *slash = uwsgi_get_last_char(linkpath, '/');
|
||||
@@ -139,6 +141,9 @@ check:
|
||||
}
|
||||
free(plugin_name);
|
||||
free(plugin_entry_symbol);
|
||||
|
||||
if (up->on_load)
|
||||
up->on_load();
|
||||
return plugin_handle;
|
||||
}
|
||||
uwsgi_log( "%s\n", dlerror());
|
||||
|
||||
@@ -10,6 +10,7 @@ struct uwsgi_cgi {
|
||||
struct uwsgi_string_list *index;
|
||||
struct uwsgi_string_list *allowed_ext;
|
||||
struct uwsgi_string_list *unset;
|
||||
struct uwsgi_string_list *loadlib;
|
||||
int optimize;
|
||||
int has_mountpoints;
|
||||
struct uwsgi_dyn_dict *default_cgi;
|
||||
@@ -24,6 +25,7 @@ struct uwsgi_cgi {
|
||||
#define LONG_ARGS_CGI_INDEX LONG_ARGS_CGI_BASE + 5
|
||||
#define LONG_ARGS_CGI_ALLOWED_EXT LONG_ARGS_CGI_BASE + 6
|
||||
#define LONG_ARGS_CGI_UNSET LONG_ARGS_CGI_BASE + 7
|
||||
#define LONG_ARGS_CGI_LOADLIB LONG_ARGS_CGI_BASE + 8
|
||||
|
||||
struct option uwsgi_cgi_options[] = {
|
||||
|
||||
@@ -35,6 +37,7 @@ struct option uwsgi_cgi_options[] = {
|
||||
{"cgi-index", required_argument, 0, LONG_ARGS_CGI_INDEX},
|
||||
{"cgi-allowed-ext", required_argument, 0, LONG_ARGS_CGI_ALLOWED_EXT},
|
||||
{"cgi-unset", required_argument, 0, LONG_ARGS_CGI_UNSET},
|
||||
{"cgi-loadlib", required_argument, 0, LONG_ARGS_CGI_LOADLIB},
|
||||
{"cgi-optimize", no_argument, &uc.optimize, 1},
|
||||
{"cgi-optimized", no_argument, &uc.optimize, 1},
|
||||
{"cgi-path-info", no_argument, &uc.path_info, 1},
|
||||
@@ -150,9 +153,38 @@ void uwsgi_cgi_apps() {
|
||||
|
||||
int uwsgi_cgi_init(){
|
||||
|
||||
void (*cgi_sym)(void);
|
||||
|
||||
if (!uc.buffer_size) uc.buffer_size = 65536;
|
||||
if (!uc.timeout) uc.timeout = 60;
|
||||
|
||||
struct uwsgi_string_list *ll = uc.loadlib;
|
||||
while(ll) {
|
||||
char *colon = strchr(ll->value, ':');
|
||||
if (!colon) {
|
||||
uwsgi_log("invalid cgi-loadlib syntax, must be in the form lib:func\n");
|
||||
exit(1);
|
||||
}
|
||||
*colon = 0;
|
||||
void *cgi_lib = dlopen(ll->value, RTLD_NOW | RTLD_GLOBAL);
|
||||
if (!cgi_lib) {
|
||||
uwsgi_log( "cgi-loadlib: %s\n", dlerror());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cgi_sym = dlsym(cgi_lib, colon+1);
|
||||
if (!cgi_sym) {
|
||||
uwsgi_log("unknown symbol %s in lib %s\n", colon+1, ll->value);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cgi_sym();
|
||||
uwsgi_log("[cgi-loadlib] loaded symbol %s from %s\n", colon+1, ll->value);
|
||||
|
||||
*colon = ':';
|
||||
ll = ll->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
@@ -383,7 +415,7 @@ int uwsgi_cgi_walk(struct wsgi_request *wsgi_req, char *full_path, char *docroot
|
||||
// not a directory, stop walking
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
if (i < (wsgi_req->path_info_len-discard_base)-1) {
|
||||
*path_info = ptr + i + 1;
|
||||
*path_info = ptr + i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -704,6 +736,11 @@ clear:
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
|
||||
// for newer php
|
||||
if (setenv("REDIRECT_STATUS", "200", 0)) {
|
||||
uwsgi_error("setenv()");
|
||||
}
|
||||
|
||||
if (path_info && wsgi_req->path_info_len-discard_base > 0) {
|
||||
if (setenv("PATH_INFO", uwsgi_concat2n(path_info, wsgi_req->path_info_len-discard_base, "", 0), 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
@@ -769,6 +806,16 @@ clear:
|
||||
}
|
||||
|
||||
if (helper) {
|
||||
if (!uwsgi_starts_with(helper, strlen(helper), "sym://", 6)) {
|
||||
void (*cgi_func)(char *) = dlsym(RTLD_DEFAULT, helper+6);
|
||||
if (cgi_func) {
|
||||
cgi_func(command);
|
||||
}
|
||||
else {
|
||||
uwsgi_log("unable to find symbol %s\n", helper+6);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
argv[0] = helper;
|
||||
argv[1] = command;
|
||||
argv[2] = NULL;
|
||||
@@ -819,6 +866,9 @@ int uwsgi_cgi_manage_options(int i, char *optarg) {
|
||||
case LONG_ARGS_CGI_ALLOWED_EXT:
|
||||
uwsgi_string_new_list(&uc.allowed_ext, optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CGI_LOADLIB:
|
||||
uwsgi_string_new_list(&uc.loadlib, uwsgi_str(optarg));
|
||||
return 1;
|
||||
case LONG_ARGS_CGI_UNSET:
|
||||
uwsgi_string_new_list(&uc.unset, optarg);
|
||||
return 1;
|
||||
|
||||
@@ -40,7 +40,7 @@ extern "C" int uwsgi_cplusplus_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
fc = new FakeClass();
|
||||
// get PATH_INFO
|
||||
fc->foobar = uwsgi_get_var(wsgi_req, (char *) "PATH_INFO", &fc->foobar_len);
|
||||
fc->foobar = uwsgi_get_var(wsgi_req, (char *) "PATH_INFO", 9, &fc->foobar_len);
|
||||
|
||||
if (fc->foobar) {
|
||||
// send output
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define LONG_ARGS_FASTROUTER_USE_CODE_STRING 150008
|
||||
#define LONG_ARGS_FASTROUTER_TOLERANCE 150009
|
||||
#define LONG_ARGS_FASTROUTER_STATS 150010
|
||||
#define LONG_ARGS_FASTROUTER_ZERG 150011
|
||||
|
||||
#define FASTROUTER_STATUS_FREE 0
|
||||
#define FASTROUTER_STATUS_CONNECTING 1
|
||||
@@ -39,6 +40,7 @@ void fastrouter_send_stats(int);
|
||||
struct uwsgi_fastrouter_socket {
|
||||
char *name;
|
||||
int fd;
|
||||
char *zerg;
|
||||
struct uwsgi_fastrouter_socket *next;
|
||||
};
|
||||
|
||||
@@ -93,7 +95,7 @@ static void fastrouter_go_cheap(void) {
|
||||
}
|
||||
|
||||
|
||||
static struct uwsgi_fastrouter_socket *uwsgi_fastrouter_new_socket(char *name) {
|
||||
static struct uwsgi_fastrouter_socket *uwsgi_fastrouter_new_socket(char *name, int fd) {
|
||||
|
||||
struct uwsgi_fastrouter_socket *uwsgi_sock = ufr.sockets, *old_uwsgi_sock;
|
||||
|
||||
@@ -113,6 +115,12 @@ static struct uwsgi_fastrouter_socket *uwsgi_fastrouter_new_socket(char *name) {
|
||||
|
||||
memset(uwsgi_sock, 0, sizeof(struct uwsgi_fastrouter_socket));
|
||||
uwsgi_sock->name = name;
|
||||
if (name) {
|
||||
uwsgi_sock->fd = -1;
|
||||
}
|
||||
else {
|
||||
uwsgi_sock->fd = fd;
|
||||
}
|
||||
|
||||
return uwsgi_sock;
|
||||
}
|
||||
@@ -121,6 +129,7 @@ static struct uwsgi_fastrouter_socket *uwsgi_fastrouter_new_socket(char *name) {
|
||||
|
||||
struct option fastrouter_options[] = {
|
||||
{"fastrouter", required_argument, 0, LONG_ARGS_FASTROUTER},
|
||||
{"fastrouter-zerg", required_argument, 0, LONG_ARGS_FASTROUTER_ZERG},
|
||||
{"fastrouter-use-cache", no_argument, &ufr.use_cache, 1},
|
||||
{"fastrouter-use-pattern", required_argument, 0, LONG_ARGS_FASTROUTER_USE_PATTERN},
|
||||
{"fastrouter-use-base", required_argument, 0, LONG_ARGS_FASTROUTER_USE_BASE},
|
||||
@@ -194,7 +203,7 @@ static void close_session(struct fastrouter_session **fr_table, struct fastroute
|
||||
|
||||
close(fr_session->fd);
|
||||
fr_table[fr_session->fd] = NULL;
|
||||
if (fr_session->instance_fd != -1) {
|
||||
|
||||
if (ufr.subscriptions && fr_session->un && fr_session->un->len > 0) {
|
||||
// decrease reference count
|
||||
#ifdef UWSGI_DEBUG
|
||||
@@ -219,6 +228,8 @@ static void close_session(struct fastrouter_session **fr_table, struct fastroute
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (fr_session->instance_fd != -1) {
|
||||
close(fr_session->instance_fd);
|
||||
fr_table[fr_session->instance_fd] = NULL;
|
||||
}
|
||||
@@ -333,7 +344,10 @@ void fastrouter_loop() {
|
||||
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
|
||||
|
||||
while(ufr_sock) {
|
||||
if (ufr_sock->name[0] == '=') {
|
||||
if (ufr_sock->fd > -1) {
|
||||
ufr_sock->name = uwsgi_getsockname(ufr_sock->fd);
|
||||
}
|
||||
else if (ufr_sock->name[0] == '=') {
|
||||
int shared_socket = atoi(ufr_sock->name+1);
|
||||
if (shared_socket >= 0) {
|
||||
ufr_sock->fd = uwsgi_get_shared_socket_fd_by_num(shared_socket);
|
||||
@@ -352,7 +366,12 @@ void fastrouter_loop() {
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi_log("uwsgi fastrouter/proxy bound on %s\n", ufr_sock->name);
|
||||
if (ufr_sock->zerg) {
|
||||
uwsgi_log("uwsgi fastrouter/proxy bound on %s (from zerg server %s)\n", ufr_sock->name, ufr_sock->zerg);
|
||||
}
|
||||
else {
|
||||
uwsgi_log("uwsgi fastrouter/proxy bound on %s\n", ufr_sock->name);
|
||||
}
|
||||
|
||||
if (!ufr.cheap) {
|
||||
event_queue_add_fd_read(ufr.queue, ufr_sock->fd);
|
||||
@@ -792,10 +811,32 @@ int fastrouter_opt(int i, char *optarg) {
|
||||
char *cs;
|
||||
char *cs_code;
|
||||
char *cs_func;
|
||||
int zerg_fd;
|
||||
int *zerg;
|
||||
int j;
|
||||
struct uwsgi_fastrouter_socket *fr_sock;
|
||||
|
||||
switch(i) {
|
||||
case LONG_ARGS_FASTROUTER:
|
||||
uwsgi_fastrouter_new_socket(generate_socket_name(optarg));
|
||||
uwsgi_fastrouter_new_socket(generate_socket_name(optarg), -1);
|
||||
return 1;
|
||||
case LONG_ARGS_FASTROUTER_ZERG:
|
||||
zerg_fd = uwsgi_connect(optarg, 30, 0);
|
||||
if (zerg_fd < 0) {
|
||||
uwsgi_log("--- unable to connect to zerg server ---\n");
|
||||
exit(1);
|
||||
}
|
||||
zerg = uwsgi_attach_fd(zerg_fd, 8, "uwsgi-zerg", 11);
|
||||
if (zerg == NULL) {
|
||||
uwsgi_log("--- invalid data received from zerg-server ---\n");
|
||||
exit(1);
|
||||
}
|
||||
close(zerg_fd);
|
||||
for(j=0;j<8;j++) {
|
||||
if (zerg[j] == -1) break;
|
||||
fr_sock = uwsgi_fastrouter_new_socket(NULL, zerg[j]);
|
||||
fr_sock->zerg = optarg;
|
||||
}
|
||||
return 1;
|
||||
case LONG_ARGS_FASTROUTER_SUBSCRIPTION_SERVER:
|
||||
ufr.subscription_server = optarg;
|
||||
|
||||
@@ -58,14 +58,13 @@ void fiber_loop() {
|
||||
uwsgi.schedule_to_main = fiber_schedule_to_main;
|
||||
uwsgi.schedule_to_req = fiber_schedule_to_req;
|
||||
|
||||
// must run all the rack/ruby plugins without protection
|
||||
ur.unprotected = 1;
|
||||
|
||||
rb_protect(protected_async_loop, 0, &error);
|
||||
|
||||
if (error) {
|
||||
uwsgi_ruby_exception();
|
||||
exit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// never here
|
||||
|
||||
@@ -9,6 +9,7 @@ NAME='fiber'
|
||||
CFLAGS = os.popen(RUBYPATH + " -e \"require 'rbconfig';print Config::CONFIG['CFLAGS']\"").read().rstrip().split()
|
||||
|
||||
CFLAGS.append('-Wno-unused-parameter')
|
||||
CFLAGS.append('-DRUBY19')
|
||||
|
||||
includedir = os.popen(RUBYPATH + " -e \"require 'rbconfig';print Config::CONFIG['rubyhdrdir']\"").read().rstrip()
|
||||
if includedir == 'nil':
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
#include "../../uwsgi.h"
|
||||
#include <zlib.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
#define MAX_GELF 8192
|
||||
|
||||
struct graylog2_config {
|
||||
char *host;
|
||||
char json_buf[MAX_GELF];
|
||||
char escaped_buf[MAX_GELF];
|
||||
size_t escaped_len;
|
||||
char buffer[MAX_GELF];
|
||||
} g2c;
|
||||
|
||||
ssize_t uwsgi_graylog2_logger(struct uwsgi_logger *ul, char *message, size_t len) {
|
||||
|
||||
size_t i;
|
||||
|
||||
if (!ul->configured) {
|
||||
|
||||
if (!uwsgi.choosen_logger_arg) {
|
||||
uwsgi_log_safe("invalid graylog2 syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ul->fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (ul->fd < 0) {
|
||||
uwsgi_error_safe("socket()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_socket_nb(ul->fd);
|
||||
|
||||
char *comma = strchr(uwsgi.choosen_logger_arg, ',');
|
||||
if (!comma) {
|
||||
uwsgi_log_safe("invalid graylog2 syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
g2c.host = comma + 1;
|
||||
|
||||
*comma = 0;
|
||||
|
||||
char *colon = strchr(uwsgi.choosen_logger_arg, ':');
|
||||
if (!colon) {
|
||||
uwsgi_log_safe("invalid graylog2 syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ul->addr_len = socket_to_in_addr(uwsgi.choosen_logger_arg, colon, 0, &ul->addr.sa_in);
|
||||
|
||||
*comma = ',';
|
||||
|
||||
ul->configured = 1;
|
||||
}
|
||||
|
||||
g2c.escaped_len = 0;
|
||||
|
||||
int truncated = 0;
|
||||
char *ptr = g2c.escaped_buf;
|
||||
uLongf destLen = MAX_GELF;
|
||||
|
||||
for(i=0;i<len;i++) {
|
||||
if (message[i] == '\\') {
|
||||
*ptr ++= '\\';
|
||||
g2c.escaped_len++;
|
||||
}
|
||||
else if (message[i] == '"') {
|
||||
*ptr ++= '\\';
|
||||
g2c.escaped_len++;
|
||||
}
|
||||
*ptr ++= message[i];
|
||||
g2c.escaped_len++;
|
||||
|
||||
if (!truncated) {
|
||||
if (g2c.escaped_len == 128) {
|
||||
truncated = 1;
|
||||
}
|
||||
else if (g2c.escaped_len > 128) {
|
||||
truncated = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (truncated) truncated = 128 - (truncated-1);
|
||||
else (truncated = g2c.escaped_len);
|
||||
|
||||
int rlen = snprintf(g2c.json_buf, MAX_GELF, "{ \"version\": \"1.0\", \"host\": \"%s\", \"short_message\": \"%.*s\", \"full_message\": \"%.*s\", \"timestamp\": %d, \"level\": 5, \"facility\": \"uWSGI-%s\" }",
|
||||
g2c.host, truncated, g2c.escaped_buf, (int)g2c.escaped_len, g2c.escaped_buf, (int) time(NULL), UWSGI_VERSION);
|
||||
|
||||
if (rlen > 0) {
|
||||
if (compressBound((uLong) rlen) <= MAX_GELF) {
|
||||
if (compress((Bytef *) g2c.buffer, &destLen, (Bytef *) g2c.json_buf, (uLong) rlen) == Z_OK) {
|
||||
return sendto(ul->fd, g2c.buffer, destLen, 0, (const struct sockaddr *) &ul->addr, ul->addr_len);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void uwsgi_graylog2_register() {
|
||||
uwsgi_register_logger("graylog2", uwsgi_graylog2_logger);
|
||||
}
|
||||
|
||||
int uwsgi_graylog2_init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct uwsgi_plugin graylog2_plugin = {
|
||||
|
||||
.name = "graylog2",
|
||||
.on_load = uwsgi_graylog2_register,
|
||||
.init = uwsgi_graylog2_init
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='graylog2'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = ['-lz']
|
||||
GCC_LIST = ['graylog2_plugin']
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
ssize_t uwsgi_socket_logger(struct uwsgi_logger *ul, char *message, size_t len) {
|
||||
|
||||
int family = AF_UNIX;
|
||||
|
||||
if (!ul->configured) {
|
||||
|
||||
char *comma = strchr(uwsgi.choosen_logger_arg, ',');
|
||||
if (comma) {
|
||||
ul->data = comma+1;
|
||||
*comma = 0;
|
||||
}
|
||||
|
||||
char *colon = strchr(uwsgi.choosen_logger_arg, ':');
|
||||
if (colon) {
|
||||
family = AF_INET;
|
||||
ul->addr_len = socket_to_in_addr(uwsgi.choosen_logger_arg, colon, 0, &ul->addr.sa_in);
|
||||
}
|
||||
else {
|
||||
ul->addr_len = socket_to_un_addr(uwsgi.choosen_logger_arg, &ul->addr.sa_un);
|
||||
}
|
||||
|
||||
ul->fd = socket(family, SOCK_DGRAM, 0);
|
||||
if (ul->fd < 0) {
|
||||
uwsgi_error_safe("socket()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&ul->msg, 0, sizeof(struct msghdr));
|
||||
|
||||
ul->msg.msg_name = &ul->addr;
|
||||
ul->msg.msg_namelen = ul->addr_len;
|
||||
if (ul->data) {
|
||||
ul->msg.msg_iov = uwsgi_malloc(sizeof(struct iovec) * 2);
|
||||
ul->msg.msg_iov[0].iov_base = ul->data;
|
||||
ul->msg.msg_iov[0].iov_len = strlen(ul->data);
|
||||
ul->msg.msg_iovlen = 2;
|
||||
ul->count = 1;
|
||||
}
|
||||
else {
|
||||
ul->msg.msg_iov = uwsgi_malloc(sizeof(struct iovec));
|
||||
ul->msg.msg_iovlen = 1;
|
||||
}
|
||||
|
||||
if (comma) {
|
||||
*comma = ',' ;
|
||||
}
|
||||
|
||||
ul->configured = 1;
|
||||
}
|
||||
|
||||
|
||||
ul->msg.msg_iov[ul->count].iov_base = message;
|
||||
ul->msg.msg_iov[ul->count].iov_len = len;
|
||||
|
||||
return sendmsg(ul->fd, &ul->msg, 0);
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_logsocket_register() {
|
||||
uwsgi_register_logger("socket", uwsgi_socket_logger);
|
||||
}
|
||||
|
||||
int uwsgi_logsocket_init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct uwsgi_plugin logsocket_plugin = {
|
||||
|
||||
.name = "logsocket",
|
||||
.on_load = uwsgi_logsocket_register,
|
||||
.init = uwsgi_logsocket_init
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='logsocket'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
GCC_LIST = ['logsocket_plugin']
|
||||
@@ -0,0 +1,16 @@
|
||||
PHP_ARG_WITH(uwsgi,,
|
||||
[ --with-uwsgi=UWSGISRCDIR Build PHP as a uWSGI plugin (UNIX/POSIX only)], no, no)
|
||||
|
||||
AC_MSG_CHECKING([for UWSGI])
|
||||
if test "$PHP_UWSGI" != "no"; then
|
||||
|
||||
INSTALL_IT="\$(INSTALL) -m 0755 $SAPI_SHARED $PHP_UWSGI/php_plugin.so"
|
||||
|
||||
UWSGI_CFLAGS=`cd $PHP_UWSGI ; python uwsgiconfig.py --cflags`
|
||||
UWSGI_CFLAGS="$UWSGI_CFLAGS -I$PHP_UWSGI"
|
||||
|
||||
PHP_SELECT_SAPI(uwsgi, shared, php_plugin.c, $UWSGI_CFLAGS)
|
||||
AC_MSG_RESULT([$PHP_UWSGI])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
@@ -0,0 +1,494 @@
|
||||
#include "php.h"
|
||||
#include "SAPI.h"
|
||||
#include "php_main.h"
|
||||
#include "php_variables.h"
|
||||
|
||||
#include "ext/standard/php_smart_str.h"
|
||||
|
||||
#include <uwsgi.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
// http status codes list
|
||||
extern struct http_status_codes hsc[];
|
||||
|
||||
struct uwsgi_php {
|
||||
struct uwsgi_string_list *allowed_docroot;
|
||||
struct uwsgi_string_list *allowed_ext;
|
||||
} uphp;
|
||||
|
||||
#define LONG_ARGS_PHP_BASE 17000 + ((14 + 1) * 1000)
|
||||
#define LONG_ARGS_PHP_INI LONG_ARGS_PHP_BASE + 1
|
||||
#define LONG_ARGS_PHP_ALLOWED_DOCROOT LONG_ARGS_PHP_BASE + 2
|
||||
#define LONG_ARGS_PHP_ALLOWED_EXT LONG_ARGS_PHP_BASE + 3
|
||||
|
||||
struct option uwsgi_php_options[] = {
|
||||
|
||||
{"php-ini", required_argument, 0, LONG_ARGS_PHP_INI},
|
||||
{"php-config", required_argument, 0, LONG_ARGS_PHP_INI},
|
||||
{"php-allowed-docroot", required_argument, 0, LONG_ARGS_PHP_ALLOWED_DOCROOT},
|
||||
{"php-allowed-ext", required_argument, 0, LONG_ARGS_PHP_ALLOWED_EXT},
|
||||
{0, 0, 0, 0},
|
||||
|
||||
};
|
||||
|
||||
|
||||
static int sapi_uwsgi_ub_write(const char *str, uint str_length TSRMLS_DC)
|
||||
{
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);
|
||||
|
||||
ssize_t len = wsgi_req->socket->proto_write(wsgi_req, (char *) str, str_length);
|
||||
if (len != str_length) {
|
||||
php_handle_aborted_connection();
|
||||
return -1;
|
||||
}
|
||||
wsgi_req->response_size += len;
|
||||
return str_length;
|
||||
}
|
||||
|
||||
void uwsgi_php_404(struct wsgi_request *wsgi_req) {
|
||||
|
||||
wsgi_req->status = 404;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write(wsgi_req, "HTTP/1.0 404 Not Found\r\n\r\nNot Found", 35);
|
||||
}
|
||||
|
||||
void uwsgi_php_403(struct wsgi_request *wsgi_req) {
|
||||
|
||||
wsgi_req->status = 403;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write(wsgi_req, "HTTP/1.0 403 Forbidden\r\n\r\nForbidden", 35);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int sapi_uwsgi_send_headers(sapi_headers_struct *sapi_headers)
|
||||
{
|
||||
sapi_header_struct *h;
|
||||
zend_llist_position pos;
|
||||
struct iovec iov[6];
|
||||
char status[4];
|
||||
struct http_status_codes *http_sc;
|
||||
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);
|
||||
wsgi_req->status = SG(sapi_headers).http_response_code;
|
||||
if (!wsgi_req->status) wsgi_req->status = 200;
|
||||
|
||||
iov[0].iov_base = wsgi_req->protocol;
|
||||
iov[0].iov_len = wsgi_req->protocol_len;
|
||||
|
||||
|
||||
iov[1].iov_base = " ";
|
||||
iov[1].iov_len = 1;
|
||||
|
||||
uwsgi_num2str2n(wsgi_req->status, status, 4);
|
||||
|
||||
iov[2].iov_base = status;
|
||||
iov[2].iov_len = 3;
|
||||
|
||||
iov[3].iov_base = " ";
|
||||
iov[3].iov_len = 1;
|
||||
|
||||
// get the status code
|
||||
for (http_sc = hsc; http_sc->message != NULL; http_sc++) {
|
||||
if (!strncmp(http_sc->key, status, 3)) {
|
||||
iov[4].iov_base = (char *) http_sc->message;
|
||||
iov[4].iov_len = http_sc->message_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (iov[4].iov_len == 0) {
|
||||
iov[4].iov_base = "Unknown";
|
||||
iov[4].iov_len = 7;
|
||||
}
|
||||
|
||||
iov[5].iov_base = "\r\n";
|
||||
iov[5].iov_len = 2;
|
||||
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, iov, 6);
|
||||
|
||||
h = zend_llist_get_first_ex(&sapi_headers->headers, &pos);
|
||||
while (h) {
|
||||
iov[0].iov_base = h->header;
|
||||
iov[0].iov_len = h->header_len;
|
||||
iov[1].iov_base = "\r\n";
|
||||
iov[1].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, iov, 2);
|
||||
wsgi_req->header_cnt++;
|
||||
h = zend_llist_get_next_ex(&sapi_headers->headers, &pos);
|
||||
}
|
||||
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
|
||||
|
||||
return SAPI_HEADER_SENT_SUCCESSFULLY;
|
||||
}
|
||||
|
||||
static int sapi_uwsgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
|
||||
{
|
||||
uint read_bytes = 0;
|
||||
size_t len;
|
||||
int fd = -1;
|
||||
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);
|
||||
|
||||
if (wsgi_req->body_as_file) {
|
||||
fd = fileno((FILE *)wsgi_req->async_post);
|
||||
}
|
||||
else if (uwsgi.post_buffering > 0) {
|
||||
if (wsgi_req->post_cl > (size_t) uwsgi.post_buffering) {
|
||||
fd = fileno((FILE *)wsgi_req->async_post);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fd = wsgi_req->poll.fd;
|
||||
}
|
||||
|
||||
|
||||
count_bytes = MIN(count_bytes, wsgi_req->post_cl - SG(read_post_bytes));
|
||||
|
||||
// data in memory
|
||||
if (fd == -1) {
|
||||
if (count_bytes > 0) {
|
||||
memcpy(buffer, wsgi_req->post_buffering_buf + wsgi_req->post_pos, count_bytes);
|
||||
wsgi_req->post_pos += count_bytes;
|
||||
}
|
||||
return count_bytes;
|
||||
}
|
||||
|
||||
while (read_bytes < count_bytes) {
|
||||
len = read(fd, buffer + read_bytes, count_bytes - read_bytes);
|
||||
if (len <= 0) {
|
||||
break;
|
||||
}
|
||||
read_bytes += len;
|
||||
}
|
||||
|
||||
return read_bytes;
|
||||
}
|
||||
|
||||
|
||||
static char *sapi_uwsgi_read_cookies(void)
|
||||
{
|
||||
uint16_t len = 0;
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);
|
||||
|
||||
char *cookie = uwsgi_get_var(wsgi_req, (char *)"HTTP_COOKIE", 11, &len);
|
||||
if (cookie) {
|
||||
return estrndup(cookie, len);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void sapi_uwsgi_register_variables(zval *track_vars_array TSRMLS_DC)
|
||||
{
|
||||
int i;
|
||||
struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);
|
||||
php_import_environment_variables(track_vars_array TSRMLS_CC);
|
||||
|
||||
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
|
||||
php_register_variable_safe( estrndup(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len),
|
||||
wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len,
|
||||
track_vars_array TSRMLS_CC);
|
||||
}
|
||||
|
||||
php_register_variable_safe("PATH_INFO", wsgi_req->path_info, wsgi_req->path_info_len, track_vars_array TSRMLS_CC);
|
||||
|
||||
php_register_variable_safe("SCRIPT_NAME", wsgi_req->script_name, wsgi_req->script_name_len, track_vars_array TSRMLS_CC);
|
||||
php_register_variable_safe("SCRIPT_FILENAME", wsgi_req->file, wsgi_req->file_len, track_vars_array TSRMLS_CC);
|
||||
|
||||
|
||||
if (wsgi_req->path_info_len) {
|
||||
char *path_translated = ecalloc(1, (wsgi_req->file_len - wsgi_req->script_name_len) + wsgi_req->path_info_len + 1);
|
||||
|
||||
memcpy(path_translated, wsgi_req->file, (wsgi_req->file_len - wsgi_req->script_name_len));
|
||||
memcpy(path_translated + (wsgi_req->file_len - wsgi_req->script_name_len), wsgi_req->path_info, wsgi_req->path_info_len);
|
||||
php_register_variable_safe("PATH_TRANSLATED", path_translated, (wsgi_req->file_len - wsgi_req->script_name_len) + wsgi_req->path_info_len , track_vars_array TSRMLS_CC);
|
||||
}
|
||||
|
||||
php_register_variable_safe("PHP_SELF", wsgi_req->script_name, wsgi_req->script_name_len, track_vars_array TSRMLS_CC);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static sapi_module_struct uwsgi_sapi_module;
|
||||
|
||||
static int php_uwsgi_startup(sapi_module_struct *sapi_module)
|
||||
{
|
||||
if (php_module_startup(&uwsgi_sapi_module, NULL, 0)==FAILURE) {
|
||||
return FAILURE;
|
||||
} else {
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static void sapi_uwsgi_log_message(char *message) {
|
||||
|
||||
uwsgi_log(message);
|
||||
}
|
||||
|
||||
static sapi_module_struct uwsgi_sapi_module = {
|
||||
"uwsgi",
|
||||
"uWSGI/php",
|
||||
|
||||
php_uwsgi_startup,
|
||||
php_module_shutdown_wrapper,
|
||||
|
||||
NULL, /* activate */
|
||||
NULL, /* deactivate */
|
||||
|
||||
sapi_uwsgi_ub_write,
|
||||
NULL,
|
||||
NULL, /* get uid */
|
||||
NULL, /* getenv */
|
||||
|
||||
php_error,
|
||||
|
||||
NULL,
|
||||
sapi_uwsgi_send_headers,
|
||||
NULL,
|
||||
sapi_uwsgi_read_post,
|
||||
sapi_uwsgi_read_cookies,
|
||||
|
||||
sapi_uwsgi_register_variables,
|
||||
sapi_uwsgi_log_message, /* Log message */
|
||||
NULL, /* Get request time */
|
||||
NULL, /* Child terminate */
|
||||
|
||||
STANDARD_SAPI_MODULE_PROPERTIES
|
||||
};
|
||||
|
||||
int uwsgi_php_init(void) {
|
||||
|
||||
struct http_status_codes *http_sc;
|
||||
|
||||
sapi_startup(&uwsgi_sapi_module);
|
||||
uwsgi_sapi_module.startup(&uwsgi_sapi_module);
|
||||
|
||||
// filling http status codes
|
||||
for (http_sc = hsc; http_sc->message != NULL; http_sc++) {
|
||||
http_sc->message_size = strlen(http_sc->message);
|
||||
}
|
||||
|
||||
|
||||
uwsgi_log("PHP %s initialized\n", PHP_VERSION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_php_walk(struct wsgi_request *wsgi_req, char *full_path, char *docroot, size_t docroot_len, char **path_info) {
|
||||
|
||||
// and now start walking...
|
||||
uint16_t i;
|
||||
char *ptr = wsgi_req->path_info;
|
||||
char *dst = full_path+docroot_len;
|
||||
char *part = ptr;
|
||||
int part_size = 0;
|
||||
struct stat st;
|
||||
|
||||
if (ptr[0] == '/') part_size++;
|
||||
|
||||
for(i=0;i<wsgi_req->path_info_len;i++) {
|
||||
if (ptr[i] == '/') {
|
||||
memcpy(dst, part, part_size-1);
|
||||
*(dst+part_size-1) = 0;
|
||||
|
||||
if (stat(full_path, &st)) {
|
||||
uwsgi_php_404(wsgi_req);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// not a directory, stop walking
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
if (i < (wsgi_req->path_info_len)-1) {
|
||||
*path_info = ptr + i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// check for buffer overflow !!!
|
||||
*(dst+part_size-1) = '/';
|
||||
*(dst+part_size) = 0;
|
||||
|
||||
dst += part_size ;
|
||||
part_size = 0;
|
||||
part = ptr + i + 1;
|
||||
}
|
||||
|
||||
part_size++;
|
||||
}
|
||||
|
||||
if (part < wsgi_req->path_info+wsgi_req->path_info_len) {
|
||||
memcpy(dst, part, part_size-1);
|
||||
*(dst+part_size-1) = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_php_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
char real_filename[PATH_MAX+1];
|
||||
uint16_t docroot_len = 0;
|
||||
char *path_info = NULL;
|
||||
size_t real_filename_len = 0;
|
||||
|
||||
zend_file_handle file_handle;
|
||||
|
||||
SG(server_context) = (void *) wsgi_req;
|
||||
|
||||
if (uwsgi_parse_vars(wsgi_req)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *docroot = uwsgi_get_var(wsgi_req, (char *) "DOCUMENT_ROOT", 13, &docroot_len);
|
||||
|
||||
if (!docroot) {
|
||||
docroot = uwsgi.cwd;
|
||||
docroot_len = strlen(uwsgi.cwd);
|
||||
}
|
||||
|
||||
char *filename = uwsgi_concat4n(docroot, docroot_len, "/", 1, wsgi_req->path_info, wsgi_req->path_info_len, "", 0);
|
||||
|
||||
if (uwsgi_php_walk(wsgi_req, filename, docroot, docroot_len, &path_info)) {
|
||||
free(filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (path_info) {
|
||||
wsgi_req->path_info = path_info;
|
||||
wsgi_req->path_info_len = strlen(wsgi_req->path_info);
|
||||
}
|
||||
else {
|
||||
wsgi_req->path_info = "";
|
||||
wsgi_req->path_info_len = 0;
|
||||
}
|
||||
|
||||
|
||||
if (!realpath(filename, real_filename)) {
|
||||
free(filename);
|
||||
uwsgi_php_404(wsgi_req);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(filename);
|
||||
real_filename_len = strlen(real_filename);
|
||||
|
||||
if (uphp.allowed_docroot) {
|
||||
struct uwsgi_string_list *usl = uphp.allowed_docroot;
|
||||
while(usl) {
|
||||
if (!uwsgi_starts_with(real_filename, real_filename_len, usl->value, usl->len)) {
|
||||
goto secure;
|
||||
}
|
||||
usl = usl->next;
|
||||
}
|
||||
uwsgi_php_403(wsgi_req);
|
||||
uwsgi_log("PHP security error: %s is not under an allowed docroot\n", real_filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
secure:
|
||||
|
||||
if (uphp.allowed_ext) {
|
||||
struct uwsgi_string_list *usl = uphp.allowed_ext;
|
||||
while(usl) {
|
||||
if (real_filename_len >= usl->len) {
|
||||
if (!uwsgi_strncmp(real_filename+(real_filename_len-usl->len), usl->len, usl->value, usl->len)) {
|
||||
goto secure2;
|
||||
}
|
||||
}
|
||||
usl = usl->next;
|
||||
}
|
||||
uwsgi_php_403(wsgi_req);
|
||||
uwsgi_log("PHP security error: %s does not end with an allowed extension\n", real_filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
secure2:
|
||||
|
||||
wsgi_req->file = real_filename;
|
||||
wsgi_req->file_len = strlen(wsgi_req->file);
|
||||
|
||||
if (docroot[docroot_len-1] == '/') {
|
||||
wsgi_req->script_name = real_filename + (docroot_len-1);
|
||||
}
|
||||
else {
|
||||
wsgi_req->script_name = real_filename + docroot_len;
|
||||
}
|
||||
|
||||
wsgi_req->script_name_len = strlen(wsgi_req->script_name);
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("php filename = %s\n", real_filename);
|
||||
#endif
|
||||
|
||||
// now check for allowed paths and extensions
|
||||
|
||||
SG(request_info).request_uri = estrndup(wsgi_req->uri, wsgi_req->uri_len);
|
||||
SG(request_info).request_method = estrndup(wsgi_req->method, wsgi_req->method_len);
|
||||
SG(request_info).proto_num = 1001;
|
||||
|
||||
SG(request_info).query_string = estrndup(wsgi_req->query_string, wsgi_req->query_string_len);
|
||||
SG(request_info).content_length = wsgi_req->post_cl;
|
||||
SG(request_info).content_type = estrndup(wsgi_req->content_type, wsgi_req->content_type_len);
|
||||
|
||||
SG(request_info).path_translated = wsgi_req->file;
|
||||
|
||||
file_handle.type = ZEND_HANDLE_FILENAME;
|
||||
file_handle.filename = real_filename;
|
||||
file_handle.free_filename = 0;
|
||||
file_handle.opened_path = NULL;
|
||||
|
||||
|
||||
if (php_request_startup(TSRMLS_C) == FAILURE) {
|
||||
internal_server_error(wsgi_req, "unable to start php request");
|
||||
return -1;
|
||||
}
|
||||
|
||||
php_execute_script(&file_handle TSRMLS_CC);
|
||||
|
||||
php_request_shutdown(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uwsgi_php_after_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_LOGGING])
|
||||
log_request(wsgi_req);
|
||||
}
|
||||
|
||||
int uwsgi_php_manage_options(int i, char *optarg) {
|
||||
|
||||
switch(i) {
|
||||
case LONG_ARGS_PHP_INI:
|
||||
uwsgi_sapi_module.php_ini_path_override = uwsgi_str(optarg);
|
||||
uwsgi_sapi_module.php_ini_ignore = 1;
|
||||
return 1;
|
||||
case LONG_ARGS_PHP_ALLOWED_DOCROOT:
|
||||
uwsgi_string_new_list(&uphp.allowed_docroot, optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_PHP_ALLOWED_EXT:
|
||||
uwsgi_string_new_list(&uphp.allowed_ext, optarg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SAPI_API struct uwsgi_plugin php_plugin = {
|
||||
.modifier1 = 14,
|
||||
.init = uwsgi_php_init,
|
||||
.request = uwsgi_php_request,
|
||||
.after_request = uwsgi_php_after_request,
|
||||
.options = uwsgi_php_options,
|
||||
.manage_opt = uwsgi_php_manage_options,
|
||||
};
|
||||
|
||||
@@ -87,7 +87,7 @@ XS(XS_input_read) {
|
||||
}
|
||||
else if (uwsgi.post_buffering > 0) {
|
||||
fd = -1;
|
||||
if (wsgi_req->post_cl <= (size_t) uwsgi.post_buffering) {
|
||||
if (wsgi_req->post_cl > (size_t) uwsgi.post_buffering) {
|
||||
fd = fileno((FILE *)wsgi_req->async_post);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,6 +539,7 @@ PyObject *uwsgi_mount_loader(void *arg1) {
|
||||
|
||||
if ( !strcmp(what+strlen(what)-3, ".py") || !strcmp(what+strlen(what)-5, ".wsgi")) {
|
||||
callable = uwsgi_file_loader((void *)what);
|
||||
if (!callable) exit(1);
|
||||
}
|
||||
else if (!strcmp(what+strlen(what)-4, ".ini")) {
|
||||
callable = uwsgi_paste_loader((void *)what);
|
||||
@@ -605,30 +606,44 @@ PyObject *uwsgi_file_loader(void *arg1) {
|
||||
char *callable = up.callable;
|
||||
if (!callable) callable = "application";
|
||||
|
||||
wsgi_file_module = uwsgi_pyimport_by_filename(uwsgi_concat2("uwsgi_file_", uwsgi_pythonize(filename)), filename);
|
||||
char *py_filename = uwsgi_concat2("uwsgi_file_", uwsgi_pythonize(filename));
|
||||
|
||||
wsgi_file_module = uwsgi_pyimport_by_filename(py_filename, filename);
|
||||
if (!wsgi_file_module) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
free(py_filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wsgi_file_dict = PyModule_GetDict(wsgi_file_module);
|
||||
if (!wsgi_file_dict) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
Py_DECREF(wsgi_file_module);
|
||||
free(py_filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wsgi_file_callable = PyDict_GetItemString(wsgi_file_dict, callable);
|
||||
if (!wsgi_file_callable) {
|
||||
PyErr_Print();
|
||||
Py_DECREF(wsgi_file_dict);
|
||||
Py_DECREF(wsgi_file_module);
|
||||
free(py_filename);
|
||||
uwsgi_log( "unable to find \"application\" callable in file %s\n", filename);
|
||||
exit(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyFunction_Check(wsgi_file_callable) && !PyCallable_Check(wsgi_file_callable)) {
|
||||
uwsgi_log( "\"application\" must be a callable object in file %s\n", filename);
|
||||
exit(1);
|
||||
Py_DECREF(wsgi_file_callable);
|
||||
Py_DECREF(wsgi_file_dict);
|
||||
Py_DECREF(wsgi_file_module);
|
||||
free(py_filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(py_filename);
|
||||
|
||||
return wsgi_file_callable;
|
||||
|
||||
}
|
||||
|
||||
@@ -1097,6 +1097,9 @@ void uwsgi_python_enable_threads() {
|
||||
up.gil_get = gil_real_get;
|
||||
up.gil_release = gil_real_release;
|
||||
|
||||
up.swap_ts = simple_threaded_swap_ts;
|
||||
up.reset_ts = simple_threaded_reset_ts;
|
||||
|
||||
if (uwsgi.threads > 1) {
|
||||
up.swap_ts = threaded_swap_ts;
|
||||
up.reset_ts = threaded_reset_ts;
|
||||
|
||||
@@ -259,8 +259,10 @@ PyObject *uwsgi_pyimport_by_filename(char *, char *);
|
||||
|
||||
void threaded_swap_ts(struct wsgi_request *, struct uwsgi_app *);
|
||||
void simple_swap_ts(struct wsgi_request *, struct uwsgi_app *);
|
||||
void simple_threaded_swap_ts(struct wsgi_request *, struct uwsgi_app *);
|
||||
void threaded_reset_ts(struct wsgi_request *, struct uwsgi_app *);
|
||||
void simple_reset_ts(struct wsgi_request *, struct uwsgi_app *);
|
||||
void simple_threaded_reset_ts(struct wsgi_request *, struct uwsgi_app *);
|
||||
|
||||
int uwsgi_python_profiler_call(PyObject *, PyFrameObject *, int, PyObject *);
|
||||
|
||||
|
||||
@@ -599,3 +599,23 @@ void simple_swap_ts(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {
|
||||
PyThreadState_Swap(wi->interpreter);
|
||||
}
|
||||
}
|
||||
|
||||
void simple_threaded_reset_ts(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {
|
||||
if (uwsgi.single_interpreter == 0 && wi->interpreter != up.main_thread) {
|
||||
// restoring main interpreter
|
||||
UWSGI_GET_GIL
|
||||
PyThreadState_Swap(up.main_thread);
|
||||
UWSGI_RELEASE_GIL
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void simple_threaded_swap_ts(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {
|
||||
|
||||
if (uwsgi.single_interpreter == 0 && wi->interpreter != up.main_thread) {
|
||||
// set the interpreter
|
||||
UWSGI_GET_GIL
|
||||
PyThreadState_Swap(wi->interpreter);
|
||||
UWSGI_RELEASE_GIL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,6 +240,10 @@ int uwsgi_rack_init(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
VALUE uwsgi_rb_call_new(VALUE obj) {
|
||||
return rb_funcall(obj, rb_intern("new"), 0);
|
||||
}
|
||||
|
||||
void uwsgi_rack_init_apps(void) {
|
||||
|
||||
int error;
|
||||
@@ -275,6 +279,10 @@ void uwsgi_rack_init_apps(void) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!access("config.ru", R_OK)) {
|
||||
uwsgi_log("!!! a config.ru file has been found in yor rails app, please use --rack <configfile> instead of the old --rails <app> !!!\n");
|
||||
}
|
||||
|
||||
uwsgi_log("loading rails app %s\n", ur.rails);
|
||||
rb_protect( require_rails, 0, &error ) ;
|
||||
if (error) {
|
||||
@@ -298,7 +306,11 @@ void uwsgi_rack_init_apps(void) {
|
||||
}
|
||||
|
||||
if (acim_call == Qtrue) {
|
||||
ur.dispatcher = rb_funcall( ac_dispatcher, rb_intern("new"), 0);
|
||||
ur.dispatcher = rb_protect(uwsgi_rb_call_new, ac_dispatcher, &error);
|
||||
if (error) {
|
||||
uwsgi_ruby_exception();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +324,11 @@ void uwsgi_rack_init_apps(void) {
|
||||
VALUE thin_rack = rb_const_get(rb_cObject, rb_intern("Rack"));
|
||||
VALUE thin_rack_adapter = rb_const_get(thin_rack, rb_intern("Adapter"));
|
||||
VALUE thin_rack_adapter_rails = rb_const_get(thin_rack_adapter, rb_intern("Rails"));
|
||||
ur.dispatcher = rb_funcall( thin_rack_adapter_rails, rb_intern("new"), 0);
|
||||
ur.dispatcher = rb_protect( uwsgi_rb_call_new, thin_rack_adapter_rails, &error);
|
||||
if (error) {
|
||||
uwsgi_ruby_exception();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -574,7 +590,6 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
rb_hash_aset(env, rb_str_new2("rack.errors"), rb_funcall( rb_const_get(rb_cObject, rb_intern("IO")), rb_intern("new"), 2, INT2NUM(2), rb_str_new("w",1) ));
|
||||
|
||||
|
||||
ret = rb_protect( call_dispatch, env, &error);
|
||||
if (error) {
|
||||
uwsgi_ruby_exception();
|
||||
@@ -658,9 +673,14 @@ int uwsgi_rack_request(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
}
|
||||
else if (rb_respond_to( body, rb_intern("each") )) {
|
||||
rb_protect( iterate_body, body, &error);
|
||||
if (error) {
|
||||
uwsgi_ruby_exception();
|
||||
if (ur.unprotected) {
|
||||
iterate_body(body);
|
||||
}
|
||||
else {
|
||||
rb_protect( iterate_body, body, &error);
|
||||
if (error) {
|
||||
uwsgi_ruby_exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ struct uwsgi_rack {
|
||||
int rb_shell;
|
||||
int app_id;
|
||||
|
||||
int unprotected;
|
||||
|
||||
struct uwsgi_string_list *rbrequire;
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
#define MAX_SYSLOG_PKT 1024
|
||||
|
||||
ssize_t uwsgi_rsyslog_logger(struct uwsgi_logger *ul, char *message, size_t len) {
|
||||
|
||||
char buf[MAX_SYSLOG_PKT];
|
||||
time_t current_time;
|
||||
int portn = 514;
|
||||
int rlen;
|
||||
|
||||
if (!ul->configured) {
|
||||
|
||||
if (!uwsgi.choosen_logger_arg) {
|
||||
uwsgi_log_safe("invalid rsyslog syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ul->fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (ul->fd < 0) {
|
||||
uwsgi_error_safe("socket()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_socket_nb(ul->fd);
|
||||
|
||||
char *comma = strchr(uwsgi.choosen_logger_arg, ',');
|
||||
if (comma) {
|
||||
ul->data = comma+1;
|
||||
*comma = 0;
|
||||
}
|
||||
else {
|
||||
ul->data = uwsgi_concat2(uwsgi.hostname," uwsgi");
|
||||
}
|
||||
|
||||
|
||||
char *port = strchr(uwsgi.choosen_logger_arg, ':');
|
||||
if (port) {
|
||||
portn = atoi(port+1);
|
||||
*port = 0;
|
||||
}
|
||||
|
||||
ul->addr_len = socket_to_in_addr(uwsgi.choosen_logger_arg, NULL, portn, &ul->addr.sa_in);
|
||||
|
||||
if (port) *port = ':';
|
||||
if (comma) *comma = ',';
|
||||
|
||||
ul->configured = 1;
|
||||
}
|
||||
|
||||
|
||||
current_time = time(NULL);
|
||||
|
||||
// drop newline
|
||||
if (message[len-1] == '\n') len--;
|
||||
|
||||
rlen = snprintf(buf, MAX_SYSLOG_PKT, "<29>%.*s %s: %.*s", 15, ctime(¤t_time)+4, (char *) ul->data, (int) len, message);
|
||||
if (rlen > 0) {
|
||||
return sendto(ul->fd, buf, rlen, 0, (const struct sockaddr *) &ul->addr, ul->addr_len);
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_rsyslog_register() {
|
||||
uwsgi_register_logger("rsyslog", uwsgi_rsyslog_logger);
|
||||
}
|
||||
|
||||
int uwsgi_rsyslog_init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct uwsgi_plugin rsyslog_plugin = {
|
||||
|
||||
.name = "rsyslog",
|
||||
.on_load = uwsgi_rsyslog_register,
|
||||
.init = uwsgi_rsyslog_init
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='rsyslog'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
GCC_LIST = ['rsyslog_plugin']
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
ssize_t uwsgi_syslog_logger(struct uwsgi_logger *ul, char *message, size_t len) {
|
||||
|
||||
char *syslog_opts;
|
||||
|
||||
if (!ul->configured) {
|
||||
|
||||
setlinebuf(stderr);
|
||||
|
||||
if (uwsgi.choosen_logger_arg == NULL) {
|
||||
syslog_opts = "uwsgi";
|
||||
}
|
||||
else {
|
||||
syslog_opts = uwsgi.choosen_logger_arg;
|
||||
}
|
||||
|
||||
openlog(syslog_opts, 0, LOG_DAEMON);
|
||||
|
||||
ul->configured = 1;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "%.*s", (int) len, message);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_syslog_register() {
|
||||
uwsgi_register_logger("syslog", uwsgi_syslog_logger);
|
||||
}
|
||||
|
||||
int uwsgi_syslog_init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct uwsgi_plugin syslog_plugin = {
|
||||
|
||||
.name = "syslog",
|
||||
.on_load = uwsgi_syslog_register,
|
||||
.init = uwsgi_syslog_init
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
NAME='syslog'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
GCC_LIST = ['syslog_plugin']
|
||||
+122
-105
@@ -865,69 +865,67 @@ next:
|
||||
|
||||
|
||||
// check for static files
|
||||
if (wsgi_req->path_info_len > 1) {
|
||||
|
||||
// skip extensions
|
||||
struct uwsgi_string_list *sse = uwsgi.static_skip_ext;
|
||||
while(sse) {
|
||||
if (wsgi_req->path_info_len >= sse->len) {
|
||||
if (!uwsgi_strncmp(wsgi_req->path_info+(wsgi_req->path_info_len - sse->len), sse->len, sse->value, sse->len)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sse = sse->next;
|
||||
// skip extensions
|
||||
struct uwsgi_string_list *sse = uwsgi.static_skip_ext;
|
||||
while(sse) {
|
||||
if (wsgi_req->path_info_len >= sse->len) {
|
||||
if (!uwsgi_strncmp(wsgi_req->path_info+(wsgi_req->path_info_len - sse->len), sse->len, sse->value, sse->len)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// check if a file named uwsgi.check_static+env['PATH_INFO'] exists
|
||||
udd = uwsgi.check_static;
|
||||
while(udd) {
|
||||
// need to build the path ?
|
||||
if (udd->value == NULL) {
|
||||
sse = sse->next;
|
||||
}
|
||||
// check if a file named uwsgi.check_static+env['PATH_INFO'] exists
|
||||
udd = uwsgi.check_static;
|
||||
while(udd) {
|
||||
// need to build the path ?
|
||||
if (udd->value == NULL) {
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.lock_static);
|
||||
if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.lock_static);
|
||||
#endif
|
||||
udd->value = realpath(udd->key, NULL);
|
||||
udd->value = realpath(udd->key, NULL);
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.lock_static);
|
||||
if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.lock_static);
|
||||
#endif
|
||||
if (!udd->value) goto nextcs;
|
||||
udd->vallen = strlen(udd->value);
|
||||
}
|
||||
if (!udd->value) goto nextcs;
|
||||
udd->vallen = strlen(udd->value);
|
||||
}
|
||||
|
||||
if (!uwsgi_file_serve(wsgi_req, udd->value, udd->vallen, wsgi_req->path_info, wsgi_req->path_info_len)) {
|
||||
if (!uwsgi_file_serve(wsgi_req, udd->value, udd->vallen, wsgi_req->path_info, wsgi_req->path_info_len)) {
|
||||
return -1;
|
||||
}
|
||||
nextcs:
|
||||
udd = udd->next;
|
||||
}
|
||||
|
||||
// check static-map
|
||||
udd = uwsgi.static_maps;
|
||||
while(udd) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("checking for %.*s <-> %.*s\n", wsgi_req->path_info_len, wsgi_req->path_info, udd->keylen, udd->key);
|
||||
#endif
|
||||
if (udd->status == 0) {
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.lock_static);
|
||||
#endif
|
||||
char *real_docroot = realpath(udd->value, NULL);
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.lock_static);
|
||||
#endif
|
||||
if (!real_docroot) goto nextsm;
|
||||
udd->value = real_docroot;
|
||||
udd->vallen = strlen(udd->value);
|
||||
udd->status = 1;
|
||||
}
|
||||
|
||||
if (!uwsgi_starts_with(wsgi_req->path_info, wsgi_req->path_info_len, udd->key, udd->keylen)) {
|
||||
if (!uwsgi_file_serve(wsgi_req, udd->value, udd->vallen, wsgi_req->path_info+udd->keylen, wsgi_req->path_info_len-udd->keylen)) {
|
||||
return -1;
|
||||
}
|
||||
nextcs:
|
||||
udd = udd->next;
|
||||
}
|
||||
|
||||
// check static-map
|
||||
udd = uwsgi.static_maps;
|
||||
while(udd) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("checking for %.*s <-> %.*s\n", wsgi_req->path_info_len, wsgi_req->path_info, udd->keylen, udd->key);
|
||||
#endif
|
||||
if (udd->status == 0) {
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.lock_static);
|
||||
#endif
|
||||
char *real_docroot = realpath(udd->value, NULL);
|
||||
#ifdef UWSGI_THREADING
|
||||
if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.lock_static);
|
||||
#endif
|
||||
if (!real_docroot) goto nextsm;
|
||||
udd->value = real_docroot;
|
||||
udd->vallen = strlen(udd->value);
|
||||
udd->status = 1;
|
||||
}
|
||||
|
||||
if (!uwsgi_starts_with(wsgi_req->path_info, wsgi_req->path_info_len, udd->key, udd->keylen)) {
|
||||
if (!uwsgi_file_serve(wsgi_req, udd->value, udd->vallen, wsgi_req->path_info+udd->keylen, wsgi_req->path_info_len-udd->keylen)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
nextsm:
|
||||
udd = udd->next;
|
||||
}
|
||||
udd = udd->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1485,13 +1483,66 @@ char *uwsgi_get_mime_type(char *name, int namelen, int *size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int uwsgi_append_static_path(char *dir, char *file, int file_len) {
|
||||
|
||||
size_t len = strlen(dir);
|
||||
|
||||
if (len + 1 + file_len > PATH_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dir[len-1] == '/') {
|
||||
memcpy(dir+len, file, file_len);
|
||||
dir[len+file_len] = 0;
|
||||
}
|
||||
else {
|
||||
dir[len] = '/';
|
||||
memcpy(dir+len+1, file, file_len);
|
||||
dir[len+1+file_len] = 0;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int uwsgi_static_stat(char *filename, struct stat *st) {
|
||||
|
||||
int ret = stat(filename, st);
|
||||
// if non-existant return -1
|
||||
if (ret < 0) return -1;
|
||||
|
||||
if (S_ISREG(st->st_mode)) return 0;
|
||||
|
||||
// check for index
|
||||
if (S_ISDIR(st->st_mode)) {
|
||||
struct uwsgi_string_list *usl = uwsgi.static_index;
|
||||
while(usl) {
|
||||
ret = uwsgi_append_static_path(filename, usl->value, usl->len);
|
||||
if (ret >= 0) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("checking for %s\n", filename);
|
||||
#endif
|
||||
if (!uwsgi_static_stat(filename, st)) {
|
||||
return 0;
|
||||
}
|
||||
// reset to original name
|
||||
filename[ret] = 0;
|
||||
}
|
||||
usl = usl->next;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_t document_root_len, char *path_info, uint16_t path_info_len) {
|
||||
|
||||
struct stat st;
|
||||
struct iovec headers_vec[8];
|
||||
char real_filename[PATH_MAX];
|
||||
char *filename = uwsgi_concat3n(document_root, document_root_len, "/", 1, path_info, path_info_len);
|
||||
char real_filename[PATH_MAX+1];
|
||||
char content_length[sizeof(UMAX64_STR)+1];
|
||||
size_t real_filename_len = 0;
|
||||
|
||||
char *filename = uwsgi_concat3n(document_root, document_root_len, "/", 1, path_info, path_info_len);
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("[uwsgi-fileserve] checking for %s\n", filename);
|
||||
@@ -1511,9 +1562,11 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!stat(real_filename, &st)) {
|
||||
if (!uwsgi_static_stat(real_filename, &st)) {
|
||||
int mime_type_size = 0;
|
||||
char *mime_type = uwsgi_get_mime_type(path_info, path_info_len, &mime_type_size);
|
||||
char http_last_modified[49];
|
||||
real_filename_len = strlen(real_filename);
|
||||
char *mime_type = uwsgi_get_mime_type(real_filename, real_filename_len, &mime_type_size);
|
||||
if (wsgi_req->if_modified_since_len) {
|
||||
time_t ims = parse_http_date(wsgi_req->if_modified_since, wsgi_req->if_modified_since_len);
|
||||
if (st.st_mtime <= ims) {
|
||||
@@ -1540,18 +1593,16 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
|
||||
char http_last_modified[49];
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("[uwsgi-fileserve] file %s found\n", real_filename);
|
||||
uwsgi_log("[uwsgi-fileserve] file %s found\n", real_filename);
|
||||
#endif
|
||||
|
||||
// HTTP status
|
||||
headers_vec[0].iov_base = wsgi_req->protocol;
|
||||
headers_vec[0].iov_len = wsgi_req->protocol_len;
|
||||
headers_vec[1].iov_base = " 200 OK\r\n";
|
||||
headers_vec[1].iov_len = 9;
|
||||
wsgi_req->headers_size = wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 2);
|
||||
// HTTP status
|
||||
headers_vec[0].iov_base = wsgi_req->protocol;
|
||||
headers_vec[0].iov_len = wsgi_req->protocol_len;
|
||||
headers_vec[1].iov_base = " 200 OK\r\n";
|
||||
headers_vec[1].iov_len = 9;
|
||||
wsgi_req->headers_size = wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 2);
|
||||
|
||||
// uWSGI additional headers
|
||||
struct uwsgi_string_list *ah = uwsgi.additional_headers;
|
||||
@@ -1580,18 +1631,9 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
// nginx
|
||||
if (uwsgi.file_serve_mode == 1) {
|
||||
headers_vec[0].iov_base = "X-Accel-Redirect: "; headers_vec[0].iov_len = 18 ;
|
||||
headers_vec[1].iov_base = document_root; headers_vec[1].iov_len = document_root_len;
|
||||
if (document_root[document_root_len-1] != '/') {
|
||||
headers_vec[2].iov_base = "/"; headers_vec[2].iov_len = 1;
|
||||
headers_vec[3].iov_base = path_info; headers_vec[3].iov_len = path_info_len;
|
||||
headers_vec[4].iov_base = "\r\n"; headers_vec[4].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 5);
|
||||
}
|
||||
else {
|
||||
headers_vec[2].iov_base = path_info; headers_vec[2].iov_len = path_info_len;
|
||||
headers_vec[3].iov_base = "\r\n"; headers_vec[3].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 4);
|
||||
}
|
||||
headers_vec[1].iov_base = real_filename; headers_vec[1].iov_len = real_filename_len;
|
||||
headers_vec[2].iov_base = "\r\n"; headers_vec[2].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 3);
|
||||
// this is the final header (\r\n added)
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
|
||||
@@ -1600,18 +1642,9 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
// apache
|
||||
else if (uwsgi.file_serve_mode == 2) {
|
||||
headers_vec[0].iov_base = "X-Sendfile: "; headers_vec[0].iov_len = 12 ;
|
||||
headers_vec[1].iov_base = document_root; headers_vec[1].iov_len = document_root_len;
|
||||
if (document_root[document_root_len-1] != '/') {
|
||||
headers_vec[2].iov_base = "/"; headers_vec[2].iov_len = 1;
|
||||
headers_vec[3].iov_base = path_info; headers_vec[3].iov_len = path_info_len;
|
||||
headers_vec[4].iov_base = "\r\n"; headers_vec[4].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 5);
|
||||
}
|
||||
else {
|
||||
headers_vec[2].iov_base = path_info; headers_vec[2].iov_len = path_info_len;
|
||||
headers_vec[3].iov_base = "\r\n"; headers_vec[3].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 4);
|
||||
}
|
||||
headers_vec[1].iov_base = real_filename; headers_vec[1].iov_len = real_filename_len;
|
||||
headers_vec[2].iov_base = "\r\n"; headers_vec[2].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 3);
|
||||
// this is the final header (\r\n added)
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
|
||||
@@ -1641,24 +1674,8 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
|
||||
wsgi_req->status = 200;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
char *uwsgi_get_var(struct wsgi_request *wsgi_req, char *key, uint16_t *len) {
|
||||
|
||||
int i;
|
||||
*len = 0;
|
||||
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
|
||||
if (!uwsgi_strncmp(key, strlen(key), wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len)) {
|
||||
*len = wsgi_req->hvec[i + 1].iov_len;
|
||||
return wsgi_req->hvec[i + 1].iov_base;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,43 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
char *uwsgi_getsockname(int fd) {
|
||||
|
||||
socklen_t socket_type_len = sizeof(struct sockaddr_un);
|
||||
union uwsgi_sockaddr usa;
|
||||
union uwsgi_sockaddr_ptr gsa;
|
||||
char computed_port[6];
|
||||
char ipv4a[INET_ADDRSTRLEN + 1];
|
||||
|
||||
gsa.sa = (struct sockaddr *) &usa;
|
||||
|
||||
if (!getsockname(fd, gsa.sa, &socket_type_len)) {
|
||||
if (gsa.sa->sa_family == AF_UNIX) {
|
||||
if (usa.sa_un.sun_path[0] == 0) {
|
||||
return uwsgi_concat2("@", usa.sa_un.sun_path+1);
|
||||
}
|
||||
else {
|
||||
return uwsgi_str(usa.sa_un.sun_path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
memset(ipv4a, 0, INET_ADDRSTRLEN + 1);
|
||||
memset(computed_port, 0, 6);
|
||||
if (snprintf(computed_port, 6, "%d", ntohs(gsa.sa_in->sin_port)) > 0) {
|
||||
if (inet_ntop(AF_INET, (const void *) &gsa.sa_in->sin_addr.s_addr, ipv4a, INET_ADDRSTRLEN)) {
|
||||
if (!strcmp("0.0.0.0", ipv4a)) {
|
||||
return uwsgi_concat2(":", computed_port);
|
||||
}
|
||||
else {
|
||||
return uwsgi_concat3(ipv4a, ":", computed_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abstract_socket) {
|
||||
|
||||
int serverfd;
|
||||
@@ -460,15 +497,18 @@ socklen_t socket_to_un_addr(char *socket_name, struct sockaddr_un *sun_addr) {
|
||||
return sizeof(sun_addr->sun_family)+len;
|
||||
}
|
||||
|
||||
socklen_t socket_to_in_addr(char *socket_name, char *port, struct sockaddr_in *sin_addr) {
|
||||
socklen_t socket_to_in_addr(char *socket_name, char *port, int portn, struct sockaddr_in *sin_addr) {
|
||||
|
||||
memset(sin_addr, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
sin_addr->sin_family = AF_INET;
|
||||
if (port) {
|
||||
port[0] = 0;
|
||||
*port = 0;
|
||||
sin_addr->sin_port = htons(atoi(port + 1));
|
||||
}
|
||||
else {
|
||||
sin_addr->sin_port = htons(portn);
|
||||
}
|
||||
|
||||
if (socket_name[0] == 0) {
|
||||
sin_addr->sin_addr.s_addr = INADDR_ANY;
|
||||
@@ -483,6 +523,10 @@ socklen_t socket_to_in_addr(char *socket_name, char *port, struct sockaddr_in *s
|
||||
}
|
||||
}
|
||||
|
||||
if (port) {
|
||||
*port = ':';
|
||||
}
|
||||
|
||||
return sizeof(struct sockaddr_in);
|
||||
|
||||
}
|
||||
@@ -493,7 +537,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
struct sockaddr_in uws_addr;
|
||||
int reuse = 1;
|
||||
|
||||
socket_to_in_addr(socket_name, tcp_port, &uws_addr);
|
||||
socket_to_in_addr(socket_name, tcp_port, 0, &uws_addr);
|
||||
|
||||
serverfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (serverfd < 0) {
|
||||
|
||||
@@ -275,49 +275,46 @@ void logto(char *logfile) {
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
void log_zeromq(char *node) {
|
||||
ssize_t uwsgi_zeromq_logger(struct uwsgi_logger *ul, char *message, size_t len) {
|
||||
|
||||
void *ctx = zmq_init(1);
|
||||
if (ctx == NULL) {
|
||||
uwsgi_error("zmq_init()");
|
||||
exit(1);
|
||||
if (!ul->configured) {
|
||||
|
||||
if (!uwsgi.choosen_logger_arg) {
|
||||
uwsgi_log_safe("invalid zeromq syntax\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void *ctx = zmq_init(1);
|
||||
if (ctx == NULL) {
|
||||
uwsgi_error_safe("zmq_init()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ul->data = zmq_socket(ctx, ZMQ_PUSH);
|
||||
if (ul->data == NULL) {
|
||||
uwsgi_error_safe("zmq_socket()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (zmq_connect(ul->data, uwsgi.choosen_logger_arg) < 0) {
|
||||
uwsgi_error_safe("zmq_connect()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ul->configured = 1;
|
||||
}
|
||||
|
||||
zmq_msg_t msg;
|
||||
if (zmq_msg_init_size (&msg, len) == 0) {
|
||||
memcpy(zmq_msg_data(&msg), message, len);
|
||||
zmq_send(ul->data, &msg, 0);
|
||||
zmq_msg_close(&msg);
|
||||
}
|
||||
|
||||
uwsgi.zmq_log_socket = zmq_socket(ctx, ZMQ_PUSH);
|
||||
if (uwsgi.zmq_log_socket == NULL) {
|
||||
uwsgi_error("zmq_socket()");
|
||||
exit(1);
|
||||
}
|
||||
if (zmq_connect(uwsgi.zmq_log_socket, node) < 0) {
|
||||
uwsgi_error("zmq_connect()");
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void log_socket(char *socket_name) {
|
||||
|
||||
int family = AF_UNIX;
|
||||
|
||||
uwsgi.log_socket_addr = uwsgi_malloc(sizeof(union uwsgi_sockaddr));
|
||||
|
||||
char *colon = strchr(socket_name, ':');
|
||||
if (colon) {
|
||||
family = AF_INET;
|
||||
uwsgi.log_socket_size = socket_to_in_addr(socket_name, colon, &uwsgi.log_socket_addr->sa_in);
|
||||
}
|
||||
else {
|
||||
uwsgi.log_socket_size = socket_to_un_addr(socket_name, &uwsgi.log_socket_addr->sa_un);
|
||||
}
|
||||
|
||||
uwsgi.log_socket_fd = socket(family, SOCK_DGRAM, 0);
|
||||
if (uwsgi.log_socket_fd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void create_logpipe(void) {
|
||||
|
||||
#if defined(SOCK_SEQPACKET) && defined(__linux__)
|
||||
@@ -346,22 +343,6 @@ void create_logpipe(void) {
|
||||
|
||||
}
|
||||
|
||||
void log_syslog(char *syslog_opts) {
|
||||
|
||||
setlinebuf(stderr);
|
||||
|
||||
if (syslog_opts == NULL) {
|
||||
syslog_opts = "uwsgi";
|
||||
}
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("opening syslog\n");
|
||||
#endif
|
||||
|
||||
openlog(syslog_opts, 0, LOG_DAEMON);
|
||||
|
||||
}
|
||||
|
||||
char *uwsgi_get_cwd() {
|
||||
|
||||
// set this to static to avoid useless reallocations in stats mode
|
||||
@@ -518,7 +499,7 @@ void uwsgi_as_root() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) && !defined(OBSOLETE_LINUX_KERNEL)
|
||||
if (uwsgi.unshare && !uwsgi.reloads) {
|
||||
|
||||
if (unshare(uwsgi.unshare)) {
|
||||
@@ -1118,7 +1099,7 @@ void parse_sys_envs(char **envs) {
|
||||
char *earg, *eq_pos;
|
||||
|
||||
while (*uenvs) {
|
||||
if (!strncmp(*uenvs, "UWSGI_", 6) && strncmp(*uenvs, "UWSGI_RELOADS=", 14)) {
|
||||
if (!strncmp(*uenvs, "UWSGI_", 6) && strncmp(*uenvs, "UWSGI_RELOADS=", 14) && strncmp(*uenvs, "UWSGI_ORIGINAL_PROC_NAME=", 25)) {
|
||||
earg = uwsgi_malloc(strlen(*uenvs + 6) + 1);
|
||||
env_to_arg(*uenvs + 6, earg);
|
||||
eq_pos = strchr(earg, '=');
|
||||
@@ -3233,6 +3214,9 @@ static struct uwsgi_unshare_id uwsgi_unshare_list[] = {
|
||||
#ifdef CLONE_NEWNET
|
||||
{"net", CLONE_NEWNET},
|
||||
#endif
|
||||
#ifdef CLONE_NEWPID
|
||||
{"pid", CLONE_NEWPID},
|
||||
#endif
|
||||
#ifdef CLONE_NEWNS
|
||||
{"ns", CLONE_NEWNS},
|
||||
{"mount", CLONE_NEWNS},
|
||||
@@ -3569,6 +3553,20 @@ void http_url_decode(char *buf, uint16_t *len, char *dst) {
|
||||
|
||||
}
|
||||
|
||||
char *uwsgi_get_var(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *len) {
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
|
||||
if (!uwsgi_strncmp(key, keylen, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len)) {
|
||||
*len = wsgi_req->hvec[i + 1].iov_len;
|
||||
return wsgi_req->hvec[i + 1].iov_base;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void uwsgi_add_app(int id, uint8_t modifier1, char *mountpoint, int mountpoint_len) {
|
||||
|
||||
struct uwsgi_app *wi = &uwsgi_apps[id];
|
||||
|
||||
@@ -231,6 +231,8 @@ static struct option long_base_options[] = {
|
||||
{"logfile-chmod", required_argument, 0, LONG_ARGS_LOGFILE_CHMOD},
|
||||
{"log-syslog", optional_argument, 0, LONG_ARGS_LOG_SYSLOG},
|
||||
{"log-socket", required_argument, 0, LONG_ARGS_LOG_SOCKET},
|
||||
{"logger", required_argument, 0, LONG_ARGS_LOGGER},
|
||||
{"threaded-logger", no_argument, &uwsgi.threaded_logger, 1},
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
{"log-zeromq", required_argument, 0, LONG_ARGS_LOG_ZEROMQ},
|
||||
#endif
|
||||
@@ -256,6 +258,7 @@ static struct option long_base_options[] = {
|
||||
{"lazy", no_argument, &uwsgi.lazy, 1},
|
||||
{"cheap", no_argument, &uwsgi.cheap, 1},
|
||||
{"cheaper", required_argument, 0, LONG_ARGS_CHEAPER},
|
||||
{"cheaper-step", required_argument, 0, LONG_ARGS_CHEAPER_STEP},
|
||||
{"idle", required_argument, 0, LONG_ARGS_IDLE},
|
||||
{"die-on-idle", no_argument, &uwsgi.die_on_idle, 1},
|
||||
{"mount", required_argument, 0, LONG_ARGS_MOUNT},
|
||||
@@ -275,8 +278,10 @@ static struct option long_base_options[] = {
|
||||
#endif
|
||||
{"add-header", required_argument, 0, LONG_ARGS_ADD_HEADER},
|
||||
{"check-static", required_argument, 0, LONG_ARGS_CHECK_STATIC},
|
||||
{"static-check", required_argument, 0, LONG_ARGS_CHECK_STATIC},
|
||||
{"static-skip-ext", required_argument, 0, LONG_ARGS_STATIC_SKIP_EXT},
|
||||
{"static-map", required_argument, 0, LONG_ARGS_STATIC_MAP},
|
||||
{"static-index", required_argument, 0, LONG_ARGS_STATIC_INDEX},
|
||||
{"mimefile", required_argument, 0, LONG_ARGS_MIMEFILE},
|
||||
{"mime-file", required_argument, 0, LONG_ARGS_MIMEFILE},
|
||||
{"file-serve-mode", required_argument, 0, LONG_ARGS_FILE_SERVE_MODE},
|
||||
@@ -327,6 +332,58 @@ void show_config(void) {
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_apply_templates(void) {
|
||||
|
||||
struct uwsgi_config_template *uct = uwsgi.config_templates;
|
||||
|
||||
while (uct) {
|
||||
if (uct->applied) {
|
||||
uct = uct->next;
|
||||
continue;
|
||||
}
|
||||
uwsgi_log("using %s as config template\n", uct->filename);
|
||||
#ifdef UWSGI_XML
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 4, ".xml")) {
|
||||
uwsgi_xml_config(uct->filename, uwsgi.wsgi_req, 0, uwsgi.magic_table);
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_INI
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 4, ".ini")) {
|
||||
uwsgi_ini_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_YAML
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 4, ".yml")) {
|
||||
uwsgi_yaml_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 5, ".yaml")) {
|
||||
uwsgi_yaml_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_JSON
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 3, ".js")) {
|
||||
uwsgi_json_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 5, ".json")) {
|
||||
uwsgi_json_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_SQLITE3
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 3, ".db")) {
|
||||
uwsgi_sqlite3_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 7, ".sqlite")) {
|
||||
uwsgi_sqlite3_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 8, ".sqlite3")) {
|
||||
uwsgi_sqlite3_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
#endif
|
||||
uct->applied = 1;
|
||||
uct = uct->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_configure(void) {
|
||||
|
||||
@@ -337,18 +394,32 @@ void uwsgi_configure(void) {
|
||||
int is_retry;
|
||||
int found;
|
||||
|
||||
// option must be processed in reverse (to have a consistent template system)
|
||||
// but first load plugins...
|
||||
// plugins and inherit must be processed first (to have a consistent template system)
|
||||
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
if (uwsgi.exported_opts[i]->configured)
|
||||
continue;
|
||||
|
||||
if (!strcmp("plugin", uwsgi.exported_opts[i]->key) || !strcmp("plugins", uwsgi.exported_opts[i]->key)) {
|
||||
manage_opt(LONG_ARGS_PLUGINS, uwsgi.exported_opts[i]->value);
|
||||
uwsgi.exported_opts[i]->configured = 1;
|
||||
}
|
||||
|
||||
else if (!strcmp("inherit", uwsgi.exported_opts[i]->key)) {
|
||||
manage_opt(LONG_ARGS_INHERIT, uwsgi.exported_opts[i]->value);
|
||||
uwsgi.exported_opts[i]->configured = 1;
|
||||
}
|
||||
|
||||
else if (!strcmp("vassals-inherit", uwsgi.exported_opts[i]->key)) {
|
||||
manage_opt(LONG_ARGS_VASSALS_INHERIT, uwsgi.exported_opts[i]->value);
|
||||
uwsgi.exported_opts[i]->configured = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = uwsgi.exported_opts_cnt-1; i >= 0; i--) {
|
||||
// apply templates (again)
|
||||
uwsgi_apply_templates();
|
||||
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("i = %d %p\n", i, uwsgi.exported_opts[i]);
|
||||
@@ -373,7 +444,7 @@ void uwsgi_configure(void) {
|
||||
*aopt->flag = aopt->val;
|
||||
else if (val) {
|
||||
if (aopt->has_arg == optional_argument) {
|
||||
if (!strcasecmp("true", val)) {
|
||||
if (!strcasecmp("true", val) || !strcmp("1", val)) {
|
||||
val = NULL;
|
||||
}
|
||||
}
|
||||
@@ -1213,6 +1284,16 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
// ok we can now safely play with argv and environ
|
||||
fixup_argv_and_environ(argc, argv, environ);
|
||||
|
||||
if (gethostname(uwsgi.hostname, 255)) {
|
||||
uwsgi_error("gethostname()");
|
||||
}
|
||||
uwsgi.hostname_len = strlen(uwsgi.hostname);
|
||||
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
uwsgi_register_logger("zeromq", uwsgi_zeromq_logger);
|
||||
uwsgi_register_logger("zmq", uwsgi_zeromq_logger);
|
||||
#endif
|
||||
|
||||
//initialize embedded plugins
|
||||
UWSGI_LOAD_EMBEDDED_PLUGINS
|
||||
// now a bit of magic, if the executable basename contains a 'uwsgi_' string,
|
||||
@@ -1220,14 +1301,22 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("executable name: %s\n", uwsgi.binary_path);
|
||||
#endif
|
||||
char *p = strrchr(uwsgi.binary_path, '/');
|
||||
if (p == NULL) p = uwsgi.binary_path;
|
||||
|
||||
char *original_proc_name = getenv("UWSGI_ORIGINAL_PROC_NAME");
|
||||
if (!original_proc_name) {
|
||||
// here we use argv[0];
|
||||
original_proc_name = argv[0];
|
||||
setenv("UWSGI_ORIGINAL_PROC_NAME", original_proc_name, 1);
|
||||
}
|
||||
char *p = strrchr(original_proc_name, '/');
|
||||
if (p == NULL) p = original_proc_name;
|
||||
p = strstr(p, "uwsgi_");
|
||||
if (p != NULL) {
|
||||
plugins_requested = strchr(p, '_');
|
||||
if (plugins_requested != NULL && *(++plugins_requested) != '\0') {
|
||||
uwsgi_log("plugin = %s\n", plugins_requested);
|
||||
uwsgi_load_plugin(0, plugins_requested, NULL, 0);
|
||||
plugins_requested = strtok(uwsgi_str(p+6), "_");
|
||||
while(plugins_requested) {
|
||||
uwsgi_log("[uwsgi] implicit plugin requested %s\n", plugins_requested);
|
||||
uwsgi_load_plugin(-1, plugins_requested, NULL, 0);
|
||||
plugins_requested = strtok(NULL, "_");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1243,11 +1332,6 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
|
||||
build_options();
|
||||
|
||||
if (gethostname(uwsgi.hostname, 255)) {
|
||||
uwsgi_error("gethostname()");
|
||||
}
|
||||
uwsgi.hostname_len = strlen(uwsgi.hostname);
|
||||
|
||||
uwsgi.magic_table['v'] = uwsgi.cwd;
|
||||
uwsgi.magic_table['h'] = uwsgi.hostname;
|
||||
|
||||
@@ -1398,48 +1482,8 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
//parse environ
|
||||
parse_sys_envs(environ);
|
||||
|
||||
struct uwsgi_config_template *uct = uwsgi.config_templates;
|
||||
while (uct) {
|
||||
uwsgi_log("using %s as config template\n", uct->filename);
|
||||
#ifdef UWSGI_XML
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 4, ".xml")) {
|
||||
uwsgi_xml_config(uct->filename, uwsgi.wsgi_req, 0, uwsgi.magic_table);
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_INI
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 4, ".ini")) {
|
||||
uwsgi_ini_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_YAML
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 4, ".yml")) {
|
||||
uwsgi_yaml_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 5, ".yaml")) {
|
||||
uwsgi_yaml_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_JSON
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 3, ".js")) {
|
||||
uwsgi_json_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 5, ".json")) {
|
||||
uwsgi_json_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_SQLITE3
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 3, ".db")) {
|
||||
uwsgi_sqlite3_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 7, ".sqlite")) {
|
||||
uwsgi_sqlite3_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
if (!strcmp(uct->filename + strlen(uct->filename) - 8, ".sqlite3")) {
|
||||
uwsgi_sqlite3_config(uct->filename, uwsgi.magic_table);
|
||||
}
|
||||
#endif
|
||||
uct = uct->next;
|
||||
}
|
||||
// apply templates passed from command line
|
||||
uwsgi_apply_templates();
|
||||
|
||||
// second pass: ENVs
|
||||
uwsgi_apply_config_pass('$', (char *(*)(char *))getenv);
|
||||
@@ -1450,18 +1494,34 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
// last pass: REFERENCEs
|
||||
uwsgi_apply_config_pass('%', uwsgi_get_exported_opt);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ok, the options dictionary is available, lets manage it
|
||||
|
||||
|
||||
uwsgi_configure();
|
||||
|
||||
// setup master logging
|
||||
if (uwsgi.log_master) {
|
||||
|
||||
if (uwsgi.requested_logger) {
|
||||
char *colon = strchr(uwsgi.requested_logger, ':');
|
||||
if (colon) {
|
||||
*colon = 0;
|
||||
}
|
||||
|
||||
uwsgi.choosen_logger = uwsgi_get_logger(uwsgi.requested_logger);
|
||||
if (!uwsgi.choosen_logger) {
|
||||
uwsgi_log("unable to find logger %s\n", uwsgi.requested_logger);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (colon) {
|
||||
uwsgi.choosen_logger_arg = colon+1;
|
||||
*colon = ':';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uwsgi.original_log_fd = dup(1);
|
||||
create_logpipe();
|
||||
|
||||
}
|
||||
|
||||
/* uWSGI IS CONFIGURED !!! */
|
||||
@@ -2418,37 +2478,34 @@ skipzero:
|
||||
uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
*/
|
||||
|
||||
uwsgi_log("*** Operational MODE: ");
|
||||
if (!uwsgi.numproc) {
|
||||
uwsgi_rawlog("no-workers");
|
||||
uwsgi_log("*** Operational MODE: no-workers ***\n");
|
||||
}
|
||||
else if (uwsgi.threads > 1) {
|
||||
if (uwsgi.numproc > 1) {
|
||||
uwsgi_rawlog("preforking+threaded");
|
||||
uwsgi_log("*** Operational MODE: preforking+threaded ***\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_rawlog("threaded");
|
||||
uwsgi_log("*** Operational MODE: threaded ***\n");
|
||||
}
|
||||
}
|
||||
#ifdef UWSGI_ASYNC
|
||||
else if (uwsgi.async > 1) {
|
||||
if (uwsgi.numproc > 1) {
|
||||
uwsgi_rawlog("preforking+async");
|
||||
uwsgi_log("*** Operational MODE: preforking+async ***\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_rawlog("async");
|
||||
uwsgi_log("*** Operational MODE: async ***\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (uwsgi.numproc > 1) {
|
||||
uwsgi_rawlog("preforking");
|
||||
uwsgi_log("*** Operational MODE: preforking ***\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_rawlog("single process");
|
||||
uwsgi_log("*** Operational MODE: single process ***\n");
|
||||
}
|
||||
|
||||
uwsgi_rawlog(" ***\n");
|
||||
|
||||
// even the master has cores..
|
||||
uwsgi.core = uwsgi_malloc(sizeof(struct uwsgi_core *) * uwsgi.cores);
|
||||
for (j = 0; j < uwsgi.cores; j++) {
|
||||
@@ -3087,6 +3144,9 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
uwsgi.cheaper = 1;
|
||||
uwsgi.cheaper_count = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CHEAPER_STEP:
|
||||
uwsgi.cheaper_step = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CHDIR:
|
||||
uwsgi.chdir = optarg;
|
||||
return 1;
|
||||
@@ -3175,22 +3235,30 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
uwsgi.log_master = 1;
|
||||
return 1;
|
||||
case LONG_ARGS_LOG_SOCKET:
|
||||
uwsgi.log_socket = 1;
|
||||
uwsgi.log_master = 1;
|
||||
uwsgi.master_process = 1;
|
||||
log_socket(optarg);
|
||||
uwsgi.requested_logger = uwsgi_concat2("socket:", optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_LOGGER:
|
||||
uwsgi.log_master = 1;
|
||||
uwsgi.master_process = 1;
|
||||
uwsgi.requested_logger = uwsgi_str(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_LOG_SYSLOG:
|
||||
log_syslog(optarg);
|
||||
uwsgi.log_syslog = 1;
|
||||
uwsgi.log_master = 1;
|
||||
uwsgi.master_process = 1;
|
||||
if (optarg) {
|
||||
uwsgi.requested_logger = uwsgi_concat2("syslog:", optarg);
|
||||
}
|
||||
else {
|
||||
uwsgi.requested_logger = "syslog";
|
||||
}
|
||||
return 1;
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
case LONG_ARGS_LOG_ZEROMQ:
|
||||
log_zeromq(optarg);
|
||||
uwsgi.log_master = 1;
|
||||
uwsgi.master_process = 1;
|
||||
uwsgi.requested_logger = uwsgi_concat2("zeromq:", optarg);
|
||||
return 1;
|
||||
#endif
|
||||
case LONG_ARGS_PRINT:
|
||||
@@ -3325,6 +3393,7 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
|
||||
uct->filename = optarg;
|
||||
uct->next = NULL;
|
||||
uct->applied = 0;
|
||||
|
||||
return 1;
|
||||
case LONG_ARGS_VASSAL_SOS_BACKLOG:
|
||||
@@ -3386,6 +3455,9 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
case LONG_ARGS_STATIC_SKIP_EXT:
|
||||
uwsgi_string_new_list(&uwsgi.static_skip_ext, optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_STATIC_INDEX:
|
||||
uwsgi_string_new_list(&uwsgi.static_index, optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_STATIC_MAP:
|
||||
mountpoint = uwsgi_str(optarg);
|
||||
docroot = strchr(mountpoint, '=');
|
||||
@@ -3650,12 +3722,18 @@ static int manage_base_opt(int i, char *optarg) {
|
||||
#endif
|
||||
|
||||
case 'd':
|
||||
if (!uwsgi.is_a_reload) {
|
||||
daemonize(optarg);
|
||||
}
|
||||
else if (uwsgi.log_reopen) {
|
||||
// do not daemonize in emperor mode
|
||||
if (uwsgi.has_emperor) {
|
||||
logto(optarg);
|
||||
}
|
||||
else {
|
||||
if (!uwsgi.is_a_reload) {
|
||||
daemonize(optarg);
|
||||
}
|
||||
else if (uwsgi.log_reopen) {
|
||||
logto(optarg);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
case 's':
|
||||
uwsgi_sock = uwsgi_new_socket(generate_socket_name(optarg));
|
||||
|
||||
@@ -11,6 +11,8 @@ extern "C" {
|
||||
#define UMAX64_STR "18446744073709551616"
|
||||
|
||||
#define uwsgi_error(x) uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
|
||||
#define uwsgi_log_safe(x) if (uwsgi.original_log_fd != 2) dup2(uwsgi.original_log_fd, 2) ; uwsgi_log(x);
|
||||
#define uwsgi_error_safe(x) if (uwsgi.original_log_fd != 2) dup2(uwsgi.original_log_fd, 2) ; uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
|
||||
#define uwsgi_log_initial if (!uwsgi.no_initial_output) uwsgi_log
|
||||
#define uwsgi_fatal_error(x) uwsgi_error(x); exit(1);
|
||||
#define uwsgi_error_open(x) uwsgi_log("open(\"%s\"): %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
|
||||
@@ -65,6 +67,8 @@ extern char UWSGI_EMBED_CONFIG_END;
|
||||
#define ULEP(pname)\
|
||||
if (pname##_plugin.request) {\
|
||||
uwsgi.p[pname##_plugin.modifier1] = &pname##_plugin;\
|
||||
if (uwsgi.p[pname##_plugin.modifier1]->on_load)\
|
||||
uwsgi.p[pname##_plugin.modifier1]->on_load();\
|
||||
}\
|
||||
else {\
|
||||
if (uwsgi.gp_cnt >= MAX_GENERIC_PLUGINS) {\
|
||||
@@ -72,6 +76,8 @@ extern char UWSGI_EMBED_CONFIG_END;
|
||||
exit(1);\
|
||||
}\
|
||||
uwsgi.gp[uwsgi.gp_cnt] = &pname##_plugin;\
|
||||
if (uwsgi.gp[uwsgi.gp_cnt]->on_load)\
|
||||
uwsgi.gp[uwsgi.gp_cnt]->on_load();\
|
||||
uwsgi.gp_cnt++;\
|
||||
}\
|
||||
|
||||
@@ -126,8 +132,6 @@ extern char UWSGI_EMBED_CONFIG_END;
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#ifdef UWSGI_HAS_IFADDRS
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
@@ -271,6 +275,7 @@ struct uwsgi_help_item {
|
||||
|
||||
struct uwsgi_config_template {
|
||||
char *filename;
|
||||
int applied;
|
||||
struct uwsgi_config_template *next;
|
||||
};
|
||||
|
||||
@@ -340,6 +345,19 @@ struct uwsgi_daemon {
|
||||
struct uwsgi_daemon *next;
|
||||
};
|
||||
|
||||
struct uwsgi_logger {
|
||||
char *name;
|
||||
ssize_t (*func)(struct uwsgi_logger *, char *, size_t);
|
||||
int configured;
|
||||
int fd;
|
||||
void *data;
|
||||
union uwsgi_sockaddr addr;
|
||||
socklen_t addr_len;
|
||||
int count;
|
||||
struct msghdr msg;
|
||||
struct uwsgi_logger *next;
|
||||
};
|
||||
|
||||
struct uwsgi_queue_header {
|
||||
uint64_t pos;
|
||||
uint64_t pull_pos;
|
||||
@@ -539,6 +557,9 @@ struct uwsgi_opt {
|
||||
#define LONG_ARGS_EXEC_AS_ROOT 17169
|
||||
#define LONG_ARGS_EXEC_AS_USER 17170
|
||||
#define LONG_ARGS_STATIC_SKIP_EXT 17171
|
||||
#define LONG_ARGS_LOGGER 17172
|
||||
#define LONG_ARGS_STATIC_INDEX 17173
|
||||
#define LONG_ARGS_CHEAPER_STEP 17174
|
||||
|
||||
|
||||
#define UWSGI_OK 0
|
||||
@@ -649,6 +670,7 @@ struct uwsgi_plugin {
|
||||
const char *alias;
|
||||
uint8_t modifier1;
|
||||
void *data;
|
||||
void (*on_load) (void);
|
||||
int (*init) (void);
|
||||
void (*post_init) (void);
|
||||
void (*post_fork) (void);
|
||||
@@ -1064,6 +1086,7 @@ struct uwsgi_server {
|
||||
int cheap;
|
||||
// enable cheaper mode
|
||||
int cheaper;
|
||||
int cheaper_step;
|
||||
// minimal number of running workers in cheaper mode
|
||||
int cheaper_count;
|
||||
// enable idle mode
|
||||
@@ -1184,15 +1207,8 @@ struct uwsgi_server {
|
||||
off_t log_maxsize;
|
||||
char *log_backupname;
|
||||
|
||||
int log_syslog;
|
||||
int original_log_fd;
|
||||
|
||||
int log_socket;
|
||||
int log_socket_fd;
|
||||
union uwsgi_sockaddr *log_socket_addr;
|
||||
socklen_t log_socket_size;
|
||||
|
||||
|
||||
// static file serving
|
||||
int file_serve_mode;
|
||||
int build_mime_dict;
|
||||
@@ -1203,6 +1219,12 @@ struct uwsgi_server {
|
||||
struct uwsgi_string_list *exec_as_root;
|
||||
struct uwsgi_string_list *exec_as_user;
|
||||
|
||||
struct uwsgi_logger *loggers;
|
||||
struct uwsgi_logger *choosen_logger;
|
||||
char *requested_logger;
|
||||
char *choosen_logger_arg;
|
||||
int threaded_logger;
|
||||
|
||||
struct uwsgi_daemon *daemons;
|
||||
int daemons_cnt;
|
||||
|
||||
@@ -1210,6 +1232,7 @@ struct uwsgi_server {
|
||||
struct uwsgi_dyn_dict *check_static;
|
||||
struct uwsgi_dyn_dict *mimetypes;
|
||||
struct uwsgi_string_list *static_skip_ext;
|
||||
struct uwsgi_string_list *static_index;
|
||||
|
||||
char *logfile;
|
||||
int logfile_chown;
|
||||
@@ -1456,7 +1479,6 @@ struct uwsgi_server {
|
||||
int zeromq_recv_flag;
|
||||
pthread_mutex_t zmq_lock;
|
||||
pthread_key_t zmq_pull;
|
||||
void *zmq_log_socket;
|
||||
#endif
|
||||
struct uwsgi_socket *sockets;
|
||||
struct uwsgi_socket *shared_sockets;
|
||||
@@ -2123,7 +2145,6 @@ char *uwsgi_cheap_string(char *, int);
|
||||
|
||||
int uwsgi_parse_array(char *, uint16_t, char **, uint16_t *, uint8_t *);
|
||||
|
||||
void log_syslog(char *);
|
||||
|
||||
struct uwsgi_gateway *register_gateway(char *, void (*)(void));
|
||||
struct uwsgi_gateway *register_fat_gateway(char *, void (*)(void));
|
||||
@@ -2340,7 +2361,7 @@ uint16_t proto_base_add_uwsgi_header(struct wsgi_request *, char *, uint16_t, ch
|
||||
uint16_t proto_base_add_uwsgi_var(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
|
||||
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
void log_zeromq(char *);
|
||||
ssize_t uwsgi_zeromq_logger(struct uwsgi_logger *, char *, size_t len);
|
||||
int uwsgi_proto_zeromq_accept(struct wsgi_request *, int);
|
||||
void uwsgi_proto_zeromq_close(struct wsgi_request *);
|
||||
ssize_t uwsgi_proto_zeromq_writev_header(struct wsgi_request *, struct iovec *, size_t);
|
||||
@@ -2386,9 +2407,7 @@ void uwsgi_ignition(void);
|
||||
void master_check_cluster_nodes(void);
|
||||
int uwsgi_respawn_worker(int);
|
||||
|
||||
void log_socket(char *);
|
||||
|
||||
socklen_t socket_to_in_addr(char *, char *, struct sockaddr_in *);
|
||||
socklen_t socket_to_in_addr(char *, char *, int, struct sockaddr_in *);
|
||||
socklen_t socket_to_un_addr(char *, struct sockaddr_un *);
|
||||
|
||||
int uwsgi_get_shared_socket_fd_by_num(int);
|
||||
@@ -2419,8 +2438,6 @@ int uwsgi_signal_registered(uint8_t);
|
||||
|
||||
int uwsgi_endswith(char *, char *);
|
||||
|
||||
char *uwsgi_get_var(struct wsgi_request *, char *, uint16_t *);
|
||||
|
||||
int uwsgi_cache_server(char *, int);
|
||||
|
||||
void uwsgi_chown(char *, char *);
|
||||
@@ -2553,6 +2570,12 @@ void uwsgi_linux_ksm_map(void);
|
||||
void uwsgi_build_cap(char *);
|
||||
#endif
|
||||
|
||||
void uwsgi_register_logger(char *, ssize_t (*func)(struct uwsgi_logger *, char *, size_t));
|
||||
struct uwsgi_logger *uwsgi_get_logger(char *);
|
||||
|
||||
char *uwsgi_getsockname(int);
|
||||
char *uwsgi_get_var(struct wsgi_request *, char *, uint16_t, uint16_t *);
|
||||
|
||||
#ifdef UWSGI_AS_SHARED_LIBRARY
|
||||
int uwsgi_init(int, char **, char **);
|
||||
#endif
|
||||
|
||||
+23
-13
@@ -1,6 +1,6 @@
|
||||
# uWSGI build system
|
||||
|
||||
uwsgi_version = '1.0-dev'
|
||||
uwsgi_version = '1.0'
|
||||
|
||||
import os
|
||||
import re
|
||||
@@ -105,7 +105,7 @@ def compile(cflags, objfile, srcfile):
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def build_uwsgi(uc):
|
||||
def build_uwsgi(uc, print_only=False):
|
||||
|
||||
gcc_list, cflags, ldflags, libs = uc.get_gcll()
|
||||
|
||||
@@ -126,6 +126,10 @@ def build_uwsgi(uc):
|
||||
cflags.append(epc)
|
||||
cflags.append(eplc)
|
||||
|
||||
if print_only:
|
||||
print(' '.join(cflags))
|
||||
sys.exit(0)
|
||||
|
||||
print("configured CFLAGS: %s" % ' '.join(cflags))
|
||||
|
||||
print("*** uWSGI compiling server core ***")
|
||||
@@ -220,9 +224,10 @@ def build_uwsgi(uc):
|
||||
|
||||
class uConf(object):
|
||||
|
||||
def __init__(self, filename):
|
||||
def __init__(self, filename, mute=False):
|
||||
self.config = ConfigParser.ConfigParser()
|
||||
print("using profile: %s" % filename)
|
||||
if not mute:
|
||||
print("using profile: %s" % filename)
|
||||
if not os.path.exists(filename):
|
||||
raise Exception("profile not found !!!")
|
||||
|
||||
@@ -281,8 +286,8 @@ class uConf(object):
|
||||
except:
|
||||
self.include_path = ['/usr/include', '/usr/local/include']
|
||||
|
||||
|
||||
print("detected include path: %s" % self.include_path)
|
||||
if not mute:
|
||||
print("detected include path: %s" % self.include_path)
|
||||
|
||||
try:
|
||||
gcc_major = int(gcc_version.split('.')[0])
|
||||
@@ -834,13 +839,7 @@ if __name__ == "__main__":
|
||||
print("please specify an argument")
|
||||
sys.exit(1)
|
||||
|
||||
if cmd == '--cflags':
|
||||
print(' '.join(cflags))
|
||||
if cmd == '--ldflags':
|
||||
print(' '.join(ldflags))
|
||||
if cmd == '--libs':
|
||||
print(' '.join(libs))
|
||||
elif cmd == '--build':
|
||||
if cmd == '--build':
|
||||
bconf = os.environ.get('UWSGI_PROFILE','default.ini')
|
||||
try:
|
||||
bconf = sys.argv[2]
|
||||
@@ -851,6 +850,17 @@ if __name__ == "__main__":
|
||||
if not '/' in bconf:
|
||||
bconf = 'buildconf/%s' % bconf
|
||||
build_uwsgi(uConf(bconf))
|
||||
elif cmd == '--cflags':
|
||||
bconf = os.environ.get('UWSGI_PROFILE','default.ini')
|
||||
try:
|
||||
bconf = sys.argv[2]
|
||||
except:
|
||||
pass
|
||||
if not bconf.endswith('.ini'):
|
||||
bconf += '.ini'
|
||||
if not '/' in bconf:
|
||||
bconf = 'buildconf/%s' % bconf
|
||||
build_uwsgi(uConf(bconf, True), True)
|
||||
elif cmd == '--unbit':
|
||||
build_uwsgi(uConf('buildconf/unbit.ini'))
|
||||
elif cmd == '--plugin':
|
||||
|
||||
@@ -202,7 +202,6 @@ class mulemsg_loop(object):
|
||||
|
||||
def __call__(self):
|
||||
if uwsgi.mule_id() == self.num:
|
||||
print " i am the mule"
|
||||
while True:
|
||||
message = uwsgi.mule_get_msg()
|
||||
if message:
|
||||
|
||||
+4
-4
@@ -30,12 +30,12 @@ def serve_logo(e, sr):
|
||||
def serve_options(e, sr):
|
||||
sr('200 OK', [('Content-Type', 'text/html')])
|
||||
for opt in xrange(0,256):
|
||||
yield "%d = %d<br/>" % (opt, uwsgi.get_option(opt))
|
||||
yield "<b>%d</b> = %d<br/>" % (opt, uwsgi.get_option(opt))
|
||||
|
||||
def serve_config(e, sr):
|
||||
sr('200 OK', [('Content-Type', 'text/html')])
|
||||
for opt in uwsgi.opt.keys():
|
||||
yield "%s = %s<br/>" % (opt, uwsgi.opt[opt])
|
||||
yield "<b>%s</b> = %s<br/>" % (opt, uwsgi.opt[opt])
|
||||
|
||||
routes = {}
|
||||
routes['/xsendfile'] = xsendfile
|
||||
@@ -95,7 +95,7 @@ def application(env, start_response):
|
||||
""" % (w['id'], w['pid'], w['status'], w['running_time']/1000, w['avg_rt']/1000, w['tx'], apps)
|
||||
|
||||
return """
|
||||
<img src="/logo"/> version %s<br/>
|
||||
<img src="/logo"/> version %s running on %s<br/>
|
||||
<hr size="1"/>
|
||||
|
||||
Configuration<br/>
|
||||
@@ -115,7 +115,7 @@ Workers and applications<br/>
|
||||
%s
|
||||
</table>
|
||||
|
||||
""" % (uwsgi.version, workers)
|
||||
""" % (uwsgi.version, uwsgi.hostname, workers)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user