Compare commits

..
37 Commits
Author SHA1 Message Date
Roberto De Ioris e8aa0e1e26 fixed a typecasting 2013-03-11 20:51:08 +01:00
Unbit 46a8aae908 added CacheGet to mono 2013-03-11 16:10:39 +01:00
Unbit a9f90464e6 fixed routing condition bug 2013-03-11 12:44:22 +01:00
Unbit 4bcdba2334 removed Changelog, we maintain them online 2013-03-11 12:16:44 +01:00
Unbit 64a8f3464a fixed routing goto 2013-03-11 10:37:10 +01:00
Unbit e640bd6f9b completed legion scroll 2013-03-11 09:44:50 +01:00
Unbit 71a6726bcf finally removed --app and static-offload-to-thread 2013-03-11 07:13:05 +01:00
Unbit fe13774b4b internal routing optimization 2013-03-11 07:05:58 +01:00
Unbit ecc3a5e8e2 another routing fix 2013-03-11 06:46:52 +01:00
Unbit dd1881576a removed grunt support 2013-03-10 22:22:16 +01:00
Unbit 322a2d2365 improved routing + static management 2013-03-10 21:30:54 +01:00
Unbit a76d7a1c66 first part of legion scroll implementation 2013-03-10 17:55:58 +01:00
Unbit 5631dcabf8 fixed --static-index when methods different from GET/HEAD are in place 2013-03-10 12:05:25 +01:00
Unbit 3f731e2577 Merge branch 'master' of github.com:unbit/uwsgi 2013-03-10 08:55:05 +01:00
Unbit 7a1b7f299b added --whitelist and --blacklist context 2013-03-10 08:54:45 +01:00
unbit 322673215e Merge pull request #178 from xrmx/coverity-buildconf
Add build profile for coverity scan
2013-03-09 15:28:44 -08:00
Riccardo Magliocchetti b58a0c4969 Add build profile for coverity scan
Add all the language plugins i can actually compile on my machine
so that we have a bit more plugin coverage instead of the plain make.
31 more bugs reported by Coverity scan.
2013-03-09 18:32:15 +01:00
Unbit c5fe8c6d30 reverted flock fd anti-leak 2013-03-09 18:13:18 +01:00
Unbit 7f54f5075d fixed a leak in routing api 2013-03-09 18:10:23 +01:00
unbit 95d4cea3bb Merge pull request #177 from xrmx/coverity10
More issues reported by Coverity
2013-03-09 09:03:55 -08:00
Riccardo Magliocchetti d6ff3ac018 core/legion: fix memory leak in wsgi_opt_legion_quorum
Reported by Coverity as CID #971024.
2013-03-09 17:04:57 +01:00
Riccardo Magliocchetti 1f4099c874 core/mule: fix a memory leak in uwsgi_setup_mules_and_farms
Reported by Coverity as CID #971028.
2013-03-09 17:01:18 +01:00
Riccardo Magliocchetti 8cd298de34 core/protocol: fix leak in send_udp_message
By moving the allocation after some early returns in case of error.

Reported by Coverity as CID #971033.
2013-03-09 16:52:20 +01:00
Riccardo Magliocchetti 851df33977 core/queue: close queue store after mmap()
Reported by Coverity as CID #971035.
2013-03-09 16:49:58 +01:00
Riccardo Magliocchetti 17f3f3d9a0 core/stats: fix memory leak in uwsgi_stats_pusher_setup
Reported by Coverity as CID #971039.
2013-03-09 16:46:49 +01:00
Riccardo Magliocchetti 4273489e42 core/uwsgi: fix memory leak in signal_pidfile
Reportd by Coverity as CID #971046.
2013-03-09 16:37:19 +01:00
Riccardo Magliocchetti 57077ac68c core/uwsgi: don't leak fd in flock related function
Reported by Coverity as CID #971047, #971048.
2013-03-09 16:34:32 +01:00
Riccardo Magliocchetti 45f61435a1 core: fix a couple of leaks in uwsgi_opt_load_dl
Reported by Coverity as CID #971049, #971050.
2013-03-09 16:27:57 +01:00
Riccardo Magliocchetti 28153af4ad plugin/python: fix leak in uwsgi_file_loader
Reported by Coverity as CID #971055.
2013-03-09 16:21:16 +01:00
Riccardo Magliocchetti 341cfd90b6 plugin/python: fix a leak in symimporter_load_module
Reported by Coverity as CID #971058.
2013-03-09 16:17:18 +01:00
Riccardo Magliocchetti 82342577a4 plugins/zergpool: fix a couple of memory leaks in add_zergpool_socket
Reported by Coverity as CID #971071, #971070.
2013-03-09 16:02:04 +01:00
Riccardo Magliocchetti 9d735fdbea plugins/python: don't copy router_name in py_uwsgi_route
No need to create a news string since uwsgi_route_api_func use it
for just a strcmp.

