Compare commits

...
9 Commits
12 changed files with 488 additions and 5 deletions
+1
View File
@@ -26,3 +26,4 @@ e91bc724325e14c13b8f548c0b6a315c48a1c32a 0.9.8-rc2
0f1f3924ee5309a9990d9af1ffc68846e3dfb31b 0.9.8-rc4
42efe1f329005618c8b44f901979ebcecd5216fb 0.9.8
fd8477b6348faf16588106055ca59df1c488f76a 0.9.8.1
7169ef1d68d3dab4737bcc3f9e082839e5a06cc1 0.9.8.2
+8
View File
@@ -1,5 +1,13 @@
*** july 2011 ***
* 0.9.8.3 [20110723]
- implemented uwsgi.SymZipImporter to load embedded zip files
- OSX Lion is officially supported
- fixed xinetd support (example file added in contrib)
- suppot for systemd socket activation
- added --freebind option (Linux only)
* 0.9.8.2 [20110719]
- fixed an ini and yaml parsing bug spotted by Raffaele Colace
+4
View File
@@ -0,0 +1,4 @@
import sys
import uwsgi
sys.meta_path.insert(0, uwsgi.SymbolsZipImporter("pygments_zip"))
+5
View File
@@ -0,0 +1,5 @@
import sys
import uwsgi
sys.meta_path.insert(0, uwsgi.SymbolsZipImporter("django_zip:djenv/lib/python2.6/site-packages"))
sys.meta_path.insert(0, uwsgi.SymbolsZipImporter("djapp_zip"))
+3
View File
@@ -0,0 +1,3 @@
[uwsgi]
inherit = default
embed_files = bootstrap3.py,django.zip,djapp.zip
+1
View File
@@ -674,6 +674,7 @@ clear:
close(ctl_poll.fd);
}
return NULL;
}
int uwsgi_cache_server(char *socket, int threads) {
+14
View File
@@ -0,0 +1,14 @@
service uwsgi
{
disable = no
id = uwsgi-000
type = UNLISTED
socket_type = stream
server = /root/uwsgi/uwsgi
server_args = --chdir /root/uwsgi/ --module welcome --logto /tmp/uwsgi.log
port = 3031
bind = 127.0.0.1
user = root
wait = yes
}
+376
View File
@@ -1,5 +1,7 @@
#include "uwsgi_python.h"
#ifndef PYTHREE
extern struct uwsgi_server uwsgi;
extern struct uwsgi_python up;
@@ -8,6 +10,13 @@ struct _symimporter {
PyObject_HEAD;
} uwsgi_symbol_importer_object;
struct _symzipimporter {
PyObject_HEAD;
char *prefix;
PyObject *zip;
PyObject *items;
} uwsgi_symbol_zip_importer_object;
static char *symbolize(char *name) {
char *base = uwsgi_concat2(name, "");
@@ -22,6 +31,84 @@ static char *symbolize(char *name) {
return base;
}
static char *name_to_py(char *prefix, char *name) {
char *base;
char *ptr;
if (prefix) {
if (prefix[strlen(prefix)-1] == '/') {
base = uwsgi_concat3(prefix, name, ".py");
ptr = base + strlen(prefix);
}
else {
base = uwsgi_concat4(prefix, "/", name, ".py");
ptr = base + strlen(prefix) + 1;
}
}
else {
base = uwsgi_concat2(name, ".py");
ptr = base;
}
while(*ptr != 0) {
if (*ptr == '.') {
*ptr = '/';
}
ptr++;
}
// fix .py
ptr-=3;
*ptr = '.';
return base;
}
static char *name_to_init_py(char *prefix, char *name) {
char *base;
char *ptr;
if (prefix) {
if (prefix[strlen(prefix)-1] == '/') {
base = uwsgi_concat3(prefix, name, "/__init__.py");
ptr = base + strlen(prefix);
}
else {
base = uwsgi_concat4(prefix, "/", name, "/__init__.py");
ptr = base + strlen(prefix) + 1;
}
}
else {
base = uwsgi_concat2(name, "/__init__.py");
ptr = base;
}
while(*ptr != 0) {
if (*ptr == '.') {
*ptr = '/';
}
ptr++;
}
// fix .py
ptr-=3;
*ptr = '.';
return base;
}
static char *name_to_symbol(char *name, char *what) {
char *symbol = uwsgi_concat4("_binary_", name, "_", what);
char *sym_ptr_start = dlsym(RTLD_DEFAULT, symbol);
free(symbol);
return sym_ptr_start;
}
static char *name_to_symbol_module(char *name, char *what) {
char *symbol = uwsgi_concat4("_binary_", name, "_py_", what);
@@ -38,6 +125,127 @@ static char *name_to_symbol_pkg(char *name, char *what) {
return sym_ptr_start;
}
int py_list_has_string(PyObject *obj, char *name) {
Py_ssize_t i, len = PyList_Size(obj);
int found = 0;
for(i=0;i<len;i++) {
PyObject *current = PyList_GetItem(obj, i);
char *filename = PyString_AsString(current);
if (!strcmp(filename, name)) {
found = 1;
break;
}
}
return found;
}
static PyObject* symzipimporter_find_module(PyObject *self, PyObject *args) {
char *fullname;
PyObject *path = NULL;
struct _symzipimporter *this = (struct _symzipimporter *) self;
if (!PyArg_ParseTuple(args, "s|O:find_module", &fullname, &path)) {
return NULL;
}
char *filename = name_to_py(this->prefix, fullname);
if (py_list_has_string(this->items, filename)) {
free(filename);
return self;
}
PyErr_Clear();
free(filename);
filename = name_to_init_py(this->prefix, fullname);
if (py_list_has_string(this->items, filename)) {
free(filename);
return self;
}
PyErr_Clear();
free(filename);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* symzipimporter_load_module(PyObject *self, PyObject *args) {
char *fullname;
char *modname;
struct _symzipimporter *this = (struct _symzipimporter *) self;
if (!PyArg_ParseTuple(args, "s:load_module", &fullname)) {
return NULL;
}
char *filename = name_to_py(this->prefix, fullname);
if (py_list_has_string(this->items, filename)) {
PyObject *mod = PyImport_AddModule(fullname);
if (!mod) goto clear;
PyObject *dict = PyModule_GetDict(mod);
if (!dict) goto clear;
PyDict_SetItemString(dict, "__loader__", self);
modname = uwsgi_concat2("symzip://", fullname);
PyObject *source = PyObject_CallMethod(this->zip, "read", "(s)", filename);
free(filename);
PyObject *code = Py_CompileString(PyString_AsString(source), modname, Py_file_input);
mod = PyImport_ExecCodeModuleEx(fullname, code, modname);
Py_DECREF(code);
Py_DECREF(source);
free(modname);
return mod;
}
PyErr_Clear();
free(filename);
filename = name_to_init_py(this->prefix, fullname);
if (py_list_has_string(this->items, filename)) {
PyObject *mod = PyImport_AddModule(fullname);
if (!mod) goto clear;
PyObject *dict = PyModule_GetDict(mod);
if (!dict) goto clear;
modname = uwsgi_concat2("symzip://", fullname);
PyObject *pkgpath = Py_BuildValue("[O]", PyString_FromString(modname));
PyDict_SetItemString(dict, "__path__", pkgpath);
PyDict_SetItemString(dict, "__loader__", self);
PyObject *source = PyObject_CallMethod(this->zip, "read", "(s)", filename);
free(filename);
PyObject *code = Py_CompileString(PyString_AsString(source), modname, Py_file_input);
mod = PyImport_ExecCodeModuleEx(fullname, code, modname);
Py_DECREF(code);
Py_DECREF(source);
free(modname);
return mod;
}
clear:
PyErr_Clear();
free(filename);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* symimporter_find_module(PyObject *self, PyObject *args) {
char *fullname;
@@ -146,6 +354,11 @@ static PyMethodDef symimporter_methods[] = {
{"load_module", symimporter_load_module, METH_VARARGS},
};
static PyMethodDef symzipimporter_methods[] = {
{"find_module", symzipimporter_find_module, METH_VARARGS},
{"load_module", symzipimporter_load_module, METH_VARARGS},
};
static void uwsgi_symimporter_free(struct _symimporter *self) {
PyObject_Del(self);
}
@@ -193,6 +406,154 @@ static PyTypeObject SymImporter_Type = {
PyObject_GC_Del, /* tp_free */
};
static int
symzipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds)
{
char *name;
char *prefix = NULL;
if (!PyArg_ParseTuple(args, "s", &name))
return -1;
// avoid GC !!!
name = uwsgi_concat2(name, "");
prefix = strchr(name, ':');
if (prefix) {
prefix[0] = 0;
}
char *code_start = name_to_symbol(name, "start");
if (!code_start) {
PyErr_Format(PyExc_ValueError, "unable to find symbol");
return -1;
}
char *code_end = name_to_symbol(name, "end");
if (!code_end) {
PyErr_Format(PyExc_ValueError, "unable to find symbol");
return -1;
}
PyObject *stringio = PyImport_ImportModule("StringIO");
if (!stringio) {
PyErr_Print();
return -1;
}
PyObject *stringio_dict = PyModule_GetDict(stringio);
if (!stringio_dict) {
PyErr_Print();
return -1;
}
PyObject *stringio_stringio = PyDict_GetItemString(stringio_dict, "StringIO");
if (!stringio_stringio) {
PyErr_Print();
return -1;
}
PyObject *stringio_args = PyTuple_New(1);
PyTuple_SetItem(stringio_args, 0, PyString_FromStringAndSize(code_start, code_end-code_start));
PyObject *source_code = PyInstance_New(stringio_stringio, stringio_args, NULL);
if (!source_code) {
PyErr_Print();
return -1;
}
PyObject *zipfile = PyImport_ImportModule("zipfile");
if (!zipfile) {
PyErr_Print();
return -1;
}
PyObject *zipfile_dict = PyModule_GetDict(zipfile);
if (!zipfile_dict) {
PyErr_Print();
return -1;
}
PyObject *zipfile_zipfile = PyDict_GetItemString(zipfile_dict, "ZipFile");
if (!zipfile_zipfile) {
PyErr_Print();
return -1;
}
PyObject *zipfile_args = PyTuple_New(1);
PyTuple_SetItem(zipfile_args, 0, source_code);
self->zip = PyInstance_New(zipfile_zipfile, zipfile_args, NULL);
if (!self->zip) {
PyErr_Print();
return -1;
}
Py_INCREF(self->zip);
self->items = PyObject_CallMethod(self->zip, "namelist", NULL);
if (!self->items) {
PyErr_Print();
return -1;
}
Py_INCREF(self->items);
self->prefix = NULL;
if (prefix) {
self->prefix = prefix+1;
prefix[0] = ':';
}
return 0;
}
static PyTypeObject SymZipImporter_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"uwsgi.SymbolsZipImporter",
sizeof(struct _symzipimporter),
0, /* tp_itemsize */
(destructor) uwsgi_symimporter_free, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT,
"uwsgi symbols zip importer", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
symzipimporter_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc) symzipimporter_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
int uwsgi_init_symbol_import() {
@@ -202,6 +563,12 @@ int uwsgi_init_symbol_import() {
exit(1);
}
if (PyType_Ready(&SymZipImporter_Type) < 0) {
PyErr_Print();
uwsgi_log("unable to initialize symbols zip importer module\n");
exit(1);
}
PyObject *uwsgi_em = PyImport_ImportModule("uwsgi");
if (!uwsgi_em) {
PyErr_Print();
@@ -216,7 +583,16 @@ int uwsgi_init_symbol_import() {
exit(1);
}
if (PyModule_AddObject(uwsgi_em, "SymbolsZipImporter",
(PyObject *)&SymZipImporter_Type) < 0) {
PyErr_Print();
uwsgi_log("unable to initialize symbols zip importer object\n");
exit(1);
}
return 0;
}
#endif
+42 -3
View File
@@ -500,6 +500,17 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
uwsgi_nuclear_blast();
}
#ifdef __linux__
#ifdef IP_FREEBIND
if (uwsgi.freebind) {
if (setsockopt(serverfd, SOL_IP, IP_FREEBIND, (const void *) &uwsgi.freebind, sizeof(int)) < 0) {
uwsgi_error("setsockopt()");
uwsgi_nuclear_blast();
}
}
#endif
#endif
if (uwsgi.reuse_port) {
#ifdef SO_REUSEPORT
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEPORT, (const void *) &uwsgi.reuse_port, sizeof(int)) < 0) {
@@ -758,7 +769,25 @@ struct uwsgi_socket *uwsgi_new_socket(char *name) {
char *auto_port = uwsgi_num2str(ntohs(sin.sin_port));
uwsgi_sock->name = uwsgi_concat3n(name, tcp_port-name, ":", 1, auto_port, strlen(auto_port));
}
}
// is it fd 0 ?
else if (tcp_port[1] == ':') {
uwsgi_sock->fd = 0;
uwsgi_sock->family = AF_INET;
uwsgi_sock->bound = 1;
socket_type_len = sizeof(struct sockaddr_in);
if (getsockname(0, (struct sockaddr *)&sin, &socket_type_len)) {
uwsgi_error("getsockname()");
exit(1);
}
char *auto_port = uwsgi_num2str(ntohs(sin.sin_port));
char *auto_ip = inet_ntoa(sin.sin_addr);
uwsgi_sock->name = uwsgi_concat3n(auto_ip, strlen(auto_ip), ":", 1, auto_port, strlen(auto_port));
}
}
return uwsgi_sock;
@@ -790,7 +819,12 @@ void uwsgi_add_socket_from_fd(struct uwsgi_socket *uwsgi_sock, int fd) {
uwsgi_sock->family = AF_UNIX;
uwsgi_sock->bound = 1;
uwsgi_sock->name = uwsgi_concat2(usa.sa_un.sun_path+abstract, "");
uwsgi_log("uwsgi zerg socket %d attached to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), usa.sa_un.sun_path+abstract, uwsgi_sock->fd);
if (uwsgi.zerg) {
uwsgi_log("uwsgi zerg socket %d attached to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), usa.sa_un.sun_path+abstract, uwsgi_sock->fd);
}
else {
uwsgi_log("uwsgi socket %d attached to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), usa.sa_un.sun_path+abstract, uwsgi_sock->fd);
}
return;
}
if (!strcmp(usa.sa_un.sun_path+abstract, uwsgi_sock->name+abstract)) {
@@ -825,7 +859,12 @@ void uwsgi_add_socket_from_fd(struct uwsgi_socket *uwsgi_sock, int fd) {
uwsgi_sock->family = AF_INET;
uwsgi_sock->bound = 1;
uwsgi_sock->name = uwsgi_concat2(computed_addr, "");
uwsgi_log("uwsgi zerg socket %d attached to INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
if (uwsgi.zerg) {
uwsgi_log("uwsgi zerg socket %d attached to INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
}
else {
uwsgi_log("uwsgi socket %d attached to INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
}
free(computed_addr);
return;
}
+29 -1
View File
@@ -57,6 +57,9 @@ static struct option long_base_options[] = {
{"abstract-socket", no_argument, 0, 'a'},
{"chmod-socket", optional_argument, 0, 'C'},
{"chown-socket", required_argument, 0, LONG_ARGS_CHOWN_SOCKET},
#ifdef __linux__
{"freebind", no_argument, &uwsgi.freebind, 1},
#endif
{"map-socket", required_argument, 0, LONG_ARGS_MAP_SOCKET},
{"chmod", optional_argument, 0, 'C'},
#ifdef UWSGI_THREADING
@@ -1656,6 +1659,29 @@ int uwsgi_start(void *v_argv) {
if (!uwsgi.no_server) {
// systemd socket activation
if (!uwsgi.is_a_reload) {
char *listen_pid = getenv("LISTEN_PID");
if (listen_pid) {
if (atoi(listen_pid) == (int) getpid()) {
char *listen_fds = getenv("LISTEN_FDS");
if (listen_fds) {
int systemd_fds = atoi(listen_fds);
if (systemd_fds > 0) {
for(i=3;i<3+systemd_fds;i++) {
uwsgi_sock = uwsgi_new_socket(NULL);
uwsgi_add_socket_from_fd(uwsgi_sock, i);
}
}
unsetenv("LISTEN_PID");
unsetenv("LISTEN_FDS");
goto skipzero;
}
}
}
}
//check for inherited sockets
if (uwsgi.is_a_reload || uwsgi.zerg) {
@@ -1775,7 +1801,7 @@ int uwsgi_start(void *v_argv) {
uwsgi_log("uwsgi socket %d inherited UNIX address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
}
else {
uwsgi_sock = uwsgi_new_socket(uwsgi_concat2(":0", ""));
uwsgi_sock = uwsgi_new_socket(uwsgi_concat2("::",""));
uwsgi_log("uwsgi socket %d inherited INET address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
}
}
@@ -1795,6 +1821,8 @@ int uwsgi_start(void *v_argv) {
}
}
skipzero:
// check for auto_port socket
uwsgi_sock = uwsgi.sockets;
+4
View File
@@ -1095,6 +1095,10 @@ struct uwsgi_server {
struct timeval start_tv;
int abstract_socket;
#ifdef __linux__
int freebind;
#endif
int chmod_socket;
char *chown_socket;
mode_t chmod_socket_value;
+1 -1
View File
@@ -1,6 +1,6 @@
# uWSGI build system
uwsgi_version = '0.9.8.2'
uwsgi_version = '0.9.8.3'
import os
import re