Compare commits

...
1848 Commits
Author SHA1 Message Date
Unbit fe8ee7c7b3 uWSGI 1.9.4 2013-03-30 16:29:51 +01:00
Unbit cd382c6bc0 added rpcblob/rpcnext 2013-03-30 16:06:47 +01:00
Unbit e68296c293 a bit of cosmetic for uwsgi.h 2013-03-30 09:28:06 +01:00
Unbit cc189feae5 added uwsgi_register_signal to v8 2013-03-30 09:25:50 +01:00
unbit 18e19027a1 Merge pull request #207 from prymitive/legion_api
refactored legion opt functions to be more plugin friendly
2013-03-30 00:58:46 -07:00
Łukasz Mierzwa 2d2e0e4757 refactored legion opt functions to be more plugin friendly 2013-03-29 23:33:33 +01:00
Unbit a9f50d79f9 start 1.9.4 2013-03-29 21:24:56 +01:00
Unbit 0ccd31bee0 fixed reloading when in Go mode 2013-03-29 21:24:41 +01:00
Unbit 3ea82b2bcd do not differentiate reload when uWSGI is build as shared library 2013-03-29 21:21:46 +01:00
Unbit 6dad7b3ced ported the cplusplus plugin to the new api 2013-03-29 19:43:03 +01:00
Unbit f96ebd2b07 Merge branch 'master' of github.com:unbit/uwsgi 2013-03-29 19:37:53 +01:00
Unbit b8d0e7a3ac beta quality v8 plugin 2013-03-29 19:37:33 +01:00
unbit 14cca3d497 Merge pull request #204 from prymitive/legion_join_hook
legion join hook
2013-03-29 06:02:42 -07:00
Łukasz Mierzwa c343ca0cc3 legion join hook 2013-03-29 14:01:02 +01:00
Unbit 527d371bda fixed multiple mules event handling 2013-03-29 13:34:48 +01:00
Unbit b87a800a9a avoid resetting uwsgi.mywid in the master 2013-03-29 13:24:33 +01:00
Unbit e406993ed1 fixed typo 2013-03-29 12:51:52 +01:00
Unbit eeff935fc9 fixed signal handling in non-workers 2013-03-29 12:50:56 +01:00
Unbit 0791394f1a official support for SmartOS 2013-03-29 08:12:58 +00:00
unbit 082a407b06 Merge pull request #201 from prymitive/cache_restore_items_count
update cache items count after restore
2013-03-28 15:23:22 -07:00
Łukasz Mierzwa 8a89b49df1 update cache items count after restore 2013-03-28 23:20:17 +01:00
unbit 2314b9cbab Merge pull request #200 from jbert/master
Fix segfault in psgi plugin
2013-03-28 15:02:26 -07:00
John Berthels d0cca85c83 fix segfault in psgi handler after taking early-exit error path in coroae_accept_request 2013-03-28 17:29:00 +00:00
unbit 6a7a5cbcba Merge pull request #199 from prymitive/cache_stats_missin_list_close
missing list close in cache stats
2013-03-28 09:28:02 -07:00
Łukasz Mierzwa ecccc82cc8 missing list close 2013-03-28 16:56:31 +01:00
Unbit 02693489fe fixed php headers generation 2013-03-28 12:13:23 +01:00
Unbit 0f5dba5828 apache 2.4 support in mod_proxy_uwsgi 2013-03-28 11:19:13 +01:00
Unbit e528d4c4b7 implemented --emperor-tyrant-nofollow 2013-03-28 10:18:01 +01:00
Unbit 52a3af6acf prepare for uWSGI 1.9.3 2013-03-28 10:05:24 +01:00
Unbit dcefea9958 added rpcret routing action 2013-03-28 10:03:33 +01:00
Unbit 59121ff834 added --lua-load, fixed lua rpc memory leak 2013-03-28 09:21:47 +01:00
Unbit 7f5bb6d472 allows usage of configurators in the emperor 2013-03-28 09:07:15 +01:00
Unbit 639c1a508c support for lua ordered arrays in configurations 2013-03-28 09:00:10 +01:00
Unbit 417a26fc64 added config.lua example 2013-03-28 08:02:32 +01:00
Unbit 210ccd0063 allows configuration via lua 2013-03-28 08:02:07 +01:00
unbit 1bf0162d38 Merge pull request #196 from ryankask/jvm-plugin-import
Fix imports for the JVM plugin
2013-03-27 02:53:03 -07:00
Ryan Kaskel e93027fd7e Fix imports for JVM plugin. 2013-03-27 09:48:14 +00:00
Unbit 807060706f prepare for 1.9.2 2013-03-26 20:05:33 +01:00
Unbit a317f88d3c added the cache command to the ssi plugin 2013-03-26 20:03:37 +01:00
Unbit e17a7f0701 fixed a typo 2013-03-26 19:53:32 +01:00
Unbit db325eb9fe fixed readline() + post_buffering 2013-03-26 17:54:42 +01:00
Unbit b41a4c8c3b fixed python3 headers management 2013-03-26 16:45:57 +01:00
Unbit 73b4d11d18 added ssi router 2013-03-26 15:38:45 +01:00
Unbit 8162b87287 beta quality ssi plugin 2013-03-26 15:19:23 +01:00
Unbit 70e9e4f3ee added printenv 2013-03-26 12:24:17 +01:00
Unbit e61ae376b3 other improvements in the ssi plugin 2013-03-26 11:48:51 +01:00
Unbit 2d57b0e926 added preliminary ssi support 2013-03-26 11:33:00 +01:00
Unbit ae683af07a completed the geoip plugin [2] 2013-03-26 07:11:27 +01:00
Unbit 3c4f6a9171 completed the geoip plugin 2013-03-26 07:05:02 +01:00
Unbit 39986e546c fixed GeoIP plugin 2013-03-26 06:47:18 +01:00
Unbit 2e81a80f7b added preliminary geoip plugin 2013-03-25 19:11:20 +01:00
Unbit fcb3aa38c8 allows freeing route vars 2013-03-25 18:15:29 +01:00
Unbit 00a38d8ec5 fixed routing vars management 2013-03-25 18:10:41 +01:00
Unbit 07a0ab4227 pluggable routing vars 2013-03-25 18:05:57 +01:00
Unbit d4a9a2c543 fixed exceptions in the fiber plugin 2013-03-25 17:46:29 +01:00
Unbit 2b523fc60d added query string management functions 2013-03-25 10:21:20 +01:00
Unbit 0c26928236 added cookie management and --route-run 2013-03-25 09:56:53 +01:00
Unbit 8401e56a22 added 'empty' internal routing condition 2013-03-25 09:04:30 +01:00
Unbit 5109f9ae0b back to libxml2 default 2013-03-25 08:47:22 +01:00
Unbit c9bc06669a .ini file can backreference themselves 2013-03-25 08:47:00 +01:00
unbit a83fb2672c Merge pull request #189 from xtfxme/enhance/189-dashful-endif-endfor
Routing table appear to go nuts when used within a FOR loop
2013-03-24 23:18:50 -07:00
C Anthony Risinger 8f9ecb44d9 [#189] endfor/endif => end-for/end-if ...i know i'm not alone 2013-03-24 15:45:04 -05:00
Unbit bfcc09a8de prepare for cookie management in internal routing 2013-03-24 21:05:21 +01:00
Unbit f8a8c997db removed cache type in routing instruction 2013-03-24 20:30:56 +01:00
Unbit 132b996f30 added cachestore routing instruction 2013-03-24 19:43:41 +01:00
Unbit 12f970cdfb prepare for routing-governed caching 2013-03-24 19:24:13 +01:00
Unbit 9afa963225 prepare for gem 1.9.1 2013-03-24 11:39:44 +01:00
Unbit ed368d0d51 fixed signal copy on write 2013-03-24 10:30:01 +01:00
Unbit 21f21d34ba fixed legion scrolls api 2013-03-24 09:52:16 +01:00
Unbit f37823c809 completed --emperor-on-demand-dir 2013-03-23 10:34:36 +01:00
Unbit 6eaefcff5e added build profile for ubuntu ppa 2013-03-23 06:15:55 +01:00
Unbit 79235c1cc3 another memory report fix for Unbit 2013-03-23 04:41:58 +01:00
Unbit 29135f014b Unbit fixes 2013-03-23 04:11:33 +01:00
Unbit 13c998fb8d added uwsgi_main.c 2013-03-23 03:56:56 +01:00
Unbit 71bfd0d636 prepare for uWSGI 1.9.1 2013-03-23 03:52:19 +01:00
Unbit 51e99e0f5a removed UWSGI_INI 2013-03-23 03:15:33 +01:00
Unbit 66e7beefc4 fixed rack exceptions management 2013-03-22 19:53:47 +01:00
Unbit f2b10c35b7 fixed build without pcre 2013-03-22 11:15:13 +01:00
Unbit e951eba96c improved emperor on demand mode 2013-03-22 14:56:49 +01:00
Unbit 9fe18da7a3 added startswith endswith and regexp/re routing instructions 2013-03-22 10:14:34 +01:00
Unbit a14fdead14 added rpc router instruction 2013-03-22 09:26:11 +01:00
Unbit 9a671a4991 added %V magic var (contains UWSGI_VERSION) 2013-03-21 17:18:41 +01:00
Unbit 8f5e7b124a added --emperor-on-demand-exec 2013-03-21 16:55:23 +01:00
Unbit 5f7464d015 implemented --emperor-on-demand-ext 2013-03-21 16:42:24 +01:00
Unbit 238dd6c1d0 added a commodity mongodb plugin for system without mongoclient shared library 2013-03-21 15:18:09 +01:00
Roberta Giordano 82e4e54edc removed some unbit useless definition 2013-03-21 07:59:45 +01:00
Unbit 9946cbb9da added 'equal' routing func 2013-03-21 06:54:36 +01:00
Unbit 2474adb23a completed routing cache instruction 2013-03-21 06:31:26 +01:00
Unbit f40757bb67 free carbon_address memory 2013-03-21 06:19:31 +01:00
unbit bc29479930 Merge pull request #188 from prymitive/carbon_resolve_hostnames
allow connecting to carbon server using hostname resolved on every cycle...
2013-03-20 22:04:50 -07:00
Łukasz Mierzwa 4ec78edaa3 allow connecting to carbon server using hostname resolved on every cycle, fixes #186 2013-03-20 21:47:56 +01:00
Unbit aa0271158d allows build profiles to be stored on http/https/ftp 2013-03-20 19:44:46 +01:00
Unbit c0aa5bfe17 added the crypto logger 2013-03-20 16:22:40 +01:00
Unbit 3f8e6a8cc8 completed xslt plugin 2013-03-19 17:53:12 +01:00
Unbit ef0316fc2e Merge branch 'master' of github.com:unbit/uwsgi 2013-03-19 15:18:33 +01:00
Unbit 7274efab15 added xslt plugin 2013-03-19 15:18:03 +01:00
Unbit e44b62b6b2 on demand vassals 2013-03-18 15:42:34 +01:00
Unbit 31c041d435 added --exec-post-app 2013-03-18 13:32:09 +01:00
Unbit 35f47371ed first part of uwsgi_legion_scrolls() function api 2013-03-18 13:22:10 +01:00
unbit c5412e1620 Merge pull request #185 from guokr/master
Supporting JVM/Ring installing in Virtualenv
2013-03-18 03:09:03 -07:00
Mingli a9b4c52811 supporting virtualenv 2013-03-18 17:53:04 +08:00
Roberto De Ioris 5ce40b6ac8 fixed --req-logger after reload 2013-03-18 09:19:25 +01:00
Unbit b93dcbf46f removed download_url from setup.py 2013-03-17 08:10:12 +01:00
Unbit 8051a2bc98 prepare for 1.9 release 2013-03-17 07:15:24 +01:00
Unbit 78d8b221fc added --gevent-monkey-patch 2013-03-17 07:14:54 +01:00
Unbit d51cada284 second (and last i hope) part of mongrel2 support refactoring 2013-03-16 18:24:25 +01:00
Unbit 389eef9e88 first part of mongrel2 support refactoring 2013-03-16 18:02:11 +01:00
Unbit 270fb0c50d avoid routing loop 2013-03-16 16:48:26 +01:00
Unbit e7e9dfee88 fixed DragonFlyBSD support 2013-03-16 15:45:49 +01:00
Unbit 3bafae276d improved binary detection path on cygwin 2013-03-16 12:33:00 +01:00
Unbit cfebe2927d fixed lazy mode 2013-03-15 13:47:29 +01:00
Unbit 1d4294a845 added some comment for the statsd plugin 2013-03-15 11:34:19 +01:00
Unbit 12cfdd9864 added stats_pusher_statsd plugin 2013-03-15 11:32:08 +01:00
Unbit add930c517 fixed uuid support in cygwin 2013-03-15 07:31:41 +01:00
Unbit 32972978be added java support for cygwin 2013-03-13 17:50:56 +01:00
Unbit c8bad3550e added proper locking to windows 2013-03-13 15:51:14 +01:00
Unbit ecc55d789d added proper-locking to poll event mode 2013-03-13 15:03:30 +01:00
Unbit 88555e2c20 improved poll() support 2013-03-13 14:33:38 +01:00
Unbit ec2bfcd302 allows building router basicauth on cygwin 2013-03-13 11:14:32 +01:00
Unbit f1f81ed4c4 fixed python3 build 2013-03-13 11:00:05 +01:00
Unbit 87933cca26 another series of cygwin fixes 2013-03-13 10:51:33 +01:00
Unbit 2dcd8624a2 psgi support for windows 2013-03-13 10:12:24 +01:00
Unbit 7fcef76bbe experimental windows/cygwin support 2013-03-13 09:44:32 +01:00
Unbit 2a5c4e938d fixed requets overwrite in PATH_INFO rewrite (fixed typo) 2013-03-12 15:57:44 +01:00
Unbit 274eae27ef fixed requets overwrite in PATH_INFO rewrite 2013-03-12 15:56:30 +01:00
Unbit 207220bc50 fixed #180 2013-03-12 11:45:03 +01:00
Unbit fb8c4439c7 the whole ring test suite passes 2013-03-12 11:15:45 +01:00
Roberto De Ioris 894be9c41e let the /sequence ring test pass 2013-03-12 09:42:13 +01:00
unbit 0a4bff8963 Merge pull request #182 from guokr/master
Ring plugin tests
2013-03-12 00:27:11 -07:00
Mingli d515f3e279 add tests for ring plugin 2013-03-12 14:47:51 +08:00
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
Unbit b64884961d removed unused functions 2013-03-09 09:24:15 +01:00
Unbit 619e853a19 cache sync is working again 2013-03-09 06:34:48 +01:00
Unbit 050908a65e added a test for clojure rpc 2013-03-08 21:11:28 +01:00
Unbit bcb1e623d9 implemented uwsgi.rpc jvm function [test] 2013-03-08 20:59:05 +01:00
Unbit 57105c1bc7 implemented uwsgi.rpc jvm function 2013-03-08 20:58:52 +01:00
Unbit 8bb5b8a9f3 removed old java test 2013-03-08 20:30:26 +01:00
Unbit fba0d196ff fixed php body read 2013-03-08 20:23:09 +01:00
Unbit e29c50c9a5 prepare for JVM uwsgi.rpc() api function 2013-03-08 20:02:21 +01:00
Unbit 4ad9c8d034 fixed default cache set 2013-03-08 20:00:25 +01:00
Unbit 059b4c6ba3 ported cache magic api to go 2013-03-08 19:35:27 +01:00
Unbit 3ab96621db ported magic cache api to lua 2013-03-08 19:06:36 +01:00
Unbit 9bbe148112 ported magic cache api to php 2013-03-08 18:51:31 +01:00
Unbit e32de9b892 ported magic cache api to ruby 2013-03-08 18:12:12 +01:00
Unbit dea7f0fbb8 ported the new magic cache api to perl/psgi 2013-03-08 17:39:55 +01:00
Unbit a684bc6124 completed magic cache clear 2013-03-08 17:21:08 +01:00
Unbit 849ba0856f implemented cache magic exists and del 2013-03-08 17:04:36 +01:00
Unbit f728e277e2 fixed the cache router 2013-03-08 16:40:59 +01:00
Unbit d11fed3511 prepare for exists del and clear 2013-03-08 16:32:46 +01:00
Unbit f3b1acc55e completed cache magic update 2013-03-08 16:26:16 +01:00
Unbit 61722a7876 other improvements in the cache api 2013-03-08 16:16:49 +01:00
Unbit e418a35159 added cache check for max item size 2013-03-08 14:18:49 +01:00
Unbit cd29b033f0 reimplementation of the cache networking protocol to be fully non-blocking 2013-03-08 13:45:27 +01:00
Unbit f3f191558a removed the threaded cache server, it has been superseeded by the new async architecture 2013-03-08 11:29:56 +01:00
Unbit c728471b94 another update to the cache magic api 2013-03-08 11:23:26 +01:00
Unbit 4383578795 prepare for magic cache functions 2013-03-08 10:04:13 +01:00
Unbit b2f127a798 do not start the alarm thread if not needed 2013-03-08 09:19:40 +01:00
Unbit f8212f9e4b fixed alarm subsystem and added uwsgi.alarm to the JVM 2013-03-08 09:18:20 +01:00
Unbit 5e70986bc9 added JVM cache_get and lock/unlock 2013-03-08 08:12:51 +01:00
Unbit d61dff3c26 Merge branch 'master' of https://github.com/unbit/uwsgi 2013-03-08 06:42:04 +01:00
Unbit 2b2da8b7f4 fixed #172 2013-03-08 06:41:46 +01:00
unbit 827b142577 Merge pull request #175 from gber/master
Add optional logging to notfound plugin
2013-03-07 10:40:26 -08:00
Guido Berhoerster d753e1aeef add option for enabling logging in notfound plugin 2013-03-07 19:27:13 +01:00
Unbit 8f7e5fc1bc fixed cache_update for lua 2013-03-07 13:23:24 +01:00
Unbit 650c251236 Merge branch 'master' of github.com:unbit/uwsgi 2013-03-07 13:14:51 +01:00
Unbit 3acb67bd2a try again semop() on interrupt 2013-03-07 13:14:31 +01:00
unbit f9f0eb45e5 Merge pull request #174 from kunkku/lua
Lua binding for cache update function
2013-03-07 01:52:39 -08:00
Kaarle Ritvanen fe0c1a4bb3 Lua binding for cache update function 2013-03-07 09:17:58 +00:00
Unbit eb90b773fa ported JWSGI to the new stable api and refactored ring plugin 2013-03-07 07:01:28 +01:00
Unbit 4f9369aa3a fork() friendly signal management 2013-03-06 20:16:09 +01:00
Unbit 2ae323feee better broodlord num computation 2013-03-06 19:55:20 +01:00
Unbit 56a79ae09c improved broodlord mode [2] 2013-03-06 19:11:49 +01:00
Unbit 48f6d5a240 improved broodlord mode 2013-03-06 19:05:38 +01:00
Unbit 49f717b616 fork() safe rpc subsystem 2013-03-06 18:21:39 +01:00
Unbit 77bae96c34 the ring support is complete 2013-03-06 16:09:06 +01:00
Unbit cbbaa24d6e completetd uwsgi.RequestBody jvm implementation 2013-03-06 14:44:49 +01:00
Unbit 37010c04ca implemented read() method for jvm input stream 2013-03-06 14:26:52 +01:00
Unbit 5902749f9d started implementing jvm body input stream 2013-03-06 13:51:42 +01:00
Unbit b1db1ae651 maintain python2.4 and centos5 compatibility 2013-03-06 13:24:51 +01:00
Unbit d96e394947 implemented ring content-length 2013-03-06 12:25:09 +01:00
Unbit 89891c80ae added ssl error clear even in the ssl router 2013-03-06 11:43:09 +01:00
Unbit edabc3cc6e fixed jvm build on python3 2013-03-06 11:15:16 +01:00
Unbit 9d4300d514 call ERR_clear_error after each https session close 2013-03-06 10:35:32 +01:00
Unbit af1eac9fcc correctly report REMOTE_ADDR and REMOTE_PORT in the fastrouter 2013-03-06 08:55:04 +01:00
Unbit fd50b1e054 allows loading custom classes 2013-03-05 19:23:17 +01:00
Unbit 1239e740ab better jvm class loading 2013-03-05 18:37:20 +01:00
Unbit f6535488e5 more tolerant ring support 2013-03-05 18:00:42 +01:00
Unbit c1c4dd01d2 ring + input_stream completed 2013-03-05 14:01:22 +01:00
Unbit 5cc9c8405a completed uwsgi_jvm_consume_input_stream 2013-03-05 13:56:30 +01:00
Unbit 990028697b Merge branch 'master' of github.com:unbit/uwsgi 2013-03-05 13:44:37 +01:00
Unbit 666c7c5b3f improved OSX jvm auto-detection 2013-03-05 13:40:35 +01:00
Unbit 1ccf9335dd prepare for managing InputStream 2013-03-05 07:58:01 +01:00
Unbit f90bb6b53c better iSeq detection in ring 2013-03-05 07:20:38 +01:00
Unbit 0ad74e282c better jvm paths detection 2013-03-04 21:40:47 +01:00
Unbit 34d6c0ad16 added some doc on top of the ring plugin 2013-03-04 21:36:06 +01:00
Unbit 4ceeb3b789 added more request item to the ring request map 2013-03-04 21:24:45 +01:00
Unbit 259c6c493f huge amount of jvm memory leak fixes 2013-03-04 21:18:59 +01:00
Unbit a3dd2e6efd added support ring clojure.io.file response 2013-03-04 16:50:37 +01:00
Unbit af3860dbd7 completed status and headers management for the ring plugin 2013-03-04 15:43:52 +01:00
Unbit 980b4f3c9a fixed type in yaml/ini parsers 2013-03-04 14:09:13 +01:00
Unbit efa0e0b27b added jvm api for iterations 2013-03-04 14:07:52 +01:00
Unbit d8d60e9a24 signals can now be registered even by non-fork friendly plugins 2013-03-04 06:48:25 +01:00
Unbit 6f5a521692 ported post_build hooks to the new build system 2013-03-04 06:14:22 +01:00
Unbit 522cbfe855 Merge branch 'master' of github.com:unbit/uwsgi 2013-03-04 06:11:27 +01:00
Unbit ed4425ee86 prepare for clojure/ring support 2013-03-04 06:11:07 +01:00
Unbit cb271e9a05 use exec/execfile instead of import in the build system 2013-03-04 06:10:28 +01:00
unbit 621cb99684 Merge pull request #170 from xrmx/coverity9
A few more coverity fixes
2013-03-03 13:46:35 -08:00
unbit 8600060d79 Merge pull request #169 from xrmx/coverity8
More issues reported by Coverity
2013-03-03 13:46:03 -08:00
Riccardo Magliocchetti 511a0aca0b plugins/http: remove self assignment
Also while at it cleanup the handling of the if branch around
the ifdefery.

Reported by Coverity as CID #970999.
2013-03-03 19:51:40 +01:00
Riccardo Magliocchetti 0b0a0ccce1 core/yaml: use size_t for buffer lenght in yaml_get_line
As the only user pass a size_t value and they have different
storage size.

Reported by Coverity as CID #970987.
2013-03-03 19:47:45 +01:00
Riccardo Magliocchetti e4e346772a core/ini: change ini_get_line size type
The only user of ini_get_line uses a size_t as size. Since off_t
and size_t have different storage size just switch ini_get_line
to size_t.

Reported by Coverity as CID #970984.
2013-03-03 19:44:30 +01:00
Riccardo Magliocchetti f102ef64da core/static: Add missing break in switch
Reported by Coverity as CID #970990.
2013-03-03 19:37:49 +01:00
Riccardo Magliocchetti 192c73d53d plugins/router_http: Fix copy and paste bug in uwsgi_routing_func_http
Don't redeclare ub_url since it is already there.

Reported by Coverity as CID #989243, #989252.
2013-03-03 19:29:50 +01:00
Riccardo Magliocchetti 07bd3f5df0 core/exception: avoid null pointer dereference in uwsgi_exception_run_handlers
If wsgi_req is NULL and uwsgi.reload_on_exception is True

Reported by Coverity as CID #989244.
2013-03-03 19:06:59 +01:00
Riccardo Magliocchetti eae00a5c77 core/subscription: fix wrong check in uwsgi_subscribe2
It looks like both s2_server and s2_key are mandatory in
uwsgi_send_subscription so fail if any of them is missing not both.

Reported by coverity as CID #989245.
2013-03-03 18:56:46 +01:00
Riccardo Magliocchetti 133dff6b76 core/alarm: fix memory leak in uwsgi_alarm_thread_loop
Rpoerted by Coverity as CID #989247.
2013-03-03 18:51:46 +01:00
Riccardo Magliocchetti cf634e11a9 core/exceptions: fix leak in uwsgi_exception_handler_thread_loop
Reported by Coverity as CID #989248.
2013-03-03 18:48:59 +01:00
Riccardo Magliocchetti 18dfd10b71 core/exceptions: fix memory leak in wsgi_exception_setup_handlers
Reported by Coverity as CID #989249.
2013-03-03 18:44:33 +01:00
Unbit 54b4189ab9 added uwsgi.java as the base for JVM request plugins 2013-03-03 18:43:22 +01:00
Riccardo Magliocchetti 7e58d78bfe proto/base: fix copy and paste bug in uwsgi_proto_base_cgi_prepare_headers
Reported by Coverity as CID #989253
2013-03-03 18:36:03 +01:00
Unbit 6497c93e3e completeted JVM multithread support 2013-03-03 15:38:01 +01:00
Unbit 27d637a9b2 report useful initialization message for the jvm 2013-03-03 14:40:09 +01:00
Unbit 296f9304ba Merge branch 'master' of github.com:unbit/uwsgi 2013-03-03 14:28:35 +01:00
Unbit a04420e5ef fixed jvm multiple args rpc 2013-03-03 14:28:09 +01:00
Unbit 2e4bc3dc6b allows mixing shared RPC with unshared 2013-03-03 13:56:38 +01:00
Unbit 773d853bb4 the RPC subsystem is no more dependent on cow 2013-03-03 13:28:06 +01:00
Unbit 92e06b1078 another series of improvements for the jvm 2013-03-03 12:36:35 +01:00
Unbit 1e6dd22fd8 prepare for new generation JVM plugin 2013-03-02 21:22:20 +01:00
unbit e5eba6be46 Merge pull request #168 from prymitive/ignore_nagios_requests
don't count ping requests
2013-03-02 11:24:11 -08:00
Łukasz Mierzwa 456729f6e2 don't count ping requests 2013-03-02 20:12:52 +01:00
Unbit 5f191b6e7f allows building the ruby plugin on heroku [3] 2013-03-02 16:16:54 +01:00
Unbit 7435235502 allows building the ruby plugin on heroku [2] 2013-03-02 16:14:32 +01:00
Unbit 764af285d3 allows building the ruby plugin on heroku 2013-03-02 16:09:59 +01:00
Unbit 3ed597368d completetd gemspec 2013-03-02 14:59:34 +01:00
Unbit 2119e06e38 allows building uwsgi as a gem 2013-03-02 14:34:09 +01:00
Unbit 0770fd8815 better error reporting on failed uploads 2013-03-02 13:59:22 +01:00
Unbit 6a94d1f91c fixed base64 decoding 2013-03-01 14:58:51 +01:00
Unbit f53c79cce7 Merge branch 'master' of github.com:unbit/uwsgi 2013-03-01 14:44:35 +01:00
Unbit a2e4c6e272 added isexec route condition 2013-03-01 14:44:15 +01:00
unbit ce898614a0 Merge pull request #165 from prymitive/carbon_hostname
add option for dot replacement in carbon hostname
2013-03-01 05:37:13 -08:00
Łukasz Mierzwa 0676c5e6a8 add option for dot replacement in carbon hostname 2013-03-01 14:13:48 +01:00
Unbit 1469e68a33 added --route-if and --route-if-not 2013-03-01 12:39:39 +01:00
Unbit f4ad33976d added --if-plugin and --if-not-plugin 2013-03-01 11:20:38 +01:00
Unbit c8e12a6be3 better to avoid RegisterSignal in Mono 2013-03-01 11:10:21 +01:00
Unbit 48af1b28d4 Mono RegisterSignal implementation 2013-03-01 09:43:33 +01:00
Unbit b8c115a127 better dummy plugin 2013-03-01 08:26:55 +01:00
Unbit c009ab82f5 sadly Mono is not fork() friendly 2013-03-01 08:19:44 +01:00
Unbit b0c421ff4b fixed Mono domains handling 2013-02-28 20:20:04 +01:00
Unbit a39ac59757 refactored cgi plugin 2013-02-28 14:42:43 +01:00
Unbit d3792cba72 fixed php build without pcre 2013-02-28 14:16:04 +01:00
Unbit 4aa17c40fc allows building without ssl 2013-02-28 14:08:15 +01:00
Unbit 38b1f52723 fixed static-index and apply_fast routes 2013-02-28 12:14:59 +01:00
Unbit 30e50df5d4 better header in mono plugin 2013-02-28 00:20:19 +01:00
Roberto De Ioris 22d9a2b831 fixed OpenBSD support 2013-02-28 10:02:56 +01:00
Unbit 6bccb62799 added for-glob 2013-02-27 23:48:56 +01:00
Unbit acd1215524 added asp.net dynamic applications 2013-02-27 23:36:01 +01:00
Unbit 4381e816ae fixed cache_del2 2013-02-27 23:00:50 +01:00
Unbit 5760338445 multi-app mode for mono 2013-02-27 09:19:50 +01:00
Unbit e517bcea7c implemented Mono send file from handle 2013-02-27 08:30:14 +01:00
Unbit b6bdafa669 another round of Mono methods implementation 2013-02-27 06:52:53 +01:00
Unbit 5bd10a99fb report unavailable lock engine 2013-02-27 04:28:11 +01:00
Unbit b8dfd1be85 fixed pthread locking ifdef bug 2013-02-27 04:10:20 +01:00
Unbit 3c810e5ca8 updated carbon plugin 2013-02-27 01:15:56 +01:00
Unbit 61a1ca4ca4 initialize alarm and exception thread ONLY in the master 2013-02-26 19:29:29 +01:00
Unbit a71d9953a1 fixed sign bug 2013-02-26 17:46:47 +01:00
Unbit b20fbf5fe8 re-added uwsgi.route() 2013-02-26 06:38:34 +01:00
Unbit c73490fc80 prepare for --mono-key 2013-02-26 02:09:38 +01:00
Unbit da6b052bef added --mono-gc-freq 2013-02-26 01:34:45 +01:00
Unbit 08ea52164c fixed BSD support for Mono 2013-02-26 09:58:17 +01:00
Unbit 4de3d534a8 first public release of the new Mono/ASP.NET plugin 2013-02-26 01:09:09 +01:00
Unbit 7be55d71a8 improved mono build system 2013-02-25 23:14:43 +01:00
Unbit 6e24730025 fixed mime type with static-index 2013-02-25 23:10:29 +01:00
Unbit 513380d5c9 first version of the new mono plugin 2013-02-25 17:50:19 +01:00
Unbit 2f474b2af4 added support for ruby 2 2013-02-25 07:33:05 +01:00
Unbit a062ef2ac2 added rb tmier in the PSGI plugin 2013-02-24 09:45:39 +01:00
Unbit b82566268a completeted the CoroAE plugin, added timers to the PSGI plugin 2013-02-24 09:41:33 +01:00
Unbit 8d16ce28b9 avoid async queue full log storming 2013-02-24 07:55:46 +01:00
Unbit 2a9835649e added --tcp-nodelay 2013-02-23 15:50:34 +01:00
unbit 9912ab6afb Merge pull request #157 from xrmx/coverity7
More issues reported by Coverity
2013-02-23 06:25:04 -08:00
Unbit 94f18e3508 allows --attach-daemon without workers 2013-02-23 14:45:20 +01:00
Unbit 25c812e4aa fixed --http-socket url decoding 2013-02-23 13:46:31 +01:00
Unbit bddf8fe5c9 completed --perl-arg and --perl-args 2013-02-23 13:24:59 +01:00
Unbit fbabb14c61 another heroku check [5] 2013-02-23 13:03:48 +01:00
Unbit fd62e2ebb7 another heroku check [4] 2013-02-23 12:59:13 +01:00
Unbit e96c43970d another heroku check [3] 2013-02-23 12:54:00 +01:00
Unbit 99eda6d084 another heroku check [2] 2013-02-23 12:51:20 +01:00
Unbit 91b2cc7570 another heroku check 2013-02-23 12:47:06 +01:00
Unbit 0ff6277f28 prepare for perl args 2013-02-23 12:46:14 +01:00
Unbit dee99b6535 try to understand how heroku installed python [9] 2013-02-23 11:57:48 +01:00
Unbit 39260ebac0 try to understand how heroku installed python [8] 2013-02-23 11:53:47 +01:00
Unbit ac3ec1781e try to understand how heroku installed python [7] 2013-02-23 11:46:33 +01:00
Unbit e8925ac7b7 try to understand how heroku installed python [6] 2013-02-23 11:42:55 +01:00
Unbit 2877a5a05d try to understand how heroku installed python [5] 2013-02-23 11:40:50 +01:00
Unbit 9e3bfd261a try to understand how heroku installed python [5] 2013-02-23 11:38:34 +01:00
Unbit 636cd261e0 try to understand how heroku installed python [4] 2013-02-23 11:26:21 +01:00
Unbit 5fff6467a8 try to understand how heroku installed python [4] 2013-02-23 11:24:42 +01:00
Unbit 647c972ffe try to understand how heroku installed python [3] 2013-02-23 11:21:12 +01:00
Unbit ed9ac16c78 try to understand how heroku installed python [2] 2013-02-23 11:14:01 +01:00
Unbit 4f1b610459 try to understand how heroku installed python 2013-02-23 11:11:25 +01:00
Unbit a68b9b9fa6 attempt to better build on non-share-library configs 2013-02-23 11:08:41 +01:00
Unbit cd8e9f62b2 fixed GIL in new body reading system 2013-02-23 08:28:27 +01:00
Unbit f3ee043246 fixed a refcnt bug in psgi plugin 2013-02-23 08:26:57 +01:00
Riccardo Magliocchetti 949fdb5f86 core/cache: fix memory leak
Reported by Coverity as CID #981514.
2013-02-22 08:42:49 +01:00
Riccardo Magliocchetti d1c8a02151 core/io: check realloc() return value
Reported by Coverity as CID #981513.
2013-02-22 08:42:33 +01:00
Riccardo Magliocchetti 7c0f002239 core/emperor: fix memory leak on error path
Reported by Coverity as CID #971011.
2013-02-22 08:15:55 +01:00
Riccardo Magliocchetti 4d236b9b74 core/cache: close() mmapped cache store
The file will actually get closed when unmapped but we should
remove our reference to it.

Reported by Coverity scan as CID #971009.
2013-02-22 07:54:51 +01:00
Riccardo Magliocchetti 8d39eabf9d core/alarm: fix memory leak
Reported by Coverity scan as CID #971007.
2013-02-22 07:49:42 +01:00
unbit 591cec9a2c Merge pull request #156 from prymitive/fix_travis
Make travis fail is test request had errors
2013-02-20 05:46:31 -08:00
Łukasz Mierzwa 057d0bc250 add -f switch to curl options so that it will exit with non-zero return code if request fails 2013-02-20 13:38:38 +01:00
Unbit 252731544b it is too early to automatically build the router_memcached plugin 2013-02-20 11:42:33 +01:00
Unbit cdb901c091 another series of routing porting to the new api 2013-02-20 11:41:30 +01:00
Unbit 00c5a77554 new routing translator functions 2013-02-20 11:33:33 +01:00
Unbit 0e5f8acde5 goto label can be build from regexp 2013-02-20 07:57:46 +01:00
Unbit d2ae982329 improved routing label 2013-02-20 06:51:38 +01:00
Unbit 5307de6974 added uwsgi_buffer json escaper 2013-02-19 19:09:27 +01:00
Unbit dc2f9f405d added redirect-301 internal router instruction 2013-02-19 12:39:42 +01:00
Unbit e610682b31 added exception_log plugin 2013-02-19 12:34:43 +01:00
Unbit 34b6bc5378 preliminary support for exception handlers 2013-02-19 10:59:48 +01:00
Unbit 3d171f52b3 report client address and client port on corerouter errors 2013-02-19 09:01:41 +01:00
Unbit cfa4d2a3ad added ipv6 in corerouters 2013-02-19 08:19:47 +01:00
Unbit 12bf2cd3af fixed exception management in python mules and improved uwsgidecorators 2013-02-19 07:11:45 +01:00
Unbit 5089123e5a prepare for ipv6 support in corerouters 2013-02-18 18:21:57 +01:00
Unbit 4d53d3a16a added more logvars 2013-02-18 13:05:43 +01:00
Unbit 941dd70e3b added additional infos in the exceptions catcher 2013-02-17 16:24:36 +01:00
Unbit 609b5aeb0a porte the ruby/rack plugin to the new exception api 2013-02-17 16:18:12 +01:00
Unbit 8e6b810df8 fixed lua plugin 2013-02-17 14:27:32 +01:00
Unbit f31186a0f9 completetd first part of the new exceptions framework 2013-02-17 14:26:31 +01:00
Unbit b5a6da5448 refactored catch_exceptions 2013-02-17 11:22:09 +01:00
Unbit 0a9b5f05b0 prepare for advanced exception management 2013-02-17 10:12:49 +01:00
Unbit 7c8ae1737a fixed reports in xmpp alarm 2013-02-17 09:33:03 +01:00
Unbit 0e502172c9 added websockets tolerance 2013-02-16 13:31:01 +01:00
Unbit 0dd2a34e22 improved websockets support 2013-02-16 13:13:04 +01:00
Unbit f4b8f3e49d fixed a stupid bug in websocket ruby example 2013-02-16 10:23:04 +01:00
Unbit 9610ec72ab openindiana fixes 2013-02-15 22:24:35 +01:00
Unbit 32bf82552e added SCGI support 2013-02-15 19:08:28 +01:00
Unbit d15f1a9e36 prepare for SCGI support 2013-02-15 17:53:06 +01:00
Unbit 5e02bc3c84 UWSGI_ALARM is no more required 2013-02-15 12:26:45 +01:00
Unbit d397036e29 improved the alarm subsystem 2013-02-15 12:17:29 +01:00
Unbit c92fde03b9 various micro-optmizations in async, caching and static file serving 2013-02-15 08:11:33 +01:00
Unbit e1598af32f fiber requiers async mode 2013-02-14 20:53:13 +01:00
Unbit fbfab14224 improved fiber support 2013-02-14 20:49:26 +01:00
Unbit 8ff56a694a added --http-socket-modifier1 and --http-socket-modifier2 2013-02-14 20:10:56 +01:00
Unbit 639f26ff26 improved fastcgi support 2013-02-14 20:08:35 +01:00
Unbit 7d8a2968d5 first part of the fastcgi porting to the new api 2013-02-14 17:30:23 +01:00
Unbit f70c7c1e17 report worker id during gevent requests waiting 2013-02-14 12:13:33 +01:00
Unbit a89eb5d8cb report go version on startup 2013-02-14 12:11:49 +01:00
Unbit 4c9d30cc1b ported Go to the new api 2013-02-14 11:34:33 +01:00
Unbit fd7d4fc944 greatly improved chain reload in gevent mode 2013-02-14 10:12:24 +01:00
Unbit 7106301d86 report write_errors in core statistics 2013-02-14 09:27:04 +01:00
Unbit f046d47eb2 worker's busy value is now dinamically computed 2013-02-14 09:17:59 +01:00
Unbit 0b8b6346be ported router_uwsgi to the new api 2013-02-13 16:20:40 +01:00
Unbit 104c8a8b90 fixed routing + ugreen 2013-02-13 12:23:46 +01:00
Unbit f25ab0fdd2 more improvements on the non-blocking api 2013-02-13 12:07:07 +01:00
Unbit bb789d1ac0 fixed cheaper 2013-02-13 08:56:43 +01:00
Unbit e94315ca75 Merge branch 'master' of https://github.com/unbit/uwsgi 2013-02-12 18:12:17 +01:00
unbit dd2e07122a Merge pull request #151 from xrmx/ipleak
core: don't leak ip in uwsgi_open_and_read()
2013-02-12 10:19:52 -08:00
Unbit 375d446bf0 mules and gateways are correctly managed 2013-02-12 19:18:54 +01:00
Unbit 46eafeaa58 graceful reload is working again 2013-02-12 18:47:53 +01:00
Unbit 79dccaac9c first big (really bug) master refactoring 2013-02-12 18:42:36 +01:00
Unbit cdf05dcef2 make older compilers happy 2013-02-12 18:12:04 +01:00
unbit 7d8aa98766 Merge pull request #155 from prymitive/carbon_requests_fix
fixed carbon requests metric
2013-02-11 22:14:24 -08:00
Łukasz Mierzwa 115470837e fixed carbon requests metric 2013-02-11 20:51:58 +01:00
Unbit c226feaeca added --touch-chain-reload 2013-02-11 20:10:43 +01:00
Unbit 669c14ac71 fixed subscription reference count 2013-02-11 20:03:52 +01:00
Unbit 1c5347ac90 added router_memcached plugin 2013-02-11 18:57:58 +01:00
Unbit 83ce30a51e added an heavy test for new caching system 2013-02-11 16:57:03 +01:00
Unbit f75a637ef6 implemented cache bitmap blocks unmarking 2013-02-11 14:50:55 +01:00
Unbit 48d749f11b prepare for unmarking function 2013-02-11 14:20:10 +01:00
unbit 3f041350a2 Update README 2013-02-11 14:11:36 +01:00
Unbit 39613d466a other improvements for bitmap based caching 2013-02-11 14:09:40 +01:00
Unbit 3c32980fe3 forget to reset SIGCHLD to SIG_DFL 2013-02-10 20:13:32 +01:00
Unbit a1fbed315f reset sigmask on startup 2013-02-10 19:51:36 +01:00
Unbit c0083c5801 first commit for bitmap based cache 2013-02-10 12:11:47 +01:00
Unbit f86404f03f fixed FreeBSD sendfile 2013-02-09 18:16:37 +01:00
unbit 602f0385cb Merge pull request #153 from prymitive/cheaper_zero_fix
additional validation of the --cheaper value at startup
2013-02-09 07:22:34 -08:00
Łukasz Mierzwa c32da58a7c additional validation of the --cheaper value at startup 2013-02-09 14:15:35 +01:00
Riccardo Magliocchetti d64a734292 core: don't leak ip in uwsgi_open_and_read()
While at it convert malloc() to uwsgi_malloc() to cleanup error
handling.

Reported by Coverity Scan as CID #971018.
2013-02-09 12:49:35 +01:00
Unbit 65c047dca1 added timebomb concept and improved gevent reloading 2013-02-09 07:55:12 +01:00
Unbit 73b1887287 fixed #34 2013-02-08 21:06:42 +01:00
Unbit 8d41a77baa coro and gevent improvements 2013-02-08 07:01:04 +01:00
Unbit 0692bf45da fixed a stupid bug in protocol parser 2013-02-07 21:09:22 +01:00
Unbit 9d5d439191 rpc subsystem is now async/greenthreads friendly 2013-02-07 18:31:44 +01:00
Unbit 9f15345183 prepare dor async-friendly rpc 2013-02-07 17:23:59 +01:00
Unbit 7d84413038 added a note on cheap string 2013-02-07 16:49:42 +01:00
Unbit ecd4b9bc36 added notes for the new caching plugin 2013-02-07 16:15:26 +01:00
Unbit 47d66ab368 ported cache store system to the new api 2013-02-07 16:01:15 +01:00
Unbit 54227db3e4 cache syncing is working again 2013-02-07 15:42:14 +01:00
Unbit aecd9a7703 ported udp cache server to the new api 2013-02-07 15:33:01 +01:00
Unbit dd0551bf68 ported the cache sync client system to the new api 2013-02-07 15:21:32 +01:00
Unbit d649853a51 ported cache udp nodes to the new api 2013-02-07 15:12:58 +01:00
Unbit 05ad7bf07e fixed suspend when harakiri is in place 2013-02-07 14:10:13 +01:00
Unbit f29ac2117f refactored mod_proxy_uwsgi 2013-02-07 13:35:43 +01:00
Unbit 91be1f8929 really apply PATH_INFO fix in mod_proxy_uwsgi 2013-02-07 11:43:59 +01:00
Unbit 1e9c8c47bb add copyright notes in mod_proxy_uwsgi and correctly decode PATH_INFO/SCRIPT_NAME 2013-02-07 10:05:15 +01:00
Unbit 63c8ce3bf8 updated mod_uwsgi copyright notes 2013-02-07 09:43:01 +01:00
Unbit d13b58869d fiber fixes 2013-02-04 11:23:47 +01:00
Unbit 49740e99fb Merge branch 'master' of github.com:unbit/uwsgi 2013-02-04 11:02:43 +01:00
unbit 09b136ed2c Merge pull request #149 from prymitive/alarm_curl
ifdefed stuff only available in newer curl releases
2013-02-05 03:30:59 -08:00
Łukasz Mierzwa 5be46f0cb3 ifdefed stuff only available in newer curl releases 2013-02-05 11:50:06 +01:00
Unbit e5094e7efa ruby/rack websockets support 2013-02-04 11:02:24 +01:00
Unbit 60580a0195 prepare for ruby websockets + fibers support 2013-02-04 08:55:19 +01:00
Unbit 0a73039cfc improved ugreen support and cgi integration 2013-02-04 04:56:13 +01:00
Unbit 94aed13978 simplified --http-websockets 2013-02-03 20:52:42 +01:00
Unbit 9679645354 Coro::AnyEvent + websockets is working 2013-02-03 20:38:30 +01:00
Unbit 0c1a25b8a6 coroae fixes 2013-02-03 17:03:59 +01:00
Unbit 4a3c1e537b zmq need a bit more work... 2013-02-03 15:58:29 +01:00
Unbit c355c93f12 ported ping plugin to the new api 2013-02-03 14:17:39 +01:00
Unbit 5552e87087 generalized offload subsystem 2013-02-03 14:14:00 +01:00
Roberta Giordano 67544158d9 osx fixes 2013-02-04 13:08:16 +01:00
Unbit f117f404fc fixed a regression with sendfile() 2013-02-03 10:57:13 +01:00
Unbit d4130dbc4b first round of protocol parsers optimizations
preliminary api for language-independent body read

another step

completed body read language independent implementation

ported gevent to the new read/write api

ported websockets to the new read/write api

removed channels subsystem

removed channels subsystem

ported lua to the new read/write api

fixed post-buffering

readline is still broken

improved request body readline

very difficult test for readline()/read() combo passed

other improvements in postbuffering/read/readline

ported --http-socket to the new api

added X-Forwarded-SSL management

removed old api

more refactoring

ported the RACK plugin to the new api

ported psgi plugin to the new api

defintely removed clustering

simpified ifdel hell

simpified ifdef hell

removed useless configuration options
2013-02-03 10:38:13 +01:00
Unbit e50a7c518f improved alarm_xmpp plugin 2013-01-31 09:56:20 +01:00
Unbit 874b994e66 added --static-gzip-* options 2013-01-31 07:49:19 +01:00
Unbit cc93687476 better support for robust mutexes 2013-01-30 18:31:15 +01:00
Unbit e354f3b37a fixed PTHREAD_PRIO_INHERIT 2013-01-30 18:07:24 +01:00
Unbit d204e75c1c added --thunder-lock 2013-01-30 17:59:00 +01:00
Unbit 8c0e77b737 fixed SERVER_PORT in routers when shared sockets are in place 2013-01-30 16:31:11 +01:00
Unbit 70f12c4407 fixed backlog reporting on 32bit 2013-01-30 14:06:09 +01:00
Unbit ac78830a90 offloading by default, if available 2013-01-30 13:22:02 +01:00
Unbit 534f78acb3 improved sendfile management 2013-01-30 12:51:13 +01:00
Unbit 443c2c5a29 better route/sendfile/offload logging 2013-01-30 12:24:38 +01:00
Unbit feca5abc53 announce only spdy3 2013-01-30 08:30:33 +01:00
unbit c643c3069c Merge pull request #143 from xrmx/coverity6
Fix some leaks reported by Coverity scan
2013-01-30 10:57:36 -08:00
unbit 1cffe0dfe6 Merge pull request #142 from prymitive/router_delta
add last_request attribute to subscription node, it will hold the number...
2013-01-30 09:45:07 -08:00
Łukasz Mierzwa 3761709ec4 add last_request attribute to subscription node, it will hold the number of requests since last subscription ping
use node->last_requests instead of absolute request counter in (w)lrc
2013-01-30 18:32:06 +01:00
Riccardo Magliocchetti 956f54033c plugins/http: fixup some leaks in spdy
Reported by Coverity as CID #971245, #971246.
2013-01-30 18:05:42 +01:00
Riccardo Magliocchetti 7afd4e39eb proto/zeromq: Don't leak ub on write error in uwsgi_proto_zeromq_writev_header
Reported by Coverity as CID #971247.
2013-01-30 17:43:45 +01:00
Unbit 76866a05ba fixed realloc() usare in core/io.c as spotted by cppcheck [2] 2013-01-29 16:31:48 +01:00
Unbit 74eeee48ae fixed realloc() usare in core/io.c as spotted by cppcheck 2013-01-29 16:28:45 +01:00
Unbit 3babcbe2bb added --route-referer 2013-01-29 12:07:56 +01:00
Unbit 1a50463ed9 --sslrouter and --sslrouter2 to be more aligned with --https 2013-01-29 10:57:30 +01:00
Unbit a88244a700 fixed --sslrouter-sni 2013-01-29 10:51:04 +01:00
Unbit 7cf4cc788c added --sni-dir 2013-01-29 09:44:20 +01:00
Unbit 990e7241e6 added the sslrouter and various corerouters micro-optimizations 2013-01-29 09:08:41 +01:00
unbit 40d69f90d9 Merge pull request #141 from xrmx/coverity5
Check return value of library call Coverity issues
2013-01-28 13:52:56 -08:00
Unbit 194f4897e3 new rbtree implementation 2013-01-28 22:22:29 +01:00
Riccardo Magliocchetti d56e35651b core/cluster: log sendto() error
Reported by Coverity as CID #970958.
2013-01-28 19:41:41 +01:00
Riccardo Magliocchetti 58314c2800 core: log when sendmsg fails
Reported by Coverity as CID #970962, #970963.
2013-01-28 18:41:08 +01:00
Riccardo Magliocchetti 0af894df06 core: log when fcntl() fails
Reported by Coverity as CID #970967, #970966.
2013-01-28 18:37:28 +01:00
Riccardo Magliocchetti 9bfcec2999 lib/linux_ns: check mkdir() return value
Fail earlier if we can't create the dirs we need.
Reported by Coverity as CID #970969.
2013-01-28 18:31:15 +01:00
Unbit 65c513bec2 when the emperor has a master, allows it to respawn the dead emperor 2013-01-28 16:35:12 +01:00
Unbit ec3a95dafb fixed request log routing 2013-01-28 10:59:26 +01:00
Unbit 8386d7829d fixed fastrouter read body hook 2013-01-28 10:45:27 +01:00
Unbit bb9c3e0d6c logformat can now create apache compatible logs 2013-01-28 09:42:11 +01:00
Unbit bc5b71a5ec Merge branch 'master' of https://github.com/unbit/uwsgi 2013-01-28 09:34:22 +01:00
Unbit 2cdf1b7265 fill empty logvars 2013-01-28 09:34:09 +01:00
unbit 162c861e74 Merge pull request #137 from prymitive/reload_mercy_for_cheaped
reload/cheap mercy for invidual workers
2013-01-28 00:19:55 -08:00
unbit edb9c5f982 Merge pull request #138 from prymitive/php_new_cache
fixed php plugin to use new cache api
2013-01-28 00:01:22 -08:00
Łukasz Mierzwa c88be57dd9 refactored php plugin to use new cache api 2013-01-28 00:44:41 +01:00
Łukasz Mierzwa c1682f4ee4 reload/cheap mercy for invidual workers 2013-01-27 23:19:50 +01:00
Unbit 799ac9310f after years we can finally differentiate between stderr and request logging 2013-01-27 17:59:23 +01:00
unbit 2540e739c7 Merge pull request #136 from xrmx/coverity4
More issues reported by Coverity
2013-01-27 04:54:54 -08:00
Riccardo Magliocchetti 43ee6a305f plugin/python: fix some leaks on error paths in symimporter
Reported by Coverity as CID #971059, #971060.
2013-01-27 12:36:54 +01:00
Riccardo Magliocchetti 0cb2e6852b plugins/python: fix tracebaker resource leaks on import error
Reported by Coverity as CID #971061, #971062, #971063.
2013-01-27 12:19:45 +01:00
Riccardo Magliocchetti a559e9ea63 plugins/python: fix a couple of memory leaks
Reported by Coverity as CID #971065, #971066.
2013-01-27 12:10:19 +01:00
Riccardo Magliocchetti 89dfa7976a core/socket: fix a couple of memory leaks
Reported by Coverity as CID #971053, #971054.
2013-01-27 11:54:48 +01:00
Unbit 56a8d44cb0 Merge branch 'master' of https://github.com/unbit/uwsgi 2013-01-27 11:37:41 +01:00
Unbit 7fc644d1a8 fixed uwsgi_cache_create definition 2013-01-27 11:37:23 +01:00
Riccardo Magliocchetti 74d6bac54b plugins/python: check return value of PyType_Ready in init_uwsgi_embedded_module
Reported by Coverity as CID #970972.
2013-01-27 10:33:17 +01:00
Riccardo Magliocchetti 5647aff995 plugins/python: remove double assignment to same variable
Which coverity reports as undefined behaviour in CID #970978.
2013-01-27 10:22:31 +01:00
Riccardo Magliocchetti cf67363164 core: prefer strncpy over strcpy in emperor
Coverity reports a possible buffer overrun which is not possible
at the momento because the only caller of uwsgi_emperor_blacklist_add
use another fixed buffer of the same size as te one we are writing
to. Still better safe than sorry. Reported as CID #971078.
2013-01-27 10:17:01 +01:00
Roberta Giordano 1bdec68fb7 added uagent to logvars 2013-01-27 09:34:55 +01:00
Unbit 5698955384 added ltime logformat 2013-01-27 08:59:05 +01:00
unbit 732466e4e4 Merge pull request #133 from xrmx/coverity3
Fix "argument cannot be negative" errors reported by Coverity
2013-01-26 22:21:44 -08:00
unbit 23165a1587 Merge pull request #132 from xrmx/coverity2a
More issues reported by Coverity
2013-01-26 22:20:15 -08:00
unbit d9a8e071e2 Merge pull request #131 from xrmx/coverity
Fix some issues spotted by coverity scan
2013-01-26 22:18:03 -08:00
Riccardo Magliocchetti e106a6ef61 plugins/python: check uwsgi_connect return code in uwsgi_python_harakiri
Reported by Coverity as CID #970996.
2013-01-26 21:23:17 +01:00
Riccardo Magliocchetti 297bd429a9 core: check return of uwsgi_connect in uwsgi_opt_connect_and_read
Reported by Coverity as CID #970995.
2013-01-26 21:18:55 +01:00
Riccardo Magliocchetti 838bdd27a6 core: check return of getgroups()
When we pass 0 as size to getgroups() the number of additional
groups is return. If it returns error or 0 don't even try to
poke for additional groups.

Reported by Coverity as CID #970944.
2013-01-26 21:10:33 +01:00
Riccardo Magliocchetti f50e179100 core: don't call dup2 on negative fd after open() error
Also call close() only if open was succesful.
Reported by Coverity as CID #970991.
2013-01-26 21:00:11 +01:00
Riccardo Magliocchetti c6ddaf6b8d core: add missing legion mutex unlock on error path
Reported by Coverity as CID #970988.
2013-01-26 19:45:46 +01:00
Riccardo Magliocchetti cbc06f92d0 core: add missing unlock in wsgi_req_accept
Reported by Coverity as CID #970989.
2013-01-26 19:29:46 +01:00
Riccardo Magliocchetti 386fac2421 core: fix copy & paste bug in uwsgi_manage_command_cron
It looks like tm_hour is used where tm_mon was intended.
Reported by Coverity as CID #970975.
2013-01-26 19:18:15 +01:00
Riccardo Magliocchetti 3138d0b6c3 plugins/carbon: add missing call to va_end()
Reported by Coverity as CID #971091.
2013-01-26 19:14:52 +01:00
Riccardo Magliocchetti 135a5a505c lib/linux_ns.c: fix some possible null pointer dereferences
In case we cannot open /self/proc/mounts or it is malformed.
Spotted by Coverity, CID #971002, #971003.
2013-01-26 19:06:49 +01:00
Riccardo Magliocchetti 1b47a8932e plugins/cache: fix resource leak
Reported by Coverity, CID #971053.
2013-01-26 18:44:08 +01:00
Riccardo Magliocchetti 01e4d07fb8 plugins/corerouter: use correct goto label
After cwd has been allocated we should exit through end0.
Spotted by Coverity, CID #971054.
2013-01-26 18:39:37 +01:00
Riccardo Magliocchetti ec1bfdeb2a plugins/router_http: fix leak if connection to host fails
Fix Coverity CID #971069.
2013-01-26 18:29:36 +01:00
Riccardo Magliocchetti ac3d617037 core: remove spurious call to dlsym
Fix use after free reported by Coverity, CID #971090
2013-01-26 18:13:11 +01:00
Roberta Giordano 253805daa6 added rsize,hsize and cl logvars, added logvar: routing instruction 2013-01-26 17:25:18 +01:00
unbit 63e4964808 Merge pull request #130 from prymitive/busyness_ifdef_fix
better backlog ifdef in cheaper_busyness
2013-01-26 05:41:00 -08:00
Łukasz Mierzwa 57962d2e6e better backlog ifdef in cheaper_busyness 2013-01-26 14:08:29 +01:00
unbit f81ea8e898 Merge pull request #109 from prymitive/busyness_backlog
spawn new workers if backlog is > 0 for some time
2013-01-26 05:04:24 -08:00
Łukasz Mierzwa 821af5d763 spawn new workers if backlog is > 0 for some time 2013-01-26 13:59:42 +01:00
unbit 2e923aaf9e Merge pull request #128 from prymitive/rsyslog_fixes
split messages > 995 bytes into chunks in rsyslog plugin
2013-01-26 03:46:12 -08:00
Łukasz Mierzwa 15b12983e1 * add buf to uwsgi_logger struct and use it when logger needs buffering (rsyslog + graylog2)
* allow to split big syslog messages into chunks
* allow to set maximum syslog packet size (some syslog deamons support that)
2013-01-26 12:37:23 +01:00
unbit 15f0f8d294 Merge pull request #125 from prymitive/worker_lifetime
new options to control worker minimum and maximum lifetime
2013-01-26 03:29:34 -08:00
unbit c6658fca72 Merge pull request #129 from prymitive/named_cache_stats
don't free lock name of a named cache
2013-01-26 03:22:13 -08:00
Łukasz Mierzwa 5bbc7ee673 don't free lock name of a named cache 2013-01-26 11:56:16 +01:00
Unbit 37927c6f5d ported sweepers to the new api and added more statistics 2013-01-26 07:43:12 +01:00
Unbit 1a6ee9a775 added --emperor-procname 2013-01-26 04:11:07 +01:00
Unbit d42649d80b implemented SPDYv3 WINDOW UPDATE 2013-01-25 18:58:11 +01:00
Unbit 2acd338429 SPDY improvements 2013-01-25 17:38:42 +01:00
Unbit 7adcb19d1a fixed --http-to-https 2013-01-25 12:51:26 +01:00
Unbit a2f776b487 fixed rawrouter allocation bug 2013-01-25 11:00:29 +01:00
Unbit 941ae2b5e3 better non-blocking support for protocols 2013-01-25 10:38:10 +01:00
Unbit e88d4bbb79 improved expect-continue management 2013-01-25 09:41:39 +01:00
Unbit db352999b8 --check-cache takes an optional parameter (the cache name) 2013-01-24 20:43:15 +01:00
Unbit 744fed60b9 Merge branch 'master' of https://github.com/unbit/uwsgi 2013-01-24 20:41:00 +01:00
Unbit df85a8e6a9 added uwsgi_cache_safe_get2() commodity function 2013-01-24 20:40:43 +01:00
unbit 7ba7fd55d0 Merge pull request #126 from prymitive/master_init_fix
One more fix is needed for master branch
2013-01-24 11:32:47 -08:00
Łukasz Mierzwa 6fd2176b3e fixed new cache typo 2013-01-24 20:25:11 +01:00
Unbit 271ac33193 fixed a regression caused by new caching system 2013-01-24 20:20:14 +01:00
Unbit 8d33491211 added magix gzipper in http corerouter and added sessions counter in corerouters 2013-01-24 19:31:50 +01:00
Unbit 13a42599ea corerouters --*-use-cache option can take an optional cache name 2013-01-24 10:24:46 +01:00
Unbit cb8878dc81 --ssl-sessions-use-cache can take the cache name as parameter 2013-01-24 10:03:07 +01:00
Unbit 5e561c0d1e --cache2 is ready 2013-01-24 09:02:53 +01:00
Unbit fbfe58948b prepare for the --cache2 option 2013-01-23 20:38:55 +01:00
Unbit e839a9eb89 ported psgi and rack plugin to the new caching api 2013-01-23 20:32:52 +01:00
Unbit b90779aecf improved the caching subsystem to allows dynamic key 2013-01-23 20:16:49 +01:00
Unbit 2447f819cb first commit of the new caching infrastructure 2013-01-23 16:15:43 +01:00
Roberto De Ioris 6f956c6965 fixed gzip encoding 2013-01-22 18:28:40 +01:00
Roberto De Ioris 729fdd22c4 preliminary support for uWSGI-Encoding magic header 2013-01-21 19:24:27 +01:00
Łukasz Mierzwa 7b59668386 new options to control worker minimum and maximum lifetime 2013-01-21 16:44:43 +01:00
Roberto De Ioris 1e5739f8ea added core/strings.c 2013-01-21 16:41:33 +01:00
Roberto De Ioris 3ef7e9aee3 added --rem-header support 2013-01-21 16:13:20 +01:00
Roberto De Ioris 4854b3cbcf fixed rack plugin 2013-01-21 14:55:35 +01:00
Roberto De Ioris 5273dbba90 maintain after_hook test in welcome.py 2013-01-21 14:53:40 +01:00
Roberto De Ioris b59f3b254f fixed buf in python uwsgi.workers() 2013-01-21 14:50:27 +01:00
Roberto De Ioris dda6bb2a5f dump request vars in stats (if possibile and safe) 2013-01-21 14:24:42 +01:00
Roberto De Ioris 0daff2cfe2 multithread corner case fixes 2013-01-21 12:12:36 +01:00
Roberto De Ioris 61ee03a99e improved http keepalive 2013-01-21 10:15:26 +01:00
Roberto De Ioris 06b6704be3 tempoarily disable fastcgi support to continue building with clang 2013-01-21 09:07:15 +01:00
Roberto De Ioris ab2a8c90cd fixed http router 2013-01-20 20:51:48 +01:00
unbit 21ada10805 Merge pull request #123 from prymitive/busyness_backlog_fixes
Better backlog messages in cheaper_busyness
2013-01-20 10:22:51 -08:00
Łukasz Mierzwa 3d8467506a better log messages when backlog is over limit but we already started max number of workers 2013-01-20 18:52:27 +01:00
Roberto De Ioris 8f996bb68d fixed go plugin 2013-01-20 18:04:06 +01:00
Roberto De Ioris 9f55579b87 added support for automatic status codes 2013-01-20 17:29:03 +01:00
Roberto De Ioris 215e514385 tiny fixes in the psgi plugin 2013-01-20 17:06:29 +01:00
Roberto De Ioris 77bd73d597 psgi plugin improvements 2013-01-20 16:25:39 +01:00
Roberto De Ioris 3642198acd added gevent.h 2013-01-20 16:01:39 +01:00
Roberto De Ioris 810a1463d5 started porting the gevent plugin to the new api 2013-01-20 16:00:11 +01:00
Roberto De Ioris d3dfdbb0ba refactoring [2] 2013-01-20 15:34:24 +01:00
Roberto De Ioris f71f76c6e6 refactoring 2013-01-20 15:20:35 +01:00
Roberto De Ioris 287a8c8a24 improved notfound plugin 2013-01-20 14:46:39 +01:00
Roberto De Ioris 70d9dab5ef avoid wasting resources on failed writes... 2013-01-20 14:45:40 +01:00
Roberto De Ioris c9987aa721 ported http-socket to the new api 2013-01-20 14:35:06 +01:00
Roberto De Ioris 874e8b5621 completed port of the python plugin to the new writing api 2013-01-20 14:17:54 +01:00
Roberto De Ioris 4b3b3f9200 need to fix go support 2013-01-20 13:14:34 +01:00
Roberto De Ioris 994209ffb0 another bunch of portings 2013-01-20 13:08:10 +01:00
Roberto De Ioris 4cd5643c8f ported lua to the new api 2013-01-20 13:01:23 +01:00
Roberto De Ioris b7e2eaad0f ported the example plugin 2013-01-20 12:52:58 +01:00
Roberto De Ioris 71a5e8b768 ported php to the new api 2013-01-20 12:46:52 +01:00
Roberto De Ioris 6044af9e7a ported the cgi plugin to the new write api 2013-01-20 12:36:17 +01:00
Roberto De Ioris 4e2178ffab another WSGI optimization 2013-01-20 11:41:43 +01:00
Roberto De Ioris 37e153d5de need to find a way to better manage write errors... 2013-01-20 10:32:02 +01:00
Roberto De Ioris e1316153be another series of porting 2013-01-19 21:42:05 +01:00
Roberto De Ioris 876f775698 solid sendfile for the new api 2013-01-19 20:59:53 +01:00
Roberto De Ioris 2bd714c610 new writer api 2013-01-19 19:06:06 +01:00
Roberto De Ioris 1b0c5bea6c another destructive commit 2013-01-19 16:53:31 +01:00
Roberto De Ioris 1f8cadb15d psgi plugin was badly broken in async mode when threads are enabled 2013-01-19 13:23:12 +01:00
unbit 83d24bee99 Merge pull request #121 from prymitive/carbon_root
[carbon] allow setting empty carbon root node
2013-01-18 14:15:00 -08:00
Roberto De Ioris 297111f2b6 non-working prototype for Coro::AnyEvent loop engine 2013-01-18 21:50:21 +01:00
Łukasz Mierzwa 0f354cbf2c allow setting empty carbon root node 2013-01-18 21:39:14 +01:00
unbit 1303efb2a4 Merge pull request #120 from prymitive/carbon_fixes
push memory metrics only if --memory-report is enabled
2013-01-18 07:45:51 -08:00
Łukasz Mierzwa 234b09b17c push memory metrics only if --memory-report is enabled & fixed total harakiri counter to include cheaper workers 2013-01-18 16:38:56 +01:00
Roberto De Ioris fe4f621d79 added --http-auto-chunked 2013-01-18 14:51:16 +01:00
Roberto De Ioris 3f83e91fb2 added uwsgi_buffer_insert() 2013-01-18 09:57:19 +01:00
Roberto De Ioris 9aebb6c564 working --http-keepalive implementation 2013-01-17 17:13:13 +01:00
Roberto De Ioris c7da6b2d45 removed a useless log 2013-01-16 19:34:14 +01:00
Roberto De Ioris bbf35be595 fixed mule management 2013-01-16 16:58:30 +01:00
Roberto De Ioris 419875e6cf fixed unix signal usage in mules and spooler 2013-01-16 16:47:46 +01:00
Roberto De Ioris aa36a2ce5f Merge branch 'master' of https://github.com/unbit/uwsgi 2013-01-16 16:25:27 +01:00
Roberto De Ioris 4c669b17ef fixed http-socket body storage leak 2013-01-16 16:25:06 +01:00
unbit abb4c9b6da Merge pull request #119 from prymitive/carbon_namespace
allow setting root node in carbon stats
2013-01-16 05:54:32 -08:00
Roberto De Ioris fe244e16d9 Merge branch 'master' of https://github.com/unbit/uwsgi 2013-01-16 14:47:32 +01:00
Roberto De Ioris 499202e84f added uwsgi::postfork and uwsgi::atexit 2013-01-16 14:47:14 +01:00
Łukasz Mierzwa e33b56890f allow setting root node in carbon stats 2013-01-16 14:37:24 +01:00
unbit 63275e9ec7 Merge pull request #118 from prymitive/carbon_busyness_fixes
carbon - detect stuck workers
2013-01-16 05:24:31 -08:00
Łukasz Mierzwa c182f30e8d carbon - detect cases were no request is completed but worker was busy and set busyness to 100% 2013-01-16 14:13:11 +01:00
unbit e365211cd0 Merge pull request #117 from prymitive/busyness_fixes
cheaper busyness -  detecting stuck workers
2013-01-16 03:28:59 -08:00
unbit 4838baf01a Merge pull request #116 from nwalker/master
another size_t fix
2013-01-16 03:26:16 -08:00
Łukasz Mierzwa 7db8636da5 cheaper busyness - detect cases were no request is completed but worker was busy 2013-01-16 12:09:40 +01:00
Alex Bubnoff 74d84be587 yet another size_t fix 2013-01-16 15:45:57 +07:00
Roberto De Ioris 8dd74ced5d Merge branch 'master' of github.com:unbit/uwsgi 2013-01-14 16:41:07 +01:00
Roberto De Ioris 9cb97dd62d php-fallback 2013-01-14 16:40:43 +01:00
Roberto De Ioris cd91830d65 fixed websockets test 2013-01-14 15:17:21 +01:00
unbit 1cefceba10 Merge pull request #113 from prymitive/core_logs
fixed init log
2013-01-13 06:32:41 -08:00
Łukasz Mierzwa afc2e7dbe2 fixed init log 2013-01-13 15:21:43 +01:00
unbit b1a9d2d497 Update tests/websockets.py 2013-01-13 13:11:37 +01:00
Roberto De Ioris ee129f02bc support for websockets over https 2013-01-13 12:46:03 +01:00
Roberto De Ioris 7ac4282047 synchrnous websockets + channels implementation 2013-01-13 10:53:11 +01:00
Roberto De Ioris 50fe00d142 gevent-friendly channel hook 2013-01-13 09:32:58 +01:00
Roberto De Ioris 6dab462296 first workign channel commit 2013-01-13 09:06:28 +01:00
Roberto De Ioris d614eabeac fixed websocket on older compilers 2013-01-13 05:24:42 +01:00
Roberto De Ioris 7da87bdf9d added --load-file-in-cache 2013-01-12 20:00:43 +01:00
Roberto De Ioris cf682773fb various int->size_t fixes 2013-01-12 19:50:49 +01:00
Roberto De Ioris 78a05ef9e8 use size_t instead of int in io functions 2013-01-12 19:22:51 +01:00
Roberto De Ioris 17d9b5f58d improved cache router added send and send-crnl route instruction 2013-01-12 19:02:40 +01:00
Roberto De Ioris 385458b291 fixed gevent leak 2013-01-12 17:17:30 +01:00
Roberta Giordano 7a80ee49be osx fixes 2013-01-11 14:44:21 +01:00
Roberto De Ioris e31d0a8693 websocket gevent hooks 2013-01-11 14:40:23 +01:00
Roberto De Ioris 9d43d6c9d4 removed some debug info 2013-01-11 11:57:42 +01:00
Roberto De Ioris b03008d1a6 spdy ping/pong 2013-01-11 11:46:32 +01:00
Roberto De Ioris 94c29a396a added new files 2013-01-11 10:22:12 +01:00
Roberto De Ioris bba8e503c1 fixed spdy/http memory cooperation 2013-01-11 08:04:46 +01:00
Roberto De Ioris 9c2e9e42f9 ported https to the new api 2013-01-11 07:40:21 +01:00
Roberto De Ioris 82d5e0ead8 Merge branch 'master' of github.com:unbit/uwsgi 2013-01-10 22:15:38 +01:00
Roberto De Ioris 3d9a20953e allows building on debian etch 4 2013-01-10 22:11:51 +01:00
Roberto De Ioris 1004ad0edc added 'signal' internal router instruction 2013-01-10 19:43:22 +01:00
Roberto De Ioris 688a227886 preliminary Websockets and SPDY support, highly optimized corerouters 2013-01-10 19:28:21 +01:00
unbit 7541195a5f Merge pull request #111 from xtfxme/defect/sec-sub
defect/sec-sub: Incorrect offset + length used for pkt encryption
2013-01-07 04:36:39 -08:00
C Anthony Risinger db24fa7bd4 defect/sec-sub: Incorrect offset + length used for pkt encryption
Off-by-four bug included the (uninitialized) uwsgi protocol header as part of
the signed packet during encryption, but *not* decryption, effectively preventing successful subscriptions; omit the header from both sides.
2013-01-07 06:24:39 -06:00
Roberto De Ioris 339c49f560 fixed remote_user in spnego plugin 2013-01-05 18:01:32 +01:00
Roberto De Ioris 8dd943542e added a route rule for remote_user 2013-01-05 17:49:27 +01:00
Roberto De Ioris 0f156fc25e fixed spnego on auth errors 2013-01-05 17:45:16 +01:00
Roberto De Ioris 8f7e65c467 added spnego/kerberos router 2013-01-05 17:21:21 +01:00
Roberto De Ioris 08b2437146 added base64 functions 2013-01-05 17:19:23 +01:00
Roberto De Ioris 912098c4c1 added --legion-skew-tolerance 2013-01-05 12:14:41 +01:00
Roberto De Ioris 3d3b21afc9 improved break routing instruction and first round of uwsgi protocol parsing optimizations 2013-01-05 11:46:11 +01:00
Roberto De Ioris 3cd7a1163d added addheader routing instruction 2013-01-05 09:35:47 +01:00
Roberto De Ioris e335c611a3 added addvar routing instruction 2013-01-05 09:06:29 +01:00
Roberto De Ioris 3409ce86e7 added --perl-version 2013-01-05 08:38:07 +01:00
Roberto De Ioris 02a9d37c32 added --python-version 2013-01-05 08:33:00 +01:00
Roberto De Ioris 121124c3cd implemented advanced login in internal routing subsystem 2013-01-04 21:15:26 +01:00
Roberto De Ioris c6440ffa2d fixed broodlord mode stats 2013-01-04 20:41:00 +01:00
Roberto De Ioris 6bab2b2318 refactored routing 2013-01-04 20:25:31 +01:00
Roberto De Ioris 7ae7b3d715 added 'static' internal router 2013-01-03 10:38:13 +01:00
Roberto De Ioris 2a2c650bec improved routing subsystem with the GOON return code 2013-01-03 10:13:38 +01:00
Roberto De Ioris ed69d78a9b export HTTP_AUTHORIZARION in mod_proxy_uwsgi 2013-01-02 17:38:03 +01:00
Roberto De Ioris 50c2fde29e fixed cheaper-initial startup message 2013-01-02 16:41:48 +01:00
unbit 96b35a3fff Merge pull request #98 from nwalker/master
Broken pyerl build
2013-01-02 00:17:47 -08:00
unbit 09a5ffeffb Merge pull request #107 from kunkku/lua-lock
Lua bindings for lock/unlock functions
2013-01-02 00:15:03 -08:00
Kaarle Ritvanen e4642e5e56 Lua bindings for lock/unlock functions 2013-01-01 15:11:46 +02:00
Roberto De Ioris 8236233489 legion subsystem does not require workers 2013-01-01 11:46:19 +01:00
Roberto De Ioris 5bfad8a1c5 added check key to the subscribe2 new generation subscriber 2013-01-01 09:56:19 +01:00
Roberto De Ioris c0dcbb7bac refactored subscriptions 2012-12-31 13:00:05 +01:00
Roberto De Ioris 808216fbd2 rewritten subscription packet generation uwsgi uwsgi_buffer struct 2012-12-31 11:40:06 +01:00
Roberto De Ioris f9a91fad63 added --static-cache-paths <seconds> 2012-12-31 11:14:53 +01:00
Roberto De Ioris 7956bebb25 added --static-safe 2012-12-31 10:51:17 +01:00
Roberto De Ioris 30633b2c9f refactored static support 2012-12-31 10:33:11 +01:00
Roberto De Ioris c713c1013c exported uwsgi_legion_i_am_the_lord() api function 2012-12-31 10:16:38 +01:00
Roberto De Ioris becdd27467 fixed locing in legion stats 2012-12-31 09:59:59 +01:00
Roberto De Ioris 2216aafcf1 take checksum in account to recognize quorum changes 2012-12-31 09:23:04 +01:00
unbit 7b3859b484 Update core/master_utils.c 2012-12-30 19:08:05 +01:00
unbit b1ab162bd2 Merge pull request #104 from prymitive/legion_stats
basic legion stats
2012-12-30 10:05:19 -08:00
unbit a0dbcee7d5 Merge pull request #103 from prymitive/legion_quorum_warning
[legion] periodic warnings when no quorum is reached
2012-12-30 10:01:59 -08:00
unbit 5312a8a0f6 Merge pull request #102 from prymitive/travis_update
fixed travis tests after latests cleanups
2012-12-30 10:00:55 -08:00
Łukasz Mierzwa 9e9b28a9cd fixed travis tests after latests cleanups 2012-12-30 15:51:39 +01:00
Łukasz Mierzwa 572298e63d periodic warnings when no quorum is reached 2012-12-30 15:48:47 +01:00
Łukasz Mierzwa 32a47c91b7 basic legion stats 2012-12-30 15:47:43 +01:00
Roberto De Ioris 556905048e legions now supports nodes with the same valor, uuid will be the diff 2012-12-30 12:46:09 +01:00
Roberto De Ioris 219d77fc17 fixed uuid compare 2012-12-30 12:41:21 +01:00
Roberto De Ioris e34371a974 debug quorum 2012-12-30 12:29:17 +01:00
Roberto De Ioris c5099b6d38 faster uwsgi_uuid_cmp() 2012-12-30 12:17:22 +01:00
Roberto De Ioris d535c22723 do not rely on uuid_compare() [2] 2012-12-30 12:14:50 +01:00
Roberto De Ioris fa68d2cae3 do not rely on uuid_compare() 2012-12-30 12:13:11 +01:00
Roberto De Ioris 5a754e66fe implemented uuid compare for legion and added a warning for system not using libuuid 2012-12-30 11:55:50 +01:00
Roberto De Ioris 83f9920705 improved mod_proxy_uwsgi 2012-12-30 11:04:43 +01:00
Roberto De Ioris f3dd60d683 fixed socket naming 2012-12-30 08:52:43 +01:00
Roberto De Ioris e25e671104 removed excessive debugging info in legion 2012-12-30 08:34:21 +01:00
Roberto De Ioris c3b101baf4 improve legion reliability 2012-12-29 20:26:59 +01:00
Roberto De Ioris b60c9b24b3 added 'signal' and 'log' Lord action 2012-12-29 20:21:03 +01:00
Roberto De Ioris 8aba421a87 fixed iv usage 2012-12-29 20:08:58 +01:00
Roberto De Ioris 15c0b5f5e9 implemented iv for legion 2012-12-29 20:03:00 +01:00
Roberto De Ioris f6271b1893 fixed quorum math 2012-12-29 19:39:10 +01:00
Roberto De Ioris 374317cffd completed voting subsystem for legions 2012-12-29 19:13:43 +01:00
Roberto De Ioris 6f7b158942 report checksum in quorum 2012-12-29 18:45:51 +01:00
Roberto De Ioris 310eb53a37 added checksum and unix time check in legion packets 2012-12-29 18:44:58 +01:00
Roberto De Ioris badeafef59 reports quorum status at every legion changes 2012-12-29 18:18:39 +01:00
Roberto De Ioris 35557de982 improvements in the legion subsystem 2012-12-29 17:52:38 +01:00
Roberto De Ioris b0a7501212 first attempt of legion quorum implementation [step 2] 2012-12-29 17:36:36 +01:00
Roberto De Ioris f45db5456e first attempt of legion quorum implementation 2012-12-29 17:29:25 +01:00
Roberto De Ioris 2b58c79611 add uuid to legion packets 2012-12-29 16:11:19 +01:00
Roberto De Ioris b7499f22f5 do not report error if /proc file system is not mounted 2012-12-29 15:37:53 +01:00
Roberto De Ioris d55a5e1b8c added --cache-sync for initial synchronization with remote caches 2012-12-28 21:24:28 +01:00
Roberto De Ioris e4ec5b000e refactored utils.c and created io.c 2012-12-28 21:10:06 +01:00
Roberto De Ioris dd983135c6 another cleanup [2] 2012-12-28 14:33:12 +01:00
Roberto De Ioris 09fe2960b5 another cleanup 2012-12-28 14:32:27 +01:00
Roberto De Ioris cf5794e22c moved uwsgirouter*.py to examples 2012-12-28 14:31:29 +01:00
Alex Bubnoff 2f2876fe6b fixed build error of pyerl plugin 2012-12-24 17:36:04 +07:00
unbit 1f1008c415 Update CONTRIBUTORS 2012-12-24 10:46:26 +01:00
unbit c02a936b61 Merge pull request #97 from guokr/master
Fix the memory leak of jvm and jwsgi plugins
2012-12-24 00:04:20 -08:00
Mingli d28cdaabb3 release chars 2012-12-24 11:33:21 +08:00
Mingli ec78213819 fix compiler error 2012-12-24 11:06:27 +08:00
Mingli 2a2303e37f remove local ref in jvm and fix indent 2012-12-24 10:19:37 +08:00
Mingli 90bc859222 Merge remote-tracking branch 'upstream/master' 2012-12-24 10:00:52 +08:00
Mingli a3be8d36fe frame scoping in jwsgi 2012-12-24 09:57:35 +08:00
Roberto De Ioris de3e70c61f skel for storage subsystem 2012-12-22 10:12:59 +01:00
Roberto De Ioris c3bba30af5 improved listen_queue management in freebsd 2012-12-21 12:07:30 +01:00
Roberto De Ioris 35566a8533 start refactoring tcp_info usage 2012-12-21 11:50:05 +01:00
Roberto De Ioris dda86dbc9c fixed a https/corerouter corner-case bug 2012-12-21 11:30:46 +01:00
Roberto De Ioris 5f971812d1 set HTTPS to on when behind stud 2012-12-21 08:59:25 +01:00
Giovanni Scala 17c8fff794 fixed --php-app-bypass 2012-12-20 20:44:25 +01:00
Giovanni Scala e4d5ca9209 added --php-app-bypass 2012-12-20 20:42:27 +01:00
Roberto De Ioris 8536bc349a added --http-stud-prefix 2012-12-19 18:37:13 +01:00
Roberto De Ioris e4b34921e1 report pos in failed uploads 2012-12-16 12:56:55 +01:00
Roberto De Ioris f966ef8e69 fixed computation of post data 2012-12-16 12:17:06 +01:00
Roberto De Ioris df8efa31dd more debug for https 2012-12-16 10:57:56 +01:00
Roberto De Ioris ee6aff6665 added additional uwgsi-gevent error report 2012-12-15 20:34:25 +01:00
Roberto De Ioris 5f2abf9949 fixed uwsgi_str_num for 32bit 2012-12-15 14:30:22 +01:00
unbit ee9b4a70d4 Merge pull request #86 from scottkmaxwell/master
1.4.3 wouldn't build on my Mac due to a too-strict cast in the Yaml plug-in.
2012-12-13 22:48:40 -08:00
Roberto De Ioris d5632f7715 fixed net offloading and http internal router 2012-12-13 15:25:45 +01:00
Roberto De Ioris efd10599a6 oops alarm_xmpp should not be build by default 2012-12-13 11:06:23 +01:00
Roberto De Ioris f0a846927e allows embedding .cc and .m files 2012-12-13 11:03:17 +01:00
Scott Maxwell 5e876e4adc Loosen up cast so we can build on Mac
Cast to (const unsigned char*) caused error building on OS X Mountain Lion
2012-12-12 09:51:30 -08:00
Roberto De Ioris d968e9f39e dup2() returns < 0 on error 2012-12-12 15:02:37 +01:00
unbit 54fa0ab19f Merge pull request #84 from prymitive/travis_buildconf
travis buildconf
2012-12-11 21:52:05 -08:00
Łukasz Mierzwa d63a570230 travis buildconf 2012-12-11 22:32:23 +01:00
Roberto De Ioris 98e9822150 removed garbage from old versions 2012-12-10 17:37:13 +01:00
unbit 6a9809b301 Merge pull request #82 from prymitive/cheaper_initial
check if --cheaper-initial is valid
2012-12-10 08:07:54 -08:00
Łukasz Mierzwa 47590a2b0d check if --cheaper-initial is valid 2012-12-10 17:01:15 +01:00
Roberto De Ioris 1447ae01bd improved uwsgi_run_command 2012-12-10 15:10:52 +01:00
Roberto De Ioris d24ad0e61c close fds for external processes 2012-12-10 14:45:01 +01:00
Roberto De Ioris 0a0b27ad4c added offload-thread alias 2012-12-07 13:39:39 +01:00
Roberto De Ioris 504151b695 improved stdin management in cron 2012-12-07 12:40:29 +01:00
Roberto De Ioris 813074b010 fixed emperor 2012-12-07 12:06:49 +01:00
Roberto De Ioris 01cbcbad47 django dir will be in a dedicated repository 2012-12-07 11:39:15 +01:00
Roberto De Ioris 20b0dc0d1e removed uwsgicc, it should be on a separate repository 2012-12-07 11:33:50 +01:00
root 6e6dd65cef updated Changelog for 1.5 2012-12-07 11:30:17 +01:00
root e77f1d5069 %z is not portable 2012-12-07 11:25:14 +01:00
root 41af8e54bb fixed FIXME for #79 2012-12-07 11:18:33 +01:00
unbit d598a10013 Merge pull request #79 from prymitive/log_format_fixes
few log format fixes
2012-12-07 02:16:18 -08:00
root 9af9cd09f9 --not-alarm-log is the only condition that need to break 2012-12-07 11:13:44 +01:00
root b358c46413 added support for negative regexp in alarm-log 2012-12-07 10:58:58 +01:00
root 45ffa98b5e added preliminary support for TCP_FASTOPEN 2012-12-07 10:33:39 +01:00
root f458877e53 improved emperor reloading 2012-12-07 09:04:32 +01:00
root 544e598dcb improved emperor custom config management 2012-12-07 07:58:48 +01:00
root 360a94691d added --get for shell scripting 2012-12-06 14:51:34 +01:00
unbit a297b9b981 Merge pull request #78 from prymitive/cheaper_busyness_logging
fixed log format in cheaper_busyness
2012-12-06 05:28:05 -08:00
Łukasz Mierzwa 7bb424622c few log format fixes 2012-12-06 13:55:43 +01:00
Łukasz Mierzwa 0d382a846a fixed log format in cheaper_busyness 2012-12-06 12:44:37 +01:00
root e82430369e added --legion-death 2012-12-06 11:23:45 +01:00
unbit 647e1e0826 Merge pull request #77 from prymitive/x_forwarded_for
use client address if X-Forwarded-For is missing
2012-12-06 02:00:53 -08:00
Łukasz Mierzwa b5802b4793 fallback to REMOTE_ADDR if HTTP_X_FORWARDED_FOR is missing but --log-x-forwarded-for was used 2012-12-06 10:51:59 +01:00
root af5dbda00d fixed unlord 2012-12-06 10:35:11 +01:00
root 4b889c90bf completed legion subsystem, added cmd legion_action 2012-12-06 10:24:32 +01:00
unbit 1313841dd3 Merge pull request #76 from prymitive/carbon_newline
missing new line in carbon plugin logs
2012-12-05 23:56:34 -08:00
Łukasz Mierzwa b09c343627 missing new line in carbon plugin logs 2012-12-05 22:33:08 +01:00
root ca97c0653f added newline to legion log 2012-12-05 21:03:47 +01:00
Roberto De Ioris 76edb7374e support for zeromq3 in emperor_zeromq 2012-12-04 12:55:55 +01:00
Roberto De Ioris c8f53b9296 report name and pid for upcoming Lord 2012-12-04 12:44:02 +01:00
Roberto De Ioris 55a190312a a note about iv for encryption 2012-12-04 12:37:32 +01:00
Roberto De Ioris 7ebbac0dd8 completed legion management and logic 2012-12-04 12:35:17 +01:00
Roberto De Ioris 1662f58a09 added first lord check 2012-12-03 19:44:39 +01:00
Roberto De Ioris ac5ca4a002 added legion decrypter 2012-12-03 19:42:13 +01:00
Roberto De Ioris ebadaa73a8 bind to legion address 2012-12-03 18:09:28 +01:00
Roberto De Ioris 55fdc9d847 initialize encrypt/decrypt contexts for legions 2012-12-03 17:39:03 +01:00
Roberto De Ioris a409a82736 Merge branch 'master' of github.com:unbit/uwsgi 2012-12-03 15:58:18 +01:00
Roberto De Ioris 58e3b7166c added core/ssl.c for ssl utilities (moved from core/utils.c) and prepare for legion support 2012-12-03 15:57:54 +01:00
unbit cac413f725 Update core/legion.c 2012-12-03 09:43:45 +01:00
Roberto De Ioris 73e3938d9a added legions subsystem introduction 2012-12-03 09:41:54 +01:00
Roberto De Ioris 985114b7bd fixed #66 2012-12-01 15:44:52 +01:00
Roberto De Ioris fb4a594add SNI support 2012-12-01 15:34:28 +01:00
Roberto De Ioris 5d8f91c1ed added zeromq imperial monitor 2012-11-30 18:33:46 +01:00
Roberto De Ioris 759a9d4439 added emperor:// to the supported schemes, improved vassals config handling 2012-11-30 18:23:27 +01:00
unbit 25b29df65e core: make smart-attach-daemon smart enough
Avoid call storming of pidfile check that leads to multiple daemons
running instead of one. Fix #65.
2012-11-28 20:57:06 +01:00
unbit 9f396466bd Merge pull request #64 from prymitive/touch_logrotate
fixed --touch-logrotate after my patch
2012-11-27 12:07:24 -08:00
Łukasz Mierzwa c79b36a59d fixed --touch-logrotate after my patch 2012-11-27 20:47:55 +01:00
unbit de33a4a5a3 Merge pull request #61 from prymitive/touch_reload
enhanced file touch checker
2012-11-27 04:04:19 -08:00
Roberto De Ioris 88e108cacc fixed #20 2012-11-27 13:02:59 +01:00
unbit 163d71c5b8 Merge pull request #62 from xrmx/cpucount
uwsgiconfig: permit to override CPUCOUNT with environment variable
2012-11-27 03:37:59 -08:00
Riccardo Magliocchetti 936d4b19a5 uwsgiconfig: permit to override CPUCOUNT with environment variable
CPUCOUNT=X make

will force X cores instead of the autodetected ones
2012-11-27 12:23:06 +01:00
Łukasz Mierzwa 93cbd60f11 enhanced file touch checker 2012-11-27 11:54:13 +01:00
Roberto De Ioris 850cbea236 added --http-session-context 2012-11-25 21:21:08 +01:00
Roberto De Ioris 3ceda8993a removed some debug 2012-11-25 19:04:37 +01:00
Roberto De Ioris ccad290b78 added cache full counter 2012-11-25 18:51:01 +01:00
Roberto De Ioris 66d28aa958 added cache stats 2012-11-25 18:43:37 +01:00
Roberto De Ioris 3717b8cd13 implemented udp cache del 2012-11-25 17:48:18 +01:00
Roberto De Ioris 6e5fc85e54 uwsgi_cache_del now takes flags 2012-11-25 17:29:41 +01:00
Roberto De Ioris a3bbfde884 refactored cache threads 2012-11-25 17:22:44 +01:00
Roberto De Ioris fd86c6cafa implemented expires in cache udp server 2012-11-25 16:42:40 +01:00
Roberto De Ioris cb87f8f6d6 implemented udp cache update 2012-11-25 16:02:05 +01:00
Roberto De Ioris 4ccd20eb23 pre-build cache udp nodes addresses 2012-11-25 14:09:25 +01:00
Roberto De Ioris 9ced8f9bdd skeleton for --cache-udp-server and --cache-udp-node 2012-11-25 13:07:34 +01:00
Roberto De Ioris 4eb174e9cb first implementation of ssl sessions store in the shared cache 2012-11-25 10:46:58 +01:00
Roberto De Ioris 598250d469 added --php-var 2012-11-24 11:22:01 +01:00
Roberto De Ioris 6cc3faf14d improved QUERY_STRING management in router_rewrite 2012-11-24 11:14:44 +01:00
Roberto De Ioris 8864f3c53c fixed corner-case ssl body reading 2012-11-24 09:52:24 +01:00
unbit 49dd3366fc Merge pull request #60 from prymitive/travisci
removed python2.5 from build
2012-11-23 05:26:04 -08:00
Łukasz Mierzwa 5d253ab00f removed python2.5 2012-11-23 14:20:03 +01:00
Roberto De Ioris 25db778f32 Revert "uClibc compatibility for core"
This reverts commit c2d2f13bfb.
2012-11-23 10:10:26 +01:00
unbit 35fbd85fad Merge pull request #59 from kunkku/uclibc
uClibc compatibility for core
2012-11-23 00:26:00 -08:00
Kaarle Ritvanen c2d2f13bfb uClibc compatibility for core 2012-11-23 08:45:24 +02:00
Roberto De Ioris 7add254781 fixed typo in the php plugin 2012-11-22 16:38:22 +01:00
Giovanni Scala 970d899986 honour QSA style in php-app-qs 2012-11-22 07:39:01 +01:00
Giovanni Scala d719ed6a3b added php-app-qs 2012-11-22 06:26:36 +01:00
Giovanni Scala 7fcc8ba6ac fixed sendfile offload with bigger files 2012-11-22 05:28:56 +01:00
Roberto De Ioris 70e1bda986 refactored rewrite plugin 2012-11-21 18:01:39 +01:00
Roberto De Ioris 32789e62a5 fixed PATH_TRANSLATED in cgi and improved var appending 2012-11-21 17:54:47 +01:00
Roberto De Ioris 6297ed0455 do not crash on non-existent config files 2012-11-21 07:48:06 +01:00
unbit 1cbabf6296 Merge pull request #56 from xtfxme/feature/extract
feature/extract: dump the specified address to stdout and exit
2012-11-20 07:56:33 -08:00
C Anthony Risinger e7f694cdc5 feature/extract: dump the specified address to stdout and exit
similar to `--connect-and-read` except for file-like addresses; allows such
things as:

```
$ uwsgi --extract data://0
$ uwsgi --extract sym://embedded_json
$ uwsgi --extract http://me.local/config.xml
$ uwsgi --extract section://rootfs.tar.gz
$ uwsgi --ini exec://"uwsgi --extract section://rootfs.tar.gz | \
        tar xz && cat rootfs/config.ini"
```

...the latter of which embeds/extracts a complete rootfs for immediate use!
combined with embedded configs + declare-options, one can construct a self-
extracting -- single-file -- app that managed it's own plugins, configs,
databases, shared libs, [...]
2012-11-20 09:48:29 -06:00
Unbit 5f93d93cc1 added x magic var 2012-11-19 09:35:22 +01:00
Unbit 15fa7a9c09 improved section detection 2012-11-19 09:16:29 +01:00
Roberto De Ioris 2e9e5af686 added perl signal_wait and mule handler 2012-11-17 12:12:43 +00:00
Roberto De Ioris 54c1055f15 Merge branch 'master' of github.com:unbit/uwsgi 2012-11-16 19:58:05 +00:00
Roberto De Ioris 114d71af8d implemented register_signal in the psgi plugin 2012-11-16 19:57:54 +00:00
unbit 757c3e7d95 Merge pull request #52 from prymitive/travisci
More advanced travis config
2012-11-15 05:19:04 -08:00
unbit 0233f3e712 Merge pull request #54 from kunkku/lua-async
Support asynchronous requests in Lua plugin
2012-11-15 05:18:05 -08:00
Kaarle Ritvanen e23a7bfd80 support asynchronous requests in Lua plugin 2012-11-15 14:18:45 +02:00
Roberto De Ioris 6c67d205b8 fixed magic_table management 2012-11-15 10:01:24 +01:00
Łukasz Mierzwa aaaae5a602 * travis config with plugins for multiple python and ruby versions
* basic script with tests for each python and rack plugin
2012-11-13 21:27:15 +01:00
Roberto De Ioris 5ddd773680 fixed #51 2012-11-13 04:36:45 +01:00
Roberto De Ioris 34bb5de3aa fixed static_maps 2012-11-12 14:42:44 +01:00
Roberto De Ioris e23094e820 clear uwsgi_thread structure on setup 2012-11-12 14:11:15 +01:00
Roberto De Ioris 8d53e4aa54 fixed offload threading when the numbr of ocres is higher than 1 2012-11-12 13:49:10 +01:00
Roberto De Ioris ca1666789d Merge branch 'master' of github.com:unbit/uwsgi 2012-11-12 13:13:26 +01:00
Roberto De Ioris 211ed5c71c corerouter NOT courerouter 2012-11-12 13:09:06 +01:00
unbit 9f6a88d9d7 Merge pull request #48 from prymitive/travis
minimal travis.yml file
2012-11-12 03:35:38 -08:00
Roberto De Ioris 3d483f22ca 'wsgi' option is an alias for 'module' not 'wsgi-file' 2012-11-12 11:57:02 +01:00
Roberto De Ioris a6bbb0cfa4 starting 1.5 development cycle 2012-11-12 11:37:51 +01:00
Łukasz Mierzwa e6c9e53f14 minimal travis.yml file 2012-11-12 10:52:42 +01:00
Roberto De Ioris e13734ae6c uWSGI 1.4 2012-11-12 10:45:05 +01:00
Roberto De Ioris cf62b03e33 endiness fixes and added support for not waiting for thread cancellation 2012-11-12 10:36:18 +01:00
Roberto De Ioris b2f292c2da some Changelong improvement 2012-11-12 09:46:47 +01:00
Roberto De Ioris b96b6a24a6 support for rack official commit afc9b0313c 2012-11-12 09:40:38 +01:00
Roberto De Ioris b2a1237781 added --undeferred-shared-socket 2012-11-11 19:41:00 +01:00
Roberto De Ioris a48af2e226 workaround missing IP_FREEBIND 2012-11-11 19:07:28 +01:00
Roberto De Ioris 33446c3179 better cap management 2012-11-11 18:59:05 +01:00
Roberto De Ioris 242e01e37a added 'wsgi' alias option 2012-11-11 17:32:18 +01:00
Roberto De Ioris 41eba2b486 report static nodes in corerouters stats 2012-11-10 11:51:19 +01:00
Roberto De Ioris 24763fdbd2 fixed xclient 2012-11-10 11:23:39 +01:00
Roberto De Ioris 951cbf3eba implemented retries and fallback on the rawrouter 2012-11-10 10:25:40 +01:00
Roberto De Ioris 8759b66206 ported rawrouter to the new api with xclient support 2012-11-10 09:33:33 +01:00
Roberto De Ioris 93aacace5f ready for 1.4-rc2 2012-11-09 22:37:54 +01:00
Roberta Giordano 8406fb12be fixed OSX sendfile 2012-11-09 21:55:26 +01:00
Roberto De Ioris 6af3ea267e added offload sendfile to OSX 2012-11-09 21:54:05 +01:00
Roberto De Ioris 9ff37ce019 be more verbose about offload threads 2012-11-09 21:46:28 +01:00
Roberto De Ioris f4187680bd offload sendfile supported on FreeBSD and DragonFly 2012-11-09 21:36:39 +01:00
Roberto De Ioris 57b72ac17d allows multiple offload threads 2012-11-09 21:24:30 +01:00
Roberto De Ioris 5c64839734 even the router_uwsgi plugin can offload 2012-11-09 20:18:43 +01:00
Roberto De Ioris e4de9a8bc7 improved offload threads subsystem 2012-11-09 20:04:27 +01:00
Roberto De Ioris 689b4afb44 moved offload functions to a dedicated file 2012-11-09 16:48:30 +01:00
Roberto De Ioris ceebaa7d9d fixed indentation 2012-11-09 12:16:39 +01:00
Roberto De Ioris 0fa2c543ec added pcre jit support 2012-11-09 12:04:13 +01:00
Roberto De Ioris 519df88126 allows cross-domain JSON requests to stats subsystem 2012-11-08 17:38:57 +01:00
Roberto De Ioris 75b275591d count per-core static requests 2012-11-08 09:05:46 +01:00
Roberto De Ioris 2f901f08cb fixed magic vars for symlinks 2012-11-08 07:33:43 +01:00
Roberto De Ioris b041fe4473 fixed wrong error message 2012-11-08 06:50:31 +01:00
Roberto De Ioris f5d6cb65f9 added uwsgi.Handler(http.Handler) go func 2012-11-07 15:52:37 +01:00
Roberto De Ioris 9c94aedb29 added Changelog for 1.4 2012-11-07 14:20:08 +01:00
Roberto De Ioris d248b290f2 added --php--allowed-script 2012-11-07 12:24:12 +01:00
Roberto De Ioris cb48070db1 fixed systemd support 2012-11-07 11:40:56 +01:00
unbit cd34bac104 Merge pull request #45 from prymitive/static_methods
disable static files offloading for methods other than GET and HEAD
2012-11-06 11:23:01 -08:00
Łukasz Mierzwa c966fbb163 disable static files offloading for methods other than GET and HEAD 2012-11-06 14:00:04 +01:00
Roberto De Ioris feac596efc fixed SSL buffer usage 2012-11-06 06:26:41 +01:00
Roberto De Ioris 981ddfcefe do not segfault on go if master-requiring api is called 2012-11-05 19:42:39 +01:00
Roberto De Ioris 5e561b6578 simplified go interface 2012-11-05 18:18:48 +01:00
unbit fab495fadc added Stephen Pierce to CONTRIBUTORS 2012-11-05 17:24:59 +01:00
Unbit ecbda6dc26 refactored go symbol loaders 2012-11-05 11:16:42 +01:00
Roberto De Ioris e23766e4d0 added go complextest 2012-11-05 10:37:07 +01:00
Roberto De Ioris 6d9de4c618 completed caching support for go 2012-11-05 10:32:37 +01:00
Roberto De Ioris 4ca14f6046 added two tests for go web apps, and completed request body advanced management 2012-11-05 09:09:38 +01:00
Roberto De Ioris d856c9920d added comments in uwsgi.go package 2012-11-05 07:51:00 +01:00
Roberto De Ioris fd62440265 Merge branch 'master' of github.com:unbit/uwsgi 2012-11-04 19:52:59 +01:00
Roberto De Ioris d4041c9e1d fixed goroutines support 2012-11-04 19:52:46 +01:00
unbit dc9e1bd324 Merge pull request #44 from StephenPierce/new-snmp-functions
New snmp functions
2012-11-04 10:44:39 -08:00
Roberto De Ioris 89bbd967ed added --goroutines shortcut 2012-11-04 11:00:06 +01:00
Roberto De Ioris 276ada315d fallback to DefaultServeMux if no RequestHandler has been defined 2012-11-04 10:54:06 +01:00
Roberto De Ioris bdd0d408a0 go modifier1 is officially assigned as 11 2012-11-04 10:41:51 +01:00
Roberta Giordano 5ddaa2e436 fixed go build in OSX 2012-11-04 10:31:12 +01:00
Roberto De Ioris f9d0e75056 automatically build uwsgi.go 2012-11-04 10:17:23 +01:00
Roberto De Ioris 7776a1f0be added preliminary go support 2012-11-04 09:24:06 +01:00
Stephen Pierce a33a57d8af Removed unneeded import 2012-11-02 16:02:46 -07:00
Stephen Pierce 9371e2b8de Added SNMP incr/decr functions for counter32/counter64/gauge types. Wrapped all operations (set/get/incr/decr) with lock to prevent contention. 2012-11-02 16:00:31 -07:00
Roberto De Ioris 6c1a842f7d improved reloading robustness 2012-11-02 14:30:14 +01:00
Roberto De Ioris d746deaf02 Merge branch 'master' of github.com:unbit/uwsgi 2012-11-02 12:38:09 +01:00
Roberto De Ioris 09fca72b4c fixed spooler max tasks handling 2012-11-02 12:37:41 +01:00
unbit 2ffc31e578 Merge pull request #41 from prymitive/valgrind
valgrind suppression file generator
2012-11-02 04:14:56 -07:00
unbit 2a254d195a Merge pull request #42 from prymitive/head
set http status on head static request
2012-11-02 04:14:33 -07:00
Roberto De Ioris 95d3ee4e61 added mongodb stats pusher 2012-11-02 12:06:08 +01:00
Roberto De Ioris 4d56474511 implemented stats pushers 2012-11-02 11:23:12 +01:00
Łukasz Mierzwa 46a33b268a set http status on head static request 2012-11-02 11:21:52 +01:00
Łukasz Mierzwa b0829cc2e3 more suppressions 2012-11-02 10:56:56 +01:00
Łukasz Mierzwa 93a0913182 valgrind suppression file generator 2012-11-02 10:38:00 +01:00
Roberto De Ioris 0605148e21 report signal_queue size in stats, fixed linux timerfd and inotify 2012-11-02 09:44:49 +01:00
Roberto De Ioris e7b5c7c8e4 allows generating minified json 2012-11-02 08:43:55 +01:00
Roberto De Ioris b2a0fd1914 truncate malformed/huge log lines 2012-10-31 19:55:21 +01:00
Roberto De Ioris 9cc89a6052 emperor is now tolerant to extreme Linux-OOM situations 2012-10-31 11:11:39 +01:00
Roberto De Ioris 1606b8b775 remove obsolete ruby threading definitions 2012-10-31 10:54:57 +01:00
unbit cfac385f8e Merge pull request #39 from prymitive/cppcheck
missing close() call in utils/uwsgi_num_from_file()
2012-10-31 02:29:54 -07:00
Łukasz Mierzwa 99fd4572cb missing close() call in utils/uwsgi_num_from_file() 2012-10-30 23:57:48 +01:00
Roberto De Ioris d3194ca011 remove monitored fd from async queue when in async mode 2012-10-30 18:31:04 +01:00
Roberto De Ioris af61a9e33f re-indented core/async.c 2012-10-30 18:01:35 +01:00
Roberto De Ioris 4896e22a62 preventively read a page of data in stats http mode 2012-10-30 09:42:17 +01:00
Roberto De Ioris 7882d12a80 better sockets management in stats servers 2012-10-30 09:31:15 +01:00
Roberto De Ioris 9342acc500 allows exported json stats in http format 2012-10-30 08:45:32 +01:00
Roberto De Ioris 929a919c9d exports spoolers data in stats server 2012-10-30 08:19:42 +01:00
Roberto De Ioris d1f6e97dd7 do not transfer static files if method is HEAD 2012-10-30 07:22:25 +01:00
Roberto De Ioris f9d76f90eb better configfile path management 2012-10-29 19:48:43 +01:00
Unbit 2de5e8994f allows building without routing 2012-10-29 16:51:21 +01:00
unbit 7e935253a2 Merge pull request #36 from prymitive/fr
count requests in (fast|http)router
2012-10-29 04:07:50 -07:00
Łukasz Mierzwa 4c20d83573 count requests in (fast|http)router / with cs->un checks 2012-10-29 11:44:56 +01:00
Łukasz Mierzwa 7035a676a2 count requests in (fast|http)router 2012-10-29 10:58:03 +01:00
Roberto De Ioris 736f99d10b added router_cache plugin 2012-10-29 10:11:42 +01:00
Roberto De Ioris ea422a4576 fixed cache size reporting in 32bit 2012-10-29 09:29:43 +01:00
Roberto De Ioris e274f53286 a couple of fedora17-specific fixes 2012-10-28 19:58:25 +01:00
Roberto De Ioris c03dcf4617 added logfile commodity plugin 2012-10-28 19:27:42 +01:00
Roberto De Ioris d70c7ceb89 added --log-route 2012-10-28 18:15:09 +01:00
Roberto De Ioris 9ae1354d1a added the systemd journal logger 2012-10-28 08:02:18 +01:00
Roberto De Ioris b29f0b9436 reimplemented --http-to-https 2012-10-27 20:12:19 +02:00
Roberto De Ioris e01cd802d8 re-implemented http expect/continue 2012-10-27 19:39:01 +02:00
Roberto De Ioris c7b57c9776 added --log-filter 2012-10-27 15:59:48 +02:00
Roberto De Ioris 3a48b898ad refactored router_access plugin 2012-10-27 15:37:14 +02:00
unbit 4f4771b527 Merge pull request #31 from brainbitsca/master
router_access - plugin to implement hosts_access
2012-10-27 06:03:58 -07:00
Roberto De Ioris b43df60d7f added uwsgi_kvlist_parse api function 2012-10-27 14:58:19 +02:00
Roberto De Ioris 10a5661218 added C Anthony Risinger as contributor 2012-10-27 12:15:53 +02:00
Roberto De Ioris a99670cfb5 fixed an incredibly stupid bug in http/https router 2012-10-27 11:58:10 +02:00
unbit 7967e8ac3c Merge pull request #33 from prymitive/harakiri
More accurate harakiri counting
2012-10-26 01:31:12 -07:00
colinlbc e105ebe273 remove stray uwsgi_log() 2012-10-25 14:47:50 -07:00
colinlbc 11d2c004c2 moved critical scrncpy out of #ifdef UWSGI_DEBUG 2012-10-25 14:30:47 -07:00
colinlbc e8bfa12372 Reworked things to get rid of several pointer errors.
Implemented svcname paramater for hosts access mode to set daemon name in hosts.allow,hosts.deny.
New router config syntax:

svcname defaults to uwsgi

uwsgi.ini:
router access:hosts
router access:hosts=svcname
router access:allow=addr
router access:deny=addr

hosts.deny:
svcname:ALL
2012-10-25 14:10:37 -07:00
Łukasz Mierzwa 317e9efa2d harakiri count is now accurate so we don't need to divide here 2012-10-25 15:23:35 +02:00
Łukasz Mierzwa 4b99bff520 don't increment harakiri counter on multiple SIGKILLs sent to the same process 2012-10-25 15:18:00 +02:00
colinlbc 99f584cff0 use char *remote_addr instead of wsgi_req->remote_addr 2012-10-24 03:03:13 -07:00
colinlbc fc6a79dcc9 corrected hosts_ctl to use STRING_UNKNOWN instead of wsgi_req->host. This
wants the remote_hostname, not the request host header.
2012-10-24 02:54:30 -07:00
colinlbc 75af812b83 Fixed a couple of silly mistakes in the access:action,host syntax parsing
Made changes based on unbit feedback:
- separated header, body output in 403 error
- used uwsgi_concat2n to copy strings out of wsgi_req->remote_addr and wsgi_req->host
2012-10-24 02:15:41 -07:00
Colin Ligertwood 0f4e1eb7e2 A simple access control router using libwrap. Currently only tested on OpenBSD 5.1.
I've used router_authbasic as a guide to write this. Placeholders exist for an
internal ACL scheme. Syntax follows:

router = ^/path acces:hosts         -- hosts access router using libwrap, works!
router = ^/path access:allow,ipaddr -- internal allow, unimplemented
router = ^/path access:deny,ipaddr  -- internal deny, unimplemented

It's just a few hours hacking and I'm not entirely sure how the internal access
control will work, but the hosts access stuff works in openbsd. It returns a 403
on denial.
2012-10-24 01:09:44 -07:00
Roberto De Ioris a3e0c2260f fixed a leak and a refcount bug in the tracebacker 2012-10-24 08:05:35 +02:00
Roberto De Ioris 3f63caa5eb fixed a typo 2012-10-24 07:13:33 +02:00
info@unbit.it 61bd3fb0e6 fixed kqueue support 2012-10-23 23:46:54 +02:00
Roberto De Ioris d6b4b8ea6e improved wsgi.input reports 2012-10-23 20:44:01 +02:00
Roberto De Ioris 3a451fb42f updates request switches at every gevent sleep/switch 2012-10-22 17:16:21 +02:00
Roberto De Ioris 7017712c6d non blocking wsgi.input in gevent 2012-10-22 15:58:36 +02:00
Roberto De Ioris 49140c3387 removed sendfile buildconf option 2012-10-22 14:07:33 +02:00
Roberto De Ioris 1d9edc3e34 ops, missing some ugly global vars 2012-10-22 10:03:56 +02:00
Roberto De Ioris fffe070e30 use threaded build only on build_uwsgi() 2012-10-22 09:41:24 +02:00
Roberto De Ioris 29ce04adce implemented reliable gevent non-blocking writes 2012-10-22 08:34:37 +02:00
unbit c487fb0cf0 Merge pull request #27 from xtfxme/improvement/gitignore-build-products
.gitignore build products and cache files
2012-10-21 21:29:47 -07:00
C Anthony Risinger 503fcd5ed5 .gitignore build products and cache files 2012-10-21 21:33:15 -05:00
Roberto De Ioris 7136beeff7 added uwsgi.offload_transfer() 2012-10-21 18:19:14 +02:00
Roberto De Ioris 64c7d71c35 completed https request body management 2012-10-21 14:04:10 +02:00
Roberto De Ioris d2d714e933 another series of https porting to the new api and ported multithread build system to python3 2012-10-21 12:36:15 +02:00
Roberto De Ioris f7399ef2ec use linux SOCK_NONBLOCK on uwsgi_connect() 2012-10-21 11:56:04 +02:00
Roberto De Ioris 4014bc53bd fixed handling of 'remaining' post data in http router 2012-10-21 11:31:47 +02:00
Roberto De Ioris b8f42a8d0b put a lock for print in multithreaded compilation 2012-10-21 10:31:24 +02:00
Roberto De Ioris b40442a0f8 fixed race condition on fork()/early-fail during worker respawn 2012-10-21 10:21:42 +02:00
Roberto De Ioris bee3bf5d43 added --so-send-timeout 2012-10-20 21:08:48 +02:00
Roberto De Ioris 59cc3d7c04 fixed PATH_INFO usage in embedded http mode 2012-10-20 20:58:19 +02:00
Roberto De Ioris 8dc072732b fixed building on ubuntu quantal 2012-10-20 19:45:09 +02:00
Roberto De Ioris 37b7c31849 fixed fastrouter leak with the new api 2012-10-20 19:39:08 +02:00
Roberto De Ioris 738b886267 get rid of ugly oracle/sun ifdef, will find a better solution later 2012-10-20 19:35:53 +02:00
Roberto De Ioris 8679f8b845 use accept4() if available 2012-10-20 19:20:52 +02:00
Roberta Giordano ecfae75886 fixed static-offload-to-thread on no-linux platforms 2012-10-20 18:52:07 +02:00
Roberto De Ioris cefc9fcc58 fixed http compilation 2012-10-20 18:17:50 +02:00
Roberto De Ioris 03104063cb improved http memory handling 2012-10-20 18:16:03 +02:00
Roberto De Ioris ef10dc054f fixed fastrouter 2012-10-20 17:55:04 +02:00
Roberto De Ioris 242497102e Merge branch 'master' of https://github.com/unbit/uwsgi 2012-10-20 17:30:58 +02:00
Roberto De Ioris 0242b464e7 another step for https porting 2012-10-20 17:29:45 +02:00
Roberto De Ioris 353b837f67 preliminary port of the http router to the new api 2012-10-20 16:54:16 +02:00
Roberto De Ioris d70ecab49f simplified the fastrouter 2012-10-20 13:47:23 +02:00
Roberto De Ioris c65adaaac7 first (destructive) commit for 1.4 2012-10-20 13:47:07 +02:00
unbit 4f0406c1cc Merge pull request #21 from akx/master
Add "include" config entry
2012-10-19 10:28:39 -07:00
Roberto De Ioris 6ea535a74d fixed gil usage in gevent plugin 2012-10-18 16:06:53 +02:00
Roberto De Ioris 2e66ae9abe added a test for static offloads 2012-10-18 14:55:49 +02:00
Aarni Koskela 39aa8ca8be Add "include" config entry (practically "inherit" with UWSGI_OPT_IMMEDIATE). 2012-10-18 15:26:38 +03:00
Roberto De Ioris ef80a7bba9 fixed offload to thread 2012-10-18 12:32:02 +02:00
Roberto De Ioris 8a65125ae5 added matheval support 2012-10-18 10:44:29 +02:00
Roberto De Ioris 86d9b4bc0e always get gil on python atexit 2012-10-18 08:27:51 +02:00
Roberto De Ioris 1d691139c7 ignore sockets presence on uwsgi.loop 2012-10-18 08:07:46 +02:00
Roberto De Ioris 94eb4f078e improved gevent usage of threads (it allows tracebacker and autoreloader to work in gevent) 2012-10-17 21:19:48 +02:00
Roberto De Ioris 47f3b39870 another refactoring for simple loop 2012-10-17 13:51:12 +02:00
Roberto De Ioris c67d26f8cc support for unlimited loop engines 2012-10-17 13:43:29 +02:00
Roberto De Ioris 9c99b29e47 refactored loop engines 2012-10-17 13:16:23 +02:00
unbit 5ce2020d6f Merge pull request #18 from dpetzold/master
Hard fail if --listen > somaxconn
2012-10-12 05:57:56 -07:00
Derrick Petzold d965587d9d uwsgi_linux_somaxconn -> uwsgi_num_from_file
Changed return type to long.
2012-10-09 19:15:44 +00:00
unbit 4f85c215cd Update CONTRIBUTORS
added Aarni Koskela to the CONTRIBUTORS
2012-10-09 21:04:05 +03:00
Unbit 1015ef9611 added (joke) alarm_speech plugin for OSX 2012-10-09 18:43:02 +02:00
Roberto De Ioris adcbc061b1 allows usage of objective-c in plugins 2012-10-09 14:50:14 +02:00
Roberto De Ioris 42229b08ce added shared require for rack 2012-10-09 13:32:22 +02:00
Roberto De Ioris 7bac625537 gevent plugin is now included in the default build profile 2012-10-09 10:28:28 +02:00
Roberto De Ioris a3e9a288d3 better usage of uwsgi_log_initial 2012-10-09 06:51:14 +02:00
Derrick Petzold 946a46df86 If the listen option is greater than the system max hard fail. 2012-10-08 19:57:44 +00:00
Roberto De Ioris e368b2da5e more reliable reloading system in cheaper modes 2012-10-07 10:54:33 +02:00
Roberto De Ioris 6b32ac086e improved lua plugin performance and status management 2012-10-07 08:45:50 +02:00
Roberto De Ioris 1651e3b0ef Merge branch 'master' of github.com:unbit/uwsgi 2012-10-06 19:18:45 +02:00
Roberto De Ioris fee6c65365 added --smart-attach-daemon/--smart-attach-daemon2 2012-10-06 19:18:26 +02:00
unbit 6070bd70a7 Merge pull request #15 from prymitive/wlrc
weighted least reference count (wlrc) load balancing algorithm
2012-10-06 04:54:42 -07:00
Łukasz Mierzwa 86ea390ba8 weighted least reference count (wlrc) load balancing algorithm 2012-10-06 12:27:56 +02:00
unbit e9158255a1 Merge pull request #13 from prymitive/lrc
make lrc act like rr under low load
2012-10-05 00:34:50 -07:00
Roberto De Ioris cd80885a49 Merge branch 'master' of github.com:unbit/uwsgi 2012-10-04 20:04:46 +02:00
Roberto De Ioris 8925ea06e1 improved router_http 2012-10-04 20:04:23 +02:00
unbit f1135c736a Merge pull request #12 from avar/pass_SERVER_ADDR_from_nginx
nginx/uwsgi_params: pass SERVER_ADDR to uwsgi
2012-10-04 01:41:18 -07:00
Łukasz Mierzwa c9f0786edd with this patch lrc acts more like rr algorithm when request rate is very low. Side effect is that when one adds new node to long running cluster, then lrc will try to catch new node request count up to other nodes value, but since it will only happen during low request rate, than I don't consider it as an issue 2012-10-04 10:31:47 +02:00
Roberto De Ioris 7e52f14786 improved development version string generation 2012-10-04 08:44:07 +02:00
Roberto De Ioris e35dcdbcdb migrated to github 2012-10-04 08:39:38 +02:00
roberto@quantal64 c59a3cb35a added support for PEP 405 virtualenvs 2012-10-03 20:49:58 +02:00
roberto@quantal64 a9703f8533 another fix for lrc 2012-10-03 08:51:36 +02:00
roberto@quantal64 0de510b777 fixed erlang plugin, improved xmpp alarm 2012-10-03 07:52:34 +02:00
roberto@quantal64 8a0fa1ffc4 fixed lrc algo 2012-10-03 07:02:32 +02:00
roberto@quantal64 4ca422a0a8 added --subscription-dotsplit 2012-10-03 06:56:37 +02:00
roberto@quantal64 a979abf0c6 added multiple algorithms support for subscription load balancing 2012-10-02 17:08:40 +02:00
roberto@quantal64 d12ddded55 added support for (working, high-performance) static file offloading in linux 2012-10-02 08:51:35 +02:00
roberto@quantal64 3beead6459 fixed leak in python3 headers management, prepare for truly working static file serving offload 2012-10-01 19:49:04 +02:00
roberto@sirius 248741a81f fixed non-blocking write on osx 2012-10-01 18:55:25 +02:00
roberto@quantal64 188b66e92c Added tag 1.3 for changeset 620e0cb6ccdb 2012-09-30 09:24:02 +02:00
roberto@quantal64 5ae1c6fbd1 uWSGI 1.3 2012-09-30 09:23:53 +02:00
roberto@quantal64 51b9b5d070 added cppcheck option, improved multicast 2012-09-29 09:16:09 +02:00
roberto@quantal64 dafe3bb12c fixed rack.input with buffered arg 2012-09-28 16:21:37 +02:00
roberto@mercury 973e508af7 reports details on memory allocation error, and bypass broken rack middlewares 2012-09-28 12:37:11 +02:00
roberto@mercury 8e31bb612e allows building the rack plugin without async support 2012-09-28 06:16:55 +02:00
roberto@longshot f920ac0fb0 use SSL_CTX_use_certificate_chain_file instead of SSL_CTX_use_certificate_file 2012-09-27 19:39:14 +02:00
roberto@longshot ae1b5afd7d reoved last libstrophe reference 2012-09-27 18:21:14 +02:00
roberto@quantal64 1f2bae130e added alarm_xmpp plugin 2012-09-27 17:45:42 +02:00
roberto@quantal64 4417e55862 completed http support for alarm_curl 2012-09-27 08:01:06 +02:00
roberto@quantal64 74a84bdd3a added support for mail subject in alarm_curl plugin 2012-09-26 19:55:58 +02:00
roberto@quantal64 b764252e7f applied verbose bind errors 2012-09-26 18:42:48 +02:00
roberto@quantal64 2fd71be9d9 allows building without alarms 2012-09-26 07:19:01 +02:00
roberto@quantal64 d65f873e77 sadly Rack::BodyProxy is still badly broken on 1.9 2012-09-26 07:10:13 +02:00
roberto@quantal64 1427c9ce1c added alarm_curl plugin 2012-09-24 08:36:04 +02:00
roberto@quantal64 c3de9320d7 pass alarm to stdin in cmd mode 2012-09-23 17:19:56 +02:00
roberto@quantal64 674151e485 added alarm subsystem 2012-09-23 16:25:40 +02:00
roberto@quantal64 9c042ffc1c Added tag 1.3-rc4 for changeset aeea5a5d2e8b 2012-09-22 09:48:11 +02:00
roberto@quantal64 c5dc74b021 uWSGI 1.3-rc4 2012-09-22 09:45:08 +02:00
roberto@quantal64 97137488f9 improved emperor mongodb tyrant mode 2012-09-22 09:38:15 +02:00
roberto@quantal64 8cff01a1c7 report imperial monitor in emperor statistics 2012-09-22 09:21:37 +02:00
roberto@quantal64 3c8452313e added emperor_mongodb plugin 2012-09-22 09:04:47 +02:00
roberto@quantal64 322b130fc9 refactored imperial monitors api 2012-09-22 08:58:17 +02:00
roberto@quantal64 6c001c2fda fixed usage of inlining 2012-09-22 07:57:42 +02:00
roberto@quantal64 5d4050817d added --dlopen 2012-09-22 05:52:28 +02:00
roberto@quantal64 0a1147a4f6 added --rb-patch-rack-bodyproxy for older ruby/rack versions 2012-09-21 11:02:29 +02:00
roberto@quantal64 f92cb0e6a2 fixed rack compilation 2012-09-21 09:51:36 +02:00
roberto@quantal64 8b79c76261 refactored daemonize2 2012-09-20 18:08:49 +02:00
roberto@quantal64 0015b51262 fixed POST-handling reports 2012-09-20 17:49:30 +02:00
roberto@quantal64 b1dc8cd9c6 improved async cores detection 2012-09-20 17:41:13 +02:00
roberto@quantal64 3269e2d288 added support for dependancies in plugins 2012-09-20 17:16:30 +02:00
roberto@quantal64 71a9747d96 applied latest carbon patches from Łukasz Mierzwa 2012-09-20 16:43:20 +02:00
roberto@quantal64 455d041ce4 fixed http router parser 2012-09-20 16:36:08 +02:00
roberto@arch 88205f8dd1 added mongodblog plugin 2012-09-19 15:15:03 +02:00
roberto@centos6 7d9dadddf6 support for loading file for elf sections 2012-09-18 00:42:53 +02:00
roberto@centos6 57e78dd76f implemented rack.input each 2012-09-17 16:26:44 +02:00
roberto@centos6 7d0d2b33f4 improved rack.input disk buffering (second part) 2012-09-17 15:51:31 +02:00
roberto@quantal64 03c739102d reimplementing rack.input without IO wrapper 2012-09-17 13:43:43 +02:00
roberto@quantal64 392bb8d7b1 allows building with python3 and without embedded module 2012-09-17 07:41:11 +02:00
roberto@quantal64 505b35be29 do not try to remove sockets in abstract namespace 2012-09-17 06:47:07 +02:00
roberto@quantal64 fdb002ad9b added %0 - %9 magic vars for splitting paths 2012-09-17 06:33:52 +02:00
roberto@quantal64 557c46373f improved %c 2012-09-15 16:15:47 +02:00
roberto@quantal64 3cde8be505 allows building without embedded and multiple interpreters 2012-09-15 12:14:12 +02:00
roberto@quantal64 c2cf1f3a62 fixed threading + lazy 2012-09-14 15:52:23 +02:00
roberto@quantal64 956cb1f13c Added tag 1.3-rc3 for changeset 883b946db903 2012-09-13 18:47:08 +02:00
roberto@quantal64 f698b558e1 uWSGI 1.3-rc3 2012-09-13 18:46:56 +02:00
roberto@quantal64 ca832900a0 ensure master_cleanup is run by the master 2012-09-13 16:58:05 +02:00
roberto@quantal64 6a6227a8e7 added a warning for --map-socket invalid syntax 2012-09-13 14:09:55 +02:00
roberto@quantal64 8539cdb5a7 ported build system to python 3.3 2012-09-13 14:05:47 +02:00
Ævar Arnfjörð Bjarmason 15194e6b55 nginx/uwsgi_params: pass SERVER_ADDR to uwsgi
nginx is capable of passing SERVER_ADDR to us like Apache would do via
mod_Ruwsgi, it just doesn't do so because that variable wasn't listed
in nginx/uwsgi_params.

This and other variables are passed from nginx from the nginx code in
src/http/ngx_http_variables.c. This was tested with nginx 1.0.15.
2012-09-13 08:17:22 +00:00
roberto@quantal64 5cea1de1ba added master_cleanup hook and carbon flush on stop/reload 2012-09-12 19:03:22 +02:00
roberto@quantal64 e735b9e31f applied busyness_backlog.diff by Łukasz Mierzwa 2012-09-12 18:12:55 +02:00
roberto@quantal64 9ff8f8899f added --log-drain 2012-09-12 08:08:32 +02:00
roberto@quantal64 d908c4ef35 allows building without udp 2012-09-07 19:45:58 +02:00
roberto@quantal64 207f50726d oops, use classic perl syntax for push 2012-09-07 19:36:21 +02:00
roberto@quantal64 212559fcce put sleep() in each psgi cleanup hook to show its power :P 2012-09-07 19:13:34 +02:00
roberto@quantal64 cf480e499c implemented psgi cleanup handlers, and fixed a leak in rpc call 2012-09-07 19:09:22 +02:00
roberto@quantal64 f2e27f5154 improved process limit detection 2012-09-07 14:54:57 +02:00
roberto@quantal64 d932a4feae fixed typcasting 2012-09-07 14:40:06 +02:00
roberto@quantal64 da6e05072f explicit link with librt for alternatives clock 2012-09-07 06:58:26 +02:00
roberto@quantal64 13277d9d71 improved cheaper_busyness 2012-09-06 17:10:03 +02:00
roberto@quantal64 f17f8b337f fixed idle mode 2012-09-06 16:21:12 +02:00
roberto@quantal64 ffb454e414 headers must be sent before close() 2012-09-06 15:22:17 +02:00
roberto@quantal64 424f5a09e7 call close() always, even if client disconnect 2012-09-06 15:02:12 +02:00
roberto@quantal64 c29a6f6446 removed STOP/TSTP signal from gateways 2012-09-06 11:20:21 +02:00
roberto@quantal64 6f7edf0941 fixed uwsgi_buffer realloc len 2012-09-04 19:18:38 +02:00
roberto@quantal64 a4c4b7e8d2 fixed uwsgi_buffer realloc 2012-09-04 18:13:16 +02:00
roberto@quantal64 837f6f3a54 initialize spooler locks before app loading 2012-09-04 08:21:40 +02:00
roberto@quantal64 13041da6bf fixed piping 2012-09-04 08:13:02 +02:00
roberto@quantal64 046824dae7 fixed usage of mmap() 2012-09-03 14:11:42 +02:00
roberto@quantal64 269a588d9d uWSGI 1.3-rc2 2012-09-01 11:42:42 +02:00
roberto@quantal64 50ae12518a Added tag 1.3-rc2 for changeset 14524da00a8b 2012-09-01 11:42:31 +02:00
roberto@quantal64 a932937adf use new uwsgi_buffer structure for zeromq headers 2012-09-01 11:41:40 +02:00
roberto@quantal64 23bd924ace fixed remote cache_get for non existent keys 2012-09-01 11:34:44 +02:00
roberto@quantal64 e8f39685cc added the router_http plugin 2012-09-01 11:17:20 +02:00
roberto@quantal64 2122bacb33 fixed router_uwsgi in http/fastcgi and buffered modes 2012-09-01 08:18:43 +02:00
roberto@quantal64 3cb3c83442 added --if-opt/--if-not-opt 2012-09-01 07:45:28 +02:00
roberto@quantal64 d552d5257c add support for value check in if-env/if-not-env 2012-09-01 07:38:29 +02:00
roberto@quantal64 0aff486a73 added --spooler-external 2012-09-01 07:23:16 +02:00
roberto@quantal64 b887f3fc27 removed regexp-mount 2012-08-31 12:18:39 +02:00
roberto@freebsd64 b30e2c4ad8 added cpu affinity support for freebsd 2012-08-31 11:46:53 +02:00
roberto@openindiana64 040b17e5eb openindiana 64bit fixes 2012-08-31 11:08:51 +02:00
roberto@quantal64 770114a21c solaris fixes 2012-08-31 11:01:12 +02:00
roberto@quantal64 2864568f09 oops, forgot to remove debug :P 2012-08-31 10:49:13 +02:00
roberto@quantal64 56eaa88dd7 completed socket initialization refactoring 2012-08-31 10:47:33 +02:00
roberto@quantal64 bb54b90640 refactored mapped sockets and cpu affinity 2012-08-31 09:43:02 +02:00
roberto@quantal64 34502eeabe moved workers shared memory initialization to init.c 2012-08-31 09:34:01 +02:00
roberto@quantal64 ae90f29fa3 refactored mules and farms initialization 2012-08-31 09:30:33 +02:00
roberto@quantal64 1eeda4faaa moved buffer, post_buffers and hvec to shared uwsgi_core 2012-08-31 09:18:02 +02:00
roberto@quantal64 18046c976e first phase of main() refactory 2012-08-31 08:42:56 +02:00
roberto@quantal64 530bf85cf9 get rid of another series of gettimeofday 2012-08-30 20:23:32 +02:00
roberto@quantal64 5261a9fed5 report per-core requests in stats 2012-08-30 20:16:34 +02:00
roberto@quantal64 26d0d8dfdc improved clock usage in logging subsystem 2012-08-30 20:11:27 +02:00
roberto@quantal64 eddf494b07 big commit for allowing full access to workers/cores/requests data from the api/stats 2012-08-30 16:54:13 +02:00
roberto@quantal64 689a4ef6d4 added support for lua table in the WSAPI plugin, patch by Aaron B. 2012-08-30 08:54:25 +02:00
roberto@quantal64 9398304c60 fixed fastcgi support for response bigger than 64k 2012-08-28 18:31:45 +02:00
roberto@quantal64 e904f9f76e improved gevent graceful reload 2012-08-27 17:52:56 +02:00
roberto@quantal64 5df34ecfd8 fixed nanoseconds/microseconds conversion 2012-08-26 10:33:00 +02:00
roberto@quantal64 a96951880d added router_rewrite plugin 2012-08-26 09:11:42 +02:00
roberto@quantal64 c4425627ee added clock realtime plugin 2012-08-25 17:23:38 +02:00
roberto@quantal64 7033a0b5d2 added monotonic clock plugin 2012-08-25 17:15:58 +02:00
roberto@quantal64 a491be3975 added --clock and --clock-list options 2012-08-25 17:04:28 +02:00
roberto@quantal64 c664ac21bb added uwsgi pluggable clock infrastructure 2012-08-25 16:54:49 +02:00
roberto@quantal64 2205c0c33d fixed goodbye_cruel_world in gevent mode 2012-08-24 10:55:30 +02:00
roberto@quantal64 e9c54a4228 fixed emperor blacklist removal 2012-08-24 10:39:43 +02:00
roberto@quantal64 a38427944c fixed a series of typo 2012-08-23 17:06:03 +02:00
roberto@quantal64 124db58683 applied big Lukasz patch for busyness cheaper algo and improved carbon support 2012-08-23 17:02:15 +02:00
roberto@quantal64 aa075f9aaa added listing options for showing internal loaded features 2012-08-23 16:51:56 +02:00
roberto@quantal64 305f8a0667 auto-formatting of json output 2012-08-23 12:46:26 +02:00
roberto@quantal64 9d8238a2bb fixed json output 2012-08-23 11:37:15 +02:00
roberto@quantal64 3fccd4c5c0 fix early error reporting 2012-08-23 11:21:44 +02:00
roberto@quantal64 1a330e49f6 fixed reference counting in wrr 2012-08-20 20:37:02 +02:00
roberto@quantal64 7c09f294bf added content-length report on http body reading errors 2012-08-20 20:32:58 +02:00
roberto@quantal64 22c520043f improved/fixed wrr 2012-08-19 07:53:03 +02:00
roberto@quantal64 859c1eed0e try to fix subscription wrr 2012-08-18 20:40:28 +02:00
roberto@quantal64 e942668613 fixed a typo 2012-08-14 15:35:11 +02:00
roberto@quantal64 169c3a7970 added debug logging for busyness algo 2012-08-14 14:29:25 +02:00
roberto@quantal64 22892ce550 fixed carbon no_workers check 2012-08-14 14:15:35 +02:00
roberto@quantal64 2f5132c539 supports partial-write in linux sendfile 2012-08-13 19:08:17 +02:00
roberto@quantal64 d737bd0d35 applied Aarni Koskela patch for mod_uwsgi 2012-08-13 10:32:05 +02:00
roberto@quantal64 665958f1f5 fixed https write queue 2012-08-10 14:59:25 +02:00
roberto@quantal64 4bf86892ab another fix for write queue [2] 2012-08-10 13:04:26 +02:00
roberto@quantal64 bab89d1152 another fix for write queue 2012-08-10 12:49:23 +02:00
roberto@quantal64 4322c3b538 added support for better/true non-blocking write in http router 2012-08-10 11:12:59 +02:00
roberto@quantal64 9fabfd77ee added --so-keepalive 2012-08-10 09:11:01 +02:00
roberto@quantal64 94ce4187c9 added pam plugin 2012-08-09 18:21:02 +02:00
roberto@quantal64 e78388e287 added limit-nproc 2012-08-09 17:31:11 +02:00
roberto@quantal64 e3014bd0dc prepare for before_privileges_drop plugins 2012-08-09 17:25:05 +02:00
roberto@quantal64 36c79b100e improved build system reporting (by Łukasz Mierzwa) 2012-08-09 15:00:19 +02:00
roberto@quantal64 f6641aeca1 honour --add-header in php,rack and psgi plugins 2012-08-09 11:41:51 +02:00
roberto@quantal64 278187e738 added experimental 'busyness' cheaper algo 2012-08-09 11:06:45 +02:00
roberto@quantal64 668831d437 added --cheaper-initial 2012-08-09 07:36:41 +02:00
unbit 340f1e24ae Merge pull request #10 from xtfxme/defect-emperor-amqp-transient-queues
AMQP Emperor: Auto-delete transient queues
2012-07-26 22:12:55 -07:00
C Anthony Risinger 44e773f737 AMQP Emperor: Auto-delete transient queues
uWSGI requests a transient queue but does not set the `auto-delete` bit
resulting in unbounded creation of new -> abandonded queues.
2012-07-25 12:19:35 -05:00
roberto@quantal64 03aae347b0 allows ugreen with threads 2012-07-22 11:43:39 +02:00
roberto@mrspurr e393f36f0a fixed env clear in async mode 2012-07-22 11:21:08 +02:00
roberto@quantal64 b169193723 --json must be IMMEDIATE 2012-07-20 08:56:01 +02:00
roberto@quantal64 2de9b9d5c7 try to fix paste usage in python 3 2012-07-19 07:41:00 +02:00
roberto@quantal64 bde43ee7b2 added python logger 2012-07-17 11:20:16 +02:00
roberto@quantal64 4921e676d3 allows multiple loggers for the same instance 2012-07-17 10:40:39 +02:00
roberto@quantal64 b76a47231c fixed per-request chdir management 2012-07-17 10:06:38 +02:00
roberto@quantal64 2561d26b95 added --privileged-binary-patch-arg and --unprivileged-binary-patch-arg [2] 2012-07-16 12:22:28 +02:00
roberto@quantal64 4492bf517b added --privileged-binary-patch-arg and --unprivileged-binary-patch-arg 2012-07-16 12:12:47 +02:00
roberto@quantal64 c195e7e8ea added --privileged-binary-patch and --unprivileged-binary-patch, useful for running non-uwsgi apps using the Emperor 2012-07-16 11:55:40 +02:00
roberto@quantal64 667b418e28 improved IOVEC management in http router 2012-07-15 07:53:27 +02:00
roberto@quantal64 0ee7ba6aae save mountpoint,chdir and touch-reload valies of dynamic apps in shared memory 2012-07-13 21:44:16 +02:00
roberto@quantal64 8a656908e1 improved emperor stats and added emperormon.ru 2012-07-13 16:52:11 +02:00
roberto@quantal64 4f05d04c7f export blacklist in emperor stats 2012-07-13 16:18:36 +02:00
roberto@quantal64 c0fcbb7b85 fixed casting in wsgi.input (web3/pump part) 2012-07-13 13:23:30 +02:00
roberto@quantal64 fe36479d5c fixed casting in wsgi.input 2012-07-13 13:00:17 +02:00
roberto@quantal64 849829d6c0 correctly raise exception when the first iteration in a generator fails 2012-07-13 08:11:14 +02:00
roberto@quantal64 a77e9d3241 support for dir:// and glob:// in emperor configs 2012-07-12 20:44:43 +02:00
roberto@quantal64 fe26d41215 added support for vassal's heartbeat 2012-07-12 14:39:45 +02:00
roberto@quantal64 4d86712d4d if --harakiri and --py-tracebacker are both specified you will get a python traceback on harakiri 2012-07-12 05:25:24 +02:00
roberto@quantal64 006197a7c3 re-added support for emperor_amqp 2012-07-11 08:32:49 +02:00
roberto@quantal64 434aeb9761 improved emperor_pg plugin 2012-07-11 06:48:48 +02:00
roberto@quantal64 b1ca831269 fixed vassals removal 2012-07-11 06:43:45 +02:00
roberto@quantal64 8fc9b14db4 smarter config management in the emperor 2012-07-10 18:16:20 +02:00
roberto@quantal64 36cc5434fd added emperor postgresql plugin 2012-07-10 17:57:01 +02:00
roberto@quantal64 70c30a62e6 added --emperor-pidfile 2012-07-10 14:46:13 +02:00
roberto@quantal64 56827398d1 reindented the emperor and added some comment 2012-07-10 12:59:51 +02:00
roberto@quantal64 bd5cc93872 added preliminary support for vassal's heartbeat 2012-07-10 12:46:47 +02:00
roberto@quantal64 88be144a81 fixed a race condition in graceful reload 2012-07-10 12:34:57 +02:00
roberto@quantal64 8046194696 added --emperor-freq 2012-07-10 12:07:46 +02:00
roberto@quantal64 3012cb6bf9 new throttling system for the emperor 2012-07-10 11:53:34 +02:00
roberto@quantal64 cf74ccaaef new emperor infrastructure
--HG--
rename : lib/amqp.c => plugins/emperor_amqp/amqp.c
2012-07-10 09:32:50 +02:00
roberto@quantal64 8749053f30 removed websockets.py 2012-07-09 19:12:37 +02:00
roberto@quantal64 8368ce0e4c moved config files example to examples/ dir
--HG--
rename : debug.ini => examples/debug.ini
rename : fibers.yml => examples/fibers.yml
rename : heavytest.ini => examples/heavytest.ini
rename : logic.ini => examples/logic.ini
rename : mega.xml => examples/mega.xml
rename : multi.ini => examples/multi.ini
rename : multi.xml => examples/multi.xml
rename : protected.ini => examples/protected.ini
rename : sites.xml => examples/sites.xml
rename : uwsgi.xml => examples/uwsgi.xml
rename : welcome.ini => examples/welcome.ini
rename : werkzeug.yml => examples/werkzeug.yml
rename : werkzeug_strict.yml => examples/werkzeug_strict.yml
rename : zmqgevent.ini => examples/zmqgevent.ini
2012-07-09 19:10:47 +02:00
roberto@quantal64 c6c2157c1d moved all of the c files to the core directory
--HG--
rename : async.c => core/async.c
rename : cache.c => core/cache.c
rename : cluster.c => core/cluster.c
rename : event.c => core/event.c
rename : gateway.c => core/gateway.c
rename : ini.c => core/ini.c
rename : json.c => core/json.c
rename : ldap.c => core/ldap.c
rename : lock.c => core/lock.c
rename : logging.c => core/logging.c
rename : loop.c => core/loop.c
rename : mule.c => core/mule.c
rename : notify.c => core/notify.c
rename : plugins.c => core/plugins.c
rename : protocol.c => core/protocol.c
rename : queue.c => core/queue.c
rename : rb_timers.c => core/rb_timers.c
rename : regexp.c => core/regexp.c
rename : routing.c => core/routing.c
rename : rpc.c => core/rpc.c
rename : sendfile.c => core/sendfile.c
rename : setup_utils.c => core/setup_utils.c
rename : signal.c => core/signal.c
rename : skel.c => core/skel.c
rename : snmp.c => core/snmp.c
rename : socket.c => core/socket.c
rename : spooler.c => core/spooler.c
rename : sqlite3.c => core/sqlite3.c
rename : stats.c => core/stats.c
rename : subscription.c => core/subscription.c
rename : utils.c => core/utils.c
rename : xmlconf.c => core/xmlconf.c
rename : yaml.c => core/yaml.c
2012-07-09 19:08:51 +02:00
roberto@quantal64 4740c81280 updated uwsgiconfig.py 2012-07-09 19:01:13 +02:00
roberto@quantal64 f4f6e628b8 moved uwsgi.c to core
--HG--
rename : uwsgi.c => core/uwsgi.c
2012-07-09 19:00:39 +02:00
roberto@quantal64 55239207f4 started moving sources to core directory
--HG--
rename : emperor.c => core/emperor.c
rename : master.c => core/master.c
rename : master_utils.c => core/master_utils.c
2012-07-09 19:00:08 +02:00
unbit d912e951a0 Merge pull request #8 from skywave/zeromq3
Make compatible with zeroMQ-3.x
2012-07-08 22:24:16 -07:00
skywave b0c3184565 Make compatible with zeroMQ-3.x
In the 3.x versions of ZeroMQ some definitions were refactored, this
commit makes uwsgi compatible again with newer versions. Without this
patch compiliation of uwsgi will fail
2012-07-09 00:19:30 +02:00
roberto@quantal64 b3c9c5057f fixed a typo and an fd leak spotted by riccardo 2012-07-08 21:31:09 +02:00
roberto@quantal64 1c022ee01d added --lazy-apps as a more 'gentle' --lazy mode 2012-07-08 21:25:48 +02:00
roberto@quantal64 18589d86ff report system info on startup 2012-07-08 21:19:50 +02:00
roberto@quantal64 5a7b5d37b4 fix #138 2012-07-08 20:18:56 +02:00
roberto@quantal64 3e2115aa21 added proto logvar 2012-07-08 19:10:40 +02:00
roberto@quantal64 3f4a041e07 added time and ctime logvars 2012-07-08 19:03:44 +02:00
roberto@quantal64 59eb46895c first part of --logformat support 2012-07-08 18:29:51 +02:00
roberto@quantal64 2f452cc6f6 preliminary support for --worker-mount 2012-07-08 15:47:05 +02:00
roberto@quantal64 770bb1d122 reindented master.c 2012-07-08 07:20:31 +02:00
roberto@quantal64 4a036fb2ad refactored snmp and udp master support 2012-07-08 07:17:52 +02:00
roberto@quantal64 2ef72ad80f refactored master emperor manager 2012-07-08 07:06:22 +02:00
roberto@quantal64 c9088067d5 refactored master snapshot restore 2012-07-08 07:02:45 +02:00
roberto@quantal64 6f772f77c9 reindented master.c 2012-07-08 07:00:22 +02:00
roberto@quantal64 2430617427 refactored master mercy 2012-07-08 07:00:00 +02:00
roberto@quantal64 28888720bd refactored clusterbuf allocation 2012-07-08 06:52:32 +02:00
roberto@quantal64 32a1ba27ba refactored deadlock detector 2012-07-08 06:44:06 +02:00
roberto@quantal64 b750ee2aa3 fixed lazy reload + cheaper 2012-07-08 06:13:53 +02:00
roberto@quantal64 86aa5190b1 better waitpid usage 2012-07-08 05:07:07 +02:00
roberto@quantal64 55288af936 fixed async + threading support 2012-07-07 10:04:50 +02:00
roberto@quantal64 827d2e461b fixed cheap mode for routers 2012-07-01 16:56:30 +02:00
roberto@sirius 8400bcf8bc improved subscription system using a hash table 2012-07-01 14:27:15 +02:00
roberto@wuantal64 4dcfde541a added --rb-threads option and postinit_apps hook 2012-06-27 16:51:25 +02:00
roberto@quantal64 cf04a87688 preparing for ruby threads: add warnings if native threads are enabled 2012-06-27 16:24:55 +02:00
roberto@quantal64 65f88593b8 report mule pid when it cripples 2012-06-26 07:59:35 +02:00
roberto@quantal64 dbdf453724 fixed mongrel2 tnetstring JSON method 2012-06-25 13:41:33 +02:00
roberto@quantal64 e7f157b102 added an example config file for zeromq+gevent 2012-06-24 13:30:06 +02:00
roberto@quantal64 d30a5a4a50 little optimization for mongrel2 + gevent 2012-06-24 11:59:52 +02:00
roberto@quantal64 b0cfb0ca1f fixed a typo in gevent plugin 2012-06-24 08:59:58 +02:00
roberto@quantal64 c150f8c793 improved zeromq + threading 2012-06-23 19:54:11 +02:00
roberto@quantal64 46733c0673 started refactory of zeromq protocol handler 2012-06-23 16:59:17 +02:00
roberto@quantal64 772d1c8a5a refactored a bunch of initializing functions and allows zeromq+gevent 2012-06-23 10:00:43 +02:00
roberto@goyle 3f4bbdebe5 added a test for gevent+spooler 2012-06-21 10:52:36 +02:00
roberto@goyle 0394977658 allows greenlets to send jobs to the spooler 2012-06-21 10:24:28 +02:00
roberto@quantal64 33c9d01baf goodbye_cruel_world hook for gevent 2012-06-19 08:00:32 +02:00
roberto@quantal64 1367ee1e40 reporting correct python threads status 2012-06-17 19:08:17 +02:00
roberto@quantal64 8ddeed80cf the http router is now websocket friendly 2012-06-17 18:06:53 +02:00
roberto@quantal64 e796a57f14 fixed WSGI headers sending in websocket mode 2012-06-17 13:10:34 +02:00
roberto@sirius 839962370a trying to avoid OSX mess with universal binaries 2012-06-13 14:59:07 +02:00
roberto@quantal64 0a993c10e0 improved (and stabilized) auto-snapshotting 2012-06-13 12:44:36 +02:00
roberto@quantal64 aaaef51f2a be sure brained/patched mules are killed when the master dies 2012-06-13 11:04:35 +02:00
roberto@quantal64 8e10efd027 added options for setting Expires based on REQUEST_URI and PATH_INFO 2012-06-13 10:53:21 +02:00
roberto@quantal64 13c112430d fixed logfile inheritance 2012-06-13 08:04:05 +02:00
roberto@quantal64 05a40e786c fixed a typo 2012-06-12 14:36:48 +02:00
roberto@quantal64 64e05bed38 added support for graceful reloads in gevent plugin 2012-06-11 09:33:16 +02:00
roberto@quantal64 6f39909cd4 added support for multiple sockets in gevent plugin 2012-06-11 08:44:56 +02:00
roberto@mrspurr b4e41532eb dynamic modifier management for the rack plugin 2012-06-10 11:50:14 +02:00
roberto@mrspurr 4ca33d3f88 moved lib/rbtree.h to uwsgi.h 2012-06-10 11:28:32 +02:00
roberto@quantal64 b40cdfbe66 fixed spooler with chdir 2012-06-08 20:55:15 +02:00
roberto@quantal64 e775b18fd5 added http-to-https 2012-06-07 11:38:04 +02:00
roberto@quantal64 b1506712c9 added uwsgi.cache_clear api function 2012-06-07 08:02:29 +02:00
roberto@quantal64 7af2be5f1c reindenting a bunch of messy files 2012-06-06 09:32:34 +02:00
roberto@quantal64 27b1c63563 allows ipv6 socket to be inherited 2012-06-06 09:15:35 +02:00
roberto@quantal64 7b8fbf0f96 added binder.pl 2012-06-05 16:52:03 +02:00
roberto@quantal64 a748686349 added support for fd:// syntax in sockets options 2012-06-05 16:51:03 +02:00
roberto@quantal64 e2a0173d36 ready for the first 1.3 snapshot 2012-06-03 18:51:47 +02:00
roberto@quantal64 4d25e05986 fixed ruby rvm support 2012-06-03 18:32:05 +02:00
roberto@quantal64 c2091c52eb completed the python tracebacker 2012-06-03 10:58:34 +02:00
roberto@quantal64 d74928fa0f added @harakiri decorator for new uwsgi.set_user_harakiri option 2012-06-02 13:46:37 +02:00
roberto@quantal64 dc8bf75b73 implemented user defined harakiri via uwsgi.set_user_harakiri 2012-06-02 11:24:55 +02:00
roberto@quantal64 cc5ae8bf31 fixed a leak in uwsgi.workers() 2012-06-02 09:59:21 +02:00
roberto@quantal64 f62f7f9282 thread-safe wsgi env behaviour 2012-06-02 09:43:24 +02:00
roberto@quantal64 c3cbcbb0d5 added --wsgi-env-behaviour for choosing the WSGI environ allocator/destroyer policy 2012-06-02 07:37:52 +02:00
roberto@quantal64 ec2889b202 fixed python3 compilation 2012-06-01 19:57:07 +02:00
roberto@quantal64 474d04d6a1 added a security check in the http router 2012-05-31 18:53:09 +02:00
roberto@quantal64 18f535413f fixed signed subscription filenames 2012-05-31 16:25:07 +02:00
roberto@quantal64 85ca80f7ea added --extra-plugin build option for simplified plugin development 2012-05-31 15:24:07 +02:00
roberto@quantal64 097d10439d print cflags to stdout 2012-05-31 13:36:53 +02:00
roberto@quantal64 209d96131d fixed psgi post buffering in memory 2012-05-31 13:23:00 +02:00
roberto@quantal64 4baed7b7b8 added support for --cflags 2012-05-31 10:03:17 +02:00
roberto@precise64 9f02286018 fixed a typo in psgi.input 2012-05-30 14:44:56 +02:00
roberto@precise64 1b7d3b5fe9 fixed httprouter and rawrouter requests count 2012-05-29 19:02:07 +02:00
roberto@precise64 a6d7aa7da3 fixed waitpid() usage when in cheap mode 2012-05-29 16:40:45 +02:00
roberto@precise64 11fe76f26d improved --namespace-keep-mount with Lukasz ideas 2012-05-29 15:09:52 +02:00
roberto@precise64 1b6fdf6093 completed server side security of new subscription system 2012-05-29 14:37:26 +02:00
robert@mrspurr fa3badcfd0 improved security of secure subscription server 2012-05-29 14:36:04 +02:00
roberto@precise64 ce1b022025 added --namespace-keep-mount 2012-05-29 10:40:08 +02:00
roberto@precise64 6e81548daa allows building without ssl 2012-05-28 14:46:34 +02:00
roberto@precise64 bb7271ec17 another ifdef for older openssl versions 2012-05-28 14:42:58 +02:00
roberto@precise64 f6ca42a4b0 fixed locking reporting on older systems 2012-05-28 13:51:05 +02:00
roberto@precise64 bcf5d3a480 fixed yaml reporting 2012-05-28 13:46:17 +02:00
roberto@precise64 fffe26ceac added configuration report at the end of uWSGI compilation 2012-05-28 13:44:08 +02:00
roberto@centos64 fd17bdf963 fixed for older openssl versions 2012-05-28 13:08:31 +02:00
roberto@precise64 a168009382 implemented the 'secure' subscription system 2012-05-28 13:02:09 +02:00
roberto@precise64 f624f92e4d refactored keepalive support in http/https router 2012-05-27 15:25:53 +02:00
roberto@precise64 f065171aa1 export HTTPS_DN and HTTPS_CC 2012-05-27 13:28:19 +02:00
roberto@precise64 b7532abcc8 added support for SSL client certificate 2012-05-27 10:07:34 +02:00
roberto@precise64 59aa0308c7 fully disable ssl caching 2012-05-26 16:26:29 +02:00
roberto@precise64 6b5708a563 added a big WARNING for users forgetting to load plugins 2012-05-26 09:46:25 +02:00
roberto@precise64 c1a4834624 allows shared sockets to be subscribed 2012-05-26 09:05:30 +02:00
roberto@precise64 35ce3630c6 allows custom socket to be subscribed 2012-05-26 08:44:15 +02:00
roberto@precise64 c686912707 added rawrouter 2012-05-25 21:23:57 +02:00
roberto@precise64 963964afef custom options can now define commandline options too 2012-05-25 07:40:55 +02:00
roberto@precise64 53666dd289 allows multicast to be used as a subscription server 2012-05-24 20:59:15 +02:00
roberto@precise64 d8d292348e refactored snmp 2012-05-24 20:40:56 +02:00
roberto@precise64 678726859c applied Łukasz Mierzwa patch for carbon no workers 2012-05-24 20:34:10 +02:00
roberto@precise64 bedafceac3 applied riccardo's patch 2012-05-24 20:29:07 +02:00
roberto@precise64 a3635bc45f another master refactoring 2012-05-24 14:30:27 +02:00
roberto@precise64 8cc8394676 removed SCTP support 2012-05-24 12:24:29 +02:00
roberto@precise64 e5124093ff do not check for died processes if diedpid is invalid 2012-05-24 12:05:26 +02:00
roberto@precise64 6d1d5d6bf8 applied riccardo's patch for correct perror report 2012-05-23 20:39:34 +02:00
roberto@precise64 8964b45558 do not disable waitpid() calls during cheap mode 2012-05-23 20:37:13 +02:00
roberto@precise64 eb0e9e7d1a openssl session caching is a problem, no way to make non-blocking io call in callbacks... 2012-05-20 20:51:46 +02:00
roberto@precise64 17254ee863 added support for ssl session caching 2012-05-20 20:31:20 +02:00
roberto@backup 85fdfdd81f protect from SSL beast attack 2012-05-20 08:44:59 +02:00
roberto@precise64 3d194cd8cc added --declare-option 2012-05-19 10:59:40 +02:00
roberto@precise64 3cc591fd8b clang fix 2012-05-18 20:39:58 +02:00
roberto@precise64 3bb43745b8 remove HTTP_CONTENT_LENGTH and HTTP_CONTENT_TYPE from rack/psgi automatically 2012-05-18 16:08:23 +02:00
roberto@precise64 beb12b6804 better DH support based on stud 2012-05-18 11:09:49 +02:00
roberto@mrspurr 9a9cb2f8fe disable ssl2 2012-05-18 08:08:20 +02:00
roberto@centos4 6b7fed814c fixed support for centos4 2012-05-16 15:38:35 +02:00
roberto@precise64 47e26d93c0 ladies and gentleman, https support in the http router/load-balancer 2012-05-16 17:16:26 +02:00
roberto@precise64 de51c46fd8 allows graceful reloads on shared sockets 2012-05-16 11:09:25 +02:00
roberto@precise64 d342bdaf72 added --log-master-bufsize 2012-05-15 08:59:08 +02:00
roberto@precise64 7ee0150e2b force master mode in cheap/idle 2012-05-15 04:24:58 +02:00
roberto@precise64 cd5b0e7e58 ported corerouter stats to the new infrastructure 2012-05-14 21:04:29 +02:00
roberto@precise64 aebda4aced fixed a regression with http pipelined requests 2012-05-14 18:52:27 +02:00
roberto@sirius 26b7e6aabf improved wait_for_threads 2012-05-14 17:42:34 +02:00
roberto@precise64 9b16859c33 ported emperor stats to the new infrastructure 2012-05-14 16:21:16 +02:00
roberto@precise64 d662bf6064 new stats generator subsystem 2012-05-14 15:47:05 +02:00
roberto@precise64 a695a27b9c leave http-keepalive as experimental/useless/broken 2012-05-14 13:20:21 +02:00
roberto@precise64 e46077f576 httprouter keepalive preliminary support 2012-05-13 23:47:32 +02:00
roberto@precise64 6ec3b05ce5 fixed uwsgi signals in async mode 2012-05-13 19:49:00 +02:00
roberto@precise64.local f9d561993a added contrib/uwsgisubscribers.ru 2012-05-13 11:13:11 +02:00
roberto@precise64 c0b59234d0 report exceptions before stacktrace in psgi 2012-05-13 08:50:54 +02:00
roberto@precise64 f041509f15 another big merge of routers 2012-05-13 07:44:05 +02:00
roberto@precise64 06b4300d09 uwsgi.sendfile is for raw usage 2012-05-13 06:46:48 +02:00
roberto@precise64 7bf2194a08 a first series of solaris fixes 2012-05-12 19:48:12 +02:00
roberto@precise64 b6bdf37a1d merged http and fastrouter 2012-05-12 19:37:44 +02:00
roberto@precise64 4060436099 allows subscription system via unix socket 2012-05-12 18:22:44 +02:00
roberto@precise64 406b6098c5 unsubscribe/resubscribe on suspend/resume 2012-05-12 17:48:25 +02:00
roberto@precise64 a5606098aa implemented psgix.logger 2012-05-12 17:36:24 +02:00
roberto@precise64 ff9bab4b4e fixed psgi fileno() support 2012-05-12 17:02:21 +02:00
roberto@precise64 6e881293ff fixed async mode in non-linux systems 2012-05-12 11:23:37 +02:00
roberto@precise64 5fac82cfee fixed wsgi.file_wrapper 2012-05-12 10:54:35 +02:00
roberto@precise64 83da420cfc added corerouter 2012-05-12 10:50:19 +02:00
roberto@precise64 b2abccd302 fixed uwsgi.sendfile() 2012-05-12 10:47:04 +02:00
roberto@precise64 99d9e8cd67 applied atexit patch from 1.2.2 2012-05-11 21:15:58 +02:00
roberto@precise64 9fe275141f added preliminary python tracebacker 2012-05-11 20:44:56 +02:00
roberto@precise64 8c833101d8 let's start 1.3 development cycle 2012-05-10 09:58:09 +02:00
roberto@precise64 0c6f9faaf1 the installer now wants absolute binary path 2012-05-10 08:35:17 +02:00
roberto@precise64 a93ff5bf1f allows multiple start_response without leaks 2012-05-08 19:14:25 +02:00
roberto@precise64 d258c1b417 avoid WSGI status_line to be decref'ed 2012-05-08 18:47:49 +02:00
roberto@precise64 6e473a75bd added UWSGI_BIN_NAME support 2012-05-08 17:17:54 +02:00
roberto@precise64 433de267a6 added redislog plugin 2012-05-06 16:04:56 +02:00
roberto@precise64 2beca32c36 do not run cheaper algos or subscriptions on suspended instances 2012-05-06 14:04:43 +02:00
roberto@precise64 15aaddb4d3 allows embedding the psgi plugin 2012-05-05 10:23:26 +02:00
roberto@precise64 35ddb777b4 added interpolation support in build profile 2012-05-05 10:06:44 +02:00
roberto@precise64 b15a0a2d4b added --disable-write-exception 2012-05-05 09:30:43 +02:00
roberto@precise64 95bda63c40 added --exec-as-user-atexit (patch by Łukasz Mierzwa) 2012-05-05 09:11:40 +02:00
roberto@precise64 62b24fcd2a another python headers management optimization 2012-05-05 09:00:52 +02:00
roberto@precise64 df0406902e fixed static file offloading 2012-05-05 07:44:10 +02:00
roberto@precise64 71d57274e5 fixed optional pargs management 2012-05-05 07:11:35 +02:00
roberto@debian32 08c6258459 tolerate php wrong sign-compare 2012-05-04 16:26:06 +02:00
roberto@precise64 9a4e950480 added a fallback for pthread robust mutexes 2012-05-03 20:19:58 +02:00
roberto@precise64 e2dcdba5a7 fixed headers sent 2012-05-02 11:34:10 +02:00
roberto@precise64 c39cf848de better implementation of start_response() 2012-05-02 09:30:37 +02:00
roberto@precise64 5ccf2254eb added preliminary version of mod_proxy_uwsgi for apache2 2012-05-01 15:59:42 +02:00
roberto@precise64 dd291b9b71 fixed streaming in mod_uwsgi 2012-05-01 09:07:20 +02:00
roberto@precise64 0515fbb2d6 Added tag 1.2 for changeset c3cdecbf2bac 2012-04-30 11:05:16 +02:00
roberto@precise64 6692276472 uWSGI 1.2 2012-04-30 11:05:08 +02:00
roberto@mrspurr 81c09a9c9c report signum in worker's death 2012-04-29 05:04:19 +02:00
roberto@precise64 6a0a367ec3 added a test for gevent + threads 2012-04-26 15:11:52 +02:00
roberto@precise64 bdf533d62b fixed auto-reloading 2012-04-26 14:51:39 +02:00
roberto@precise64 1aba0bc26c completed --if-reload//--if-not-reload 2012-04-26 09:40:20 +02:00
roberto@precise64 aac6e9a365 fixed ruby -bash 2012-04-26 09:26:33 +02:00
roberto@precise64 9da732d96c added --if-reload/--if-not-reload and --unenv 2012-04-26 09:17:45 +02:00
roberto@precise64 328ba43ed2 fix uninitialzied structure 2012-04-25 17:55:47 +02:00
roberto@freebsd9 62d3253b02 fix kqueue() usage 2012-04-25 15:02:19 +02:00
roberto@mrspurr e5ba01e707 fixed socket in non-blocking mode 2012-04-25 14:18:40 +02:00
roberto@openbsd51 82c25f7f8c better execinfo detection 2012-04-25 11:00:25 +02:00
roberto@precise64 8791866ea0 added ebug infos for touch checks 2012-04-25 08:37:23 +02:00
roberto@opensuse12 8f10b8fece fix python version printing on freeky systems 2012-04-25 08:11:12 +02:00
roberto@opensuse12 0d28d210d4 another opensuse-related fix, build mimedict only if needed 2012-04-25 08:02:24 +02:00
roberto@precise 2368a5a050 fixed bug 121 2012-04-25 07:21:28 +02:00
roberto@precise64 74a9b1b41d added uwsgi.ready() 2012-04-24 21:50:00 +02:00
roberto@precise64 672c49e8eb refactored signal handling 2012-04-24 21:27:43 +02:00
roberto@precise64 225db32636 threading support for gevent 2012-04-24 19:23:14 +02:00
roberto@opensuse12 01541e4a50 fixed bug #120 2012-04-24 18:53:38 +02:00
roberto@precise64 357e260b45 some minor cleanup spotted by marcin deranek 2012-04-20 16:27:00 +02:00
roberto@centos32 a2513b1851 put a \0 at the end of process name 2012-04-20 16:11:16 +02:00
roberto@precise64 bbe8604054 added hack for ruby -bash 2012-04-20 14:11:08 +02:00
roberto@precise64 58a33de7f7 Added tag 1.2-rc2 for changeset 29de0fb320bc 2012-04-20 10:11:59 +02:00
roberto@precise64 ab7abc6a48 added upstart socket activation support and applied git001 patch for additional include paths 2012-04-20 09:59:59 +02:00
roberto@mrspurr 4986bdf202 added --static-map2 2012-04-20 07:04:02 +02:00
roberto@precise64 11aaddac98 fixed --static-map to a file 2012-04-19 19:44:35 +02:00
roberto@precise64 da9b2b4378 added static-expires/static-expires-mtime 2012-04-19 19:22:00 +02:00
roberto@freebsd9 9771a98bc6 fixed a typecast in rack plugin 2012-04-18 15:47:55 +02:00
roberto@precise64 033ee5f4e9 fixed a typo 2012-04-18 14:38:30 +02:00
roberto@precise64 1383163627 import dummy_threading whenever threads are in place 2012-04-18 10:14:41 +02:00
roberto@precise64 1d31b35c4f export static_offload_threads in statistics 2012-04-18 08:01:48 +02:00
roberto@precise64 7b2cc757b2 fixed SERVER_PORT in zeromq 2012-04-18 00:54:43 +02:00
roberto@precise64 68cddd1c2e fixed REMOTE_ADDR in mongrel2 when protocol is tnetstring 2012-04-17 23:41:04 +02:00
roberto@goyle b2a9fbbc5c set offload threading stacksize to 512k 2012-04-17 22:26:32 +02:00
roberto@goyle 0fcb13b9f1 implemented offload static file serving 2012-04-17 22:01:54 +02:00
roberto@goyle 938a22ce2e multiple mime file support 2012-04-17 20:04:48 +02:00
roberto@goyle 2df5dbfe52 added support for expires header 2012-04-17 19:24:13 +02:00
roberto@goyle feed0d0faa fixed get_mime_type 2012-04-15 22:33:05 +02:00
roberto@goyle c8373d20a9 added a check for strlen in the cgi plugin 2012-04-15 17:42:28 +02:00
roberto@mrspurr 170267a04a fixed mod_Ruwsgi 2012-04-15 07:11:45 +02:00
roberto@precise64 bd5969db67 fix initial messages 2012-04-15 07:06:33 +02:00
roberto@precise64 02256c013c added --carbon-no-workers 2012-04-14 13:54:41 +02:00
roberto@precise64 89be9a0d4a Added tag 1.2-rc1 for changeset 24c8fe5a26e5 2012-04-14 12:55:03 +02:00
roberto@precise64 4e57a6e145 uWSGI 1.2-rc1 2012-04-14 12:54:48 +02:00
roberto@openindiana64 784434ef3e opeinindiana fixes 2012-04-14 12:24:04 +02:00
roberto@precise64 91273b2301 py-auto-reload-ignore 2012-04-14 11:48:27 +02:00
roberto@precise64 2bcc85a99f added support for REMOTE_ADDR in mongrel2/zeromq 2012-04-14 10:08:34 +02:00
roberto@precise64 b7e6da3392 added --write-errors-tolerance and --write-errors-exception-only 2012-04-14 09:11:52 +02:00
roberto@precise64 d934270a27 merge 2012-04-14 08:22:54 +02:00
roberto@fiorenzo ed5a268e1f fix reloading of gateways 2012-04-13 19:01:05 +02:00
roberto@fiorenzo 95beaa0a86 merge 2012-04-13 17:09:22 +02:00
roberto@fiorenzo 0d3bf93c76 fixed fd leak in daemonize 2012-04-13 17:08:52 +02:00
roberto@sirius 50fb43066a ported fastcgi and zeromq to the new api 2012-04-13 16:23:55 +02:00
roberto@centos4 c33ec8ff56 ported locking to obsolete kernels 2012-04-13 14:09:03 +02:00
roberto@mrspurr e6afeec8af fixed return value in cache sweeper thread 2012-04-13 15:57:07 +02:00
roberto@sirius 57b9bdb958 better write()/writev() management 2012-04-13 11:36:43 +02:00
roberto@precise64 315bcb72c9 applied nagios patch from github 2012-04-11 07:23:00 +02:00
roberto@precise64 6b2460c02f improved syslog 2012-04-11 07:20:58 +02:00
roberto@precise64 35bc999a59 correctly set bin_name in setup.py 2012-04-09 08:41:27 +02:00
roberto@precise64 f00ad75e45 added --emperor-magic-exec 2012-04-08 09:13:07 +02:00
roberto@openbsd51 6bfe8e5b41 openBSD fixes 2012-04-08 08:24:51 +02:00
roberto@precise64 d7e8fd7d06 a couple of typo 2012-04-07 21:17:09 +02:00
roberto@precise64 949a0c35d5 improve cache reliability and performance of the sweeper 2012-04-07 21:08:42 +02:00
roberto@precise64 d193d5572f add --cache-expire-freq 2012-04-06 16:09:58 +02:00
roberto@precise64 f79f7e44a7 fixed cache and queue locking 2012-04-06 15:54:29 +02:00
roberto@mrspurr 26db55aafd fixed --pyargv 2012-04-06 11:39:48 +02:00
roberto@mrspurr 9d405c6cb2 fixed locking in uwsgi.cache_exists 2012-04-06 10:28:02 +02:00
roberto@mrspurr cceee511f2 added support for reload-on-exception on PyPy and interval-based cron syntax 2012-04-06 07:40:21 +02:00
roberto@freebsd9 e2024ed2fd merge 2012-04-05 12:28:30 +02:00
roberto@freebsd9 add7e2ee0e added execinfo support for FreeBSD 2012-04-05 12:28:10 +02:00
roberto@precise64 0458aa8eb4 use ctime_r instead of ctime 2012-04-05 12:15:04 +02:00
roberto@freebsd9 9ff6be783a use posix semaphores on freebsd9 2012-04-05 06:22:02 +02:00
roberto@mrspurr 14c558559b pypy now has PyFile_FromFile 2012-04-05 05:52:58 +02:00
roberto@centos64 92c5dcb6f2 allows robust mutexes on older linux systems 2012-04-04 22:54:56 +02:00
roberto@precise64 ae31f349f7 added robust mutexes 2012-04-04 22:53:07 +02:00
roberto@centos64 ce2846d04f first pthread robust implementation 2012-04-04 21:48:34 +02:00
roberto@mrspurr 7a6c9a5fe4 merge 2012-04-04 17:29:39 +02:00
roberto@mrspurr 43c258ad48 support for virtualenv in pypy 2012-04-04 17:29:00 +02:00
roberto@precise64 8ba032adb2 added --spooler-max-tasks 2012-04-03 17:59:37 +02:00
roberto@precise64 1a61dfd4e0 ported mod_Ruwsgi to apache 2.4 2012-04-03 09:02:00 +02:00
roberto@precise64 8e150e77a8 ported mod_uwsgi to apache 2.4 2012-04-03 08:47:09 +02:00
roberto@goyle 729fa753fa remove unneded pypy ifdef 2012-04-02 19:33:33 +02:00
roberto@longshot bf6c552189 fixed python 2.4 2012-04-02 07:55:22 +02:00
roberto@precise64 e9dc987a95 revert wsgi.url_scheme 2012-04-02 07:48:20 +02:00
roberto@precise64 35d9a39100 fixed autoload 2012-04-01 06:14:09 +02:00
roberto@mrspurr a864c8d6ed fix pypy when no app is loaded 2012-03-31 18:06:03 +02:00
roberto@precise64 c2df8a099e added --python-auto-reload 2012-03-31 17:55:09 +02:00
roberto@precise64 878e9cb9ba reports microseconds in python profilers 2012-03-31 15:48:22 +02:00
roberto@precise64 3612ea2186 fixed a deadlock in get_mime_type 2012-03-30 21:15:14 +02:00
roberto@precise64 81f0f93d96 improved module aliasing 2012-03-30 10:17:30 +02:00
roberto@precise64 c2d7b65145 better error management in pymodule-alias 2012-03-29 12:59:50 +02:00
roberto@precise64 6274e82cea fix fastrouter subscription refcnt 2012-03-29 11:26:35 +02:00
roberto@precise64 66655c9429 php append options 2012-03-28 18:28:24 +02:00
roberto@precise64 f47c8553d5 added uwsgi_expand_path() 2012-03-28 16:48:17 +02:00
roberto@precise64 f2802d3332 gevent current_req fix 2012-03-28 16:22:18 +02:00
roberto@precise64 1a173c849f minor fixes for test suite 2012-03-28 12:40:20 +02:00
roberto@precise64 57d4cd9fc9 gevent fixes 2012-03-28 11:08:04 +02:00
roberto@precise64 f6b9345716 fixed a garbage in python_call 2012-03-28 10:21:20 +02:00
roberto@freebsd64 792cd01320 fixed daemonize 2012-03-28 09:34:37 +02:00
roberto@mrspurr 03bc7d0399 close bug 85 2012-03-28 09:00:53 +02:00
roberto@mrspurr ed8f0812d7 PyPy SUPPORT 2012-03-27 13:58:27 +02:00
roberto@precise64 196dc45d0b fixed zero socket (2) 2012-03-26 14:28:18 +02:00
roberto@precise64 f8ff906d1b fixed zero socket 2012-03-26 14:20:08 +02:00
roberto@precise64 bbf1b0eda5 merged pypy 2012-03-26 13:41:50 +02:00
roberto@precise64 6f811a4899 better realpath for static docroot 2012-03-26 13:41:18 +02:00
roberto@mrspurr c66957d685 first round of pypy patches 2012-03-26 10:46:12 +02:00
roberto@goyle 282b2d5ace lua fixes 2012-03-23 21:22:17 +01:00
roberto@precise64 6a73e3ae05 fixed rack.input read 2012-03-22 16:25:27 +01:00
roberto@precise64 5856d410fd second part of zerg fixes 2012-03-22 11:14:41 +01:00
roberto@precise64 08d9de54f0 uniq zerg sockets 2012-03-22 10:05:00 +01:00
roberto@precise64 af1f98131a --perl-no-die-catch 2012-03-22 08:32:11 +01:00
roberto@precise64 9cef49ec57 fixed perl caching, added uwsgi::signal 2012-03-22 08:26:33 +01:00
roberto@precise64 d60c6d50ec fixed plugin loading by symlink 2012-03-22 07:35:27 +01:00
roberto@precise64 f3fdec2739 completed --reload-on-exception* options 2012-03-21 20:37:03 +01:00
roberto@precise64 1a20f57b73 fixed --spooler-quiet 2012-03-21 20:28:08 +01:00
roberto@precise64 0fc74dac4d better GIL usage 2012-03-21 20:21:51 +01:00
roberto@precise64 4117dd91fc ported psycopg2 example to the new api 2012-03-21 19:53:40 +01:00
roberto@precise64 508ca0df39 add realpath() for php DOCUMENT_ROOT 2012-03-21 19:28:24 +01:00
roberto@precise64 a50e356beb more verbose php debug 2012-03-21 07:50:27 +01:00
roberto@precise64 a0b7237083 added --spooler-quiet 2012-03-20 15:42:10 +01:00
roberto@precise64 08afa73e69 spooler multiprocess fixes 2012-03-20 10:58:48 +01:00
roberto@precise64 b386317921 fixed python3 reload-on-exception 2012-03-19 13:39:07 +01:00
roberto@precise64 2043127f22 fixed snmp support 2012-03-19 07:29:39 +01:00
roberto@precise64 c297a9415b started 1.2 development cycle 2012-03-18 09:03:14 +01:00
roberto@precise64 f9f9f25a01 added exception detection 2012-03-18 08:21:45 +01:00
roberto@precise64 9001af1beb better uuid detection 2012-03-17 11:01:01 +01:00
roberto@debian32 4b03f17186 python 3.x fix 2012-03-17 10:36:06 +01:00
roberto@precise64 3dbab36b91 uWSGI 1.1 2012-03-17 07:56:09 +01:00
roberto@precise64 056c890845 Added tag 1.1 for changeset e1568fd16b7b 2012-03-17 07:39:33 +01:00
roberto@precise64 4f43cd74ad env must not be immediate 2012-03-16 20:53:03 +01:00
roberto@precise64 6585b7b13d fixed pifile 2012-03-16 13:38:26 +01:00
roberto@precise64 e55048b574 fixed logdate 2012-03-16 13:07:06 +01:00
roberto@mercury 570dcde654 report listen_queue_errors 2012-03-16 06:52:48 +01:00
roberto@precise64 3cb16ee29b ready for 1.1 release 2012-03-15 20:42:41 +01:00
roberto@mailcop3 bb453da5b5 added support for SIOBKLGQ 2012-03-15 20:40:26 +01:00
roberto@precise64 1a93b68664 fixed expire_timeouts in fastrouter 2012-03-15 17:44:56 +01:00
roberto@precise64 2ce2494a50 bumped to -rc4 2012-03-15 17:36:59 +01:00
roberto@precise64 0a1e451289 Added tag 1.1-rc4 for changeset ef99144291f0 2012-03-15 17:31:05 +01:00
roberto@precise64 8ef7819080 re-included WSGI iterator close() 2012-03-15 17:29:55 +01:00
roberto@precise64 319ad13af2 allows plugin 255 to be used 2012-03-15 08:58:41 +01:00
roberto@precise4 fe28e90ae3 fixed a bug in spooler and signal plugin 2012-03-15 08:48:26 +01:00
roberto f604a0a533 bumped to 1.1-rc3 2012-03-14 18:30:19 +01:00
roberto@precise64 4ab78d42a3 Added tag 1.1-rc3 for changeset ede5c664978b 2012-03-14 18:30:02 +01:00
roberto@precise64 c631e7dae6 fixed multiple touch-reload 2012-03-14 18:29:04 +01:00
roberto@precise da8e88d638 Added tag 1.1-rc2 for changeset 901f0cb5de36 2012-03-14 12:08:58 +01:00
roberto@precise64 4707d9250d queue/cache fix 2012-03-14 11:34:51 +01:00
roberto@precise64 d719960411 fixed emperor amqp 2012-03-14 10:03:54 +01:00
roberto@precise64 734818c995 fixed shared sockets 2012-03-14 08:28:25 +01:00
roberto@precise64 a35335a820 fixed lua plugin 2012-03-12 18:54:04 +01:00
roberto@precise64 aca4dbfbe7 fixed threading rpc 2012-03-12 14:54:59 +01:00
roberto@precise64 b036029b32 another locking fix 2012-03-12 09:58:02 +01:00
roberto@freebsd64 52f3e757ed added --ftok 2012-03-12 09:40:56 +01:00
roberto@precise64 c4ce1cf7d8 appliead Riccardo's patches 2012-03-11 20:10:04 +01:00
roberto@icarus 48175d0759 various fixed for php and cgi plugins, added notfound plugin 2012-03-11 17:21:53 +00:00
roberto@precise64 2932168db7 Added tag 1.1-rc1 for changeset 1d1702789710 2012-03-10 15:23:47 +01:00
roberto@precise64 e8d96b8f84 completed ldap support 2012-03-10 15:21:08 +01:00
roberto@precise64 bd15fd9da1 fixed ldap support 2012-03-10 14:30:48 +01:00
roberto@precise64 6e98eda963 set version to 1.1, only LDAP missing 2012-03-10 13:34:17 +01:00
roberto@precise64 ec9bb3601e added --flock/--flock2/--flock-wait/--flock-wait2 2012-03-10 13:26:45 +01:00
roberto@precise64 02e4840b29 re-added --ignore-sigpipe 2012-03-10 12:34:45 +01:00
roberto@precise64 d7e8523fcf do not call atexit hooks in async mode 2012-03-10 12:06:19 +01:00
roberto@precise64 41464c3bfa fr sctp fix 2012-03-10 11:35:05 +01:00
roberto@goyle a3617d0b5a fastrouter heavy optimization 2012-03-10 11:25:19 +01:00
roberto@centos6 10ff849ebd fixed permissions of files 2012-03-07 15:06:38 +01:00
roberto@centos6 c2f7d487d0 initgroups() usage 2012-03-07 04:40:16 +01:00
roberto@centos6 395cf57e21 added stats for sctp fastrouter 2012-03-07 02:55:48 +01:00
roberto@centos6 4c854a83c9 SCTP improvements, rack optimizations 2012-03-07 01:40:57 +01:00
roberto@centos6 881b3b7e0c another series of SCTP fixes 2012-03-06 16:43:41 +01:00
roberto@openbsd50 bb28e4279b fixed cgi cast of FILE 2012-03-06 15:22:38 +01:00
roberto@openbsd50 c65b8ce162 various fixes 2012-03-06 15:20:25 +01:00
roberto@openindiana 8a303b1965 solaris fixes 2012-03-06 12:19:29 +01:00
roberto@centos6 adca811941 fixed 105 2012-03-06 11:34:56 +01:00
roberto@goyle f79e9d8773 fixed a typo 2012-03-05 16:22:20 +01:00
roberto@precise64 629fbf4f07 another series of sctp patch 2012-03-05 04:29:11 +01:00
roberto@precise64 da9ce52294 little refactoring for the fastrouter 2012-03-04 16:10:35 +01:00
roberto@precise64 205605a3c4 fixed PATH_INFO in php 2012-03-03 17:34:44 +01:00
roberto@precise64 e39127be92 ready for rc 2012-03-03 16:31:26 +01:00
roberto@precise64 0b2458d74a SCTP is experimenta, stop development til 1.1 release 2012-03-03 16:17:16 +01:00
roberto@precise64 9d661122bd added experimental SCTP/persistent connections support 2012-03-03 13:46:21 +01:00
roberto@precise64 8518747a51 try to reduce spooler wait 2012-03-03 09:35:46 +01:00
roberto@precise64 2f6450a560 <app> tag usage will be removed in uWSGI 1.2 2012-03-02 08:27:52 +01:00
roberto@precise64 c72889c10f added --daemonize2 2012-03-02 07:31:20 +01:00
roberto@precise64 bb7456e3f8 gateways structure is again shared 2012-03-01 21:27:17 +01:00
roberto@precise64 5aff13543e another fastrouter fix 2012-03-01 20:11:06 +01:00
roberto@precise64 c7d967d43c fixed python 3 2012-03-01 18:30:32 +01:00
roberto@precise64 1a42194304 added ruby rvm/gemset support 2012-03-01 18:22:25 +01:00
roberto@precise64 312563437c multiprocess spooler 2012-03-01 14:54:10 +01:00
roberto@precise64 5972ac1ed7 fixed permission in ipcsem 2012-03-01 11:11:51 +01:00
roberto@precise64 75d4123b34 added locking test 2012-03-01 11:06:53 +01:00
roberto@precise64 89ef4f68a9 added ipcsem 2012-03-01 11:06:00 +01:00
roberto@precise64 ed72677e52 even fcntl is broken 2012-03-01 09:51:31 +01:00
roberto@precise64 08ab27c36c cache_get optimization 2012-03-01 09:15:43 +01:00
roberto@precise64 af8bb8fd05 fixed locking in multithread 2012-03-01 09:06:02 +01:00
roberto@precise64 57bade7eae close stdin in vassals 2012-02-29 14:57:44 +01:00
roberto@mishmash 3c6de0e84d various fastrouter fixes 2012-02-29 10:14:44 +01:00
roberto@precise64 24e3fea334 added fd:// to corerouter bind subsystem 2012-02-29 08:47:52 +01:00
roberto@precise64 6af77aab8b added --fastrouter-gracetime 2012-02-29 07:46:24 +01:00
roberto@precise64 12325633ed fastrouter improvements 2012-02-29 07:04:14 +01:00
roberto@sirius 3a108b61ee fixed pause reporting 2012-02-28 18:56:32 +01:00
roberto@goyle b2eaf384ac --fastrouter-fallback 2012-02-28 18:08:40 +01:00
roberto@precise64 3d17ef9603 lockf for sun 2012-02-28 10:31:24 +01:00
roberto@precise64 3b031872f7 lockf for sun 2012-02-28 10:30:07 +01:00
roberto@precise64 e97d39f37c prepared umtx for future implementations 2012-02-28 09:21:44 +01:00
roberto@sirius 763f715279 ported locking api to OSX 2012-02-28 09:18:41 +01:00
roberto@precise64 af9f79f3eb ported new locking api to linux 2012-02-28 09:14:08 +01:00
roberto@freebsd64 01ab3e2895 broken commit for new locking api 2012-02-28 09:05:37 +01:00
roberto@precise64 7a34344632 fixed a bug in setrlimit 2012-02-27 20:21:55 +01:00
roberto@precise64 9714cb6790 fixed log flush 2012-02-27 19:48:35 +01:00
roberto@precise64 aa981d03e8 reintroduce the remote spooler plugin [2] 2012-02-27 15:59:47 +01:00
roberto@precise64 9a09164fc3 reintroduce the remote spooler plugin 2012-02-27 15:59:07 +01:00
roberto@precise64 9674a81323 added --forkbomb-delay 2012-02-27 14:38:49 +01:00
roberto@precise64 aba7280691 added --need-app 2012-02-27 14:27:34 +01:00
roberto@precise64 ef9908b058 fixed --cluster-reload and --cluster-log 2012-02-26 12:35:05 +01:00
roberto@precise64 4da4fb4cbd completed clustering porting 2012-02-26 12:30:35 +01:00
roberto@precise64 b4f8a3b179 fixed bug #62 2012-02-26 09:07:14 +01:00
roberto@precise64 b48a955848 fixed paste logging 2012-02-26 08:57:43 +01:00
roberto@precise64 5ea4e3bcc3 removed url from setup.py 2012-02-26 08:26:21 +01:00
roberto@precise64 6732cb01a8 free libxml2 resources on exit 2012-02-26 08:05:39 +01:00
roberto@precise64 0b5ca736d4 re-added expat support 2012-02-25 20:26:17 +01:00
roberto@precise64 a2358c6bec completed porting of the http plugin to the new api 2012-02-25 18:36:04 +01:00
roberto@precise64 10775dd2ac another series of http ports 2012-02-25 18:24:56 +01:00
roberto@precise64 d33d12c642 ported --http-var 2012-02-25 18:20:59 +01:00
roberto@precise64 af3ccfeed4 added negative configlogic 2012-02-25 09:24:07 +01:00
roberto@precise64 1d64267aba added --check-static-docroot 2012-02-25 08:44:00 +01:00
roberto@cable 9bbef9b0c5 various condition build fixes 2012-02-25 08:34:11 +01:00
roberto@precise64 c95ec82b03 a series of php/cgi fixes 2012-02-24 12:12:19 +01:00
roberto@precise64 46108a00f0 fixed startup time in rack plugin 2012-02-24 09:37:33 +01:00
roberto@precise64 d6c3fd7771 --php-app added 2012-02-24 09:26:57 +01:00
roberto@precise64 ad783ccaf0 added script for external app loading 2012-02-24 06:49:54 +01:00
roberto@precise64 f58be4241f added cheaper_backlog2 example 2012-02-23 21:46:27 +01:00
roberto@precise64 cb1d22d88b added pluggable cheaper algorithms 2012-02-23 21:38:53 +01:00
roberto@precise64 6c8453d98e another logging refactoring 2012-02-23 20:42:00 +01:00
roberto@colossus 061de3b037 merge 2012-02-23 18:16:38 +01:00
roberto@colossus ded065ef38 php-server-software 2012-02-23 18:16:18 +01:00
roberto@precise64 822959238c fixed a bug with --set 2012-02-23 16:58:36 +01:00
roberto@precise64 4ebb9d7b46 faster restart thanks to single getrlimit call 2012-02-23 14:13:38 +01:00
roberto@precise64 cc49964c43 fixed a lost null pointer 2012-02-23 07:51:36 +01:00
roberto@precise64 3787d5e84a flush logs on exit 2012-02-23 07:48:54 +01:00
roberto@precise64 7329606a6a added a cast (just to be sure) 2012-02-22 17:11:12 +01:00
roberto@precise64 5facafadea added uwsgi api support for php 2012-02-22 16:44:56 +01:00
roberto@precise64 d3102df2bf added a signal handler for FPE 2012-02-22 12:00:32 +01:00
roberto@precise64 87860da238 better loaded app reporting 2012-02-22 11:55:06 +01:00
roberto@precise64 4a8aa01f40 added startup time for apps 2012-02-22 11:39:19 +01:00
roberto@longshot 9d35067b4b allows custom php-config path 2012-02-22 10:33:45 +01:00
roberto@precise64 1c29be3745 fix php uwsgi.h include 2012-02-20 04:07:16 +01:00
roberto@centos6 bf3c3a3768 another php update 2012-02-19 17:52:17 +01:00
roberto@fedora32 b25de79ae4 completed new php plugin 2012-02-19 15:44:23 +01:00
roberto@precise64 ba663ef2cc ready for new php plugin 2012-02-19 11:08:52 +01:00
roberto@precise64 19185640a5 fixed a typo 2012-02-18 16:29:21 +01:00
roberto@precise64 eafe8c4fff new cheaper implementation 2012-02-18 16:28:01 +01:00
roberto@precise64 bdd3e69024 removed some funny debug log 2012-02-18 11:40:25 +01:00
roberto@precise64 b5a7ab3688 fixed paste logging 2012-02-18 09:32:39 +01:00
roberto@centos64 cc0fa8dee6 fixed rack build 2012-02-18 08:55:35 +01:00
roberto@precise64 14941cc1c0 deprecate <app> 2012-02-18 08:40:36 +01:00
roberto@precise64 910cb3a790 fixed single-intepreter mode 2012-02-18 08:32:53 +01:00
roberto@precise64 355e989eea refactored xmlconf 2012-02-18 08:07:48 +01:00
roberto@precise64 bfcd9dad25 removed useless makefiles 2012-02-18 07:37:48 +01:00
roberto@precise64 73ed5fd7cf added --auto-weight 2012-02-18 07:25:11 +01:00
roberto@netbsd64 d21cc0970c NetBSD fixes 2012-02-18 08:16:37 +01:00
roberto@precise64 eb8b03139d master_loop function is becoming extremely huge, time to refactor it... 2012-02-17 20:36:04 +01:00
roberto@precise64 1558145985 refactored uwsgi_reload() 2012-02-17 20:23:29 +01:00
roberto@precise64 4ea9a29e62 fixed some typo in comments 2012-02-17 20:09:54 +01:00
roberto@precise64 72c8d9cd5e refactored/reimplemented cheaper mode 2012-02-17 19:04:32 +01:00
roberto@precise64 fb4fc38f14 better umask handling 2012-02-17 17:58:46 +01:00
roberto@precise64 de25db9e75 fixed shared sockets for http and fastrouter plugins 2012-02-17 17:48:57 +01:00
roberto@precise64 4ba558430d added wrr to fastrouter/subscription 2012-02-17 13:57:46 +01:00
roberto@precise64 e4711484ac fixed a stupid deadlock 2012-02-17 11:21:08 +01:00
roberto@precise64 5081a3f635 placed a mutex in threaded logger trying to fix #84 2012-02-17 09:50:56 +01:00
roberto@precise64 b31fa366a2 make older gcc happy for gevent 2012-02-17 07:05:26 +01:00
roberto@precise64 c1b24b390a fixed unsubscribe 2012-02-16 20:13:36 +01:00
roberto@precise64 b7461442b0 added a report on unsubscribe 2012-02-16 16:56:08 +01:00
roberto@precise64 c072e9b609 added stacktrace to perl errors 2012-02-16 11:31:52 +01:00
roberto@precise64 5236c58255 added new routing rules 2012-02-16 09:04:59 +01:00
roberto@precise64 4f5280ea2b zeromq/mongrel2 improvements 2012-02-16 07:33:31 +01:00
roberto@precise64 4d1c3fcaea added UWSGI_APPID management in router_uwsgi 2012-02-16 07:22:13 +01:00
roberto@precise64 310acaf4cc do not inizialize request plugins if not needed 2012-02-15 21:28:12 +01:00
roberto@precise64 8111acaad1 completed new perl infrastructure 2012-02-15 20:34:52 +01:00
roberto@mrspurr c80b10d2b2 fixes for non ithreads perl 2012-02-15 19:55:43 +01:00
roberto@precise64 9807192bd1 thread-safe perl multi-app support 2012-02-15 18:10:22 +01:00
roberto@precise64 9386c97851 added perl multiple interpreter support (non-thread-safe) 2012-02-15 14:10:33 +01:00
roberto@precise64 7f3e9b10c4 merge 2012-02-15 05:03:56 +01:00
roberto@precise64 360719582b fix #91 2012-02-15 05:03:15 +01:00
roberto@sirius a1a6d4a248 fxed the carbon plugin 2012-02-14 16:20:34 +01:00
roberto@precise64 015ea78927 set correct status in routers 2012-02-13 19:27:42 +01:00
roberto@precise64 ad32841aaa fixed wrong definition of --route option 2012-02-13 19:22:32 +01:00
roberto@precise64 2a3771dccf added blacklist/whitelist support for options 2012-02-13 16:55:48 +01:00
roberto@precise64 26af8af48f fixed port handling in fastrouter stats 2012-02-13 11:54:03 +01:00
roberto@precise64 5829c3a843 new plugin infrastructure 2012-02-13 11:40:06 +01:00
roberto@goyle c723d6d9d5 non-linux fix 2012-02-13 07:56:59 +01:00
roberto@oneiric64 2c0c9a918a fixed a stupid bug in uniq_warning 2012-02-13 06:41:27 +01:00
roberto@precise64 8f9bc7170e added zergpool pluin 2012-02-12 17:20:51 +01:00
roberto@precise64 ee002167d4 improved zergpool 2012-02-12 17:17:19 +01:00
roberto@precise64 4ddeb26cca extended zerg mode to support an unlimited number of sockets 2012-02-12 13:16:58 +01:00
roberto@precise64 a1514e2eaf added another config style for basicauth 2012-02-12 10:11:39 +01:00
roberto@precise64 5d1c7ab8b0 fixed a race condition in cheaper + threads 2012-02-12 09:42:17 +01:00
roberto@precise64 27698e34f5 added protected.ini 2012-02-12 09:28:19 +01:00
roberto@precise64 c06b4773c7 thread-safe basicauth 2012-02-12 09:26:38 +01:00
roberto@mrspurr e431936a8e python set() is not good 2012-02-12 08:43:21 +01:00
roberto@precise64 de3d22a401 preliminary support for http basic auth (real) 2012-02-12 08:35:21 +01:00
roberto@precise64 22778d9de7 preliminary support for http basic auth 2012-02-12 08:34:14 +01:00
roberto@precise64 069f517b04 added --zerg-fallback 2012-02-11 21:02:15 +01:00
roberto@precise64 1017dda1ec merge 2012-02-11 17:50:20 +01:00
roberto@centos64 581b4a4216 off by one fix 2012-02-11 17:40:41 +01:00
roberto@precise64 e1f00cbf96 better erlang detection 2012-02-11 17:20:47 +01:00
roberto@centos64 32ad0a7b87 build improvements 2012-02-11 14:17:00 +01:00
roberto@oneiric64 aa4b9b16fb fixed magic_table handling 2012-02-10 16:14:44 +01:00
roberto@oneiric64 73721ab73a disable write-strings 2012-02-10 15:27:02 +01:00
roberto@oneiric64 90cc3dc389 fixed rack build 2012-02-10 12:37:07 +01:00
roberto@oneiric64 f4f4d5a6c0 python atexit improvements from mod_wsgi 2012-02-10 11:18:53 +01:00
roberto@oneiric64 4bd2410ee7 added support for logic in config directives with a first 'for' implementation 2012-02-10 09:06:09 +01:00
roberto@gambit 6bc264d33b various fixes for better cgi routing support 2012-02-09 13:00:27 +01:00
roberto@gambit c7d1c6818b fixed touch-reload 2012-02-09 12:32:31 +01:00
roberto@oneiric64 937e68bf67 another lock fix 2012-02-08 12:56:46 +01:00
roberto@oneiric64 434fb96be7 another fix in locking subsystem 2012-02-08 12:49:06 +01:00
roberto@oneiric64 e2fe86027c improved pyargv management 2012-02-08 12:19:14 +01:00
roberto@oneiric64 06ca891d94 fixed threading in command mode 2012-02-08 11:54:15 +01:00
roberto@oneiric64 57c00c9b12 set to_hell in command mode 2012-02-08 11:41:01 +01:00
roberto@sirius b320e1e222 disable master process in command mode 2012-02-08 11:15:29 +01:00
roberto@sirius c72ddc9dd8 added command mode 2012-02-08 11:01:04 +01:00
roberto@oneiric64 c37a386674 added uwsgi.is_locked 2012-02-07 16:40:25 +01:00
roberto@oneiric64 ad6a79b5b7 remove -Wwrite-strings 2012-02-07 16:09:45 +01:00
roberto@oneiric64 ff733cd50b fixed logto 2012-02-07 15:37:19 +01:00
roberto@oneiric64 53128a2391 fixed daemonize and cron 2012-02-07 15:32:34 +01:00
roberto@oneiric64 d01fc8804c fixed a stupid bug in cron management 2012-02-07 14:36:26 +01:00
roberto@oneiric64 e520d7a58f fixed mules signal handling 2012-02-07 12:38:37 +01:00
roberto@freebsd64 7846ea636c ported new locking api to freebsd 2012-02-07 12:09:20 +01:00
roberto@mrspurr 0025ad8329 ported new lock api to OSX 2012-02-07 12:03:50 +01:00
roberto@oneiric64 1a1f270f4e completed locking refactoring on linux 2012-02-07 11:56:19 +01:00
roberto@oneiric64 517f4498f5 another locking refactoring 2012-02-07 11:10:20 +01:00
roberto@oneiric64 87a165477f fixed disable logging 2012-02-07 05:34:28 +01:00
roberto@oneiric64 1e657f0b77 plugins loading fix 2012-02-07 05:26:51 +01:00
roberto@oneiric64 a8e399db1e psgi fixes 2012-02-07 05:08:53 +01:00
roberto@oneiric64 66f9607404 various fixes reported by Lukasz Mierzwa 2012-02-07 03:20:10 +01:00
roberto@oneiric64 27319c2da3 ported --http-manage-expect to new options api 2012-02-06 17:23:22 +01:00
roberto@oneiric64 de21abb21c ported jvm plugin to the new options api 2012-02-06 17:17:26 +01:00
roberto@oneiric64 94cae4ac17 completed php porting to the new api 2012-02-06 17:01:16 +01:00
roberto@oneiric64 3b5e1f98f5 completed fastrouter porting to the new options api 2012-02-06 16:56:06 +01:00
roberto@oneiric64 594f67c6d7 added support for paste loggers 2012-02-06 16:29:04 +01:00
roberto@oneiric64 f1b415df2f completed python plugin porting to the new options api 2012-02-06 16:14:15 +01:00
roberto@oneiric64 c07e0ef581 --touch-logreopen and --touch-logrotate 2012-02-06 16:00:51 +01:00
roberto@goyle 0d4f6501b0 ported backtrace to osx 2012-02-06 11:38:56 +01:00
roberto@goyle d2cbb7eea2 allow non-pcre build 2012-02-06 11:02:57 +01:00
roberto@oneiric64 f4cb3c67c1 a series of stupid fixes 2012-02-05 11:56:50 +01:00
roberto@oneiric64 a51877cd1d another series of options fixes/porting 2012-02-05 11:50:33 +01:00
roberto@oneiric64 c0c3287f74 fully ported cgi plugin to the new options api 2012-02-05 11:44:18 +01:00
roberto@oneiric64 83378802af completed porting perl/psgi to new options api 2012-02-05 11:25:39 +01:00
roberto f05d712923 completed ruby/rack porting to the new options api 2012-02-05 11:20:19 +01:00
roberto@freebsd64 5b2df55b8e ported freebsd to the new locking api 2012-02-05 11:07:40 +01:00
roberto@oneiric64 865ec4dd8f added internal routing subsystem 2012-02-05 10:43:03 +01:00
roberto@oneiric64 6ddf1afc81 ported --http-use-cache to the new api 2012-02-04 16:20:37 +01:00
roberto@mrspurr 7bd44f4f14 added internal routing infrastructure 2012-02-04 16:10:32 +01:00
roberto@goyle a92c2003ee prepare for new routing system 2012-02-02 18:20:10 +01:00
roberto@debian64 97a8c5e4b6 another fix for pyargv 2012-02-02 11:40:52 +01:00
roberto@debian64 a5aa31f13e applied ticket #82 2012-02-02 11:25:44 +01:00
roberto@debian64 1a0161cb6b fixed pyargv 2012-02-02 11:14:34 +01:00
roberto@debian64 b8c17baf7c fixed pythonpath 2012-02-02 11:08:02 +01:00
roberto@debian64 e161ea3f0a another fix for locking 2012-02-02 11:04:51 +01:00
roberto@debian64 fb827a274b started porting rack plugin to the new options api 2012-02-02 10:29:31 +01:00
roberto@debian64 7281318ef6 fixed bug #79 2012-02-02 10:20:57 +01:00
roberto@debian64 80be7385ed fixed locking 2012-02-02 09:59:48 +01:00
roberto@debian64 8913dda413 added uwsgi_tmpname() 2012-02-02 09:07:39 +01:00
roberto@debian64 b8ad90104b another series of fastrouter patches 2012-02-02 09:01:53 +01:00
roberto@debian64 2646109986 ported --fastrouter option 2012-02-02 08:56:47 +01:00
roberto@oneiric64 cf247c828a fixed emperor reload in lazy mode 2012-02-01 17:53:50 +01:00
roberto@debian64 28106e624e fixed http protocol bug 2012-02-01 16:41:50 +01:00
roberto@debian64 30e8420342 added --cheaper-overload 2012-02-01 16:07:29 +01:00
roberto@debian64 99e4d55e9b ported pthread mutex to the new api 2012-02-01 15:32:33 +01:00
roberto@goyle f9daec9e43 implementation of lock detector 2012-02-01 14:30:26 +01:00
roberto@goyle 68a2902ce3 fixed readlink in binary path 2012-01-31 11:46:30 +01:00
roberto@goyle 4b2db3de57 started revamp of the JVM plugin 2012-01-31 11:15:05 +01:00
roberto@goyle c4c526df17 fixed gateways in non-master mode 2012-01-31 11:03:19 +01:00
roberto@goyle 15ad5531b0 another series of updates 2012-01-31 10:54:29 +01:00
roberto@goyle c0af1c1094 ported rrdtool plugin 2012-01-31 10:44:28 +01:00
roberto@goyle 9b89333244 ported lua 2012-01-31 10:40:38 +01:00
roberto@goyle 1863030078 ported ping and nagios 2012-01-31 10:38:44 +01:00
roberto@goyle 15055ffa0d ported psgi to the new api 2012-01-31 10:31:46 +01:00
roberto@oneiric64 8391ce28f7 ported max vars to new options api 2012-01-30 11:09:59 +01:00
roberto@oneiric64 b38791a357 ported chmod-socket to new options api 2012-01-30 10:46:20 +01:00
roberto@oneiric64 53ba043168 ported logdate to new options api 2012-01-30 10:37:44 +01:00
roberto@oneiric64 d46a8dba7b ported snmp to new options api 2012-01-30 10:26:28 +01:00
roberto@oneiric64 1e62afc161 ported zerg to new options api 2012-01-30 09:33:59 +01:00
roberto@oneiric64 03cf6e868f ported mule subsystem to the new options api 2012-01-30 08:26:30 +01:00
roberto@oneiri64 e1da28ccc3 ported static file serving to the new options api 2012-01-30 08:21:04 +01:00
roberto@oneiric64 4173ca36cb ported map-socket to the new api 2012-01-30 08:05:52 +01:00
roberto@oneiric64 c393de492d ported ksm 2012-01-29 08:53:08 +01:00
roberto@oneiric64 f9a716d70f fixed dynamic options 2012-01-29 08:51:45 +01:00
roberto@oneiric64 2e8655c203 ported pidfile signal to the new api 2012-01-29 08:49:07 +01:00
roberto@oneiric64 42b7164f33 ported sqlite3 to the new api 2012-01-29 08:21:33 +01:00
roberto@oneiric64 602d49b045 ported cap/unshare to the new api 2012-01-29 08:04:05 +01:00
roberto@oneiric64 58a67df534 ported uid/gid to new api 2012-01-29 07:59:56 +01:00
roberto@oneiric64 de6cc04685 added exec:// facility 2012-01-29 07:52:39 +01:00
roberto@oneiric64 33763e074d ported spooler to the new options api 2012-01-28 17:40:24 +01:00
roberto@oneiric64 32b0f8efb6 ported queue and cache to new options api 2012-01-28 17:32:34 +01:00
roberto@oneiric64 644618963a another series of options porting 2012-01-28 17:14:49 +01:00
roberto@oneiric64 97ac31376e added --never-swap 2012-01-28 17:04:37 +01:00
roberto@oneiric64 e5ec0f0221 even simpler options hook 2012-01-28 16:37:20 +01:00
roberto@oneiric64 5875ddc355 refactored first part of clustering 2012-01-28 15:42:50 +01:00
roberto@oneiric64 f7d5f4692d another series of options ported to the new api 2012-01-28 15:14:41 +01:00
roberto@oneiric64 d85bc64aa9 ported uwsgi_help to the new api 2012-01-28 09:29:57 +01:00
roberto@oneiric64 a18ed0503c implemented flag subsystem for options 2012-01-28 08:57:17 +01:00
roberto@oneiric64 77a4e3771b ported plugin loading to the new api 2012-01-28 07:40:20 +01:00
roberto@oneiric64 7523eb1cb0 ported short options to new api 2012-01-27 19:37:37 +01:00
roberto@oneiric64 46f8ee9410 ported xml config to new option/help api 2012-01-27 18:24:55 +01:00
roberto@oneiric64 f0aa9f9fd2 another part of options refactoring 2012-01-27 17:54:31 +01:00
roberto@oneiric64 73d5cadd8c massive refactoring of options management (broken, do not use this rev) 2012-01-27 16:30:00 +01:00
roberto@oneiric64 1a0e2076d5 restore termios on exit (if required) 2012-01-25 07:19:25 +01:00
roberto@oneiric64 6db3dab5ea added --pyshell-oneshot 2012-01-25 06:32:02 +01:00
roberto@oneiric64 20856549c1 fixed a double free in spooler 2012-01-24 21:33:24 +01:00
roberto@oneiric64 d570845592 fixed sigquit/sigint in hijacked mode 2012-01-24 21:13:24 +01:00
roberto@oneiric64 eed27c0aac implemented rack.input.gets and expect-continue in http router 2012-01-24 21:11:17 +01:00
roberto@oneiric64 daef139496 added --http-manage-expect 2012-01-24 18:57:29 +01:00
roberto@oneiric64 3690d836b0 another refactoring of corerouter 2012-01-23 17:36:59 +01:00
roberto@oneiric64 93faeb4177 first round of common code base for routers 2012-01-23 16:04:10 +01:00
roberto@oneiric64 095b9154e0 fixed signal handling in gateways 2012-01-23 12:33:57 +01:00
roberto@oneiric64 f86aa55220 destructive commit for http and fastrouter plugins 2012-01-23 12:13:05 +01:00
roberto@oneiric64 40f7aecbba fixed a race condition in SIGINT/SIGQUIT 2012-01-22 17:55:09 +01:00
roberto@oneiric64 5d9d67caa4 preliminary refactoring for multithreaded fastrouter/removed fastfuncs support 2012-01-22 11:48:13 +01:00
roberto@oneiric64 0f00d6fb23 added --fastrouter-post-buffering-dir 2012-01-21 17:36:15 +01:00
roberto@oneiric64 61b0e68641 added UWSGI_POSTFILE 2012-01-21 04:26:02 +01:00
roberto@oneiric64 6ed38ced3c preliminary infrastructure for fastrouter buffering 2012-01-21 03:02:09 +01:00
roberto@app2 7a681a97b5 added --exec-in-jail 2012-01-20 16:55:54 +00:00
roberto@app2 41008fa594 fix a bunch of spooler issue 2012-01-20 15:16:47 +00:00
roberto@oneiric64 fb13084b87 applied patch #76 by prymitive 2012-01-20 10:59:39 +01:00
roberto@oneiric64 3f9023281e added --exec-pre-jail and --exec-post-jail 2012-01-20 09:18:18 +01:00
roberto@oneiric64 4e21fe6607 fix uwsgi.atexit when threading mode is enabled 2012-01-18 05:01:22 +01:00
roberto@oneiric64 7a95c726cd segmentation fault manager (linux only) 2012-01-15 04:33:19 +01:00
roberto@oneiric64 940401e0f8 second round of multispooler patches 2012-01-14 06:56:11 +01:00
roberto@oneiric64 86bfb20903 applied first part of multispooler patch 2012-01-14 06:00:33 +01:00
roberto@oneiric64 e21cf87285 fixed atexit 2012-01-13 04:26:20 +01:00
roberto@oneiric64 65f1445b64 bumped to 1.1 and added uwsgi.atexit 2012-01-12 19:25:54 +01:00
roberto@oneiric64 f87761d092 fix for invalid --http address 2012-01-11 11:14:31 +01:00
roberto@oneiric64 0c712ac28d added --no-harakiri-arh 2012-01-11 05:05:15 +01:00
roberto@oneiric64 db301531d0 added uwsgi.after_req_hook 2012-01-10 20:30:46 +01:00
roberto@oneiric64 4c82a72fd5 FreeBSD9 fix 2012-01-10 19:08:00 +01:00
roberto@oneiric64 7417e582c3 a fix for subscription system 2012-01-10 18:06:46 +01:00
roberto@oneiric64 e32564c7b2 added --fastrouter-harakiri 2012-01-10 15:58:49 +01:00
roberto@oneiric64 798bc482dc fixed a leak in cgi plugin 2012-01-10 14:00:36 +01:00
roberto@oneiric64 c7e7f756bc do not build netlink support by default 2012-01-10 13:43:13 +01:00
roberto@oneiric64 24358701f7 added Roy to contributors 2012-01-06 22:03:29 +01:00
roberto@netbsd64 f1e392c0a0 added support for post_buffering in cgi plugin 2012-01-06 22:57:58 +01:00
roberto@netbsd64 5e8d38d8bc support body_as_file in cgi plugin 2012-01-06 22:21:08 +01:00
roberto@oneiric64 4650d2edbb added support for indexed cgi vars 2012-01-06 19:36:42 +01:00
roberto@oneiric64 b153033514 fixed PATH_INFO and SCRIPT_NAME in cgi plugin 2012-01-06 18:23:07 +01:00
roberto@netbsd64 6dcbce5eb7 added binary detection for NetBSD 2012-01-05 22:47:50 +01:00
roberto@oneiric64 4ceeab439a fixed a typo 2012-01-05 21:14:45 +01:00
roberto@oneiric64 8b1a6be9da various realpath fixes 2012-01-05 21:10:02 +01:00
roberto@netbsd64 baeb864075 fixed #70 2012-01-05 21:28:47 +01:00
roberto@netbsd64 c88e1c3619 realpath on BSD is different from Linux/Solaris/OSX 2012-01-05 21:25:21 +01:00
roberto@oneiric64 1b04df7c5e Added tag 1.0.1 for changeset 8fe7bb792399 2012-01-03 17:12:16 +01:00
roberto@oneiric64 237f11dba3 fixed http protocol post optimization 2012-01-03 13:44:53 +01:00
roberto@oneiric64 313f1c2f29 make some gcc OSX version happy 2012-01-02 16:53:06 +01:00
roberto@oneiric64 f0862f3bc7 Added tag 1.0 for changeset 3c7092733585 2011-12-30 08:25:31 +01:00
roberto@oneiric64 1a8850ffe5 fixed cache monitor 2011-12-28 19:36:34 +01:00
roberto@genesi e640f812ba added cache monitor from Riccardo Magliocchetti in contrib/ 2011-12-28 04:32:21 +01:00
roberto@genesi 75ea170472 report hostname in welcome.py 2011-12-27 12:18:32 +01:00
roberto@debian32 1b14b1926e dded changelog for 1.0 2011-12-27 08:18:32 +01:00
roberto@oneiric64 edaed7ab01 fixed x-accel-redirect (temp workaround) 2011-12-26 08:26:14 +01:00
roberto@oneiric64 6cceece3d7 (really) fixed fibers plugin 2011-12-26 08:18:01 +01:00
roberto@oneiric64 2add03edb8 closed bug #67 2011-12-25 23:09:54 +01:00
roberto@oneiric64 7aab9bae51 report tiem delta in idle mode 2011-12-24 11:15:18 +01:00
roberto@oneiric64 46c2c1d885 moved version string to 1.0 2011-12-23 17:47:54 +01:00
roberto@oneiric64 544e97fac0 do not export original-proc-name in uwsgi.opt 2011-12-23 12:52:27 +01:00
roberto@oneiric64 265a700498 added --cheaper-step 2011-12-22 13:23:34 +01:00
roberto@oneiric64 a657b4b0aa Added tag 1.0-rc10 for changeset af490b8c30f8 2011-12-22 07:37:45 +01:00
roberto@oneiric64 ac97c8cf34 php plugin is now in beta 2011-12-21 15:46:23 +01:00
roberto@oneiric64 545f3ee608 gratily improved the php plugin 2011-12-21 15:00:14 +01:00
roberto@oneiric64 fcd1a36420 added --static-index 2011-12-21 11:02:36 +01:00
roberto@fiorenzo 47a8ab3da9 fixed fastrouter when nodes are on non-existent unix-socket 2011-12-21 11:00:45 +01:00
roberto@oneiric64 c4375a8e7a better ordering of options 2011-12-21 09:36:06 +01:00
roberto@oneiric64 a6c5bd3bb3 fixed optional-argument support 2011-12-21 07:56:19 +01:00
roberto@oneiric64 d53127e8cf fixed Makefile after php inclusion 2011-12-20 11:57:51 +01:00
roberto@oneiric64 851dd987ab added alpha-quality php plugin 2011-12-20 11:33:03 +01:00
roberto@goyle cf582af970 added --fastrouter-zerg 2011-12-19 09:37:46 +01:00
roberto@oneiric64 d0ec331b6b do not daemonize in emperor mode 2011-12-19 07:52:42 +01:00
roberto@oneiric64 cc75f5f7b3 fixed a stupid bug in emperor 2011-12-17 22:01:45 +01:00
roberto@oneiric64 3d08b7fdd0 added --cflags as build option 2011-12-17 14:02:52 +01:00
roberto@oneiric64 7a92449fc3 another binname improvement 2011-12-16 12:17:53 +01:00
roberto@oneiric64 4b3c34469d fixed bin-name implicit plugin loading 2011-12-16 11:51:07 +01:00
roberto@oneiric64 55bf34561e detect misusage of --rails 2011-12-16 06:49:04 +01:00
roberto@oneiric64 7e79dc0405 removed a debug line in uwsgidecorators 2011-12-15 09:21:17 +01:00
roberto@oneiric64 d3053523ab completed logging pluginization 2011-12-14 10:50:25 +01:00
roberto@oneiric64 e32185cc14 added --threaded-logger 2011-12-14 09:10:26 +01:00
roberto@oneiric64 8e3e3cf27b set level to 5 in graylog2 plugin 2011-12-13 20:42:39 +01:00
roberto@oneiric64 e2cea376e8 added rsyslog plugin 2011-12-13 20:33:17 +01:00
roberto@oneiric64 2a27b66d96 ported zeromq logging to the new api 2011-12-13 19:02:58 +01:00
roberto@oneiric64 522717ca99 initial structure for logging plugins (post-1.0) 2011-12-13 18:21:23 +01:00
roberto@oneiric64 5ee106170b added contrib/cgi_python.c 2011-12-13 06:40:10 +01:00
roberto@oneiric64 d62f04a5a6 cgi loadlib 2011-12-13 06:25:18 +01:00
roberto@oneiric64 eefe5048b2 fixed threading in multiple apps 2011-12-12 17:41:49 +01:00
roberto@oneiric64 8f792fde2d export daemons infos in stats server 2011-12-12 15:15:15 +01:00
roberto@oneiric64 d8ef2d8300 added CLONE_NEWPID for future unshare() improvements 2011-12-12 13:11:50 +01:00
roberto@oneiric64 e69dd5cb6a remove unshare call() on older kernels 2011-12-12 12:54:25 +01:00
roberto@oneiric64 8acd57d87e Added tag 1.0-rc9 for changeset 5da6fe43a8c2 2011-12-12 12:03:39 +01:00
476 changed files with 65509 additions and 31676 deletions
+9
View File
@@ -0,0 +1,9 @@
*.o
*.py[co]
*.class
*.jar
/uwsgi
/uwsgibuild.*
/t/ring/target
+16
View File
@@ -40,3 +40,19 @@ fb168b0b86169219aa9b8e40f0caa6297cf34dbc 0.9.9-rc1
a2b8f25fd17ed7424d1470a287d0b3144d2a12c8 1.0-rc6
a3ca2e8e27c5c12c44ba0cacb4de4cb51377f184 1.0-rc7
365e2514cc19f0366365318f12a1d63113b02924 1.0-rc8
5da6fe43a8c29056bc9442c684615e11a3699795 1.0-rc9
af490b8c30f83bc5fb6f3837a760981474647755 1.0-rc10
3c70927335856883283fe4db448e092cecc0ccdb 1.0
8fe7bb792399cb6e6a24e20551f4149409660363 1.0.1
1d1702789710ec1c20613d2490b14f70756e67ec 1.1-rc1
901f0cb5de36ea907b26d64ac9ce54605ec531d2 1.1-rc2
ede5c664978bb40e476e8d4a5789562928f28507 1.1-rc3
ef99144291f06822d026e981d5d856cbec14d867 1.1-rc4
e1568fd16b7b586cc72deb4dfccbbe64ae0b84df 1.1
24c8fe5a26e557db41cf1cee45b8964d5885e484 1.2-rc1
29de0fb320bc0a1ce84972f9f249360e315d3c10 1.2-rc2
c3cdecbf2bac591336baddd14f9ac22e18d6e200 1.2
14524da00a8b382dffb1d16a0e70cdf4a946f369 1.3-rc2
883b946db9038372cb1d76cb1d328a3093140e7b 1.3-rc3
aeea5a5d2e8b62ad55e23d539e1be02f2b6962af 1.3-rc4
620e0cb6ccdb0ce27561b4240cb3a0ef4c3527fd 1.3
+44
View File
@@ -0,0 +1,44 @@
language: c
compiler:
- gcc
- clang
script:
- echo -e "\n\n>>> Building uWSGI binary"
- /usr/bin/python uwsgiconfig.py --build travis
- echo -e "\n\n>>> Building python26 plugin"
- /usr/bin/python2.6 -V
- /usr/bin/python2.6 uwsgiconfig.py --plugin plugins/python base python26
- echo -e "\n\n>>> Building python27 plugin"
- /usr/bin/python2.7 -V
- /usr/bin/python2.7 uwsgiconfig.py --plugin plugins/python base python27
- echo -e "\n\n>>> Building python31 plugin"
- /usr/bin/python3.1 -V
- /usr/bin/python3.1 uwsgiconfig.py --plugin plugins/python base python31
- echo -e "\n\n>>> Building python32 plugin"
- /usr/bin/python3.2 -V
- /usr/bin/python3.2 uwsgiconfig.py --plugin plugins/python base python32
- echo -e "\n\n>>> Building python33 plugin"
- /usr/bin/python3.3 -V
- /usr/bin/python3.3 uwsgiconfig.py --plugin plugins/python base python33
- echo -e "\n\n>>> Building rack 1.8.7 plugin"
- /usr/bin/ruby1.8 -v
- UWSGICONFIG_RUBYPATH=/usr/bin/ruby1.8 /usr/bin/python uwsgiconfig.py --plugin plugins/rack base rack187
- echo -e "\n\n>>> Building rack 1.9.1 plugin"
- /usr/bin/ruby1.9.1 -v
- UWSGICONFIG_RUBYPATH=/usr/bin/ruby1.9.1 /usr/bin/python uwsgiconfig.py --plugin plugins/rack base rack191
- echo -e "\n\n>>> Building cgi plugin"
- /usr/bin/python uwsgiconfig.py --plugin plugins/cgi base
- echo -e "\n\n>>> Building dummy plugin"
- /usr/bin/python uwsgiconfig.py --plugin plugins/dummy base
- echo -e "\n\n>>> Building done, starting tests"
- ./tests/travis.sh
before_install:
- sudo add-apt-repository -y ppa:fkrull/deadsnakes
- sudo apt-get update -qq
- sudo apt-get install -qqyf python2.6-dev python2.7-dev python3.1-dev python3.2-dev python3.3-dev rubygems1.8 ruby1.8-dev ruby1.9.1-dev
- sudo apt-get install -qqyf libxml2-dev libpcre3-dev libcap2-dev
- sudo apt-get install -qqyf curl
+5
View File
@@ -17,3 +17,8 @@ Charles Duffy
Lukas Lalinsky
Steven Fernandez
Łukasz Mierzwa
Roy Marples
Aarni Koskela
C Anthony Risinger
Stephen Pierce
Mingli Yuan
-544
View File
@@ -1,544 +0,0 @@
*** 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
+3
View File
@@ -3,3 +3,6 @@ all:
clean:
python uwsgiconfig.py --clean
check:
python uwsgiconfig.py --check
-2
View File
@@ -1,2 +0,0 @@
all:
python2.4 uwsgiconfig.py --build
-2
View File
@@ -1,2 +0,0 @@
all:
python2.5 uwsgiconfig.py --build
-2
View File
@@ -1,2 +0,0 @@
all:
python2.6 uwsgiconfig.py --build
-2
View File
@@ -1,2 +0,0 @@
all:
python2.7 uwsgiconfig.py --build
-2
View File
@@ -1,2 +0,0 @@
all:
python3.0 uwsgiconfig.py --build
-2
View File
@@ -1,2 +0,0 @@
all:
python3.1 uwsgiconfig.py --build
-2
View File
@@ -1,2 +0,0 @@
all:
python3.2 uwsgiconfig.py --build
-2
View File
@@ -1,2 +0,0 @@
all:
python uwsgiconfig.py --build pylua
+1 -1
View File
@@ -1,3 +1,3 @@
surprise i am empty !
Look in the online documentation on http://projects.unbit.it/uwsgi/
Look in the online documentation on https://uwsgi-docs.readthedocs.org/en/latest/
+29 -2
View File
@@ -160,20 +160,35 @@ static int uwsgi_map_location(request_rec *r)
return DECLINED;
}
static void log_err(const char *file, int line, request_rec *r,
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
static void log_err(const char *file, int line, int ami, request_rec *r,
apr_status_t status, const char *msg)
{
ap_log_rerror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, status, r, "uwsgi: %s", msg);
#else
static void log_err(const char *file, int line, request_rec *r,
apr_status_t status, const char *msg)
{
ap_log_rerror(file, line, APLOG_ERR, status, r, "uwsgi: %s", msg);
#endif
}
static void log_debug(const char *file, int line, request_rec *r, const
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
static void log_debug(const char *file, int line, int ami, request_rec *r, const
char *msg)
{
/*
ap_log_rerror(file, line, APLOG_DEBUG, APR_SUCCESS, r, msg);
ap_log_rerror(file, line, APLOG_WARNING, APR_SUCCESS, r, "uwsgi: %s", msg);
*/
ap_log_rerror(file, line, APLOG_MODULE_INDEX, APLOG_DEBUG, APR_SUCCESS, r, "uwsgi: %s", msg);
#else
static void log_debug(const char *file, int line, request_rec *r, const
char *msg) {
ap_log_rerror(file, line, APLOG_DEBUG, APR_SUCCESS, r, "uwsgi: %s", msg);
#endif
}
/* buffered socket implementation (buckets are overkill) */
@@ -412,7 +427,11 @@ send_headers(request_rec *r, struct sockbuff *s)
apr_table_t *t;
apr_status_t rv = 0;
apr_port_t port = 0;
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
GET_PORT(port, r->useragent_addr);
#else
GET_PORT(port, r->connection->remote_addr);
#endif
uwsgi_cfg *cfg = our_dconfig(r);
log_debug(APLOG_MARK,r, "sending headers");
@@ -430,7 +449,11 @@ send_headers(request_rec *r, struct sockbuff *s)
add_header(t, "REQUEST_METHOD", (char *) r->method);
add_header(t, "QUERY_STRING", r->args ? r->args : "");
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
add_header(t, "SERVER_SOFTWARE", ap_get_server_description());
#else
add_header(t, "SERVER_SOFTWARE", ap_get_server_version());
#endif
add_header(t, "SERVER_ADMIN", r->server->server_admin);
add_header(t, "SERVER_NAME", (char *) ap_get_server_name(r));
add_header(t, "SERVER_PORT", apr_psprintf(r->pool, "%u",ap_get_server_port(r)));
@@ -438,7 +461,11 @@ send_headers(request_rec *r, struct sockbuff *s)
add_header(t, "SERVER_PROTOCOL", r->protocol);
add_header(t, "REQUEST_URI", original_uri(r));
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
add_header(t, "REMOTE_ADDR", r->useragent_ip);
#else
add_header(t, "REMOTE_ADDR", r->connection->remote_ip);
#endif
add_header(t, "REMOTE_PORT", apr_psprintf(r->pool, "%d", port));
add_header(t, "REMOTE_USER", r->user);
add_header(t, "DOCUMENT_ROOT", (char *) ap_document_root(r));
+464
View File
@@ -0,0 +1,464 @@
/*
*** mod_proxy_uwsgi ***
Copyright 2009-2013 Unbit S.a.s. <info@unbit.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
To build:
apxs2 -i -c mod_proxy_uwsgi.c
To use:
LoadModule proxy_uwsgi_module /usr/lib/apache2/modules/mod_proxy_uwsgi.so
ProxyPass / uwsgi://127.0.0.1:3031/
Docs:
http://uwsgi-docs.readthedocs.org/en/latest/Apache.html#mod-proxy-uwsgi
*/
#define APR_WANT_MEMFUNC
#define APR_WANT_STRFUNC
#include "apr_strings.h"
#include "apr_hooks.h"
#include "apr_optional_hooks.h"
#include "apr_buckets.h"
#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
#include "util_script.h"
#include "mod_proxy.h"
#define UWSGI_SCHEME "uwsgi"
#define UWSGI_DEFAULT_PORT 3031
module AP_MODULE_DECLARE_DATA proxy_uwsgi_module;
static int uwsgi_canon(request_rec *r, char *url)
{
char *host, sport[sizeof(":65535")];
const char *err, *path;
apr_port_t port = UWSGI_DEFAULT_PORT;
if (strncasecmp(url, UWSGI_SCHEME "://", sizeof(UWSGI_SCHEME) + 2)) {
return DECLINED;
}
url += sizeof(UWSGI_SCHEME); /* Keep slashes */
err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
if (err) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"error parsing URL %s: %s", url, err);
return HTTP_BAD_REQUEST;
}
apr_snprintf(sport, sizeof(sport), ":%u", port);
if (ap_strchr(host, ':')) { /* if literal IPv6 address */
host = apr_pstrcat(r->pool, "[", host, "]", NULL);
}
path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
r->proxyreq);
if (!path) {
return HTTP_BAD_REQUEST;
}
r->filename = apr_pstrcat(r->pool, "proxy:" UWSGI_SCHEME "://", host, sport, "/",
path, NULL);
return OK;
}
static int uwsgi_send(proxy_conn_rec *conn, const char *buf, apr_size_t length,
request_rec *r)
{
apr_status_t rv;
apr_size_t written;
while (length > 0) {
written = length;
if ((rv = apr_socket_send(conn->sock, buf, &written)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
"sending data to %s:%u failed",
conn->hostname, conn->port);
return HTTP_SERVICE_UNAVAILABLE;
}
/* count for stats */
conn->worker->s->transferred += written;
buf += written;
length -= written;
}
return OK;
}
/*
* Send uwsgi header block
*/
static int uwsgi_send_headers(request_rec *r, proxy_conn_rec *conn)
{
char *buf, *ptr;
const apr_array_header_t *env_table;
const apr_table_entry_t *env;
int j;
apr_size_t headerlen = 4;
uint16_t pktsize, keylen, vallen;
ap_add_common_vars(r);
ap_add_cgi_vars(r);
// this is not a security problem (in Linux) as uWSGI destroy the env memory area readable in /proc
// and generally if you host untrusted apps in your server and allows them to read others uid /proc/<pid>
// files you have higher problems...
const char *auth = apr_table_get(r->headers_in, "Authorization");
if (auth) {
apr_table_setn(r->subprocess_env, "HTTP_AUTHORIZATION", auth);
}
const char *script_name = apr_table_get(r->subprocess_env, "SCRIPT_NAME");
const char *path_info = apr_table_get(r->subprocess_env, "PATH_INFO");
if (script_name && path_info) {
if (strcmp(path_info, "/")) {
apr_table_set(r->subprocess_env, "SCRIPT_NAME", apr_pstrndup(r->pool, script_name, strlen(script_name)-strlen(path_info)));
}
else {
if (!strcmp(script_name, "/")) {
apr_table_set(r->subprocess_env, "SCRIPT_NAME", "");
}
}
}
env_table = apr_table_elts(r->subprocess_env);
env = (apr_table_entry_t *)env_table->elts;
for (j = 0; j < env_table->nelts; ++j) {
headerlen += 2 + strlen(env[j].key) + 2 + strlen(env[j].val) ;
}
ptr = buf = apr_palloc(r->pool, headerlen);
ptr+=4;
for (j = 0; j < env_table->nelts; ++j) {
keylen = strlen(env[j].key);
*ptr++= (uint8_t) (keylen & 0xff);
*ptr++= (uint8_t) ((keylen >> 8) & 0xff);
memcpy(ptr, env[j].key, keylen) ; ptr+=keylen;
vallen = strlen(env[j].val);
*ptr++= (uint8_t) (vallen & 0xff);
*ptr++= (uint8_t) ((vallen >> 8) & 0xff);
memcpy(ptr, env[j].val, vallen) ; ptr+=vallen;
}
pktsize = headerlen-4;
buf[0] = 0;
buf[1] = (uint8_t) (pktsize & 0xff);
buf[2] = (uint8_t) ((pktsize >> 8) & 0xff);
buf[3] = 0;
return uwsgi_send(conn, buf, headerlen, r);
}
static int uwsgi_send_body(request_rec *r, proxy_conn_rec *conn)
{
if (ap_should_client_block(r)) {
char *buf = apr_palloc(r->pool, AP_IOBUFSIZE);
int status;
apr_size_t readlen;
readlen = ap_get_client_block(r, buf, AP_IOBUFSIZE);
while (readlen > 0) {
status = uwsgi_send(conn, buf, readlen, r);
if (status != OK) {
return HTTP_SERVICE_UNAVAILABLE;
}
readlen = ap_get_client_block(r, buf, AP_IOBUFSIZE);
}
if (readlen == -1) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"receiving request body failed");
return HTTP_INTERNAL_SERVER_ERROR;
}
}
return OK;
}
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
static request_rec *ap_proxy_make_fake_req(conn_rec *c, request_rec *r)
{
apr_pool_t *pool;
request_rec *rp;
apr_pool_create(&pool, c->pool);
rp = apr_pcalloc(pool, sizeof(*r));
rp->pool = pool;
rp->status = HTTP_OK;
rp->headers_in = apr_table_make(pool, 50);
rp->subprocess_env = apr_table_make(pool, 50);
rp->headers_out = apr_table_make(pool, 12);
rp->err_headers_out = apr_table_make(pool, 5);
rp->notes = apr_table_make(pool, 5);
rp->server = r->server;
rp->log = r->log;
rp->proxyreq = r->proxyreq;
rp->request_time = r->request_time;
rp->connection = c;
rp->output_filters = c->output_filters;
rp->input_filters = c->input_filters;
rp->proto_output_filters = c->output_filters;
rp->proto_input_filters = c->input_filters;
rp->useragent_ip = c->client_ip;
rp->useragent_addr = c->client_addr;
rp->request_config = ap_create_request_config(pool);
proxy_run_create_req(r, rp);
return rp;
}
#endif
static int uwsgi_response(request_rec *r, proxy_conn_rec *backend, proxy_server_conf *conf)
{
char buffer[HUGE_STRING_LEN];
const char *buf;
char *value, *end;
int len;
apr_status_t rc;
conn_rec *c = r->connection;
apr_off_t readbytes;
apr_status_t rv;
apr_bucket *e;
apr_read_type_e mode = APR_NONBLOCK_READ;
request_rec *rp = ap_proxy_make_fake_req(backend->connection, r);
rp->proxyreq = PROXYREQ_RESPONSE;
apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc);
len = ap_getline(buffer, sizeof(buffer), rp, 1);
if (len <= 0) {
// oops
return HTTP_INTERNAL_SERVER_ERROR;
}
backend->worker->s->read += len;
if (!apr_date_checkmask(buffer, "HTTP/#.# ###*") || len >= sizeof(buffer)-1) {
// oops
return HTTP_INTERNAL_SERVER_ERROR;
}
char keepchar = buffer[12];
buffer[12] = '\0';
r->status = atoi(&buffer[9]);
if (keepchar != '\0') {
buffer[12] = keepchar;
} else {
/* 2616 requires the space in Status-Line; the origin
* server may have sent one but ap_rgetline_core will
* have stripped it. */
buffer[12] = ' ';
buffer[13] = '\0';
}
r->status_line = apr_pstrdup(r->pool, &buffer[9]);
// start parsing headers;
while ((len = ap_getline(buffer, sizeof(buffer), rp, 1)) > 0) {
value = strchr(buffer, ':');
// invalid header skip
if (!value) continue;
*value = '\0';
++value;
while (apr_isspace(*value)) ++value;
for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end) *end = '\0';
apr_table_add(r->headers_out, buffer, value);
}
if ((buf = apr_table_get(r->headers_out, "Content-Type"))) {
ap_set_content_type(r, apr_pstrdup(r->pool, buf));
}
for(;;) {
rv = ap_get_brigade(rp->input_filters, bb,
AP_MODE_READBYTES, mode,
conf->io_buffer_size);
if (APR_STATUS_IS_EAGAIN(rv)
|| (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb))) {
e = apr_bucket_flush_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
if (ap_pass_brigade(r->output_filters, bb) || c->aborted) {
break;
}
apr_brigade_cleanup(bb);
mode = APR_BLOCK_READ;
continue;
}
else if (rv == APR_EOF) {
break;
}
else if (rv != APR_SUCCESS) {
ap_proxy_backend_broke(r, bb);
ap_pass_brigade(r->output_filters, bb);
}
mode = APR_NONBLOCK_READ;
apr_brigade_length(bb, 0, &readbytes);
backend->worker->s->read += readbytes;
ap_pass_brigade(r->output_filters, bb);
apr_brigade_cleanup(bb);
}
e = apr_bucket_eos_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(r->output_filters, bb);
apr_brigade_cleanup(bb);
return OK;
}
static int uwsgi_handler(request_rec *r, proxy_worker *worker,
proxy_server_conf *conf, char *url,
const char *proxyname, apr_port_t proxyport)
{
int status;
proxy_conn_rec *backend = NULL;
apr_pool_t *p = r->pool;
apr_uri_t *uri = apr_palloc(r->pool, sizeof(*uri));
char server_portstr[32];
if (strncasecmp(url, UWSGI_SCHEME "://", sizeof(UWSGI_SCHEME) + 2)) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"declining URL %s", url);
return DECLINED;
}
// ADD PATH_INFO
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
size_t w_len = strlen(worker->s->name);
#else
size_t w_len = strlen(worker->name);
#endif
char *u_path_info = r->filename + 6 + w_len;
int delta = 0;
if (u_path_info[0] != '/') {
delta = 1;
}
int decode_status = ap_unescape_url(url+w_len-delta);
if (decode_status) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"unable to decode uri: %s",
url+w_len-delta);
return HTTP_INTERNAL_SERVER_ERROR;
}
apr_table_add(r->subprocess_env, "PATH_INFO", url+w_len-delta);
/* Create space for state information */
status = ap_proxy_acquire_connection(UWSGI_SCHEME, &backend, worker,
r->server);
if (status != OK) {
goto cleanup;
}
backend->is_ssl = 0;
/* Step One: Determine Who To Connect To */
status = ap_proxy_determine_connection(p, r, conf, worker, backend,
uri, &url, proxyname, proxyport,
server_portstr, sizeof(server_portstr));
if (status != OK) {
goto cleanup;
}
/* Step Two: Make the Connection */
if (ap_proxy_connect_backend(UWSGI_SCHEME, backend, worker, r->server)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"failed to make connection to backend: %s:%u",
backend->hostname, backend->port);
status = HTTP_SERVICE_UNAVAILABLE;
goto cleanup;
}
/* Step Three: Create conn_rec */
if (!backend->connection) {
if ((status = ap_proxy_connection_create(UWSGI_SCHEME, backend,
r->connection, r->server)) != OK)
goto cleanup;
}
/* Step Four: Process the Request */
if ( ((status = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK)
|| ((status = uwsgi_send_headers(r, backend)) != OK)
|| ((status = uwsgi_send_body(r, backend)) != OK)
|| ((status = uwsgi_response(r, backend, conf)) != OK)) {
goto cleanup;
}
cleanup:
if (backend) {
backend->close = 1; /* always close the socket */
ap_proxy_release_connection(UWSGI_SCHEME, backend, r->server);
}
return status;
}
static void register_hooks(apr_pool_t *p)
{
proxy_hook_scheme_handler(uwsgi_handler, NULL, NULL, APR_HOOK_FIRST);
proxy_hook_canon_handler(uwsgi_canon, NULL, NULL, APR_HOOK_FIRST);
}
module AP_MODULE_DECLARE_DATA proxy_uwsgi_module = {
STANDARD20_MODULE_STUFF,
NULL, /* create per-directory config structure */
NULL, /* merge per-directory config structures */
NULL, /* create per-server config structure */
NULL, /* merge per-server config structures */
NULL, /* command table */
register_hooks /* register hooks */
};
+29 -3
View File
@@ -2,7 +2,7 @@
*** uWSGI/mod_uwsgi ***
Copyright 2009-2011 Unbit S.a.s. <info@unbit.it>
Copyright 2009-2013 Unbit S.a.s. <info@unbit.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -37,11 +37,18 @@ LoadModule uwsgi_module <path_of_apache_modules>/mod_uwsgi.so
*/
#include <unistd.h>
#include <ctype.h>
#include "apr_strings.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "httpd.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_config.h"
#include "http_log.h"
#include "util_script.h"
#include <sys/socket.h>
#include <sys/un.h>
@@ -346,7 +353,11 @@ static int uwsgi_handler(request_rec *r) {
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SERVER_PORT", apr_psprintf(r->pool, "%u",ap_get_server_port(r)), &pkt_size) ;
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "SERVER_PROTOCOL", r->protocol, &pkt_size) ;
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REQUEST_URI", r->unparsed_uri, &pkt_size) ;
#if AP_MODULE_MAGIC_AT_LEAST(20111130,0)
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REMOTE_ADDR", r->useragent_ip, &pkt_size) ;
#else
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REMOTE_ADDR", r->connection->remote_ip, &pkt_size) ;
#endif
//
if (r->user) {
@@ -356,7 +367,7 @@ static int uwsgi_handler(request_rec *r) {
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "REMOTE_USER", "", &pkt_size) ;
}
if (r->user) {
if (ap_auth_type(r) != NULL) {
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "AUTH_TYPE", (char *) ap_auth_type(r), &pkt_size) ;
}
vecptr = uwsgi_add_var(uwsgi_vars, vecptr, r, "DOCUMENT_ROOT", (char *) ap_document_root(r), &pkt_size) ;
@@ -506,7 +517,22 @@ static int uwsgi_handler(request_rec *r) {
free(uwsgi_vars);
return HTTP_INTERNAL_SERVER_ERROR;
}
apr_brigade_write(bb, NULL, NULL, buf, cnt);
if (!c->cgi_mode) {
b = apr_bucket_transient_create(buf, cnt, r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);
b = apr_bucket_flush_create(r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);
if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS) {
close(uwsgi_poll.fd);
apr_brigade_destroy(bb);
free(uwsgi_vars);
return HTTP_INTERNAL_SERVER_ERROR;
}
apr_brigade_cleanup(bb);
}
else {
apr_brigade_write(bb, NULL, NULL, buf, cnt);
}
}
else {
// EOF
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env ruby
cmd = File.expand_path "#{File.dirname(__FILE__)}/../ext/uwsgi/uwsgi.ruby"
exec(cmd, *ARGV)
-1
View File
@@ -1 +0,0 @@
object file for embedded files will be put here
+34
View File
@@ -0,0 +1,34 @@
[uwsgi]
xml = auto
yaml = true
json = auto
sqlite3 = auto
zeromq = auto
ssl = auto
ldap = auto
pcre = auto
routing = auto
debug = false
unbit = false
xml_implementation = libxml2
yaml_implementation = auto
malloc_implementation = libc
extras =
plugins =
bin_name = uwsgi
append_version =
plugin_dir = .
embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter
as_shared_library = false
locking = auto
event = auto
timer = auto
filemonitor = auto
blacklist =
whitelist =
embed_files =
embed_config =
+3
View File
@@ -0,0 +1,3 @@
[uwsgi]
main_plugin = cgi
inherit = base
+2 -1
View File
@@ -1,3 +1,4 @@
[uwsgi]
inherit = default
main_plugin =
inherit = base
embedded_plugins = null
+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
+2 -43
View File
@@ -1,44 +1,3 @@
[uwsgi]
xml = true
ini = true
yaml = true
json = auto
sqlite3 = auto
zeromq = auto
snmp = true
sctp = false
spooler = true
embedded = true
udp = true
multicast = true
threading = true
sendfile = true
minterpreters = true
async = true
evdis = false
ldap = auto
pcre = auto
debug = false
unbit = false
xml_implementation = libxml2
yaml_implementation = auto
malloc_implementation = libc
plugins =
bin_name = uwsgi
append_version =
plugin_dir = .
embedded_plugins = python, ping, cache, nagios, rrdtool, carbon, rpc, fastrouter, http, ugreen, signal
as_shared_library = false
locking = auto
event = auto
timer = auto
filemonitor = auto
embed_files =
embed_config =
[python]
paste = true
web3 = true
main_plugin = python,gevent
inherit = base
+2 -1
View File
@@ -1,3 +1,4 @@
[uwsgi]
inherit = default
main_plugin = python
inherit = base
embed_files = bootstrap3.py,django.zip,djapp.zip
+2 -1
View File
@@ -1,4 +1,5 @@
[uwsgi]
inherit = default
main_plugin = python
inherit = base
embed_files = embedme.py,uwsgidecorators.py
+2 -2
View File
@@ -1,3 +1,3 @@
[uwsgi]
inherit = default
embedded_plugins = +,erlang
main_plugin = erlang
inherit = base
+2 -2
View File
@@ -1,3 +1,3 @@
[uwsgi]
inherit = default
embedded_plugins = python, ping, cache, nagios, rpc, fastrouter, http, gevent
main_plugin = python,gevent
inherit = base
+5
View File
@@ -0,0 +1,5 @@
[uwsgi]
main_plugin = go
inherit = base
bin_name = libuwsgi.so
as_shared_library = true
+3
View File
@@ -0,0 +1,3 @@
[uwsgi]
main_plugin = jvm,jwsgi
inherit = base
+1 -1
View File
@@ -1,5 +1,5 @@
[uwsgi]
inherit = default
inherit = base
bin_name = libuwsgi.so
embedded_plugins = null
as_shared_library = true
+2 -2
View File
@@ -1,3 +1,3 @@
[uwsgi]
inherit = default
embedded_plugins = lua
main_plugin = lua
inherit = base
+2 -1
View File
@@ -1,3 +1,4 @@
[uwsgi]
inherit = default
main_plugin =
inherit = base
plugins = lua
+1 -1
View File
@@ -1,5 +1,5 @@
[uwsgi]
inherit = default
inherit = base
plugins = python, ping, rack, psgi, cache, http, fastrouter
plugin_dir = plugins
embedded_plugins = null
+3
View File
@@ -0,0 +1,3 @@
[uwsgi]
main_plugin = mono
inherit = base
+2 -2
View File
@@ -1,4 +1,4 @@
[uwsgi]
inherit = default
inherit = base
plugin_dir = /usr/lib/uwsgi
embedded_plugins = null
embedded_plugins =
+3
View File
@@ -0,0 +1,3 @@
[uwsgi]
main_plugin = php
inherit = base
+34
View File
@@ -0,0 +1,34 @@
[uwsgi]
xml = true
yaml = true
json = true
sqlite3 = true
zeromq = true
ssl = true
ldap = true
pcre = true
routing = true
debug = false
unbit = false
xml_implementation = libxml2
yaml_implementation = libyaml
malloc_implementation = libc
extras =
plugins =
bin_name = /usr/lib/libuwsgi.so
append_version = ubuntu
plugin_dir = /usr/lib/uwsgi
embedded_plugins =
as_shared_library = true
locking = auto
event = auto
timer = auto
filemonitor = auto
blacklist =
whitelist =
embed_files =
embed_config =
+2 -2
View File
@@ -1,3 +1,3 @@
[uwsgi]
inherit = default
embedded_plugins = psgi
main_plugin = psgi
inherit = base
+2 -2
View File
@@ -1,3 +1,3 @@
[uwsgi]
inherit = default
embedded_plugins = +,erlang,pyerl
main_plugin = python,erlang,pyerl
inherit = base
+2 -2
View File
@@ -1,3 +1,3 @@
[uwsgi]
inherit = default
embedded_plugins = +,lua
main_plugin = python,lua
inherit = base
+2 -4
View File
@@ -1,5 +1,3 @@
[uwsgi]
inherit = default
bin_name = libuwsgi.so
embedded_plugins = symcall
as_shared_library = true
main_plugin = pypy
inherit = base
-31
View File
@@ -1,31 +0,0 @@
[uwsgi]
xml = true
ini = true
snmp = true
sctp = false
erlang = false
spooler = true
embedded = true
udp = true
multicast = true
threading = true
sendfile = true
proxy = true
minterpreters = true
async = true
http = true
evdis = false
ldap = false
routing = false
stackless = false
debug = false
unbit = false
xml_implementation = libxml2
plugins =
bin_name = uwsgi
plugin_dir = .
embedded_plugins = python, ping, nagios, rack
[python]
paste = true
web3 = true
+6
View File
@@ -0,0 +1,6 @@
[uwsgi]
main_plugin = python,gevent
inherit = base
plugins = jvm,ring
plugin_dir = .
+2 -2
View File
@@ -1,5 +1,5 @@
[uwsgi]
inherit = default
main_plugin = pyuwsgi
inherit = base
bin_name = pyuwsgi.so
embedded_plugins = pyuwsgi,python,ping,cache,nagios,rpc,ugreen
as_shared_library = true
+2 -2
View File
@@ -1,3 +1,3 @@
[uwsgi]
inherit = default
embedded_plugins = rack, ping, cache, nagios, rpc, fastrouter, http, ugreen
main_plugin = rack
inherit = base
-30
View File
@@ -1,30 +0,0 @@
[uwsgi]
xml = true
ini = true
yaml = true
snmp = true
sctp = false
erlang = false
spooler = false
embedded = false
udp = true
multicast = false
threading = true
sendfile = true
nagios = true
proxy = true
minterpreters = true
async = true
ugreen = false
http = true
evdis = false
ldap = false
routing = false
stackless = false
debug = false
unbit = false
xml_implementation = libxml2
plugins = rack
bin_name = uwsgi
plugin_dir = .
embedded_plugins =
+3
View File
@@ -0,0 +1,3 @@
[uwsgi]
main_plugin = jvm,ring
inherit = base
+3
View File
@@ -0,0 +1,3 @@
[uwsgi]
main_plugin =
inherit = base
+17 -18
View File
@@ -1,35 +1,34 @@
[uwsgi]
xml = true
ini = true
yaml = true
json = true
json = false
sqlite3 = false
zeromq = false
snmp = false
sctp = false
spooler = true
embedded = true
udp = true
multicast = false
threading = true
sendfile = true
minterpreters = true
async = true
evdis = false
ldap = true
pcre = false
ssl = true
ldap = false
pcre = true
routing = true
debug = false
unbit = true
xml_implementation = libxml2
xml_implementation = expat
yaml_implementation = auto
malloc_implementation = libc
extras =
plugins =
bin_name = /opt/unbit/bin/uwsgi
bin_name = /opt/unbit/uwsgi19/lib/libuwsgi.so
append_version = unbit
plugin_dir = /opt/unbit/uwsgi_plugins
plugin_dir = /opt/unbit/uwsgi19/plugins
embedded_plugins =
as_shared_library = true
locking = auto
event = auto
timer = auto
filemonitor = auto
blacklist =
whitelist =
embed_files =
embed_config =
-1
View File
@@ -1,6 +1,5 @@
[uwsgi]
inherit = unbit
json = false
embedded_plugins = python
bin_name = ../bin/uwsgi
plugin_dir = ../bin/uwsgi_plugins
-419
View File
@@ -1,419 +0,0 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
void uwsgi_init_cache() {
int i;
if (!uwsgi.cache_blocksize)
uwsgi.cache_blocksize = UMAX16;
uwsgi.cache_hashtable = (uint64_t *) mmap(NULL, sizeof(uint64_t) * UMAX16, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!uwsgi.cache_hashtable) {
uwsgi_error("mmap()");
exit(1);
}
memset(uwsgi.cache_hashtable, 0, sizeof(uint64_t) * UMAX16);
uwsgi.cache_unused_stack = (uint64_t *) mmap(NULL, sizeof(uint64_t) * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!uwsgi.cache_unused_stack) {
uwsgi_error("mmap()");
exit(1);
}
memset(uwsgi.cache_unused_stack, 0, sizeof(uint64_t) * uwsgi.cache_max_items);
// the first cache item is always zero
uwsgi.shared->cache_first_available_item = 1;
uwsgi.shared->cache_unused_stack_ptr = 0;
//uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (uwsgi.cache_store) {
uwsgi.cache_filesize = (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items);
int cache_fd;
struct stat cst;
if (stat(uwsgi.cache_store, &cst)) {
uwsgi_log("creating a new cache store file: %s\n", uwsgi.cache_store);
cache_fd = open(uwsgi.cache_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (cache_fd >= 0) {
// fill the caching store
if (ftruncate(cache_fd, uwsgi.cache_filesize)) {
uwsgi_log("ftruncate()");
exit(1);
}
}
}
else {
if ((size_t) cst.st_size != uwsgi.cache_filesize || !S_ISREG(cst.st_mode)) {
uwsgi_log("invalid cache store file. Please remove it or fix cache blocksize/items to match its size\n");
exit(1);
}
cache_fd = open(uwsgi.cache_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
uwsgi_log("recovered cache from backing store file: %s\n", uwsgi.cache_store);
}
if (cache_fd < 0) {
uwsgi_error_open(uwsgi.cache_store);
exit(1);
}
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, uwsgi.cache_filesize, PROT_READ | PROT_WRITE, MAP_SHARED, cache_fd, 0);
uwsgi_cache_fix();
}
else {
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
for (i = 0; i < (int) uwsgi.cache_max_items; i++) {
memset(&uwsgi.cache_items[i], 0, sizeof(struct uwsgi_cache_item));
}
}
if (!uwsgi.cache_items) {
uwsgi_error("mmap()");
exit(1);
}
/*
uwsgi.cache = mmap(NULL, uwsgi.cache_blocksize * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!uwsgi.cache) {
uwsgi_error("mmap()");
exit(1);
}
*/
uwsgi.cache = ((void *) uwsgi.cache_items) + (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items);
uwsgi.cache_lock = uwsgi_mmap_shared_rwlock();
uwsgi_rwlock_init(uwsgi.cache_lock);
uwsgi_log("*** Cache subsystem initialized: %dMB (key: %llu bytes, keys: %llu bytes, data: %llu bytes) preallocated ***\n", ((uwsgi.cache_blocksize * uwsgi.cache_max_items) + (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items)) / (1024 * 1024),
(unsigned long long) sizeof(struct uwsgi_cache_item), (unsigned long long) sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items, (unsigned long long) uwsgi.cache_blocksize * uwsgi.cache_max_items);
}
uint32_t djb33x_hash(char *key, int keylen) {
register uint32_t hash = 5381;
int i;
for(i=0;i<keylen;i++) {
hash = ((hash << 5) + hash) ^ key[i];
}
return hash;
}
inline uint64_t uwsgi_cache_get_index(char *key, uint16_t keylen) {
uint32_t hash = djb33x_hash(key, keylen);
int hash_key = hash % 0xffff;
uint64_t slot = uwsgi.cache_hashtable[hash_key];
struct uwsgi_cache_item *uci;
//uwsgi_log("found slot %d for key %d\n", slot, hash_key);
uci = &uwsgi.cache_items[slot];
// first round
if (uci->djbhash != hash) goto cycle;
if (uci->keysize != keylen) goto cycle;
if (memcmp(uci->key, key, keylen)) goto cycle;
return slot;
cycle:
while(uci->next) {
slot = uci->next;
uci = &uwsgi.cache_items[slot];
if (uci->djbhash != hash) continue;
if (uci->keysize != keylen) continue;
if (!memcmp(uci->key, key, keylen)) return slot;
}
return 0;
}
uint32_t uwsgi_cache_exists(char *key, uint16_t keylen) {
return uwsgi_cache_get_index(key, keylen);
}
char *uwsgi_cache_get(char *key, uint16_t keylen, uint64_t *valsize) {
uint64_t index = uwsgi_cache_get_index(key, keylen);
if (index) {
if (uwsgi.cache_items[index].flags & UWSGI_CACHE_FLAG_UNGETTABLE) return NULL;
*valsize = uwsgi.cache_items[index].valsize;
uwsgi.cache_items[index].hits++;
return uwsgi.cache+(index*uwsgi.cache_blocksize);
}
return NULL;
}
int uwsgi_cache_del(char *key, uint16_t keylen) {
uint64_t index = 0;
struct uwsgi_cache_item *uci;
int ret = -1;
index = uwsgi_cache_get_index(key, keylen);
if (index) {
uci = &uwsgi.cache_items[index] ;
uci->keysize = 0;
uci->valsize = 0;
uwsgi.shared->cache_unused_stack_ptr++;
uwsgi.cache_unused_stack[uwsgi.shared->cache_unused_stack_ptr] = index;
// try to return to initial condition...
if (index == uwsgi.shared->cache_first_available_item-1) {
uwsgi.shared->cache_first_available_item--;
//uwsgi_log("FACI: %llu STACK PTR: %llu\n", (unsigned long long) uwsgi.shared->cache_first_available_item, (unsigned long long) uwsgi.shared->cache_unused_stack_ptr);
}
ret = 0;
// relink collisioned entry
if (uci->prev) {
uwsgi.cache_items[uci->prev].next = uci->next;
}
if (uci->next) {
uwsgi.cache_items[uci->next].prev = uci->prev;
}
if (!uci->prev && !uci->next) {
// reset hashtable entry
//uwsgi_log("!!! resetted hashtable entry !!!\n");
uwsgi.cache_hashtable[uci->djbhash % 0xffff] = 0;
}
uci->djbhash = 0;
uci->prev = 0;
uci->next = 0;
}
return ret;
}
void uwsgi_cache_fix() {
uint64_t i;
for(i=0;i< uwsgi.cache_max_items;i++) {
// valid record ?
if (uwsgi.cache_items[i].keysize) {
if (!uwsgi.cache_items[i].prev) {
// put value in hash_table
uwsgi.cache_hashtable[ uwsgi.cache_items[i].djbhash % 0xffff] = i;
}
}
else {
// put this record in unused stack
uwsgi.shared->cache_first_available_item = i;
uwsgi.shared->cache_unused_stack_ptr++;
uwsgi.cache_unused_stack[uwsgi.shared->cache_unused_stack_ptr] = i;
}
}
}
int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint64_t expires, uint16_t flags) {
uint64_t index = 0, last_index = 0 ;
struct uwsgi_cache_item *uci, *ucii;
int ret = -1;
int slot;
if (!keylen || !vallen) return -1;
if (keylen > UWSGI_CACHE_MAX_KEY_SIZE) return -1;
if (uwsgi.shared->cache_first_available_item >= uwsgi.cache_max_items && !uwsgi.shared->cache_unused_stack_ptr) {
uwsgi_log("*** DANGER cache is FULL !!! ***\n");
goto end;
}
//uwsgi_log("putting cache data in key %.*s %d\n", keylen, key, vallen);
index = uwsgi_cache_get_index(key, keylen);
if (!index) {
if (uwsgi.shared->cache_unused_stack_ptr) {
//uwsgi_log("!!! REUSING CACHE SLOT !!! (faci: %llu)\n", (unsigned long long) uwsgi.shared->cache_first_available_item);
index = uwsgi.cache_unused_stack[uwsgi.shared->cache_unused_stack_ptr];
uwsgi.shared->cache_unused_stack_ptr--;
}
else {
index = uwsgi.shared->cache_first_available_item;
if (uwsgi.shared->cache_first_available_item < uwsgi.cache_max_items) {
uwsgi.shared->cache_first_available_item++;
}
}
uci = &uwsgi.cache_items[index] ;
if (expires) expires += time(NULL);
uci->expires = expires;
uci->djbhash = djb33x_hash(key, keylen);
uci->hits = 0;
uci->flags = flags;
memcpy(uci->key, key, keylen);
memcpy(uwsgi.cache+(index*uwsgi.cache_blocksize), val, vallen);
// set this as late as possibile (to reduce races risk)
uci->valsize = vallen;
uci->keysize = keylen;
ret = 0;
// now put the value in the 16bit hashtable
slot = uci->djbhash % 0xffff;
if (uwsgi.cache_hashtable[slot] == 0) {
uwsgi.cache_hashtable[slot] = index;
}
else {
//uwsgi_log("HASH COLLISION !!!!\n");
// append to first available next
last_index = uwsgi.cache_hashtable[slot];
ucii = &uwsgi.cache_items[ last_index ];
while(ucii->next) {
last_index = ucii->next;
ucii = &uwsgi.cache_items[ last_index ];
}
ucii->next = index;
uci->prev = last_index;
}
}
else if (flags & UWSGI_CACHE_FLAG_UPDATE) {
uci = &uwsgi.cache_items[index] ;
if (expires) {
expires += time(NULL);
uci->expires = expires;
}
memcpy(uwsgi.cache+(index*uwsgi.cache_blocksize), val, vallen);
uci->valsize = vallen;
ret = 0;
}
end:
return ret;
}
/* THIS PART IS HEAVILY OPTIMIZED: PERFORMANCE NOT ELEGANCE !!! */
void *cache_thread_loop(void *fd_ptr) {
int *fd_tmp = (int *) fd_ptr;
int fd = *fd_tmp;
int i;
ssize_t len;
char uwsgi_packet[UMAX16+4];
struct uwsgi_header *uh = (struct uwsgi_header *) uwsgi_packet;
char *val;
uint64_t vallen;
char *key;
uint16_t keylen;
struct pollfd ctl_poll;
char *watermark;
struct sockaddr_un ctl_sun;
socklen_t ctl_sun_len;
ctl_poll.events = POLLIN;
for(;;) {
ctl_sun_len = sizeof(struct sockaddr_un);
pthread_mutex_lock(&uwsgi.cache_server_lock);
ctl_poll.fd = accept(fd, (struct sockaddr *) &ctl_sun, &ctl_sun_len);
pthread_mutex_unlock(&uwsgi.cache_server_lock);
if (ctl_poll.fd < 0) {
uwsgi_error("cache accept()");
continue;
}
i = 0;
while(i < 4) {
len = poll(&ctl_poll, 1, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
if (len <= 0) {
uwsgi_error("cache poll()");
goto clear;
}
len = read(ctl_poll.fd, uwsgi_packet+i, 4-i);
if (len < 0) {
uwsgi_error("cache read()");
goto clear;
}
i+=len;
}
if (uh->pktsize == 0) goto clear;
while(i < 4+uh->pktsize) {
len = poll(&ctl_poll, 1, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
if (len <= 0) {
uwsgi_error("cache poll()");
goto clear;
}
len = read(ctl_poll.fd, uwsgi_packet+i, (4+uh->pktsize)-i);
if (len < 0) {
uwsgi_error("cache read()");
goto clear;
}
i+=len;
}
watermark = uwsgi_packet+4+uh->pktsize;
// get first parameter
memcpy(&keylen, uwsgi_packet+4, 2);
#ifdef __BIG_ENDIAN__
keylen = uwsgi_swap16(keylen);
#endif
if (uwsgi_packet+6+keylen > watermark) goto clear;
key = uwsgi_packet+6+keylen+2;
memcpy(&keylen, key-2, 2);
#ifdef __BIG_ENDIAN__
keylen = uwsgi_swap16(keylen);
#endif
if (key+keylen > watermark) goto clear;
val = uwsgi_cache_get(key, keylen, &vallen);
if (val && vallen > 0) {
if (write(ctl_poll.fd, val, vallen) < 0) {
uwsgi_error("cache write()");
}
}
clear:
close(ctl_poll.fd);
}
return NULL;
}
int uwsgi_cache_server(char *socket, int threads) {
int *fd = uwsgi_malloc(sizeof(int));
int i;
pthread_t thread_id;
char *tcp_port = strchr(socket, ':');
if (tcp_port) {
*fd = bind_to_tcp(socket, uwsgi.listen_queue, tcp_port);
}
else {
*fd = bind_to_unix(socket, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
}
pthread_mutex_init(&uwsgi.cache_server_lock, NULL);
if (threads < 1) threads = 1;
uwsgi_log("*** cache-optimized server enabled on fd %d (%d threads) ***\n", *fd, threads);
for(i=0;i<threads;i++) {
pthread_create(&thread_id, NULL, cache_thread_loop, (void *) fd);
}
return *fd;
}
-355
View File
@@ -1,355 +0,0 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
#ifdef UWSGI_UDP
void cluster_setup() {
int rlen;
// get cluster configuration
if (uwsgi.cluster != NULL) {
// get multicast socket
uwsgi.cluster_fd = uwsgi_cluster_join(uwsgi.cluster);
uwsgi_log("JOINED CLUSTER: %s\n", uwsgi.cluster);
// ask for cluster options only if bot pre-existent options are set
if (uwsgi.exported_opts_cnt == 1 && !uwsgi.cluster_nodes) {
// now wait max 60 seconds and resend multicast request every 10 seconds
for (;;) {
uwsgi_log("asking \"%s\" uWSGI cluster for configuration data:\n", uwsgi.cluster);
if (uwsgi_send_empty_pkt(uwsgi.cluster_fd, uwsgi.cluster, 99, 0) < 0) {
uwsgi_log("unable to send multicast message to %s\n", uwsgi.cluster);
continue;
}
waitfd:
rlen = uwsgi_waitfd(uwsgi.cluster_fd, 10);
if (rlen < 0) {
break;
}
else if (rlen > 0) {
// receive the packet
char clusterbuf[4096];
if (!uwsgi_hooked_parse_dict_dgram(uwsgi.cluster_fd, clusterbuf, 4096, 99, 1, manage_string_opt, NULL)) {
uwsgi_configure();
goto options_parsed;
}
else {
goto waitfd;
}
}
}
}
options_parsed:
if (!uwsgi.cluster_nodes)
uwsgi_cluster_add_me();
}
}
void uwsgi_cluster_add_node(struct uwsgi_cluster_node *nucn, int type) {
int i;
struct uwsgi_cluster_node *ucn;
char *tcp_port;
#ifdef UWSGI_DEBUG
uwsgi_log("adding node\n");
#endif
tcp_port = strchr(nucn->name, ':');
#ifndef UWSGI_ZEROMQ
if (tcp_port == NULL) {
#else
char *zmq_dash = strchr(nucn->name, '-');
if (tcp_port == NULL && zmq_dash == NULL) {
#endif
fprintf(stdout, "invalid cluster node name %s\n", nucn->name);
return;
}
// first check for already present node
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
ucn = &uwsgi.shared->nodes[i];
if (ucn->name[0] != 0) {
if (!strcmp(ucn->name, nucn->name)) {
ucn->status = UWSGI_NODE_OK;
ucn->last_seen = time(NULL);
// update requests
ucn->requests = nucn->requests;
return;
}
}
}
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
ucn = &uwsgi.shared->nodes[i];
if (ucn->name[0] == 0) {
memcpy(ucn->name, nucn->name, strlen(nucn->name) + 1);
memcpy(ucn->nodename, nucn->nodename, strlen(nucn->nodename) + 1);
ucn->workers = nucn->workers;
ucn->ucn_addr.sin_family = AF_INET;
if (tcp_port) {
ucn->ucn_addr.sin_port = htons(atoi(tcp_port + 1));
tcp_port[0] = 0;
}
if (nucn->name[0] == 0) {
ucn->ucn_addr.sin_addr.s_addr = INADDR_ANY;
}
else {
#ifdef UWSGI_DEBUG
uwsgi_log("%s\n", nucn->name);
#endif
ucn->ucn_addr.sin_addr.s_addr = inet_addr(nucn->name);
}
ucn->type = type;
// here memory can be freed, as it is allocated by uwsgi_concat2n
if (type != CLUSTER_NODE_DYNAMIC && tcp_port) {
tcp_port[0] = ':';
}
ucn->last_seen = time(NULL);
ucn->requests = nucn->requests;
uwsgi_log("[uWSGI cluster] added node %s\n", ucn->name);
return;
}
}
uwsgi_log("unable to add node %s\n", nucn->name);
}
int uwsgi_cluster_add_me() {
const char *key1 = "hostname";
const char *key2 = "address";
const char *key3 = "workers";
const char *key4 = "requests";
char *ptrbuf;
uint16_t ustrlen;
char numproc[6];
#ifdef UWSGI_ZEROMQ
char uuid_zmq_str[37];
uuid_t uuid_zmq;
if (!uwsgi.sockets && !uwsgi.zeromq) {
#else
if (!uwsgi.sockets) {
#endif
uwsgi_log("you need to specify at least a socket to start a uWSGI cluster\n");
exit(1);
}
snprintf(numproc, 6, "%d", uwsgi.numproc);
size_t len;
if (uwsgi.sockets) {
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key2) + 2 + strlen(uwsgi.sockets->name) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
}
#ifdef UWSGI_ZEROMQ
else if (uwsgi.zeromq) {
uuid_generate(uuid_zmq);
uuid_unparse(uuid_zmq, uuid_zmq_str);
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key2) + 2 + strlen(uuid_zmq_str) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
}
#endif
else {
len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
}
char *buf = uwsgi_malloc(len);
ptrbuf = buf;
ustrlen = strlen(key1);
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
memcpy(ptrbuf, key1, strlen(key1));
ptrbuf += strlen(key1);
ustrlen = strlen(uwsgi.hostname);
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
memcpy(ptrbuf, uwsgi.hostname, strlen(uwsgi.hostname));
ptrbuf += strlen(uwsgi.hostname);
if (uwsgi.sockets && uwsgi.sockets->name) {
ustrlen = strlen(key2);
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
memcpy(ptrbuf, key2, strlen(key2));
ptrbuf += strlen(key2);
ustrlen = strlen(uwsgi.sockets->name);
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
memcpy(ptrbuf, uwsgi.sockets->name, strlen(uwsgi.sockets->name));
ptrbuf += strlen(uwsgi.sockets->name);
}
#ifdef UWSGI_ZEROMQ
else if (uwsgi.zeromq) {
ustrlen = strlen(key2);
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
memcpy(ptrbuf, key2, strlen(key2));
ptrbuf += strlen(key2);
ustrlen = strlen(uuid_zmq_str);
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
memcpy(ptrbuf, uuid_zmq_str, strlen(uuid_zmq_str));
ptrbuf += strlen(uuid_zmq_str);
}
#endif
ustrlen = strlen(key3);
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
memcpy(ptrbuf, key3, strlen(key3));
ptrbuf += strlen(key3);
ustrlen = strlen(numproc);
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
memcpy(ptrbuf, numproc, strlen(numproc));
ptrbuf += strlen(numproc);
ustrlen = strlen(key4);
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
memcpy(ptrbuf, key4, strlen(key4));
ptrbuf += strlen(key4);
ustrlen = 1;
*ptrbuf++ = (uint8_t) (ustrlen & 0xff);
*ptrbuf++ = (uint8_t) ((ustrlen >> 8) & 0xff);
memcpy(ptrbuf, "0", 1);
ptrbuf += 1;
uwsgi_string_sendto(uwsgi.cluster_fd, 95, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr), buf, len);
free(buf);
#ifdef UWSGI_DEBUG
uwsgi_log("add_me() successfull\n");
#endif
return 0;
}
int uwsgi_cluster_join(char *name) {
int fd;
char *cp;
int broadcast = 0;
if (name[0] == ':') {
fd = bind_to_udp(name, 0, 1);
broadcast = 1;
}
else {
fd = bind_to_udp(name, 1, 0);
}
if (fd >= 0) {
cp = strchr(name, ':');
cp[0] = 0;
uwsgi.mc_cluster_addr.sin_family = AF_INET;
if (broadcast) {
uwsgi.mc_cluster_addr.sin_addr.s_addr = INADDR_BROADCAST;
}
else {
uwsgi.mc_cluster_addr.sin_addr.s_addr = inet_addr(name);
}
uwsgi.mc_cluster_addr.sin_port = htons(atoi(cp + 1));
cp[0] = ':';
// announce my presence to all the nodes
uwsgi_string_sendto(fd, 73, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr), uwsgi.hostname, strlen(uwsgi.hostname));
}
else {
exit(1);
}
return fd;
}
char *uwsgi_cluster_best_node() {
int i;
int best_node = -1;
struct uwsgi_cluster_node *ucn;
for (i = 0; i < MAX_CLUSTER_NODES; i++) {
ucn = &uwsgi.shared->nodes[i];
if (ucn->name[0] != 0 && ucn->status == UWSGI_NODE_OK) {
if (best_node == -1) {
best_node = i;
}
else {
if (ucn->last_choosen < uwsgi.shared->nodes[best_node].last_choosen) {
best_node = i;
}
}
}
}
if (best_node == -1) {
return NULL;
}
uwsgi.shared->nodes[best_node].last_choosen = time(NULL);
return uwsgi.shared->nodes[best_node].name;
}
void manage_cluster_announce(char *key, uint16_t keylen, char *val, uint16_t vallen, void *data) {
char *tmpstr;
struct uwsgi_cluster_node *ucn = (struct uwsgi_cluster_node *) data;
#ifdef UWSGI_DEBUG
uwsgi_log("%.*s = %.*s\n", keylen, key, vallen, val);
#endif
if (!uwsgi_strncmp("hostname", 8, key, keylen)) {
strncpy(ucn->nodename, val, UMIN(vallen, 255));
}
if (!uwsgi_strncmp("address", 7, key, keylen)) {
strncpy(ucn->name, val, UMIN(vallen, 100));
}
if (!uwsgi_strncmp("workers", 7, key, keylen)) {
tmpstr = uwsgi_concat2n(val, vallen, "", 0);
ucn->workers = atoi(tmpstr);
free(tmpstr);
}
if (!uwsgi_strncmp("requests", 8, key, keylen)) {
tmpstr = uwsgi_concat2n(val, vallen, "", 0);
ucn->requests = strtoul(tmpstr, NULL, 0);
free(tmpstr);
}
}
#endif
+15
View File
@@ -0,0 +1,15 @@
use POSIX;
use IO::Socket::INET;
use IO::Socket::INET6;
use IO::Socket::UNIX;
my $s = IO::Socket::INET->new(LocalAddr => '127.0.0.1', LocalPort => 1717, Proto => 'tcp', Reuse => 1);
my $s2 = IO::Socket::INET->new(LocalAddr => '127.0.0.1', LocalPort => 3022, Proto => 'tcp', Reuse => 1);
my $s3 = IO::Socket::INET6->new(LocalAddr => '::', LocalPort => 3017, Proto => 'tcp', Reuse => 1);
my $s4 = IO::Socket::UNIX->new(Local => '/tmp/u.sock', Listen => 1);
dup2($s->fileno, 17);
dup2($s2->fileno, 22);
dup2($s3->fileno, 30);
dup2($s4->fileno, 0);
exec './uwsgi','-M', '--socket','fd://17', '--http-socket','fd://22', '--socket','fd://30','--stats',':5001';
+53
View File
@@ -0,0 +1,53 @@
#include <Python.h>
void uwsgi_cgi_load_python() {
Py_Initialize();
}
void uwsgi_cgi_run_python(char *filename) {
char **e, *p;
PyObject *k, *env_value;
FILE *fp = fopen(filename, "r");
PySys_SetArgv(1, &filename);
PyObject *os_module = PyImport_ImportModule("os");
if (os_module) {
PyObject *os_module_dict = PyModule_GetDict(os_module);
PyObject *py_environ = PyDict_GetItemString(os_module_dict, "environ");
if (py_environ) {
for (e = environ; *e != NULL; e++) {
p = strchr(*e, '=');
if (p == NULL) continue;
k = PyString_FromStringAndSize(*e, (int)(p-*e));
if (k == NULL) {
PyErr_Print();
continue;
}
env_value = PyString_FromString(p+1);
if (env_value == NULL) {
PyErr_Print();
Py_DECREF(k);
continue;
}
if (PyObject_SetItem(py_environ, k, env_value)) {
PyErr_Print();
}
Py_DECREF(k);
Py_DECREF(env_value);
}
}
}
PyRun_AnyFileEx(fp, filename, 1);
}
+24
View File
@@ -0,0 +1,24 @@
require 'socket'
require 'openssl'
secret = 'ciaociao'
iv = ''
address = '127.0.0.1'
port = 1717
algo = 'bf-cbc'
s = UDPSocket.new
s.bind(address, port)
cipher = OpenSSL::Cipher.new(algo)
cipher.decrypt
cipher.key = secret + ("\0" * (cipher.key_len - secret.length))
cipher.iv = iv + ("0" * (cipher.iv_len - iv.length))
loop do
msg, sender = s.recvfrom(8192)
cipher.reset
begin
puts cipher.update(msg) + cipher.final
rescue
end
end
+114
View File
@@ -0,0 +1,114 @@
require 'sinatra'
require 'socket'
require 'json'
module EmperorStats
def self.uwsgi_get_stats(server)
parts = server.split(':')
if parts.length > 1
s = TCPSocket.open(parts[0], parts[1])
else
s = UNIXSocket.open(server)
end
return JSON.parse(s.read())
end
end
template = <<eof
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%=@title%></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="unbit">
<link href="http://unbit.github.com/bootstrap/css/bootstrap.css" rel="stylesheet">
<style>
body {
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
}
</style>
<link href="http://unbit.github.com/bootstrap/css/bootstrap-responsive.css" rel="stylesheet">
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="#"><%=@title%></a>
</div>
</div>
</div>
<div class="container">
<hr/>
<h1>Emperor: <%=@stats['emperor']%></h1>
<hr/>
<div class="row">
<div class="span8">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>name</th><th>pid</th><th>first run</th>
<th>last respawn</th>
<th>last heartbeat</th>
<th>loyal</th>
<th>respawns</th>
<% if @stats['emperor_tyrant'] == 1 %>
<th>uid</th>
<th>gid</th>
<% end %>
</tr>
</thead>
<% for vassal in @stats['vassals'] %>
<tr>
<td><%=vassal['id']%></td>
<td><%=vassal['pid']%></td>
<td><%=Time.at(vassal['first_run']).strftime("%d %b %Y %H:%M:%S")%></td>
<td><%=Time.at(vassal['last_run']).strftime("%d %b %Y %H:%M:%S")%></td>
<td><% if vassal['last_heartbeat'] > 0 %><%=Time.at(vassal['last_heartbeat']).strftime("%d %b %Y %H:%M:%S")%><% end %></td>
<td><% if vassal['loyal'] > 0 %><%=Time.at(vassal['last_loyal']).strftime("%d %b %Y %H:%M:%S")%><% end %></td>
<td><%=vassal['respawns']%></td>
<% if @stats['emperor_tyrant'] == 1 %>
<td><%=vassal['uid']%></td>
<td><%=vassal['gid']%></td>
<% end %>
</tr>
<% end %>
</table>
</div>
<div class="span4">
<h3>blacklist</h3>
<table class="table table-striped table-bordered">
<thead>
<tr><th>name</th><th>throttle</th></tr>
<% for bli in @stats['blacklist'] %>
<tr>
<td><%=bli['id']%></td>
<td><%=bli['throttle_level']%></td>
</tr>
<% end %>
</thead>
</table>
</div>
</div>
<script src="http://unbit.github.com/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="http://unbit.github.com/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
</body>
</html>
eof
get '/' do
@stats = EmperorStats::uwsgi_get_stats(ENV['EMPEROR'])
@title = 'uWSGI Emperor monitor'
erb template
end
run Sinatra::Application
View File
+15
View File
@@ -0,0 +1,15 @@
use IO::Socket::INET;
my $s = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => $ARGV[0]);
my $mountpoint = $ARGV[1];
my $app = $ARGV[2];
my $uwsgi_appid = pack('v', length('UWSGI_APPID')).'UWSGI_APPID'.pack('v', length($mountpoint)).$mountpoint;
my $uwsgi_script = pack('v', length('UWSGI_SCRIPT')).'UWSGI_SCRIPT'.pack('v', length($app)).$app;
$s->send(pack('CvC', 5, length($uwsgi_appid.$uwsgi_script),0).$uwsgi_appid.$uwsgi_script);
while((my $cnt = $s->recv(my $buf, 4096))> 0) {
print $buf;
}
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/perl
use Crypt::OpenSSL::RSA;
use IO::Socket::INET;
open PK,$ARGV[3];
my @lines = <PK>;
close PK;
$rsa_priv = Crypt::OpenSSL::RSA->new_private_key(join('',@lines));
my %items = {};
$items{'key'} = $ARGV[1];
$items{'address'} = $ARGV[2];
my $uwsgi_pkt = '';
foreach(keys %items) {
$uwsgi_pkt .= pack('v', length($_)).$_.pack('v', length($items{$_})).$items{$_};
}
my $unix_check = time();
$uwsgi_pkt .= pack('v', 4).'unix'.pack('v', length($unix_check)).$unix_check;
my $signature = $rsa_priv->sign($uwsgi_pkt);
$uwsgi_pkt .= pack('v', 4).'sign'.pack('v', length($signature)).$signature;
my $udp = new IO::Socket::INET(PeerAddr => $ARGV[0], Proto => 'udp');
$udp->send(pack('CvC', 224, length($uwsgi_pkt), 0).$uwsgi_pkt);
print ''.(length($uwsgi_pkt)+4).' bytes sent to '.$ARGV[0]."\n";
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/perl
use IO::Socket::INET;
my %items = {};
$items{'key'} = $ARGV[1];
$items{'address'} = $ARGV[2];
my $uwsgi_pkt = '';
foreach(keys %items) {
$uwsgi_pkt .= pack('v', length($_)).$_.pack('v', length($items{$_})).$items{$_};
}
my $udp = new IO::Socket::INET(PeerAddr => $ARGV[0], Proto => 'udp');
$udp->send(pack('CvC', 224, length($uwsgi_pkt), 0).$uwsgi_pkt);
print ''.(length($uwsgi_pkt)+4).' bytes sent to '.$ARGV[0]."\n";
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
COMMAND=./uwsgi
CONFIG_FILE=
FIRST=0
for ARG in $@;do
if [ $FIRST -eq 0 ];then
FIRST=1
else
ARGS="$ARGS $ARG"
fi
done
export UWSGI_INHERIT=CONFIG_FILE
export UWSGI_PYRUN=$1
export UWSGI_PYARGV=$ARGS
exec $COMMAND
+123
View File
@@ -0,0 +1,123 @@
import mmap
import os
import struct
import array
import time
import sys
from optparse import OptionParser
class Cache:
def __init__(self, filename, cache_slots, block_size=65536, sample_sleep=1):
self.block_size = block_size
self.cache_slots = cache_slots
self.key_size = 2048
self.item_size = 2 + 2 + 4 + 8 + 8 + 8 + 8 + 8 + self.key_size
self.block_size_start = self.item_size * self.cache_slots
fd = os.open(filename, os.O_RDONLY)
self.cache_store = mmap.mmap(fd, 0, mmap.MAP_SHARED, mmap.PROT_READ)
self.sample_sleep = sample_sleep
self.samples = 0
self.history = []
self.cache_full = 0
self.cache_empty = 0
self.cache_items = 0
self.block_sizes = 0
def store_read_item_block(self, position):
pos = self.cache_store.tell()
# uwsgi cache stores cache entries first and then the blocks
self.cache_store.seek(self.block_size_start + (position * self.block_size))
buf = self.cache_store.read(self.block_size)
self.cache_store.seek(pos)
return buf
def store_read_item(self, position):
buf = self.cache_store.read(self.item_size)
fields = struct.unpack_from('@HHIQQQQQ2048c', buf)
key = array.array('c', fields[8:self.key_size+8]).tostring().rstrip('\x00')
if [x for x in key if x!= '\x00']:
buf = self.store_read_item_block(position)
value = array.array('c', buf).tostring().rstrip('\x00')
else:
value = ''
return (position, key, value, len(value))
def read(self):
data = [self.store_read_item(i) for i in range(self.cache_slots)]
self.cache_store.seek(0)
self.update_stats(data)
if self.sample_sleep:
time.sleep(self.sample_sleep)
return data
def update_stats(self, data):
# data is a list of (position, key, value, len(value)) tuples
items = len([1 for x in data if x[3] > 0])
self.cache_items += items
full, empty = items == self.cache_slots, items == 0
if full:
self.cache_full += 1
if empty:
self.cache_empty += 1
self.samples += 1
block_sizes = sum([x[3] for x in data])
self.block_sizes += block_sizes
self.history.append({'full': full, 'empty': empty, 'data': data, \
'items': items, 'block_sizes': block_sizes})
def dump(self):
return {
'samples': self.samples,
'history': self.history,
'cache_slots': self.cache_slots,
'sample_sleep': self.sample_sleep,
'cache_empty': self.cache_empty,
'cache_full': self.cache_full,
'cache_items': self.cache_items,
'block_sizes': self.block_sizes,
}
def show_dump(self):
d = self.dump()
print
print "Recorded %d samples (%d second(s) sleep between samples)" % \
(d['samples'], d['sample_sleep'])
print "Cache empty %d times, full %d times, %.2f items on average" % \
(d['cache_empty'], d['cache_full'], d['cache_items'] / d['samples'])
print "Block size average size: %d bytes" % \
(d['block_sizes'] / d['cache_items'] * 8)
print "Data in cache average: %d bytes" % \
(d['block_sizes'] / d['samples'] * 8)
def main(options):
cache = Cache(options.cache_store, options.cache_slots, options.block_size,
options.sleep_time)
print "Recording..."
while True:
try:
data = cache.read()
except KeyboardInterrupt:
cache.show_dump()
sys.exit(0)
if __name__ == '__main__':
parser = OptionParser()
parser.add_option("-s", "--cache-slots", dest="cache_slots", type="int",
help="Slots available in the cache, uwsgi cache option")
parser.add_option("-c", "--cache-store", dest="cache_store", default="uwsgi.cache",
help="The filename of the cache store, uwsgi cache-store option. Default: uwsgi.cache")
parser.add_option("-b", "--block-size", dest="block_size", default=65536, type="int",
help="The size of the cache block, uwsgi cache-blocksize option. Default: 65536")
parser.add_option("-t", "--sleep-time", dest="sleep_time", default=1, type="int",
help="The time to sleep between each sample. Default: 1")
(options, args) = parser.parse_args()
if not options.cache_slots:
parser.error('Option -s / --cache-slots is mandatory')
main(options)
+96
View File
@@ -0,0 +1,96 @@
require 'sinatra'
require 'socket'
require 'json'
module USubscribers
def self.uwsgi_get_stats(server)
parts = server.split(':')
if parts.length > 1
s = TCPSocket.open(parts[0], parts[1])
else
s = UNIXSocket.open(server)
end
return JSON.parse(s.read())
end
end
template = <<eof
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%=@title%></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="unbit">
<link href="http://unbit.github.com/bootstrap/css/bootstrap.css" rel="stylesheet">
<style>
body {
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
}
</style>
<link href="http://unbit.github.com/bootstrap/css/bootstrap-responsive.css" rel="stylesheet">
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="#"><%=@title%></a>
</div>
</div>
</div>
<% for server in @servers.keys %>
<div class="container">
<hr/>
<h1>SubscriptionServer: <%=server%></h1>
<hr/>
<div class="row">
<% for pool in @servers[server] %>
<div class="span6">
<h3><%=pool['key']%> (<%=pool['hits']%> hits)</h3>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>node</th><th>load</th><th>requests</th>
<th>last check</th>
<th>fail count</th>
</tr>
</thead>
<% for node in pool['nodes'] %>
<tr>
<td><%=node['name']%></td><td><%=node['load']%></td><td><%=node['requests']%></td>
<td><%=Time.at(node['last_check']).strftime("%d-%m-%Y %H:%M:%S")%></td>
<td><%=node['failcnt']%></td>
</tr>
<% end %>
</table>
</div>
<% end %>
</div>
</div>
<% end %>
<script src="http://unbit.github.com/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="http://unbit.github.com/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
</body>
</html>
eof
get '/' do
@servers = {}
for server in ENV['U_SERVERS'].split(',')
stats = USubscribers::uwsgi_get_stats(server)
if stats
@servers[server] = stats['subscriptions']
end
end
@title = 'uWSGI subscriptions viewer'
erb template
end
run Sinatra::Application
+342
View File
@@ -0,0 +1,342 @@
#include "../uwsgi.h"
extern struct uwsgi_server uwsgi;
// generate a uwsgi signal on alarm
void uwsgi_alarm_init_signal(struct uwsgi_alarm_instance *uai) {
uai->data8 = atoi(uai->arg);
}
void uwsgi_alarm_func_signal(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
uwsgi_route_signal(uai->data8);
}
// run a command on alarm
void uwsgi_alarm_init_cmd(struct uwsgi_alarm_instance *uai) {
uai->data_ptr = uai->arg;
}
void uwsgi_alarm_func_cmd(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
int pipe[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe)) {
return;
}
uwsgi_socket_nb(pipe[0]);
uwsgi_socket_nb(pipe[1]);
if (write(pipe[1], msg, len) != (ssize_t) len) {
close(pipe[0]);
close(pipe[1]);
return;
}
uwsgi_run_command(uai->data_ptr, pipe, -1);
close(pipe[0]);
close(pipe[1]);
}
// pass the log line to a mule
void uwsgi_alarm_init_mule(struct uwsgi_alarm_instance *uai) {
uai->data32 = atoi(uai->arg);
if (uai->data32 > (uint32_t) uwsgi.mules_cnt) {
uwsgi_log_alarm("] invalid mule_id (%d mules available), fallback to 0\n", uwsgi.mules_cnt);
uai->data32 = 0;
}
}
void uwsgi_alarm_func_mule(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
// skip if mules are not available
if (uwsgi.mules_cnt == 0)
return;
int fd = uwsgi.shared->mule_queue_pipe[0];
if (uai->data32 > 0) {
int mule_id = uai->data32 - 1;
fd = uwsgi.mules[mule_id].queue_pipe[0];
}
mule_send_msg(fd, msg, len);
}
// register a new alarm
void uwsgi_register_alarm(char *name, void (*init) (struct uwsgi_alarm_instance *), void (*func) (struct uwsgi_alarm_instance *, char *, size_t)) {
struct uwsgi_alarm *old_ua = NULL, *ua = uwsgi.alarms;
while (ua) {
// skip already initialized alarms
if (!strcmp(ua->name, name)) {
return;
}
old_ua = ua;
ua = ua->next;
}
ua = uwsgi_calloc(sizeof(struct uwsgi_alarm));
ua->name = name;
ua->init = init;
ua->func = func;
if (old_ua) {
old_ua->next = ua;
}
else {
uwsgi.alarms = ua;
}
}
// register embedded alarms
void uwsgi_register_embedded_alarms() {
uwsgi_register_alarm("signal", uwsgi_alarm_init_signal, uwsgi_alarm_func_signal);
uwsgi_register_alarm("cmd", uwsgi_alarm_init_cmd, uwsgi_alarm_func_cmd);
uwsgi_register_alarm("mule", uwsgi_alarm_init_mule, uwsgi_alarm_func_mule);
}
static int uwsgi_alarm_add(char *name, char *plugin, char *arg) {
struct uwsgi_alarm *ua = uwsgi.alarms;
while (ua) {
if (!strcmp(ua->name, plugin)) {
break;
}
ua = ua->next;
}
if (!ua)
return -1;
struct uwsgi_alarm_instance *old_uai = NULL, *uai = uwsgi.alarm_instances;
while (uai) {
old_uai = uai;
uai = uai->next;
}
uai = uwsgi_calloc(sizeof(struct uwsgi_alarm_instance));
uai->name = name;
uai->alarm = ua;
uai->arg = arg;
uai->last_msg = uwsgi_malloc(uwsgi.log_master_bufsize);
if (old_uai) {
old_uai->next = uai;
}
else {
uwsgi.alarm_instances = uai;
}
ua->init(uai);
return 0;
}
// get an alarm instance by its name
static struct uwsgi_alarm_instance *uwsgi_alarm_get_instance(char *name) {
struct uwsgi_alarm_instance *uai = uwsgi.alarm_instances;
while (uai) {
if (!strcmp(name, uai->name)) {
return uai;
}
uai = uai->next;
}
return NULL;
}
#ifdef UWSGI_PCRE
static int uwsgi_alarm_log_add(char *alarms, char *regexp, int negate) {
struct uwsgi_alarm_log *old_ual = NULL, *ual = uwsgi.alarm_logs;
while (ual) {
old_ual = ual;
ual = ual->next;
}
ual = uwsgi_calloc(sizeof(struct uwsgi_alarm_log));
if (uwsgi_regexp_build(regexp, &ual->pattern, &ual->pattern_extra)) {
return -1;
}
ual->negate = negate;
if (old_ual) {
old_ual->next = ual;
}
else {
uwsgi.alarm_logs = ual;
}
// map instances to the log
char *list = uwsgi_str(alarms);
char *p = strtok(list, ",");
while (p) {
struct uwsgi_alarm_instance *uai = uwsgi_alarm_get_instance(p);
if (!uai) {
free(list);
return -1;
}
struct uwsgi_alarm_ll *old_uall = NULL, *uall = ual->alarms;
while (uall) {
old_uall = uall;
uall = uall->next;
}
uall = uwsgi_calloc(sizeof(struct uwsgi_alarm_ll));
uall->alarm = uai;
if (old_uall) {
old_uall->next = uall;
}
else {
ual->alarms = uall;
}
p = strtok(NULL, ",");
}
free(list);
return 0;
}
#endif
static void uwsgi_alarm_thread_loop(struct uwsgi_thread *ut) {
char *buf = uwsgi_malloc(uwsgi.alarm_msg_size + sizeof(long));
for (;;) {
int interesting_fd = -1;
int ret = event_queue_wait(ut->queue, -1, &interesting_fd);
if (ret > 0) {
ssize_t len = read(ut->pipe[1], buf, uwsgi.alarm_msg_size + sizeof(long));
if (len > (ssize_t)(sizeof(long) + 1)) {
size_t msg_size = len - sizeof(long);
char *msg = buf + sizeof(long);
long ptr = 0;
memcpy(&ptr, buf, sizeof(long));
struct uwsgi_alarm_instance *uai = (struct uwsgi_alarm_instance *) ptr;
if (!uai)
break;
uwsgi_alarm_run(uai, msg, msg_size);
}
}
}
free(buf);
}
// initialize alarms, instances and log regexps
void uwsgi_alarms_init() {
if (!uwsgi.master_process) return;
// first of all, create instance of alarms
struct uwsgi_string_list *usl = uwsgi.alarm_list;
while (usl) {
char *line = uwsgi_str(usl->value);
char *space = strchr(line, ' ');
if (!space) {
uwsgi_log("invalid alarm syntax: %s\n", usl->value);
exit(1);
}
*space = 0;
char *plugin = space + 1;
char *colon = strchr(plugin, ':');
if (!colon) {
uwsgi_log("invalid alarm syntax: %s\n", usl->value);
exit(1);
}
*colon = 0;
char *arg = colon + 1;
// here the alarm is mapped to a name and initialized
if (uwsgi_alarm_add(line, plugin, arg)) {
uwsgi_log("invalid alarm: %s\n", usl->value);
exit(1);
}
usl = usl->next;
}
if (!uwsgi.alarm_instances) return;
#ifdef UWSGI_PCRE
// then map log-alarm
usl = uwsgi.alarm_logs_list;
while (usl) {
char *line = uwsgi_str(usl->value);
char *space = strchr(line, ' ');
if (!space) {
uwsgi_log("invalid log-alarm syntax: %s\n", usl->value);
exit(1);
}
*space = 0;
char *regexp = space + 1;
// here the log-alarm is created
if (uwsgi_alarm_log_add(line, regexp, usl->custom)) {
uwsgi_log("invalid log-alarm: %s\n", usl->value);
exit(1);
}
usl = usl->next;
}
#endif
}
void uwsgi_alarm_thread_start() {
if (!uwsgi.alarm_instances) return;
// start the alarm_thread
uwsgi.alarm_thread = uwsgi_thread_new(uwsgi_alarm_thread_loop);
if (!uwsgi.alarm_thread) {
uwsgi_log("unable to spawn alarm thread\n");
exit(1);
}
}
#ifdef UWSGI_PCRE
// check if a log should raise an alarm
void uwsgi_alarm_log_check(char *msg, size_t len) {
if (!uwsgi_strncmp(msg, len, "[uwsgi-alarm", 12))
return;
struct uwsgi_alarm_log *ual = uwsgi.alarm_logs;
while (ual) {
if (uwsgi_regexp_match(ual->pattern, ual->pattern_extra, msg, len) >= 0) {
if (!ual->negate) {
uwsgi_alarm_log_run(ual, msg, len);
}
else {
break;
}
}
ual = ual->next;
}
}
#endif
// call the alarm func
void uwsgi_alarm_run(struct uwsgi_alarm_instance *uai, char *msg, size_t len) {
time_t now = uwsgi_now();
// avoid alarm storming/loop if last message is the same
if (!uwsgi_strncmp(msg, len, uai->last_msg, uai->last_msg_size)) {
if (now - uai->last_run < uwsgi.alarm_freq)
return;
}
uai->alarm->func(uai, msg, len);
uai->last_run = uwsgi_now();
memcpy(uai->last_msg, msg, len);
uai->last_msg_size = len;
}
#ifdef UWSGI_PCRE
// call the alarms mapped to a log line
void uwsgi_alarm_log_run(struct uwsgi_alarm_log *ual, char *msg, size_t len) {
struct uwsgi_alarm_ll *uall = ual->alarms;
while (uall) {
uwsgi_alarm_run(uall->alarm, msg, len);
uall = uall->next;
}
}
#endif
// this is the api function workers,mules and whatever you want can call from code
void uwsgi_alarm_trigger(char *alarm_instance_name, char *msg, size_t len) {
if (!uwsgi.alarm_thread) return;
if (len > uwsgi.alarm_msg_size) return;
struct uwsgi_alarm_instance *uai = uwsgi_alarm_get_instance(alarm_instance_name);
if (!uai) return;
struct iovec iov[2];
iov[0].iov_base = &uai;
iov[0].iov_len = sizeof(long);
iov[1].iov_base = msg;
iov[1].iov_len = len;
// now send the message to the alarm thread
if (writev(uwsgi.alarm_thread->pipe[0], iov, 2) != (ssize_t) (len+sizeof(long))) {
uwsgi_error("[uwsgi-alarm-error] uwsgi_alarm_trigger()/writev()");
}
}
+196 -143
View File
@@ -1,7 +1,37 @@
#include "uwsgi.h"
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
void uwsgi_async_queue_is_full(time_t now) {
if (now > uwsgi.async_queue_is_full) {
uwsgi_log_verbose("[DANGER] async queue is full !!!\n");
uwsgi.async_queue_is_full = now;
}
}
void uwsgi_async_init() {
int i;
uwsgi.async_queue = event_queue_init();
if (uwsgi.async_queue < 0) {
exit(1);
}
uwsgi_add_sockets_to_queue(uwsgi.async_queue, -1);
uwsgi.rb_async_timeouts = uwsgi_init_rb_timer();
uwsgi.async_queue_unused = uwsgi_malloc(sizeof(struct wsgi_request *) * uwsgi.async);
for (i = 0; i < uwsgi.async; i++) {
uwsgi.async_queue_unused[i] = &uwsgi.workers[uwsgi.mywid].cores[i].req;
}
uwsgi.async_queue_unused_ptr = uwsgi.async - 1;
}
struct wsgi_request *find_wsgi_req_proto_by_fd(int fd) {
return uwsgi.async_proto_fd_table[fd];
}
@@ -10,51 +40,51 @@ struct wsgi_request *find_wsgi_req_by_fd(int fd) {
return uwsgi.async_waiting_fd_table[fd];
}
void runqueue_remove(struct uwsgi_async_request *u_request) {
static void runqueue_remove(struct uwsgi_async_request *u_request) {
struct uwsgi_async_request *parent = u_request->prev;
struct uwsgi_async_request *child = u_request->next;
if (parent) {
parent->next = child;
}
if (child) {
child->prev = parent;
}
if (parent == NULL) {
uwsgi.async_runqueue = child;
}
if (parent) {
parent->next = child;
}
if (child) {
child->prev = parent;
}
if (parent == NULL) {
uwsgi.async_runqueue = child;
}
if (u_request == uwsgi.async_runqueue_last) {
uwsgi.async_runqueue_last = parent;
}
free(u_request);
free(u_request);
uwsgi.async_runqueue_cnt--;
}
void runqueue_push(struct wsgi_request *wsgi_req) {
static void runqueue_push(struct wsgi_request *wsgi_req) {
struct uwsgi_async_request *uar;
if (uwsgi.async_runqueue == NULL) {
// empty runqueue, create a new one
uwsgi.async_runqueue = uwsgi_malloc(sizeof(struct uwsgi_async_request));
uwsgi.async_runqueue->next = NULL;
uwsgi.async_runqueue->prev = NULL;
uwsgi.async_runqueue->wsgi_req = wsgi_req;
uwsgi.async_runqueue_last = uwsgi.async_runqueue;
}
else {
// empty runqueue, create a new one
uwsgi.async_runqueue = uwsgi_malloc(sizeof(struct uwsgi_async_request));
uwsgi.async_runqueue->next = NULL;
uwsgi.async_runqueue->prev = NULL;
uwsgi.async_runqueue->wsgi_req = wsgi_req;
uwsgi.async_runqueue_last = uwsgi.async_runqueue;
}
else {
uar = uwsgi_malloc(sizeof(struct uwsgi_async_request));
uar->prev = uwsgi.async_runqueue_last;
uar->next = NULL;
uar->wsgi_req = wsgi_req;
uwsgi.async_runqueue_last->next = uar;
uwsgi.async_runqueue_last = uar;
}
uar->prev = uwsgi.async_runqueue_last;
uar->next = NULL;
uar->wsgi_req = wsgi_req;
uwsgi.async_runqueue_last->next = uar;
uwsgi.async_runqueue_last = uar;
}
uwsgi.async_runqueue_cnt++;
@@ -73,30 +103,30 @@ struct wsgi_request *find_first_available_wsgi_req() {
return wsgi_req;
}
void async_expire_timeouts() {
static void async_expire_timeouts(uint64_t now) {
struct wsgi_request *wsgi_req;
time_t current_time = time(NULL);
struct uwsgi_async_fd *uaf = NULL, *current_uaf;
struct uwsgi_rb_timer *urbt;
for(;;) {
for (;;) {
urbt = uwsgi_min_rb_timer(uwsgi.rb_async_timeouts);
urbt = uwsgi_min_rb_timer(uwsgi.rb_async_timeouts, NULL);
if (urbt == NULL) return;
if (urbt == NULL)
return;
if (urbt->key <= current_time) {
wsgi_req = (struct wsgi_request *) urbt->data;
if (urbt->value <= now) {
wsgi_req = (struct wsgi_request *) urbt->data;
// timeout expired
wsgi_req->async_timed_out = 1;
rb_erase(&wsgi_req->async_timeout->rbt, uwsgi.rb_async_timeouts);
uwsgi_del_rb_timer(uwsgi.rb_async_timeouts, wsgi_req->async_timeout);
free(wsgi_req->async_timeout);
wsgi_req->async_timeout = NULL;
uaf = wsgi_req->waiting_fds;
// remove fds from monitoring (no problem modifying the queue here, as the function is executed only when there are no fd ready)
while(uaf) {
while (uaf) {
event_queue_del_fd(uwsgi.async_queue, uaf->fd, uaf->event);
uwsgi.async_waiting_fd_table[uaf->fd] = NULL;
current_uaf = uaf;
@@ -106,22 +136,23 @@ void async_expire_timeouts() {
wsgi_req->waiting_fds = NULL;
// put th request in the runqueue
runqueue_push(wsgi_req);
continue;
}
continue;
}
break;
}
break;
}
}
void async_add_fd_read(struct wsgi_request *wsgi_req, int fd, int timeout) {
int async_add_fd_read(struct wsgi_request *wsgi_req, int fd, int timeout) {
struct uwsgi_async_fd *last_uad = NULL, *uad = wsgi_req->waiting_fds;
if (fd < 0) return ;
if (fd < 0)
return -1;
// find first slot
while(uad) {
while (uad) {
last_uad = uad;
uad = uad->next;
}
@@ -143,57 +174,93 @@ void async_add_fd_read(struct wsgi_request *wsgi_req, int fd, int timeout) {
async_add_timeout(wsgi_req, timeout);
}
uwsgi.async_waiting_fd_table[fd] = wsgi_req;
event_queue_add_fd_read(uwsgi.async_queue, fd);
wsgi_req->async_force_again = 1;
return event_queue_add_fd_read(uwsgi.async_queue, fd);
}
static int async_wait_fd_read(int fd, int timeout) {
struct wsgi_request *wsgi_req = current_wsgi_req();
if (async_add_fd_read(wsgi_req, fd, timeout)) {
return -1;
}
if (uwsgi.schedule_to_main) {
uwsgi.schedule_to_main(wsgi_req);
}
if (wsgi_req->async_timed_out) {
wsgi_req->async_timed_out = 0;
return 0;
}
return 1;
}
void async_add_timeout(struct wsgi_request *wsgi_req, int timeout) {
if (timeout > 0 && wsgi_req->async_timeout == NULL) {
wsgi_req->async_timeout = uwsgi_add_rb_timer(uwsgi.rb_async_timeouts, time(NULL)+timeout, wsgi_req);
}
wsgi_req->async_timeout = uwsgi_add_rb_timer(uwsgi.rb_async_timeouts, uwsgi_now() + timeout, wsgi_req);
}
}
void async_add_fd_write(struct wsgi_request *wsgi_req, int fd, int timeout) {
int async_add_fd_write(struct wsgi_request *wsgi_req, int fd, int timeout) {
struct uwsgi_async_fd *last_uad = NULL, *uad = wsgi_req->waiting_fds;
struct uwsgi_async_fd *last_uad = NULL, *uad = wsgi_req->waiting_fds;
if (fd < 0) return ;
if (fd < 0)
return -1;
// find first slot
while(uad) {
last_uad = uad;
uad = uad->next;
}
// find first slot
while (uad) {
last_uad = uad;
uad = uad->next;
}
uad = uwsgi_malloc(sizeof(struct uwsgi_async_fd));
uad->fd = fd;
uad = uwsgi_malloc(sizeof(struct uwsgi_async_fd));
uad->fd = fd;
uad->event = event_queue_write();
uad->prev = last_uad;
uad->next = NULL;
uad->prev = last_uad;
uad->next = NULL;
if (last_uad) {
last_uad->next = uad;
}
else {
wsgi_req->waiting_fds = uad;
}
if (last_uad) {
last_uad->next = uad;
}
else {
wsgi_req->waiting_fds = uad;
}
if (timeout > 0) {
async_add_timeout(wsgi_req, timeout);
}
uwsgi.async_waiting_fd_table[fd] = wsgi_req;
event_queue_add_fd_write(uwsgi.async_queue, fd);
wsgi_req->async_force_again = 1;
return event_queue_add_fd_write(uwsgi.async_queue, fd);
}
static int async_wait_fd_write(int fd, int timeout) {
struct wsgi_request *wsgi_req = current_wsgi_req();
if (async_add_fd_write(wsgi_req, fd, timeout)) {
return -1;
}
if (uwsgi.schedule_to_main) {
uwsgi.schedule_to_main(wsgi_req);
}
if (wsgi_req->async_timed_out) {
wsgi_req->async_timed_out = 0;
return 0;
}
return 1;
}
void async_schedule_to_req(void) {
uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->request(uwsgi.wsgi_req);
uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh->modifier1]->request(uwsgi.wsgi_req);
}
void *async_loop(void *arg1) {
void async_loop() {
if (uwsgi.async < 2) {
uwsgi_log("the async loop engine requires async mode (--async <n>)\n");
exit(1);
}
struct uwsgi_async_fd *tmp_uaf;
int interesting_fd, i;
@@ -202,7 +269,7 @@ void *async_loop(void *arg1) {
int is_a_new_connection;
int proto_parser_status;
time_t now, last_now = 0;
uint64_t now;
static struct uwsgi_async_request *current_request = NULL, *next_async_request = NULL;
@@ -212,93 +279,84 @@ void *async_loop(void *arg1) {
uwsgi.async_runqueue = NULL;
uwsgi.async_runqueue_cnt = 0;
uwsgi.wait_write_hook = async_wait_fd_write;
uwsgi.wait_read_hook = async_wait_fd_read;
if (uwsgi.signal_socket > -1) {
event_queue_add_fd_read(uwsgi.async_queue, uwsgi.signal_socket);
event_queue_add_fd_read(uwsgi.async_queue, uwsgi.my_signal_socket);
}
// set a default request manager
if (!uwsgi.schedule_to_req) uwsgi.schedule_to_req = async_schedule_to_req;
if (!uwsgi.schedule_to_req)
uwsgi.schedule_to_req = async_schedule_to_req;
if (!uwsgi.schedule_to_main) {
uwsgi_log("*** WARNING *** async mode without coroutine/greenthread engine loaded !!!\n");
}
while (uwsgi.workers[uwsgi.mywid].manage_next_request) {
now = (uint64_t) uwsgi_now();
if (uwsgi.async_runqueue_cnt) {
timeout = 0;
}
else {
min_timeout = uwsgi_min_rb_timer(uwsgi.rb_async_timeouts);
if (uwsgi.async_runqueue_cnt) {
timeout = 0;
}
if (min_timeout) {
timeout = min_timeout->key - time(NULL);
if (timeout <= 0) {
async_expire_timeouts();
timeout = 0;
}
min_timeout = uwsgi_min_rb_timer(uwsgi.rb_async_timeouts, NULL);
if (min_timeout) {
timeout = min_timeout->value - now;
if (timeout <= 0) {
async_expire_timeouts(now);
timeout = 0;
}
}
else {
timeout = -1;
}
}
}
uwsgi.async_nevents = event_queue_wait_multi(uwsgi.async_queue, timeout, events, 64);
now = (uint64_t) uwsgi_now();
// timeout ???
if (uwsgi.async_nevents == 0) {
async_expire_timeouts();
async_expire_timeouts(now);
}
for(i=0;i<uwsgi.async_nevents;i++) {
for (i = 0; i < uwsgi.async_nevents; i++) {
// manage events
interesting_fd = event_queue_interesting_fd(events, i);
if (uwsgi.signal_socket > -1 && (interesting_fd == uwsgi.signal_socket || interesting_fd == uwsgi.my_signal_socket)) {
uwsgi_receive_signal(interesting_fd, "worker", uwsgi.mywid);
continue;
}
is_a_new_connection = 0;
// new request coming in ?
uwsgi_sock = uwsgi.sockets;
while(uwsgi_sock) {
while (uwsgi_sock) {
if (interesting_fd == uwsgi_sock->fd) {
is_a_new_connection = 1;
is_a_new_connection = 1;
uwsgi.wsgi_req = find_first_available_wsgi_req();
if (uwsgi.wsgi_req == NULL) {
now = time(NULL);
if (now > last_now) {
uwsgi_log("async queue is full !!!\n");
last_now = now;
}
break;;
uwsgi_async_queue_is_full((time_t)now);
break;
}
wsgi_req_setup(uwsgi.wsgi_req, uwsgi.wsgi_req->async_id, uwsgi_sock );
wsgi_req_setup(uwsgi.wsgi_req, uwsgi.wsgi_req->async_id, uwsgi_sock);
if (wsgi_req_simple_accept(uwsgi.wsgi_req, interesting_fd)) {
#ifdef UWSGI_EVENT_USE_PORT
event_queue_add_fd_read(uwsgi.async_queue, interesting_fd);
#endif
uwsgi.async_queue_unused_ptr++;
uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = uwsgi.wsgi_req;
break;
}
#ifdef UWSGI_EVENT_USE_PORT
event_queue_add_fd_read(uwsgi.async_queue, interesting_fd);
#endif
// on linux we do not need to reset the socket to blocking state
#ifndef __linux__
if (uwsgi.numproc > 1) {
/* re-set blocking socket */
if (fcntl(uwsgi.wsgi_req->poll.fd, F_SETFL, uwsgi_sock->arg) < 0) {
uwsgi_error("fcntl()");
uwsgi.async_queue_unused_ptr++;
uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = uwsgi.wsgi_req;
break;
}
}
#endif
if (wsgi_req_async_recv(uwsgi.wsgi_req)) {
uwsgi.async_queue_unused_ptr++;
@@ -322,22 +380,21 @@ void *async_loop(void *arg1) {
if (uwsgi.wsgi_req) {
proto_parser_status = uwsgi.wsgi_req->socket->proto(uwsgi.wsgi_req);
// reset timeout
rb_erase(&uwsgi.wsgi_req->async_timeout->rbt, uwsgi.rb_async_timeouts);
uwsgi_del_rb_timer(uwsgi.rb_async_timeouts, uwsgi.wsgi_req->async_timeout);
free(uwsgi.wsgi_req->async_timeout);
uwsgi.wsgi_req->async_timeout = NULL;
// parsing complete
if (!proto_parser_status) {
// remove fd from event poll and fd proto table
#ifndef UWSGI_EVENT_USE_PORT
event_queue_del_fd(uwsgi.async_queue, interesting_fd, event_queue_read());
#endif
// remove fd from event poll and fd proto table
uwsgi.async_proto_fd_table[interesting_fd] = NULL;
event_queue_del_fd(uwsgi.async_queue, interesting_fd, event_queue_read());
// put request in the runqueue
runqueue_push(uwsgi.wsgi_req);
continue;
}
else if (proto_parser_status == -1) {
uwsgi_log("error parsing request\n");
else if (proto_parser_status < 0) {
if (proto_parser_status == -1)
uwsgi_log("error parsing request\n");
uwsgi.async_proto_fd_table[interesting_fd] = NULL;
close(interesting_fd);
continue;
@@ -356,27 +413,27 @@ void *async_loop(void *arg1) {
}
// remove all the fd monitors and timeout
while(uwsgi.wsgi_req->waiting_fds) {
#ifndef UWSGI_EVENT_USE_PORT
event_queue_del_fd(uwsgi.async_queue, uwsgi.wsgi_req->waiting_fds->fd, uwsgi.wsgi_req->waiting_fds->event);
#endif
tmp_uaf = uwsgi.wsgi_req->waiting_fds;
uwsgi.async_waiting_fd_table[tmp_uaf->fd] = NULL;
uwsgi.wsgi_req->waiting_fds = tmp_uaf->next;
free(tmp_uaf);
}
while (uwsgi.wsgi_req->waiting_fds) {
tmp_uaf = uwsgi.wsgi_req->waiting_fds;
uwsgi.async_waiting_fd_table[tmp_uaf->fd] = NULL;
event_queue_del_fd(uwsgi.async_queue, tmp_uaf->fd, tmp_uaf->event);
uwsgi.wsgi_req->waiting_fds = tmp_uaf->next;
free(tmp_uaf);
}
uwsgi.wsgi_req->waiting_fds = NULL;
if (uwsgi.wsgi_req->async_timeout) {
rb_erase(&uwsgi.wsgi_req->async_timeout->rbt, uwsgi.rb_async_timeouts);
free(uwsgi.wsgi_req->async_timeout);
uwsgi.wsgi_req->async_timeout = NULL;
}
if (uwsgi.wsgi_req->async_timeout) {
uwsgi_del_rb_timer(uwsgi.rb_async_timeouts, uwsgi.wsgi_req->async_timeout);
free(uwsgi.wsgi_req->async_timeout);
uwsgi.wsgi_req->async_timeout = NULL;
}
uwsgi.wsgi_req->async_ready_fd = 1;
uwsgi.wsgi_req->async_last_ready_fd = interesting_fd;
// put the request in the runqueue again
runqueue_push(uwsgi.wsgi_req);
// avoid managing other enqueued events...
break;
}
}
@@ -395,20 +452,18 @@ void *async_loop(void *arg1) {
// request ended ?
if (uwsgi.wsgi_req->async_status <= UWSGI_OK) {
// remove all the monitored fds and timeout
while(uwsgi.wsgi_req->waiting_fds) {
#ifndef UWSGI_EVENT_USE_PORT
event_queue_del_fd(uwsgi.async_queue, uwsgi.wsgi_req->waiting_fds->fd, uwsgi.wsgi_req->waiting_fds->event);
#endif
while (uwsgi.wsgi_req->waiting_fds) {
tmp_uaf = uwsgi.wsgi_req->waiting_fds;
uwsgi.async_waiting_fd_table[tmp_uaf->fd] = NULL;
event_queue_del_fd(uwsgi.async_queue, tmp_uaf->fd, tmp_uaf->event);
uwsgi.wsgi_req->waiting_fds = tmp_uaf->next;
free(tmp_uaf);
}
uwsgi.wsgi_req->waiting_fds = NULL;
if (uwsgi.wsgi_req->async_timeout) {
rb_erase(&uwsgi.wsgi_req->async_timeout->rbt, uwsgi.rb_async_timeouts);
free(uwsgi.wsgi_req->async_timeout);
uwsgi.wsgi_req->async_timeout = NULL;
uwsgi_del_rb_timer(uwsgi.rb_async_timeouts, uwsgi.wsgi_req->async_timeout);
free(uwsgi.wsgi_req->async_timeout);
uwsgi.wsgi_req->async_timeout = NULL;
}
// remove from the list
@@ -422,7 +477,7 @@ void *async_loop(void *arg1) {
}
else if (uwsgi.wsgi_req->waiting_fds || uwsgi.wsgi_req->async_timeout) {
// remove this request from suspended list
// remove this request from suspended list
runqueue_remove(current_request);
}
@@ -433,6 +488,4 @@ void *async_loop(void *arg1) {
}
return NULL;
}
+356
View File
@@ -0,0 +1,356 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
struct uwsgi_buffer *uwsgi_buffer_new(size_t len) {
struct uwsgi_buffer *ub = uwsgi_calloc(sizeof(struct uwsgi_buffer));
if (len) {
ub->buf = uwsgi_malloc(len);
ub->len = len;
}
return ub;
}
int uwsgi_buffer_fix(struct uwsgi_buffer *ub, size_t len) {
if (ub->limit > 0 && len > ub->limit)
return -1;
if (ub->len < len) {
char *new_buf = realloc(ub->buf, len);
if (!new_buf) {
uwsgi_error("uwsgi_buffer_fix()");
return -1;
}
ub->buf = new_buf;
ub->len = len;
}
return 0;
}
int uwsgi_buffer_ensure(struct uwsgi_buffer *ub, size_t len) {
size_t remains = ub->len - ub->pos;
if (remains < len) {
size_t new_len = ub->len + (len - remains);
if (ub->limit > 0 && new_len > ub->limit) {
new_len = ub->limit;
if (new_len == ub->len)
return -1;
}
char *new_buf = realloc(ub->buf, new_len);
if (!new_buf) {
uwsgi_error("uwsgi_buffer_ensure()");
return -1;
}
ub->buf = new_buf;
ub->len = new_len;
}
return 0;
}
int uwsgi_buffer_insert(struct uwsgi_buffer *ub, size_t pos, char *buf, size_t len) {
size_t to_move = (ub->pos-pos);
if (uwsgi_buffer_ensure(ub, len)) return -1;
memmove(ub->buf+pos+len, ub->buf+pos, to_move);
memcpy(ub->buf+pos, buf, len);
ub->pos += len;
return 0;
}
int uwsgi_buffer_insert_chunked(struct uwsgi_buffer *ub, size_t pos, size_t len) {
// 0xFFFFFFFFFFFFFFFF\r\n\0
char chunked[19];
int ret = snprintf(chunked, 19, "%X\r\n", (unsigned int) len);
if (ret <= 0 || ret > 19) {
return -1;
}
return uwsgi_buffer_insert(ub, pos, chunked, ret);
}
int uwsgi_buffer_append_chunked(struct uwsgi_buffer *ub, size_t len) {
// 0xFFFFFFFFFFFFFFFF\r\n\0
char chunked[19];
int ret = snprintf(chunked, 19, "%X\r\n", (unsigned int) len);
if (ret <= 0 || ret > 19) {
return -1;
}
return uwsgi_buffer_append(ub, chunked, ret);
}
int uwsgi_buffer_decapitate(struct uwsgi_buffer *ub, size_t len) {
if (len > ub->pos) return -1;
memmove(ub->buf, ub->buf + len, ub->pos-len);
ub->pos = ub->pos-len;
return 0;
}
int uwsgi_buffer_byte(struct uwsgi_buffer *ub, char byte) {
return uwsgi_buffer_append(ub, &byte, 1);
}
int uwsgi_buffer_u8(struct uwsgi_buffer *ub, uint8_t u8) {
return uwsgi_buffer_append(ub, (char *) &u8, 1);
}
int uwsgi_buffer_append(struct uwsgi_buffer *ub, char *buf, size_t len) {
size_t remains = ub->len - ub->pos;
if (len > remains) {
size_t chunk_size = UMAX(len, (size_t) uwsgi.page_size);
if (ub->limit > 0 && ub->len + chunk_size > ub->limit) {
// retry with another minimal size
if (len < (size_t) uwsgi.page_size) {
chunk_size = len;
}
if (ub->len + chunk_size > ub->limit)
return -1;
}
char *new_buf = realloc(ub->buf, ub->len + chunk_size);
if (!new_buf) {
uwsgi_error("uwsgi_buffer_append()");
return -1;
}
ub->buf = new_buf;
ub->len += chunk_size;
}
memcpy(ub->buf + ub->pos, buf, len);
ub->pos += len;
return 0;
}
int uwsgi_buffer_append_json(struct uwsgi_buffer *ub, char *buf, size_t len) {
// need to escape \ and "
size_t i;
for(i=0;i<len;i++) {
if (buf[i] == '"') {
if (uwsgi_buffer_append(ub, "\\\"", 2)) return -1;
}
else if (buf[i] == '\\') {
if (uwsgi_buffer_append(ub, "\\\\", 2)) return -1;
}
else {
if (uwsgi_buffer_append(ub, buf+i, 1)) return -1;
}
}
return 0;
}
int uwsgi_buffer_u16le(struct uwsgi_buffer *ub, uint16_t num) {
uint8_t buf[2];
buf[0] = (uint8_t) (num & 0xff);
buf[1] = (uint8_t) ((num >> 8) & 0xff);
return uwsgi_buffer_append(ub, (char *) buf, 2);
}
int uwsgi_buffer_u16be(struct uwsgi_buffer *ub, uint16_t num) {
uint8_t buf[2];
buf[1] = (uint8_t) (num & 0xff);
buf[0] = (uint8_t) ((num >> 8) & 0xff);
return uwsgi_buffer_append(ub, (char *) buf, 2);
}
int uwsgi_buffer_u24be(struct uwsgi_buffer *ub, uint32_t num) {
uint8_t buf[3];
buf[2] = (uint8_t) (num & 0xff);
buf[1] = (uint8_t) ((num >> 8) & 0xff);
buf[0] = (uint8_t) ((num >> 16) & 0xff);
return uwsgi_buffer_append(ub, (char *) buf, 3);
}
int uwsgi_buffer_u32be(struct uwsgi_buffer *ub, uint32_t num) {
uint8_t buf[4];
buf[3] = (uint8_t) (num & 0xff);
buf[2] = (uint8_t) ((num >> 8) & 0xff);
buf[1] = (uint8_t) ((num >> 16) & 0xff);
buf[0] = (uint8_t) ((num >> 24) & 0xff);
return uwsgi_buffer_append(ub, (char *) buf, 4);
}
int uwsgi_buffer_u32le(struct uwsgi_buffer *ub, uint32_t num) {
uint8_t buf[4];
buf[0] = (uint8_t) (num & 0xff);
buf[1] = (uint8_t) ((num >> 8) & 0xff);
buf[2] = (uint8_t) ((num >> 16) & 0xff);
buf[3] = (uint8_t) ((num >> 24) & 0xff);
return uwsgi_buffer_append(ub, (char *) buf, 4);
}
int uwsgi_buffer_u64be(struct uwsgi_buffer *ub, uint64_t num) {
uint8_t buf[8];
buf[7] = (uint8_t) (num & 0xff);
buf[6] = (uint8_t) ((num >> 8) & 0xff);
buf[5] = (uint8_t) ((num >> 16) & 0xff);
buf[4] = (uint8_t) ((num >> 24) & 0xff);
buf[3] = (uint8_t) ((num >> 32) & 0xff);
buf[2] = (uint8_t) ((num >> 40) & 0xff);
buf[1] = (uint8_t) ((num >> 48) & 0xff);
buf[0] = (uint8_t) ((num >> 56) & 0xff);
return uwsgi_buffer_append(ub, (char *) buf, 8);
}
int uwsgi_buffer_append_ipv4(struct uwsgi_buffer *ub, void *addr) {
char ip[INET_ADDRSTRLEN];
if (!inet_ntop(AF_INET, addr, ip, INET_ADDRSTRLEN)) {
uwsgi_error("uwsgi_buffer_append_ipv4() -> inet_ntop()");
return -1;
}
return uwsgi_buffer_append(ub, ip, strlen(ip));
}
int uwsgi_buffer_num64(struct uwsgi_buffer *ub, int64_t num) {
char buf[sizeof(UMAX64_STR)+1];
int ret = snprintf(buf, sizeof(UMAX64_STR)+1, "%lld", (long long) num);
if (ret <= 0 || ret > (int) (sizeof(UMAX64_STR)+1)) {
return -1;
}
return uwsgi_buffer_append(ub, buf, ret);
}
int uwsgi_buffer_append_keyval(struct uwsgi_buffer *ub, char *key, uint16_t keylen, char *val, uint16_t vallen) {
if (uwsgi_buffer_u16le(ub, keylen)) return -1;
if (uwsgi_buffer_append(ub, key, keylen)) return -1;
if (uwsgi_buffer_u16le(ub, vallen)) return -1;
return uwsgi_buffer_append(ub, val, vallen);
}
int uwsgi_buffer_append_keyval32(struct uwsgi_buffer *ub, char *key, uint32_t keylen, char *val, uint32_t vallen) {
if (uwsgi_buffer_u32be(ub, keylen)) return -1;
if (uwsgi_buffer_append(ub, key, keylen)) return -1;
if (uwsgi_buffer_u32be(ub, vallen)) return -1;
return uwsgi_buffer_append(ub, val, vallen);
}
int uwsgi_buffer_append_keynum(struct uwsgi_buffer *ub, char *key, uint16_t keylen, int64_t num) {
char buf[sizeof(UMAX64_STR)+1];
int ret = snprintf(buf, (sizeof(UMAX64_STR)+1), "%lld", (long long) num);
if (ret <= 0 || ret > (int) (sizeof(UMAX64_STR)+1)) {
return -1;
}
if (uwsgi_buffer_u16le(ub, keylen)) return -1;
if (uwsgi_buffer_append(ub, key, keylen)) return -1;
if (uwsgi_buffer_u16le(ub, ret)) return -1;
return uwsgi_buffer_append(ub, buf, ret);
}
int uwsgi_buffer_append_valnum(struct uwsgi_buffer *ub, int64_t num) {
char buf[sizeof(UMAX64_STR)+1];
int ret = snprintf(buf, (sizeof(UMAX64_STR)+1), "%lld", (long long) num);
if (ret <= 0 || ret > (int) (sizeof(UMAX64_STR)+1)) {
return -1;
}
if (uwsgi_buffer_u16le(ub, ret)) return -1;
return uwsgi_buffer_append(ub, buf, ret);
}
int uwsgi_buffer_append_keyipv4(struct uwsgi_buffer *ub, char *key, uint16_t keylen, void *addr) {
if (uwsgi_buffer_u16le(ub, keylen)) return -1;
if (uwsgi_buffer_append(ub, key, keylen)) return -1;
if (uwsgi_buffer_u16le(ub, 15)) return -1;
char *ptr = ub->buf + (ub->pos - 2);
if (uwsgi_buffer_append_ipv4(ub, addr)) return -1;
// fix the size
*ptr = ((ub->buf+ub->pos) - (ptr+2));
return 0;
}
int uwsgi_buffer_append_base64(struct uwsgi_buffer *ub, char *s, size_t len) {
size_t b64_len = 0;
char *b64 = uwsgi_base64_encode(s, len, &b64_len);
if (!b64) return -1;
int ret = uwsgi_buffer_append(ub, b64, b64_len);
free(b64);
return ret;
}
void uwsgi_buffer_destroy(struct uwsgi_buffer *ub) {
if (ub->buf)
free(ub->buf);
free(ub);
}
ssize_t uwsgi_buffer_write_simple(struct wsgi_request *wsgi_req, struct uwsgi_buffer *ub) {
size_t remains = ub->pos;
while(remains) {
ssize_t len = write(wsgi_req->fd, ub->buf + (ub->pos - remains), remains);
if (len <= 0) {
return len;
}
remains -= len;
}
return ub->pos;
}
int uwsgi_buffer_send(struct uwsgi_buffer *ub, int fd) {
size_t remains = ub->pos;
char *ptr = ub->buf;
while (remains > 0) {
int ret = uwsgi_waitfd_write(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
if (ret > 0) {
ssize_t len = write(fd, ptr, remains);
if (len > 0) {
ptr += len;
remains -= len;
}
else if (len == 0) {
return -1;
}
else {
uwsgi_error("uwsgi_buffer_send()");
return -1;
}
}
else if (ret == 0) {
uwsgi_log("timeout while sending buffer !!!\n");
return -1;
}
else {
return -1;
}
}
return 0;
}
int uwsgi_buffer_set_uh(struct uwsgi_buffer *ub, uint8_t modifier1, uint8_t modifier2) {
if (ub->pos < 4) return -1;
ub->buf[0] = modifier1;
ub->buf[1] = (uint8_t) ((ub->pos - 4) & 0xff);
ub->buf[2] = (uint8_t) (((ub->pos - 4) >> 8) & 0xff);
ub->buf[3] = modifier2;
return 0;
}
struct uwsgi_buffer *uwsgi_buffer_from_file(char *filename) {
struct stat st;
int fd = open(filename, O_RDONLY);
if (fd < 0) {
return NULL;
}
if (fstat(fd, &st)) {
close(fd);
return NULL;
}
struct uwsgi_buffer *ub = uwsgi_buffer_new(st.st_size);
ssize_t len = read(fd, ub->buf, st.st_size);
close(fd);
if (len != st.st_size) {
uwsgi_buffer_destroy(ub);
return NULL;
}
ub->pos = len;
return ub;
}
+1698
View File
File diff suppressed because it is too large Load Diff
+46
View File
@@ -0,0 +1,46 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
// in the future we will need to use the best clock source for each os/system
time_t uwsgi_now() {
return uwsgi.clock->seconds();
}
uint64_t uwsgi_micros() {
return uwsgi.clock->microseconds();
}
void uwsgi_register_clock(struct uwsgi_clock *clock) {
struct uwsgi_clock *clocks = uwsgi.clocks;
clock->next = NULL;
if (!clocks) {
uwsgi.clocks = clock;
return;
}
while (clocks) {
if (!clocks->next) {
clocks->next = clock;
return;
}
clocks = clocks->next;
}
}
void uwsgi_set_clock(char *name) {
struct uwsgi_clock *clocks = uwsgi.clocks;
while (clocks) {
if (!strcmp(name, clocks->name)) {
uwsgi.clock = clocks;
return;
}
clocks = clocks->next;
}
uwsgi_log("unable to set \"%s\" clock\n", name);
exit(1);
}
+33
View File
@@ -0,0 +1,33 @@
#include <uwsgi.h>
/*
pluggable configuration system
*/
extern struct uwsgi_server uwsgi;
struct uwsgi_configurator *uwsgi_register_configurator(char *name, void (*func)(char *, char **)) {
struct uwsgi_configurator *old_uc = NULL,*uc = uwsgi.configurators;
while(uc) {
if (!strcmp(uc->name, name)) {
return uc;
}
old_uc = uc;
uc = uc->next;
}
uc = uwsgi_calloc(sizeof(struct uwsgi_configurator));
uc->name = name;
uc->func = func;
if (old_uc) {
old_uc->next = uc;
}
else {
uwsgi.configurators = uc;
}
return uc;
}
+81
View File
@@ -0,0 +1,81 @@
#include <uwsgi.h>
/*
cookie management functions (mainly used by the internal routing subsystem)
*/
static char *check_cookie(char *cookie, uint16_t cookie_len, char *key, uint16_t keylen, uint16_t *vallen) {
uint16_t orig_cookie_len = cookie_len-1;
// first lstrip white spaces
char *ptr = cookie;
uint16_t i;
for(i=0;i<cookie_len;i++) {
if (isspace((int)ptr[i])) {
cookie++;
cookie_len--;
}
else {
break;
}
}
// then rstrip (skipping the first char...)
for(i=orig_cookie_len;i>0;i--) {
if (isspace((int)ptr[i])) {
cookie_len--;
}
else {
break;
}
}
// now search for the first equal sign
char *equal = memchr(cookie, '=', cookie_len);
if (!equal) return NULL;
if (uwsgi_strncmp(key, keylen, cookie, equal-cookie)) {
return NULL;
}
cookie_len -= (equal-cookie)+1;
if (cookie_len == 0) return NULL;
*vallen = cookie_len;
return equal+1;
}
char *uwsgi_get_cookie(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
uint16_t i;
char *cookie = wsgi_req->cookie;
uint16_t cookie_len = 0;
char *ptr = wsgi_req->cookie;
//start splitting by ;
for(i=0;i<wsgi_req->cookie_len;i++) {
if (!cookie) {
cookie = ptr + i;
}
if (ptr[i] == ';') {
char *value = check_cookie(cookie, cookie_len, key, keylen, vallen);
if (value) {
return value;
}
cookie_len = 0;
cookie = NULL;
}
else {
cookie_len++;
}
}
if (cookie_len > 0) {
char *value = check_cookie(cookie, cookie_len, key, keylen, vallen);
if (value) {
return value;
}
}
return NULL;
}
+312
View File
@@ -0,0 +1,312 @@
#include "../uwsgi.h"
extern struct uwsgi_server uwsgi;
/*
External uwsgi daemons
There are 3 kind of daemons (read: external applications) that can be managed
by uWSGI.
1) dumb daemons (attached with --attach-daemon)
they must not daemonize() and when they exit() the master is notified (via waitpid)
and the process is respawned
2) smart daemons with daemonization
you specify a pidfile and a command
- on startup - if the pidfile does not exists or contains a not-available pid (checked with kill(pid, 0))
the daemon is respawned
- on master ckeck - if the pidfile does not exist or if it point to a non-existent pid
the daemon is respawned
3) smart daemons without daemonization
same as 2, but the daemonization and pidfile creation is managed by uWSGI
status:
0 -> never started
1 -> just started
2 -> started and monitored (only in pidfile based)
*/
void uwsgi_daemons_smart_check() {
static time_t last_run = 0;
time_t now = uwsgi_now();
if (now - last_run <= 0) {
return;
}
last_run = now;
struct uwsgi_daemon *ud = uwsgi.daemons;
while (ud) {
if (ud->pidfile) {
int checked_pid = uwsgi_check_pidfile(ud->pidfile);
if (checked_pid <= 0) {
// monitored instance
if (ud->status == 2) {
uwsgi_spawn_daemon(ud);
}
else {
ud->pidfile_checks++;
if (ud->pidfile_checks >= (unsigned int) ud->freq) {
uwsgi_log("[uwsgi-daemons] found changed pidfile for \"%s\" (old_pid: %d new_pid: %d)\n", ud->command, (int) ud->pid, (int) checked_pid);
uwsgi_spawn_daemon(ud);
}
}
}
else if (checked_pid != ud->pid) {
uwsgi_log("[uwsgi-daemons] found changed pid for \"%s\" (old_pid: %d new_pid: %d)\n", ud->command, (int) ud->pid, (int) checked_pid);
ud->pid = checked_pid;
}
// all ok, pidfile and process found
else {
ud->status = 2;
}
}
ud = ud->next;
}
}
// this function is called when a dumb daemon dies and we do not wat to respawn it
int uwsgi_daemon_check_pid_death(pid_t diedpid) {
struct uwsgi_daemon *ud = uwsgi.daemons;
while (ud) {
if (ud->pid == diedpid && !ud->pidfile) {
uwsgi_log("daemon \"%s\" (pid: %d) annihilated\n", ud->command, (int) diedpid);
return -1;
}
ud = ud->next;
}
return 0;
}
// this function is called when a dumb daemon dies and we want to respawn it
int uwsgi_daemon_check_pid_reload(pid_t diedpid) {
struct uwsgi_daemon *ud = uwsgi.daemons;
while (ud) {
if (ud->pid == diedpid && !ud->pidfile) {
uwsgi_spawn_daemon(ud);
return 1;
}
ud = ud->next;
}
return 0;
}
int uwsgi_check_pidfile(char *filename) {
struct stat st;
pid_t ret = -1;
int fd = open(filename, O_RDONLY);
if (fd < 0) {
uwsgi_error_open(filename);
goto end;
}
if (fstat(fd, &st)) {
uwsgi_error("fstat()");
goto end2;
}
char *pidstr = uwsgi_calloc(st.st_size + 1);
if (read(fd, pidstr, st.st_size) != st.st_size) {
uwsgi_error("read()");
goto end3;
}
pid_t pid = atoi(pidstr);
if (pid <= 0)
goto end3;
if (!kill(pid, 0)) {
ret = pid;
}
end3:
free(pidstr);
end2:
close(fd);
end:
return ret;
}
void uwsgi_daemons_spawn_all() {
struct uwsgi_daemon *ud = uwsgi.daemons;
while (ud) {
if (!ud->registered) {
if (ud->pidfile) {
int checked_pid = uwsgi_check_pidfile(ud->pidfile);
if (checked_pid <= 0) {
uwsgi_spawn_daemon(ud);
}
else {
ud->pid = checked_pid;
uwsgi_log("[uwsgi-daemons] found valid/active pidfile for \"%s\" (pid: %d)\n", ud->command, (int) ud->pid);
}
}
else {
uwsgi_spawn_daemon(ud);
}
ud->registered = 1;
}
ud = ud->next;
}
}
void uwsgi_detach_daemons() {
struct uwsgi_daemon *ud = uwsgi.daemons;
while (ud) {
if (ud->pid > 0 && !ud->pidfile)
kill(-ud->pid, SIGKILL);
ud = ud->next;
}
}
void uwsgi_spawn_daemon(struct uwsgi_daemon *ud) {
int devnull = -1;
int throttle = 0;
if (uwsgi.current_time - ud->last_spawn <= 3) {
throttle = ud->respawns - (uwsgi.current_time - ud->last_spawn);
}
pid_t pid = uwsgi_fork("uWSGI external daemon");
if (pid < 0) {
uwsgi_error("fork()");
return;
}
if (pid > 0) {
ud->pid = pid;
ud->status = 1;
ud->pidfile_checks = 0;
if (ud->respawns == 0) {
ud->born = uwsgi_now();
}
ud->respawns++;
ud->last_spawn = uwsgi_now();
}
else {
// close uwsgi sockets
uwsgi_close_all_sockets();
uwsgi_close_all_fds();
if (ud->daemonize) {
/* refork... */
pid = fork();
if (pid < 0) {
uwsgi_error("fork()");
exit(1);
}
if (pid != 0) {
_exit(0);
}
uwsgi_write_pidfile(ud->pidfile);
}
// /dev/null will became stdin
devnull = open("/dev/null", O_RDONLY);
if (devnull < 0) {
uwsgi_error("/dev/null open()");
exit(1);
}
if (devnull != 0) {
if (dup2(devnull, 0) < 0) {
uwsgi_error("dup2()");
exit(1);
}
close(devnull);
}
if (setsid() < 0) {
uwsgi_error("setsid()");
exit(1);
}
if (!ud->pidfile) {
#ifdef __linux__
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
uwsgi_error("prctl()");
}
#endif
}
if (throttle) {
uwsgi_log("[uwsgi-daemons] throttling \"%s\" for %d seconds\n", ud->command, throttle);
sleep(throttle);
}
uwsgi_log("[uwsgi-daemons] %sspawning \"%s\"\n", ud->respawns > 0 ? "re" : "", ud->command);
uwsgi_exec_command_with_args(ud->command);
uwsgi_log("[uwsgi-daemons] unable to spawn \"%s\"\n", ud->command);
// never here;
exit(1);
}
return;
}
void uwsgi_opt_add_daemon(char *opt, char *value, void *none) {
struct uwsgi_daemon *uwsgi_ud = uwsgi.daemons, *old_ud;
char *pidfile = NULL;
int daemonize = 0;
int freq = 10;
char *command = uwsgi_str(value);
if (!strcmp(opt, "smart-attach-daemon") || !strcmp(opt, "smart-attach-daemon2")) {
char *space = strchr(command, ' ');
if (!space) {
uwsgi_log("invalid smart-attach-daemon syntax: %s\n", command);
exit(1);
}
*space = 0;
pidfile = command;
// check for freq
char *comma = strchr(pidfile, ',');
if (comma) {
*comma = 0;
freq = atoi(comma + 1);
}
command = space + 1;
if (!strcmp(opt, "smart-attach-daemon2")) {
daemonize = 1;
}
}
if (!uwsgi_ud) {
uwsgi.daemons = uwsgi_malloc(sizeof(struct uwsgi_daemon));
uwsgi_ud = uwsgi.daemons;
}
else {
while (uwsgi_ud) {
old_ud = uwsgi_ud;
uwsgi_ud = uwsgi_ud->next;
}
uwsgi_ud = uwsgi_malloc(sizeof(struct uwsgi_daemon));
old_ud->next = uwsgi_ud;
}
uwsgi_ud->command = command;
uwsgi_ud->pid = 0;
uwsgi_ud->status = 0;
uwsgi_ud->freq = freq;
uwsgi_ud->registered = 0;
uwsgi_ud->next = NULL;
uwsgi_ud->respawns = 0;
uwsgi_ud->last_spawn = 0;
uwsgi_ud->daemonize = daemonize;
uwsgi_ud->pidfile = pidfile;
uwsgi.daemons_cnt++;
}
+1699
View File
File diff suppressed because it is too large Load Diff
+45
View File
@@ -0,0 +1,45 @@
#include <uwsgi.h>
// generate internal server error message
void uwsgi_500(struct wsgi_request *wsgi_req) {
if (uwsgi_response_prepare_headers(wsgi_req, "500 Internal Server Error", 25)) return;
if (uwsgi_response_add_connection_close(wsgi_req)) return;
uwsgi_response_write_body_do(wsgi_req, "Internal Server Error", 21);
}
void uwsgi_404(struct wsgi_request *wsgi_req) {
if (uwsgi_response_prepare_headers(wsgi_req, "404 Not Found", 13)) return;
if (uwsgi_response_add_connection_close(wsgi_req)) return;
if (uwsgi_response_add_header(wsgi_req, "Content-Type", 12, "text/plain", 10)) return;
uwsgi_response_write_body_do(wsgi_req, "Not Found", 9);
}
void uwsgi_403(struct wsgi_request *wsgi_req) {
if (uwsgi_response_prepare_headers(wsgi_req, "403 Forbidden", 13)) return;
if (uwsgi_response_add_connection_close(wsgi_req)) return;
if (uwsgi_response_add_content_type(wsgi_req, "text/plain", 10)) return;
uwsgi_response_write_body_do(wsgi_req, "Forbidden", 9);
}
void uwsgi_redirect_to_slash(struct wsgi_request *wsgi_req) {
char *redirect = NULL;
size_t redirect_len = 0;
if (uwsgi_response_prepare_headers(wsgi_req, "301 Moved Permanently", 21)) return;
if (uwsgi_response_add_connection_close(wsgi_req)) return;
if (wsgi_req->query_string_len == 0) {
redirect = uwsgi_concat2n(wsgi_req->path_info, wsgi_req->path_info_len, "/", 1);
redirect_len = wsgi_req->path_info_len + 1;
}
else {
redirect = uwsgi_concat3n(wsgi_req->path_info, wsgi_req->path_info_len, "/?", 2, wsgi_req->query_string, wsgi_req->query_string_len);
redirect_len = wsgi_req->path_info_len + 2 + wsgi_req->query_string_len;
}
uwsgi_response_add_header(wsgi_req, "Location", 8, redirect, redirect_len);
free(redirect);
return;
}
+1394
View File
File diff suppressed because it is too large Load Diff
+499
View File
@@ -0,0 +1,499 @@
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
/*
Exceptions management
generally exceptions are printed in the logs, but if you enable
an exception manager they will be stored in a (relatively big) uwsgi packet
with the following structure.
"vars" -> keyval of request vars
"backtrace" -> list of backtrace lines. Each line is a list of 5 elements filename,line,function,text,custom
"unix" -> seconds since the epoch
"class" -> the exception class
"msg" -> a text message mapped to the extension
"repr" -> a text message mapped to the extension in language-specific gergo
"wid" -> worker id
"core" -> the core generating the exception
"pid" -> pid of the worker
"node" -> hostname
Other vars can be added, but you cannot be sure they will be used by exceptions handler.
The exception-uwsgi packet is passed "as is" to the exception handler
Exceptions hooks:
a request plugin can export that hooks:
struct uwsgi_buffer *backtrace(struct wsgi_request *);
struct uwsgi_buffer *exception_class(struct wsgi_request *);
struct uwsgi_buffer *exception_msg(struct wsgi_request *);
struct uwsgi_buffer *exception_repr(struct wsgi_request *);
void exception_log(struct wsgi_request *);
Remember to reset the exception status (if possibile) after each call
Exceptions catcher:
This is a special development-mode in which exceptions are printed
to the HTTP client.
*/
struct uwsgi_buffer *uwsgi_exception_handler_object(struct wsgi_request *wsgi_req) {
struct uwsgi_buffer *ub = uwsgi_buffer_new(4096);
if (uwsgi_buffer_append_keyval(ub, "vars", 4, wsgi_req->buffer,wsgi_req->uh->pktsize)) goto error;
if (uwsgi.p[wsgi_req->uh->modifier1]->backtrace) {
struct uwsgi_buffer *bt = uwsgi.p[wsgi_req->uh->modifier1]->backtrace(wsgi_req);
if (bt) {
if (uwsgi_buffer_append_keyval(ub, "backtrace", 9, bt->buf, bt->pos)) {
uwsgi_buffer_destroy(bt);
goto error;
}
uwsgi_buffer_destroy(bt);
}
}
if (uwsgi.p[wsgi_req->uh->modifier1]->exception_class) {
struct uwsgi_buffer *ec = uwsgi.p[wsgi_req->uh->modifier1]->exception_class(wsgi_req);
if (ec) {
if (uwsgi_buffer_append_keyval(ub, "class", 5, ec->buf, ec->pos)) {
uwsgi_buffer_destroy(ec);
goto error;
}
uwsgi_buffer_destroy(ec);
}
}
if (uwsgi.p[wsgi_req->uh->modifier1]->exception_msg) {
struct uwsgi_buffer *em = uwsgi.p[wsgi_req->uh->modifier1]->exception_msg(wsgi_req);
if (em) {
if (uwsgi_buffer_append_keyval(ub, "msg", 3, em->buf, em->pos)) {
uwsgi_buffer_destroy(em);
goto error;
}
uwsgi_buffer_destroy(em);
}
}
if (uwsgi.p[wsgi_req->uh->modifier1]->exception_repr) {
struct uwsgi_buffer *er = uwsgi.p[wsgi_req->uh->modifier1]->exception_repr(wsgi_req);
if (er) {
if (uwsgi_buffer_append_keyval(ub, "repr", 4, er->buf, er->pos)) {
uwsgi_buffer_destroy(er);
goto error;
}
uwsgi_buffer_destroy(er);
}
}
if (uwsgi_buffer_append_keynum(ub, "unix", 4, uwsgi_now())) goto error;
if (uwsgi_buffer_append_keynum(ub, "wid", 3, uwsgi.mywid)) goto error;
if (uwsgi_buffer_append_keynum(ub, "pid", 3, uwsgi.mypid)) goto error;
if (uwsgi_buffer_append_keynum(ub, "core", 4, wsgi_req->async_id)) goto error;
if (uwsgi_buffer_append_keyval(ub, "node", 4, uwsgi.hostname, uwsgi.hostname_len)) goto error;
return ub;
error:
uwsgi_buffer_destroy(ub);
return NULL;
}
static void append_vars_to_ubuf(char *key, uint16_t keylen, char *val, uint16_t vallen, void *data) {
struct uwsgi_buffer *ub = (struct uwsgi_buffer *) data;
if (uwsgi_buffer_append(ub, key, keylen)) return;
if (uwsgi_buffer_append(ub, " = ", 3)) return;
if (uwsgi_buffer_append(ub, val, vallen)) return;
if (uwsgi_buffer_append(ub, "\n", 1)) return;
}
static void append_backtrace_to_ubuf(uint16_t pos, char *value, uint16_t len, void *data) {
struct uwsgi_buffer *ub = (struct uwsgi_buffer *) data;
uint16_t item = 0;
if (pos > 0) {
item = pos % 5;
}
switch(item) {
// filename
case 0:
if (uwsgi_buffer_append(ub, "filename: \"", 11)) return;
if (uwsgi_buffer_append(ub, value, len)) return;
if (uwsgi_buffer_append(ub, "\" ", 2)) return;
break;
// lineno
case 1:
if (uwsgi_buffer_append(ub, "line: ", 6)) return;
if (uwsgi_buffer_append(ub, value, len)) return;
if (uwsgi_buffer_append(ub, " ", 1)) return;
break;
// function
case 2:
if (uwsgi_buffer_append(ub, "function: \"", 11)) return;
if (uwsgi_buffer_append(ub, value, len)) return;
if (uwsgi_buffer_append(ub, "\" ", 2)) return;
break;
// text
case 3:
if (len > 0) {
if (uwsgi_buffer_append(ub, "text/code: \"", 12)) return;
if (uwsgi_buffer_append(ub, value, len)) return;
if (uwsgi_buffer_append(ub, "\" ", 2)) return;
}
break;
// custom
case 4:
if (len > 0) {
if (uwsgi_buffer_append(ub, "custom: \"", 9)) return;
if (uwsgi_buffer_append(ub, value, len)) return;
if (uwsgi_buffer_append(ub, "\" ", 2)) return;
}
if (uwsgi_buffer_append(ub, "\n", 1)) return;
break;
default:
break;
}
}
int uwsgi_exceptions_catch(struct wsgi_request *wsgi_req) {
if (uwsgi_response_prepare_headers(wsgi_req, "500 Internal Server Error", 25)) {
return -1;
}
if (uwsgi_response_add_content_type(wsgi_req, "text/plain", 10)) {
return -1;
}
struct uwsgi_buffer *ub = uwsgi_buffer_new(4096);
if (uwsgi_buffer_append(ub, "uWSGI exceptions catcher for \"", 30)) goto error;
if (uwsgi_buffer_append(ub, wsgi_req->method, wsgi_req->method_len)) goto error;
if (uwsgi_buffer_append(ub, " ", 1)) goto error;
if (uwsgi_buffer_append(ub, wsgi_req->uri, wsgi_req->uri_len)) goto error;
if (uwsgi_buffer_append(ub, "\" (request plugin: \"", 20)) goto error;
if (uwsgi_buffer_append(ub, (char *) uwsgi.p[wsgi_req->uh->modifier1]->name, strlen(uwsgi.p[wsgi_req->uh->modifier1]->name))) goto error;
if (uwsgi_buffer_append(ub, "\", modifier1: ", 14 )) goto error;
if (uwsgi_buffer_num64(ub, wsgi_req->uh->modifier1)) goto error;
if (uwsgi_buffer_append(ub, ")\n\n", 3)) goto error;
if (uwsgi_buffer_append(ub, "Exception: ", 11)) goto error;
if (uwsgi.p[wsgi_req->uh->modifier1]->exception_repr) {
struct uwsgi_buffer *ub_exc_repr = uwsgi.p[wsgi_req->uh->modifier1]->exception_repr(wsgi_req);
if (ub_exc_repr) {
if (uwsgi_buffer_append(ub, ub_exc_repr->buf, ub_exc_repr->pos)) {
uwsgi_buffer_destroy(ub_exc_repr);
goto error;
}
uwsgi_buffer_destroy(ub_exc_repr);
}
else {
goto notavail3;
}
}
else {
notavail3:
if (uwsgi_buffer_append(ub, "-Not available-", 15)) goto error;
}
if (uwsgi_buffer_append(ub, "\n\n", 2)) goto error;
if (uwsgi_buffer_append(ub, "Exception class: ", 17)) goto error;
if (uwsgi.p[wsgi_req->uh->modifier1]->exception_class) {
struct uwsgi_buffer *ub_exc_class = uwsgi.p[wsgi_req->uh->modifier1]->exception_class(wsgi_req);
if (ub_exc_class) {
if (uwsgi_buffer_append(ub, ub_exc_class->buf, ub_exc_class->pos)) {
uwsgi_buffer_destroy(ub_exc_class);
goto error;
}
uwsgi_buffer_destroy(ub_exc_class);
}
else {
goto notavail;
}
}
else {
notavail:
if (uwsgi_buffer_append(ub, "-Not available-", 15)) goto error;
}
if (uwsgi_buffer_append(ub, "\n\n", 2)) goto error;
if (uwsgi_buffer_append(ub, "Exception message: ", 19)) goto error;
if (uwsgi.p[wsgi_req->uh->modifier1]->exception_msg) {
struct uwsgi_buffer *ub_exc_msg = uwsgi.p[wsgi_req->uh->modifier1]->exception_msg(wsgi_req);
if (ub_exc_msg) {
if (uwsgi_buffer_append(ub, ub_exc_msg->buf, ub_exc_msg->pos)) {
uwsgi_buffer_destroy(ub_exc_msg);
goto error;
}
uwsgi_buffer_destroy(ub_exc_msg);
}
else {
goto notavail2;
}
}
else {
notavail2:
if (uwsgi_buffer_append(ub, "-Not available-", 15)) goto error;
}
if (uwsgi_buffer_append(ub, "\n\n", 2)) goto error;
if (uwsgi_buffer_append(ub, "Backtrace:\n", 11)) goto error;
if (uwsgi.p[wsgi_req->uh->modifier1]->backtrace) {
struct uwsgi_buffer *ub_exc_bt = uwsgi.p[wsgi_req->uh->modifier1]->backtrace(wsgi_req);
if (ub_exc_bt) {
struct uwsgi_buffer *parsed_bt = uwsgi_buffer_new(4096);
if (uwsgi_hooked_parse_array(ub_exc_bt->buf, ub_exc_bt->pos, append_backtrace_to_ubuf, parsed_bt)) {
uwsgi_buffer_destroy(ub_exc_bt);
uwsgi_buffer_destroy(parsed_bt);
goto error;
}
uwsgi_buffer_destroy(ub_exc_bt);
if (uwsgi_buffer_append(ub, parsed_bt->buf, parsed_bt->pos)) {
uwsgi_buffer_destroy(parsed_bt);
goto error;
}
uwsgi_buffer_destroy(parsed_bt);
}
else {
goto notavail4;
}
}
else {
notavail4:
if (uwsgi_buffer_append(ub, "-Not available-", 15)) goto error;
}
if (uwsgi_buffer_append(ub, "\n\n", 2)) goto error;
if (uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->uh->pktsize, append_vars_to_ubuf, ub)) {
goto error;
}
if (uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos)) {
goto error;
}
uwsgi_buffer_destroy(ub);
return 0;
error:
uwsgi_buffer_destroy(ub);
return -1;
}
static void uwsgi_exception_run_handlers(struct uwsgi_buffer *ub) {
struct uwsgi_string_list *usl = uwsgi.exception_handlers_instance;
struct iovec iov[2];
iov[1].iov_base = ub->buf;
iov[1].iov_len = ub->pos;
while(usl) {
struct uwsgi_exception_handler_instance *uehi = (struct uwsgi_exception_handler_instance *) usl->custom_ptr;
iov[0].iov_base = &uehi;
iov[0].iov_len = sizeof(long);
// now send the message to the exception handler thread
if (writev(uwsgi.exception_handler_thread->pipe[0], iov, 2) != (ssize_t) (ub->pos+sizeof(long))) {
uwsgi_error("[uwsgi-exception-handler-error] uwsgi_exception_run_handlers()/writev()");
}
usl = usl->next;
}
}
void uwsgi_manage_exception(struct wsgi_request *wsgi_req,int catch) {
int do_exit = uwsgi.reload_on_exception;
if (!wsgi_req) goto log2;
if (do_exit) goto check_catch;
if (wsgi_req && uwsgi.exception_handlers_instance) {
struct uwsgi_buffer *ehi = uwsgi_exception_handler_object(wsgi_req);
if (ehi) {
uwsgi_exception_run_handlers(ehi);
uwsgi_buffer_destroy(ehi);
}
}
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].exceptions++;
uwsgi_apps[wsgi_req->app_id].exceptions++;
if (uwsgi.reload_on_exception_type && uwsgi.p[wsgi_req->uh->modifier1]->exception_class) {
struct uwsgi_buffer *ub = uwsgi.p[wsgi_req->uh->modifier1]->exception_msg(wsgi_req);
if (ub) {
struct uwsgi_string_list *usl = uwsgi.reload_on_exception_type;
while (usl) {
if (!uwsgi_strncmp(usl->value, usl->len, ub->buf, ub->len)) {
do_exit = 1;
uwsgi_buffer_destroy(ub);
goto check_catch;
}
usl = usl->next;
}
uwsgi_buffer_destroy(ub);
}
}
if (uwsgi.reload_on_exception_value && uwsgi.p[wsgi_req->uh->modifier1]->exception_msg) {
struct uwsgi_buffer *ub = uwsgi.p[wsgi_req->uh->modifier1]->exception_msg(wsgi_req);
if (ub) {
struct uwsgi_string_list *usl = uwsgi.reload_on_exception_value;
while (usl) {
if (!uwsgi_strncmp(usl->value, usl->len, ub->buf, ub->len)) {
do_exit = 1;
uwsgi_buffer_destroy(ub);
goto check_catch;
}
usl = usl->next;
}
uwsgi_buffer_destroy(ub);
}
}
if (uwsgi.reload_on_exception_repr && uwsgi.p[wsgi_req->uh->modifier1]->exception_repr) {
struct uwsgi_buffer *ub = uwsgi.p[wsgi_req->uh->modifier1]->exception_msg(wsgi_req);
if (ub) {
struct uwsgi_string_list *usl = uwsgi.reload_on_exception_repr;
while (usl) {
if (!uwsgi_strncmp(usl->value, usl->len, ub->buf, ub->len)) {
do_exit = 1;
uwsgi_buffer_destroy(ub);
goto check_catch;
}
usl = usl->next;
}
uwsgi_buffer_destroy(ub);
}
}
check_catch:
if (catch && wsgi_req) {
if (uwsgi_exceptions_catch(wsgi_req)) {
// for now, just goto, new features could be added
goto log;
}
}
log:
if (uwsgi.p[wsgi_req->uh->modifier1]->exception_log) {
uwsgi.p[wsgi_req->uh->modifier1]->exception_log(wsgi_req);
}
log2:
if (do_exit) {
exit(UWSGI_EXCEPTION_CODE);
}
}
struct uwsgi_exception_handler *uwsgi_register_exception_handler(char *name, int (*func)(struct uwsgi_exception_handler_instance *, char *, size_t)) {
struct uwsgi_exception_handler *old_ueh = NULL, *ueh = uwsgi.exception_handlers;
while(ueh) {
if (!strcmp(name, ueh->name)) {
return NULL;
}
old_ueh = ueh;
ueh = ueh->next;
}
ueh = uwsgi_calloc(sizeof(struct uwsgi_exception_handler));
ueh->name = name;
ueh->func = func;
if (old_ueh) {
old_ueh->next = ueh;
}
else {
uwsgi.exception_handlers = ueh;
}
return ueh;
}
struct uwsgi_exception_handler *uwsgi_exception_handler_by_name(char *name) {
struct uwsgi_exception_handler *ueh = uwsgi.exception_handlers;
while(ueh) {
if (!strcmp(name, ueh->name)) {
return ueh;
}
ueh = ueh->next;
}
return NULL;
}
static void uwsgi_exception_handler_thread_loop(struct uwsgi_thread *ut) {
char *buf = uwsgi_malloc(uwsgi.exception_handler_msg_size + sizeof(long));
for (;;) {
int interesting_fd = -1;
int ret = event_queue_wait(ut->queue, -1, &interesting_fd);
if (ret > 0) {
ssize_t len = read(ut->pipe[1], buf, uwsgi.alarm_msg_size + sizeof(long));
if (len > (ssize_t)(sizeof(long) + 1)) {
size_t msg_size = len - sizeof(long);
char *msg = buf + sizeof(long);
long ptr = 0;
memcpy(&ptr, buf, sizeof(long));
struct uwsgi_exception_handler_instance *uehi = (struct uwsgi_exception_handler_instance *) ptr;
if (!uehi)
break;
if (uehi->handler->func(uehi, msg, msg_size)) {
uwsgi_log("[uwsgi-exception] error running the handler \"%s\" args: \"%s\"\n", uehi->handler->name, uehi->arg ? uehi->arg : "");
}
}
}
}
free(buf);
}
void uwsgi_exception_setup_handlers() {
struct uwsgi_string_list *usl = uwsgi.exception_handlers_instance;
while(usl) {
char *handler = uwsgi_str(usl->value);
char *colon = strchr(handler, ':');
if (colon) {
*colon = 0;
}
struct uwsgi_exception_handler *ueh = uwsgi_exception_handler_by_name(handler);
if (!ueh) {
uwsgi_log("unable to find exception handler: %s\n", handler);
free(handler);
exit(1);
}
free(handler);
struct uwsgi_exception_handler_instance *uehi = uwsgi_calloc(sizeof(struct uwsgi_exception_handler_instance));
uehi->handler = ueh;
if (colon) {
uehi->arg = colon+1;
}
usl->custom_ptr = uehi;
usl = usl->next;
}
}
void uwsgi_exceptions_handler_thread_start() {
// start the exception_handler_thread
uwsgi.exception_handler_thread = uwsgi_thread_new(uwsgi_exception_handler_thread_loop);
if (!uwsgi.exception_handler_thread) {
uwsgi_log("unable to spawn exception handler thread\n");
exit(1);
}
}
+166
View File
@@ -0,0 +1,166 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
struct uwsgi_gateway *register_gateway(char *name, void (*loop) (int, void *), void *data) {
struct uwsgi_gateway *ug;
int num = 1, i;
if (ushared->gateways_cnt >= MAX_GATEWAYS) {
uwsgi_log("you can register max %d gateways\n", MAX_GATEWAYS);
return NULL;
}
for (i = 0; i < ushared->gateways_cnt; i++) {
if (!strcmp(name, ushared->gateways[i].name)) {
num++;
}
}
char *fullname = uwsgi_concat3(name, " ", uwsgi_num2str(num));
ug = &ushared->gateways[ushared->gateways_cnt];
ug->pid = 0;
ug->name = name;
ug->loop = loop;
ug->num = num;
ug->fullname = fullname;
ug->data = data;
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, ug->internal_subscription_pipe)) {
uwsgi_error("socketpair()");
}
if (!uwsgi.master_process)
gateway_respawn(ushared->gateways_cnt);
ushared->gateways_cnt++;
return ug;
}
static void gateway_brutal_end() {
_exit(UWSGI_END_CODE);
}
void gateway_respawn(int id) {
pid_t gw_pid;
struct uwsgi_gateway *ug = &ushared->gateways[id];
if (uwsgi.master_process)
uwsgi.shared->gateways_harakiri[id] = 0;
gw_pid = uwsgi_fork(ug->fullname);
if (gw_pid < 0) {
uwsgi_error("fork()");
return;
}
if (gw_pid == 0) {
uwsgi_fixup_fds(0, 0, ug);
if (uwsgi.master_as_root)
uwsgi_as_root();
#ifdef __linux__
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
uwsgi_error("prctl()");
}
#endif
uwsgi.mypid = getpid();
atexit(gateway_brutal_end);
signal(SIGALRM, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGINT, end_me);
signal(SIGTERM, end_me);
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGSTOP, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
ug->loop(id, ug->data);
// never here !!! (i hope)
exit(1);
}
ug->pid = gw_pid;
ug->respawns++;
if (ug->respawns == 1) {
uwsgi_log("spawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
}
else {
uwsgi_log("respawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
}
}
struct uwsgi_gateway_socket *uwsgi_new_gateway_socket(char *name, char *owner) {
struct uwsgi_gateway_socket *uwsgi_sock = uwsgi.gateway_sockets, *old_uwsgi_sock;
if (!uwsgi_sock) {
uwsgi.gateway_sockets = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
uwsgi_sock = uwsgi.gateway_sockets;
}
else {
while (uwsgi_sock) {
old_uwsgi_sock = uwsgi_sock;
uwsgi_sock = uwsgi_sock->next;
}
uwsgi_sock = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
old_uwsgi_sock->next = uwsgi_sock;
}
memset(uwsgi_sock, 0, sizeof(struct uwsgi_gateway_socket));
uwsgi_sock->fd = -1;
uwsgi_sock->shared = 0;
uwsgi_sock->name = name;
uwsgi_sock->name_len = strlen(name);
uwsgi_sock->owner = owner;
return uwsgi_sock;
}
struct uwsgi_gateway_socket *uwsgi_new_gateway_socket_from_fd(int fd, char *owner) {
struct uwsgi_gateway_socket *uwsgi_sock = uwsgi.gateway_sockets, *old_uwsgi_sock;
if (!uwsgi_sock) {
uwsgi.gateway_sockets = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
uwsgi_sock = uwsgi.gateway_sockets;
}
else {
while (uwsgi_sock) {
old_uwsgi_sock = uwsgi_sock;
uwsgi_sock = uwsgi_sock->next;
}
uwsgi_sock = uwsgi_malloc(sizeof(struct uwsgi_gateway_socket));
old_uwsgi_sock->next = uwsgi_sock;
}
memset(uwsgi_sock, 0, sizeof(struct uwsgi_gateway_socket));
uwsgi_sock->fd = fd;
uwsgi_sock->name = uwsgi_getsockname(fd);
uwsgi_sock->name_len = strlen(uwsgi_sock->name);
uwsgi_sock->owner = owner;
return uwsgi_sock;
}
void uwsgi_gateway_go_cheap(char *gw_id, int queue, int *i_am_cheap) {
uwsgi_log("[%s pid %d] no more nodes available. Going cheap...\n", gw_id, (int) uwsgi.mypid);
struct uwsgi_gateway_socket *ugs = uwsgi.gateway_sockets;
while (ugs) {
if (!strcmp(ugs->owner, gw_id) && !ugs->subscription) {
event_queue_del_fd(queue, ugs->fd, event_queue_read());
}
ugs = ugs->next;
}
*i_am_cheap = 1;
}
+93
View File
@@ -0,0 +1,93 @@
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
// Bernstein classic hash (this is not static as it is used by other areas)
uint32_t djb33x_hash(char *key, uint64_t keylen) {
register uint32_t hash = 5381;
uint64_t i;
for (i = 0; i < keylen; i++) {
hash = ((hash << 5) + hash) ^ key[i];
}
return hash;
}
// Murmur2 hash Copyright (C) Austin Appleby
// adapted from nginx
uint32_t murmur2_hash(char *key, uint64_t keylen) {
uint32_t h, k;
uint8_t *ukey = (uint8_t *) key;
h = 0 ^ keylen;
while (keylen >= 4) {
k = ukey[0];
k |= ukey[1] << 8;
k |= ukey[2] << 16;
k |= ukey[3] << 24;
k *= 0x5bd1e995;
k ^= k >> 24;
k *= 0x5bd1e995;
h *= 0x5bd1e995;
h ^= k;
ukey += 4;
keylen -= 4;
}
switch (keylen) {
case 3:
h ^= key[2] << 16;
case 2:
h ^= key[1] << 8;
case 1:
h ^= key[0];
h *= 0x5bd1e995;
}
h ^= h >> 13;
h *= 0x5bd1e995;
h ^= h >> 15;
return h;
}
struct uwsgi_hash_algo *uwsgi_hash_algo_get(char *name) {
struct uwsgi_hash_algo *uha = uwsgi.hash_algos;
while(uha) {
if (!strcmp(name, uha->name)) {
return uha;
}
uha = uha->next;
}
return NULL;
}
void uwsgi_hash_algo_register(char *name, uint32_t (*func)(char *, uint64_t)) {
struct uwsgi_hash_algo *old_uha = NULL, *uha = uwsgi.hash_algos;
while(uha) {
if (!strcmp(uha->name, name)) return;
old_uha = uha;
uha = uha->next;
}
uha = uwsgi_calloc(sizeof(struct uwsgi_hash_algo));
uha->name = name;
uha->func = func;
if (old_uha) {
old_uha->next = uha;
}
else {
uwsgi.hash_algos = uha;
}
}
void uwsgi_hash_algo_register_all() {
uwsgi_hash_algo_register("djb33x", djb33x_hash);
uwsgi_hash_algo_register("murmur2", murmur2_hash);
}
+36 -27
View File
@@ -1,6 +1,4 @@
#ifdef UWSGI_INI
#include "uwsgi.h"
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
@@ -9,12 +7,14 @@ extern struct uwsgi_server uwsgi;
This memory must not be freed for all the server lifecycle
*/
static char *last_file = NULL;
void ini_rstrip(char *line) {
off_t i;
for(i = strlen(line)-1;i>=0; i--) {
if (line[i] == ' ' || line[i] == '\t') {
for (i = strlen(line) - 1; i >= 0; i--) {
if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r') {
line[i] = 0;
continue;
}
@@ -27,8 +27,8 @@ char *ini_lstrip(char *line) {
off_t i;
char *ptr = line;
for(i=0;i< (int) strlen(line);i++) {
if (line[i] == ' ' || line[i] == '\t') {
for (i = 0; i < (int) strlen(line); i++) {
if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r') {
ptr++;
continue;
}
@@ -43,7 +43,7 @@ char *ini_get_key(char *key) {
off_t i;
char *ptr = key;
for(i=0;i< (int) strlen(key);i++) {
for (i = 0; i < (int) strlen(key); i++) {
ptr++;
if (key[i] == '=') {
key[i] = 0;
@@ -54,12 +54,12 @@ char *ini_get_key(char *key) {
return ptr;
}
char *ini_get_line(char *ini, off_t size) {
char *ini_get_line(char *ini, size_t size) {
off_t i;
size_t i;
char *ptr = ini;
for(i=0;i<size;i++) {
for (i = 0; i < size; i++) {
ptr++;
if (ini[i] == '\n') {
ini[i] = 0;
@@ -78,7 +78,7 @@ char *ini_get_line(char *ini, off_t size) {
void uwsgi_ini_config(char *file, char *magic_table[]) {
int len = 0;
size_t len = 0;
char *ini;
char *ini_line;
@@ -92,28 +92,39 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
char *section_asked = "uwsgi";
char *colon;
if (uwsgi_check_scheme(file)) {
colon = uwsgi_get_last_char(file, '/');
colon = uwsgi_get_last_char(colon, ':');
}
else {
colon = uwsgi_get_last_char(file, ':');
}
colon = uwsgi_get_last_char(file, '/');
colon = uwsgi_get_last_char(colon, ':');
}
else {
colon = uwsgi_get_last_char(file, ':');
}
if (colon) {
colon[0] = 0;
if (colon[1] != 0) {
section_asked = colon+1;
section_asked = colon + 1;
}
if (colon == file) {
file = last_file;
}
}
if (file[0] != 0) {
uwsgi_log("[uWSGI] getting INI configuration from %s\n", file);
if (file[0] != 0 && file != last_file) {
uwsgi_log_initial("[uWSGI] getting INI configuration from %s\n", file);
}
ini = uwsgi_open_and_read(file, &len, 1, magic_table);
if (file != last_file) {
if (last_file) {
free(last_file);
}
last_file = uwsgi_str(file);
}
while(len) {
while (len) {
ini_line = ini_get_line(ini, len);
if (ini_line == NULL) {
break;
@@ -125,8 +136,8 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
ini_rstrip(key);
if (key[0] != 0) {
if (key[0] == '[') {
section = key+1;
section[strlen(section)-1] = 0;
section = key + 1;
section[strlen(section) - 1] = 0;
}
else if (key[0] == ';' || key[0] == '#') {
// this is a comment
@@ -139,7 +150,7 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
ini_rstrip(key);
val = ini_lstrip(val);
ini_rstrip(val);
add_exported_option((char *)key, val, 0);
add_exported_option((char *) key, val, 0);
}
}
}
@@ -156,5 +167,3 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
}
#endif
+450
View File
@@ -0,0 +1,450 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
struct http_status_codes {
const char key[3];
const char *message;
int message_size;
};
/* statistically ordered */
struct http_status_codes hsc[] = {
{"200", "OK"},
{"302", "Found"},
{"404", "Not Found"},
{"500", "Internal Server Error"},
{"301", "Moved Permanently"},
{"304", "Not Modified"},
{"303", "See Other"},
{"403", "Forbidden"},
{"307", "Temporary Redirect"},
{"401", "Unauthorized"},
{"400", "Bad Request"},
{"405", "Method Not Allowed"},
{"408", "Request Timeout"},
{"100", "Continue"},
{"101", "Switching Protocols"},
{"201", "Created"},
{"202", "Accepted"},
{"203", "Non-Authoritative Information"},
{"204", "No Content"},
{"205", "Reset Content"},
{"206", "Partial Content"},
{"300", "Multiple Choices"},
{"305", "Use Proxy"},
{"402", "Payment Required"},
{"406", "Not Acceptable"},
{"407", "Proxy Authentication Required"},
{"409", "Conflict"},
{"410", "Gone"},
{"411", "Length Required"},
{"412", "Precondition Failed"},
{"413", "Request Entity Too Large"},
{"414", "Request-URI Too Long"},
{"415", "Unsupported Media Type"},
{"416", "Requested Range Not Satisfiable"},
{"417", "Expectation Failed"},
{"501", "Not Implemented"},
{"502", "Bad Gateway"},
{"503", "Service Unavailable"},
{"504", "Gateway Timeout"},
{"505", "HTTP Version Not Supported"},
{"", NULL},
};
void uwsgi_init_default() {
uwsgi.cpus = 1;
uwsgi.backtrace_depth = 64;
uwsgi.max_apps = 64;
uwsgi.master_queue = -1;
uwsgi.signal_socket = -1;
uwsgi.my_signal_socket = -1;
uwsgi.stats_fd = -1;
uwsgi.stats_pusher_default_freq = 3;
uwsgi.original_log_fd = -1;
uwsgi.emperor_fd_config = -1;
// default emperor scan frequency
uwsgi.emperor_freq = 3;
uwsgi.emperor_throttle = 1000;
uwsgi.emperor_heartbeat = 30;
// max 3 minutes throttling
uwsgi.emperor_max_throttle = 1000 * 180;
uwsgi.emperor_pid = -1;
uwsgi.subscribe_freq = 10;
uwsgi.subscription_tolerance = 17;
uwsgi.cores = 1;
uwsgi.threads = 1;
// default max number of rpc slot
uwsgi.rpc_max = 64;
uwsgi.offload_threads_events = 64;
uwsgi.default_app = -1;
uwsgi.buffer_size = 4096;
uwsgi.body_read_warning = 8;
uwsgi.numproc = 1;
uwsgi.forkbomb_delay = 2;
uwsgi.async = 1;
uwsgi.listen_queue = 100;
uwsgi.cheaper_overload = 3;
uwsgi.log_master_bufsize = 8192;
uwsgi.worker_reload_mercy = 60;
uwsgi.max_vars = MAX_VARS;
uwsgi.vec_size = 4 + 1 + (4 * MAX_VARS);
uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] = 4;
uwsgi.shared->options[UWSGI_OPTION_LOGGING] = 1;
// a workers hould be running for at least 10 seconds
uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME] = 10;
uwsgi.shared->spooler_frequency = 30;
uwsgi.shared->spooler_signal_pipe[0] = -1;
uwsgi.shared->spooler_signal_pipe[1] = -1;
uwsgi.shared->mule_signal_pipe[0] = -1;
uwsgi.shared->mule_signal_pipe[1] = -1;
uwsgi.shared->mule_queue_pipe[0] = -1;
uwsgi.shared->mule_queue_pipe[1] = -1;
uwsgi.shared->worker_log_pipe[0] = -1;
uwsgi.shared->worker_log_pipe[1] = -1;
uwsgi.shared->worker_req_log_pipe[0] = -1;
uwsgi.shared->worker_req_log_pipe[1] = -1;
uwsgi.req_log_fd = 2;
#ifdef UWSGI_SSL
// 1 day of tolerance
uwsgi.subscriptions_sign_check_tolerance = 3600 * 24;
uwsgi.ssl_sessions_timeout = 300;
#endif
uwsgi.alarm_freq = 3;
uwsgi.alarm_msg_size = 8192;
uwsgi.exception_handler_msg_size = 65536;
uwsgi.multicast_ttl = 1;
uwsgi.multicast_loop = 1;
// filling http status codes
struct http_status_codes *http_sc;
for (http_sc = hsc; http_sc->message != NULL; http_sc++) {
http_sc->message_size = strlen(http_sc->message);
}
uwsgi.empty = "";
uwsgi.wait_read_hook = uwsgi_simple_wait_read_hook;
uwsgi.wait_write_hook = uwsgi_simple_wait_write_hook;
uwsgi_websockets_init();
}
void uwsgi_setup_reload() {
char env_reload_buf[11];
char *env_reloads = getenv("UWSGI_RELOADS");
if (env_reloads) {
//convert env value to int
uwsgi.reloads = atoi(env_reloads);
uwsgi.reloads++;
//convert reloads to string
int rlen = snprintf(env_reload_buf, 10, "%u", uwsgi.reloads);
if (rlen > 0) {
env_reload_buf[rlen] = 0;
if (setenv("UWSGI_RELOADS", env_reload_buf, 1)) {
uwsgi_error("setenv()");
}
}
uwsgi.is_a_reload = 1;
}
else {
if (setenv("UWSGI_RELOADS", "0", 1)) {
uwsgi_error("setenv()");
}
}
}
void uwsgi_autoload_plugins_by_name(char *argv_zero) {
char *plugins_requested = NULL;
char *original_proc_name = getenv("UWSGI_ORIGINAL_PROC_NAME");
if (!original_proc_name) {
// here we use argv[0];
original_proc_name = argv_zero;
setenv("UWSGI_ORIGINAL_PROC_NAME", original_proc_name, 1);
}
char *p = strrchr(original_proc_name, '/');
if (p == NULL)
p = original_proc_name;
p = strstr(p, "uwsgi_");
if (p != NULL) {
plugins_requested = strtok(uwsgi_str(p + 6), "_");
while (plugins_requested) {
uwsgi_log("[uwsgi] implicit plugin requested %s\n", plugins_requested);
uwsgi_load_plugin(-1, plugins_requested, NULL);
plugins_requested = strtok(NULL, "_");
}
}
plugins_requested = getenv("UWSGI_PLUGINS");
if (plugins_requested) {
plugins_requested = uwsgi_concat2(plugins_requested, "");
char *p = strtok(plugins_requested, ",");
while (p != NULL) {
uwsgi_load_plugin(-1, p, NULL);
p = strtok(NULL, ",");
}
}
}
void uwsgi_commandline_config() {
int i;
uwsgi.option_index = -1;
char *optname;
while ((i = getopt_long(uwsgi.argc, uwsgi.argv, uwsgi.short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
if (i == '?') {
uwsgi_log("getopt_long() error\n");
exit(1);
}
if (uwsgi.option_index > -1) {
optname = (char *) uwsgi.long_options[uwsgi.option_index].name;
}
else {
optname = uwsgi_get_optname_by_index(i);
}
if (!optname) {
uwsgi_log("unable to parse command line options\n");
exit(1);
}
uwsgi.option_index = -1;
add_exported_option(optname, optarg, 0);
}
#ifdef UWSGI_DEBUG
uwsgi_log("optind:%d argc:%d\n", optind, uwsgi.argc);
#endif
if (optind < uwsgi.argc) {
for (i = optind; i < uwsgi.argc; i++) {
char *lazy = uwsgi.argv[i];
if (lazy[0] != '[') {
uwsgi_opt_load(NULL, lazy, NULL);
// manage magic mountpoint
int magic = 0;
int j;
for (j = 0; j < uwsgi.gp_cnt; j++) {
if (uwsgi.gp[j]->magic) {
if (uwsgi.gp[j]->magic(NULL, lazy)) {
magic = 1;
break;
}
}
}
if (!magic) {
for (j = 0; j < 256; j++) {
if (uwsgi.p[j]->magic) {
if (uwsgi.p[j]->magic(NULL, lazy)) {
magic = 1;
break;
}
}
}
}
}
}
}
}
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));
for (i = 0; i <= uwsgi.numproc; i++) {
// allocate memory for apps
uwsgi.workers[i].apps = (struct uwsgi_app *) uwsgi_calloc_shared(sizeof(struct uwsgi_app) * uwsgi.max_apps);
// allocate memory for cores
uwsgi.workers[i].cores = (struct uwsgi_core *) uwsgi_calloc_shared(sizeof(struct uwsgi_core) * uwsgi.cores);
// this is a trick for avoiding too much memory areas
void *ts = uwsgi_calloc_shared(sizeof(void *) * uwsgi.max_apps * uwsgi.cores);
// add 4 bytes for uwsgi header
void *buffers = uwsgi_malloc_shared((uwsgi.buffer_size+4) * uwsgi.cores);
void *hvec = uwsgi_malloc_shared(sizeof(struct iovec) * uwsgi.vec_size * uwsgi.cores);
void *post_buf = NULL;
if (uwsgi.post_buffering > 0)
post_buf = uwsgi_malloc_shared(uwsgi.post_buffering_bufsize * uwsgi.cores);
for (j = 0; j < uwsgi.cores; j++) {
// allocate shared memory for thread states (required for some language, like python)
uwsgi.workers[i].cores[j].ts = ts + ((sizeof(void *) * uwsgi.max_apps) * j);
// raw per-request buffer (+4 bytes for uwsgi header)
uwsgi.workers[i].cores[j].buffer = buffers + ((uwsgi.buffer_size+4) * j);
// iovec for uwsgi vars
uwsgi.workers[i].cores[j].hvec = hvec + ((sizeof(struct iovec) * uwsgi.vec_size) * j);
if (post_buf)
uwsgi.workers[i].cores[j].post_buf = post_buf + (uwsgi.post_buffering_bufsize * j);
}
// master does not need to following steps...
if (i == 0)
continue;
uwsgi.workers[i].signal_pipe[0] = -1;
uwsgi.workers[i].signal_pipe[1] = -1;
snprintf(uwsgi.workers[i].name, 0xff, "uWSGI worker %d", i);
snprintf(uwsgi.workers[i].snapshot_name, 0xff, "uWSGI snapshot %d", i);
}
uint64_t total_memory = (sizeof(struct uwsgi_app) * uwsgi.max_apps) + (sizeof(struct uwsgi_core) * uwsgi.cores) + (sizeof(void *) * uwsgi.max_apps * uwsgi.cores) + (uwsgi.buffer_size * uwsgi.cores) + (sizeof(struct iovec) * uwsgi.vec_size * uwsgi.cores);
if (uwsgi.post_buffering > 0) {
total_memory += (uwsgi.post_buffering_bufsize * uwsgi.cores);
}
total_memory *= (uwsgi.numproc + uwsgi.master_process);
if (uwsgi.numproc > 0)
uwsgi_log("mapped %llu bytes (%llu KB) for %d cores\n", (unsigned long long) total_memory, (unsigned long long) (total_memory / 1024), uwsgi.cores * uwsgi.numproc);
// allocate signal table
uwsgi.shared->signal_table = uwsgi_calloc_shared(sizeof(struct uwsgi_signal_entry) * 256 * (uwsgi.numproc + 1));
}
pid_t uwsgi_daemonize2() {
if (uwsgi.has_emperor) {
logto(uwsgi.daemonize2);
}
else {
if (!uwsgi.is_a_reload) {
uwsgi_log("*** daemonizing uWSGI ***\n");
daemonize(uwsgi.daemonize2);
}
else if (uwsgi.log_reopen) {
logto(uwsgi.daemonize2);
}
}
uwsgi.mypid = getpid();
uwsgi.workers[0].pid = uwsgi.mypid;
if (uwsgi.pidfile && !uwsgi.is_a_reload) {
uwsgi_write_pidfile(uwsgi.pidfile);
}
if (uwsgi.pidfile2 && !uwsgi.is_a_reload) {
uwsgi_write_pidfile(uwsgi.pidfile2);
}
return uwsgi.mypid;
}
// fix/check related options
void sanitize_args() {
if (uwsgi.async > 1) {
uwsgi.cores = uwsgi.async;
}
if (uwsgi.threads > 1) {
uwsgi.has_threads = 1;
uwsgi.cores = uwsgi.threads;
}
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
if (!uwsgi.post_buffering) {
uwsgi_log(" *** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers *** \n");
}
}
if (uwsgi.write_errors_exception_only) {
uwsgi.ignore_sigpipe = 1;
uwsgi.ignore_write_errors = 1;
}
if (uwsgi.cheaper_count == 0) uwsgi.cheaper = 0;
if (uwsgi.cheaper_count > 0 && uwsgi.cheaper_count >= uwsgi.numproc) {
uwsgi_log("invalid cheaper value: must be lower than processes\n");
exit(1);
}
if (uwsgi.cheaper && uwsgi.cheaper_count) {
if (uwsgi.cheaper_initial) {
if (uwsgi.cheaper_initial < uwsgi.cheaper_count) {
uwsgi_log("warning: invalid cheaper-initial value (%d), must be equal or higher than cheaper (%d), using %d as initial number of workers\n",
uwsgi.cheaper_initial, uwsgi.cheaper_count, uwsgi.cheaper_count);
uwsgi.cheaper_initial = uwsgi.cheaper_count;
}
else if (uwsgi.cheaper_initial > uwsgi.numproc) {
uwsgi_log("warning: invalid cheaper-initial value (%d), must be lower or equal than worker count (%d), using %d as initial number of workers\n",
uwsgi.cheaper_initial, uwsgi.numproc, uwsgi.numproc);
uwsgi.cheaper_initial = uwsgi.numproc;
}
}
else {
uwsgi.cheaper_initial = uwsgi.cheaper_count;
}
}
if (uwsgi.auto_snapshot > 0 && uwsgi.auto_snapshot > uwsgi.numproc) {
uwsgi_log("invalid auto-snapshot value: must be <= than processes\n");
exit(1);
}
if (uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME] > 0 && uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME] >= uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME]) {
uwsgi_log("invalid min-worker-lifetime value (%d), must be lower than max-worker-lifetime (%d)\n",
uwsgi.shared->options[UWSGI_OPTION_MIN_WORKER_LIFETIME], uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME]);
exit(1);
}
}
const char *uwsgi_http_status_msg(char *status, uint16_t *len) {
struct http_status_codes *http_sc;
for (http_sc = hsc; http_sc->message != NULL; http_sc++) {
if (!strncmp(http_sc->key, status, 3)) {
*len = http_sc->message_size;
return http_sc->message;
}
}
return NULL;
}
+1008
View File
File diff suppressed because it is too large Load Diff
+111
View File
@@ -0,0 +1,111 @@
#ifdef UWSGI_JSON
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
#include <jansson.h>
/*
I really love the jansson library...
*/
void uwsgi_json_config(char *file, char *magic_table[]) {
size_t len = 0;
char *json_data;
const char *key;
json_t *root;
json_error_t error;
json_t *config;
json_t *config_value, *config_array_item;
void *config_iter;
char *object_asked = "uwsgi";
char *colon;
int i;
if (uwsgi_check_scheme(file)) {
colon = uwsgi_get_last_char(file, '/');
colon = uwsgi_get_last_char(colon, ':');
}
else {
colon = uwsgi_get_last_char(file, ':');
}
if (colon) {
colon[0] = 0;
if (colon[1] != 0) {
object_asked = colon + 1;
}
}
uwsgi_log_initial("[uWSGI] getting JSON configuration from %s\n", file);
json_data = uwsgi_open_and_read(file, &len, 1, magic_table);
#ifdef JANSSON_MAJOR_VERSION
root = json_loads(json_data, 0, &error);
#else
root = json_loads(json_data, &error);
#endif
if (!root) {
uwsgi_log("error parsing JSON data: line %d %s\n", error.line, error.text);
exit(1);
}
config = json_object_get(root, object_asked);
if (!json_is_object(config)) {
uwsgi_log("you must define a object named %s in your JSON data\n", object_asked);
exit(1);
}
config_iter = json_object_iter(config);
while (config_iter) {
key = json_object_iter_key(config_iter);
config_value = json_object_iter_value(config_iter);
if (json_is_string(config_value)) {
add_exported_option((char *) key, (char *) json_string_value(config_value), 0);
}
else if (json_is_true(config_value)) {
add_exported_option((char *) key, strdup("1"), 0);
}
else if (json_is_false(config_value) || json_is_null(config_value)) {
add_exported_option((char *) key, strdup("0"), 0);
}
else if (json_is_integer(config_value)) {
add_exported_option((char *) key, uwsgi_num2str(json_integer_value(config_value)), 0);
}
else if (json_is_array(config_value)) {
for (i = 0; i < (int) json_array_size(config_value); i++) {
config_array_item = json_array_get(config_value, i);
if (json_is_string(config_array_item)) {
add_exported_option((char *) key, (char *) json_string_value(config_array_item), 0);
}
else if (json_is_true(config_array_item)) {
add_exported_option((char *) key, strdup("1"), 0);
}
else if (json_is_false(config_array_item) || json_is_null(config_array_item)) {
add_exported_option((char *) key, strdup("0"), 0);
}
else if (json_is_integer(config_array_item)) {
add_exported_option((char *) key, uwsgi_num2str(json_integer_value(config_array_item)), 0);
}
}
}
config_iter = json_object_iter_next(config, config_iter);
}
}
#endif
+76 -99
View File
@@ -19,25 +19,25 @@ void ldap2uwsgi(char *ldapname, char *uwsginame) {
int i;
for(i=0;i< (int) strlen(ldapname);i++) {
if (isupper( (int)ldapname[i])) {
for (i = 0; i < (int) strlen(ldapname); i++) {
if (isupper((int) ldapname[i])) {
*ptr++ = '-';
*ptr++ = tolower( (int) ldapname[i]);
*ptr++ = tolower((int) ldapname[i]);
}
else {
*ptr++ = ldapname[i];
}
}
*ptr++= 0;
*ptr++ = 0;
}
int calc_ldap_name(char *name) {
int i;
int counter = 0;
for(i=0;i< (int)strlen(name);i++) {
if (isupper( (int) name[i])) {
for (i = 0; i < (int) strlen(name); i++) {
if (isupper((int) name[i])) {
counter++;
}
}
@@ -52,7 +52,7 @@ struct uwsgi_ldap_entry {
};
void uwsgi_name_to_ldap(char *src, char *dst) {
void uwsgi_name_to_ldap(char *src, char *dst) {
int i;
char *ptr = dst;
@@ -61,16 +61,16 @@ void uwsgi_name_to_ldap(char *src, char *dst) {
strcat(dst, " 'uWSGI");
ptr+= 7;
ptr += 7;
for(i=0;i< (int)strlen(src);i++) {
if (src[i] == '-') {
i++;
*ptr++= toupper( (int) src[i]);
}
else {
*ptr++= src[i];
}
for (i = 0; i < (int) strlen(src); i++) {
if (src[i] == '-') {
i++;
*ptr++ = toupper((int) src[i]);
}
else {
*ptr++ = src[i];
}
}
strcat(dst, "'");
@@ -82,7 +82,7 @@ struct uwsgi_ldap_entry *get_ldap_by_num(struct uwsgi_ldap_entry *root, int num,
int i;
struct uwsgi_ldap_entry *ule;
for(i=0;i<count;i++) {
for (i = 0; i < count; i++) {
ule = &root[i];
if (ule->num == num) {
return ule;
@@ -96,9 +96,9 @@ struct uwsgi_ldap_entry *search_ldap_cache(struct uwsgi_ldap_entry *root, char *
int i;
struct uwsgi_ldap_entry *ule;
for(i=0;i<count;i++) {
for (i = 0; i < count; i++) {
ule = &root[i];
if (uwsgi_list_has_str(ule->names, name+1)) {
if (uwsgi_list_has_str(ule->names, name + 1)) {
return ule;
}
}
@@ -108,56 +108,38 @@ struct uwsgi_ldap_entry *search_ldap_cache(struct uwsgi_ldap_entry *root, char *
struct uwsgi_ldap_entry *get_ldap_names(int *count) {
struct option *aopt, *lopt;
struct uwsgi_option *op = uwsgi.options;
struct uwsgi_ldap_entry *ule, *entry;
char ldap_name[1024];
static int counter = 30000000;
*count = 0;
lopt = uwsgi.long_options;
ule = uwsgi_malloc(sizeof(struct uwsgi_ldap_entry)*count_options(lopt));
ule = uwsgi_malloc(sizeof(struct uwsgi_ldap_entry) * uwsgi_count_options(op));
while( (aopt = lopt) ) {
if (!aopt->name)
break;
while (op && op->name) {
uwsgi_name_to_ldap((char *)aopt->name, ldap_name);
uwsgi_name_to_ldap((char *) op->name, ldap_name);
entry = search_ldap_cache(ule, ldap_name, *count);
if (entry) goto next;
if (entry)
goto next;
if (aopt->flag) {
entry = &ule[*count] ;
entry->num = counter;
strcpy(entry->names, ldap_name);
counter++;
*count = *count+1;
}
else {
entry = get_ldap_by_num(ule, aopt->val, *count);
if (entry) {
strcat(entry->names, ldap_name);
}
else {
entry = &ule[*count] ;
entry->num = aopt->val;
strcpy(entry->names, ldap_name);
*count = *count+1;
}
}
entry = &ule[*count];
entry->num = *count;
strcpy(entry->names, ldap_name);
*count = *count + 1;
entry->has_arg = op->type;
entry->has_arg = aopt->has_arg;
next:
lopt++;
op++;
}
return ule;
}
void uwsgi_ldap_schema_dump_ldif() {
void uwsgi_opt_ldap_dump_ldif(char *opt, char *foo, void *bar) {
int i;
int items;
@@ -169,7 +151,7 @@ void uwsgi_ldap_schema_dump_ldif() {
struct uwsgi_ldap_entry *entry, *ule = get_ldap_names(&items);
for(i=0;i<items;i++) {
for (i = 0; i < items; i++) {
entry = &ule[i];
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
@@ -187,19 +169,19 @@ void uwsgi_ldap_schema_dump_ldif() {
uwsgi_log("olcObjectClasses: ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( ");
for(i=0;i<items;i++) {
entry = &ule[i];
for (i = 0; i < items; i++) {
char *list2 = uwsgi_concat2(entry->names+1, "");
entry = &ule[i];
char *list2 = uwsgi_concat2(entry->names + 1, "");
char *p = strtok(list2, " ");
while (p != NULL) {
uwsgi_log("%.*s $ ", strlen(p)-2, p+1);
p = strtok(NULL, " ");
}
while (p != NULL) {
uwsgi_log("%.*s $ ", strlen(p) - 2, p + 1);
p = strtok(NULL, " ");
}
free(list2);
free(list2);
}
@@ -210,45 +192,45 @@ void uwsgi_ldap_schema_dump_ldif() {
exit(0);
}
void uwsgi_ldap_schema_dump() {
void uwsgi_opt_ldap_dump(char *opt, char *foo, void *bar) {
int i;
int items;
struct uwsgi_ldap_entry *entry, *ule = get_ldap_names(&items);
for(i=0;i<items;i++) {
for (i = 0; i < items; i++) {
entry = &ule[i];
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
entry = &ule[i];
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
if (entry->has_arg) {
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
}
else {
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
}
}
if (entry->has_arg) {
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
}
else {
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
}
}
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.50000 NAME 'uWSGInull' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
uwsgi_log("objectclass ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( ");
for(i=0;i<items;i++) {
for (i = 0; i < items; i++) {
entry = &ule[i];
entry = &ule[i];
char *list2 = uwsgi_concat2(entry->names+1, "");
char *p = strtok(list2, " ");
while (p != NULL) {
uwsgi_log("%.*s $ ", strlen(p)-2, p+1);
p = strtok(NULL, " ");
}
char *list2 = uwsgi_concat2(entry->names + 1, "");
char *p = strtok(list2, " ");
while (p != NULL) {
uwsgi_log("%.*s $ ", strlen(p) - 2, p + 1);
p = strtok(NULL, " ");
}
free(list2);
free(list2);
}
}
@@ -258,7 +240,7 @@ void uwsgi_ldap_schema_dump() {
exit(0);
}
void uwsgi_ldap_config() {
void uwsgi_ldap_config(char *url) {
LDAP *ldp;
LDAPMessage *results, *entry;
@@ -267,7 +249,6 @@ void uwsgi_ldap_config() {
char *attr;
char *uwsgi_attr;
char *url = "ldap:///";
char *url_slash;
int desired_version = LDAP_VERSION3;
@@ -275,10 +256,6 @@ void uwsgi_ldap_config() {
LDAPURLDesc *ldap_url;
if (uwsgi.ldap) {
url = uwsgi.ldap;
}
if (!ldap_is_ldap_url(url)) {
uwsgi_log("invalid LDAP url.\n");
exit(1);
@@ -288,7 +265,7 @@ void uwsgi_ldap_config() {
uwsgi_log("unable to parse LDAP url.\n");
exit(1);
}
uwsgi_log("[uWSGI] getting LDAP configuration from %s\n", url);
url_slash = strchr(url, '/');
@@ -305,25 +282,25 @@ void uwsgi_ldap_config() {
#endif
#if LDAP_API_VERSION >= 3000
if ( (ret = ldap_initialize( &ldp, url)) != LDAP_SUCCESS) {
if ((ret = ldap_initialize(&ldp, url)) != LDAP_SUCCESS) {
uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
exit(1);
}
#else
if ( (ldp = ldap_init( ldap_url->lud_host, ldap_url->lud_port)) == NULL) {
if ((ldp = ldap_init(ldap_url->lud_host, ldap_url->lud_port)) == NULL) {
uwsgi_error("ldap_init()");
exit(1);
}
#endif
if ( (ret = ldap_set_option(ldp, LDAP_OPT_PROTOCOL_VERSION, &desired_version)) != LDAP_OPT_SUCCESS) {
if ((ret = ldap_set_option(ldp, LDAP_OPT_PROTOCOL_VERSION, &desired_version)) != LDAP_OPT_SUCCESS) {
uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
exit(1);
}
if ( (ret = ldap_search_ext_s(ldp, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, NULL, 0, NULL, NULL, NULL, 1, &results)) != LDAP_SUCCESS) {
if ((ret = ldap_search_ext_s(ldp, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, NULL, 0, NULL, NULL, NULL, 1, &results)) != LDAP_SUCCESS) {
uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
exit(1);
}
@@ -342,17 +319,17 @@ void uwsgi_ldap_config() {
entry = ldap_first_entry(ldp, results);
int found = 0;
for( attr = ldap_first_attribute(ldp, entry, &ber); attr != NULL; attr = ldap_next_attribute(ldp, entry, ber)) {
if (!strncmp(attr,"uWSGI",5)) {
for (attr = ldap_first_attribute(ldp, entry, &ber); attr != NULL; attr = ldap_next_attribute(ldp, entry, ber)) {
if (!strncmp(attr, "uWSGI", 5)) {
found = 1;
uwsgi_attr = malloc( calc_ldap_name(attr) + 1 );
uwsgi_attr = malloc(calc_ldap_name(attr) + 1);
if (!uwsgi_attr) {
uwsgi_error("malloc()");
exit(1);
}
ldap2uwsgi(attr+5, uwsgi_attr);
ldap2uwsgi(attr + 5, uwsgi_attr);
#ifdef UWSGI_DEBUG
uwsgi_debug("LDAP attribute: %s = --%s\n", attr, uwsgi_attr);
@@ -360,7 +337,7 @@ void uwsgi_ldap_config() {
bervalues = ldap_get_values_len(ldp, entry, attr);
if (bervalues) {
// do not free uwsgi_attr/uwsgi_val;
char *uwsgi_val = malloc( bervalues[0]->bv_len + 1 );
char *uwsgi_val = malloc(bervalues[0]->bv_len + 1);
if (!uwsgi_val) {
uwsgi_error("malloc()");
exit(1);
@@ -369,7 +346,7 @@ void uwsgi_ldap_config() {
memcpy(uwsgi_val, bervalues[0]->bv_val, bervalues[0]->bv_len);
uwsgi_val[bervalues[0]->bv_len] = 0;
add_exported_option((char*) uwsgi_attr, uwsgi_val, 0);
add_exported_option((char *) uwsgi_attr, uwsgi_val, 0);
free(bervalues);
}
else {
+1116
View File
File diff suppressed because it is too large Load Diff
+776
View File
@@ -0,0 +1,776 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
static struct uwsgi_lock_item *uwsgi_register_lock(char *id, int rw) {
struct uwsgi_lock_item *uli = uwsgi.registered_locks;
if (!uli) {
uwsgi.registered_locks = uwsgi_malloc_shared(sizeof(struct uwsgi_lock_item));
uwsgi.registered_locks->id = id;
uwsgi.registered_locks->pid = 0;
if (rw) {
uwsgi.registered_locks->lock_ptr = uwsgi_malloc_shared(uwsgi.rwlock_size);
}
else {
uwsgi.registered_locks->lock_ptr = uwsgi_malloc_shared(uwsgi.lock_size);
}
uwsgi.registered_locks->rw = rw;
uwsgi.registered_locks->next = NULL;
return uwsgi.registered_locks;
}
while (uli) {
if (!uli->next) {
uli->next = uwsgi_malloc_shared(sizeof(struct uwsgi_lock_item));
if (rw) {
uli->next->lock_ptr = uwsgi_malloc_shared(uwsgi.rwlock_size);
}
else {
uli->next->lock_ptr = uwsgi_malloc_shared(uwsgi.lock_size);
}
uli->next->id = id;
uli->next->pid = 0;
uli->next->rw = rw;
uli->next->next = NULL;
return uli->next;
}
uli = uli->next;
}
uwsgi_log("*** DANGER: unable to allocate lock %s ***\n", id);
exit(1);
}
#ifdef UWSGI_LOCK_USE_MUTEX
#ifdef OBSOLETE_LINUX_KERNEL
#undef EOWNERDEAD
#endif
#ifdef EOWNERDEAD
#define UWSGI_LOCK_ENGINE_NAME "pthread robust mutexes"
int uwsgi_pthread_robust_mutexes_enabled = 1;
#else
#define UWSGI_LOCK_ENGINE_NAME "pthread mutexes"
#endif
#define UWSGI_LOCK_SIZE sizeof(pthread_mutex_t)
#ifdef OBSOLETE_LINUX_KERNEL
#define UWSGI_RWLOCK_SIZE sizeof(pthread_mutex_t)
#else
#define UWSGI_RWLOCK_SIZE sizeof(pthread_rwlock_t)
#endif
#ifndef PTHREAD_PRIO_INHERIT
int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr,
int __protocol);
#define PTHREAD_PRIO_INHERIT 1
#endif
// REMEMBER lock must contains space for both pthread_mutex_t and pthread_mutexattr_t !!!
struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
pthread_mutexattr_t attr;
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
#ifdef EOWNERDEAD
retry:
#endif
if (pthread_mutexattr_init(&attr)) {
uwsgi_log("unable to allocate mutexattr structure\n");
exit(1);
}
if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
uwsgi_log("unable to share mutex\n");
exit(1);
}
#ifdef EOWNERDEAD
#ifndef PTHREAD_MUTEX_ROBUST
#define PTHREAD_MUTEX_ROBUST PTHREAD_MUTEX_ROBUST_NP
#endif
if (pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT)) {
uwsgi_log("unable to set PTHREAD_PRIO_INHERIT\n");
exit(1);
}
if (uwsgi_pthread_robust_mutexes_enabled) {
if (pthread_mutexattr_setrobust_np(&attr, PTHREAD_MUTEX_ROBUST)) {
uwsgi_log("unable to make the mutex 'robust'\n");
exit(1);
}
}
#endif
if (pthread_mutex_init((pthread_mutex_t *) uli->lock_ptr, &attr)) {
#ifdef EOWNERDEAD
if (uwsgi_pthread_robust_mutexes_enabled) {
uwsgi_log("!!! it looks like your kernel does not support pthread robust mutexes !!!\n");
uwsgi_log("!!! falling back to standard pthread mutexes !!!\n");
uwsgi_pthread_robust_mutexes_enabled = 0;
pthread_mutexattr_destroy(&attr);
goto retry;
}
#endif
uwsgi_log("unable to initialize mutex\n");
exit(1);
}
pthread_mutexattr_destroy(&attr);
#ifdef EOWNERDEAD
if (!uwsgi_pthread_robust_mutexes_enabled) {
uli->can_deadlock = 1;
}
#else
uli->can_deadlock = 1;
#endif
return uli;
}
pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item * uli) {
if (pthread_mutex_trylock((pthread_mutex_t *) uli->lock_ptr) == 0) {
pthread_mutex_unlock((pthread_mutex_t *) uli->lock_ptr);
return 0;
}
return uli->pid;
}
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item * uli) {
#ifdef OBSOLETE_LINUX_KERNEL
return uwsgi_lock_fast_check(uli);
#else
if (pthread_rwlock_trywrlock((pthread_rwlock_t *) uli->lock_ptr) == 0) {
pthread_rwlock_unlock((pthread_rwlock_t *) uli->lock_ptr);
return 0;
}
return uli->pid;
#endif
}
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
#ifdef EOWNERDEAD
if (pthread_mutex_lock((pthread_mutex_t *) uli->lock_ptr) == EOWNERDEAD) {
uwsgi_log("[deadlock-detector] a process holding a robust mutex died. recovering...\n");
pthread_mutex_consistent_np((pthread_mutex_t *) uli->lock_ptr);
}
#else
pthread_mutex_lock((pthread_mutex_t *) uli->lock_ptr);
#endif
uli->pid = uwsgi.mypid;
}
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
pthread_mutex_unlock((pthread_mutex_t *) uli->lock_ptr);
uli->pid = 0;
}
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) {
#ifdef OBSOLETE_LINUX_KERNEL
uwsgi_lock_fast(uli);
#else
pthread_rwlock_rdlock((pthread_rwlock_t *) uli->lock_ptr);
uli->pid = uwsgi.mypid;
#endif
}
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) {
#ifdef OBSOLETE_LINUX_KERNEL
uwsgi_lock_fast(uli);
#else
pthread_rwlock_wrlock((pthread_rwlock_t *) uli->lock_ptr);
uli->pid = uwsgi.mypid;
#endif
}
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
#ifdef OBSOLETE_LINUX_KERNEL
uwsgi_unlock_fast(uli);
#else
pthread_rwlock_unlock((pthread_rwlock_t *) uli->lock_ptr);
uli->pid = 0;
#endif
}
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
#ifdef OBSOLETE_LINUX_KERNEL
return uwsgi_lock_fast_init(id);
#else
pthread_rwlockattr_t attr;
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 1);
if (pthread_rwlockattr_init(&attr)) {
uwsgi_log("unable to allocate rwlock structure\n");
exit(1);
}
if (pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
uwsgi_log("unable to share rwlock\n");
exit(1);
}
if (pthread_rwlock_init((pthread_rwlock_t *) uli->lock_ptr, &attr)) {
uwsgi_log("unable to initialize rwlock\n");
exit(1);
}
pthread_rwlockattr_destroy(&attr);
uli->can_deadlock = 1;
return uli;
#endif
}
#elif defined(UWSGI_LOCK_USE_UMTX)
/* Warning: FreeBSD is still not ready for process-shared UMTX */
#include <machine/atomic.h>
#include <sys/umtx.h>
#define UWSGI_LOCK_SIZE sizeof(struct umtx)
#define UWSGI_RWLOCK_SIZE sizeof(struct umtx)
#define UWSGI_LOCK_ENGINE_NAME "FreeBSD umtx"
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
return uwsgi_lock_fast_init(id);
}
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_lock_fast(uli);
}
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_lock_fast(uli);
}
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_unlock_fast(uli);
}
struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
umtx_init((struct umtx *) uli->lock_ptr);
return uli;
}
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
umtx_lock((struct umtx *) uli->lock_ptr, (u_long) getpid());
uli->pid = uwsgi.mypid;
}
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
umtx_unlock((struct umtx *) uli->lock_ptr, (u_long) getpid());
uli->pid = 0;
}
pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) {
if (umtx_trylock((struct umtx *) uli->lock_ptr, (u_long) getpid())) {
umtx_unlock((struct umtx *) uli->lock_ptr, (u_long) getpid());
return 0;
}
return uli->pid;
}
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item * uli) {
return uwsgi_lock_fast_check(uli);
}
#elif defined(UWSGI_LOCK_USE_POSIX_SEM)
#define UWSGI_LOCK_SIZE sizeof(sem_t)
#define UWSGI_RWLOCK_SIZE sizeof(sem_t)
#define UWSGI_LOCK_ENGINE_NAME "POSIX semaphores"
#include <semaphore.h>
struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
sem_init((sem_t *) uli->lock_ptr, 1, 1);
uli->can_deadlock = 1;
return uli;
}
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
return uwsgi_lock_fast_init(id);
}
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
sem_wait((sem_t *) uli->lock_ptr);
uli->pid = uwsgi.mypid;
}
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
sem_post((sem_t *) uli->lock_ptr);
uli->pid = 0;
}
pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) {
if (sem_trywait((sem_t *) uli->lock_ptr) == 0) {
sem_post((sem_t *) uli->lock_ptr);
return 0;
}
return uli->pid;
}
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item * uli) {
return uwsgi_lock_fast_check(uli);
}
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_lock_fast(uli);
}
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_lock_fast(uli);
}
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_unlock_fast(uli);
}
#elif defined(UWSGI_LOCK_USE_OSX_SPINLOCK)
#define UWSGI_LOCK_ENGINE_NAME "OSX spinlocks"
#define UWSGI_LOCK_SIZE sizeof(OSSpinLock)
#define UWSGI_RWLOCK_SIZE sizeof(OSSpinLock)
struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
memset(uli->lock_ptr, 0, UWSGI_LOCK_SIZE);
uli->can_deadlock = 1;
return uli;
}
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
OSSpinLockLock((OSSpinLock *) uli->lock_ptr);
uli->pid = uwsgi.mypid;
}
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
OSSpinLockUnlock((OSSpinLock *) uli->lock_ptr);
uli->pid = 0;
}
pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) {
if (OSSpinLockTry((OSSpinLock *) uli->lock_ptr)) {
OSSpinLockUnlock((OSSpinLock *) uli->lock_ptr);
return 0;
}
return uli->pid;
}
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 1);
memset(uli->lock_ptr, 0, UWSGI_LOCK_SIZE);
uli->can_deadlock = 1;
return uli;
}
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_lock_fast(uli);
}
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_lock_fast(uli);
}
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) {
return uwsgi_lock_fast_check(uli);
}
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_unlock_fast(uli);
}
#elif defined(UWSGI_LOCK_USE_WINDOWS_MUTEX)
#define UWSGI_LOCK_ENGINE_NAME "windows mutexes"
#define UWSGI_LOCK_SIZE sizeof(HANDLE)
#define UWSGI_RWLOCK_SIZE sizeof(HANDLE)
struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
struct _SECURITY_ATTRIBUTES sa;
memset(&sa, 0, sizeof(struct _SECURITY_ATTRIBUTES));
sa.bInheritHandle = 1;
uli->lock_ptr = CreateMutex(&sa, FALSE, NULL);
return uli;
}
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
WaitForSingleObject(uli->lock_ptr, INFINITE);
uli->pid = uwsgi.mypid;
}
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
ReleaseMutex(uli->lock_ptr);
uli->pid = 0;
}
pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) {
if (WaitForSingleObject(uli->lock_ptr, 0) == WAIT_TIMEOUT) {
return 0;
}
return uli->pid;
}
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
return uwsgi_lock_fast_init(id);
}
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_lock_fast(uli);
}
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_lock_fast(uli);
}
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) {
return uwsgi_lock_fast_check(uli);
}
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
uwsgi_unlock_fast(uli);
}
#else
#define uwsgi_lock_fast_init uwsgi_lock_ipcsem_init
#define uwsgi_lock_fast_check uwsgi_lock_ipcsem_check
#define uwsgi_lock_fast uwsgi_lock_ipcsem
#define uwsgi_unlock_fast uwsgi_unlock_ipcsem
#define uwsgi_rwlock_fast_init uwsgi_rwlock_ipcsem_init
#define uwsgi_rwlock_fast_check uwsgi_rwlock_ipcsem_check
#define uwsgi_rlock_fast uwsgi_rlock_ipcsem
#define uwsgi_wlock_fast uwsgi_wlock_ipcsem
#define uwsgi_rwunlock_fast uwsgi_rwunlock_ipcsem
#define UWSGI_LOCK_SIZE sizeof(int)
#define UWSGI_RWLOCK_SIZE sizeof(int)
#define UWSGI_LOCK_ENGINE_NAME "ipcsem"
#define UWSGI_IPCSEM_ATEXIT 1
#endif
struct uwsgi_lock_item *uwsgi_lock_ipcsem_init(char *id) {
// used by ftok
static int counter = 1;
union semun {
int val;
struct semid_ds *buf;
ushort *array;
} semu;
int semid;
key_t myKey;
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
if (uwsgi.ftok) {
myKey = ftok(uwsgi.ftok, counter);
if (myKey < 0) {
uwsgi_error("ftok()");
exit(1);
}
counter++;
semid = semget(myKey, 1, IPC_CREAT | 0666);
}
else {
semid = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0666);
}
if (semid < 0) {
uwsgi_error("semget()");
exit(1);
}
// do this now, to allows triggering of atexit hook in case of problems
memcpy(uli->lock_ptr, &semid, sizeof(int));
semu.val = 1;
if (semctl(semid, 0, SETVAL, semu)) {
uwsgi_error("semctl()");
exit(1);
}
return uli;
}
void uwsgi_lock_ipcsem(struct uwsgi_lock_item *uli) {
int semid;
struct sembuf sb;
sb.sem_num = 0;
sb.sem_op = -1;
sb.sem_flg = SEM_UNDO;
memcpy(&semid, uli->lock_ptr, sizeof(int));
retry:
if (semop(semid, &sb, 1)) {
if (errno == EINTR) goto retry;
uwsgi_error("semop()");
}
}
void uwsgi_unlock_ipcsem(struct uwsgi_lock_item *uli) {
int semid;
struct sembuf sb;
sb.sem_num = 0;
sb.sem_op = 1;
sb.sem_flg = SEM_UNDO;
memcpy(&semid, uli->lock_ptr, sizeof(int));
retry:
if (semop(semid, &sb, 1)) {
if (errno == EINTR) goto retry;
uwsgi_error("semop()");
}
}
struct uwsgi_lock_item *uwsgi_rwlock_ipcsem_init(char *id) {
return uwsgi_lock_ipcsem_init(id);
}
void uwsgi_rlock_ipcsem(struct uwsgi_lock_item *uli) {
uwsgi_lock_ipcsem(uli);
}
void uwsgi_wlock_ipcsem(struct uwsgi_lock_item *uli) {
uwsgi_lock_ipcsem(uli);
}
void uwsgi_rwunlock_ipcsem(struct uwsgi_lock_item *uli) {
uwsgi_unlock_ipcsem(uli);
}
// ipc cannot deadlock
pid_t uwsgi_lock_ipcsem_check(struct uwsgi_lock_item *uli) {
return 0;
}
void uwsgi_ipcsem_clear(void) {
struct uwsgi_lock_item *uli = uwsgi.registered_locks;
if (!uwsgi.workers)
goto clear;
if (uwsgi.mywid == 0)
goto clear;
if (uwsgi.master_process && getpid() == uwsgi.workers[0].pid)
goto clear;
if (!uwsgi.master_process && uwsgi.mywid == 1)
goto clear;
return;
clear:
#ifdef UWSGI_DEBUG
uwsgi_log("removing sysvipc semaphores...\n");
#endif
while (uli) {
int semid = 0;
memcpy(&semid, uli->lock_ptr, sizeof(int));
if (semctl(semid, 0, IPC_RMID)) {
uwsgi_error("semctl()");
}
uli = uli->next;
}
}
pid_t uwsgi_rwlock_ipcsem_check(struct uwsgi_lock_item *uli) {
return uwsgi_lock_ipcsem_check(uli);
}
void uwsgi_setup_locking() {
int i;
if (uwsgi.locking_setup) return;
// use the fastest available locking
if (uwsgi.lock_engine) {
if (!strcmp(uwsgi.lock_engine, "ipcsem")) {
uwsgi_log_initial("lock engine: ipcsem\n");
atexit(uwsgi_ipcsem_clear);
uwsgi.lock_ops.lock_init = uwsgi_lock_ipcsem_init;
uwsgi.lock_ops.lock_check = uwsgi_lock_ipcsem_check;
uwsgi.lock_ops.lock = uwsgi_lock_ipcsem;
uwsgi.lock_ops.unlock = uwsgi_unlock_ipcsem;
uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_ipcsem_init;
uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_ipcsem_check;
uwsgi.lock_ops.rlock = uwsgi_rlock_ipcsem;
uwsgi.lock_ops.wlock = uwsgi_wlock_ipcsem;
uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_ipcsem;
uwsgi.lock_size = 8;
uwsgi.rwlock_size = 8;
goto ready;
}
uwsgi_log("unable to find lock engine \"%s\"\n", uwsgi.lock_engine);
exit(1);
}
uwsgi_log_initial("lock engine: %s\n", UWSGI_LOCK_ENGINE_NAME);
#ifdef UWSGI_IPCSEM_ATEXIT
atexit(uwsgi_ipcsem_clear);
#endif
uwsgi.lock_ops.lock_init = uwsgi_lock_fast_init;
uwsgi.lock_ops.lock_check = uwsgi_lock_fast_check;
uwsgi.lock_ops.lock = uwsgi_lock_fast;
uwsgi.lock_ops.unlock = uwsgi_unlock_fast;
uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_fast_init;
uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_fast_check;
uwsgi.lock_ops.rlock = uwsgi_rlock_fast;
uwsgi.lock_ops.wlock = uwsgi_wlock_fast;
uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_fast;
uwsgi.lock_size = UWSGI_LOCK_SIZE;
uwsgi.rwlock_size = UWSGI_RWLOCK_SIZE;
ready:
// application generic lock
uwsgi.user_lock = uwsgi_malloc(sizeof(void *) * (uwsgi.locks + 1));
for (i = 0; i < uwsgi.locks + 1; i++) {
uwsgi.user_lock[i] = uwsgi_lock_init(uwsgi_concat2("user ", uwsgi_num2str(i)));
}
// event queue lock (mitigate same event on multiple queues)
if (uwsgi.threads > 1) {
pthread_mutex_init(&uwsgi.thunder_mutex, NULL);
}
if (uwsgi.master_process) {
// signal table lock
uwsgi.signal_table_lock = uwsgi_lock_init("signal");
// fmon table lock
uwsgi.fmon_table_lock = uwsgi_lock_init("filemon");
// timer table lock
uwsgi.timer_table_lock = uwsgi_lock_init("timer");
// probe table lock
uwsgi.probe_table_lock = uwsgi_lock_init("probe");
// rb_timer table lock
uwsgi.rb_timer_table_lock = uwsgi_lock_init("rbtimer");
// cron table lock
uwsgi.cron_table_lock = uwsgi_lock_init("cron");
}
if (uwsgi.use_thunder_lock) {
// process shared thunder lock
uwsgi.the_thunder_lock = uwsgi_lock_init("thunder");
}
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;
}
int uwsgi_fcntl_lock(int fd) {
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = 0;
int ret = fcntl(fd, F_SETLKW, &fl);
if (ret < 0)
uwsgi_error("fcntl()");
return ret;
}
int uwsgi_fcntl_is_locked(int fd) {
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = 0;
if (fcntl(fd, F_SETLK, &fl)) {
return 1;
}
return 0;
}
void uwsgi_deadlock_check(pid_t diedpid) {
struct uwsgi_lock_item *uli = uwsgi.registered_locks;
while (uli) {
if (!uli->can_deadlock)
goto nextlock;
pid_t locked_pid = 0;
if (uli->rw) {
locked_pid = uwsgi_rwlock_check(uli);
}
else {
locked_pid = uwsgi_lock_check(uli);
}
if (locked_pid == diedpid) {
uwsgi_log("[deadlock-detector] pid %d was holding lock %s (%p)\n", (int) diedpid, uli->id, uli->lock_ptr);
if (uli->rw) {
uwsgi_rwunlock(uli);
}
else {
uwsgi_unlock(uli);
}
}
nextlock:
uli = uli->next;
}
}
void uwsgi_user_lock(int lock_num) {
uwsgi_lock(uwsgi.user_lock[lock_num]);
}
void uwsgi_user_unlock(int lock_num) {
uwsgi_unlock(uwsgi.user_lock[lock_num]);
}
+1495
View File
File diff suppressed because it is too large Load Diff
+166
View File
@@ -0,0 +1,166 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
struct wsgi_request *threaded_current_wsgi_req() {
return pthread_getspecific(uwsgi.tur_key);
}
struct wsgi_request *simple_current_wsgi_req() {
return uwsgi.wsgi_req;
}
void uwsgi_register_loop(char *name, void (*func) (void)) {
struct uwsgi_loop *old_loop = NULL, *loop = uwsgi.loops;
while (loop) {
// check if the loop engine is already registered
if (!strcmp(name, loop->name))
return;
old_loop = loop;
loop = loop->next;
}
loop = uwsgi_calloc(sizeof(struct uwsgi_loop));
loop->name = name;
loop->loop = func;
if (old_loop) {
old_loop->next = loop;
}
else {
uwsgi.loops = loop;
}
}
void *uwsgi_get_loop(char *name) {
struct uwsgi_loop *loop = uwsgi.loops;
while (loop) {
if (!strcmp(name, loop->name)) {
return loop->loop;
}
loop = loop->next;
}
return NULL;
}
/*
this is the default (simple) loop.
it will run simple_loop_run function for each spawned thread
simple_loop_run monitors sockets and signals descriptors
and manages them.
*/
void simple_loop() {
uwsgi_loop_cores_run(simple_loop_run);
}
void uwsgi_loop_cores_run(void *(*func) (void *)) {
int i;
for (i = 1; i < uwsgi.threads; i++) {
long j = i;
pthread_create(&uwsgi.workers[uwsgi.mywid].cores[i].thread_id, &uwsgi.threads_attr, func, (void *) j);
}
long y = 0;
func((void *) y);
}
void uwsgi_setup_thread_req(long core_id, struct wsgi_request *wsgi_req) {
int i;
sigset_t smask;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &i);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &i);
pthread_setspecific(uwsgi.tur_key, (void *) wsgi_req);
if (core_id > 0) {
// block all signals on new threads
sigfillset(&smask);
#ifdef UWSGI_DEBUG
sigdelset(&smask, SIGSEGV);
#endif
pthread_sigmask(SIG_BLOCK, &smask, NULL);
// run per-thread socket hook
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while (uwsgi_sock) {
if (uwsgi_sock->proto_thread_fixup) {
uwsgi_sock->proto_thread_fixup(uwsgi_sock, core_id);
}
uwsgi_sock = uwsgi_sock->next;
}
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->init_thread) {
uwsgi.p[i]->init_thread(core_id);
}
}
}
}
void simple_loop_run_int(int core_id) {
long y = core_id;
simple_loop_run((void *) y);
}
void *simple_loop_run(void *arg1) {
long core_id = (long) arg1;
struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core_id].req;
if (uwsgi.threads > 1) {
uwsgi_setup_thread_req(core_id, wsgi_req);
}
// initialize the main event queue to monitor sockets
int main_queue = event_queue_init();
uwsgi_add_sockets_to_queue(main_queue, core_id);
if (uwsgi.signal_socket > -1) {
event_queue_add_fd_read(main_queue, uwsgi.signal_socket);
event_queue_add_fd_read(main_queue, uwsgi.my_signal_socket);
}
// ok we are ready, let's start managing requests and signals
while (uwsgi.workers[uwsgi.mywid].manage_next_request) {
wsgi_req_setup(wsgi_req, core_id, NULL);
if (wsgi_req_accept(main_queue, wsgi_req)) {
continue;
}
if (wsgi_req_recv(main_queue, wsgi_req)) {
uwsgi_destroy_request(wsgi_req);
continue;
}
uwsgi_close_request(wsgi_req);
}
// end of the loop
if (uwsgi.workers[uwsgi.mywid].destroy && uwsgi.workers[0].pid > 0) {
#ifdef __APPLE__
kill(uwsgi.workers[0].pid, SIGTERM);
#else
if (uwsgi.propagate_touch) {
kill(uwsgi.workers[0].pid, SIGHUP);
}
else {
gracefully_kill(0);
}
#endif
}
return NULL;
}
+924
View File
@@ -0,0 +1,924 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
void uwsgi_restore_auto_snapshot(int signum) {
if (uwsgi.workers[1].snapshot > 0) {
uwsgi.restore_snapshot = 1;
}
else {
uwsgi_log("[WARNING] no snapshot available\n");
}
}
void uwsgi_block_signal(int signum) {
sigset_t smask;
sigemptyset(&smask);
sigaddset(&smask, signum);
if (sigprocmask(SIG_BLOCK, &smask, NULL)) {
uwsgi_error("sigprocmask()");
}
}
void uwsgi_unblock_signal(int signum) {
sigset_t smask;
sigemptyset(&smask);
sigaddset(&smask, signum);
if (sigprocmask(SIG_UNBLOCK, &smask, NULL)) {
uwsgi_error("sigprocmask()");
}
}
void uwsgi_master_manage_udp(int udp_fd) {
struct sockaddr_in udp_client;
char udp_client_addr[16];
int i;
socklen_t udp_len = sizeof(udp_client);
ssize_t rlen = recvfrom(udp_fd, uwsgi.wsgi_req->buffer, uwsgi.buffer_size, 0, (struct sockaddr *) &udp_client, &udp_len);
if (rlen < 0) {
uwsgi_error("recvfrom()");
}
else if (rlen > 0) {
memset(udp_client_addr, 0, 16);
if (inet_ntop(AF_INET, &udp_client.sin_addr.s_addr, udp_client_addr, 16)) {
if (uwsgi.wsgi_req->buffer[0] == UWSGI_MODIFIER_MULTICAST_ANNOUNCE) {
}
else if (uwsgi.wsgi_req->buffer[0] == 0x30 && uwsgi.snmp) {
manage_snmp(udp_fd, (uint8_t *) uwsgi.wsgi_req->buffer, rlen, &udp_client);
}
else {
// loop the various udp manager until one returns true
int udp_managed = 0;
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->manage_udp) {
if (uwsgi.p[i]->manage_udp(udp_client_addr, udp_client.sin_port, uwsgi.wsgi_req->buffer, rlen)) {
udp_managed = 1;
break;
}
}
}
// else a simple udp logger
if (!udp_managed) {
uwsgi_log("[udp:%s:%d] %.*s", udp_client_addr, ntohs(udp_client.sin_port), (int) rlen, uwsgi.wsgi_req->buffer);
}
}
}
else {
uwsgi_error("inet_ntop()");
}
}
}
void uwsgi_master_manage_emperor() {
char byte;
ssize_t rlen = read(uwsgi.emperor_fd, &byte, 1);
if (rlen > 0) {
uwsgi_log_verbose("received message %d from emperor\n", byte);
// remove me
if (byte == 0) {
close(uwsgi.emperor_fd);
if (!uwsgi.status.brutally_reloading)
kill_them_all(0);
}
// reload me
else if (byte == 1) {
// un-lazy the stack to trigger a real reload
uwsgi.lazy = 0;
uwsgi_block_signal(SIGHUP);
grace_them_all(0);
uwsgi_unblock_signal(SIGHUP);
}
}
else {
uwsgi_log("lost connection with my emperor !!!\n");
close(uwsgi.emperor_fd);
if (!uwsgi.status.brutally_reloading)
kill_them_all(0);
sleep(2);
exit(1);
}
}
void uwsgi_master_restore_snapshot() {
int i, waitpid_status;
uwsgi_log("[snapshot] restoring workers...\n");
for (i = 1; i <= uwsgi.numproc; i++) {
if (uwsgi.workers[i].pid == 0)
continue;
kill(uwsgi.workers[i].pid, SIGKILL);
if (waitpid(uwsgi.workers[i].pid, &waitpid_status, 0) < 0) {
uwsgi_error("waitpid()");
}
if (uwsgi.auto_snapshot > 0 && i > uwsgi.auto_snapshot) {
uwsgi.workers[i].pid = 0;
uwsgi.workers[i].snapshot = 0;
}
else {
uwsgi.workers[i].pid = uwsgi.workers[i].snapshot;
uwsgi.workers[i].snapshot = 0;
kill(uwsgi.workers[i].pid, SIGURG);
uwsgi_log("Restored uWSGI worker %d (pid: %d)\n", i, (int) uwsgi.workers[i].pid);
}
}
uwsgi.restore_snapshot = 0;
}
void suspend_resume_them_all(int signum) {
int i;
int suspend = 0;
if (uwsgi.workers[0].suspended == 1) {
uwsgi_log_verbose("*** (SIGTSTP received) resuming workers ***\n");
uwsgi.workers[0].suspended = 0;
}
else {
uwsgi_log_verbose("*** PAUSE (press start to resume, if you do not have a joypad send SIGTSTP) ***\n");
suspend = 1;
uwsgi.workers[0].suspended = 1;
}
// subscribe/unsubscribe if needed
uwsgi_subscribe_all(suspend, 1);
for (i = 1; i <= uwsgi.numproc; i++) {
uwsgi.workers[i].suspended = suspend;
if (uwsgi.workers[i].pid > 0) {
if (kill(uwsgi.workers[i].pid, SIGTSTP)) {
uwsgi_error("kill()");
}
}
}
}
void uwsgi_master_check_mercy() {
int i;
for (i = 1; i <= uwsgi.numproc; i++) {
if (uwsgi.workers[i].pid > 0 && uwsgi.workers[i].cursed_at) {
if (uwsgi_now() > uwsgi.workers[i].no_mercy_at) {
uwsgi_log_verbose("worker %d (pid: %d) is taking too much time to die...NO MERCY !!!\n", i, uwsgi.workers[i].pid);
// yes that look strangem but we avoid callign it again if we skip waitpid() call below
uwsgi_curse(i, SIGKILL);
}
}
}
}
void expire_rb_timeouts(struct uwsgi_rbtree *tree) {
uint64_t current = (uint64_t) uwsgi_now();
struct uwsgi_rb_timer *urbt;
struct uwsgi_signal_rb_timer *usrbt;
for (;;) {
urbt = uwsgi_min_rb_timer(tree, NULL);
if (urbt == NULL)
return;
if (urbt->value <= current) {
// remove the timeout and add another
usrbt = (struct uwsgi_signal_rb_timer *) urbt->data;
uwsgi_del_rb_timer(tree, urbt);
free(urbt);
usrbt->iterations_done++;
uwsgi_route_signal(usrbt->sig);
if (!usrbt->iterations || usrbt->iterations_done < usrbt->iterations) {
usrbt->uwsgi_rb_timer = uwsgi_add_rb_timer(tree, uwsgi_now() + usrbt->value, usrbt);
}
continue;
}
break;
}
}
int uwsgi_get_tcp_info(int fd) {
#if defined(__linux__) || defined(__FreeBSD__)
socklen_t tis = sizeof(struct tcp_info);
if (!getsockopt(fd, IPPROTO_TCP, TCP_INFO, &uwsgi.shared->ti, &tis)) {
// checks for older kernels
#if defined(__linux__)
if (!uwsgi.shared->ti.tcpi_sacked) {
#elif defined(__FreeBSD__)
if (!uwsgi.shared->ti.__tcpi_sacked) {
#endif
return 0;
}
#if defined(__linux__)
uwsgi.shared->load = (uint64_t) uwsgi.shared->ti.tcpi_unacked;
uwsgi.shared->max_load = (uint64_t) uwsgi.shared->ti.tcpi_sacked;
#elif defined(__FreeBSD__)
uwsgi.shared->load = (uint64_t) uwsgi.shared->ti.__tcpi_unacked;
uwsgi.shared->max_load = (uint64_t) uwsgi.shared->ti.__tcpi_sacked;
#endif
uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS] = uwsgi.shared->load;
if (uwsgi.vassal_sos_backlog > 0 && uwsgi.has_emperor) {
if (uwsgi.shared->load >= (uint64_t) uwsgi.vassal_sos_backlog) {
// ask emperor for help
char byte = 30;
if (write(uwsgi.emperor_fd, &byte, 1) != 1) {
uwsgi_error("write()");
}
else {
uwsgi_log("asking emperor for reinforcements (backlog: %llu)...\n", (unsigned long long ) uwsgi.shared->load);
}
}
}
if (uwsgi.shared->load >= uwsgi.shared->max_load) {
uwsgi_log_verbose("*** uWSGI listen queue of socket %d full !!! (%llu/%llu) ***\n", fd, (unsigned long long ) uwsgi.shared->load, (unsigned long long ) uwsgi.shared->max_load);
uwsgi.shared->options[UWSGI_OPTION_BACKLOG_ERRORS]++;
}
return uwsgi.shared->load;
}
#endif
return 0;
}
#ifdef __linux__
#include <linux/sockios.h>
#ifdef UNBIT
#define SIOBKLGQ 0x8908
#endif
#ifdef SIOBKLGQ
int get_linux_unbit_SIOBKLGQ(int fd) {
int queue = 0;
if (ioctl(fd, SIOBKLGQ, &queue) >= 0) {
uwsgi.shared->load = queue;
uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS] = queue;
if (queue >= uwsgi.listen_queue) {
uwsgi_log_verbose("*** uWSGI listen queue of socket %d full !!! (%d/%d) ***\n", fd, queue, uwsgi.listen_queue);
uwsgi.shared->options[UWSGI_OPTION_BACKLOG_ERRORS]++;
}
return queue;
}
return 0;
}
#endif
#endif
int master_loop(char **argv, char **environ) {
struct timeval last_respawn;
int last_respawn_rate = 0;
pid_t diedpid;
int waitpid_status;
time_t now = 0;
int i = 0;
int rlen;
int check_interval = 1;
struct uwsgi_rb_timer *min_timeout;
struct uwsgi_rbtree *rb_timers = uwsgi_init_rb_timer();
if (uwsgi.procname_master) {
uwsgi_set_processname(uwsgi.procname_master);
}
else if (uwsgi.procname) {
uwsgi_set_processname(uwsgi.procname);
}
else if (uwsgi.auto_procname) {
uwsgi_set_processname("uWSGI master");
}
uwsgi.current_time = uwsgi_now();
uwsgi_unix_signal(SIGTSTP, suspend_resume_them_all);
uwsgi_unix_signal(SIGHUP, grace_them_all);
if (uwsgi.die_on_term) {
uwsgi_unix_signal(SIGTERM, kill_them_all);
uwsgi_unix_signal(SIGQUIT, reap_them_all);
}
else {
uwsgi_unix_signal(SIGTERM, reap_them_all);
uwsgi_unix_signal(SIGQUIT, kill_them_all);
}
uwsgi_unix_signal(SIGINT, kill_them_all);
uwsgi_unix_signal(SIGUSR1, stats);
if (uwsgi.auto_snapshot) {
uwsgi_unix_signal(SIGURG, uwsgi_restore_auto_snapshot);
}
atexit(uwsgi_master_cleanup_hooks);
uwsgi.master_queue = event_queue_init();
/* route signals to workers... */
#ifdef UWSGI_DEBUG
uwsgi_log("adding %d to signal poll\n", uwsgi.shared->worker_signal_pipe[0]);
#endif
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_signal_pipe[0]);
if (uwsgi.spoolers) {
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]);
}
if (uwsgi.mules_cnt > 0) {
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->mule_signal_pipe[0]);
}
if (uwsgi.log_master) {
uwsgi.log_master_buf = uwsgi_malloc(uwsgi.log_master_bufsize);
if (!uwsgi.threaded_logger) {
#ifdef UWSGI_DEBUG
uwsgi_log("adding %d to master logging\n", uwsgi.shared->worker_log_pipe[0]);
#endif
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_log_pipe[0]);
if (uwsgi.req_log_master) {
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_req_log_pipe[0]);
}
}
else {
uwsgi_threaded_logger_spawn();
}
}
#ifdef UWSGI_SSL
uwsgi_start_legions();
#endif
uwsgi_cache_start_sweepers();
uwsgi_cache_start_sync_servers();
uwsgi.wsgi_req->buffer = uwsgi.workers[0].cores[0].buffer;
if (uwsgi.has_emperor) {
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.emperor_fd);
}
if (uwsgi.zerg_server) {
uwsgi.zerg_server_fd = bind_to_unix(uwsgi.zerg_server, uwsgi.listen_queue, 0, 0);
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.zerg_server_fd);
uwsgi_log("*** Zerg server enabled on %s ***\n", uwsgi.zerg_server);
}
if (uwsgi.stats) {
char *tcp_port = strchr(uwsgi.stats, ':');
if (tcp_port) {
// disable deferred accept for this socket
int current_defer_accept = uwsgi.no_defer_accept;
uwsgi.no_defer_accept = 1;
uwsgi.stats_fd = bind_to_tcp(uwsgi.stats, uwsgi.listen_queue, tcp_port);
uwsgi.no_defer_accept = current_defer_accept;
}
else {
uwsgi.stats_fd = bind_to_unix(uwsgi.stats, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
}
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.stats_fd);
uwsgi_log("*** Stats server enabled on %s fd: %d ***\n", uwsgi.stats, uwsgi.stats_fd);
}
if (uwsgi.stats_pusher_instances) {
if (!uwsgi_thread_new(uwsgi_stats_pusher_loop)) {
uwsgi_log("!!! unable to spawn stats pusher thread !!!\n");
exit(1);
}
}
if (uwsgi.udp_socket) {
uwsgi.udp_fd = bind_to_udp(uwsgi.udp_socket, 0, 0);
if (uwsgi.udp_fd < 0) {
uwsgi_log("unable to bind to udp socket. SNMP services will be disabled.\n");
}
else {
uwsgi_log("UDP server enabled.\n");
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.udp_fd);
}
}
uwsgi.snmp_fd = uwsgi_setup_snmp();
if (uwsgi.status.is_cheap) {
uwsgi_add_sockets_to_queue(uwsgi.master_queue, -1);
for (i = 1; i <= uwsgi.numproc; i++) {
uwsgi.workers[i].cheaped = 1;
}
uwsgi_log("cheap mode enabled: waiting for socket connection...\n");
}
// spawn mules
for (i = 0; i < uwsgi.mules_cnt; i++) {
size_t mule_patch_size = 0;
uwsgi.mules[i].patch = uwsgi_string_get_list(&uwsgi.mules_patches, i, &mule_patch_size);
uwsgi_mule(i + 1);
}
// spawn gateways
for (i = 0; i < ushared->gateways_cnt; i++) {
if (ushared->gateways[i].pid == 0) {
gateway_respawn(i);
}
}
// spawn daemons
uwsgi_daemons_spawn_all();
// first subscription
uwsgi_subscribe_all(0, 1);
// sync the cache store if needed
uwsgi_cache_sync_all();
if (uwsgi.queue_store && uwsgi.queue_filesize) {
if (msync(uwsgi.queue_header, uwsgi.queue_filesize, MS_ASYNC)) {
uwsgi_error("msync()");
}
}
// update touches timestamps
uwsgi_check_touches(uwsgi.touch_reload);
uwsgi_check_touches(uwsgi.touch_logrotate);
uwsgi_check_touches(uwsgi.touch_logreopen);
uwsgi_check_touches(uwsgi.touch_chain_reload);
uwsgi_check_touches(uwsgi.touch_workers_reload);
uwsgi_check_touches(uwsgi.touch_gracefully_stop);
// setup cheaper algos (can be stacked)
uwsgi.cheaper_algo = uwsgi_cheaper_algo_spare;
if (uwsgi.requested_cheaper_algo) {
uwsgi.cheaper_algo = NULL;
struct uwsgi_cheaper_algo *uca = uwsgi.cheaper_algos;
while (uca) {
if (!strcmp(uca->name, uwsgi.requested_cheaper_algo)) {
uwsgi.cheaper_algo = uca->func;
break;
}
uca = uca->next;
}
if (!uwsgi.cheaper_algo) {
uwsgi_log("unable to find requested cheaper algorithm, falling back to spare\n");
uwsgi.cheaper_algo = uwsgi_cheaper_algo_spare;
}
}
// here really starts the master loop
for (;;) {
//uwsgi_log("uwsgi.ready_to_reload %d %d\n", uwsgi.ready_to_reload, uwsgi.numproc);
// run master_cycle hook for every plugin
for (i = 0; i < uwsgi.gp_cnt; i++) {
if (uwsgi.gp[i]->master_cycle) {
uwsgi.gp[i]->master_cycle();
}
}
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->master_cycle) {
uwsgi.p[i]->master_cycle();
}
}
// check for death (before reload !!!)
uwsgi_master_check_death();
// check for realod
if (uwsgi_master_check_reload(argv)) {
return -1;
}
// check chain reload
uwsgi_master_check_chain();
// check if some worker is taking too much to die...
uwsgi_master_check_mercy();
// check for daemons (smart and dumb)
uwsgi_daemons_smart_check();
if (uwsgi.respawn_snapshots) {
for (i = 1; i <= uwsgi.respawn_snapshots; i++) {
if (uwsgi_respawn_worker(i))
return 0;
}
uwsgi.respawn_snapshots = 0;
}
if (uwsgi.restore_snapshot) {
uwsgi_master_restore_snapshot();
continue;
}
// cheaper management
if (uwsgi.cheaper && !uwsgi.status.is_cheap && !uwsgi_instance_is_reloading && !uwsgi_instance_is_dying && !uwsgi.workers[0].suspended) {
if (!uwsgi_calc_cheaper())
return 0;
}
// check if someone is dead
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
if (diedpid == -1) {
if (errno == ECHILD) {
// something did not work as expected, just assume all has been cleared
uwsgi_master_commit_status();
diedpid = 0;
}
else {
uwsgi_error("waitpid()");
/* here is better to reload all the uWSGI stack */
uwsgi_log("something horrible happened...\n");
reap_them_all(0);
exit(1);
}
}
// no one died just run all of the standard master tasks
if (diedpid == 0) {
/* all processes ok, doing status scan after N seconds */
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!check_interval)
check_interval = 1;
// add unregistered file monitors
// locking is not needed as monitors can only increase
for (i = 0; i < ushared->files_monitored_cnt; i++) {
if (!ushared->files_monitored[i].registered) {
ushared->files_monitored[i].fd = event_queue_add_file_monitor(uwsgi.master_queue, ushared->files_monitored[i].filename, &ushared->files_monitored[i].id);
ushared->files_monitored[i].registered = 1;
}
}
// add unregistered timers
// locking is not needed as timers can only increase
for (i = 0; i < ushared->timers_cnt; i++) {
if (!ushared->timers[i].registered) {
ushared->timers[i].fd = event_queue_add_timer(uwsgi.master_queue, &ushared->timers[i].id, ushared->timers[i].value);
ushared->timers[i].registered = 1;
}
}
// add unregistered rb_timers
// locking is not needed as rb_timers can only increase
for (i = 0; i < ushared->rb_timers_cnt; i++) {
if (!ushared->rb_timers[i].registered) {
ushared->rb_timers[i].uwsgi_rb_timer = uwsgi_add_rb_timer(rb_timers, uwsgi_now() + ushared->rb_timers[i].value, &ushared->rb_timers[i]);
ushared->rb_timers[i].registered = 1;
}
}
int interesting_fd = -1;
if (ushared->rb_timers_cnt > 0) {
min_timeout = uwsgi_min_rb_timer(rb_timers, NULL);
if (min_timeout == NULL) {
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
}
else {
check_interval = min_timeout->value - uwsgi_now();
if (check_interval <= 0) {
expire_rb_timeouts(rb_timers);
check_interval = 0;
}
}
}
// wait for event
rlen = event_queue_wait(uwsgi.master_queue, check_interval, &interesting_fd);
if (rlen == 0) {
if (ushared->rb_timers_cnt > 0) {
expire_rb_timeouts(rb_timers);
}
}
// check uwsgi-cron table
if (ushared->cron_cnt) {
uwsgi_manage_signal_cron(uwsgi_now());
}
if (uwsgi.crons) {
uwsgi_manage_command_cron(uwsgi_now());
}
// check for probes
if (ushared->probes_cnt > 0) {
uwsgi_lock(uwsgi.probe_table_lock);
for (i = 0; i < ushared->probes_cnt; i++) {
if (interesting_fd == -1) {
// increment cycles
ushared->probes[i].cycles++;
}
if (ushared->probes[i].func(interesting_fd, &ushared->probes[i])) {
uwsgi_route_signal(ushared->probes[i].sig);
}
}
uwsgi_unlock(uwsgi.probe_table_lock);
}
// some event returned
if (rlen > 0) {
// if the following function returns -1, a new worker has just spawned
if (uwsgi_master_manage_events(interesting_fd)) {
return 0;
}
}
now = uwsgi_now();
if (now - uwsgi.current_time < 1) {
continue;
}
uwsgi.current_time = now;
// checking logsize
if (uwsgi.logfile) {
uwsgi_check_logrotate();
}
// this will be incremented at (more or less) regular intervals
uwsgi.master_cycles++;
// recalculate requests counter on race conditions risky configurations
// a bit of inaccuracy is better than locking;)
uwsgi_master_fix_request_counters();
// check for idle
uwsgi_master_check_idle();
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!check_interval)
check_interval = 1;
// get listen_queue status
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while (uwsgi_sock) {
if (uwsgi_sock->family == AF_INET) {
uwsgi_sock->queue = uwsgi_get_tcp_info(uwsgi_sock->fd);
}
#ifdef __linux__
#ifdef SIOBKLGQ
else if (uwsgi_sock->family == AF_UNIX) {
uwsgi_sock->queue = get_linux_unbit_SIOBKLGQ(uwsgi_sock->fd);
}
#endif
#endif
uwsgi_sock = uwsgi_sock->next;
}
// check if some worker has to die (harakiri, evil checks...)
uwsgi_master_check_workers_deadline();
uwsgi_master_check_gateways_deadline();
uwsgi_master_check_mules_deadline();
uwsgi_master_check_spoolers_deadline();
#ifdef __linux__
#ifdef MADV_MERGEABLE
if (uwsgi.linux_ksm > 0 && (uwsgi.master_cycles % uwsgi.linux_ksm) == 0) {
uwsgi_linux_ksm_map();
}
#endif
#endif
// resubscribe every 10 cycles by default
if (( (uwsgi.subscriptions || uwsgi.subscriptions2) && ((uwsgi.master_cycles % uwsgi.subscribe_freq) == 0 || uwsgi.master_cycles == 1)) && !uwsgi_instance_is_reloading && !uwsgi_instance_is_dying && !uwsgi.workers[0].suspended) {
uwsgi_subscribe_all(0, 0);
}
uwsgi_cache_sync_all();
if (uwsgi.queue_store && uwsgi.queue_filesize && uwsgi.queue_store_sync && ((uwsgi.master_cycles % uwsgi.queue_store_sync) == 0)) {
if (msync(uwsgi.queue_header, uwsgi.queue_filesize, MS_ASYNC)) {
uwsgi_error("msync()");
}
}
// check touch_reload
if (!uwsgi_instance_is_reloading && !uwsgi_instance_is_dying) {
char *touched = uwsgi_check_touches(uwsgi.touch_reload);
if (touched) {
uwsgi_log_verbose("*** %s has been touched... grace them all !!! ***\n", touched);
uwsgi_block_signal(SIGHUP);
grace_them_all(0);
uwsgi_unblock_signal(SIGHUP);
continue;
}
touched = uwsgi_check_touches(uwsgi.touch_workers_reload);
if (touched) {
uwsgi_log_verbose("*** %s has been touched... workers reload !!! ***\n", touched);
uwsgi_block_signal(SIGHUP);
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi.workers[i].pid > 0) {
uwsgi_curse(i, SIGHUP);
}
}
uwsgi_unblock_signal(SIGHUP);
continue;
}
touched = uwsgi_check_touches(uwsgi.touch_chain_reload);
if (touched) {
if (uwsgi.status.chain_reloading == 0) {
uwsgi_log_verbose("*** %s has been touched... chain reload !!! ***\n", touched);
uwsgi.status.chain_reloading = 1;
}
else {
uwsgi_log_verbose("*** %s has been touched... but chain reload is already running ***\n", touched);
}
}
}
continue;
}
// no one died
if (diedpid <= 0)
continue;
// check for deadlocks first
uwsgi_deadlock_check(diedpid);
// reload gateways and daemons only on normal workflow (+outworld status)
if (!uwsgi_instance_is_reloading && !uwsgi_instance_is_dying) {
if (uwsgi_master_check_emperor_death(diedpid)) continue;
if (uwsgi_master_check_spoolers_death(diedpid)) continue;
if (uwsgi_master_check_mules_death(diedpid)) continue;
if (uwsgi_master_check_gateways_death(diedpid)) continue;
if (uwsgi_master_check_daemons_death(diedpid)) continue;
}
/* What happens here ?
case 1) the diedpid is not a worker, report it and continue
case 2) the diedpid is a worker and we are not in a reload procedure -> reload it
case 3) the diedpid is a worker and we are in graceful reload -> uwsgi.ready_to_reload++ and continue
case 3) the diedpid is a worker and we are in brutal reload -> uwsgi.ready_to_die++ and continue
*/
int thewid = find_worker_id(diedpid);
if (thewid <= 0) {
// check spooler, mules, gateways and daemons
struct uwsgi_spooler *uspool = uwsgi.spoolers;
while (uspool) {
if (uspool->pid > 0 && diedpid == uspool->pid) {
uwsgi_log("spooler (pid: %d) annihilated\n", (int) diedpid);
goto next;
}
uspool = uspool->next;
}
for (i = 0; i < uwsgi.mules_cnt; i++) {
if (uwsgi.mules[i].pid == diedpid) {
uwsgi_log("mule %d (pid: %d) annihilated\n", i + 1, (int) diedpid);
goto next;
}
}
for (i = 0; i < ushared->gateways_cnt; i++) {
if (ushared->gateways[i].pid == diedpid) {
uwsgi_log("gateway %d (%s, pid: %d) annihilated\n", i + 1, ushared->gateways[i].fullname, (int) diedpid);
goto next;
}
}
if (uwsgi_daemon_check_pid_death(diedpid))
goto next;
if (WIFEXITED(waitpid_status)) {
uwsgi_log("subprocess %d exited with code %d\n", (int) diedpid, WEXITSTATUS(waitpid_status));
}
else if (WIFSIGNALED(waitpid_status)) {
uwsgi_log("subprocess %d exited by signal %d\n", (int) diedpid, WTERMSIG(waitpid_status));
}
else if (WIFSTOPPED(waitpid_status)) {
uwsgi_log("subprocess %d stopped\n", (int) diedpid);
}
next:
continue;
}
// ok a worker died...
uwsgi.workers[thewid].pid = 0;
// only to be safe :P
uwsgi.workers[thewid].harakiri = 0;
// ok, if we are reloading or dying, just continue the master loop
// as soon as all of the workers have pid == 0, the action (exit, or reload) is triggered
if (uwsgi_instance_is_reloading || uwsgi_instance_is_dying) {
uwsgi_log("worker %d buried after %d seconds\n", thewid, (int) (uwsgi_now()-uwsgi.workers[thewid].cursed_at));
uwsgi.workers[thewid].cursed_at = 0;
continue;
}
// if we are stopping workers, just end here
if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_FAILED_APP_CODE) {
uwsgi_log("OOPS ! failed loading app in worker %d (pid %d) :( trying again...\n", thewid, (int) diedpid);
}
else if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_DE_HIJACKED_CODE) {
uwsgi_log("...restoring worker %d (pid: %d)...\n", thewid, (int) diedpid);
}
else if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_EXCEPTION_CODE) {
uwsgi_log("... monitored exception detected, respawning worker %d (pid: %d)...\n", thewid, (int) diedpid);
}
else if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_QUIET_CODE) {
// noop
}
else if (uwsgi.workers[thewid].manage_next_request) {
if (WIFSIGNALED(waitpid_status)) {
uwsgi_log("DAMN ! worker %d (pid: %d) died, killed by signal %d :( trying respawn ...\n", thewid, (int) diedpid, (int) WTERMSIG(waitpid_status));
}
else {
uwsgi_log("DAMN ! worker %d (pid: %d) died :( trying respawn ...\n", thewid, (int) diedpid);
}
}
else if (uwsgi.workers[thewid].cursed_at > 0) {
uwsgi_log("worker %d killed successfully (pid: %d)\n", thewid, (int) diedpid);
}
// manage_next_request is zero, but killed by signal...
else if (WIFSIGNALED(waitpid_status)) {
uwsgi_log("DAMN ! worker %d (pid: %d) MISTERIOUSLY killed by signal %d :( trying respawn ...\n", thewid, (int) diedpid, (int) WTERMSIG(waitpid_status));
}
if (uwsgi.workers[thewid].cheaped == 1) {
uwsgi_log("uWSGI worker %d cheaped.\n", thewid);
continue;
}
// avoid fork bombing
gettimeofday(&last_respawn, NULL);
if (last_respawn.tv_sec <= uwsgi.respawn_delta + check_interval) {
last_respawn_rate++;
if (last_respawn_rate > uwsgi.numproc) {
if (uwsgi.forkbomb_delay > 0) {
uwsgi_log("worker respawning too fast !!! i have to sleep a bit (%d seconds)...\n", uwsgi.forkbomb_delay);
/* use --forkbomb-delay 0 to disable sleeping */
sleep(uwsgi.forkbomb_delay);
}
last_respawn_rate = 0;
}
}
else {
last_respawn_rate = 0;
}
gettimeofday(&last_respawn, NULL);
uwsgi.respawn_delta = last_respawn.tv_sec;
// are we chain reloading it ?
if (uwsgi.status.chain_reloading == thewid) {
uwsgi.status.chain_reloading++;
}
// respawn the worker (if needed)
if (uwsgi_respawn_worker(thewid))
return 0;
// end of the loop
}
// never here
}
+278
View File
@@ -0,0 +1,278 @@
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
// check if all of the workers are dead and exit uWSGI
void uwsgi_master_check_death() {
if (uwsgi_instance_is_dying) {
int i;
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi.workers[i].pid > 0) {
return;
}
}
uwsgi_log("goodbye to uWSGI.\n");
exit(0);
}
}
// check if all of the workers are dead, and trigger a reload
int uwsgi_master_check_reload(char **argv) {
if (uwsgi_instance_is_reloading) {
int i;
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi.workers[i].pid > 0) {
return 0;
}
}
uwsgi_reload(argv);
// never here (unless in shared library mode)
return -1;
}
return 0;
}
// check for chain reload
void uwsgi_master_check_chain() {
if (!uwsgi.status.chain_reloading) return;
if (uwsgi.status.chain_reloading > uwsgi.numproc) {
uwsgi.status.chain_reloading = 0;
uwsgi_log_verbose("chain reloading complete\n");
}
int i;
uwsgi_block_signal(SIGHUP);
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi.workers[i].pid > 0 && uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].cursed_at == 0 && i == uwsgi.status.chain_reloading) {
uwsgi_curse(i, SIGHUP);
break;
}
}
uwsgi_unblock_signal(SIGHUP);
}
// special function for assuming all of the workers are dead
void uwsgi_master_commit_status() {
int i;
for(i=1;i<=uwsgi.numproc;i++) {
uwsgi.workers[i].pid = 0;
}
}
void uwsgi_master_check_idle() {
static time_t last_request_timecheck = 0;
static uint64_t last_request_count = 0;
int i;
int waitpid_status;
if (!uwsgi.idle || uwsgi.status.is_cheap)
return;
uwsgi.current_time = uwsgi_now();
if (!last_request_timecheck)
last_request_timecheck = uwsgi.current_time;
// security check, stop the check if there are busy workers
for (i = 1; i <= uwsgi.numproc; i++) {
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
if (uwsgi_worker_is_busy(i)) {
return;
}
}
}
if (last_request_count != uwsgi.workers[0].requests) {
last_request_timecheck = uwsgi.current_time;
last_request_count = uwsgi.workers[0].requests;
}
// a bit of over-engeneering to avoid clock skews
else if (last_request_timecheck < uwsgi.current_time && (uwsgi.current_time - last_request_timecheck > uwsgi.idle)) {
uwsgi_log("workers have been inactive for more than %d seconds (%llu-%llu)\n", uwsgi.idle, (unsigned long long) uwsgi.current_time, (unsigned long long) last_request_timecheck);
uwsgi.status.is_cheap = 1;
if (uwsgi.die_on_idle) {
if (uwsgi.has_emperor) {
char byte = 22;
if (write(uwsgi.emperor_fd, &byte, 1) != 1) {
uwsgi_error("write()");
kill_them_all(0);
}
}
else {
kill_them_all(0);
}
return;
}
for (i = 1; i <= uwsgi.numproc; i++) {
uwsgi.workers[i].cheaped = 1;
if (uwsgi.workers[i].pid == 0)
continue;
kill(uwsgi.workers[i].pid, SIGKILL);
if (waitpid(uwsgi.workers[i].pid, &waitpid_status, 0) < 0) {
if (errno != ECHILD)
uwsgi_error("uwsgi_master_check_idle()/waitpid()");
}
}
uwsgi_add_sockets_to_queue(uwsgi.master_queue, -1);
uwsgi_log("cheap mode enabled: waiting for socket connection...\n");
last_request_timecheck = 0;
}
}
void uwsgi_master_check_workers_deadline() {
int i;
for (i = 1; i <= uwsgi.numproc; i++) {
/* first check for harakiri */
if (uwsgi.workers[i].harakiri > 0) {
if (uwsgi.workers[i].harakiri < (time_t) uwsgi.current_time) {
trigger_harakiri(i);
}
}
/* then user-defined harakiri */
if (uwsgi.workers[i].user_harakiri > 0) {
if (uwsgi.workers[i].user_harakiri < (time_t) uwsgi.current_time) {
trigger_harakiri(i);
}
}
// then for evil memory checkers
if (uwsgi.evil_reload_on_as) {
if ((rlim_t) uwsgi.workers[i].vsz_size >= uwsgi.evil_reload_on_as) {
uwsgi_log("*** EVIL RELOAD ON WORKER %d ADDRESS SPACE: %lld (pid: %d) ***\n", i, (long long) uwsgi.workers[i].vsz_size, uwsgi.workers[i].pid);
kill(uwsgi.workers[i].pid, SIGKILL);
uwsgi.workers[i].vsz_size = 0;
}
}
if (uwsgi.evil_reload_on_rss) {
if ((rlim_t) uwsgi.workers[i].rss_size >= uwsgi.evil_reload_on_rss) {
uwsgi_log("*** EVIL RELOAD ON WORKER %d RSS: %lld (pid: %d) ***\n", i, (long long) uwsgi.workers[i].rss_size, uwsgi.workers[i].pid);
kill(uwsgi.workers[i].pid, SIGKILL);
uwsgi.workers[i].rss_size = 0;
}
}
// check if worker was running longer than allowed lifetime
if (uwsgi.workers[i].pid > 0 && uwsgi.workers[i].cheaped == 0 && uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME] > 0) {
uint64_t lifetime = uwsgi_now() - uwsgi.workers[i].last_spawn;
if (lifetime > uwsgi.shared->options[UWSGI_OPTION_MAX_WORKER_LIFETIME] && uwsgi.workers[i].manage_next_request == 1) {
uwsgi_log("worker %d lifetime reached, it was running for %llu second(s)\n", i, (unsigned long long) lifetime);
uwsgi.workers[i].manage_next_request = 0;
kill(uwsgi.workers[i].pid, SIGWINCH);
}
}
// need to find a better way
//uwsgi.workers[i].last_running_time = uwsgi.workers[i].running_time;
}
}
void uwsgi_master_check_gateways_deadline() {
int i;
for (i = 0; i < ushared->gateways_cnt; i++) {
if (ushared->gateways_harakiri[i] > 0) {
if (ushared->gateways_harakiri[i] < (time_t) uwsgi.current_time) {
if (ushared->gateways[i].pid > 0) {
kill(ushared->gateways[i].pid, SIGKILL);
}
ushared->gateways_harakiri[i] = 0;
}
}
}
}
void uwsgi_master_check_mules_deadline() {
int i;
for (i = 0; i < uwsgi.mules_cnt; i++) {
if (uwsgi.mules[i].harakiri > 0) {
if (uwsgi.mules[i].harakiri < (time_t) uwsgi.current_time) {
uwsgi_log("*** HARAKIRI ON MULE %d HANDLING SIGNAL %d (pid: %d) ***\n", i + 1, uwsgi.mules[i].signum, uwsgi.mules[i].pid);
kill(uwsgi.mules[i].pid, SIGKILL);
uwsgi.mules[i].harakiri = 0;
}
}
}
}
void uwsgi_master_check_spoolers_deadline() {
struct uwsgi_spooler *uspool = uwsgi.spoolers;
while (uspool) {
if (uspool->harakiri > 0 && uspool->harakiri < (time_t) uwsgi.current_time) {
uwsgi_log("*** HARAKIRI ON THE SPOOLER (pid: %d) ***\n", uspool->pid);
kill(uspool->pid, SIGKILL);
uspool->harakiri = 0;
}
uspool = uspool->next;
}
}
int uwsgi_master_check_spoolers_death(int diedpid) {
struct uwsgi_spooler *uspool = uwsgi.spoolers;
while (uspool) {
if (uspool->pid > 0 && diedpid == uspool->pid) {
uwsgi_log("OOOPS the spooler is no more...trying respawn...\n");
uspool->respawned++;
uspool->pid = spooler_start(uspool);
return -1;
}
uspool = uspool->next;
}
return 0;
}
int uwsgi_master_check_emperor_death(int diedpid) {
if (uwsgi.emperor_pid >= 0 && diedpid == uwsgi.emperor_pid) {
uwsgi_log_verbose("!!! Emperor died !!!\n");
uwsgi_emperor_start();
return -1;
}
return 0;
}
int uwsgi_master_check_mules_death(int diedpid) {
int i;
for (i = 0; i < uwsgi.mules_cnt; i++) {
if (uwsgi.mules[i].pid == diedpid) {
uwsgi_log("OOOPS mule %d (pid: %d) crippled...trying respawn...\n", i + 1, uwsgi.mules[i].pid);
uwsgi_mule(i + 1);
return -1;
}
}
return 0;
}
int uwsgi_master_check_gateways_death(int diedpid) {
int i;
for (i = 0; i < ushared->gateways_cnt; i++) {
if (ushared->gateways[i].pid == diedpid) {
gateway_respawn(i);
return -1;
}
}
return 0;
}
int uwsgi_master_check_daemons_death(int diedpid) {
/* reload the daemons */
if (uwsgi_daemon_check_pid_reload(diedpid)) {
return -1;
}
return 0;
}
int uwsgi_worker_is_busy(int wid) {
int i;
for(i=0;i<uwsgi.cores;i++) {
if (uwsgi.workers[wid].cores[i].in_request) {
return 1;
}
}
return 0;
}
+174
View File
@@ -0,0 +1,174 @@
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
int uwsgi_master_manage_events(int interesting_fd) {
// is a logline ?
if (uwsgi.log_master && !uwsgi.threaded_logger) {
// stderr log ?
if (interesting_fd == uwsgi.shared->worker_log_pipe[0]) {
uwsgi_master_log();
return 0;
}
// req log ?
if (uwsgi.req_log_master && interesting_fd == uwsgi.shared->worker_req_log_pipe[0]) {
uwsgi_master_req_log();
return 0;
}
}
// stats server ?
if (uwsgi.stats && uwsgi.stats_fd > -1) {
if (interesting_fd == uwsgi.stats_fd) {
uwsgi_send_stats(uwsgi.stats_fd, uwsgi_master_generate_stats);
return 0;
}
}
// a zerg connection ?
if (uwsgi.zerg_server) {
if (interesting_fd == uwsgi.zerg_server_fd) {
uwsgi_manage_zerg(uwsgi.zerg_server_fd, 0, NULL);
return 0;
}
}
// emperor event ?
if (uwsgi.has_emperor) {
if (interesting_fd == uwsgi.emperor_fd) {
uwsgi_master_manage_emperor();
return 0;
}
}
// wakeup from cheap mode ?
if (uwsgi.status.is_cheap) {
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while (uwsgi_sock) {
if (interesting_fd == uwsgi_sock->fd) {
uwsgi.status.is_cheap = 0;
uwsgi_del_sockets_from_queue(uwsgi.master_queue);
// how many worker we need to respawn ?
int needed = uwsgi.numproc;
// if in cheaper mode, just respawn the minimal amount
if (uwsgi.cheaper) {
needed = uwsgi.cheaper_count;
}
int i;
for (i = 1; i <= needed; i++) {
if (uwsgi_respawn_worker(i))
return -1;
}
// here we continue instead of returning
break;
}
uwsgi_sock = uwsgi_sock->next;
}
}
// an SNMP request ?
if (uwsgi.snmp_addr && interesting_fd == uwsgi.snmp_fd) {
uwsgi_master_manage_snmp(uwsgi.snmp_fd);
return 0;
}
// a UDP request ?
if (uwsgi.udp_socket && interesting_fd == uwsgi.udp_fd) {
uwsgi_master_manage_udp(uwsgi.udp_fd);
return 0;
}
// check if some file monitor is ready
// no need to lock as we are only getting registered items (and only the master can register them)
int i;
for (i = 0; i < ushared->files_monitored_cnt; i++) {
if (ushared->files_monitored[i].registered) {
if (interesting_fd == ushared->files_monitored[i].fd) {
struct uwsgi_fmon *uf = event_queue_ack_file_monitor(uwsgi.master_queue, interesting_fd);
// now call the file_monitor handler
if (uf)
uwsgi_route_signal(uf->sig);
return 0;
}
}
}
// check if some timer elapsed
// no need to lock again
for (i = 0; i < ushared->timers_cnt; i++) {
if (ushared->timers[i].registered) {
if (interesting_fd == ushared->timers[i].fd) {
struct uwsgi_timer *ut = event_queue_ack_timer(interesting_fd);
// now call the timer handler
if (ut)
uwsgi_route_signal(ut->sig);
return 0;
}
}
}
uint8_t uwsgi_signal;
// check for worker signal
if (interesting_fd == uwsgi.shared->worker_signal_pipe[0]) {
ssize_t rlen = read(interesting_fd, &uwsgi_signal, 1);
if (rlen < 0) {
uwsgi_error("uwsgi_master_manage_events()/read()");
}
else if (rlen > 0) {
uwsgi_route_signal(uwsgi_signal);
}
else {
// TODO restart workers here
uwsgi_log_verbose("lost connection with workers !!!\n");
close(interesting_fd);
}
return 0;
}
// check for spooler signal
if (uwsgi.spoolers) {
if (interesting_fd == uwsgi.shared->spooler_signal_pipe[0]) {
ssize_t rlen = read(interesting_fd, &uwsgi_signal, 1);
if (rlen < 0) {
uwsgi_error("uwsgi_master_manage_events()/read()");
}
else if (rlen > 0) {
uwsgi_route_signal(uwsgi_signal);
}
else {
// TODO restart spoolers here
uwsgi_log_verbose("lost connection with spoolers\n");
close(interesting_fd);
}
return 0;
}
}
// check for mules signal
if (uwsgi.mules_cnt > 0) {
if (interesting_fd == uwsgi.shared->mule_signal_pipe[0]) {
ssize_t rlen = read(interesting_fd, &uwsgi_signal, 1);
if (rlen < 0) {
uwsgi_error("uwsgi_master_manage_events()/read()");
}
else if (rlen > 0) {
uwsgi_route_signal(uwsgi_signal);
}
else {
// TODO respawn mules here
uwsgi_log_verbose("lost connection with mules\n");
close(interesting_fd);
}
// return 0;
}
}
return 0;
}
+1487
View File
File diff suppressed because it is too large Load Diff
+470
View File
@@ -0,0 +1,470 @@
/*
uWSGI mules are very simple workers only managing signals or running custom code in background.
By default they born in signal-only mode, but if you patch them (passing the script/code to run) they will became fully customized daemons.
*/
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
void uwsgi_mule_handler(void);
void mule_send_msg(int fd, char *message, size_t len) {
socklen_t so_bufsize_len = sizeof(int);
int so_bufsize = 0;
if (write(fd, message, len) != (ssize_t) len) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &so_bufsize, &so_bufsize_len)) {
uwsgi_error("getsockopt()");
}
uwsgi_log("*** MULE MSG QUEUE IS FULL: buffer size %d bytes (you can tune it with --signal-bufsize) ***\n", so_bufsize);
}
else {
uwsgi_error("mule_send_msg()");
}
}
}
void uwsgi_mule(int id) {
int i;
pid_t pid = uwsgi_fork(uwsgi.mules[id - 1].name);
if (pid == 0) {
#ifdef __linux__
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
uwsgi_error("prctl()");
}
#endif
signal(SIGALRM, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGINT, end_me);
signal(SIGTERM, end_me);
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGSTOP, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
uwsgi.muleid = id;
// avoid race conditions
uwsgi.mules[id - 1].id = id;
uwsgi.mules[id - 1].pid = getpid();
uwsgi.mypid = uwsgi.mules[id - 1].pid;
uwsgi_fixup_fds(0, id, NULL);
uwsgi.my_signal_socket = uwsgi.mules[id - 1].signal_pipe[1];
uwsgi.signal_socket = uwsgi.shared->mule_signal_pipe[1];
uwsgi_close_all_sockets();
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->master_fixup) {
uwsgi.p[i]->master_fixup(1);
}
}
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->post_fork) {
uwsgi.p[i]->post_fork();
}
}
if (uwsgi.mules[id - 1].patch) {
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->mule) {
if (uwsgi.p[i]->mule(uwsgi.mules[id - 1].patch) == 1) {
// never here ?
end_me(1);
}
}
}
}
uwsgi_mule_handler();
}
else if (pid > 0) {
uwsgi.mules[id - 1].id = id;
uwsgi.mules[id - 1].pid = pid;
uwsgi_log("spawned uWSGI mule %d (pid: %d)\n", id, (int) pid);
}
}
int uwsgi_farm_has_mule(struct uwsgi_farm *farm, int muleid) {
struct uwsgi_mule_farm *umf = farm->mules;
while (umf) {
if (umf->mule->id == muleid) {
return 1;
}
umf = umf->next;
}
return 0;
}
int farm_has_signaled(int fd) {
int i;
for (i = 0; i < uwsgi.farms_cnt; i++) {
struct uwsgi_mule_farm *umf = uwsgi.farms[i].mules;
while (umf) {
if (umf->mule->id == uwsgi.muleid && uwsgi.farms[i].signal_pipe[1] == fd) {
return 1;
}
umf = umf->next;
}
}
return 0;
}
int farm_has_msg(int fd) {
int i;
for (i = 0; i < uwsgi.farms_cnt; i++) {
struct uwsgi_mule_farm *umf = uwsgi.farms[i].mules;
while (umf) {
if (umf->mule->id == uwsgi.muleid && uwsgi.farms[i].queue_pipe[1] == fd) {
return 1;
}
umf = umf->next;
}
}
return 0;
}
void uwsgi_mule_add_farm_to_queue(int queue) {
int i;
for (i = 0; i < uwsgi.farms_cnt; i++) {
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
event_queue_add_fd_read(queue, uwsgi.farms[i].signal_pipe[1]);
event_queue_add_fd_read(queue, uwsgi.farms[i].queue_pipe[1]);
}
}
}
void uwsgi_mule_handler() {
ssize_t len;
uint8_t uwsgi_signal;
int rlen;
int interesting_fd;
// this must be configurable
char message[65536];
int mule_queue = event_queue_init();
event_queue_add_fd_read(mule_queue, uwsgi.signal_socket);
event_queue_add_fd_read(mule_queue, uwsgi.my_signal_socket);
event_queue_add_fd_read(mule_queue, uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1]);
event_queue_add_fd_read(mule_queue, uwsgi.shared->mule_queue_pipe[1]);
uwsgi_mule_add_farm_to_queue(mule_queue);
for (;;) {
rlen = event_queue_wait(mule_queue, -1, &interesting_fd);
if (rlen <= 0) {
continue;
}
if (interesting_fd == uwsgi.signal_socket || interesting_fd == uwsgi.my_signal_socket || farm_has_signaled(interesting_fd)) {
len = read(interesting_fd, &uwsgi_signal, 1);
if (len <= 0) {
if (len < 0 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) continue;
uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid);
end_me(0);
}
#ifdef UWSGI_DEBUG
uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid);
#endif
if (uwsgi_signal_handler(uwsgi_signal)) {
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.muleid);
}
}
else if (interesting_fd == uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1] || interesting_fd == uwsgi.shared->mule_queue_pipe[1] || farm_has_msg(interesting_fd)) {
len = read(interesting_fd, message, 65536);
if (len < 0) {
if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) {
uwsgi_error("uwsgi_mule_handler/read()");
}
}
else {
int i, found = 0;
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->mule_msg) {
if (uwsgi.p[i]->mule_msg(message, len)) {
found = 1;
break;
}
}
}
if (!found)
uwsgi_log("*** mule %d received a %ld bytes message ***\n", uwsgi.muleid, (long) len);
}
}
}
}
struct uwsgi_mule *get_mule_by_id(int id) {
int i;
for (i = 0; i < uwsgi.mules_cnt; i++) {
if (uwsgi.mules[i].id == id) {
return &uwsgi.mules[i];
}
}
return NULL;
}
struct uwsgi_farm *get_farm_by_name(char *name) {
int i;
for (i = 0; i < uwsgi.farms_cnt; i++) {
if (!strcmp(uwsgi.farms[i].name, name)) {
return &uwsgi.farms[i];
}
}
return NULL;
}
struct uwsgi_mule_farm *uwsgi_mule_farm_new(struct uwsgi_mule_farm **umf, struct uwsgi_mule *um) {
struct uwsgi_mule_farm *uwsgi_mf = *umf, *old_umf;
if (!uwsgi_mf) {
*umf = uwsgi_malloc(sizeof(struct uwsgi_mule_farm));
uwsgi_mf = *umf;
}
else {
while (uwsgi_mf) {
old_umf = uwsgi_mf;
uwsgi_mf = uwsgi_mf->next;
}
uwsgi_mf = uwsgi_malloc(sizeof(struct uwsgi_mule_farm));
old_umf->next = uwsgi_mf;
}
uwsgi_mf->mule = um;
uwsgi_mf->next = NULL;
return uwsgi_mf;
}
ssize_t uwsgi_mule_get_msg(int manage_signals, int manage_farms, char *message, size_t buffer_size, int timeout) {
ssize_t len = 0;
struct pollfd *mulepoll;
int count = 4;
int farms_count = 0;
uint8_t uwsgi_signal;
int i;
if (uwsgi.muleid == 0)
return -1;
if (manage_signals)
count = 2;
if (!manage_farms)
goto next;
for (i = 0; i < uwsgi.farms_cnt; i++) {
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid))
farms_count++;
}
next:
if (timeout > -1)
timeout = timeout * 1000;
mulepoll = uwsgi_malloc(sizeof(struct pollfd) * (count + farms_count));
mulepoll[0].fd = uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1];
mulepoll[0].events = POLLIN;
mulepoll[1].fd = uwsgi.shared->mule_queue_pipe[1];
mulepoll[1].events = POLLIN;
if (count > 2) {
mulepoll[2].fd = uwsgi.signal_socket;
mulepoll[2].events = POLLIN;
mulepoll[3].fd = uwsgi.my_signal_socket;
mulepoll[3].events = POLLIN;
}
if (farms_count > 0) {
int tmp_cnt = 0;
for (i = 0; i < uwsgi.farms_cnt; i++) {
if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
mulepoll[count + tmp_cnt].fd = uwsgi.farms[i].queue_pipe[1];
mulepoll[count + tmp_cnt].events = POLLIN;
tmp_cnt++;
}
}
}
int ret = poll(mulepoll, count + farms_count, timeout);
if (ret <= 0) {
uwsgi_error("poll");
}
else {
if (mulepoll[0].revents & POLLIN) {
len = read(uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1], message, buffer_size);
}
else if (mulepoll[1].revents & POLLIN) {
len = read(uwsgi.shared->mule_queue_pipe[1], message, buffer_size);
}
else {
if (count > 2) {
int interesting_fd = -1;
if (mulepoll[2].revents & POLLIN) {
interesting_fd = mulepoll[2].fd;
}
else if (mulepoll[3].revents & POLLIN) {
interesting_fd = mulepoll[3].fd;
}
if (interesting_fd > -1) {
len = read(interesting_fd, &uwsgi_signal, 1);
if (len <= 0) {
if (len < 0 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) goto clear;
uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid);
end_me(0);
}
#ifdef UWSGI_DEBUG
uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid);
#endif
if (uwsgi_signal_handler(uwsgi_signal)) {
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.muleid);
}
// set the error condition
len = -1;
goto clear;
}
}
// read messages in the farm
for (i = 0; i < farms_count; i++) {
if (mulepoll[count + i].revents & POLLIN) {
len = read(mulepoll[count + i].fd, message, buffer_size);
break;
}
}
}
}
if (len < 0) {
uwsgi_error("read()");
goto clear;
}
clear:
free(mulepoll);
return len;
}
void uwsgi_opt_add_mule(char *opt, char *value, void *foobar) {
uwsgi.mules_cnt++;
uwsgi_string_new_list(&uwsgi.mules_patches, value);
}
void uwsgi_opt_add_mules(char *opt, char *value, void *foobar) {
int i;
for (i = 0; i < atoi(value); i++) {
uwsgi.mules_cnt++;
uwsgi_string_new_list(&uwsgi.mules_patches, NULL);
}
}
void uwsgi_opt_add_farm(char *opt, char *value, void *foobar) {
uwsgi.farms_cnt++;
uwsgi_string_new_list(&uwsgi.farms_list, value);
}
void uwsgi_setup_mules_and_farms() {
int i;
if (uwsgi.mules_cnt > 0) {
uwsgi.mules = (struct uwsgi_mule *) uwsgi_calloc_shared(sizeof(struct uwsgi_mule) * uwsgi.mules_cnt);
create_signal_pipe(uwsgi.shared->mule_signal_pipe);
create_signal_pipe(uwsgi.shared->mule_queue_pipe);
for (i = 0; i < uwsgi.mules_cnt; i++) {
// create the socket pipe
create_signal_pipe(uwsgi.mules[i].signal_pipe);
create_signal_pipe(uwsgi.mules[i].queue_pipe);
uwsgi.mules[i].id = i + 1;
snprintf(uwsgi.mules[i].name, 0xff, "uWSGI mule %d", i + 1);
}
}
if (uwsgi.farms_cnt > 0) {
uwsgi.farms = (struct uwsgi_farm *) uwsgi_calloc_shared(sizeof(struct uwsgi_farm) * uwsgi.farms_cnt);
struct uwsgi_string_list *farm_name = uwsgi.farms_list;
for (i = 0; i < uwsgi.farms_cnt; i++) {
char *farm_value = uwsgi_str(farm_name->value);
char *mules_list = strchr(farm_value, ':');
if (!mules_list) {
uwsgi_log("invalid farm value (%s) must be in the form name:mule[,muleN].\n", farm_value);
exit(1);
}
mules_list[0] = 0;
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);
create_signal_pipe(uwsgi.farms[i].queue_pipe);
char *p = strtok(mules_list, ",");
while (p != NULL) {
struct uwsgi_mule *um = get_mule_by_id(atoi(p));
if (!um) {
uwsgi_log("invalid mule id: %s\n", p);
exit(1);
}
uwsgi_mule_farm_new(&uwsgi.farms[i].mules, um);
p = strtok(NULL, ",");
}
uwsgi_log("created farm %d name: %s mules:%s\n", i + 1, uwsgi.farms[i].name, strchr(farm_name->value, ':') + 1);
farm_name = farm_name->next;
}
}
}
+18 -13
View File
@@ -16,25 +16,28 @@ void uwsgi_systemd_notify(char *message) {
iovec[1].iov_len = strlen(message);
iovec[2].iov_base = "\n";
iovec[2].iov_len = 1;
iovec[2].iov_len = 1;
msghdr->msg_iovlen = 3;
sendmsg(uwsgi.notification_fd, msghdr, 0);
if (sendmsg(uwsgi.notification_fd, msghdr, 0) < 0) {
uwsgi_error("sendmsg()");
}
}
void uwsgi_systemd_notify_ready(void) {
struct msghdr *msghdr = (struct msghdr *) uwsgi.notification_object;
struct iovec *iovec = msghdr->msg_iov;
struct iovec *iovec = msghdr->msg_iov;
iovec[0].iov_base = "STATUS=uWSGI is ready\nREADY=1\n";
iovec[0].iov_len = 30;
iovec[0].iov_base = "STATUS=uWSGI is ready\nREADY=1\n";
iovec[0].iov_len = 30;
msghdr->msg_iovlen = 1;
sendmsg(uwsgi.notification_fd, msghdr, 0);
if (sendmsg(uwsgi.notification_fd, msghdr, 0) < 0) {
uwsgi_error("sendmsg()");
}
}
@@ -49,24 +52,26 @@ void uwsgi_systemd_init(char *systemd_socket) {
return;
}
size_t len = strlen(systemd_socket);
sd_sun = uwsgi_malloc(sizeof(struct sockaddr_un));
memset(sd_sun, 0, sizeof(struct sockaddr_un));
sd_sun->sun_family = AF_UNIX;
strncpy(sd_sun->sun_path, systemd_socket, sizeof(sd_sun->sun_path));
if (sd_sun->sun_path[0] == '@') sd_sun->sun_path[0] = 0;
strncpy(sd_sun->sun_path, systemd_socket, UMIN(len, sizeof(sd_sun->sun_path)));
if (sd_sun->sun_path[0] == '@')
sd_sun->sun_path[0] = 0;
msghdr = uwsgi_malloc(sizeof(struct msghdr));
memset(msghdr, 0, sizeof(struct msghdr));
msghdr->msg_iov = uwsgi_malloc(sizeof(struct iovec)*3);
memset(msghdr->msg_iov, 0, sizeof(struct iovec)*3);
msghdr->msg_iov = uwsgi_malloc(sizeof(struct iovec) * 3);
memset(msghdr->msg_iov, 0, sizeof(struct iovec) * 3);
msghdr->msg_name = sd_sun;
msghdr->msg_namelen = sizeof(struct sockaddr_un);
msghdr->msg_namelen = sizeof(struct sockaddr_un) - (sizeof(sd_sun->sun_path) - len);
uwsgi.notification_object = msghdr;
uwsgi.notify = uwsgi_systemd_notify;
uwsgi.notify_ready = uwsgi_systemd_notify_ready;
}
+509
View File
@@ -0,0 +1,509 @@
#include "uwsgi.h"
/*
uWSGI offloading subsystem
steps to offload a task
1) allocate a uwsgi_offload_request structure (could be on stack)
struct uwsgi_offload_request uor;
2) prepare it for a specific engine (last argument is the takeover flag)
uwsgi_offload_setup(my_engine, &uor, 1)
3) run it (last argument is the waiter)
int uwsgi_offload_run(wsgi_req, &uor, NULL);
between 2 and 3 you can set specific values
*/
extern struct uwsgi_server uwsgi;
#define uwsgi_offload_retry if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) return 0;
#define uwsgi_offload_0r_1w(x, y) if (event_queue_del_fd(ut->queue, x, event_queue_read())) return -1;\
if (event_queue_fd_read_to_write(ut->queue, y)) return -1;
void uwsgi_offload_setup(struct uwsgi_offload_engine *uoe, struct uwsgi_offload_request *uor, struct wsgi_request *wsgi_req, uint8_t takeover) {
memset(uor, 0, sizeof(struct uwsgi_offload_request));
uor->engine = uoe;
uor->s = wsgi_req->fd;
uor->fd = -1;
uor->fd2 = -1;
// an engine could changes behaviour based on pipe anf takeover values
uor->pipe[0] = -1;
uor->pipe[1] = -1;
uor->takeover = takeover;
}
static int uwsgi_offload_enqueue(struct wsgi_request *wsgi_req, struct uwsgi_offload_request *uor) {
struct uwsgi_core *uc = &uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id];
uc->offloaded_requests++;
// round robin
if (uc->offload_rr >= uwsgi.offload_threads) {
uc->offload_rr = 0;
}
struct uwsgi_thread *ut = uwsgi.offload_thread[uc->offload_rr];
uc->offload_rr++;
if (write(ut->pipe[0], uor, sizeof(struct uwsgi_offload_request)) != sizeof(struct uwsgi_offload_request)) {
if (uor->takeover) {
wsgi_req->fd_closed = 0;
}
return -1;
}
return 0;
}
/*
transfer offload engine:
name -> socket name
ubuf -> data to send
*/
int u_offload_transfer_prepare(struct wsgi_request *wsgi_req, struct uwsgi_offload_request *uor) {
if (!uor->name) {
return -1;
}
uor->fd = uwsgi_connect(uor->ubuf->buf, 0, 1);
if (uor->fd < 0) {
uwsgi_error("u_offload_transfer_prepare()/connect()");
return -1;
}
return 0;
}
/*
sendfile offload engine:
name -> filename to transfer
fd -> file descriptor of file to transfer
fd2 -> sendfile destination (default wsgi_req->fd)
len -> size of the file or amount of data to transfer
pos -> position in the file
*/
static int u_offload_sendfile_prepare(struct wsgi_request *wsgi_req, struct uwsgi_offload_request *uor) {
if (!uor->name && uor->fd == -1) return -1;
if (uor->name) {
uor->fd = open(uor->name, O_RDONLY | O_NONBLOCK);
if (uor->fd < 0) {
uwsgi_error_open(uor->name);
return -1;
}
}
// make a fstat to get the file size
if (!uor->len) {
struct stat st;
if (fstat(uor->fd, &st)) {
uwsgi_error("u_offload_sendfile_prepare()/fstat()");
if (uor->name) {
close(uor->fd);
}
return -1;
}
uor->len = st.st_size;
}
if (uor->fd2 == -1) {
uor->fd2 = uor->s;
}
uor->s = -1;
return 0;
}
static void uwsgi_offload_close(struct uwsgi_thread *ut, struct uwsgi_offload_request *uor) {
// close the socket and the file descriptor
if (uor->takeover && uor->s > -1) {
close(uor->s);
}
if (uor->fd != -1) {
close(uor->fd);
}
if (uor->fd2 != -1) {
close(uor->fd2);
}
// remove the structure from the linked list;
struct uwsgi_offload_request *prev = uor->prev;
struct uwsgi_offload_request *next = uor->next;
if (uor == ut->offload_requests_head) {
ut->offload_requests_head = next;
}
if (uor == ut->offload_requests_tail) {
ut->offload_requests_tail = prev;
}
if (prev) {
prev->next = next;
}
if (next) {
next->prev = prev;
}
if (uor->buf) {
free(uor->buf);
}
if (uor->ubuf) {
uwsgi_buffer_destroy(uor->ubuf);
}
if (uor->pipe[0] != -1) {
close(uor->pipe[1]);
close(uor->pipe[0]);
}
free(uor);
}
static void uwsgi_offload_append(struct uwsgi_thread *ut, struct uwsgi_offload_request *uor) {
if (!ut->offload_requests_head) {
ut->offload_requests_head = uor;
}
if (ut->offload_requests_tail) {
ut->offload_requests_tail->next = uor;
uor->prev = ut->offload_requests_tail;
}
ut->offload_requests_tail = uor;
}
static struct uwsgi_offload_request *uwsgi_offload_get_by_fd(struct uwsgi_thread *ut, int s) {
struct uwsgi_offload_request *uor = ut->offload_requests_head;
while (uor) {
if (uor->s == s || uor->fd == s || uor->fd2 == s) {
return uor;
}
uor = uor->next;
}
return NULL;
}
static void uwsgi_offload_loop(struct uwsgi_thread *ut) {
int i;
void *events = event_queue_alloc(uwsgi.offload_threads_events);
for (;;) {
int nevents = event_queue_wait_multi(ut->queue, -1, events, uwsgi.offload_threads_events);
for (i = 0; i < nevents; i++) {
int interesting_fd = event_queue_interesting_fd(events, i);
if (interesting_fd == ut->pipe[1]) {
struct uwsgi_offload_request *uor = uwsgi_malloc(sizeof(struct uwsgi_offload_request));
ssize_t len = read(ut->pipe[1], uor, sizeof(struct uwsgi_offload_request));
if (len != sizeof(struct uwsgi_offload_request)) {
uwsgi_error("read()");
free(uor);
continue;
}
// cal the event function for the first time
if (uor->engine->event_func(ut, uor, -1)) {
uwsgi_offload_close(ut, uor);
continue;
}
uwsgi_offload_append(ut, uor);
continue;
}
// get the task from the interesting fd
struct uwsgi_offload_request *uor = uwsgi_offload_get_by_fd(ut, interesting_fd);
if (!uor)
continue;
// run the hook
if (uor->engine->event_func(ut, uor, interesting_fd)) {
uwsgi_offload_close(ut, uor);
}
}
}
}
struct uwsgi_thread *uwsgi_offload_thread_start() {
return uwsgi_thread_new(uwsgi_offload_loop);
}
/*
the offload task starts after having acquired the file fd
uor->len -> the size of the file
uor->pos -> start writing from pos (default 0)
status: none
*/
static int u_offload_sendfile_do(struct uwsgi_thread *ut, struct uwsgi_offload_request *uor, int fd) {
if (fd == -1) {
if (event_queue_add_fd_write(ut->queue, uor->fd2)) return -1;
return 0;
}
#if defined(__linux__) || defined(__sun__)
ssize_t len = sendfile(uor->fd2, uor->fd, &uor->pos, 128 * 1024);
if (len > 0) {
uor->written += len;
if (uor->written >= uor->len) {
return -1;
}
return 0;
}
else if (len < 0) {
uwsgi_offload_retry
uwsgi_error("u_offload_sendfile_do()");
}
#elif defined(__FreeBSD__) || defined(__DragonFly__)
off_t sbytes = 0;
int ret = sendfile(uor->fd, uor->fd2, uor->pos, 0, NULL, &sbytes, 0);
// transfer finished
if (ret == -1) {
uor->pos += sbytes;
uwsgi_offload_retry
uwsgi_error("u_offload_sendfile_do()");
}
#elif defined(__APPLE__)
off_t len = 0;
int ret = sendfile(uor->fd, uor->fd2, uor->pos, &len, NULL, 0);
// transfer finished
if (ret == -1) {
uor->pos += len;
uwsgi_offload_retry
uwsgi_error("u_offload_sendfile_do()");
}
#endif
return -1;
}
/*
the offload task starts soon after the call to connect()
status:
0 -> waiting for connection on fd
1 -> sending request to fd (write event)
2 -> start waiting for read on s and fd
3 -> write to s
4 -> write to fd
*/
static int u_offload_transfer_do(struct uwsgi_thread *ut, struct uwsgi_offload_request *uor, int fd) {
ssize_t rlen;
// setup
if (fd == -1) {
event_queue_add_fd_write(ut->queue, uor->fd);
return 0;
}
switch(uor->status) {
// waiting for connection
case 0:
if (fd == uor->fd) {
uor->status = 1;
// ok try to send the request right now...
return u_offload_transfer_do(ut, uor, fd);
}
return -1;
// write event (or just connected)
case 1:
if (fd == uor->fd) {
rlen = write(uor->fd, uor->ubuf->buf + uor->written, uor->ubuf->pos-uor->written);
if (rlen > 0) {
uor->written += rlen;
if (uor->written >= (size_t)uor->ubuf->pos) {
uor->status = 2;
if (event_queue_add_fd_read(ut->queue, uor->s)) return -1;
if (event_queue_fd_write_to_read(ut->queue, uor->fd)) return -1;
}
return 0;
}
else if (rlen < 0) {
uwsgi_offload_retry
uwsgi_error("u_offload_transfer_do() -> write()");
}
}
return -1;
// read event from s or fd
case 2:
if (!uor->buf) {
uor->buf = uwsgi_malloc(4096);
}
if (fd == uor->fd) {
rlen = read(uor->fd, uor->buf, 4096);
if (rlen > 0) {
uor->to_write = rlen;
uor->pos = 0;
uwsgi_offload_0r_1w(uor->fd, uor->s)
uor->status = 3;
return 0;
}
if (rlen < 0) {
uwsgi_offload_retry
uwsgi_error("u_offload_transfer_do() -> read()/fd");
}
}
else if (fd == uor->s) {
rlen = read(uor->s, uor->buf, 4096);
if (rlen > 0) {
uor->to_write = rlen;
uor->pos = 0;
uwsgi_offload_0r_1w(uor->s, uor->fd)
uor->status = 4;
return 0;
}
if (rlen < 0) {
uwsgi_offload_retry
uwsgi_error("u_offload_transfer_do() -> read()/s");
}
}
return -1;
// write event on s
case 3:
rlen = write(uor->s, uor->buf + uor->pos, uor->to_write);
if (rlen > 0) {
uor->to_write -= rlen;
uor->pos += rlen;
if (uor->to_write == 0) {
if (event_queue_fd_write_to_read(ut->queue, uor->s)) return -1;
if (event_queue_add_fd_read(ut->queue, uor->fd)) return -1;
uor->status = 2;
}
return 0;
}
else if (rlen < 0) {
uwsgi_offload_retry
uwsgi_error("u_offload_transfer_do() -> write()/s");
}
return -1;
// write event on fd
case 4:
rlen = write(uor->fd, uor->buf + uor->pos, uor->to_write);
if (rlen > 0) {
uor->to_write -= rlen;
uor->pos += rlen;
if (uor->to_write == 0) {
if (event_queue_fd_write_to_read(ut->queue, uor->fd)) return -1;
if (event_queue_add_fd_read(ut->queue, uor->s)) return -1;
uor->status = 2;
}
return 0;
}
else if (rlen < 0) {
uwsgi_offload_retry
uwsgi_error("u_offload_transfer_do() -> write()/fd");
}
return -1;
default:
break;
}
return -1;
}
int uwsgi_offload_run(struct wsgi_request *wsgi_req, struct uwsgi_offload_request *uor, int *wait) {
if (uor->engine->prepare_func(wsgi_req, uor)) {
return -1;
}
if (wait) {
if (pipe(uor->pipe)) {
uwsgi_error("uwsgi_offload_setup()/pipe()");
return -1;
}
*wait = uor->pipe[0];
uwsgi_socket_nb(uor->pipe[0]);
uwsgi_socket_nb(uor->pipe[1]);
}
if (uor->takeover) {
wsgi_req->fd_closed = 1;
}
if (uwsgi_offload_enqueue(wsgi_req, uor)) {
close(uor->pipe[0]);
close(uor->pipe[1]);
if (uor->takeover) {
wsgi_req->fd_closed = 0;
}
return -1;
}
return 0;
};
struct uwsgi_offload_engine *uwsgi_offload_engine_by_name(char *name) {
struct uwsgi_offload_engine *uoe = uwsgi.offload_engines;
while(uoe) {
if (!strcmp(name, uoe->name)) {
return uoe;
}
}
return NULL;
}
struct uwsgi_offload_engine *uwsgi_offload_register_engine(char *name, int (*prepare_func)(struct wsgi_request *, struct uwsgi_offload_request *), int (*event_func) (struct uwsgi_thread *, struct uwsgi_offload_request *, int)) {
struct uwsgi_offload_engine *old_engine=NULL,*engine=uwsgi.offload_engines;
while(engine) {
if (!strcmp(engine->name, name)) {
return engine;
}
old_engine = engine;
engine = engine->next;
}
engine = uwsgi_calloc(sizeof(struct uwsgi_offload_engine));
engine->name = name;
engine->prepare_func = prepare_func;
engine->event_func = event_func;
if (old_engine) {
old_engine->next = engine;
}
else {
uwsgi.offload_engines = engine;
}
return engine;
}
void uwsgi_offload_engines_register_all() {
uwsgi.offload_engine_sendfile = uwsgi_offload_register_engine("sendfile", u_offload_sendfile_prepare, u_offload_sendfile_do);
uwsgi.offload_engine_transfer = uwsgi_offload_register_engine("transfer", u_offload_transfer_prepare, u_offload_transfer_do);
}
int uwsgi_offload_request_sendfile_do(struct wsgi_request *wsgi_req, int fd, size_t len) {
struct uwsgi_offload_request uor;
uwsgi_offload_setup(uwsgi.offload_engine_sendfile, &uor, wsgi_req, 1);
uor.fd = fd;
uor.len = len;
return uwsgi_offload_run(wsgi_req, &uor, NULL);
}
int uwsgi_offload_request_net_do(struct wsgi_request *wsgi_req, char *socketname, struct uwsgi_buffer *ubuf) {
struct uwsgi_offload_request uor;
uwsgi_offload_setup(uwsgi.offload_engine_transfer, &uor, wsgi_req, 1);
uor.name = socketname;
uor.ubuf = ubuf;
return uwsgi_offload_run(wsgi_req, &uor, NULL);
}
+307
View File
@@ -0,0 +1,307 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
#ifdef UWSGI_ELF
static void uwsgi_plugin_parse_section(char *filename) {
size_t s_len = 0;
char *buf = uwsgi_elf_section(filename, "uwsgi", &s_len);
if (buf) {
char *ctx = NULL;
char *p = strtok_r(buf, "\n", &ctx);
while (p) {
char *equal = strchr(p, '=');
if (equal) {
*equal = 0;
if (!strcmp(p, "requires")) {
uwsgi_load_plugin(-1, equal + 1, NULL);
}
}
p = strtok_r(NULL, "\n", &ctx);
}
free(buf);
}
}
#endif
int plugin_already_loaded(const char *plugin) {
int i;
for (i = 0; i < 256; i++) {
if (uwsgi.p[i]->name) {
if (!strcmp(plugin, uwsgi.p[i]->name)) {
#ifdef UWSGI_DEBUG
uwsgi_log("%s plugin already available\n", plugin);
#endif
return 1;
}
}
if (uwsgi.p[i]->alias) {
if (!strcmp(plugin, uwsgi.p[i]->alias)) {
#ifdef UWSGI_DEBUG
uwsgi_log("%s plugin already available\n", plugin);
#endif
return 1;
}
}
}
for (i = 0; i < uwsgi.gp_cnt; i++) {
if (uwsgi.gp[i]->name) {
if (!strcmp(plugin, uwsgi.gp[i]->name)) {
#ifdef UWSGI_DEBUG
uwsgi_log("%s plugin already available\n", plugin);
#endif
return 1;
}
}
if (uwsgi.gp[i]->alias) {
if (!strcmp(plugin, uwsgi.gp[i]->alias)) {
#ifdef UWSGI_DEBUG
uwsgi_log("%s plugin already available\n", plugin);
#endif
return 1;
}
}
}
return 0;
}
void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {
void *plugin_handle = NULL;
char *plugin_abs_path = NULL;
char *plugin_filename = NULL;
int need_free = 0;
char *plugin_name = uwsgi_strip(uwsgi_str(plugin));
char *plugin_symbol_name_start = plugin_name;
struct uwsgi_plugin *up;
char linkpath_buf[1024], linkpath[1024];
int linkpath_size;
char *colon = strchr(plugin_name, ':');
if (colon) {
colon[0] = 0;
modifier = atoi(plugin_name);
plugin_name = colon + 1;
colon[0] = ':';
}
if (!uwsgi_endswith(plugin_name, "_plugin.so")) {
plugin_name = uwsgi_concat2(plugin_name, "_plugin.so");
need_free = 1;
}
plugin_symbol_name_start = plugin_name;
// step 1: check for absolute plugin (stop if it fails)
if (strchr(plugin_name, '/')) {
#ifdef UWSGI_ELF
uwsgi_plugin_parse_section(plugin_name);
#endif
plugin_handle = dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL);
if (!plugin_handle) {
if (!has_option)
uwsgi_log("%s\n", dlerror());
goto end;
}
plugin_symbol_name_start = uwsgi_get_last_char(plugin_name, '/');
plugin_symbol_name_start++;
plugin_abs_path = plugin_name;
goto success;
}
// step dir, check for user-supplied plugins directory
struct uwsgi_string_list *pdir = uwsgi.plugins_dir;
while (pdir) {
plugin_filename = uwsgi_concat3(pdir->value, "/", plugin_name);
#ifdef UWSGI_ELF
uwsgi_plugin_parse_section(plugin_filename);
#endif
plugin_handle = dlopen(plugin_filename, RTLD_NOW | RTLD_GLOBAL);
if (plugin_handle) {
plugin_abs_path = plugin_filename;
//free(plugin_filename);
goto success;
}
free(plugin_filename);
plugin_filename = NULL;
pdir = pdir->next;
}
// last step: search in compile-time plugin_dir
if (!plugin_handle) {
plugin_filename = uwsgi_concat3(UWSGI_PLUGIN_DIR, "/", plugin_name);
#ifdef UWSGI_ELF
uwsgi_plugin_parse_section(plugin_filename);
#endif
plugin_handle = dlopen(plugin_filename, RTLD_NOW | RTLD_GLOBAL);
plugin_abs_path = plugin_filename;
//free(plugin_filename);
}
success:
if (!plugin_handle) {
if (!has_option)
uwsgi_log("!!! UNABLE to load uWSGI plugin: %s !!!\n", dlerror());
}
else {
char *plugin_entry_symbol = uwsgi_concat2n(plugin_symbol_name_start, strlen(plugin_symbol_name_start) - 3, "", 0);
up = dlsym(plugin_handle, plugin_entry_symbol);
if (!up) {
// is it a link ?
memset(linkpath_buf, 0, 1024);
memset(linkpath, 0, 1024);
if ((linkpath_size = readlink(plugin_abs_path, linkpath_buf, 1023)) > 0) {
do {
linkpath_buf[linkpath_size] = '\0';
strncpy(linkpath, linkpath_buf, linkpath_size + 1);
} while ((linkpath_size = readlink(linkpath, linkpath_buf, 1023)) > 0);
#ifdef UWSGI_DEBUG
uwsgi_log("%s\n", linkpath);
#endif
free(plugin_entry_symbol);
char *slash = uwsgi_get_last_char(linkpath, '/');
if (!slash) {
slash = linkpath;
}
else {
slash++;
}
plugin_entry_symbol = uwsgi_concat2n(slash, strlen(slash) - 3, "", 0);
up = dlsym(plugin_handle, plugin_entry_symbol);
}
}
if (up) {
if (!up->name) {
uwsgi_log("the loaded plugin (%s) has no .name attribute\n", plugin_name);
if (dlclose(plugin_handle)) {
uwsgi_error("dlclose()");
}
if (need_free)
free(plugin_name);
if (plugin_filename)
free(plugin_filename);
free(plugin_entry_symbol);
return NULL;
}
if (plugin_already_loaded(up->name)) {
if (dlclose(plugin_handle)) {
uwsgi_error("dlclose()");
}
if (need_free)
free(plugin_name);
if (plugin_filename)
free(plugin_filename);
free(plugin_entry_symbol);
return NULL;
}
if (has_option) {
struct uwsgi_option *op = up->options;
int found = 0;
while (op && op->name) {
if (!strcmp(has_option, op->name)) {
found = 1;
break;
}
op++;
}
if (!found) {
if (dlclose(plugin_handle)) {
uwsgi_error("dlclose()");
}
if (need_free)
free(plugin_name);
if (plugin_filename)
free(plugin_filename);
free(plugin_entry_symbol);
return NULL;
}
}
if (modifier != -1) {
fill_plugin_table(modifier, up);
up->modifier1 = modifier;
}
else {
fill_plugin_table(up->modifier1, up);
}
if (need_free)
free(plugin_name);
if (plugin_filename)
free(plugin_filename);
free(plugin_entry_symbol);
if (up->on_load)
up->on_load();
return plugin_handle;
}
if (!has_option)
uwsgi_log("%s\n", dlerror());
}
end:
if (need_free)
free(plugin_name);
if (plugin_filename)
free(plugin_filename);
return NULL;
}
int uwsgi_try_autoload(char *option) {
DIR *d;
struct dirent *dp;
// step dir, check for user-supplied plugins directory
struct uwsgi_string_list *pdir = uwsgi.plugins_dir;
while (pdir) {
d = opendir(pdir->value);
if (d) {
while ((dp = readdir(d)) != NULL) {
if (uwsgi_endswith(dp->d_name, "_plugin.so")) {
char *filename = uwsgi_concat3(pdir->value, "/", dp->d_name);
if (uwsgi_load_plugin(-1, filename, option)) {
uwsgi_log("option \"%s\" found in plugin %s\n", option, filename);
free(filename);
closedir(d);
// add new options
build_options();
return 1;
}
free(filename);
}
}
closedir(d);
}
pdir = pdir->next;
}
// last step: search in compile-time plugin_dir
d = opendir(UWSGI_PLUGIN_DIR);
if (!d)
return 0;
while ((dp = readdir(d)) != NULL) {
if (uwsgi_endswith(dp->d_name, "_plugin.so")) {
char *filename = uwsgi_concat3(UWSGI_PLUGIN_DIR, "/", dp->d_name);
if (uwsgi_load_plugin(-1, filename, option)) {
uwsgi_log("option \"%s\" found in plugin %s\n", option, filename);
free(filename);
closedir(d);
// add new options
build_options();
return 1;
}
free(filename);
}
}
closedir(d);
return 0;
}
+107
View File
@@ -0,0 +1,107 @@
#include <uwsgi.h>
/*
upload progress facilities
*/
extern struct uwsgi_server uwsgi;
char *uwsgi_upload_progress_create(struct wsgi_request *wsgi_req, int *fd) {
const char *x_progress_id = "X-Progress-ID=";
char *xpi_ptr = (char *) x_progress_id;
uint16_t i;
char *upload_progress_filename = NULL;
if (wsgi_req->uri_len <= 51)
return NULL;
for (i = 0; i < wsgi_req->uri_len; i++) {
if (wsgi_req->uri[i] == xpi_ptr[0]) {
if (xpi_ptr[0] == '=') {
if (wsgi_req->uri + i + 36 <= wsgi_req->uri + wsgi_req->uri_len) {
upload_progress_filename = wsgi_req->uri + i + 1;
}
break;
}
xpi_ptr++;
}
else {
xpi_ptr = (char *) x_progress_id;
}
}
// now check for valid uuid (from spec available at http://en.wikipedia.org/wiki/Universally_unique_identifier)
if (!upload_progress_filename)
return NULL;
uwsgi_log("upload progress uuid = %.*s\n", 36, upload_progress_filename);
if (!check_hex(upload_progress_filename, 8))
return NULL;
if (upload_progress_filename[8] != '-')
return NULL;
if (!check_hex(upload_progress_filename + 9, 4))
return NULL;
if (upload_progress_filename[13] != '-')
return NULL;
if (!check_hex(upload_progress_filename + 14, 4))
return NULL;
if (upload_progress_filename[18] != '-')
return NULL;
if (!check_hex(upload_progress_filename + 19, 4))
return NULL;
if (upload_progress_filename[23] != '-')
return NULL;
if (!check_hex(upload_progress_filename + 24, 12))
return NULL;
upload_progress_filename = uwsgi_concat4n(uwsgi.upload_progress, strlen(uwsgi.upload_progress), "/", 1, upload_progress_filename, 36, ".js", 3);
// here we use O_EXCL to avoid eventual application bug in uuid generation/using
*fd = open(upload_progress_filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP);
if (*fd < 0) {
uwsgi_error_open(upload_progress_filename);
free(upload_progress_filename);
return NULL;
}
return upload_progress_filename;
}
int uwsgi_upload_progress_update(struct wsgi_request *wsgi_req, int fd, size_t remains) {
char buf[4096];
int ret = snprintf(buf, 4096, "{ \"state\" : \"uploading\", \"received\" : %llu, \"size\" : %llu }\r\n", (unsigned long long) (wsgi_req->post_cl - remains), (unsigned long long) wsgi_req->post_cl);
if (ret < 0) {
return -1;
}
if (lseek(fd, 0, SEEK_SET)) {
uwsgi_error("uwsgi_upload_progress_update()/lseek()");
return -1;
}
if (write(fd, buf, ret) != ret) {
uwsgi_error("uwsgi_upload_progress_update()/write()");
return -1;
}
if (fsync(fd)) {
uwsgi_error("uwsgi_upload_progress_update()/fsync()");
return -1;
}
return 0;
}
void uwsgi_upload_progress_destroy(char *filename, int fd) {
close(fd);
if (unlink(filename)) {
uwsgi_error("uwsgi_upload_progress_destroy()/unlink()");
}
free(filename);
}
+1086
View File
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
#include <uwsgi.h>
/*
QUERY_STRING management functions (mainly used by the internal routing subsystem)
*/
static char *check_qs(char *qs, uint16_t qs_len, char *key, uint16_t keylen, uint16_t *vallen) {
// search for the equal sign
char *equal = memchr(qs, '=', qs_len);
if (!equal) return NULL;
if (uwsgi_strncmp(key, keylen, qs, equal-qs)) {
return NULL;
}
qs_len -= (equal-qs)+1;
if (qs_len == 0) return NULL;
*vallen = qs_len;
return equal+1;
}
char *uwsgi_get_qs(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
uint16_t i;
char *qs = wsgi_req->query_string;
uint16_t qs_len = 0;
char *ptr = wsgi_req->query_string;
//start splitting by ;
for(i=0;i<wsgi_req->query_string_len;i++) {
if (!qs) {
qs = ptr + i;
}
if (ptr[i] == '&') {
char *value = check_qs(qs, qs_len, key, keylen, vallen);
if (value) {
return value;
}
qs_len = 0;
qs = NULL;
}
else {
qs_len++;
}
}
if (qs_len > 0) {
char *value = check_qs(qs, qs_len, key, keylen, vallen);
if (value) {
return value;
}
}
return NULL;
}
+194
View File
@@ -0,0 +1,194 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
void uwsgi_init_queue() {
if (!uwsgi.queue_blocksize)
uwsgi.queue_blocksize = 8192;
if ((uwsgi.queue_blocksize * uwsgi.queue_size) % uwsgi.page_size != 0) {
uwsgi_log("invalid queue size/blocksize %llu: must be a multiple of memory page size (%d bytes)\n", (unsigned long long) uwsgi.queue_blocksize, uwsgi.page_size);
exit(1);
}
if (uwsgi.queue_store) {
uwsgi.queue_filesize = uwsgi.queue_blocksize * uwsgi.queue_size + 16;
int queue_fd;
struct stat qst;
if (stat(uwsgi.queue_store, &qst)) {
uwsgi_log("creating a new queue store file: %s\n", uwsgi.queue_store);
queue_fd = open(uwsgi.queue_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (queue_fd >= 0) {
// fill the queue store
if (ftruncate(queue_fd, uwsgi.queue_filesize)) {
uwsgi_log("ftruncate()");
exit(1);
}
}
}
else {
if ((size_t) qst.st_size != uwsgi.queue_filesize || !S_ISREG(qst.st_mode)) {
uwsgi_log("invalid queue store file. Please remove it or fix queue blocksize/items to match its size\n");
exit(1);
}
queue_fd = open(uwsgi.queue_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
uwsgi_log("recovered queue from backing store file: %s\n", uwsgi.queue_store);
}
if (queue_fd < 0) {
uwsgi_error_open(uwsgi.queue_store);
exit(1);
}
uwsgi.queue = mmap(NULL, uwsgi.queue_filesize, PROT_READ | PROT_WRITE, MAP_SHARED, queue_fd, 0);
// 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);
// fix header
uwsgi.queue_header = uwsgi.queue;
uwsgi.queue += 16;
uwsgi.queue_header->pos = 0;
uwsgi.queue_header->pull_pos = 0;
}
if (!uwsgi.queue) {
uwsgi_error("mmap()");
exit(1);
}
uwsgi.queue_lock = uwsgi_rwlock_init("queue");
uwsgi_log("*** Queue subsystem initialized: %luMB preallocated ***\n", (uwsgi.queue_blocksize * uwsgi.queue_size) / (1024 * 1024));
}
char *uwsgi_queue_get(uint64_t index, uint64_t * size) {
struct uwsgi_queue_item *uqi;
char *ptr = (char *) uwsgi.queue;
if (index >= uwsgi.queue_size)
return NULL;
ptr = ptr + (uwsgi.queue_blocksize * index);
uqi = (struct uwsgi_queue_item *) ptr;
*size = uqi->size;
return ptr + sizeof(struct uwsgi_queue_item);
}
char *uwsgi_queue_pop(uint64_t * size) {
struct uwsgi_queue_item *uqi;
char *ptr = (char *) uwsgi.queue;
if (uwsgi.queue_header->pos == 0) {
uwsgi.queue_header->pos = uwsgi.queue_size - 1;
}
else {
uwsgi.queue_header->pos--;
}
ptr = ptr + (uwsgi.queue_blocksize * uwsgi.queue_header->pos);
uqi = (struct uwsgi_queue_item *) ptr;
if (!uqi->size)
return NULL;
*size = uqi->size;
// remove item
uqi->size = 0;
return ptr + sizeof(struct uwsgi_queue_item);
}
char *uwsgi_queue_pull(uint64_t * size) {
struct uwsgi_queue_item *uqi;
char *ptr = (char *) uwsgi.queue;
ptr = ptr + (uwsgi.queue_blocksize * uwsgi.queue_header->pull_pos);
uqi = (struct uwsgi_queue_item *) ptr;
if (!uqi->size)
return NULL;
*size = uqi->size;
uwsgi.queue_header->pull_pos++;
if (uwsgi.queue_header->pull_pos >= uwsgi.queue_size)
uwsgi.queue_header->pull_pos = 0;
// remove item
uqi->size = 0;
return ptr + sizeof(struct uwsgi_queue_item);
}
int uwsgi_queue_push(char *message, uint64_t size) {
struct uwsgi_queue_item *uqi;
char *ptr = (char *) uwsgi.queue;
if (size > uwsgi.queue_blocksize + sizeof(struct uwsgi_queue_item))
return 0;
if (!size)
return 0;
ptr = ptr + (uwsgi.queue_blocksize * uwsgi.queue_header->pos);
uqi = (struct uwsgi_queue_item *) ptr;
ptr += sizeof(struct uwsgi_queue_item);
uqi->size = size;
uqi->ts = uwsgi_now();
memcpy(ptr, message, size);
uwsgi.queue_header->pos++;
if (uwsgi.queue_header->pos >= uwsgi.queue_size)
uwsgi.queue_header->pos = 0;
return 1;
}
int uwsgi_queue_set(uint64_t pos, char *message, uint64_t size) {
struct uwsgi_queue_item *uqi;
char *ptr = (char *) uwsgi.queue;
if (size > uwsgi.queue_blocksize + sizeof(struct uwsgi_queue_item))
return 0;
if (!size)
return 0;
if (pos >= uwsgi.queue_size)
return 0;
ptr = ptr + (uwsgi.queue_blocksize * pos);
uqi = (struct uwsgi_queue_item *) ptr;
ptr += sizeof(struct uwsgi_queue_item);
uqi->size = size;
uqi->ts = uwsgi_now();
memcpy(ptr, message, size);
return 1;
}

Some files were not shown because too many files have changed in this diff Show More