Reported by Coverity as CID #989251.
2013-03-09 15:50:02 +01:00
Unbit 1775526b89 improved asp.net support 2013-03-09 15:11:42 +01:00
Unbit c84f205c74 improved mono build 2013-03-09 12:56:40 +01:00
Unbit 591faabc00 fixed spooler plugin 2013-03-09 11:48:56 +01:00
Unbit e945003d07 fixed jwsgi plugin name 2013-03-09 11:27:25 +01:00
Unbit 26c6ec4283 fixed admin and echo plugins 2013-03-09 11:03:46 +01:00
27 changed files with 583 additions and 1008 deletions
-683
View File
@@ -1,683 +0,0 @@
*** current ***
* 1.5
- added --not-alarm-log
- support for TCP_FASTOPEN (Linux-only)
- improved emperor reloading
- added --get
- Legion subsystem
- emperor_zeromq plugin
- SNI support
- distributed SSL session cache
*** november 2012 ***
* 1.4
- gevent improvements
- improved http/https router and fastrouter
- Go official support
- a new set of infos are exported to the stats system
- improved systemd support
- log filtering and routing
- improved tracebacker
- offload transfer for static files, and network transfers
- matheval support
- plugins can be written in Obj-C
- smart attach daemon
- added support for PEP 405 virtualenvs
- rawrouter with xclient support
- internal routing plugin for cache
*** semptember 2012 ***
* 1.3
- python tracebacker
- user-governed harakiri
- simplified external plugin development
- Linux namespace mountpoint improvements
- secured subscription system
- merged routers codebase (fastrouter, http, rawrouter)
- https support in the http router
- config report at the end of uWSGI build process
- improved subscription system (multicast and unix socket)
- custom options
- graceful reloads on shared sockets
- configurable log-master buffer size
- extreme-optimizations for the stats subsystem
- redislog and mongodblog plugins
- added python logger
- mongodb and postgres imperial monitors
- implemented psgix.logger and psgix.cleanup
- full rack spec compliance
- preliminary ipv6 support
- gevent graceful reloads
- support for multiple loggers and logformat
- lazy-apps to load apps after fork() but without changing reloading subsystem
- emperor heartbeat subsystem
- cheaper busyness plugin
- pluggable clock sources
- added router_rewrite and router_http plugins
- external spoolers
- support for section:// and fd:// loaders
- alarm subsystem (with curl and xmpp plugins)
*** april 2012 ***
* 1.2 [20120430]
- PyPy support
- Improved gevent support with threads
- Python auto-reload subsystem
- added --spooler-max-tasks
- pthread robust mutexes support in Linux and Solaris
- posix semaphores support in FreeBSD9
- thread-safe ctime() reporting
- interval support in cron subsystem
- improved syslog support
- better management of disconnected clients
- static files serving improvements
- another set of multithreading optimizations
- minor fixes in the Rack plugin
- Upstart socket-activation support
*** march 2012 ***
* 1.1 [20120317]
- new options parser subsystem
- improved php support
- multiple spooler with multiprocessing
- segmentation fault and floating point exceptions manager
- never-swap option
- zergpool plugin
- perl/psgi multiple interpreters support
- deadlock detector
- pluggable cheaper algos
- new internal routing susbsystem
- preliminary support for config logic
- log rotation infrastructure
- support for paste loggers
- threading improvements
- plugins can now mapped to specific modifiers
- <app> tag is deprecated (use mount option)
- report startup time for apps
- reintroduced expat support
- reintroduced remote spooler plugin
- various fastrouter optimizations
- added ruby rvm support
*** 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]
- various spooler improvements
- upload progress optimizations and fixes
- new emperor mode: Tyrant
- allows multiple --ini options
- better binary path detection
- gevent loop engine support
- resolve domain names in socket logging
- snmp fixes and reintroduction of the snmp-api
- fixed grunt mode
- you can specify build profile via env var UWSGI_PROFILE
- reintroduction of string-based multiapp
- new option --emperor-throttle
- improved queue and sharedarea subsystems
- uWSGI can now be built as a shared library
- new api attribute: uwsgi.magic_table
- improved apache2 module
- new option --pyshell
- allow threads in gateways
- fastrouter improvements
- the application list is now shared and exported to the api
- allows setting the thread stack size
- UWSGI_APPID for better multiapp hosting
- better reloading in lazy mode
- native pump support
- various rack fixes
- support for attaching binary data in the executable
- new option --set
- extreme-optimized http protocol parser
- WSGI handler optimizations
*** 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
- spooler has been extremely improved
- new option --chown-socket
- added uwsgidecorators for elegant uwsgi api access from python
- the rack plugin is now stable
- support for embedding config and generic files in the server binary
- high-performance cache-server
- accept() is now locked on all threads in the same workers
- preliminary implementation of hooks in emperor
- support for C++ in server core
- tcp port auto-bind
- implemented workers, workerN and spooler signal target
- prefork/multithread uwsgi.signal_wait() implementation
- export uwsgi.node in WSGI vars
- new option --import (python plugin)
- support for unlimited number of Linux cgroups
- broodlord mode
*** june 2011 ***
* 0.9.8.1 [20110625]
- the build system has been improved
- various threading fixes
- fix python GIL status after reload
- new option --propagate-touch
- fixed uwsgi.sendfile
- fixed readline() support in wsgi.input
- fixed dynamic touch reload
- new option --logto2
- export %c in config files
- fixed libyaml support
- support passing modifiers in subscription system
- reset random seed in spooler
- subscribe from a list in a text file
- allow binding on port 0 (auto-assignment)
- reset random seed on grunt
- fix vhost mode for empty hostname
- fixed python3+virtualenv support
- tasks are now allowed to chdir() in spooler
- better zeromq+clustering support
- clustering has been refactored
- fixed rpc
- report correct worker id in cheap mode
- fixed a fd-leak in attach-daemon
- use setsid() in attach-daemon
- zerg mode
- added psgix.harakiri
- allows magic vars in sqlite3 config db
- added UWSGI_FASTROUTER_KEY var
- slowdown async-queue-is-full messages
- new option --cron
- --vassals-start-hook and --vassals-stop-hook
- the proxy plugin has been removed
* 0.9.8 [20110605]
- support for --callable in virtualhosting mode
- a NetBSD fix
- abstract unix socket can be prefixed with \0 (nginx-style)
- add /lib to the linker in sun-like systems
- a mercy mode of 5 seconds is enabled by default on SIGINT/SIGQUIT
* 0.9.8-rc4 [20110602]
- fixed REMOTE_ADDR when --protocol=http
- official support for OpenIndiana
- added a welcome.py test script
- new api attribute uwsgi.version_info
- improved the admin plugin
- two new management flag for backlog queue monitoring
- fixed uwsgi_log for bigger loglines
- new option --early-emperor to allows out-of-jail emperors
- emperor can now spawn other emperors (sub-emperors)
- fixed idle mode in single-process
- fixed solaris iovec
*** may 2011 ***
* 0.9.8-rc3 [20110530]
- snapshotting support
- fixed python 3.x spooler
- improvements for grunt processes
- better abstract unix socket
- --log-socket allows logging to generic DGRAM sockets
- a bunch of solaris fixes
- new option --no-fd-passing for fastrouter
- --fastrouter-subscription-slot to set the number of slot in subscription server
- unlimited shared sockets
- fixed netlink compilation
- auto-reconnect on emperor+amqp server disconnection
- various emperor fixes
- unlimited fastrouter sockets
- better cgroup support
- --add-header option allow adding of custom HTTP response headers
- cheap and idle operational modes
* 0.9.8-rc2 [20110521]
- new option --die-on-term
- fixed touch reload
- a couple of optimizations for wsgi.input
- systemd integration
* 0.9.8-rc1 [20110514]
- massive code cleanup and refactoring
- added vassals loyalty concept
- fixed virtualhosting with dynamic virtualenv
- fixed reloading on grand-central-dispatch-enabled OSX
- improved PSGI support with uGreen and async support
- improved Rack support with complete fiber+async in ruby 1.9
- support for JSON config files
- native multi-protocol support (added fastcgi and http)
- Mongrel2 support
- support for templates in vassals
- various threading fixes
- gcc-4.6 support
- support for logging via zeromq
- support for configuration passed via pipe/stdin
- pythonpath entries are now unlimited
- socket entries are unlimited
- pythonpath can be a glob
- lazy mode added
- new language-independent profiling subsystem
- support for configuration stored in a sqlite3 db
- allow workers to survive to syslogd death (when --log-syslog is used)
- fix traceback in Python 3.x
- support for uwsgi signals in threads
- plugin autoloading
- graceful reloading for threads
- new wsgi.input object
- support for alternative allocators (tcmalloc and jemalloc)
*** april 2011 ***
* 0.9.7.2 [20110406]
- new option --touch-reload <file> to reload the stack on <file> modification
--static-map <mountpoint=documentroot> allows to serve static files
- fixed --post-limit management
- disallow empty socket names
- implemented exception_info WSGI support
- new options --reload-on-as <n> and --reload-on-rss <n> allows
to recycle workers when their memory usage is higher than <n> MB
- fixed syslog support (use --log-syslog[=facility] to enable it)
- improved plugin loading system
- added support for RabbitMQ as event dispatcher for the Emperor
- fixed FreeBSD memory report
- PSGI plugin can be compiled without ithreads
- various Emperor fixes
- fixed a regression with setgroups()
- support for shared sockets (used in jails within network namespaces)
*** march 2011 ***
* 0.9.7.1 [20110326]
- fixed python stackless support
- added persistence for queue
- forbid daemonizing in vassal mode
- modifier1 30 is available again
- allow python modules to be mapped/aliased via http
- added --pidfile2 and --logfile-chown
- added UWSGI_CACHE_GET dynamic variable
- 304/If-Modified-Since support for --check-static
- option --check-cache for integrated caching
- option --map-socket to assign specific workers to socket
- fixed unix fd passing on older OSX versions
- fixed post-buffering without pep3333-input
- fixed python threading without uwsgi cores
- support for Linux network namespace
- build with sys.abiflags if necessary
* 0.9.7 [20110317]
- fixed psgi compilation on GNU systems
- improved --pep3333-input
- better error reporting on failed open/fopen
- fixed uGreen
- added greenlet support
- various solaris fixes
- new help system
- updated async support
- fixed uwsgi.cache_get in python
* 0.9.7-rc3 [20110312]
- added support for persistent cache (--cache-store <filename>)
- less verbose file monitoring
- fixed a race condition in emperor startup
- fixed erlang empty list encoding
- improved snmp support
- fixed cache modifier 111 for 3 and 4
- preliminary cpu-affinity support (Linux only)
- fixed ldap support
- auto-configure ldap compilation
- added --allowed-modifiers (allow only a subset of modifiers)
- fixed a bug with getopt_long
* 0.9.7-rc2 [20110309]
- added cron-like interface to signal framework
- improved Linux namespaces support
- fixed multithreading + --max-requests
- added support for reference in configuration files
* 0.9.7-rc1 [20110307]
- export %v in emperor mode
- fixed signal race condition in server reload
- fixed http router post handling bug
- added uwsgi.erlang_register_process in pyerl plugin
- fixed unix socket inherit
- fixed linux namespace support in recent kernel/gcc
- ported threading to python 3.2
- add build date to uWSGI startup info
- do not allow clustering without defining a socket
- kill all the gateways/daemons on startup errors
- fixed vacuum after chdir()
- fixed gateways reload
- re-added support for OpenBSD and NetBSD
- fixed post-buffering in python
- use erlang binary for python string
- fixed memory leak in pyerl plugin
- removed broken log rotation (post-poned)
- fixed no_argument options in ini and yaml parsing
* 0.9.7-beta1 [20110301]
- fully modular re-design
- advanced build system with presets
- threading support
- emperor mode for massive auto-hosting
- caching subsystem
- message queue (even stacked) support
- improved server reloading system
- support for Linux Cgroups and Namespaces
- integrated upload progress
- Clustering infrastructure via multicast, broadcast or subscriptions
- support for attaching/monitoring external apps to the master process
- improved virtualhosting mode
- extremely improved Python support with better usage of multiple interpreters
- improved multiple apps support
- Production ready, evented HTTP router/proxy/load-balancer
- Production ready, evented uwsgi router/proxy/load-balancer
- new Erlang stack
- Internal signal subsystem
- support for RubyOnRails and Rack apps
- A huge series of fixes and optimizations
*** february 2011 ***
* 0.9.6.8 [20110207]
- fixed a bug when using --limit-as
- fixed a erlang buffer initialization
- added --ignore-sigpipe
- added --master-as-root
*** january 2011 ***
* 0.9.6.7 [20110130]
- a huge amount of async optimizations and fixes
- --logdate takes an optional strftime-like value
- follow $PATH on reloading
- uwsgi.core is exported in WSGI env
- uwsgi.log() respect for --logdate
- initial banner respect for --logdate
- fixed --post-buffering
- default listen backlog queue is now 100
- Python 3 support is no more marked as experimental
- Python 3.2 support
- new option --chroot-reload will force a reload of the uWSGI stack after a chroot
- fixed a typo in INI parsing
*** december 2010 ***
* 0.9.6.6 [20101230]
- support for YAML configuration files
- backported python module aliasing from 0.9.7-dev
- better apache2 module (support for SetEnv directive, fixed REQUEST_URI and improved connection handling)
- uwsgi.post_fork_hook implementation (to execute function after fork()) (thanks George Kollias)
- option --gid calls setgroups() after setgid() (thanks Jorge Cardona)
- fixed uGreen compilation (and uGreen is now built by default)
- fixed timeout and thundering herd problem in async modes (many thanks to Test157 for giving us a good async-test-app)
- disable TCP_INFO in older Linux kernels (thanks Bo Shi)
- enable TCP_INFO in FreeBSD (limited usage due to FreeBSD kernel support)
- fixed static virtualhosting mode using xml files (thanks Guido Notari of Link I.T. spa)
- new option --close-on-exec (thanks Jean-Baptiste Quenot)
- use HTTP_HOST var (and fallback to SERVER_NAME) in virtual hosting mode
- fixed a buffer overflow in automatic socket_name allocation (spotted by Riccardo Magliocchetti)
- Official support for Nexenta
*** september 2010 ***
* 0.9.6.5 [20100929]
- PEP 3333 support
- fix --pythonpath with --wsgi-file
- x-wsgiorg.uwsgi.version renamed to uwsgi.version
* 0.9.6.4 [20100925]
- fix a stupid bug in conditional logging backport
* 0.9.6.3 [20100925]
- fix a buffer overflow in .ini parsing (it throws a glibc error on malloc)
- backport of conditional logging from 0.9.7-dev
- backport of backlog queue monitor from 0.9.7-dev (only Linux)
* 0.9.6.2 [20100915]
- fix a regression in virtual hosting mode
- fix pythonpath usage in --ini and --ini-paste
- new uwsgi packet var: UWSGI_CHDIR
* 0.9.6.1 [20100912]
- print the request uri during SIGPIPE or HARAKIRI
- added SIGUSR2 support (it will print the current running request, if available)
- protocol parsing optimization
- fixed --logto support
- new --eval option allows inline definition of WSGI script
- support for defining WSGI script in xml using CDATA
- allow --pp as --pythonpath shortcut
- various spooler optimizations and fixes
- added -O2 optimization by default
- added uwsgi.is_a_reload commodity function
- .ini file support fix
- SNMP agent fix
- support for subprocesses generated by master
- fix a regression in SCRIPT_NAME handling
- Haiku official support
- gcc 2.95 support
- dynamic app management optimizations
- export x-wsgiorg.uwsgi.version in WSGI env
*** august 2010 ***
* 0.9.6 [20100829]
- better handling of SCRIPT_NAME
- vacuum option for deleting unix sockets and pidfiles after usage
- advanced XML configuration
- new configuration systems: INI files and LDAP
- embedded HTTP server for development/testing
- better signal handling
- PSGI plugin improved
- usability fixes and new commodities options for root startup
- grunt processes (detached workers)
- preliminary integrated virtualhosting mode
- new option catch-exceptions can redirect python exceptions to your browser
- logging improvements (--logto and --logdate options)
- Full PEP 333 compliant usage of wsgi.file_wrapper
- re-initialize random seed after every fork() [security fix]
- fix Spooler's usage of stdin
- export WSGI environment in uwsgi.env (for doing evil things)
- logsize tracking (uwsgi.logsize) for future embedded log rotation
*** july 2010 ***
* 0.9.5.4 [20100706]
*** june 2010 ***
* 0.9.5.3 [20100628]
- fixed linux x86_64 compilation (sorry)
* 0.9.5.2 [20100626] *
- fixed a request parsing bug
- applied debian fixes
- fixed multiple interpreter sys.argv
- improved --chmod-socket
- fixed uid 0 SIGHUP
- updated nginx and apache modules
- updated PSGI, lua and example plugin
- fixed --pyargv with python 3.x
- improved plugin build system
*** may 2010 ***
* 0.9.5.1 [20100519] *
- fixed paste support
- added a new modifier (22)
- full support for configuration via environment variables
- nginx_string option in nginx module
- fix for harakiri without master
- backported unladen swallow support for 0.9.6-dev
- fixed address space limit detection via getrlimit()
- http body buffering implementation
- added --prio option (to set priority)
- added --post-limit to limit the size of uploads
- added --logto option to allow udp logging without daemonizing
- applied Gentoo's packagers fixes for build system
* 0.9.5 [20100501] *
- hook based request/modifier management
- plugin support via dlopen
- on-the-fly management flag
- integrated proxy
- logging via udp
- improved spooler for cron-like apps
- async support
- green thread platform (uGreen) on top of the async mode
- transparent Erlang integration
- embedded snmp agent
- nagios mode
- improved python 3.x support
- improved xml configuration
- new build system
- address space usage limiting
- lot of portability fixes
- lot of optimizations and code refactoring
*** april 2010 ***
* Fourth Maintenance release [20100427] *
- backported non-yielding app optimization from 0.9.5
- backported udp logging from 0.9.5
- backported uwsgi_error() from 0.9.5 (no more dumb perror())
- fix a rare (but possible) segmentation fault
- added --version
- updated apache2 module
*** march 2010 ***
* Third Maintenance release [20100310] *
- fix sendfile on 64bit
- include setup.py
*** february 2010 ***
* Maintenance release *
- better support for NetBSD
- threading fix for FreeBSD
- sendfile portability fixes
- new makefiles
- example app for testing static file serving
- fixes for ROCK_SOLID mode
*** january 2010 ***
- Integrated Spooler
- better error management
- long options
- clustering functions
- experimental lighttpd module
- official support for OpenBSD and OpenSolaris
- FastFuncs
- new functions for embedded module
- reliable harakiri
- better Makefiles
- python threads support in master process
- proper timeout handling in apache2 module
- endianess fixes all over the place
- paste support
- Django app for managing and monitoring the uWSGI server
- options for changin uid/gid and chrooting when run by root
- lot of bugfixes and optimizations
*** 20091129 Version 0.9.3 ***
- Nginx 0.7.x module
- configuration via python module
- support (non-standard) for Python 3.x
- Twisted client resource adapter
- graceful restart of worker processes and hot-plug substitution/upgrade of the uWSGI server
- shared memory area to share data between workers/processes
- Tomcat handler
- support for virtualenv
- tons of bugfixes and optimizations
*** 20090829 Version 0.9.2 ***
- TCP support
- configurable internal timeout (socket/poll)
- Cherokee handler
- code refactoring
- Makefiles
- customizable harakiri handler (put an harakiri(environ, start_response) function in your wsgi script)
- limit requests per worker
- a lot of bugfix and optimizations
+4
View File
@@ -0,0 +1,4 @@
[uwsgi]
# pypy,jvm,ring,jwsgi
main_plugin = erlang,psgi,rack,lua,python,gevent,php,cgi,mono,pyerl,go
inherit = base
+1 -1
View File
@@ -296,7 +296,7 @@ void uwsgi_commandline_config() {
void uwsgi_setup_workers() {
int i, j;
// allocate shared memory for workers + master
uwsgi.workers = (struct uwsgi_worker *) uwsgi_calloc_shared(sizeof(struct uwsgi_worker) * (uwsgi.numproc + 1 + uwsgi.grunt));
uwsgi.workers = (struct uwsgi_worker *) uwsgi_calloc_shared(sizeof(struct uwsgi_worker) * (uwsgi.numproc + 1));
for (i = 0; i <= uwsgi.numproc; i++) {
// allocate memory for apps
+92 -6
View File
@@ -75,6 +75,10 @@ void uwsgi_parse_legion(char *key, uint16_t keylen, char *value, uint16_t vallen
memcpy(ul->lord_uuid, value, 36);
}
}
else if (!uwsgi_strncmp(key, keylen, "scroll", 6)) {
ul->scroll = value;
ul->scroll_len = vallen;
}
}
// critical section (remember to lock when you use it)
@@ -170,9 +174,9 @@ static void legions_check_nodes() {
struct uwsgi_legion_node *tmp_node = node;
node = node->next;
uwsgi_log("[uwsgi-legion] node: %.*s valor: %llu uuid: %.*s left Legion %s\n", tmp_node->name_len, tmp_node->name, tmp_node->valor, 36, tmp_node->uuid, legion->legion);
pthread_mutex_lock(&legion->lock);
uwsgi_wlock(legion->lock);
uwsgi_legion_remove_node(legion, tmp_node);
pthread_mutex_unlock(&legion->lock);
uwsgi_rwunlock(legion->lock);
continue;
}
node = node->next;
@@ -281,6 +285,15 @@ static void legions_check_nodes_step2() {
}
usl = usl->next;
}
if (ul->scroll_len > 0 && ul->scroll_len <= ul->lord_scroll_size) {
uwsgi_wlock(ul->lock);
ul->lord_scroll_len = ul->scroll_len;
memcpy(ul->lord_scroll, ul->scroll, ul->lord_scroll_len);
uwsgi_rwunlock(ul->lock);
}
else {
ul->lord_scroll_len = 0;
}
ul->i_am_the_lord = uwsgi_now();
// trick: reduce the time needed by the old lord to unlord itself
uwsgi_legion_announce(ul);
@@ -289,6 +302,11 @@ static void legions_check_nodes_step2() {
else {
if (ul->i_am_the_lord) {
uwsgi_log("[uwsgi-legion] a new Lord (valor: %llu uuid: %.*s) raised for Legion %s...\n", ul->lord_valor, 36, ul->lord_uuid, ul->legion);
if (ul->lord_scroll_len > 0) {
uwsgi_log("*********** The New Lord Scroll ***********\n\n");
uwsgi_log("%.*s\n", ul->lord_scroll_len, ul->lord_scroll);
uwsgi_log("\n*********** End of the New Lord Scroll ***********\n\n");
}
// no more lord, trigger unlord hooks
struct uwsgi_string_list *usl = ul->unlord_hooks;
while (usl) {
@@ -354,6 +372,18 @@ struct uwsgi_legion_node *uwsgi_legion_get_lord(struct uwsgi_legion *ul) {
ul->lord_valor = best_valor;
memcpy(ul->lord_uuid, best_uuid, 36);
if (!best_node) return NULL;
if (best_node->scroll_len > 0 && best_node->scroll_len <= ul->lord_scroll_size) {
uwsgi_wlock(ul->lock);
ul->lord_scroll_len = best_node->scroll_len;
memcpy(ul->lord_scroll, best_node->scroll, ul->lord_scroll_len);
uwsgi_rwunlock(ul->lock);
}
else {
ul->lord_scroll_len = 0;
}
return best_node;
}
@@ -483,9 +513,15 @@ static void *legion_loop(void *foobar) {
struct uwsgi_legion_node *node = uwsgi_legion_get_node(ul, legion_msg.valor, legion_msg.name, legion_msg.name_len, legion_msg.uuid);
if (!node) {
// add the new node
pthread_mutex_lock(&ul->lock);
uwsgi_wlock(ul->lock);
node = uwsgi_legion_add_node(ul, legion_msg.valor, legion_msg.name, legion_msg.name_len, legion_msg.uuid);
pthread_mutex_unlock(&ul->lock);
if (!node) continue;
if (legion_msg.scroll_len > 0) {
node->scroll = uwsgi_malloc(legion_msg.scroll_len);
node->scroll_len = legion_msg.scroll_len;
memcpy(node->scroll, legion_msg.scroll, node->scroll_len);
}
uwsgi_rwunlock(ul->lock);
uwsgi_log("[uwsgi-legion] node: %.*s valor: %llu uuid: %.*s joined Legion %s\n", node->name_len, node->name, node->valor, 36, node->uuid, ul->legion);
}
@@ -624,6 +660,11 @@ int uwsgi_legion_announce(struct uwsgi_legion *ul) {
goto err;
if (uwsgi_buffer_append_keyval(ub, "lord_uuid", 9, ul->lord_uuid, 36))
goto err;
if (ul->scroll_len > 0) {
if (uwsgi_buffer_append_keyval(ub, "scroll", 6, ul->scroll, ul->scroll_len))
goto err;
}
#ifdef UWSGI_UUID
#endif
@@ -716,8 +757,33 @@ void uwsgi_opt_legion_quorum(char *opt, char *value, void *foobar) {
}
ul->quorum = atoi(space+1);
free(legion);
}
void uwsgi_opt_legion_scroll(char *opt, char *value, void *foobar) {
char *legion = uwsgi_str(value);
char *space = strchr(legion, ' ');
if (!space) {
uwsgi_log("invalid legion-scroll syntax, must be <legion> <scroll>\n");
exit(1);
}
*space = 0;
struct uwsgi_legion *ul = uwsgi_legion_get_by_name(legion);
if (!ul) {
uwsgi_log("unknown legion: %s\n", legion);
exit(1);
}
ul->scroll = space+1;
ul->scroll_len = strlen(ul->scroll);
// DO NOT FREE IT !!!
//free(legion);
}
void uwsgi_opt_legion_hook(char *opt, char *value, void *foobar) {
@@ -867,7 +933,12 @@ void uwsgi_opt_legion(char *opt, char *value, void *foobar) {
ul->encrypt_ctx = ctx;
ul->decrypt_ctx = ctx2;
pthread_mutex_init(&ul->lock, NULL);
if (!uwsgi.legion_scroll_max_size) {
uwsgi.legion_scroll_max_size = 4096;
}
ul->lord_scroll_size = uwsgi.legion_scroll_max_size;
ul->lord_scroll = uwsgi_calloc_shared(ul->lord_scroll_size);
uwsgi_legion_add(ul);
}
@@ -929,8 +1000,23 @@ next:
int uwsgi_legion_i_am_the_lord(char *name) {
struct uwsgi_legion *legion = uwsgi_legion_get_by_name(name);
if (legion && legion->i_am_the_lord) {
if (!legion) return 0;
if (legion->i_am_the_lord) {
return 1;
}
return 0;
}
char *uwsgi_legion_lord_scroll(char *name, uint16_t *rlen) {
char *buf = NULL;
struct uwsgi_legion *legion = uwsgi_legion_get_by_name(name);
if (!legion) return 0;
uwsgi_rlock(legion->lock);
if (legion->lord_scroll_len > 0) {
buf = uwsgi_malloc(legion->lord_scroll_len);
memcpy(buf, legion->lord_scroll, legion->lord_scroll_len);
*rlen = legion->lord_scroll_len;
}
uwsgi_rwunlock(legion->lock);
return buf;
}
+9
View File
@@ -641,6 +641,15 @@ ready:
}
uwsgi.rpc_table_lock = uwsgi_lock_init("rpc");
#ifdef UWSGI_SSL
// register locking for legions
struct uwsgi_legion *ul = uwsgi.legions;
while(ul) {
ul->lock = uwsgi_lock_init(uwsgi_concat2("legion_", ul->legion));
ul = ul->next;
}
#endif
uwsgi.locking_setup = 1;
}
+3 -3
View File
@@ -1312,7 +1312,7 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
if (uwsgi_stats_list_open(us))
goto end;
pthread_mutex_lock(&legion->lock);
uwsgi_rlock(legion->lock);
struct uwsgi_legion_node *node = legion->nodes_head;
while (node) {
if (uwsgi_stats_object_open(us))
@@ -1342,7 +1342,7 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
goto unlock_legion_mutex;
}
}
pthread_mutex_unlock(&legion->lock);
uwsgi_rwunlock(legion->lock);
if (uwsgi_stats_list_close(us))
goto end;
@@ -1371,7 +1371,7 @@ struct uwsgi_stats *uwsgi_master_generate_stats() {
#ifdef UWSGI_SSL
unlock_legion_mutex:
if (legion)
pthread_mutex_unlock(&legion->lock);
uwsgi_rwunlock(legion->lock);
#endif
end:
free(us->base);
+1
View File
@@ -437,6 +437,7 @@ void uwsgi_setup_mules_and_farms() {
mules_list++;
strncpy(uwsgi.farms[i].name, farm_value, 0xff);
free(farm_value);
// create the socket pipe
create_signal_pipe(uwsgi.farms[i].signal_pipe);
+63 -53
View File
@@ -28,13 +28,6 @@ ssize_t send_udp_message(uint8_t modifier1, uint8_t modifier2, char *host, char
struct uwsgi_header *uh;
if (message) {
uh = (struct uwsgi_header *) message;
}
else {
uh = (struct uwsgi_header *) uwsgi_malloc(4);
}
udp_port = strchr(host, ':');
if (udp_port) {
udp_port[0] = 0;
@@ -64,6 +57,13 @@ ssize_t send_udp_message(uint8_t modifier1, uint8_t modifier2, char *host, char
}
if (message) {
uh = (struct uwsgi_header *) message;
}
else {
uh = (struct uwsgi_header *) uwsgi_malloc(4);
}
uh->modifier1 = modifier1;
#ifdef __BIG_ENDIAN__
uh->pktsize = uwsgi_swap16(message_size);
@@ -578,7 +578,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
ptrbuf = buffer;
bufferend = ptrbuf + wsgi_req->uh->pktsize;
int i;
/* set an HTTP 500 status as default */
wsgi_req->status = 500;
@@ -673,7 +673,6 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
next:
// manage post buffering (if needed as post_file could be created before)
if (uwsgi.post_buffering > 0 && !wsgi_req->post_file) {
// read to disk if post_cl > post_buffering (it will eventually do upload progress...)
@@ -759,12 +758,7 @@ next:
}
// check for static files
// skip methods other than GET and HEAD
if (uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "GET", 3) && uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "HEAD", 4)) {
return 0;
}
/* CHECK FOR STATIC FILES */
// skip extensions
struct uwsgi_string_list *sse = uwsgi.static_skip_ext;
@@ -886,44 +880,6 @@ nextsm2:
return 0;
}
ssize_t uwsgi_send_empty_pkt(int fd, char *socket_name, uint8_t modifier1, uint8_t modifier2) {
struct uwsgi_header uh;
char *port;
uint16_t s_port;
struct sockaddr_in uaddr;
int ret;
uh.modifier1 = modifier1;
uh.pktsize = 0;
uh.modifier2 = modifier2;
if (socket_name) {
port = strchr(socket_name, ':');
if (!port)
return -1;
s_port = atoi(port + 1);
port[0] = 0;
memset(&uaddr, 0, sizeof(struct sockaddr_in));
uaddr.sin_family = AF_INET;
uaddr.sin_addr.s_addr = inet_addr(socket_name);
uaddr.sin_port = htons(s_port);
port[0] = ':';
ret = sendto(fd, &uh, 4, 0, (struct sockaddr *) &uaddr, sizeof(struct sockaddr_in));
}
else {
ret = send(fd, &uh, 4, 0);
}
if (ret < 0) {
uwsgi_error("sendto()");
}
return ret;
}
int uwsgi_hooked_parse(char *buffer, size_t len, void (*hook) (char *, uint16_t, char *, uint16_t, void *), void *data) {
char *ptrbuf, *bufferend;
@@ -1043,3 +999,57 @@ char *uwsgi_req_append(struct wsgi_request *wsgi_req, char *key, uint16_t keylen
return ptr;
}
int uwsgi_req_append_path_info_with_index(struct wsgi_request *wsgi_req, char *index, uint16_t index_len) {
uint8_t need_slash = 0;
if (wsgi_req->path_info_len > 0) {
if (wsgi_req->path_info[wsgi_req->path_info_len-1] != '/') {
need_slash = 1;
}
}
wsgi_req->path_info_len += need_slash + index_len;
// 2 + 9 + 2
if ((wsgi_req->uh->pktsize + (13 + wsgi_req->path_info_len)) > uwsgi.buffer_size) {
uwsgi_log("not enough buffer space to transform the PATH_INFO variable, consider increasing it with the --buffer-size option\n");
return -1;
}
if (wsgi_req->var_cnt >= uwsgi.vec_size - (4 + 2)) {
uwsgi_log("max vec size reached for PATH_INFO + index. skip this request.\n");
return -1;
}
uint16_t keylen = 9;
char *ptr = wsgi_req->buffer + wsgi_req->uh->pktsize;
*ptr++ = (uint8_t) (keylen & 0xff);
*ptr++ = (uint8_t) ((keylen >> 8) & 0xff);
memcpy(ptr, "PATH_INFO", keylen);
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = ptr;
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = keylen;
wsgi_req->var_cnt++;
ptr += keylen;
*ptr++ = (uint8_t) (wsgi_req->path_info_len & 0xff);
*ptr++ = (uint8_t) ((wsgi_req->path_info_len >> 8) & 0xff);
char *new_path_info = ptr;
memcpy(ptr, wsgi_req->path_info, wsgi_req->path_info_len - (need_slash + index_len));
ptr+=wsgi_req->path_info_len - (need_slash + index_len);
if (need_slash) {
*ptr ++= '/';
}
memcpy(ptr, index, index_len);
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = new_path_info;
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = wsgi_req->path_info_len;
wsgi_req->var_cnt++;
wsgi_req->uh->pktsize += 13 + wsgi_req->path_info_len;
wsgi_req->path_info = new_path_info;
return 0;
}
+1
View File
@@ -47,6 +47,7 @@ void uwsgi_init_queue() {
// fix header
uwsgi.queue_header = uwsgi.queue;
uwsgi.queue += 16;
close(queue_fd);
}
else {
uwsgi.queue = mmap(NULL, (uwsgi.queue_blocksize * uwsgi.queue_size) + 16, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+18 -15
View File
@@ -72,8 +72,9 @@ struct uwsgi_buffer *uwsgi_routing_translate(struct wsgi_request *wsgi_req, stru
}
// add the final NULL byte (to simplify plugin work)
if (uwsgi_buffer_append(ub, "\0", 1)) goto error;
// .. but came back of 1 position to avoid accounting it
ub->pos--;
if (pass1 != data) {
free(pass1);
@@ -85,17 +86,21 @@ error:
return NULL;
}
static int uwsgi_apply_routes_do(struct wsgi_request *wsgi_req, char *subject, uint16_t subject_len) {
int uwsgi_apply_routes_do(struct wsgi_request *wsgi_req, char *subject, uint16_t subject_len) {
struct uwsgi_route *routes = uwsgi.routes;
void *goon_func = NULL;
int n = -1;
char *orig_subject = subject;
uint16_t orig_subject_len = subject_len;
while (routes) {
if (wsgi_req->route_goto > 0 && wsgi_req->route_pc < wsgi_req->route_goto) {
goto next;
}
if (goon_func && goon_func == routes->func) {
goto next;
}
@@ -149,6 +154,8 @@ static int uwsgi_apply_routes_do(struct wsgi_request *wsgi_req, char *subject, u
}
}
next:
subject = orig_subject;
subject_len = orig_subject_len;
routes = routes->next;
if (routes) wsgi_req->route_pc++;
}
@@ -169,28 +176,21 @@ int uwsgi_apply_routes(struct wsgi_request *wsgi_req) {
return UWSGI_ROUTE_BREAK;
}
// in case ogf static files serving previous rules could be applied
if (wsgi_req->routes_applied) {
return UWSGI_ROUTE_CONTINUE;
}
return uwsgi_apply_routes_do(wsgi_req, NULL, 0);
}
int uwsgi_apply_routes_fast(struct wsgi_request *wsgi_req, char *subject, uint16_t subject_len) {
if (!uwsgi.routes)
return UWSGI_ROUTE_CONTINUE;
// avoid loops
if (wsgi_req->is_routing)
return UWSGI_ROUTE_CONTINUE;
return uwsgi_apply_routes_do(wsgi_req, subject, subject_len);
}
static void *uwsgi_route_get_condition_func(char *name) {
struct uwsgi_route_condition *urc = uwsgi.route_conditions;
while(urc) {
if (!strcmp(urc->name, name)) {
return urc->func;
}
urc = urc->next;
}
return NULL;
}
@@ -344,12 +344,14 @@ int uwsgi_route_api_func(struct wsgi_request *wsgi_req, char *router, char *args
}
r = r->next;
}
free(args);
return -1;
found:
ur = uwsgi_calloc(sizeof(struct uwsgi_route));
// initialize the virtual route
if (r->func(ur, args)) {
free(ur);
free(args);
return -1;
}
// call it
@@ -358,6 +360,7 @@ found:
ur->free(ur);
}
free(ur);
free(args);
return ret;
}
+25 -7
View File
@@ -393,7 +393,7 @@ ssize_t uwsgi_append_static_path(char *dir, size_t dir_len, char *file, size_t f
return len;
}
int uwsgi_static_stat(char *filename, size_t *filename_len, struct stat *st) {
static int uwsgi_static_stat(struct wsgi_request *wsgi_req, char *filename, size_t *filename_len, struct stat *st, struct uwsgi_string_list **index) {
int ret = stat(filename, st);
// if non-existant return -1
@@ -412,7 +412,8 @@ int uwsgi_static_stat(char *filename, size_t *filename_len, struct stat *st) {
#ifdef UWSGI_DEBUG
uwsgi_log("checking for %s\n", filename);
#endif
if (!uwsgi_static_stat(filename, filename_len, st)) {
if (uwsgi_is_file2(filename, st)) {
*index = usl;
*filename_len = new_len;
return 0;
}
@@ -521,6 +522,7 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
char *filename = NULL;
size_t filename_len = 0;
struct uwsgi_string_list *index = NULL;
if (!is_a_file) {
filename = uwsgi_concat3n(document_root, document_root_len, "/", 1, path_info, path_info_len);
@@ -580,23 +582,39 @@ found:
safe:
if (!uwsgi_static_stat(real_filename, &real_filename_len, &st)) {
if (!uwsgi_static_stat(wsgi_req, real_filename, &real_filename_len, &st, &index)) {
if (index) {
// if we are here the PATH_INFO need to be changed
if (uwsgi_req_append_path_info_with_index(wsgi_req, index->value, index->len)) {
return -1;
}
}
// skip methods other than GET and HEAD
if (uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "GET", 3) && uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "HEAD", 4)) {
return -1;
}
// check for skippable ext
struct uwsgi_string_list *sse = uwsgi.static_skip_ext;
while (sse) {
if (real_filename_len >= sse->len) {
if (!uwsgi_strncmp(real_filename + (real_filename_len - sse->len), sse->len, sse->value, sse->len)) {
#ifdef UWSGI_ROUTING
if (uwsgi_apply_routes_fast(wsgi_req, real_filename, real_filename_len) == UWSGI_ROUTE_BREAK)
return 0;
#endif
return -1;
}
}
sse = sse->next;
}
#ifdef UWSGI_ROUTING
// before sending the file, we need to check if some rule applies
if (uwsgi_apply_routes_do(wsgi_req, NULL, 0) == UWSGI_ROUTE_BREAK) {
return 0;
}
wsgi_req->routes_applied = 1;
#endif
return uwsgi_real_file_serve(wsgi_req, real_filename, real_filename_len, &st);
}
+2
View File
@@ -452,6 +452,7 @@ void uwsgi_stats_pusher_setup() {
pusher = uwsgi_stats_pusher_get(ssp);
if (!pusher) {
uwsgi_log("unable to find \"%s\" stats_pusher\n", ssp);
free(ssp);
exit(1);
}
char *arg = NULL;
@@ -461,6 +462,7 @@ void uwsgi_stats_pusher_setup() {
}
uwsgi_stats_pusher_add(pusher, arg);
usl = usl->next;
free(ssp);
}
}
+28 -4
View File
@@ -659,7 +659,7 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
}
// defunct process reaper
if (uwsgi.shared->options[UWSGI_OPTION_REAPER] == 1 || uwsgi.grunt) {
if (uwsgi.shared->options[UWSGI_OPTION_REAPER] == 1) {
while (waitpid(WAIT_ANY, &waitpid_status, WNOHANG) > 0);
}
@@ -1248,6 +1248,16 @@ int uwsgi_is_file(char *filename) {
return 0;
}
int uwsgi_is_file2(char *filename, struct stat *st) {
if (stat(filename, st)) {
return 0;
}
if (S_ISREG(st->st_mode))
return 1;
return 0;
}
int uwsgi_is_dir(char *filename) {
struct stat st;
if (stat(filename, &st)) {
@@ -1504,7 +1514,7 @@ void add_exported_option(char *key, char *value, int configured) {
while (blacklist) {
if (!strcmp(key, blacklist->value)) {
uwsgi_log("uWSGI error: forbidden option \"%s\"\n", key);
uwsgi_log("uWSGI error: forbidden option \"%s\" (by blacklist)\n", key);
exit(1);
}
blacklist = blacklist->next;
@@ -1520,11 +1530,25 @@ void add_exported_option(char *key, char *value, int configured) {
whitelist = whitelist->next;
}
if (!allowed) {
uwsgi_log("uWSGI error: forbidden option \"%s\"\n", key);
uwsgi_log("uWSGI error: forbidden option \"%s\" (by whitelist)\n", key);
exit(1);
}
}
if (uwsgi.blacklist_context) {
if (uwsgi_list_has_str(uwsgi.blacklist_context, key)) {
uwsgi_log("uWSGI error: forbidden option \"%s\" (by blacklist)\n", key);
exit(1);
}
}
if (uwsgi.whitelist_context) {
if (!uwsgi_list_has_str(uwsgi.whitelist_context, key)) {
uwsgi_log("uWSGI error: forbidden option \"%s\" (by whitelist)\n", key);
exit(1);
}
}
if (uwsgi.logic_opt_running)
goto add;
@@ -1839,7 +1863,7 @@ int uwsgi_list_has_num(char *list, int num) {
int uwsgi_list_has_str(char *list, char *str) {
char *list2 = uwsgi_concat2(list + 1, "");
char *list2 = uwsgi_str(list);
char *p = strtok(list2, " ");
while (p != NULL) {
+20 -7
View File
@@ -109,6 +109,12 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"endif", optional_argument, 0, "(opt logic) end if", uwsgi_opt_noop, NULL, UWSGI_OPT_IMMEDIATE},
{"blacklist", required_argument, 0, "set options blacklist context", uwsgi_opt_set_str, &uwsgi.blacklist_context, UWSGI_OPT_IMMEDIATE},
{"end-blacklist", no_argument, 0, "clear options blacklist context", uwsgi_opt_set_null, &uwsgi.blacklist_context, UWSGI_OPT_IMMEDIATE},
{"whitelist", required_argument, 0, "set options whitelist context", uwsgi_opt_set_str, &uwsgi.whitelist_context, UWSGI_OPT_IMMEDIATE},
{"end-whitelist", no_argument, 0, "clear options whitelist context", uwsgi_opt_set_null, &uwsgi.whitelist_context, UWSGI_OPT_IMMEDIATE},
{"ignore-sigpipe", no_argument, 0, "do not report (annoying) SIGPIPE", uwsgi_opt_true, &uwsgi.ignore_sigpipe, 0},
{"ignore-write-errors", no_argument, 0, "do not report (annoying) write()/writev() errors", uwsgi_opt_true, &uwsgi.ignore_write_errors, 0},
{"write-errors-tolerance", required_argument, 0, "set the maximum number of allowed write errors (default: no tolerance)", uwsgi_opt_set_64bit, &uwsgi.write_errors_tolerance, 0},
@@ -366,6 +372,9 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"legion-setup", required_argument, 0, "action to call on legion setup", uwsgi_opt_legion_hook, NULL, UWSGI_OPT_MASTER},
{"legion-death", required_argument, 0, "action to call on legion death (shutdown of the instance)", uwsgi_opt_legion_hook, NULL, UWSGI_OPT_MASTER},
{"legion-quorum", required_argument, 0, "set the quorum of a legion", uwsgi_opt_legion_quorum, NULL, UWSGI_OPT_MASTER},
{"legion-scroll", required_argument, 0, "set the scroll of a legion", uwsgi_opt_legion_scroll, NULL, UWSGI_OPT_MASTER},
{"legion-scroll", required_argument, 0, "set the scroll of a legion", uwsgi_opt_legion_scroll, NULL, UWSGI_OPT_MASTER},
{"legion-scroll-max-size", required_argument, 0, "set max size of legion scroll buffer", uwsgi_opt_set_16bit, &uwsgi.legion_scroll_max_size, 0},
{"subscriptions-sign-check", required_argument, 0, "set digest algorithm and certificate directory for secured subscription system", uwsgi_opt_scd, NULL, UWSGI_OPT_MASTER},
{"subscriptions-sign-check-tolerance", required_argument, 0, "set the maximum tolerance (in seconds) of clock skew for secured subscription system", uwsgi_opt_set_int, &uwsgi.subscriptions_sign_check_tolerance, UWSGI_OPT_MASTER},
#endif
@@ -476,7 +485,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"die-on-idle", no_argument, 0, "shutdown uWSGI when idle", uwsgi_opt_true, &uwsgi.die_on_idle, 0},
{"mount", required_argument, 0, "load application under mountpoint", uwsgi_opt_add_string_list, &uwsgi.mounts, 0},
{"worker-mount", required_argument, 0, "load application under mountpoint in the specified worker or after workers spawn", uwsgi_opt_add_string_list, &uwsgi.mounts, 0},
{"grunt", no_argument, 0, "enable grunt mode (in-request fork)", uwsgi_opt_true, &uwsgi.grunt, 0},
{"threads", required_argument, 0, "run each worker in prethreaded mode with the specified number of threads", uwsgi_opt_set_int, &uwsgi.threads, UWSGI_OPT_THREADS},
{"thread-stacksize", required_argument, 0, "set threads stacksize", uwsgi_opt_set_int, &uwsgi.threads_stacksize, UWSGI_OPT_THREADS},
@@ -602,9 +610,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"allowed-modifiers", required_argument, 0, "comma separated list of allowed modifiers", uwsgi_opt_set_str, &uwsgi.allowed_modifiers, 0},
{"remap-modifier", required_argument, 0, "remap request modifier from one id to another", uwsgi_opt_set_str, &uwsgi.remap_modifier, 0},
{"app", required_argument, 0, "*** deprecated ***", uwsgi_opt_deprecated, (void *) "use the more advanced \"mount\" option", 0},
{"static-offload-to-thread", required_argument, 0, "*** deprecated ***", uwsgi_opt_deprecated, (void *) "use the more advanced \"offload-threads\" option", 0},
{"dump-options", no_argument, 0, "dump the full list of available options", uwsgi_opt_true, &uwsgi.dump_options, 0},
{"show-config", no_argument, 0, "show the current config reformatted as ini", uwsgi_opt_true, &uwsgi.show_config, 0},
{"print", required_argument, 0, "simple print", uwsgi_opt_print, NULL, 0},
@@ -1264,6 +1269,7 @@ void signal_pidfile(int sig, char *filename) {
else {
uwsgi_log("error: invalid pidfile\n");
}
free(buffer);
}
/*static*/ void uwsgi_command_signal(char *opt) {
@@ -3224,6 +3230,12 @@ void uwsgi_opt_set_str(char *opt, char *value, void *key) {
*ptr = (char *) value;
}
void uwsgi_opt_set_null(char *opt, char *value, void *key) {
char **ptr = (char **) key;
*ptr = NULL;
}
void uwsgi_opt_set_logger(char *opt, char *value, void *prefix) {
if (!value)
@@ -3457,7 +3469,8 @@ void uwsgi_opt_load_dl(char *opt, char *value, void *none) {
void uwsgi_opt_load_plugin(char *opt, char *value, void *none) {
char *p = strtok(uwsgi_concat2(value, ""), ",");
char *plugins_list = uwsgi_concat2(value, "");
char *p = strtok(plugins_list, ",");
while (p != NULL) {
#ifdef UWSGI_DEBUG
uwsgi_debug("loading plugin %s\n", p);
@@ -3467,6 +3480,8 @@ void uwsgi_opt_load_plugin(char *opt, char *value, void *none) {
}
p = strtok(NULL, ",");
}
free(p);
free(plugins_list);
}
void uwsgi_opt_check_static(char *opt, char *value, void *foobar) {
@@ -3824,7 +3839,6 @@ void uwsgi_opt_flock(char *opt, char *filename, void *none) {
uwsgi_log("uWSGI ERROR: %s is locked by another instance\n", filename);
exit(1);
}
}
void uwsgi_opt_flock_wait(char *opt, char *filename, void *none) {
@@ -3838,7 +3852,6 @@ void uwsgi_opt_flock_wait(char *opt, char *filename, void *none) {
if (uwsgi_fcntl_lock(fd)) {
exit(1);
}
}
// report CFLAGS used for compiling the server
+13 -25
View File
@@ -6,42 +6,30 @@ extern struct uwsgi_server uwsgi;
int uwsgi_request_admin(struct wsgi_request *wsgi_req) {
uint32_t opt_value = 0;
ssize_t len;
if (wsgi_req->uh.pktsize != 0 && wsgi_req->uh.pktsize != 4)
if (wsgi_req->uh->pktsize != 0 && wsgi_req->uh->pktsize != 4)
return UWSGI_OK;
// write request
if (wsgi_req->uh.pktsize == 4) {
if (wsgi_req->uh->pktsize == 4) {
memcpy(&opt_value, wsgi_req->buffer, 4);
uwsgi_log( "setting internal option %d to %d\n", wsgi_req->uh.modifier2, opt_value);
uwsgi.shared->options[wsgi_req->uh.modifier2] = opt_value;
uwsgi_log( "setting internal option %d to %d\n", wsgi_req->uh->modifier2, opt_value);
uwsgi.shared->options[wsgi_req->uh->modifier2] = opt_value;
// ACK
wsgi_req->uh.modifier1 = 255;
wsgi_req->uh.pktsize = 0;
wsgi_req->uh.modifier2 = 1;
len = write(wsgi_req->poll.fd, wsgi_req, 4);
if (len != 4) {
uwsgi_error("write()");
}
wsgi_req->uh->modifier1 = 255;
wsgi_req->uh->pktsize = 0;
wsgi_req->uh->modifier2 = 1;
uwsgi_response_write_body_do(wsgi_req, (char *)wsgi_req->uh , 4);
}
// get request
else {
uwsgi_log( "internal option %d = %d\n", wsgi_req->uh.modifier2, uwsgi.shared->options[wsgi_req->uh.modifier2]);
uwsgi_log( "internal option %d = %d\n", wsgi_req->uh->modifier2, uwsgi.shared->options[wsgi_req->uh->modifier2]);
wsgi_req->uh.modifier1 = 10;
wsgi_req->uh.pktsize = 4;
len = write(wsgi_req->poll.fd, wsgi_req, 4);
if (len != 4) {
uwsgi_error("write()");
return UWSGI_OK;
}
len = write(wsgi_req->poll.fd, (char *) &uwsgi.shared->options[wsgi_req->uh.modifier2], 4);
if (len != 4) {
uwsgi_error("write()");
}
wsgi_req->uh->modifier1 = 10;
wsgi_req->uh->pktsize = 4;
uwsgi_response_write_body_do(wsgi_req, (char *)wsgi_req->uh , 4);
uwsgi_response_write_body_do(wsgi_req, (char *) &uwsgi.shared->options[wsgi_req->uh->modifier2], 4);
}
return UWSGI_OK;
+1 -1
View File
@@ -4,7 +4,7 @@ extern struct uwsgi_server uwsgi;
static int uwsgi_echo_request(struct wsgi_request *wsgi_req) {
return uwsgi_response_write_body_do(wsgi_req, wsgi_req->buffer, wsgi_req->uh.pktsize);
return uwsgi_response_write_body_do(wsgi_req, wsgi_req->buffer, wsgi_req->uh->pktsize);
}
struct uwsgi_plugin echo_plugin = {
+1 -1
View File
@@ -8,7 +8,7 @@ except:
exec(f.read(), up)
f.close()
NAME='ring'
NAME='jwsgi'
CFLAGS = up['CFLAGS']
CFLAGS.append('-I%s' % jvm_path)
LDFLAGS = []
+104 -7
View File
@@ -48,6 +48,7 @@ struct uwsgi_mono {
char *assembly_name ;
struct uwsgi_string_list *key;
struct uwsgi_string_list *index;
// GC frequency
uint64_t gc_freq;
@@ -61,6 +62,10 @@ struct uwsgi_mono {
MonoClass *application_class;
MonoClass *api_class;
MonoClass *byte_class;
MonoClassField *filepath;
// thunk
void (*process_request)(MonoObject *, MonoException **);
@@ -78,15 +83,53 @@ struct uwsgi_option uwsgi_mono_options[] = {
{"mono-config", required_argument, 0, "set the Mono config file", uwsgi_opt_set_str, &umono.config, 0},
{"mono-assembly", required_argument, 0, "load the specified main assembly (default: uwsgi.dll)", uwsgi_opt_set_str, &umono.assembly_name, 0},
{"mono-exec", required_argument, 0, "exec the specified assembly just before app loading", uwsgi_opt_add_string_list, &umono.exec, 0},
{"mono-index", required_argument, 0, "add an asp.net index file", uwsgi_opt_add_string_list, &umono.index, 0},
};
static MonoString *uwsgi_mono_method_GetFilePath(MonoObject *this) {
MonoString *ret = NULL;
// cache it !!!
MonoObject *filepath = mono_field_get_value_object(mono_domain_get(), umono.filepath, this);
if (filepath) {
return (MonoString *) filepath;
}
struct wsgi_request *wsgi_req = current_wsgi_req();
return mono_string_new_len(mono_domain_get(), wsgi_req->path_info, wsgi_req->path_info_len);
struct uwsgi_app *app = &uwsgi_apps[wsgi_req->app_id];
char *path = uwsgi_concat3n(app->interpreter, strlen(app->interpreter), "/", 1, wsgi_req->path_info, wsgi_req->path_info_len);
size_t path_len = strlen(app->interpreter) + 1 + wsgi_req->path_info_len;
if (!uwsgi_file_exists(path)) {
free(path);
goto simple;
}
if (uwsgi_is_dir(path)) {
struct uwsgi_string_list *usl = umono.index;
while(usl) {
char *index = uwsgi_concat3n(path, path_len, "/", 1 , usl->value, usl->len);
if (uwsgi_file_exists(index)) {
ret = mono_string_new(mono_domain_get(), index + strlen(app->interpreter));
free(path);
free(index);
mono_field_set_value(this, umono.filepath, ret);
return ret;
}
free(index);
usl = usl->next;
}
}
free(path);
simple:
ret = mono_string_new_len(mono_domain_get(), wsgi_req->path_info, wsgi_req->path_info_len);
mono_field_set_value(this, umono.filepath, ret);
return ret;
}
static MonoString *uwsgi_mono_method_GetUriPath(MonoObject *this) {
return uwsgi_mono_method_GetFilePath(this);
}
static MonoString *uwsgi_mono_method_MapPath(MonoObject *this, MonoString *virtualPath) {
// first we need to get the physical path and append the virtualPath to it
struct wsgi_request *wsgi_req = current_wsgi_req();
struct uwsgi_app *app = &uwsgi_apps[wsgi_req->app_id];
char *path = uwsgi_concat3n(app->interpreter, strlen(app->interpreter), "/", 1, mono_string_to_utf8(virtualPath), mono_string_length(virtualPath));
@@ -115,11 +158,6 @@ static MonoString *uwsgi_mono_method_GetHttpVersion(MonoObject *this) {
return mono_string_new_len(mono_domain_get(), wsgi_req->protocol, wsgi_req->protocol_len);
}
static MonoString *uwsgi_mono_method_GetUriPath(MonoObject *this) {
struct wsgi_request *wsgi_req = current_wsgi_req();
return mono_string_new_len(mono_domain_get(), wsgi_req->path_info, wsgi_req->path_info_len);
}
static MonoString *uwsgi_mono_method_GetRemoteAddress(MonoObject *this) {
struct wsgi_request *wsgi_req = current_wsgi_req();
return mono_string_new_len(mono_domain_get(), wsgi_req->remote_addr, wsgi_req->remote_addr_len);
@@ -221,6 +259,26 @@ static int uwsgi_mono_method_api_WorkerId() {
return uwsgi.mywid;
}
static MonoArray *uwsgi_mono_method_api_CacheGet(MonoString *key, MonoString *cache) {
char *c_key = mono_string_to_utf8(key);
uint16_t c_keylen = mono_string_length(key);
char *c_cache = NULL;
if (cache) {
c_cache = mono_string_to_utf8(cache);
}
uint64_t vallen = 0 ;
char *value = uwsgi_cache_magic_get(c_key, c_keylen, &vallen, c_cache);
if (value) {
MonoArray *ret = mono_array_new(mono_domain_get(), umono.byte_class, vallen);
char *buf = mono_array_addr(ret, char, 0);
memcpy(buf, value, vallen);
free(value);
return ret;
}
return NULL;
}
static void uwsgi_mono_add_internal_calls() {
// uWSGIRequest
mono_add_internal_call("uwsgi.uWSGIRequest::SendResponseFromMemory", uwsgi_mono_method_SendResponseFromMemory);
@@ -246,6 +304,7 @@ static void uwsgi_mono_add_internal_calls() {
mono_add_internal_call("uwsgi.api::Signal", uwsgi_mono_method_api_Signal);
mono_add_internal_call("uwsgi.api::WorkerId", uwsgi_mono_method_api_WorkerId);
mono_add_internal_call("uwsgi.api::RegisterSignal", uwsgi_mono_method_api_RegisterSignal);
mono_add_internal_call("uwsgi.api::CacheGet", uwsgi_mono_method_api_CacheGet);
}
static int uwsgi_mono_init() {
@@ -280,6 +339,16 @@ static void uwsgi_mono_create_jit() {
uwsgi_log("Mono JIT initialized on worker %d with version %s\n", uwsgi.mywid, umono.version);
MonoAssembly *assembly = mono_domain_assembly_open(umono.main_domain, umono.assembly_name);
if (!assembly) {
uwsgi_log("%s not found trying in global gac...\n", umono.assembly_name);
assembly = mono_assembly_load_with_partial_name(umono.assembly_name, NULL);
if (!assembly) {
if (!strcmp("uwsgi.dll", umono.assembly_name)) {
assembly = mono_assembly_load_with_partial_name("uwsgi", NULL);
}
}
}
if (!assembly) {
uwsgi_log("unable to load \"%s\" in the Mono domain\n", umono.assembly_name);
exit(1);
@@ -298,6 +367,23 @@ static void uwsgi_mono_create_jit() {
exit(1);
}
umono.byte_class = mono_class_from_name(mono_get_corlib(), "System", "Byte");
if (!umono.byte_class) {
uwsgi_log("unable to get reference to class System.Byte\n");
exit(1);
}
MonoClass *urequest = mono_class_from_name(image, "uwsgi", "uWSGIRequest");
if (!urequest) {
uwsgi_log("unable to get reference to class uwsgi.uWSGIRequest\n");
exit(1);
}
umono.filepath = mono_class_get_field_from_name(urequest, "filepath");
if (!umono.filepath) {
uwsgi_log("unable to get reference to field uwsgi.uWSGIRequest.filepath\n");
}
umono.api_class = mono_class_from_name(image, "uwsgi", "api");
if (!umono.api_class) {
uwsgi_log("unable to get reference to class uwsgi.api\n");
@@ -484,6 +570,17 @@ static int uwsgi_mono_request(struct wsgi_request *wsgi_req) {
struct uwsgi_app *app = &uwsgi_apps[wsgi_req->app_id];
app->requests++;
// check for directory without slash
char *path = uwsgi_concat3n(app->interpreter, strlen(app->interpreter), "/", 1, wsgi_req->path_info, wsgi_req->path_info_len);
size_t path_len = strlen(app->interpreter) + 1 + wsgi_req->path_info_len;
if (uwsgi_is_dir(path) && path[path_len-1] != '/') {
free(path);
uwsgi_redirect_to_slash(wsgi_req);
return UWSGI_OK;
}
free(path);
MonoException *exc = NULL;
umono.process_request(app->callable, &exc);
+10
View File
@@ -6,6 +6,8 @@ using System.Web.Hosting;
using System.Text;
using System.Runtime.CompilerServices;
[assembly: System.Reflection.AssemblyVersion ("0.0.0.1")]
namespace uwsgi {
public delegate void uWSGIHook();
@@ -32,10 +34,15 @@ namespace uwsgi {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern public static void Signal(int signum);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern public static byte[] CacheGet(string key, string cache=null);
}
class uWSGIRequest: HttpWorkerRequest {
private String filepath = null;
public override string GetAppPath() {
return "/";
}
@@ -135,6 +142,9 @@ namespace uwsgi {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern public override void SendUnknownResponseHeader (string name, string value);
public string hack_current_filename() {
return filepath;
}
}
public class uWSGIApplicationHost: MarshalByRefObject {
+4 -2
View File
@@ -7,6 +7,8 @@ LIBS = os.popen('pkg-config --libs mono-2').read().rstrip().split()
GCC_LIST = ['mono_plugin']
def post_build(config):
if os.system("mcs /target:library /r:System.Web.dll plugins/mono/uwsgi.cs") != 0:
if os.system("sn -k plugins/mono/uwsgi.key") != 0:
os._exit(1)
print("*** uwsgi.dll available in %s/plugins/mono ***" % os.getcwd())
if os.system("mcs /target:library /r:System.Web.dll /keyfile:plugins/mono/uwsgi.key plugins/mono/uwsgi.cs") != 0:
os._exit(1)
print("*** uwsgi.dll available in %s/plugins/mono/uwsgi.dll ***" % os.getcwd())
+4 -2
View File
@@ -305,7 +305,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
// cache most used values
wi->error = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL);
Py_INCREF(wi->error);
Py_INCREF((PyObject *)wi->error);
wi->gateway_version = PyTuple_New(2);
PyTuple_SetItem(wi->gateway_version, 0, PyInt_FromLong(1));
@@ -563,7 +563,9 @@ PyObject *uwsgi_file_loader(void *arg1) {
char *callable = up.callable;
if (!callable) callable = "application";
char *py_filename = uwsgi_concat2("uwsgi_file_", uwsgi_pythonize(filename));
char *pythonized_filename = uwsgi_pythonize(filename);
char *py_filename = uwsgi_concat2("uwsgi_file_", pythonized_filename);
free(pythonized_filename);
wsgi_file_module = uwsgi_pyimport_by_filename(py_filename, filename);
if (!wsgi_file_module) {
+9 -6
View File
@@ -335,28 +335,31 @@ shit:
if (code_start) {
code_end = name_to_symbol_pkg(fullname2, "end");
if (code_end) {
char *symbolized;
PyObject *mod = PyImport_AddModule(fullname);
if (!mod) goto clear;
PyObject *dict = PyModule_GetDict(mod);
if (!dict) goto clear;
source = uwsgi_concat2n(code_start, code_end-code_start, "", 0);
modname = uwsgi_concat3("sym://", symbolize(fullname), "___init___py");
symbolized = symbolize(fullname);
modname = uwsgi_concat3("sym://", symbolized, "___init___py");
PyObject *pkgpath = Py_BuildValue("[O]", PyString_FromString(modname));
PyDict_SetItemString(dict, "__path__", pkgpath);
PyDict_SetItemString(dict, "__loader__", self);
code = Py_CompileString(source, modname, Py_file_input);
if (!code) {
PyErr_Print();
goto shit2;
}
code = Py_CompileString(source, modname, Py_file_input);
if (!code) {
PyErr_Print();
goto shit2;
}
mod = PyImport_ExecCodeModuleEx(fullname, code, modname);
Py_DECREF(code);
shit2:
free(symbolized);
free(source);
free(modname);
free(fullname2);
+22 -59
View File
@@ -454,6 +454,26 @@ PyObject *py_uwsgi_i_am_the_lord(PyObject * self, PyObject * args) {
Py_INCREF(Py_False);
return Py_False;
}
PyObject *py_uwsgi_lord_scroll(PyObject * self, PyObject * args) {
char *legion_name = NULL;
if (!PyArg_ParseTuple(args, "s:lord_scroll", &legion_name)) {
return NULL;
}
uint16_t rlen = 0;
char *buf = uwsgi_legion_lord_scroll(legion_name, &rlen);
if (!buf) {
Py_INCREF(Py_None);
return Py_None;
}
PyObject *ret = PyString_FromStringAndSize(buf, rlen);
free(buf);
return ret;
}
#endif
PyObject *py_uwsgi_register_signal(PyObject * self, PyObject * args) {
@@ -717,7 +737,7 @@ static PyObject *py_uwsgi_route(PyObject * self, PyObject * args) {
return NULL;
}
int ret = uwsgi_route_api_func(wsgi_req, uwsgi_str(router_name), uwsgi_str(router_args));
int ret = uwsgi_route_api_func(wsgi_req, router_name, uwsgi_str(router_args));
return PyInt_FromLong(ret);
}
#endif
@@ -2331,63 +2351,6 @@ PyObject *py_uwsgi_parse_file(PyObject * self, PyObject * args) {
}
PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) {
pid_t grunt_pid;
struct wsgi_request *wsgi_req = py_current_wsgi_req();
if (uwsgi.grunt) {
uwsgi_log("spawning a grunt from worker %d (pid :%d)...\n", uwsgi.mywid, uwsgi.mypid);
}
else {
uwsgi_log("grunt support is disabled !!!\n");
goto clear;
}
// use a normal fork here
grunt_pid = fork();
if (grunt_pid < 0) {
uwsgi_error("fork()");
goto clear;
}
// now i am a grunt, avoid it making mess
else if (grunt_pid == 0) {
// it will no more accepts requests
uwsgi_close_all_sockets();
// create a new session
setsid();
// exit on SIGPIPE
signal(SIGPIPE, (void *) &end_me);
// here we create a new worker. Each grunt will race on this datas, so do not rely on them
uwsgi.mywid = uwsgi.numproc + 1;
uwsgi.mypid = getpid();
memset(&uwsgi.workers[uwsgi.mywid], 0, sizeof(struct uwsgi_worker));
// this is pratically useless...
uwsgi.workers[uwsgi.mywid].id = uwsgi.mywid;
// this field will be overwrite after each call
uwsgi.workers[uwsgi.mywid].pid = uwsgi.mypid;
// reset the random seed
uwsgi_python_reset_random_seed();
// TODO
// manage thread in grunt processes
Py_INCREF(Py_True);
return Py_True;
}
// close connection on the original worker
if (PyTuple_Size(args) == 0) {
if (wsgi_req->socket) {
wsgi_req->socket->proto_close(wsgi_req);
}
wsgi_req->fd_closed = 1;
}
clear:
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef uwsgi_spooler_methods[] = {
#ifdef PYTHREE
{"send_to_spooler", (PyCFunction) py_uwsgi_send_spool, METH_VARARGS | METH_KEYWORDS, ""},
@@ -2434,7 +2397,6 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"get_logvar", py_uwsgi_get_logvar, METH_VARARGS, ""},
{"alarm", py_uwsgi_alarm, METH_VARARGS, ""},
{"disconnect", py_uwsgi_disconnect, METH_VARARGS, ""},
{"grunt", py_uwsgi_grunt, METH_VARARGS, ""},
{"lock", py_uwsgi_lock, METH_VARARGS, ""},
{"is_locked", py_uwsgi_is_locked, METH_VARARGS, ""},
{"unlock", py_uwsgi_unlock, METH_VARARGS, ""},
@@ -2471,6 +2433,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"logsize", py_uwsgi_logsize, METH_VARARGS, ""},
#ifdef UWSGI_SSL
{"i_am_the_lord", py_uwsgi_i_am_the_lord, METH_VARARGS, ""},
{"lord_scroll", py_uwsgi_lord_scroll, METH_VARARGS, ""},
#endif
{"async_sleep", py_uwsgi_async_sleep, METH_VARARGS, ""},
{"async_connect", py_uwsgi_async_connect, METH_VARARGS, ""},
+7 -7
View File
@@ -20,16 +20,19 @@ int uwsgi_request_spooler(struct wsgi_request *wsgi_req) {
if (uspool == NULL) {
uwsgi_log("the spooler is inactive !!!...skip\n");
uwsgi_send_empty_pkt(wsgi_req->poll.fd, NULL, 255, 0);
uh.modifier1 = 255;
uh.pktsize = 0;
uh.modifier2 = 0;
uwsgi_response_write_body_do(wsgi_req, (char *) &uh, 4);
return -1;
}
i = spool_request(uspool, spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, wsgi_req->buffer, wsgi_req->uh.pktsize, NULL, 0, NULL, 0);
i = spool_request(uspool, spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, wsgi_req->buffer, wsgi_req->uh->pktsize, NULL, 0, NULL, 0);
uh.modifier1 = 255;
uh.pktsize = 0;
if (i > 0) {
uh.modifier2 = 1;
if (write(wsgi_req->poll.fd, &uh, 4) != 4) {
if (uwsgi_response_write_body_do(wsgi_req, (char *) &uh, 4)) {
uwsgi_log("disconnected client, remove spool file.\n");
/* client disconnect, remove spool file */
if (unlink(spool_filename)) {
@@ -43,10 +46,7 @@ int uwsgi_request_spooler(struct wsgi_request *wsgi_req) {
else {
/* announce a failed spool request */
uh.modifier2 = 0;
i = write(wsgi_req->poll.fd, &uh, 4);
if (i != 4) {
uwsgi_error("write()");
}
uwsgi_response_write_body_do(wsgi_req, (char *) &uh, 4);
}
return -1;
+7 -2
View File
@@ -104,18 +104,23 @@ struct zergpool_socket *add_zergpool_socket(char *name, char *sockets) {
p = strtok(sock_list, ",");
while(p) {
char *port = strchr(p, ':');
char *sockname;
if (!port) {
z_sock->sockets[pos] = bind_to_unix(p, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
uwsgi_log("zergpool %s bound to UNIX socket %s (fd: %d)\n", name, uwsgi_getsockname(z_sock->sockets[pos]), z_sock->sockets[pos]);
sockname = uwsgi_getsockname(z_sock->sockets[pos]);
uwsgi_log("zergpool %s bound to UNIX socket %s (fd: %d)\n", name, sockname, z_sock->sockets[pos]);
}
else {
char *gsn = generate_socket_name(p);
z_sock->sockets[pos] = bind_to_tcp(gsn, uwsgi.listen_queue, strchr(gsn, ':'));
uwsgi_log("zergpool %s bound to TCP socket %s (fd: %d)\n", name, uwsgi_getsockname(z_sock->sockets[pos]), z_sock->sockets[pos]);
sockname = uwsgi_getsockname(z_sock->sockets[pos]);
uwsgi_log("zergpool %s bound to TCP socket %s (fd: %d)\n", name, sockname, z_sock->sockets[pos]);
}
pos++;
p = strtok(NULL, ",");
free(sockname);
}
free(sock_list);
return z_sock;
}
+5
View File
@@ -0,0 +1,5 @@
<%@ language="C#"%>
Hello 1<br/>
<%= System.Text.Encoding.UTF8.GetString(uwsgi.api.CacheGet("/etc/passwd")) %><br/>
Hello 1<br/>
+129 -117
View File
@@ -565,8 +565,8 @@ union uwsgi_sockaddr_ptr {
uint64_t valor;
char uuid[37];
char *scroll;
uint64_t checksum;
uint16_t scroll_len;
uint64_t checksum;
uint64_t lord_valor;
char lord_uuid[36];
time_t last_seen;
@@ -589,6 +589,12 @@ union uwsgi_sockaddr_ptr {
uint64_t checksum;
char *scroll;
uint16_t scroll_len;
char *lord_scroll;
uint16_t lord_scroll_len;
uint16_t lord_scroll_size;
char lord_uuid[36];
uint64_t lord_valor;
@@ -599,7 +605,7 @@ union uwsgi_sockaddr_ptr {
time_t last_warning;
pthread_mutex_t lock;
struct uwsgi_lock_item *lock;
EVP_CIPHER_CTX *encrypt_ctx;
EVP_CIPHER_CTX *decrypt_ctx;
@@ -1357,6 +1363,7 @@ struct uwsgi_router {
// avoid routing loops
int is_routing;
int routes_applied;
// internal routing vm program counter
uint32_t route_pc;
// internal routing goto instruction
@@ -1503,53 +1510,55 @@ struct uwsgi_server {
struct uwsgi_instance_status status;
struct uwsgi_string_list *get_list;
struct uwsgi_string_list *get_list;
// enable threads
int has_threads;
int no_threads_wait;
// enable threads
int has_threads;
int no_threads_wait;
// default app id
int default_app;
// default app id
int default_app;
char *logto2;
char *logformat;
int logformat_strftime;
int logformat_vectors;
struct uwsgi_logchunk *logchunks;
void (*logit) (struct wsgi_request *);
struct iovec **logvectors;
char *logto2;
char *logformat;
int logformat_strftime;
int logformat_vectors;
struct uwsgi_logchunk *logchunks;
void (*logit) (struct wsgi_request *);
struct iovec **logvectors;
// autoload plugins
int autoload;
struct uwsgi_string_list *plugins_dir;
struct uwsgi_string_list *blacklist;
struct uwsgi_string_list *whitelist;
// autoload plugins
int autoload;
struct uwsgi_string_list *plugins_dir;
struct uwsgi_string_list *blacklist;
struct uwsgi_string_list *whitelist;
char *blacklist_context;
char *whitelist_context;
int snapshot;
int respawn_snapshots;
int snapshot;
int respawn_snapshots;
// enable auto-snapshotting
int auto_snapshot;
pid_t restore_snapshot;
// enable auto-snapshotting
int auto_snapshot;
pid_t restore_snapshot;
unsigned int reloads;
unsigned int reloads;
// leave master running as root
int master_as_root;
// kill the stack on SIGTERM (instead of brutal reloading)
int die_on_term;
// leave master running as root
int master_as_root;
// kill the stack on SIGTERM (instead of brutal reloading)
int die_on_term;
// disable fd passing on unix socket
int no_fd_passing;
// disable fd passing on unix socket
int no_fd_passing;
// store the current time
time_t current_time;
// store the current time
time_t current_time;
uint64_t master_cycles;
uint64_t master_cycles;
int reuse_port;
int reuse_port;
int tcp_fast_open;
int tcp_fast_open_client;
@@ -2215,6 +2224,7 @@ struct uwsgi_server {
int legion_freq;
int legion_tolerance;
int legion_skew_tolerance;
uint16_t legion_scroll_max_size;
#endif
#ifdef __linux__
@@ -2756,8 +2766,8 @@ void uwsgi_rpc_init(void);
char *magic_sub(char *, size_t, size_t *, char *[]);
void init_magic_table(char *[]);
char *uwsgi_req_append(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
char *uwsgi_req_append(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
int uwsgi_req_append_path_info_with_index(struct wsgi_request *, char *, uint16_t);
int is_unix(char *, int);
int is_a_number(char *);
@@ -3178,98 +3188,97 @@ void uwsgi_set_processname(char *);
int uwsgi_manage_opt(char *, char *);
void uwsgi_opt_print(char *, char *, void *);
void uwsgi_opt_true(char *, char *, void *);
void uwsgi_opt_set_str(char *, char *, void *);
void uwsgi_opt_set_logger(char *, char *, void *);
void uwsgi_opt_set_req_logger(char *, char *, void *);
void uwsgi_opt_set_str_spaced(char *, char *, void *);
void uwsgi_opt_add_string_list(char *, char *, void *);
void uwsgi_opt_add_addr_list(char *, char *, void *);
void uwsgi_opt_add_string_list_custom(char *, char *, void *);
void uwsgi_opt_add_dyn_dict(char *, char *, void *);
void uwsgi_opt_print(char *, char *, void *);
void uwsgi_opt_true(char *, char *, void *);
void uwsgi_opt_set_str(char *, char *, void *);
void uwsgi_opt_set_null(char *, char *, void *);
void uwsgi_opt_set_logger(char *, char *, void *);
void uwsgi_opt_set_req_logger(char *, char *, void *);
void uwsgi_opt_set_str_spaced(char *, char *, void *);
void uwsgi_opt_add_string_list(char *, char *, void *);
void uwsgi_opt_add_addr_list(char *, char *, void *);
void uwsgi_opt_add_string_list_custom(char *, char *, void *);
void uwsgi_opt_add_dyn_dict(char *, char *, void *);
#ifdef UWSGI_PCRE
void uwsgi_opt_pcre_jit(char *, char *, void *);
void uwsgi_opt_add_regexp_dyn_dict(char *, char *, void *);
void uwsgi_opt_add_regexp_list(char *, char *, void *);
void uwsgi_opt_add_regexp_custom_list(char *, char *, void *);
void uwsgi_opt_pcre_jit(char *, char *, void *);
void uwsgi_opt_add_regexp_dyn_dict(char *, char *, void *);
void uwsgi_opt_add_regexp_list(char *, char *, void *);
void uwsgi_opt_add_regexp_custom_list(char *, char *, void *);
#endif
void uwsgi_opt_set_int(char *, char *, void *);
void uwsgi_opt_set_rawint(char *, char *, void *);
void uwsgi_opt_set_16bit(char *, char *, void *);
void uwsgi_opt_set_64bit(char *, char *, void *);
void uwsgi_opt_set_megabytes(char *, char *, void *);
void uwsgi_opt_set_dyn(char *, char *, void *);
void uwsgi_opt_dyn_true(char *, char *, void *);
void uwsgi_opt_dyn_false(char *, char *, void *);
void uwsgi_opt_set_placeholder(char *, char *, void *);
void uwsgi_opt_add_shared_socket(char *, char *, void *);
void uwsgi_opt_add_socket(char *, char *, void *);
void uwsgi_opt_add_lazy_socket(char *, char *, void *);
void uwsgi_opt_add_cron(char *, char *, void *);
void uwsgi_opt_load_plugin(char *, char *, void *);
void uwsgi_opt_load_dl(char *, char *, void *);
void uwsgi_opt_load(char *, char *, void *);
void uwsgi_opt_set_int(char *, char *, void *);
void uwsgi_opt_set_rawint(char *, char *, void *);
void uwsgi_opt_set_16bit(char *, char *, void *);
void uwsgi_opt_set_64bit(char *, char *, void *);
void uwsgi_opt_set_megabytes(char *, char *, void *);
void uwsgi_opt_set_dyn(char *, char *, void *);
void uwsgi_opt_dyn_true(char *, char *, void *);
void uwsgi_opt_dyn_false(char *, char *, void *);
void uwsgi_opt_set_placeholder(char *, char *, void *);
void uwsgi_opt_add_shared_socket(char *, char *, void *);
void uwsgi_opt_add_socket(char *, char *, void *);
void uwsgi_opt_add_lazy_socket(char *, char *, void *);
void uwsgi_opt_add_cron(char *, char *, void *);
void uwsgi_opt_load_plugin(char *, char *, void *);
void uwsgi_opt_load_dl(char *, char *, void *);
void uwsgi_opt_load(char *, char *, void *);
#ifdef UWSGI_SSL
void uwsgi_opt_sni(char *, char *, void *);
struct uwsgi_string_list *uwsgi_ssl_add_sni_item(char *, char *, char *, char *, char *);
void uwsgi_opt_sni(char *, char *, void *);
struct uwsgi_string_list *uwsgi_ssl_add_sni_item(char *, char *, char *, char *, char *);
#endif
void uwsgi_opt_flock(char *, char *, void *);
void uwsgi_opt_flock_wait(char *, char *, void *);
void uwsgi_opt_flock(char *, char *, void *);
void uwsgi_opt_flock_wait(char *, char *, void *);
#ifdef UWSGI_INI
void uwsgi_opt_load_ini(char *, char *, void *);
void uwsgi_opt_load_ini(char *, char *, void *);
#endif
#ifdef UWSGI_XML
void uwsgi_opt_load_xml(char *, char *, void *);
void uwsgi_opt_load_xml(char *, char *, void *);
#endif
#ifdef UWSGI_YAML
void uwsgi_opt_load_yml(char *, char *, void *);
void uwsgi_opt_load_yml(char *, char *, void *);
#endif
#ifdef UWSGI_SQLITE3
void uwsgi_opt_load_sqlite3(char *, char *, void *);
void uwsgi_opt_load_sqlite3(char *, char *, void *);
#endif
#ifdef UWSGI_JSON
void uwsgi_opt_load_json(char *, char *, void *);
void uwsgi_opt_load_json(char *, char *, void *);
#endif
#ifdef UWSGI_LDAP
void uwsgi_opt_load_ldap(char *, char *, void *);
void uwsgi_opt_load_ldap(char *, char *, void *);
#endif
void uwsgi_opt_set_umask(char *, char *, void *);
void uwsgi_opt_add_spooler(char *, char *, void *);
void uwsgi_opt_add_daemon(char *, char *, void *);
void uwsgi_opt_set_uid(char *, char *, void *);
void uwsgi_opt_set_gid(char *, char *, void *);
void uwsgi_opt_set_env(char *, char *, void *);
void uwsgi_opt_unset_env(char *, char *, void *);
void uwsgi_opt_pidfile_signal(char *, char *, void *);
void uwsgi_opt_set_umask(char *, char *, void *);
void uwsgi_opt_add_spooler(char *, char *, void *);
void uwsgi_opt_add_daemon(char *, char *, void *);
void uwsgi_opt_set_uid(char *, char *, void *);
void uwsgi_opt_set_gid(char *, char *, void *);
void uwsgi_opt_set_env(char *, char *, void *);
void uwsgi_opt_unset_env(char *, char *, void *);
void uwsgi_opt_pidfile_signal(char *, char *, void *);
void uwsgi_opt_check_static(char *, char *, void *);
void uwsgi_opt_fileserve_mode(char *, char *, void *);
void uwsgi_opt_static_map(char *, char *, void *);
void uwsgi_opt_check_static(char *, char *, void *);
void uwsgi_opt_fileserve_mode(char *, char *, void *);
void uwsgi_opt_static_map(char *, char *, void *);
void uwsgi_opt_add_mule(char *, char *, void *);
void uwsgi_opt_add_mules(char *, char *, void *);
void uwsgi_opt_add_farm(char *, char *, void *);
void uwsgi_opt_add_mule(char *, char *, void *);
void uwsgi_opt_add_mules(char *, char *, void *);
void uwsgi_opt_add_farm(char *, char *, void *);
void uwsgi_opt_signal(char *, char *, void *);
void uwsgi_opt_signal(char *, char *, void *);
void uwsgi_opt_snmp(char *, char *, void *);
void uwsgi_opt_snmp_community(char *, char *, void *);
void uwsgi_opt_snmp(char *, char *, void *);
void uwsgi_opt_snmp_community(char *, char *, void *);
void uwsgi_opt_logfile_chmod(char *, char *, void *);
void uwsgi_opt_logfile_chmod(char *, char *, void *);
void uwsgi_opt_log_date(char *, char *, void *);
void uwsgi_opt_chmod_socket(char *, char *, void *);
void uwsgi_opt_log_date(char *, char *, void *);
void uwsgi_opt_chmod_socket(char *, char *, void *);
void uwsgi_opt_max_vars(char *, char *, void *);
void uwsgi_opt_deprecated(char *, char *, void *);
void uwsgi_opt_max_vars(char *, char *, void *);
void uwsgi_opt_deprecated(char *, char *, void *);
void uwsgi_opt_noop(char *, char *, void *);
void uwsgi_opt_noop(char *, char *, void *);
void uwsgi_opt_logic(char *, char *, void *);
void uwsgi_opt_logic(char *, char *, void *);
int uwsgi_logic_opt_for(char *, char *);
int uwsgi_logic_opt_for_glob(char *, char *);
int uwsgi_logic_opt_if_env(char *, char *);
@@ -3301,7 +3310,7 @@ char *uwsgi_tmpname(char *, char *);
struct uwsgi_router *uwsgi_register_router(char *, int (*)(struct uwsgi_route *, char *));
void uwsgi_opt_add_route(char *, char *, void *);
int uwsgi_apply_routes(struct wsgi_request *);
int uwsgi_apply_routes_fast(struct wsgi_request *, char *, uint16_t);
int uwsgi_apply_routes_do(struct wsgi_request *, char *, uint16_t);
void uwsgi_register_embedded_routers(void);
void uwsgi_routing_dump();
struct uwsgi_buffer *uwsgi_routing_translate(struct wsgi_request *, struct uwsgi_route *, char *, uint16_t, char *, size_t);
@@ -3356,6 +3365,7 @@ void uwsgi_reload(char **);
uint64_t uwsgi_micros(void);
int uwsgi_is_file(char *);
int uwsgi_is_file2(char *, struct stat *);
int uwsgi_is_dir(char *);
int uwsgi_is_link(char *);
@@ -3734,18 +3744,19 @@ void uwsgi_user_unlock(int);
char *uwsgi_strip(char *);
#ifdef UWSGI_SSL
void uwsgi_opt_legion(char *, char *, void *);
void uwsgi_opt_legion_node(char *, char *, void *);
void uwsgi_opt_legion_quorum(char *, char *, void *);
void uwsgi_opt_legion_hook(char *, char *, void *);
void uwsgi_legion_add(struct uwsgi_legion *);
char *uwsgi_ssl_rand(size_t);
void uwsgi_start_legions(void);
int uwsgi_legion_announce(struct uwsgi_legion *);
struct uwsgi_legion_action *uwsgi_legion_action_get(char *);
void uwsgi_legion_action_register(char *, int (*)(struct uwsgi_legion *, char *));
int uwsgi_legion_action_call(char *, struct uwsgi_legion *, struct uwsgi_string_list *);
void uwsgi_legion_atexit(void);
void uwsgi_opt_legion(char *, char *, void *);
void uwsgi_opt_legion_node(char *, char *, void *);
void uwsgi_opt_legion_quorum(char *, char *, void *);
void uwsgi_opt_legion_hook(char *, char *, void *);
void uwsgi_opt_legion_scroll(char *, char *, void *);
void uwsgi_legion_add(struct uwsgi_legion *);
char *uwsgi_ssl_rand(size_t);
void uwsgi_start_legions(void);
int uwsgi_legion_announce(struct uwsgi_legion *);
struct uwsgi_legion_action *uwsgi_legion_action_get(char *);
void uwsgi_legion_action_register(char *, int (*)(struct uwsgi_legion *, char *));
int uwsgi_legion_action_call(char *, struct uwsgi_legion *, struct uwsgi_string_list *);
void uwsgi_legion_atexit(void);
#endif
struct uwsgi_option *uwsgi_opt_get(char *);
@@ -3757,6 +3768,7 @@ void uwsgi_uuid(char *);
int uwsgi_uuid_cmp(char *, char *);
int uwsgi_legion_i_am_the_lord(char *);
char *uwsgi_legion_lord_scroll(char *, uint16_t *);
void uwsgi_additional_header_add(struct wsgi_request *, char *, uint16_t);
void uwsgi_remove_header(struct wsgi_request *, char *, uint16_t);