├── .gitignore ├── .readthedocs.yml ├── API.rst ├── AlarmSubsystem.rst ├── Apache.rst ├── Async.rst ├── AttachingDaemons.rst ├── Broodlord.rst ├── BuildSystem.rst ├── CGI.rst ├── CONTRIBUTORS ├── C_Api.rst ├── Caching.rst ├── Capabilities.rst ├── Carbon.rst ├── Cgroups.rst ├── Changelog-1.4.10.rst ├── Changelog-1.9.1.rst ├── Changelog-1.9.10.rst ├── Changelog-1.9.11.rst ├── Changelog-1.9.12.rst ├── Changelog-1.9.13.rst ├── Changelog-1.9.14.rst ├── Changelog-1.9.15.rst ├── Changelog-1.9.16.rst ├── Changelog-1.9.17.rst ├── Changelog-1.9.18.rst ├── Changelog-1.9.19.rst ├── Changelog-1.9.2.rst ├── Changelog-1.9.20.rst ├── Changelog-1.9.21.rst ├── Changelog-1.9.3.rst ├── Changelog-1.9.4.rst ├── Changelog-1.9.5.rst ├── Changelog-1.9.6.rst ├── Changelog-1.9.7.rst ├── Changelog-1.9.8.rst ├── Changelog-1.9.9.rst ├── Changelog-1.9.rst ├── Changelog-2.0.1.rst ├── Changelog-2.0.10.rst ├── Changelog-2.0.11.1.rst ├── Changelog-2.0.11.2.rst ├── Changelog-2.0.11.rst ├── Changelog-2.0.12.rst ├── Changelog-2.0.13.1.rst ├── Changelog-2.0.13.rst ├── Changelog-2.0.14.rst ├── Changelog-2.0.15.rst ├── Changelog-2.0.16.rst ├── Changelog-2.0.17.1.rst ├── Changelog-2.0.17.rst ├── Changelog-2.0.18.rst ├── Changelog-2.0.19.1.rst ├── Changelog-2.0.19.rst ├── Changelog-2.0.2.rst ├── Changelog-2.0.20.rst ├── Changelog-2.0.21.rst ├── Changelog-2.0.22.rst ├── Changelog-2.0.23.rst ├── Changelog-2.0.24.rst ├── Changelog-2.0.25.1.rst ├── Changelog-2.0.25.rst ├── Changelog-2.0.26.rst ├── Changelog-2.0.27.rst ├── Changelog-2.0.28.rst ├── Changelog-2.0.29.rst ├── Changelog-2.0.3.rst ├── Changelog-2.0.30.rst ├── Changelog-2.0.31.rst ├── Changelog-2.0.4.rst ├── Changelog-2.0.5.rst ├── Changelog-2.0.6.rst ├── Changelog-2.0.7.rst ├── Changelog-2.0.8.rst ├── Changelog-2.0.9.rst ├── Changelog-2.0.rst ├── Cheaper.rst ├── Cherokee.rst ├── Chunked.rst ├── Circus.rst ├── ConfigLogic.rst ├── Configuration.rst ├── Cron.rst ├── CustomOptions.rst ├── Download.rst ├── DynamicApps.rst ├── Embed.rst ├── Emperor.rst ├── EmperorProtocol.rst ├── Erlang.rst ├── FAQ.rst ├── FallbackConfig.rst ├── Fastrouter.rst ├── ForkServer.rst ├── ForkptyRouter.rst ├── FreeBSDJails.rst ├── GCCGO.rst ├── GeoIP.rst ├── Gevent.rst ├── Glossary.rst ├── GlusterFS.rst ├── Go.rst ├── GridFS.rst ├── HTTP.rst ├── HTTPS.rst ├── Hooks.rst ├── ImperialMonitors.rst ├── Inetd.rst ├── Install.rst ├── InternalRouting.rst ├── JVM.rst ├── JWSGI.rst ├── KSM.rst ├── LDAP.rst ├── LICENSE ├── LanguagesAndPlatforms.rst ├── Legion.rst ├── Lighttpd.rst ├── Locks.rst ├── LogEncoders.rst ├── LogFormat.rst ├── Logging.rst ├── Lua.rst ├── Makefile ├── Management.rst ├── ManagementFlag.rst ├── MasterFIFO.rst ├── Metrics.rst ├── Mongrel2.rst ├── Mono.rst ├── Mules.rst ├── Nagios.rst ├── Namespaces.rst ├── Nginx.rst ├── OffloadSubsystem.rst ├── OnDemandVassals.rst ├── OpenBSDhttpd.rst ├── Options.rst ├── PHP.rst ├── PSGIquickstart.rst ├── ParsingOrder.rst ├── Perl.rst ├── Protocol.rst ├── Pty.rst ├── PushingStats.rst ├── PyPy.rst ├── Python.rst ├── PythonDecorators.rst ├── PythonModule.rst ├── PythonModuleAlias.rst ├── PythonPump.rst ├── Queue.rst ├── README.rst ├── RPC.rst ├── RackQuickstart.rst ├── Rados.rst ├── Ring.rst ├── Ruby.rst ├── RubyAPI.rst ├── SNI.rst ├── SNMP.rst ├── SPDY.rst ├── SPNEGO.rst ├── SSI.rst ├── SSLScaling.rst ├── SharedArea.rst ├── Signals.rst ├── Snippets.rst ├── Spooler.rst ├── StaticFiles.rst ├── StatsServer.rst ├── SubscriptionServer.rst ├── SupportedPlatforms.rst ├── Symcall.rst ├── Systemd.rst ├── ThingsToKnow.rst ├── ThirdPartyPlugins.rst ├── Tornado.rst ├── Tracebacker.rst ├── Transformations.rst ├── TunTapRouter.rst ├── UpgradingTo2.0.rst ├── Upstart.rst ├── V8.rst ├── Vars.rst ├── WSGIquickstart.rst ├── WebCaching.rst ├── WebServers.rst ├── WebSockets.rst ├── WorkerOverride.rst ├── XSLT.rst ├── Zerg.rst ├── _options ├── generate.py ├── optdefs.py ├── optutil.py └── parse_c.py ├── _tools ├── trac_miniparser.py └── wikitool.py ├── articles ├── FunWithPerlEyetoyRaspberrypi.rst ├── MassiveHostingWithEmperorAndNamespaces.rst ├── OffloadingWebsocketsAndSSE.rst ├── SerializingAccept.rst ├── TheArtOfGracefulReloading.rst └── WSGIEnvBehaviour.rst ├── asyncio.rst ├── conf.py ├── examples ├── CPythonForkServer.rst └── README.rst ├── generate_options.pl ├── index.rst ├── optdefs.pl ├── tips_and_tricks └── README.rst ├── tutorials ├── CachingCookbook.rst ├── ConfiguringFastRouterUsingACPPPlugin.rst ├── Django_and_nginx.rst ├── DynamicProxying.rst ├── EmperorSubscriptions.rst ├── GraphiteAndMetrics.rst ├── README.rst ├── ReliableFuse.rst ├── WritingPlugins.rst ├── dreamhost.rst ├── heroku_python.rst └── heroku_ruby.rst └── uGreen.rst /.gitignore: -------------------------------------------------------------------------------- 1 | *.bat 2 | *.pyc 3 | _build 4 | _wiki 5 | _ml 6 | *.sublime* 7 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Set the version of Python and other tools you might need 9 | build: 10 | os: ubuntu-22.04 11 | tools: 12 | python: "3.11" 13 | 14 | # Build documentation in the docs/ directory with Sphinx 15 | sphinx: 16 | configuration: conf.py 17 | 18 | # We recommend specifying your dependencies to enable reproducible builds: 19 | # https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 20 | # python: 21 | # install: 22 | # - requirements: docs/requirements.txt 23 | -------------------------------------------------------------------------------- /Broodlord.rst: -------------------------------------------------------------------------------- 1 | Auto-scaling with Broodlord mode 2 | ================================ 3 | 4 | Broodlord (taken from Starcraft, like :doc:`Zerg` mode) is a way for a vassal to 5 | ask for "reinforcements" to the Emperor. "Reinforcements" are new vassals spawned on demand generally 6 | bound on the same socket. Broodlord mode alone is not very useful. However, when combined with :doc:`Zerg`, :doc:`Idle` and :doc:`Emperor` 7 | it can be used to implement auto-scaling for your apps. 8 | 9 | WARNING: If you are looking for a way to dynamically adapt the number of workers of an instance, check the :doc:`Cheaper` mode, Broodlord mode is for spawning totally new instances. 10 | 11 | A 'simple' example 12 | ------------------ 13 | 14 | We'll start apps with a single worker, adding resources on demand. Broodlord 15 | mode expects an additional stanza in your config file to be used for zergs. 16 | 17 | .. code-block:: ini 18 | 19 | [uwsgi] 20 | socket = :3031 21 | master = true 22 | vassal-sos-backlog = 10 23 | module = werkzeug.testapp:test_app 24 | processes = 1 25 | zerg-server = /tmp/broodlord.sock 26 | disable-logging = true 27 | 28 | [zerg] 29 | zerg = /tmp/broodlord.sock 30 | master = true 31 | module = werkzeug.testapp:test_app 32 | processes = 1 33 | disable-logging = true 34 | idle = 30 35 | die-on-idle = true 36 | 37 | The ``vassal-sos-backlog`` option (supported only on Linux and TCP sockets) 38 | will ask the Emperor for zergs when the listen queue is higher than the given 39 | value. By default the value is 10. More "vassal-sos-" options will be added in 40 | the future to allow for more specific detect-overload systems. 41 | 42 | The ``[zerg]`` stanza is the config the Emperor will run when a vassal requires 43 | resources. The ``die-on-idle`` option will completely destroy the zerg when 44 | inactive for more than 30 seconds. This configuration shows how to combine the 45 | various uWSGI features to implement different means of scaling. To run the 46 | Emperor we need to specify how many zerg instances can be run: 47 | 48 | .. code-block:: sh 49 | 50 | uwsgi --emperor /etc/vassals --emperor-broodlord 40 51 | 52 | This will allow you to run up to 40 additional zerg workers for your apps. 53 | 54 | `--vassal-sos` 55 | -------------- 56 | 57 | .. note:: 58 | 59 | This flag has been added in 2.0.7. 60 | 61 | `--vassal-sos` allows the vassal to ask for reinforcement as soon as all of its workers are busy. 62 | 63 | The option takes an integer value, the number of seconds to wait between asking for a new reinforcements. 64 | 65 | Manually asking for reinforcement 66 | --------------------------------- 67 | 68 | You can use the master FIFO's "B" command to force an instance to ask for reinforcements from the Emperor. 69 | 70 | .. code-block:: sh 71 | 72 | echo B > /var/run/master.fifo 73 | 74 | Under the hood (or: hacking broodlord mode) 75 | -------------------------------------------- 76 | 77 | Technically broodlord mode is a simple message sent by a vassal to "force" the Emperor to spawn another vassal with a ':zerg' suffix in the instance name. 78 | 79 | Even if the suffix is ':zerg' this does not mean you need to use Zerg mode. A 'zerg' instance could be a completely independent one that simply subscribes 80 | to a router, or binds to a SO_REUSEPORT socket. 81 | 82 | This is an example with subscription system. 83 | 84 | .. code-block:: ini 85 | 86 | [uwsgi] 87 | socket = 127.0.0.1:0 88 | subscribe2 = server=127.0.0.1:4040,key=foobar.it 89 | psgi = app.pl 90 | processes = 4 91 | vassal-sos = 3 92 | 93 | [zerg] 94 | socket = 127.0.0.1:0 95 | subscribe2 = server=127.0.0.1:4040,key=foobar.it 96 | psgi = app.pl 97 | idle = 60 98 | processes = 1 99 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Aarni Koskela 2 | Łukasz Mierzwa 3 | Bill Anderson 4 | Daniele Procida 5 | Ryan Petrello 6 | Pavlo Kapyshin 7 | Lorenzo L. Ancora 8 | -------------------------------------------------------------------------------- /C_Api.rst: -------------------------------------------------------------------------------- 1 | The uWSGI C api 2 | =============== 3 | 4 | the wsgi_request struct 5 | *********************** 6 | 7 | the uwsgi_server struct 8 | *********************** 9 | 10 | Headers and response 11 | ******************** 12 | 13 | buffers 14 | ******* 15 | 16 | strings 17 | ******* 18 | 19 | non-blocking I/O 20 | **************** 21 | 22 | Offloading 23 | ********** 24 | 25 | Request body 26 | ************ 27 | 28 | Cookies 29 | ******* 30 | 31 | Caches 32 | ****** 33 | 34 | Signals 35 | ******* 36 | 37 | Locking 38 | ******* 39 | 40 | Zlib 41 | **** 42 | 43 | Alarms 44 | ****** 45 | 46 | Websockets 47 | ********** 48 | 49 | Exec 50 | **** 51 | 52 | -------------------------------------------------------------------------------- /Capabilities.rst: -------------------------------------------------------------------------------- 1 | Setting POSIX Capabilities 2 | ========================== 3 | 4 | `POSIX capabilities`_ allow fine-grained permissions for processes. In addition 5 | to the standard UNIX permission scheme, they define a new set of privileges for 6 | system resources. To enable capabilities support (Linux Only) you have to 7 | install the ``libcap`` headers (``libcap-dev`` on Debian-based distros) before 8 | building uWSGI. As usual your processes will lose practically all of the 9 | capabilities after a ``setuid`` call. The uWSGI ``cap`` option allows you to 10 | define a list of capabilities to maintain through the call. 11 | 12 | For example, to allow your unprivileged app to bind on privileged ports and set 13 | the system clock, you will use the following options. 14 | 15 | .. code-block:: sh 16 | 17 | uwsgi --socket :1000 --uid 5000 --gid 5000 --cap net_bind_service,sys_time 18 | 19 | All of the processes generated by uWSGI will then inherit this behaviour. If 20 | your system supports capabilities not available in the uWSGI list you can 21 | simply specify the number of the constant: 22 | 23 | .. code-block:: sh 24 | 25 | uwsgi --socket :1000 --uid 5000 --gid 5000 --cap net_bind_service,sys_time,42 26 | 27 | In addition to ``net_bind_service`` and ``sys_time``, a new capability numbered '42' is added. 28 | 29 | .. _POSIX capabilities: http://en.wikipedia.org/wiki/Capability-based_security 30 | 31 | Available capabilities 32 | ---------------------- 33 | 34 | 35 | This is the list of available capabilities. 36 | 37 | ================== ====================== 38 | audit_control CAP_AUDIT_CONTROL 39 | audit_write CAP_AUDIT_WRITE 40 | chown CAP_CHOWN 41 | dac_override CAP_DAC_OVERRIDE 42 | dac_read_search CAP_DAC_READ_SEARCH 43 | fowner CAP_FOWNER 44 | fsetid CAP_FSETID 45 | ipc_lock CAP_IPC_LOCK 46 | ipc_owner CAP_IPC_OWNER 47 | kill CAP_KILL 48 | lease CAP_LEASE 49 | linux_immutable CAP_LINUX_IMMUTABLE 50 | mac_admin CAP_MAC_ADMIN 51 | mac_override CAP_MAC_OVERRIDE 52 | mknod CAP_MKNOD 53 | net_admin CAP_NET_ADMIN 54 | net_bind_service CAP_NET_BIND_SERVICE 55 | net_broadcast CAP_NET_BROADCAST 56 | net_raw CAP_NET_RAW 57 | setfcap CAP_SETFCAP 58 | setgid CAP_SETGID 59 | setpcap CAP_SETPCAP 60 | setuid CAP_SETUID 61 | sys_admin CAP_SYS_ADMIN 62 | sys_boot CAP_SYS_BOOT 63 | sys_chroot CAP_SYS_CHROOT 64 | sys_module CAP_SYS_MODULE 65 | sys_nice CAP_SYS_NICE 66 | sys_pacct CAP_SYS_PACCT 67 | sys_ptrace CAP_SYS_PTRACE 68 | sys_rawio CAP_SYS_RAWIO 69 | sys_resource CAP_SYS_RESOURCE 70 | sys_time CAP_SYS_TIME 71 | sys_tty_config CAP_SYS_TTY_CONFIG 72 | syslog CAP_SYSLOG 73 | wake_alarm CAP_WAKE_ALARM 74 | ================== ====================== 75 | -------------------------------------------------------------------------------- /Carbon.rst: -------------------------------------------------------------------------------- 1 | Integration with Graphite/Carbon 2 | ================================ 3 | 4 | `Graphite `_ is a kick-ass realtime graphing 5 | application built on top of three components: 6 | 7 | - Whisper -- a data storage system 8 | - Carbon -- a server for receiving data 9 | - Python web application for graph rendering and management. 10 | 11 | The uWSGI Carbon plugin allows you to send uWSGI's internal statistics to one 12 | or more Carbon servers. It is compiled in by default as of uWSGI 1.0, though 13 | it can also be built as a plugin. 14 | 15 | Quickstart 16 | ---------- 17 | 18 | For the sake of illustration, let's say your Carbon server is listening on 19 | ``127.0.0.1:2003`` and your uWSGI instance is on the machine ``debian32``, 20 | listening on ``127.0.0.1:3031`` with 4 processes. By adding the ``--carbon`` 21 | option to your uWSGI instance you'll instruct it to send its statistics to 22 | the Carbon server periodically. The default period is 60 seconds. 23 | 24 | .. code-block:: sh 25 | 26 | uwsgi --socket 127.0.0.1:3031 --carbon 127.0.0.1:2003 --processes 4 27 | 28 | Metrics are named like ``uwsgi...requests`` and 29 | ``uwsgi...worker.requests``, where: 30 | 31 | * ``hostname`` -- machine's hostname 32 | * ``id`` -- name of the first uWSGI socket (with dots replaced by underscores) 33 | * ``n`` -- number of the worker processes (1-based). 34 | 35 | Examples of names of Carbon metrics generated by uWSGI: 36 | 37 | * ``uwsgi.debian32.127_0_0_1:3031.requests`` 38 | (``uwsgi...requests``) 39 | * ``uwsgi.debian32.127_0_0_1:3031.worker1.requests`` 40 | (``uwsgi...worker.requests``) 41 | * ``uwsgi.debian32.127_0_0_1:3031.worker2.requests`` 42 | (``uwsgi...worker.requests``) 43 | * ``uwsgi.debian32.127_0_0_1:3031.worker3.requests`` 44 | (``uwsgi...worker.requests``) 45 | * ``uwsgi.debian32.127_0_0_1:3031.worker4.requests`` 46 | (``uwsgi...worker.requests``). 47 | 48 | .. seealso:: :doc:`tutorials/GraphiteAndMetrics` 49 | 50 | -------------------------------------------------------------------------------- /Cgroups.rst: -------------------------------------------------------------------------------- 1 | Running uWSGI in a Linux CGroup 2 | =============================== 3 | 4 | Linux cgroups are an amazing feature available in recent Linux kernels. They 5 | allow you to "jail" your processes in constrained environments with limited 6 | CPU, memory, scheduling priority, IO, etc.. 7 | 8 | .. note:: uWSGI has to be run as root to use cgroups. ``uid`` and ``gid`` are very, very necessary. 9 | 10 | Enabling cgroups 11 | ---------------- 12 | 13 | First you need to enable cgroup support in your system. Create the /cgroup 14 | directory and add this to your /etc/fstab: 15 | 16 | .. code-block:: sh 17 | 18 | none /cgroup cgroup cpu,cpuacct,memory 19 | 20 | Then mount /cgroup and you'll have jails with controlled CPU and memory usage. 21 | There are other Cgroup subsystems, but CPU and memory usage are the most useful 22 | to constrain. 23 | 24 | Let's run uWSGI in a cgroup: 25 | 26 | .. code-block:: sh 27 | 28 | ./uwsgi -M -p 8 --cgroup /cgroup/jail001 -w simple_app -m --http :9090 29 | 30 | Cgroups are simple directories. With this command your uWSGI server and its 31 | workers are "jailed" in the 'cgroup/jail001' cgroup. If you make a bunch of 32 | requests to the server, you will see usage counters -- cpuacct.* and 33 | memoryfiles.* in the cgroup directory growing. You can also use pre-existing 34 | cgroups by specifying a directory that already exists. 35 | 36 | A real world example: Scheduling QoS for your customers 37 | ------------------------------------------------------- 38 | 39 | Suppose you're hosting apps for 4 customers. Two of them are paying you $100 a 40 | month, one is paying $200, and the last is paying $400. To have a good Quality 41 | of Service implementation, the $100 apps should get 1/8, or 12.5% of your CPU 42 | power, the $200 app should get 1/4 (25%) and the last should get 50%. To 43 | implement this, we have to create 4 cgroups, one for each app, and limit their 44 | scheduling weights. 45 | 46 | .. code-block:: sh 47 | 48 | ./uwsgi --uid 1001 --gid 1001 -s /tmp/app1 -w app1 --cgroup /cgroup/app1 --cgroup-opt cpu.shares=125 49 | ./uwsgi --uid 1002 --gid 1002 -s /tmp/app2 -w app1 --cgroup /cgroup/app2 --cgroup-opt cpu.shares=125 50 | ./uwsgi --uid 1003 --gid 1003 -s /tmp/app3 -w app1 --cgroup /cgroup/app3 --cgroup-opt cpu.shares=250 51 | ./uwsgi --uid 1004 --gid 1004 -s /tmp/app4 -w app1 --cgroup /cgroup/app4 --cgroup-opt cpu.shares=500 52 | 53 | 54 | The ``cpu.shares`` values are simply computed relative to each other, so you 55 | can use whatever scheme you like, such as (125, 125, 250, 500) or even (1, 1, 56 | 2, 4). With CPU handled, we turn to limiting memory. Let's use the same 57 | scheme as before, with a maximum of 2 GB for all apps altogether. 58 | 59 | .. code-block:: sh 60 | 61 | ./uwsgi --uid 1001 --gid 1001 -s /tmp/app1 -w app1 --cgroup /cgroup/app1 --cgroup-opt cpu.shares=125 --cgroup-opt memory.limit_in_bytes=268435456 62 | ./uwsgi --uid 1002 --gid 1002 -s /tmp/app2 -w app1 --cgroup /cgroup/app2 --cgroup-opt cpu.shares=125 --cgroup-opt memory.limit_in_bytes=268435456 63 | ./uwsgi --uid 1003 --gid 1003 -s /tmp/app3 -w app1 --cgroup /cgroup/app3 --cgroup-opt cpu.shares=250 --cgroup-opt memory.limit_in_bytes=536870912 64 | ./uwsgi --uid 1004 --gid 1004 -s /tmp/app4 -w app1 --cgroup /cgroup/app4 --cgroup-opt cpu.shares=500 --cgroup-opt memory.limit_in_bytes=1067459584 65 | -------------------------------------------------------------------------------- /Changelog-1.4.10.rst: -------------------------------------------------------------------------------- 1 | uWSGI 1.4.10 (LTS) 2 | ================== 3 | 4 | 5 | Bugfixes 6 | ^^^^^^^^ 7 | 8 | * fixed python3 static files handling (via wsgi.file_wrapper) 9 | * backported python3 latin1 fix from 1.9 10 | * fixed --backtrace-depth 11 | * fixed python3 pyargv 12 | * fixed mule_msg pipe handling 13 | 14 | Availability 15 | ^^^^^^^^^^^^ 16 | 17 | uWSGI 1.4.10 has been released 20130823 18 | 19 | You can download it from: 20 | 21 | https://projects.unbit.it/downloads/uwsgi-1.4.10.tar.gz 22 | -------------------------------------------------------------------------------- /Changelog-1.9.10.rst: -------------------------------------------------------------------------------- 1 | uWSGI 1.9.10 2 | ============ 3 | 4 | Changelog [20130511] 5 | 6 | Bugfixes 7 | ******** 8 | 9 | * fixed alarm threads during reloads 10 | * fixed uninitialized memory in --touch-* options 11 | * fixed a regression in --attach-daemon 12 | 13 | New Features 14 | ************ 15 | 16 | Welcome to gccgo 17 | ^^^^^^^^^^^^^^^^ 18 | 19 | Go support in gcc 4.8 is amazing, thanks to the split-stack feature you can now have goroutines without allocating a whole pthread. 20 | 21 | As Go 1.1 will be no no more compatible with uWSGI, gccgo will became the official way for running go apps. 22 | 23 | The gccgo plugin is in early stage of development but it is already able to run in preforking mode. 24 | 25 | We are heavy working on a true "goroutines" Loop engine. Stay tuned. 26 | 27 | Final routes 28 | ^^^^^^^^^^^^ 29 | 30 | You can now run routing rules after a request. Obviously not all of the exposed actions make sense after the request but you should be able 31 | to write even more complex setup. 32 | 33 | Check this request limiter based on HTTP response status (a value you can get only after a request): 34 | 35 | https://github.com/unbit/uwsgi/blob/master/t/routing/errorlimiter.ini 36 | 37 | Availability 38 | ************ 39 | 40 | uWSGI 1.9.10 will be available since 20130511 at the following url: 41 | 42 | https://projects.unbit.it/downloads/uwsgi-1.9.10.tar.gz 43 | -------------------------------------------------------------------------------- /Changelog-1.9.17.rst: -------------------------------------------------------------------------------- 1 | uWSGI 1.9.17 2 | ============ 3 | 4 | Changelog [20130917] 5 | 6 | 7 | Bugfixes 8 | ******** 9 | 10 | - the 'pty' client is now blocking (safer approach) 11 | - removed strtok() usage (substituted by a new uwsgi api function on top of strtok_r() ) 12 | - fixed --pty-exec (Credits: C Anthony Risinger) 13 | - listen_queue/somaxconn linux check is now done even for UNIX sockets 14 | 15 | 16 | 17 | New features 18 | ************ 19 | 20 | The Master FIFO 21 | ^^^^^^^^^^^^^^^ 22 | 23 | This is a new management way in addition to UNIX signals. As we have no more free signals to use (and generally dealing with signals and pidfiles is not very funny), all of the new management features of uWSGI will be based on the master fifo. 24 | 25 | Docs are already available: :doc:`MasterFIFO` 26 | 27 | 28 | The asap hook 29 | ^^^^^^^^^^^^^ 30 | 31 | Credits: Matthijs Kooijman 32 | 33 | a new hook, named 'asap' has been added. It will be run soon after the options are parsed. 34 | 35 | Check: :doc:`Hooks` 36 | 37 | The TCC (libtcc) plugin 38 | ^^^^^^^^^^^^^^^^^^^^^^^ 39 | 40 | TCC is an embeddable c compilers. It includes a shared library (libtcc) you can use to compile strings of c code on the fly. 41 | 42 | The libtcc uWSGI plugins allows compiling strings of c to process symbols. CUrrently the "tcc" hook engine has been implemented: 43 | 44 | .. code-block:: ini 45 | 46 | [uwsgi] 47 | hook-asap = tcc:mkdir("/var/run/sockets");printf("directory created\n"); 48 | hook-as-user = tcc:printf("i am process with pid %d\n", getpid()); 49 | hook-post-app = tcc:if (getenv("DESTROY_THE_WORLD")) exit(1); 50 | http-socket = /var/run/sockets/foobar.sock 51 | 52 | 53 | 54 | The forkptyrouter gateway 55 | ^^^^^^^^^^^^^^^^^^^^^^^^^ 56 | 57 | While work on Linux containers/namespaces continues to improve we have added this special router/gateway allowing dynamic allocation of pseodoterminals 58 | in uWSGI instances. To access the sockets created by the forkptyrouter you can use the --pty-connect option exposed by the 'pty' plugin. 59 | 60 | Documention is being worked on. 61 | 62 | added a new magic var for ANSI escaping 63 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 64 | 65 | The %[ magic var has been added, it allows you to define ANSI sequences in your logs. 66 | 67 | If you like coloured logs: 68 | 69 | .. code-block:: ini 70 | 71 | log-encoder = format %[[33m${msgnl}%[[0m 72 | 73 | Routable log encoders 74 | ^^^^^^^^^^^^^^^^^^^^^ 75 | 76 | You can now attach log encoders to specific log routes: 77 | 78 | .. code-block:: ini 79 | 80 | [uwsgi] 81 | logger = stderr file:/dev/tty 82 | log-route = stderr ubuntu 83 | log-route = stderr clock 84 | print = %[[34mHELLO%[[0m 85 | ; add an encoder to the 'stderr' logger 86 | log-encoder = format:stderr %[[33m${msgnl}%[[0m 87 | http-socket = :9090 88 | 89 | --vassals-include 90 | ^^^^^^^^^^^^^^^^^ 91 | 92 | Credits: Matthijs Kooijman 93 | 94 | This is like --vassal-inherit but the parsing will be "immediate" (so you can use placeholders) 95 | 96 | The Emperor heartbeat system is now mercyless... 97 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 98 | 99 | The old approach for the heartbeat Emperor subsystem was asking for "gentle" reload to bad vassals. 100 | 101 | Now vassals not sending heartbeat (after being registered with the heartbeat subsystem) are killed with -9 102 | 103 | The result of this patch will be more robust bad vassals management 104 | 105 | logpipe 106 | ^^^^^^^ 107 | 108 | Author: INADA Naoki 109 | 110 | You can now send loglines to the stdin of an external command: 111 | 112 | .. code-block:: ini 113 | 114 | req-logger = pipe:/usr/local/bin/mylogger 115 | 116 | added "fd" logger to "logfile" plugin 117 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 118 | 119 | you can directly send logs to a file descriptors: 120 | 121 | .. code-block:: ini 122 | 123 | req-logger = fd:17 124 | 125 | 126 | Availability 127 | ************ 128 | 129 | uWSGI 1.9.17 has been released on Semptember 22th 2013 130 | 131 | You can download it from: 132 | 133 | https://projects.unbit.it/downloads/uwsgi-1.9.17.tar.gz 134 | -------------------------------------------------------------------------------- /Changelog-1.9.2.rst: -------------------------------------------------------------------------------- 1 | uWSGI 1.9.2 2 | =========== 3 | 4 | Changelog 20130326 5 | 6 | Bugfixes 7 | ******** 8 | 9 | Fixed python3 response headers managament (wrong refcnt) 10 | 11 | Fixed readline() on request body when postbuffering is in place 12 | 13 | Fixed ruby fiber plugin 14 | 15 | New features 16 | ************ 17 | 18 | route-run and the cachestore routing action 19 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 20 | 21 | You can now store responses automatically in the uWSGI cache: 22 | 23 | .. code-block:: ini 24 | 25 | [uwsgi] 26 | http-socket = :9090 27 | ; ensure the sweeper thread will run 28 | master = true 29 | cache2 = name=pippo2,items=10 30 | module = werkzeug.testapp:test_app 31 | route-run = cache:key=${REQUEST_URI},name=pippo2 32 | route-run = cachestore:key=${REQUEST_URI},expires=30,name=pippo2 33 | 34 | this example check every request for its availability in the cache 'pippo2'. If not available the request plugin (werkzeug test app) 35 | will run normally and its output will be stored in the cache (only if it returns a HTTP 200 status) 36 | 37 | ``--route-run`` is a new option allowing you to directly call routing action without checking for a specific condition (yes, it is an optimization) 38 | 39 | routing access to cookie and query string 40 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 41 | 42 | Check updated docs :doc:`InternalRouting` 43 | 44 | empty internal routing condition 45 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 46 | 47 | Check updated docs :doc:`InternalRouting` 48 | 49 | The Geoip plugin 50 | ^^^^^^^^^^^^^^^^ 51 | 52 | Check official docs :doc:`GeoIP` 53 | 54 | The SSI plugin (beta) 55 | ^^^^^^^^^^^^^^^^^^^^^ 56 | 57 | Check official docs :doc:`SSI` 58 | 59 | Availability 60 | ************ 61 | 62 | uWSGI 1.9.2 has been released on 20130326 and can be downloaded from: 63 | 64 | https://projects.unbit.it/downloads/uwsgi-1.9.2.tar.gz 65 | -------------------------------------------------------------------------------- /Changelog-1.9.4.rst: -------------------------------------------------------------------------------- 1 | uWSGI 1.9.4 2 | =========== 3 | 4 | Changelog 20130330 5 | 6 | Bugfixes 7 | ******** 8 | 9 | fixed cache statistics exported by the stats subsystem (Łukasz Mierzwa) 10 | 11 | fixed CoroEV bug in after_request (Tom Molesworth and John Berthels) 12 | 13 | update cache items after a restore from persistent storage (Łukasz Mierzwa) 14 | 15 | fixed signal handling in non-worker processes 16 | 17 | fixed thundering herd in multiple mules setup 18 | 19 | ported the cplusplus skeletal plugin to the new api 20 | 21 | fixed uWSGI reloading when build as a shared library 22 | 23 | New features 24 | ************ 25 | 26 | SmartOS official support 27 | ^^^^^^^^^^^^^^^^^^^^^^^^ 28 | 29 | From now on, SmartOS is included in the officially supported operating systems 30 | 31 | V8 initial support 32 | ^^^^^^^^^^^^^^^^^^ 33 | 34 | The Lua previous suggestion for writing uWSGI routing rules and configurations, woke up lot of javascript users stating that javascript 35 | itself could be a valid alternative. A V8 plugin is now available, supporting RPC, signal handlers and configurations. You need libv8 headers to build it: 36 | 37 | .. code-block:: sh 38 | 39 | python uwsgiconfig.py --plugin plugins/v8 40 | 41 | .. code-block:: js 42 | 43 | var config = {}; 44 | config['socket'] = [':3031', ':3032', ':3033']; 45 | config['master'] = true; 46 | config['processes'] = 3+1; 47 | config['module'] = 'werkzeug.testapp:test_app'; 48 | 49 | config; 50 | 51 | .. code-block:: sh 52 | 53 | uwsgi --plugin v8 --config foo.js 54 | 55 | The previous example will allows you to write dynamic configs in javascript, while you can export javascript functions via the RPC subsystem: 56 | 57 | .. code-block:: js 58 | 59 | function part1(request_uri, remote_addr) { 60 | return '

i am part1 for ' + request_uri + ' ' + remote_addr + "

" ; 61 | } 62 | 63 | function part2(request_uri, remote_addr) { 64 | return '

i am part2 for ' + request_uri + ' ' + remote_addr + "

" ; 65 | } 66 | 67 | function part3(request_uri, remote_addr) { 68 | return '

i am part3 for ' + request_uri + ' ' + remote_addr + "

" ; 69 | } 70 | 71 | uwsgi_register_rpc('part1', part1); 72 | uwsgi_register_rpc('part2', part2); 73 | uwsgi_register_rpc('part3', part3); 74 | 75 | .. code-block:: ini 76 | 77 | [uwsgi] 78 | plugin = v8 79 | v8-load = func.js 80 | cache2 = name=foobar,items=10 81 | 82 | http-socket = :9090 83 | 84 | route-run = addheader:Content-Type: text/html 85 | route-run = cache:key=pippo,name=foobar 86 | route-run = cachestore:key=pippo,name=foobar 87 | route-run = rpcnext:part1 ${REQUEST_URI} ${REMOTE_ADDR} 88 | route-run = rpcnext:part2 ${REQUEST_URI} ${REMOTE_ADDR} 89 | route-run = rpcnext:part3 ${REQUEST_URI} ${REMOTE_ADDR} 90 | route-run = break: 91 | 92 | The previous example generates an HTTP response from 3 javascript functions and store it in the uWSGI cache. 93 | 94 | Curious about rpcnext ? 95 | 96 | The rpcnext routing action 97 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 98 | 99 | We can already call rpc functions from the routing subsystem to generate response. With the rpcnext action (aliased as rpcblob too) 100 | you can call multiple rpc functions and assemble the return values in a single response. 101 | 102 | Legion improvements 103 | ^^^^^^^^^^^^^^^^^^^ 104 | 105 | We are hardly working in stabilizing :doc:`Legion` The objective is have a rock-solid clustering implementation for uWSGI 2.0 106 | that you can use even from your applications. 107 | 108 | The code in 1.9.4 has been refactored a bit by Łukasz Mierzwa to allow easier integration with external plugins. 109 | 110 | A new "join" hook has been added, it is called as soon as a node becomes active part of a legion (read, it is part of a quorum). 111 | 112 | Availability 113 | ************ 114 | 115 | uWSGI 1.9.4 will be available since 20130330 at this url 116 | 117 | https://projects.unbit.it/downloads/uwsgi-1.9.4.tar.gz 118 | -------------------------------------------------------------------------------- /Changelog-1.9.5.rst: -------------------------------------------------------------------------------- 1 | uWSGI 1.9.5 2 | =========== 3 | 4 | Changelog 20130404 5 | 6 | Bugfixes 7 | ******** 8 | 9 | * fixed a memory leak with cachestore routing instruction (Riccardo Magliocchetti) 10 | * fixed a memory leak in carbon plugin (Riccardo Magliocchetti) 11 | * fixed a memory leak in the cgi plugin (Riccardo Magliocchetti) 12 | * fixed old-style python dynamic apps 13 | * force the emperor to honour --max-fd for vassals 14 | * improved PSGI seek with post-buffering 15 | * fixed kvlist escaping 16 | 17 | 18 | New features 19 | ************ 20 | 21 | The GridFS plugin 22 | ^^^^^^^^^^^^^^^^^ 23 | 24 | A plugin exporting GridFS features is available, check official docs: :doc:`GridFS` 25 | 26 | V8 improvements 27 | ^^^^^^^^^^^^^^^ 28 | 29 | The V8 plugin continues to improve. Preliminary JSGI 3.0 support is available as well as multithreading. 30 | 31 | The 'require' commonjs standard has been implemented. 32 | 33 | Writing commonjs specs will be a very long work, so maybe a partnership with projects like teajs (the old v8cgi) would be a better 34 | path to follow. 35 | 36 | In the mean time, we are working on docs: :doc:`V8` 37 | 38 | The 'cgi' routing instruction 39 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 40 | 41 | You can now call CGI script directly from the :doc:`InternalRouting` 42 | 43 | .. code-block:: ini 44 | 45 | [uwsgi] 46 | plugin = cgi 47 | route = ^/cgi-bin/(.+) cgi:/usr/lib/cgi-bin/$1 48 | 49 | 50 | Availability 51 | ************ 52 | 53 | uWSGI 1.9.5 will be available since 20130404 at this url 54 | 55 | https://projects.unbit.it/downloads/uwsgi-1.9.5.tar.gz 56 | -------------------------------------------------------------------------------- /Changelog-1.9.8.rst: -------------------------------------------------------------------------------- 1 | uWSGI 1.9.8 2 | =========== 3 | 4 | Changelog [20130423] 5 | 6 | Note: this is an "emergency" release fixing 2 regressions causing a crash during reloads and when using async+uGreen 7 | 8 | Bugfixes 9 | ******** 10 | 11 | - fixed a crash when reloading the master 12 | - fixed a crash in async mode + uGreen 13 | - the 'mime' routing var requires a request var (not a raw string) 14 | 15 | Availability 16 | ************ 17 | 18 | You can download uWSGi 1.9.8 from https://projects.unbit.it/downloads/uwsgi-1.9.8.tar.gz 19 | -------------------------------------------------------------------------------- /Changelog-2.0.10.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.10 2 | ============ 3 | 4 | [20150317] 5 | 6 | Bugfixes 7 | -------- 8 | 9 | * Don't lower security standards with gcc 4.9 (Riccardo Magliocchetti) 10 | * Perl/PSGI make sure that at least two params are passed to xs_input_seek (Ivan Kruglov) 11 | * Per/PSGI fixed multiple interpreters usage 12 | * spooler: fixed scandir usage 13 | * fixed exception handler arguments management 14 | * fixed 'log-master' + 'daemonize2' disables all logging 15 | * fixed http Range header management 16 | 17 | 18 | New Features 19 | ------------ 20 | 21 | safeexec hook 22 | ************** 23 | 24 | this is like 'exec' but do not exit on error even if the executed command returns a non-zero value 25 | 26 | backported --emperor-wrapper-fallback and --emperor-wrapper-override 27 | ******************************************************************** 28 | 29 | the --emperor-wrapper-fallback option allows you to specify an alternative binary to execute 30 | when running a vassal and the default binary_path is not found (or returns an error). (you can specify it multiple times) 31 | 32 | The --emperor-wrapper-override is similar but 'overrides' the default wrapper (you can specify it multiple times) 33 | 34 | added support for UNIX sockets to rsyslog 35 | ***************************************** 36 | 37 | The rsyslog logger can now get a unix socket as address (arguments starting with a slash are recognized as a unix path) 38 | 39 | forcecl transformation 40 | ********************** 41 | 42 | this transformation works like 'fixcl' but generates the Content-Length header even if Content-Length has been listed for removal. 43 | 44 | 45 | Availability 46 | ------------ 47 | 48 | You can download uWSGI 2.0.10 from 49 | 50 | https://projects.unbit.it/downloads/uwsgi-2.0.10.tar.gz 51 | -------------------------------------------------------------------------------- /Changelog-2.0.11.1.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.11.1 2 | ============== 3 | 4 | [20150719] 5 | 6 | Bugfixes 7 | ******** 8 | 9 | * fixed HTTPS router resource deallocation and fiel descriptors leak 10 | * do not spit out ssl errors when errno is 0 11 | 12 | New Features 13 | ************ 14 | 15 | The unix_signal hook 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | You can now remap UNIX signals to specific functions symbols: 19 | 20 | .. code-block:: c 21 | 22 | #include 23 | 24 | void hello_world(int signum) { 25 | printf("Hello World\n"); 26 | } 27 | 28 | .. code-block:: sh 29 | 30 | gcc -o libhello.so -shared hello.c 31 | uwsgi --dlopen ./libhello.so --hook-master-start "unix_signal:1 hello_world" ... 32 | 33 | will run the function hello_world whenever signal 1 (SIGHUP) is raised 34 | 35 | Availability 36 | ************ 37 | 38 | You can download uWSGI 2.0.11.1 from 39 | 40 | https://projects.unbit.it/downloads/uwsgi-2.0.11.1.tar.gz 41 | -------------------------------------------------------------------------------- /Changelog-2.0.11.2.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.11.2 2 | ============== 3 | 4 | [20151007] 5 | 6 | Bugfixes 7 | ******** 8 | 9 | * OSX 10.11 supports TCP_FASTOPEN 10 | * fixed http-socket parser state after harakiri 11 | * fixed threaded request logger 12 | * fixed fastrouter subscriptions modifiers 13 | * fixed alarm backlog 14 | 15 | Availability 16 | ************ 17 | 18 | You can download uWSGI 2.0.11.2 from 19 | 20 | https://projects.unbit.it/downloads/uwsgi-2.0.11.2.tar.gz 21 | -------------------------------------------------------------------------------- /Changelog-2.0.11.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.11 2 | ============ 3 | 4 | [20150701] 5 | 6 | Bugfixes 7 | ******** 8 | 9 | - [pypy] fixed misuse of ffi.string 10 | - fixed detection for gcc 5 (jimfunk) 11 | - fixed shared sockets for gateways 12 | - [psgi] Changed abs to labs because offset is declared as a long (Peter H. Ezetta) 13 | - add null terminator to uwsgi_get_dot_h() and uwsgi_config_py() (Jay Oster) 14 | - fixed thread waiting during stop/restart (Kaiwen Xu) 15 | - fixed chain reloading verbosity 16 | - [python] fixed spooler job reference counting (Curtis Maloney) 17 | - various static analysis improvements (Riccardo Magliocchetti) 18 | - fixed sharedarea support for very big ranges 19 | - fixed gzip transformation for zero-sized responses (Curtis Maloney) 20 | - fixed management of https client certificate authentication (Vladimir Didenko) 21 | - fixed OpenBSD build 22 | - fixed TMPFILE permissions 23 | 24 | 25 | New Features 26 | ************ 27 | 28 | The mem_collector thread 29 | ^^^^^^^^^^^^^^^^^^^^^^^^ 30 | 31 | Evil memory monitors (like --evil-reload-on-rss) are now asynchronously managed by a dedicated thread. 32 | 33 | This solves the issue of runaway processes not catched by the master. 34 | 35 | fixpathinfo routing action 36 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 37 | 38 | This is another step in removing the need of the infamous uwsgi_modifier1 30 relic. 39 | 40 | This routing action assumes the PATH_INFO cgi var has the SCRIPT_NAME part included. 41 | 42 | This action allows you to set SCRIPT_NAME in nginx without bothering to rewrite the PATH_INFO (something nginx cannot afford) 43 | 44 | .. code-block:: ini 45 | 46 | [uwsgi] 47 | ; blindly assumes PATH_INFO is clobbered with SCRIPT_NAME 48 | route-run = fixpathinfo: 49 | 50 | uwsgi[sor] and time[micros] routing vars 51 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 52 | 53 | This two new vars exposes the start of the current request (in micros) and the current time (again in micros) 54 | 55 | .. code-block:: ini 56 | 57 | [uwsgi] 58 | route-run = log:request started at ${uwsgi[sor]} 59 | route-run = log:current micros time is ${time[micros]} 60 | 61 | wait-for-socket 62 | ^^^^^^^^^^^^^^^ 63 | 64 | This works like wait-for-fs/iface/file/dir 65 | 66 | The spawn of the instance is suspended until the specified tcp/unix socket is ready. 67 | 68 | You can use it to synchronize vassals spawn (like stopping a vassal until a postgresql server has been spawned) 69 | 70 | wait_for hooks 71 | ^^^^^^^^^^^^^^ 72 | 73 | All of the wait-for-* functions can now be used as a hook: 74 | 75 | .. code-block:: ini 76 | 77 | [uwsgi] 78 | ; wait for postgres soon after privileges drop 79 | hook-as-user = wait_for_socket:127.0.0.1:5432 80 | 81 | Availability 82 | ************ 83 | 84 | You can download uWSGI 2.0.11 from 85 | 86 | https://projects.unbit.it/downloads/uwsgi-2.0.11.tar.gz 87 | -------------------------------------------------------------------------------- /Changelog-2.0.12.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.12 2 | ============ 3 | 4 | [20151230] 5 | 6 | Bugfixes 7 | -------- 8 | 9 | - 'rpcvar' routing action correctly returns NEXT on empty response 10 | - uwsgiconfig: fix handling of empty keys in python3 (Simone Basso) 11 | - plugins/alarm_speech: fix AppKit spelling to support case-sensitive filesystems (Andrew Janke) 12 | - Fix inheriting INET address 0.0.0.0 (INADA Naoki) 13 | - core/xmlconf: correctly initialize libxml2 (Riccardo Magliocchetti) 14 | - Pass LIBDIR to linker in python plugin (Borys Pierov) 15 | - Platforms-related build fixes for pty, forkptyrouter and mono plugins (Jonas Smedegaard and Riccardo Magliocchetti) 16 | 17 | New Features and Backports 18 | -------------------------- 19 | 20 | The custom worker api 21 | ********************* 22 | 23 | Finally you are able to override the uWSGI processing model to completely get control of it. This is very similar to what 24 | you can do in projects like gunicorn (and its integration with tornado or gevent). Obviously native plugins are still the best approach (they allow integration with uWSGI api and states), but in some case you may want to use uWSGI process management facilities and let your app do the rest of the work. 25 | 26 | Currently only the python plugin supports "overriding" of workers, an aiohttp (asyncio) example module is available: 27 | 28 | https://github.com/unbit/uwsgi-docs/blob/master/WorkerOverride.rst 29 | 30 | 31 | --wsgi-disable-file-wrapper 32 | *************************** 33 | 34 | This option disables the wsgi.file_wrapper optimization of the WSGI standard. In some corner case this is the only trick to avoid errors. 35 | 36 | Official PHP 7 support 37 | ********************** 38 | 39 | PHP 7 is now officially supported in the php plugin. 40 | 41 | 42 | uwsgi.spooler_get_task api (Credits: Alexandre Bonnetain) 43 | ********************************************************* 44 | 45 | This patch allows you to easily parse spooler files. 46 | 47 | Check the example/test here: 48 | 49 | https://github.com/unbit/uwsgi/blob/master/t/spooler/read.py 50 | 51 | --if-hostname-match (Credits: Alexandre Bonnetain) 52 | ************************************************** 53 | 54 | This options for config logic allows you to define options only when a regexp over the hostname matches: 55 | 56 | .. code-block:: ini 57 | 58 | [uwsgi] 59 | if-hostname-match = ^prod 60 | threads = 20 61 | endif = 62 | 63 | 64 | 65 | Availability 66 | ------------ 67 | 68 | You can download uWSGI 2.0.12 from https://projects.unbit.it/downloads/uwsgi-2.0.12.tar.gz 69 | -------------------------------------------------------------------------------- /Changelog-2.0.13.1.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.13.1 2 | ============== 3 | 4 | [20160513] 5 | 6 | Bugfix quick-release 7 | 8 | Changes 9 | ------- 10 | 11 | - Fixed support for python 2.5 and python 2.6 12 | - Fixed support for older glibc 13 | - reverted EPOLLEXCLUSIVE patch, requires more investigation 14 | 15 | 16 | Availability 17 | ------------ 18 | 19 | You can download uWSGI 2.0.13.1 from https://projects.unbit.it/downloads/uwsgi-2.0.13.1.tar.gz 20 | -------------------------------------------------------------------------------- /Changelog-2.0.13.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.13 2 | ============ 3 | 4 | [20160510] 5 | 6 | Changes 7 | ------- 8 | 9 | - Fix compilation with GCC 6 10 | - Remote rpc fixes (Darvame) 11 | - Musl support! (Natanael Copa, Matt Dainty, Riccardo Magliocchetti) 12 | - Create the spooler directory if it does not exist (Alexandre Bonnetain) 13 | - Fix compilation on big endian linux (Riccardo Magliocchetti) 14 | - A ton of cache fixes (Darvame) 15 | - Make it easier to compile plugins on a different directory (Jakub Jirutka) 16 | - Add wheel package machinery (Matt Robenolt) 17 | - Use EPOLLEXCLUSIVE for reading, helps with the thundering herd problem (on linux 4.5+) (INADA Naoki) 18 | - Fix apache 2.4 integration with unix sockets (Alexandre Rossi) 19 | - Add HTTP/2 support to apache 2 proxy (Michael Fladischer, OGAWA Hirofumi) 20 | - Fix apache mod proxy compilation with apache 2.4.20 (Mathieu Arnold) 21 | - Default to clang as default compiler on MacOS X (Riccardo Magliocchetti) 22 | - Added --cgi-close-stdin-on-eof (Roberto De Ioris) 23 | 24 | 25 | Availability 26 | ------------ 27 | 28 | You can download uWSGI 2.0.13 from https://projects.unbit.it/downloads/uwsgi-2.0.13.tar.gz 29 | -------------------------------------------------------------------------------- /Changelog-2.0.14.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.14 2 | ============ 3 | 4 | [20161003] 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - backported gevent-early-monkey-patch (jianbin-wei) 12 | - Fixed OpenBSD version check (Pavel Korovin) 13 | - PSGI/Perl cache api fixes (Alexander Demenshin) 14 | - Correctly decode PATH_INFo in router_rewrite plugin (Ben Hearsum) 15 | - add uwsgi.accepting() for chain-reload + worker-override combo (enkore) 16 | - fixed workers killing when in cheaper modes (Shoham Peller) 17 | - added --cgi-safe option (nnnn20430) 18 | - Implemented graceful reload for COROAE plugin (aleksey-mashanov) 19 | - Added --php-fallback2, --php-fallback-qs (Felicity unixwitch) 20 | - Added ipv4in and ipv6in routing rules (Felicity unixwitch) 21 | - Fixed readline support in python3 when working interactively (Anthony Sottile) 22 | - Implement touch-reloading for mules and spoolers (Alexandre Bonnetain) 23 | - add request_start timestamp in stats (Ben Plotnick) 24 | - Fixed double free in uwsgi_routing_func_rewrite (William Orr) 25 | - Various mod_proxy_uwsgi fixes (Ya-Lin Huang) 26 | - support for 'no-answer' in PSGI (Anton Petrusevich) 27 | - added php-constant option (Дамјан Георгиевски [gdamjan]) 28 | - added the stdio logger (Дамјан Георгиевски [gdamjan]) 29 | - spooler: fix reading inconsistent data (Pavel Patrin) 30 | - Removed -WError from the build procedure (Riccardo Magliocchetti, suggested by Ian Denhardt) 31 | - The usual amount of coverity-based fixes (Riccardo Magliocchetti) 32 | 33 | Availability 34 | ------------ 35 | 36 | You can download uWSGI 2.0.14 from https://projects.unbit.it/downloads/uwsgi-2.0.14.tar.gz 37 | -------------------------------------------------------------------------------- /Changelog-2.0.15.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.15 2 | ============ 3 | 4 | [20170330] 5 | 6 | Maintenance release 7 | 8 | Issues 9 | ------ 10 | 11 | Unfortunately there are still 2 unfixed long standing bugs in this release: 12 | 13 | - suwsgi protocol behind nginx does not work reliably when a request body is sent by the client (https://github.com/unbit/uwsgi/issues/1490). As we cannot reproduce it in uWSGI itself, we will start checking in the nginx module too 14 | - There are reports of the "holy" wsgi env allocator crashing on specific conditions, this release includes a bunch of workarounds but they could not be enough 15 | 16 | Changes 17 | ------- 18 | 19 | - workaround for the holy allocator for avoiding crashes with newrelic (see Issues notes) 20 | - avoid time overflow in request logs during (even minimal) clock skew 21 | - fixed python logger with python3 22 | - fixed catch-exceptions with python3 23 | - backported "don't clone $env->{'psgix.io'} on 'PSGI cancel'" 24 | - added support for authentication in the redis logger 25 | - added the spinningfifo action hook to the core 26 | - fixed compilation with php 7.1 (Дамјан Георгиевски) 27 | - correctly returns error code 22 in lazy_apps + master_mode 28 | - fixed compilation for OpenSSL 1.1 (Riccardo Magliocchetti) 29 | - Add a --skip-atexit-teardown option to skip perl/python teardown (Ævar Arnfjörð Bjarmason) 30 | - fixed static file serving over https-socket 31 | 32 | Availability 33 | ------------ 34 | 35 | You can download uWSGI 2.0.15 from https://projects.unbit.it/downloads/uwsgi-2.0.15.tar.gz 36 | -------------------------------------------------------------------------------- /Changelog-2.0.16.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.16 2 | ============ 3 | 4 | [20180210] 5 | 6 | Maintenance release 7 | 8 | Security 9 | ------ 10 | 11 | - [CVE-2018-6758] Stack-based buffer overflow in core/utils.c:uwsgi_expand_path() 12 | 13 | Changes 14 | ------- 15 | 16 | - Backported early_post_jail plugin hook (Bjørnar Ness) 17 | - Fixed ipv6 suupport for http-socket (James Brown) 18 | - Enable execinfo on DragonFly BSD (Aaron LI) 19 | - Fix inet_ntop buffer size (Orivej Desh) 20 | - Add worker running time metrics (Serge/yasek) 21 | - Backported safe-pidfile, safe-pidfile2 (Nate Coraor) 22 | - Stop using libxml2 by default on osx 23 | - Fixed uwsgi_kvlist_parse signature 24 | - Backport http range fixes from master (Curtis Maloney, Sokolov Yura) 25 | - relicensed mod_proxy_uwsgi to Apache 2.0 26 | - logging: Add ${millis} support to json encode 27 | - plugins/router_xmldir: fixup invalid locale check (Riccardo Magliocchetti) 28 | - Add ssl-verify-depth flag to set the max Client CA chain length (Paul Tagliamonte) 29 | - Allow to override build date (Bernhard M. Wiedemann) 30 | - Python 3 plugin: improved thread names handling (Jyrki Muukkonen, Mark Meyer) 31 | - Added uwsgi_resolve_ip for redis host (ahmbas) 32 | - plugins/gevent: Fix signal handlers (Maslov Alexander) 33 | - Write x509 DER to the uwsgi buffer (Paul Tagliamonte) 34 | - plugin/http: Fix compilation (Melvyn Sopacua) 35 | - Fixed emperor throttling system (Jeremy Hiatt) 36 | - Fix application loading without Plack after excluding "." from @INC in new Perl versions (Anton Petrusevich) 37 | - Fix MULE MSG QUEUE IS FULL message hint (Eugene Tataurov) 38 | - Build System: support k_minor has a _xxx suffix (TOGO Li) 39 | - Fixed drop-after-* options (Robert DeRose) 40 | - Add mule_send_msg success indicator (Josh Tiras) 41 | - Properly check item size in uwsgi_queue_push (Josh Tiras) 42 | - FastRouter / HTTP Router can now have a 'fallback' key configured 43 | - HTTP Router now supports `post-buffer`, just like FastRouter 44 | - Fix handling of `env` in embedded dict in Python plugin (could cause segfaults in single thread mode) 45 | - Add support for Brotli (.br) with `--static-gzip` 46 | - Back-ported HTTP/1.1 support (--http11-socket) from 2.1 47 | 48 | Availability 49 | ------------ 50 | 51 | You can download uWSGI 2.0.16 from https://projects.unbit.it/downloads/uwsgi-2.0.16.tar.gz 52 | -------------------------------------------------------------------------------- /Changelog-2.0.17.1.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.17.1 2 | ============= 3 | 4 | [20180708] 5 | 6 | Maintenance release 7 | 8 | 9 | Changes 10 | ------- 11 | 12 | - Fixed memory leak in HTTPS_CLIENT_CERTIFICATE 13 | - TLSv1 is now disabled by default (you can re-enable it with ssl-enable-tlsv1 at your own risk) 14 | - Improved daemons throttle system 15 | - Add "secs" log formatting variable (André Cruz) 16 | - Improved snprintf() usage to be OpenBSD-friendly (Henrik, http://50hz.ws/) 17 | - Improved glibc crypt/crypt_r management (Jakub Jelen, afazekas) 18 | - Fixed websocket pong timeout check (adrianbg) 19 | - Add the "License" classifier to setup.py (Jon Dufresne) 20 | - Add support for php user.ini (Jacco Koning) 21 | - Official support for Python 3.7 (luchr) 22 | 23 | Availability 24 | ------------ 25 | 26 | You can download uWSGI 2.0.17.1 from https://projects.unbit.it/downloads/uwsgi-2.0.17.1.tar.gz 27 | -------------------------------------------------------------------------------- /Changelog-2.0.17.rst: -------------------------------------------------------------------------------- 1 | 2 | uWSGI 2.0.17 3 | ============ 4 | 5 | [20180226] 6 | 7 | Maintenance release 8 | 9 | 10 | Changes 11 | ------- 12 | 13 | - The Emperor throttling subsystem does not make use anymore of blocking functions, like usleep(), this should fix stats serving and should improve vassals startup time 14 | - [Security/PHP] enforce DOCUMENT_ROOT check when using --php-docroot to avoid directory traversal (Marios Nicolaides) 15 | - added --shutdown-sockets to improve graceful shutdowns (Andrew Wason) 16 | 17 | Availability 18 | ------------ 19 | 20 | You can download uWSGI 2.0.17 from https://projects.unbit.it/downloads/uwsgi-2.0.17.tar.gz 21 | -------------------------------------------------------------------------------- /Changelog-2.0.18.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.18 2 | ============ 3 | 4 | [20190209] 5 | 6 | Maintenance release 7 | 8 | 9 | Changes 10 | ------- 11 | 12 | - Fixed support for Python 3.7 (Takumi Akiyama) 13 | - Allow to use autoport (socket :0) with custom socket backlog (Pavel Patrin) 14 | - pyuwsgi ported to python3 (thanks lincolnloop) 15 | - pyuwsgi packages fixes (Peter Baumgartner) 16 | - pyuwsginossl build configuration for building pyuwsgi without ssl support (Peter Baumgartner) 17 | - Fix unix socket inheritance after reload on FreeBSD (Anton Yuzhaninov) 18 | - Fix crashes with --wsgi-env-behavior=holy (#1950) 19 | - Fix invalid free in python plugin (Riccardo Magliocchetti, #1942) 20 | - Fix compilation warnings with gcc-8 (Riccardo Magliocchetti, Ruslan Bilovol #1819) 21 | - Fix spooler python references (Brett Rosen) 22 | - Don't generate build warnings in systemd_logger (Chris Mayo) 23 | - Fix segmentation fault during worker shutdown (Allan Feldman, #1651) 24 | 25 | 26 | Availability 27 | ------------ 28 | 29 | You can download uWSGI 2.0.18 from https://projects.unbit.it/downloads/uwsgi-2.0.18.tar.gz 30 | -------------------------------------------------------------------------------- /Changelog-2.0.19.1.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.19.1 2 | ============== 3 | 4 | Released 20200617 5 | 6 | Bugfix release 7 | 8 | 9 | Changes 10 | ------- 11 | 12 | - Reverted CGI chunked encoding support (7dfe93d961cb83d16b02f18d450a63f3f019a27d), requires better backporting 13 | - Fixed bug with WSGI responses returning None (#2185, reported by Nico Berlee) 14 | 15 | 16 | Availability 17 | ------------ 18 | 19 | You can download uWSGI 2.0.19.1 from https://projects.unbit.it/downloads/uwsgi-2.0.19.1.tar.gz 20 | -------------------------------------------------------------------------------- /Changelog-2.0.19.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.19 2 | ============ 3 | 4 | Released 20200614 5 | 6 | Maintenance release 7 | 8 | 9 | Changes 10 | ------- 11 | 12 | - Update travis to xenial (Terence D. Honles) 13 | - Fix segfault in logsocket plugin (Riccardo Magliocchetti, #2010) 14 | - Backport Coverity fixes from master (Riccardo Magliocchetti) 15 | - Fix Python 3.7 warnings (Orivej Desh) 16 | - Fix uwsgi.workers() leak in Python plugin (Arne Welzel, #2056) 17 | - Backport redislog plugin 32-bit build fixes (Riccardo Magliocchetti, #1828) 18 | - Fix stack overflow in core/rpc (Nicola Martino) 19 | - Fix build with spaces in the path (Arne Welzel, #1939) 20 | - Add missing initialization for zend_file_handle in php plugin (Arne Welzel) 21 | - Build Python 3.7 and 3.8 plugins in CI (Arne Welzel) 22 | - Add Trove classifiers for Python 3.7 and 3.8 (Hugo) 23 | - Graceful shutdown for vassals (Sponsored by guppyltd.com) 24 | - Improve yaml parsing with libyaml (Arne Welzel, #2097) 25 | - Add smart-daemon2 option to notify daemon of master reloading (Eduardo Felipe Castegnaro) 26 | - Do not chroot multiple times when root (Arne Welzel) 27 | - Support io.BytesIO with wsgi.file_wrapper (Arne Welzel, #1126) 28 | - Add websocket continuation frames support (Timi, #1350) 29 | - Fix compilation with gevent 1.5.0 (Vytautas Liuolia) 30 | - Fix PSGI plugin build with gcc 10 (Jorge Gallegos) 31 | - Get rid of paste.script dependency in pypy/python plugins (Thomas De Schampheleire) 32 | - Improve performance for santitizing file descriptors with cgi plugin (Natanael Copa, #2053) 33 | - Fix offload-threads with honour-range (Liss Tarnell) 34 | - Fix logging packet size length overflow (Pawel Marokwsi) 35 | - Fix possible deadlock in install (Jacob Tolar) 36 | - Fix parsing of http port for ipv6 (Cyril Baÿ) 37 | - Fix impossibility of determining the end of the chunked stream with psgi plugin (ols) 38 | - Fix parsing of http-socket port for ipv6 (Daniel Holth) 39 | - Add chunked request decoding to the CGI plugin (Robert Schindler) 40 | - Add add max-worker-lifetime-delta to reload workers with a delta (Marcin Lulek , #2020) 41 | 42 | 43 | Availability 44 | ------------ 45 | 46 | You can download uWSGI 2.0.19 from https://projects.unbit.it/downloads/uwsgi-2.0.19.tar.gz 47 | -------------------------------------------------------------------------------- /Changelog-2.0.2.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.2 2 | =========== 3 | 4 | 5 | Changelog 20140226 6 | 7 | 8 | Bugfixes 9 | -------- 10 | 11 | * fixed python3 support on older compilers/libc 12 | * allow starting in spooler-only mode 13 | * fixed cache bitmap support and added test suite (credits: Danila Shtan) 14 | * fixed ftime log var 15 | * added async remote signal management 16 | * fixed end-for and end-if 17 | * fixed loop in internal-routing response chain 18 | * fixed pypy execute_source usage 19 | * logpipe: Don't setsid() twice (credits: INADA Naoki) 20 | 21 | New features and improvements 22 | ----------------------------- 23 | 24 | CGI plugin 25 | ********** 26 | 27 | The plugin has been improved to support streaming. 28 | 29 | In addition to this the long-awaited async support is finally ready. Now you can have CGI concurrency 30 | without spawning a gazillion of expensive threads/processes 31 | 32 | Check: :doc:`CGI` 33 | 34 | PSGI loading improvements 35 | ************************* 36 | 37 | The PSGI loader now tries to use Plack::Util::load_psgi() function instead of simple eval. This addresses various inconsistences 38 | in the environment (like the double parsing/compilation/execution of psgi scripts). 39 | 40 | If the Plack module is not available, a simple do-based code is used (very similar to load_psgi) 41 | 42 | Many thanks to Ævar Arnfjörð Bjarmason of booking.com for having discovered the problem 43 | 44 | Availability 45 | ************ 46 | 47 | uWSGI 2.0.2 can be downloaded from: https://projects.unbit.it/downloads/uwsgi-2.0.2.tar.gz 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Changelog-2.0.20.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.20 2 | ============ 3 | 4 | Released 20211006 5 | 6 | Maintenance release 7 | 8 | Special Note: this is the last version with GPL2+linking_exception license. Following versions will be under MIT. 9 | 10 | 11 | Changes 12 | ------- 13 | 14 | - Switch default python for build to python3 (Riccardo Magliocchetti) 15 | - Add support for PHP 8 (Riccardo Magliocchetti) 16 | - Drop support for PHP < 7 as it is EOL since end of 2018 (Riccardo Magliocchetti) 17 | - Fix segfaults when using --wsgi-env-behavior=holy (Antonio Cuni) 18 | - Replace uwsgi.h system includes in core and proto dirs for Bazel (Serge Bazanski) 19 | - gevent: fix compilation with clang11 (László Károlyi) 20 | - Fix Python 3.9 deprecations warnings (Riccardo Magliocchetti) 21 | - Add trove classifier for Python 3.9 (Adrian) 22 | - Fix message in Log SIGINT/SIGTERM triggered kill_them_all (Delena Malan) 23 | - Support 7 in weekedays as an alias for sunday to match crontab behaviour (Riccardo Magliocchetti) 24 | - Document http-timeout default of 60 seconds (Etienne H) 25 | - Add option to override python sys.executable using py-executable config 26 | - Allow specifying an iteration to uwsgi::add_rb_timer (Luciano Rocha) 27 | - Allow to compile with Python versions with minor version with 2+ digits (Cyrille Pontvieux) 28 | - Take into account new naming for LIBPL since python 3.6 (ilrico) 29 | - Added missing HTTP status codes messages (James Brown) 30 | - Official support for Python 3.10 31 | 32 | Availability 33 | ------------ 34 | 35 | You can download uWSGI 2.0.20 from https://projects.unbit.it/downloads/uwsgi-2.0.20.tar.gz 36 | -------------------------------------------------------------------------------- /Changelog-2.0.21.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.21 2 | ============ 3 | 4 | Released 20221024 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - Add PY_SSIZE_T_CLEAN define for Python 3.10 support (Thea Flowers) 12 | - Fix PHP 8 missing arginfo warnings (Дамјан Георгиевски) 13 | - Do not collide with the builtin compile function in uwsgiconfig.py (Jonathan Rosser) 14 | - add uwsgi fork hooks to update internal interpreter state in python plugin (Tahir Butt) 15 | - Properly call `.close()` as mandated by WSGI specs in python plugin (Florian Apolloner) 16 | - Fix compilation with PHP 8.1 (Riccardo Magliocchetti) 17 | - Fix memory corruption for uwsgi_cache_* in php plugin (aszlig) 18 | - Cleanup usage of threading.current_thread (Hugo van Kemenade) 19 | - Fix concurrency issues on build (Peter Law) 20 | - Fix compilation on MacOS (Shachar Itzhaky) 21 | - Fix segfault from gevent switch (Gavin Jeong) 22 | - Fix php-app for PHP 8.1 (cuchac) 23 | - make dev version PEP-0440 compliant (joshua.biagio) 24 | - Add Python 3.11 support (Victor Stinner) 25 | - Ensure to link against rt when statically linking the python plugin to libpython (Denis Dowling) 26 | - Refactor CI to run tests in parallel (Nicola Martino) 27 | - Add missing parens in plugins/coroae/uwsgiconfig.py (Eleksir) 28 | 29 | Availability 30 | ------------ 31 | 32 | You can download uWSGI 2.0.21 from https://files.pythonhosted.org/packages/b3/8e/b4fb9f793745afd6afcc0d2443d5626132e5d3540de98f28a8b8f5c753f9/uwsgi-2.0.21.tar.gz 33 | -------------------------------------------------------------------------------- /Changelog-2.0.22.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.22 2 | ============ 3 | 4 | Released 20230727 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - Add graceful harakiri to give more slack to workers in order to do cleanup actions (Filipe Felisbino) 12 | The following options have been added: 13 | 14 | - `harakiri-graceful-timeout` to control the timeout for the worker to attempt a graceful shutdown 15 | - `harakiri-graceful-signal`, to choose which signal to use for graceful harakiri (default: SIGTERM) 16 | - `harakiri-queue-threshold` in order to trigger harakiri only when the listen queue crosses a threshold 17 | - plugins/php: Fix PHP 8.2 compilation (Alexandre Rossi) 18 | - plugins/python: Use "backslashreplace" on stderr initialization (Nicolas Evrard) 19 | - Fix typo (Young Ziyi) 20 | - Fix use after free with DEBUG (Alexandre Rossi) 21 | - apache2/mod_proxy_uwsgi: stricter backend HTTP response parsing/validation (Eric Covener, via Freexian) 22 | - ci: update to ubuntu 20.04 since 18.04 is unsupported (Riccardo Magliocchetti) 23 | - plugins/rack: fix compilation with Ruby 3.1, this breaks compilation for Ruby < 2.x (Lalufu, Riccardo Magliocchetti) 24 | 25 | 26 | Availability 27 | ------------ 28 | 29 | You can download uWSGI 2.0.22 from https://files.pythonhosted.org/packages/a7/4e/c4d5559b3504bb65175a759392b03cac04b8771e9a9b14811adf1151f02f/uwsgi-2.0.22.tar.gz 30 | -------------------------------------------------------------------------------- /Changelog-2.0.23.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.23 2 | ============ 3 | 4 | Released 20231101 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - Add support for Python 3.12 (Ralf Ertzinger) 12 | - plugins/php: ini_entries is read-only since PHP 8.3 (Remi Collet) 13 | - Silence glibc warnings against pthread robust mutex functions (Riccardo Magliocchetti) 14 | - Fixup jvm library path detection (Riccardo Magliocchetti) 15 | - Use sysconfig if distutils is not available (Steve Kowalik, Terence D. Honles, Riccardo Magliocchetti) 16 | 17 | 18 | Availability 19 | ------------ 20 | 21 | You can download uWSGI 2.0.23 from https://files.pythonhosted.org/packages/79/73/b5def500729e134d1cb8dfc334e27fa2e9cfd4e639c1f60c6532d40edaed/uwsgi-2.0.23.tar.gz 22 | -------------------------------------------------------------------------------- /Changelog-2.0.24.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.24 2 | ============ 3 | 4 | Released 20240208 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - properly init cache for purge_lru (Alexandre Rossi) 12 | - fix linking with php8 (Remi Collet) 13 | - remove unused variables to fix compilation (László Károlyi) 14 | - fix function parameter type to avoid overflow in harakiri (Shai Bentov) 15 | - fix socket queue stats for ipv6 (Riccardo Magliocchetti) 16 | - fixup -Wformat-signedness warnings (Riccardo Magliocchetti) 17 | - Avoid strncpy from null in pyloader (Ben Kallus) 18 | - add clang to compile test matrix in ci (Riccardo Magliocchetti) 19 | 20 | Availability 21 | ------------ 22 | 23 | You can download uWSGI 2.0.24 from https://files.pythonhosted.org/packages/1b/ed/136698c76722268569eac4e48ab90f3ced8b8035e414a8290cb935c40c16/uwsgi-2.0.24.tar.gz 24 | -------------------------------------------------------------------------------- /Changelog-2.0.25.1.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.25.1 2 | ============== 3 | 4 | Released 20240415 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - Fix build when pcre is not found and is optional (umut) 12 | 13 | Availability 14 | ------------ 15 | 16 | You can download uWSGI 2.0.25.1 from https://files.pythonhosted.org/packages/52/9a/ab43cf8fb4847a6fda585beb1374deba0583660fa05c882a498784b2fc77/uwsgi-2.0.25.1.tar.gz 17 | -------------------------------------------------------------------------------- /Changelog-2.0.25.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.25 2 | ============ 3 | 4 | Released 20240413 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - Update glusterfs io callback function signature for 6.0 (Ralf Ertzinger) 12 | - Fix default values in help for min-worker-lifetime & legion-skew-tolerance (Thomas Riccardi) 13 | - Fix build regression with gcc < 5 (Riccardo Magliocchetti) 14 | - Add support for building against prcre2. This changes the regexp internal data 15 | structures (Alexandre Rossi) 16 | - Allow the valgrind generator script to run with a different python version (Wynn Wilkes) 17 | - Fix a potential error with not releasing the gil in uwsgi_python_rpc (Wynn Wilkes) 18 | - Rework threading cancellation handling. This can fix issues with threading, missing 19 | atexit callbacks and whatnot. (Inada Naoki) 20 | 21 | Availability 22 | ------------ 23 | 24 | You can download uWSGI 2.0.25 from https://files.pythonhosted.org/packages/c5/d6/72d625b5664468df51c5a082668b3f127cc0b154f7bb22763ac71b081d6a/uwsgi-2.0.25.tar.gz 25 | -------------------------------------------------------------------------------- /Changelog-2.0.26.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.26 2 | ============ 3 | 4 | Released 20240601 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - apache2/mod_proxy_uwsgi: let httpd handle CL/TE for non-http handlers CVE-2024-24795 (Eric Covener) 12 | - remove race-condition over termination of uWSGI process when using need-app and lazy-apps (Hanan .T) 13 | - fix 32-bit compilation with GCC14 (Rosen Penev) 14 | - uwsgiconfig: get compiler version with -dumpfullversion (Riccardo Magliocchetti) 15 | - Fix uwsgi_regexp_match() with pcre2 (Alexandre Rossi) 16 | 17 | 18 | Availability 19 | ------------ 20 | 21 | You can download uWSGI 2.0.26 from https://files.pythonhosted.org/packages/3a/7a/4c910bdc9d32640ba89f8d1dc256872c2b5e64830759f7dc346815f5b3b1/uwsgi-2.0.26.tar.gz 22 | -------------------------------------------------------------------------------- /Changelog-2.0.27.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.27 2 | ============ 3 | 4 | Released 20240923 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - pyuwsgi: avoid interleaving pywsgi threadstate (Anthony Sottile) 12 | - Fix gracefully_kill_them_all with running requests (赵浩彬) 13 | - Fix --catch-exceptions causing a segfault in Python 3.5+ (John Garland) 14 | - plugins/php: Add support for uwsgi.disconnect() function (Joe) 15 | - plugins/python: use PyOS_*Fork stable API functions on 3.7+ (Riccardo Magliocchetti) 16 | - core/uwsgi: set enable threads by default (Riccardo Magliocchetti) 17 | - plugins/python: fix compilation with Python 3.13 (Riccardo Magliocchetti, Ralf Ertzinger) 18 | - use pipe in gracefully_kill() to stop worker loop (Inada Naoki) 19 | - port pypy plugin to python3 (Alexandre Rossi) 20 | - add some integrations tests (Alexandre Rossi) 21 | 22 | 23 | Availability 24 | ------------ 25 | 26 | You can download uWSGI 2.0.27 from https://files.pythonhosted.org/packages/e1/46/fb08706bc5d922584a5aaed1f73e7a17313310aa34615c74406112ea04a6/uwsgi-2.0.27.tar.gz 27 | -------------------------------------------------------------------------------- /Changelog-2.0.28.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.28 2 | ============ 3 | 4 | Released 20241026 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - Bit more friendly log messages (Janneke Janssen) 12 | - Fix reload-on-touch/change regression from 2.0.27 (Lalufu) 13 | - Add more integration tests (Alexandre Rossi) 14 | - Fix static library not found install error on conda (Yong-Siang Shih) 15 | 16 | Availability 17 | ------------ 18 | 19 | You can download uWSGI 2.0.28 from https://files.pythonhosted.org/packages/24/c2/d58480aadc9a1f420dd96fc43cf0dcd8cb5ededb95cab53743529c23b6cd/uwsgi-2.0.28.tar.gz 20 | -------------------------------------------------------------------------------- /Changelog-2.0.29.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.29 2 | ============ 3 | 4 | Released 20250411 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - Fix integration tests not running (Alexandre Rossi) 12 | - Backport pypy plugin fixes (Alexandre Rossi) 13 | - Add support for rack 3 (Alexandre Rossi) 14 | - Fix compilation with gcc-15 (Alexandre Rossi) 15 | - Backport --max-request-delta from master (Jeremy Goulard) 16 | - Disable executable stack (Martin Liška) 17 | - Fix uwsgi_request_body_readline without new lines found (Juho Heikkinen) 18 | - Fix reload-os-env option (wszak) 19 | - Tidy python code (Curtis) 20 | - Python3 compat for examples and testing code (Thomas Goirand) 21 | 22 | Availability 23 | ------------ 24 | 25 | You can download uWSGI 2.0.29 from https://files.pythonhosted.org/packages/af/74/34f5411f1c1dc55cbcba3d817d1723b920484d2aeede4663bbaa5be7ee22/uwsgi-2.0.29.tar.gz 26 | -------------------------------------------------------------------------------- /Changelog-2.0.3.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.3 2 | =========== 3 | 4 | Changelog 20140317 5 | 6 | Bugfixes 7 | ******** 8 | 9 | * fixed spooler 'at' key usage 10 | * fixed a memory and fd leak with on-demand Emperor sokets 11 | * on __APPLE__ use LOG_NOTICE for syslog plugin 12 | * fixed mongrel2 support 13 | * hack for avoiding libmongoclient to crash on broken cursor 14 | * log alarm is now a uwsgi_log_verbose() wrapper 15 | * fixed tuntap router memory corruption 16 | * Set ECDHE curve independently from DHE parameters (Hynek Schlawack) 17 | * do not wait for a whole Emperor cycle before checking for each waitpid 18 | * fix a regression with caller() not indicating the starting *.psgi program (Ævar Arnfjörð Bjarmason) 19 | 20 | New features 21 | ************ 22 | 23 | Emperor SIGWINCH and SIGURG 24 | --------------------------- 25 | 26 | The Emperor now responds to two new signals: 27 | 28 | SIGWINCH: force an emperor rescan of vassals 29 | 30 | SIGURG: cleanup the Emperor states (for now it only clears its blacklist) 31 | 32 | Building plugins on-the-fly from git repositories 33 | ------------------------------------------------- 34 | 35 | You can now build plugins stored on git servers: 36 | 37 | .. code-block:: sh 38 | 39 | uwsgi --build-plugin https://github.com/unbit/uwsgi-bonjour 40 | 41 | or 42 | 43 | .. code-block:: sh 44 | 45 | UWSGI_EMBED_PLUGINS="bonjour=https://github.com/unbit/uwsgi-bonjour" pip install uwsgi 46 | 47 | uwsgi.add_var(key, value) 48 | ------------------------- 49 | 50 | You can now set request variables direcly from your app, for better integration with the internal routing subsystem 51 | 52 | .. code-block:: pl 53 | 54 | my $app = sub { 55 | uwsgi::add_var("newvar","newvalue"); 56 | return [200, ['Content-Type' => 'text/html'], ["Hello"]]; 57 | } 58 | 59 | .. code-block:: sh 60 | 61 | uwsgi --http-socket :9090 --psgi hello.pl --response-route-run "log:\${newvar}" 62 | 63 | add_var has been implemented in the CPython and Perl plugins 64 | 65 | 'disableheaders' routing action 66 | ------------------------------- 67 | 68 | This new action disables the sending of response headers, independently by the current request state 69 | 70 | Smarter Emperor on bad conditions 71 | --------------------------------- 72 | 73 | Now the Emperor completely destroys internal vassal-related structures when it is impossible to correctly kill a broken vassal 74 | (both for inconsistent Emperor state or for internal system problems) 75 | 76 | Availability 77 | ************ 78 | 79 | You can download uWSGI 2.0.3 from: https://projects.unbit.it/downloads/uwsgi-2.0.3.tar.gz 80 | -------------------------------------------------------------------------------- /Changelog-2.0.30.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.30 2 | ============ 3 | 4 | Released 20250603 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - Port to Python 3.14 beta 1 (Victor Stinner) 12 | - Fix atexit handler install with --lazy / --lazy-apps (Taegyun Kim) 13 | 14 | Availability 15 | ------------ 16 | 17 | You can download uWSGI 2.0.30 from https://files.pythonhosted.org/packages/6f/f0/d794e9c7359f488b158e88c9e718c5600efdb74a0daf77331e5ffb6c87c4/uwsgi-2.0.30.tar.gz 18 | -------------------------------------------------------------------------------- /Changelog-2.0.31.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.31 2 | ============ 3 | 4 | Released 20251011 5 | 6 | Maintenance release 7 | 8 | Changes 9 | ------- 10 | 11 | - Fix build with gcc-15 (Arne de Bruijn) 12 | - Build improvements (Janos Guljas, Jonas Smedegaard) 13 | - Fix some user visible typos (Alexandre Rossi) 14 | - Fix gracefully_kill_them_all() for setups using fifo-based master graceful reload (Wynn Wilkes) 15 | - Fix compilation with PHP 8.5 (Remi Collet) 16 | 17 | Availability 18 | ------------ 19 | 20 | You can download uWSGI 2.0.31 from https://files.pythonhosted.org/packages/9f/49/2f57640e889ba509fd1fae10cccec1b58972a07c2724486efba94c5ea448/uwsgi-2.0.31.tar.gz 21 | -------------------------------------------------------------------------------- /Changelog-2.0.4.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.4 2 | =========== 3 | 4 | Changelog [20140422] 5 | 6 | Bugfixes 7 | -------- 8 | 9 | - fixed "mime" routing var (Steve Stagg) 10 | - allow duplicate headers in http parsers 11 | - faster on_demand Emperor management 12 | - fixed UWSGI_ADDITIONAL_SOURCES build option 13 | - merge duplicated headers when SPDY is enabled (Łukasz Mierzwa) 14 | - fixed segfault for unnamed loggers 15 | - --need-app works in lazy-apps mode 16 | - fixed fatal hooks management 17 | 18 | 19 | New features 20 | ------------ 21 | 22 | The experimental asyncio loop engine (CPython >= 3.4) 23 | ***************************************************** 24 | 25 | asyncio (also known as 'tulip') is the new infrastructure for writing non-blocking/async/callback-based code with Python 3. 26 | 27 | This (experimental) plugin allows you to use asyncio as the uWSGI loop engine. 28 | 29 | Docs: https://uwsgi-docs.readthedocs.io/en/latest/asyncio.html 30 | 31 | httprouter advanced timeout management 32 | ************************************** 33 | 34 | The HTTP router learned 2 new specific timeouts: 35 | 36 | * `--http-headers-timeout `: defines the timeout while waiting for http headers 37 | * `--http-connect-timeout `: defines the timeout when connecting to backend instances 38 | 39 | These should help sysadmins to improve security and availability. 40 | 41 | Credits: Łukasz Mierzwa 42 | 43 | allow disabling cache warnings in --cache2 44 | ****************************************** 45 | 46 | Author: Łukasz Mierzwa 47 | 48 | The 'ignore_full' keyval option has been added to cache2. This will disable warnings when a cache is full. 49 | 50 | purge LRU cache feature by Yu Zhao (getcwd) 51 | ******************************************* 52 | 53 | This new mode allows you to configure a cache to automatically expire the least recently used (LRU) items to make space when it's running out. 54 | 55 | Just add `purge_lru=1` into your cache2 directive. 56 | 57 | support embedded config on FreeBSD 58 | ********************************** 59 | 60 | You can now embed configuration files into the binary also on FreeBSD systems: 61 | 62 | https://uwsgi-docs.readthedocs.io/en/latest/Embed.html#step-2-embedding-the-config-file 63 | 64 | RPC hook 65 | ******** 66 | 67 | Two new hooks have been added: 68 | 69 | * 'rpc' -> call the specified RPC function (fails on error) 70 | * 'rpcretry' -> call the specified RPC function (retries on error) 71 | 72 | `setmodifier1` and `setmodifier2` routing actions 73 | ************************************************* 74 | 75 | Having to load the 'uwsgi' routing plugin to simply set modifiers was really annoying. 76 | 77 | These two new routing options allow you to dynamically set request modifiers. 78 | 79 | `no_headers` option for static router 80 | ************************************* 81 | 82 | keyval based static routing actions can now avoid rewriting response headers (useful for X-Sendfile), just add no_headers=1 to your keyval options. 83 | 84 | Availability 85 | ------------ 86 | 87 | uWSGI 2.0.4 has been released on 20140422, you can download it from: 88 | 89 | https://projects.unbit.it/downloads/uwsgi-2.0.4.tar.gz 90 | 91 | 92 | -------------------------------------------------------------------------------- /Changelog-2.0.6.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.6 2 | =========== 3 | 4 | Changelog [20140701] 5 | 6 | 7 | Bugfixes 8 | ^^^^^^^^ 9 | 10 | * fixed a memory leak in the subscription system 11 | * fixed shortcut for ssl-socket 12 | * fixed Apache2 mod_proxy_uwsgi. It is now considered stable with all Apache MPM engines. 13 | * fixed SCRIPT_NAME and PATH_TRANSLATED generation in the PHP plugin (thanks Matthijs Kooijman) 14 | * remove the old FIFO socket from the event queue when recreating it (thanks Marko Tiikkaja) 15 | 16 | 17 | New features 18 | ^^^^^^^^^^^^ 19 | 20 | The new Rados plugins 21 | ********************* 22 | 23 | Credits: Marcin Deranek 24 | 25 | The Rados plugin has been improved and stabilized, and now it is considered stable and usable in production. 26 | 27 | Async modes and multithreading correctly work. 28 | 29 | Support for uploading objects (via PUT) and creating new pools (MKCOL) has been added. 30 | 31 | Expect WebDAV support in uWSGI 2.1. 32 | 33 | Docs have been updated: https://uwsgi-docs.readthedocs.io/en/latest/Rados.html 34 | 35 | --if-hostname 36 | ************* 37 | 38 | This is configuration logic for including options only when the system's hostname matches a given value. 39 | 40 | .. code-block:: ini 41 | 42 | [uwsgi] 43 | if-hostname = node1.local 44 | socket = /tmp/socket1.socket 45 | endif = 46 | 47 | if-hostname = node2.local 48 | socket = /var/run/foo.socket 49 | endif = 50 | 51 | Apache2 `mod_proxy_uwsgi` stabilization 52 | *************************************** 53 | 54 | After literally years of bug reports and corrupted data and other general badness, `mod_proxy_uwsgi` is finally stable. 55 | 56 | On modern Apache2 releases it supports UNIX sockets too. 57 | 58 | Updated docs: https://uwsgi-docs.readthedocs.io/en/latest/Apache.html#mod-proxy-uwsgi 59 | 60 | uwsgi[rsize] routing var 61 | ************************ 62 | 63 | The new `uwsgi[rsize]` routing variable (meaningful only in the 'final' chain) exposes the response size of the request. 64 | 65 | the `callint` scheme 66 | ******************** 67 | 68 | This scheme allows you to generate blobs from functions exposed by your uWSGI instance: 69 | 70 | .. code-block:: ini 71 | 72 | [uwsgi] 73 | uid = @(callint://get_my_uid) 74 | gid = @(callint://get_my_gid) 75 | 76 | --fastrouter-fallback-on-no-key 77 | ******************************* 78 | 79 | The corerouter's fallback procedure requires that a valid key (domain name) has been requested. 80 | 81 | This option forces the various routers to trigger the fallback procedure even if a key has not been found. 82 | 83 | PHP 5.5 opcode caching via --php-sapi-name 84 | ****************************************** 85 | 86 | For mysterious reasons the PHP 5.5+'s opcode caching is not enabled in the "embed" SAPI. This option allows you to fake the SAPI name -- `apache` is a good option -- to force the opcode caching engine to turn on. 87 | 88 | Improved chain-reloading 89 | ************************ 90 | 91 | Thanks to Marko Tiikkaja, the chain reloading procedure correctly works in cheaper modes and is more verbose. 92 | 93 | added 'chdir' keyval to --attach-daemon2 94 | **************************************** 95 | 96 | You can now set where attached daemons need to chdir(). 97 | 98 | Availability 99 | ^^^^^^^^^^^^ 100 | 101 | uWSGI 2.0.6 has been released on 20140701 102 | 103 | You can download it from 104 | 105 | https://projects.unbit.it/downloads/uwsgi-2.0.6.tar.gz 106 | -------------------------------------------------------------------------------- /Changelog-2.0.7.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.7 2 | =========== 3 | 4 | Changelog [20140905] 5 | 6 | Bugfixes 7 | ******** 8 | 9 | - fixed counters in Statsd plugin (Joshua C. Forest) 10 | - fixed caching in PHP plugin (Andrew Bevitt) 11 | - fixed management of system users starting with a number 12 | - fixed request body readline using `memmove` instead of `memcpy` (Andrew Wason) 13 | - ignore "user" namespace in `setns` (still a source of problems) 14 | - fixed Python3 RPC bytes/string mess (result: we support both) 15 | - do not destroy the Emperor on failed mount hooks 16 | - fixed symbol lookup error in the Mono plugin on OS X (Ventero) 17 | - fixed FastCGI and SCGI protocols error when out of buffer happens 18 | - fixed Solaris/SmartOS I/O management 19 | - fixed two memory leaks in the RPC subsystem (Riccardo Magliocchetti) 20 | - fixed the Rados plugin's PUT method (Martin Mlynář) 21 | - fixed multiple Python mountpoints with multiple threads in cow mode 22 | - stats UNIX socket is now deleted by `vacuum` 23 | - fixed off-by-one corruption in cache LRU mode 24 | - force single-CPU build in Cygwin (Guido Notari) 25 | 26 | New Features and improvements 27 | ***************************** 28 | 29 | Allow calling the spooler from every CPython context 30 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 31 | 32 | At Europython 2014, Ultrabug (an uWSGI contributor and packager) asked for the possibility to spool tasks directly from a greenlet. 33 | 34 | Done. 35 | 36 | store_delete cache2 option 37 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 38 | 39 | Author: goir 40 | 41 | The `store_delete` flag of the `--cache2` option allows you to force the cache engine to automatically remove invalid 42 | backing store files instead of steadfastly refusing to launch. 43 | 44 | file logger rotation 45 | ^^^^^^^^^^^^^^^^^^^^ 46 | 47 | Author: Riccardo Magliocchetti 48 | 49 | The `file` logger has been extended to allow the use of rotation (the same system used by the non-pluggable `--logto`). 50 | 51 | https://github.com/unbit/uwsgi/commit/0324e5965c360dccfb873ffe351dec88ddab59c5 52 | 53 | Vassal plugin hooks 54 | ^^^^^^^^^^^^^^^^^^^ 55 | 56 | The plugin hook API has been extended with two new hooks: `vassal` and `vassal_before_exec`. 57 | 58 | They allow customizing a vassal soon after its process has been created. 59 | 60 | The first third-party plugin using it is 'apparmor': https://github.com/unbit/uwsgi-apparmor 61 | 62 | This allows you to apply an Apparmor profile to a vassal. 63 | 64 | 65 | Broodlord improvements 66 | ^^^^^^^^^^^^^^^^^^^^^^ 67 | 68 | The Broodlord subsystem has been improved with a new option: `--vassal-sos` that automatically ask for reinforcement when all of the workers of an instance are busy. 69 | 70 | In addition to this a sysadmin can now manually ask for reinforcement sending the 'B' command to the master FIFO of an instance. 71 | 72 | Availability 73 | ************ 74 | 75 | uWSGI 2.0.7 has been released on 20140905, and you can download it from 76 | 77 | https://projects.unbit.it/downloads/uwsgi-2.0.7.tar.gz 78 | -------------------------------------------------------------------------------- /Changelog-2.0.8.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.8 2 | =========== 3 | 4 | Note: this is the first version with disabled-by-default SSL3, if you need it, you can re-enable with ``--ssl-enable3`` option 5 | 6 | Bugfixes 7 | -------- 8 | 9 | * fixed PHP `SCRIPT_NAME` usage when ``--php-app`` is in place 10 | * allow "appendn" hook without second argument 11 | * fix heap corruption in the Carbon plugin (credits: Nigel Heron) 12 | * fix `getifaddrs()` memory management 13 | * fixed `tcsetattr()` usage 14 | * fixed kevent usage of return value (credits: Adriano Di Luzio) 15 | * ensure PSGI response headers are in the right format 16 | * fixed reloading of attached daemons 17 | * fixed SSL/TLS shutdown 18 | * fixed mountpoint logic for paths not ending with / (credits: Adriano Di Luzio) 19 | * fixed Python3 support in spooler decorators (credits: Adriano Di Luzio) 20 | 21 | New Features 22 | ------------ 23 | 24 | RTSP and chunked input backports from 2.1 for the HTTP router 25 | ************************************************************* 26 | 27 | The ``--http-manage-rtsp`` and ``--http-chunked-input` have been backported from 2.1 allowing the HTTP router 28 | to detect RTSP and chunked requests automatically. This is useful for the upcoming https://github.com/unbit/uwsgi-realtime plugin. 29 | 30 | --hook-post-fork 31 | **************** 32 | 33 | This custom hook allows you to call actions after each `fork()`. 34 | 35 | fallback to trollius for asyncio plugin 36 | *************************************** 37 | 38 | If you build the asyncio plugin for python2, a fallback to the `trollius `_ module will be tried. 39 | 40 | This feature has gotten basically zero test coverage, so every report (bug or success alike) is welcome. 41 | 42 | added sweep_on_full, clear_on_full and no_expire to ``--cache2`` 43 | **************************************************************** 44 | 45 | Three new options for ``--cache2`` have been added for improving the caching expire strategies: 46 | 47 | * ``sweep_on_full`` will call a sweep (delete all of the expired items) as soon as the cache became full 48 | * ``clear_on_full`` will completely clear the cache as soon as it is full 49 | * ``no_expire`` forces the cache to not generate a cache sweeper thread, delegating items removal to the two previous options 50 | 51 | backported wait-for-fs/mountpoints from 2.1 52 | ******************************************* 53 | 54 | * ``--wait-for-fs `` suspend the uWSGI startup until a file/directory is available 55 | * ``--wait-for-file `` suspend the uWSGI startup until a file is available 56 | * ``--wait-for-dir `` suspend the uWSGI startup until a directory is available 57 | * ``--wait-for-mountpoint `` suspend the uWSGI startup until a mountpoint is available 58 | 59 | improved the offload api (backport from 2.1) 60 | ******************************************** 61 | 62 | uWSGI 2.0.8 is compatible with the upcoming https://github.com/unbit/uwsgi-realtime plugin that allows the use of realtime features 63 | (like websockets or audio/video streaming) using the uWSGI offload engine + Redis publish/subscribe. 64 | 65 | Allows building plugins from remote sources as embedded 66 | ******************************************************* 67 | 68 | The UWSGI_EMBED_PLUGINS environment variable has been extended to support remote plugins. As an example you can build a monolithic 69 | uwsgi binary with the Avahi and realtime plugins as: 70 | 71 | .. code-block:: sh 72 | 73 | UWSGI_EMBED_PLUGINS="avahi=https://github.com/20tab/uwsgi-avahi,realtime=https://github.com/unbit/uwsgi-realtime" make 74 | 75 | Automatically manage HTTP_X_FORWARDED_PROTO 76 | ******************************************* 77 | 78 | Albeit a new standard is available in the HTTP world for forwarded sessions (http://tools.ietf.org/html/rfc7239) this release 79 | adds support for the X-Forwarded-Proto header, automatically setting the request scheme accordingly. 80 | 81 | Availability 82 | ------------ 83 | 84 | uWSGI 2.0.8 has been released on 20141026. Download it from: 85 | 86 | https://projects.unbit.it/downloads/uwsgi-2.0.8.tar.gz 87 | -------------------------------------------------------------------------------- /Changelog-2.0.9.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0.9 2 | =========== 3 | 4 | [20141230] 5 | 6 | Bugfixes 7 | -------- 8 | 9 | * fixed mod_proxy_uwsgi for non-blocking mode (many thanks to Joe cuchac) 10 | * fixed master-fifo + cheaper 11 | * fixed leak on error in bind_to_unix (Riccardo Magliocchetti) 12 | * atexit hooks works in cheaped workers too 13 | * atexit hooks works in gevent mode too during shutdown 14 | * fixed carbon command line option value after reload 15 | * do not honour Emperor throttling on the first run 16 | * fixed Mono plugin 17 | * fixed peer name in corerouters 18 | * fixed stop signal for daemons 19 | * varios ssl/tls fixes in https/spdy router 20 | * fixed python3 --py-auto-reload-ignore 21 | * fixed modifiers in corerouters 22 | * support for yajl from homebrew (OSX) 23 | * psgi: Ensure that we call any DESTROY hooks on psgix.harakiri.commit (Ævar Arnfjörð Bjarmason) 24 | * systemdlogger: fix compilation with -Werror=format-security (Riccardo Magliocchetti) 25 | * fixed unmasked websockets 26 | * perl fixed latent refcounting bug (Mattia Barbon) 27 | 28 | New Features 29 | ------------ 30 | 31 | Improved PyPy support for Linux 32 | ******************************* 33 | 34 | The PyPy team have started building libpypy-c.so in their official releases. Now using pypy with uWSGI should be way easier: 35 | 36 | https://uwsgi-docs.readthedocs.io/en/latest/PyPy.html 37 | 38 | Fastrouter post-buffering 39 | ************************* 40 | 41 | The fastrouter got post-buffering: 42 | 43 | https://uwsgi-docs.readthedocs.io/en/latest/Fastrouter.html#post-buffering-mode-uwsgi-2-0-9 44 | 45 | Perl uwsgi::opt 46 | *************** 47 | 48 | The psgi/perl plugin exposes the uwsgi::opt hash, reporting the whole instance key-value configuration 49 | 50 | --pull-header 51 | ************* 52 | 53 | This is like --collect-header but the collected header is not returned to the client 54 | 55 | active-workers signal target 56 | **************************** 57 | 58 | This is like the 'workers' target, but forward the signal only to non-cheaper workers 59 | 60 | httpdumb routing action 61 | *********************** 62 | 63 | The http internal router exposes a new mode called 'httpdumb' that does not change headers before forwarding the request 64 | 65 | Availability 66 | ------------ 67 | 68 | uWSGI 2.0.9 has been released on 20141230. 69 | 70 | You can download it from: 71 | 72 | https://projects.unbit.it/downloads/uwsgi-2.0.9.tar.gz 73 | -------------------------------------------------------------------------------- /Changelog-2.0.rst: -------------------------------------------------------------------------------- 1 | uWSGI 2.0 2 | ========= 3 | 4 | Changelog [20131230] 5 | 6 | Important changes 7 | ***************** 8 | 9 | Dynamic options have been definitely removed as well as the broken_plugins directory 10 | 11 | Bugfixes and improvements 12 | ************************* 13 | 14 | - improved log rotation 15 | - do not rely on unix signals to print request status during harakiri 16 | - added magic vars for uid and gid 17 | - various Lua fixes 18 | - a tons of coverity-governed bugfixes made by Riccardo Magliocchetti 19 | 20 | New features 21 | ************ 22 | 23 | --attach-daemon2 24 | ^^^^^^^^^^^^^^^^ 25 | 26 | this is a keyval based option for configuring external daemons. 27 | 28 | Updated docs are: :doc:`AttachingDaemons` 29 | 30 | Linux setns() support 31 | ^^^^^^^^^^^^^^^^^^^^^ 32 | 33 | One of the biggest improvements in uWSGI 1.9-2.0 has been the total support for Linux namespaces. 34 | 35 | This last patch adds support for the setns() syscall. 36 | 37 | This syscall allows a process to "attach" to a running namespace. 38 | 39 | uWSGI instances can exposes their namespaces file descriptors (basically they are the files in /proc/self/ns) via a unix socket. 40 | 41 | External instances connects to that unix socket and automatically enters the mapped namespace. 42 | 43 | to spawn an instance in "namespace server mode", you use the ``--setns-socket `` option 44 | 45 | .. code-block:: sh 46 | 47 | uwsgi --setns-socket /var/run/ns.socket --unshare net,ipc,uts ... 48 | 49 | 50 | to attach you simply use ``--setns `` 51 | 52 | 53 | .. code-block:: sh 54 | 55 | uwsgi --setns /var/run/ns.socket ... 56 | 57 | Updated docs: :doc:`Namespaces` 58 | 59 | "private" hooks 60 | ^^^^^^^^^^^^^^^ 61 | 62 | When uWSGI runs your hooks, it verbosely print the whole hook action line. This could be a security problem 63 | in some scenario (for example when you run initial phases as root user but allows unprivileged access to logs). 64 | 65 | Prefixing your action with a '!' will suppress full logging: 66 | 67 | .. code-block:: ini 68 | 69 | [uwsgi] 70 | hook-asap = !exec:my_secret_command 71 | 72 | Support for yajl library (JSON parser) 73 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 74 | 75 | Til now uWSGI only supported jansson as the json parser required for managing .js config files. 76 | 77 | You can now use the yajl library (available in centos) as alternative JSON parser (will be automatically detected) 78 | 79 | Perl spooler support 80 | ^^^^^^^^^^^^^^^^^^^^ 81 | 82 | The perl/PSGI plugin can now be used as a spooler server: 83 | 84 | .. code-block:: pl 85 | 86 | uwsgi::spooler(sub { 87 | my $args = shift; 88 | print Dumper($args); 89 | return -2; 90 | }); 91 | 92 | 93 | The client part is still missing as we need to fix some internal api problem. 94 | 95 | Expect it in 2.0.1 ;) 96 | 97 | Gateways can drop privileges 98 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 99 | 100 | Gateways (like http router, sslrouter, rawrouter, forkptyrouter ...) can now drop privileges independently by the master. 101 | 102 | Currently only the http/https/spdy router exposes the new option (``--http-uid/--http-gid``) 103 | 104 | Subscriptions-governed SNI contexts 105 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 106 | 107 | The subscription subsystem now supports 3 additional keys (you can set them with the --subscribe2 option): 108 | 109 | ``sni_key`` 110 | 111 | ``sni_cert`` 112 | 113 | ``sni_ca`` 114 | 115 | all of the takes a path to the relevant ssl files. 116 | 117 | Check: :doc:`SNI` 118 | 119 | 120 | Availability 121 | ************ 122 | 123 | uWSGI 2.0 has been released on 20131230 and can be downloaded from: 124 | 125 | https://projects.unbit.it/downloads/uwsgi-2.0.tar.gz 126 | -------------------------------------------------------------------------------- /Cherokee.rst: -------------------------------------------------------------------------------- 1 | Cherokee support 2 | ================ 3 | 4 | .. note:: 5 | 6 | Recent official versions of Cherokee have an uWSGI configuration wizard. If 7 | you want to use it you have to install uWSGI in a directory included in your 8 | system ``PATH``. 9 | 10 | * Set the UWSGI handler for your target. 11 | * If you are using the default target (``/``) remember to uncheck the ``check_file`` property. 12 | * Configure an "information source" of type "Remote", specifying the socket name of uWSGI. If your uWSGI has TCP support, you can build a cluster by spawning the uWSGI server on a different machine. 13 | 14 | .. note:: 15 | 16 | Remember to add a target for all of your URI containing static files (ex. 17 | /media /images ...) using an appropriate handler 18 | 19 | Dynamic apps 20 | ------------ 21 | 22 | If you want to hot-add apps specify the ``UWSGI_SCRIPT`` var in the uWSGI handler options: 23 | 24 | * In the section: `Add new custom environment variable` specify ``UWSGI_SCRIPT`` as name and the name of your WSGI script (without the .py extension) as the value. 25 | 26 | Your app will be loaded automatically at the first request. 27 | -------------------------------------------------------------------------------- /Chunked.rst: -------------------------------------------------------------------------------- 1 | The Chunked input API 2 | ===================== 3 | 4 | An API for managing HTTP chunked input requests has been added in uWSGI 1.9.13. 5 | 6 | The API is very low-level to allow easy integration with standard apps. 7 | 8 | There are only two functions exposed: 9 | 10 | * ``chunked_read([timeout])`` 11 | 12 | * ``chunked_read_nb()`` 13 | 14 | This API is supported (from uWSGI 1.9.20) on CPython, PyPy and Perl. 15 | 16 | Reading chunks 17 | ************** 18 | 19 | To read a chunk (blocking) just run 20 | 21 | .. code-block:: perl 22 | 23 | my $msg = uwsgi::chunked_read 24 | 25 | If no timeout is specified, the default one will be used. If you do not get a chunk in time, the function will croak (or raise an exception when under Python). 26 | 27 | Under non-blocking/async engines you may want to use 28 | 29 | .. code-block:: perl 30 | 31 | my $msg = uwsgi::chunked_read_nb 32 | 33 | The function will soon return ``undef`` (or ``None`` on Python) if no chunks are available (and croak/raise an exception on error). 34 | 35 | A full PSGI streaming echo example: 36 | 37 | .. code-block:: perl 38 | 39 | # simple PSGI echo app reading chunked input 40 | sub streamer { 41 | $responder = shift; 42 | # generate the headers and start streaming the response 43 | my $writer = $responder->( [200, ['Content-Type' => 'text/plain']]); 44 | 45 | while(1) { 46 | my $msg = uwsgi::chunked_read; 47 | last unless $msg; 48 | $writer->write($msg); 49 | } 50 | 51 | $writer->close; 52 | } 53 | 54 | my $app = sub { 55 | return \&streamer; 56 | }; 57 | 58 | 59 | Tuning the chunks buffer 60 | ************************ 61 | 62 | Before starting to read chunks, uWSGI allocates a fixed buffer for storing chunks. 63 | 64 | All of the messages are always stored in the same buffer. If a message bigger than the buffer is received, an exception will be raised. 65 | 66 | By default the buffer is limited to 1 MB. You can tune it with the ``--chunked-input-limit`` option (bytes). 67 | 68 | 69 | Integration with proxies 70 | ************************ 71 | 72 | If you plan to put uWSGI behind a proxy/router be sure it supports chunked input requests (or generally raw HTTP requests). 73 | 74 | When using the uWSGI HTTP router just add ``--http-raw-body`` to support chunked input. 75 | 76 | HAProxy works out of the box. 77 | 78 | Nginx >= 1.4 supports chunked input. 79 | 80 | Options 81 | ******* 82 | 83 | * ``--chunked-input-limit``: the limit (in bytes) of a chunk message (default 1MB) 84 | * ``--chunked-input-timeout``: the default timeout (in seconds) for blocking chunked_read (default to the same --socket-timeout value, 4 seconds) 85 | 86 | Notes 87 | ***** 88 | 89 | * Calling chunked API functions after having consumed even a single byte of the request body is wrong (this includes ``--post-buffering``). 90 | * Chunked API functions can be called independently by the presence of "Transfer-Encoding: chunked" header. 91 | -------------------------------------------------------------------------------- /Circus.rst: -------------------------------------------------------------------------------- 1 | Running uWSGI instances with Circus 2 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 3 | 4 | Circus (https://circus.readthedocs.io/en/0.7/) is a process manager written in 5 | Python. It is very similar to projects like Supervisor, but with several 6 | additional features. Although most, if not all, of it's functionalities have a 7 | counterpart in uWSGI, Circus can be used as a library allowing you to build 8 | dynamic configurations (and extend uWSGI patterns). This aspect is very 9 | important and may be the real selling point of Circus. 10 | 11 | Socket activation 12 | ***************** 13 | 14 | Based on the venerable inetd pattern, Circus can bind to sockets and pass them to children. 15 | 16 | Start with a simple Circus config (call it circus.ini): 17 | 18 | .. code-block:: ini 19 | 20 | [circus] 21 | endpoint = tcp://127.0.0.1:5555 22 | pubsub_endpoint = tcp://127.0.0.1:5556 23 | stats_endpoint = tcp://127.0.0.1:5557 24 | 25 | [watcher:dummy] 26 | cmd = uwsgi --http-socket fd://$(circus.sockets.foo) --wsgi-file yourapp.wsgi 27 | use_sockets = True 28 | send_hup = True 29 | stop_signal = QUIT 30 | 31 | [socket:foo] 32 | host = 0.0.0.0 33 | port = 8888 34 | 35 | run it with 36 | 37 | .. code-block:: sh 38 | 39 | circusd circus.ini 40 | 41 | (Better) Socket activation 42 | ************************** 43 | 44 | If you want to spawn instances on demand, you will likely want to shut them 45 | down when they are no longer used. To accomplish that use the --idle uWSGI 46 | option. 47 | 48 | .. code-block:: ini 49 | 50 | [circus] 51 | check_delay = 5 52 | endpoint = tcp://127.0.0.1:5555 53 | pubsub_endpoint = tcp://127.0.0.1:5556 54 | stats_endpoint = tcp://127.0.0.1:5557 55 | 56 | [watcher:dummy] 57 | cmd = uwsgi --master --idle 60 --http-socket fd://$(circus.sockets.foo) --wsgi-file yourapp.wsgi 58 | use_sockets = True 59 | warmup_delay = 0 60 | send_hup = True 61 | stop_signal = QUIT 62 | 63 | [socket:foo] 64 | host = 0.0.0.0 65 | port = 8888 66 | 67 | This time we have enabled the master process. It will manage the --idle option, shutting down the instance if it is 68 | inactive for more than 60 seconds. -------------------------------------------------------------------------------- /Download.rst: -------------------------------------------------------------------------------- 1 | Getting uWSGI 2 | ============= 3 | 4 | These are the current versions of uWSGI. 5 | 6 | ======================== ========== =================================================== 7 | Release Date Link 8 | ======================== ========== =================================================== 9 | Unstable/Development \- https://github.com/unbit/uwsgi/ 10 | Stable 2025-10-11 `uwsgi-2.0.31.tar.gz `_ 11 | DOCS \- https://github.com/unbit/uwsgi-docs/ 12 | ======================== ========== =================================================== 13 | 14 | uWSGI is also available as a package in several OS/distributions. 15 | 16 | Distro packages may not be up to date. Building uWSGI requires less than 30 seconds 17 | and very few dependencies (only Python interpreter, a C compiler/linker and the libs/headers for your language of choice) 18 | -------------------------------------------------------------------------------- /DynamicApps.rst: -------------------------------------------------------------------------------- 1 | Adding applications dynamically 2 | =============================== 3 | 4 | NOTE: this is not the best approach for hosting multiple applications. You'd better to run a uWSGI instance for each app. 5 | 6 | You can start the uWSGI server without configuring an application. 7 | 8 | To load a new application you can use these variables in the uwsgi packet: 9 | 10 | * ``UWSGI_SCRIPT`` -- pass the name of a WSGI script defining an ``application`` callable 11 | * or ``UWSGI_MODULE`` and ``UWSGI_CALLABLE`` -- the module name (importable path) and the name of the callable to invoke from that module 12 | 13 | Dynamic apps are officially supported on Cherokee, Nginx, Apache, cgi_dynamic. 14 | They are easily addable to the Tomcat and Twisted handlers. 15 | 16 | Defining VirtualEnv with dynamic apps 17 | ------------------------------------- 18 | 19 | Virtualenvs are based on the ``Py_SetPythonHome()`` function. This function has 20 | effect only if called before ``Py_Initialize()`` so it can't be used with 21 | dynamic apps. 22 | 23 | To define a VirtualEnv with DynamicApps, a hack is the only solution. 24 | 25 | First you have to tell python to not import the ``site`` module. This module 26 | adds all ``site-packages`` to ``sys.path``. To emulate virtualenvs, we must 27 | load the site module only after subinterpreter initialization. Skipping the 28 | first ``import site``, we can now simply set ``sys.prefix`` and 29 | ``sys.exec_prefix`` on dynamic app loading and call 30 | 31 | .. code-block:: c 32 | 33 | PyImport_ImportModule("site"); 34 | // Some users would want to not disable initial site module loading, so the site module must be reloaded: 35 | PyImport_ReloadModule(site_module); 36 | 37 | Now we can set the VirtualEnv dynamically using the ``UWSGI_PYHOME`` var: 38 | 39 | 40 | .. code-block:: c 41 | 42 | location / { 43 | uwsgi_pass 192.168.173.5:3031; 44 | include uwsgi_params; 45 | uwsgi_param UWSGI_SCRIPT mytrac; 46 | uwsgi_param UWSGI_PYHOME /Users/roberto/uwsgi/VENV2; 47 | } 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /EmperorProtocol.rst: -------------------------------------------------------------------------------- 1 | The Emperor protocol 2 | ==================== 3 | 4 | As of 1.3 you can spawn custom applications via the :doc:`Emperor`. 5 | 6 | Non-uWSGI Vassals should never daemonize, to maintain a link with the Emperor. 7 | If you want/need better integration with the Emperor, implement the Emperor 8 | protocol. 9 | 10 | The protocol 11 | ------------ 12 | 13 | An environment variable ``UWSGI_EMPEROR_FD`` is passed to every vassal, 14 | containing a file descriptor number. 15 | 16 | .. code-block:: python 17 | 18 | import os 19 | has_emperor = os.environ.get('UWSGI_EMPEROR_FD') 20 | if has_emperor: 21 | print "I'm a vassal snake!" 22 | 23 | Or in Perl, 24 | 25 | .. code-block:: python 26 | 27 | my $has_emperor = $ENV{'UWSGI_EMPEROR_FD'} 28 | if ($has_emperor) { 29 | print "I am a vassal.\n" 30 | } 31 | 32 | Or in C, 33 | 34 | .. code-block:: c 35 | 36 | int emperor_fd = -1; 37 | char *has_emperor = getenv("UWSGI_EMPEROR_FD"); 38 | if (has_emperor) { 39 | emperor_fd = atoi(has_emperor); 40 | fprintf(stderr, "I am a vassal.\n"); 41 | } 42 | 43 | From now you can receive (and send) messages from (and to) the Emperor over this file descriptor. 44 | 45 | Messages are byte sized (0-255), and each number (byte) has a meaning. 46 | 47 | == == 48 | 0 Sent by the Emperor to stop a vassal 49 | 1 Sent by the Emperor to reload a vassal / sent by a vassal when it has been spawned 50 | 2 Sent by a vassal to ask the Emperor for configuration chunk 51 | 5 Sent by a vassal when it is ready to accept requests 52 | 17 Sent by a vassal after the first request to announce loyalty 53 | 22 Sent by a vassal to notify the Emperor of voluntary shutdown 54 | 26 Heartbeat sent by the vassal. After the first received heartbeat, the Emperor will expect more of them from the vassal. 55 | 30 Sent by the vassal to ask for :doc:`Broodlord` mode. 56 | == == 57 | -------------------------------------------------------------------------------- /FallbackConfig.rst: -------------------------------------------------------------------------------- 1 | Fallback configuration 2 | ====================== 3 | 4 | (available from 1.9.15-dev) 5 | 6 | If you need a "reset to factory defaults", or "show a welcome page if the user has made mess with its config" scenario, fallback configuration 7 | is your silver bullet 8 | 9 | Simple case 10 | *********** 11 | 12 | A very common problem is screwing-up the port on which the instance is listening. 13 | 14 | To emulate this kind of error we try to bind on port 80 as an unprivileged user: 15 | 16 | .. code-block:: sh 17 | 18 | uwsgi --uid 1000 --http-socket :80 19 | 20 | uWSGI will exit with: 21 | 22 | .. code-block:: sh 23 | 24 | bind(): Permission denied [core/socket.c line 755] 25 | 26 | Internally (from the kernel point of view) the instance exited with status 1 27 | 28 | Now we want to allow the instance to automatically bind on port 8080 when the user supplied config fails. 29 | 30 | Let's define a fallback config (you can save it as safe.ini): 31 | 32 | .. code-block:: ini 33 | 34 | [uwsgi] 35 | print = Hello i am the fallback config !!! 36 | http-socket = :8080 37 | wsgi-file = welcomeapp.wsgi 38 | 39 | Now we can re-run the (broken) instance: 40 | 41 | .. code-block:: sh 42 | 43 | uwsgi --fallback-config safe.ini --uid 1000 --http-socket :80 44 | 45 | 46 | Your error will be now something like: 47 | 48 | .. code-block:: sh 49 | 50 | bind(): Permission denied [core/socket.c line 755] 51 | Thu Jul 25 21:55:39 2013 - !!! /home/roberto/uwsgi/uwsgi (pid: 7409) exited with status 1 !!! 52 | Thu Jul 25 21:55:39 2013 - !!! Fallback config to safe.ini !!! 53 | [uWSGI] getting INI configuration from safe.ini 54 | *** Starting uWSGI 1.9.15-dev-a0cb71c (64bit) on [Thu Jul 25 21:55:39 2013] *** 55 | ... 56 | 57 | As you can see, the instance has detected the exit code 1 and has binary patched itself with a new config (without changing the pid, or calling fork()) 58 | 59 | 60 | Broken apps 61 | *********** 62 | 63 | Another common problem is the inability to load an application, but instead of bringing down the whole site we want to load 64 | an alternate application: 65 | 66 | .. code-block:: sh 67 | 68 | uwsgi --fallback-config safe.ini --need-app --http-socket :8080 --wsgi-file brokenapp.py 69 | 70 | Here the key is --need-app. It will call exit(1) if the instance has not been able to load at least one application. 71 | 72 | Multiple fallback levels 73 | ************************ 74 | 75 | Your fallback config file can specify a fallback-config directive too, allowing multiple fallback levels. BEWARE OF LOOPS!!! 76 | 77 | How it works 78 | ************ 79 | 80 | The objective is catching the exit code of a process before the process itself is destroyed (we do not want to call another fork(), or destroy already opened file descriptors) 81 | 82 | uWSGI makes heavy usage of atexit() hooks, so we only need to register the fallback handler as the first one (hooks are executed in reverse order). 83 | 84 | In addition to this we need to get the exit code in our atexit() hook, something is not supported by default (the on_exit() function is now deprecated). 85 | 86 | The solution is "patching" exit(x) with uwsgi_exit(x) that is a simple wrapper setting uwsgi.last_exit_code memory pointer. 87 | 88 | Now the hook only needs to check for uwsgi.last_exit_code == 1 and eventually execve() the binary again passing the fallback config to it 89 | 90 | .. code-block:: c 91 | 92 | char *argv[3]; 93 | argv[0] = uwsgi.binary_path; 94 | argv[1] = uwsgi.fallback_config; 95 | argv[2] = NULL; 96 | execvp(uwsgi.binary_path, argv); 97 | 98 | Notes 99 | ***** 100 | 101 | Try to place --fallback-config as soon as possible in your config tree. The various config parsers may fail (calling exit(1)) before the fallback file is registered 102 | 103 | 104 | -------------------------------------------------------------------------------- /ForkServer.rst: -------------------------------------------------------------------------------- 1 | The Fork Server (sponsored by Intellisurvey) 2 | ============================================ 3 | 4 | This is a really advanced (and complex) feature developed with sponsorship from Intellisurvey.com. 5 | 6 | If you have dozens or even hundreds of applications built upon the same codebase you can setup your Emperor to fork vassals 7 | from an already running one (with the application core loaded). 8 | 9 | Currently the feature is supported only in the PSGI plugin, and requires Linux kernel >= 3.4. 10 | 11 | How it works 12 | ------------ 13 | 14 | When in `fork-server` mode, the Emperor differentiates between two kind of vassals: base vassals and adopted vassals. 15 | 16 | "base" vassals are pretty much classic vassals; generated by `fork()` + `execve()` by the Emperor. 17 | The only difference is that they are supposed to load as much of your application code as possible as soon as possible, then suspend themselves waiting for connections on a UNIX socket. 18 | 19 | A "base" vassal will be something like this 20 | 21 | .. code-block:: ini 22 | 23 | [uwsgi] 24 | ; load myapp.pl as soon as possible 25 | early-psgi = myapp.pl 26 | ; suspend and execution and bind on UNIX socket /tmp/fork_server.socket 27 | fork-server = /tmp/fork_server.socket 28 | 29 | "Adopted" vassals are the true "new thing". 30 | 31 | Once an adopted vassal is requested, the Emperor connects to the specified fork server (instead of calling `fork()` + `execve()` itself). 32 | 33 | The Emperor passes an uwsgi-serialized array of command line options of the new vassal and up to 3 file descriptors (since UNIX sockets allow passing file descriptors from one process to another). 34 | 35 | Those 3 file descriptors are: 36 | 37 | * 1 -> the communication pipe with the Emperor (required) 38 | * 2 -> the config pipe (optional) 39 | * 3 -> on_demand socket (optional) 40 | 41 | At this point, the fork server `fork()`\ s itself twice and continues the uWSGI startup using the supplied arguments array. 42 | 43 | How can the Emperor `wait()` on an external process, then? 44 | 45 | This is why a >= 3.4 kernel is required, as thanks to the `prctl(PR_SET_CHILD_SUBREAPER, 1)` call we can tell 46 | vassals to be re-parented to the Emperor when their parent dies (in fact the fork-server forks two times, so the vassal has no live parent, poor thing). 47 | 48 | Now the Emperor has a new child and a communication pipe. And that's all. 49 | 50 | Configuring the Emperor for fork-server mode 51 | --------------------------------------------- 52 | 53 | You need only two new options: ``--emperor-use-fork-serve `` and ``--vassal-fork-base `` 54 | 55 | Let's start with a slow-loading (10 seconds) Perl app: 56 | 57 | .. code-block:: pl 58 | 59 | # myapp.pl 60 | print "I am the App\n"; 61 | sleep(10); 62 | my $app = sub { 63 | return [200, ['Content-Type'=>'text/html'], ["Hello World"]]; 64 | }; 65 | 66 | Save it as myapp.pl and load it in perlbase.ini vassal file (this is a base vassal): 67 | 68 | .. code-block:: ini 69 | 70 | [uwsgi] 71 | early-psgi = myapp.pl 72 | fork-server = /var/run/fork_server.socket 73 | 74 | Now create two vassals (one.ini and two.ini) that will `fork()` from the base one: 75 | 76 | .. code-block:: ini 77 | 78 | [uwsgi] 79 | ; one.ini 80 | http-socket = :8181 81 | processes = 4 82 | uid = 1001 83 | gid = 1001 84 | 85 | .. code-block:: ini 86 | 87 | [uwsgi] 88 | ; two.ini 89 | http-socket = :8282 90 | processes = 8 91 | uid = 1002 92 | gid = 1002 93 | 94 | As you can see they are pretty different, even in privileges. 95 | 96 | Now let's spawn the Emperor in fork-server mode allowing perlbase.ini as a "base" vassal: 97 | 98 | .. code-block:: ini 99 | 100 | [uwsgi] 101 | emperor = /etc/uwsgi/vassals 102 | emperor-use-fork-server = /var/run/fork_server.socket 103 | vassal-fork-base = perlbase.ini 104 | emperor-stats = 127.0.0.1:5000 105 | 106 | The Emperor will start running perlbase.ini as a standard vassal, while for the non-base ones it will `fork()` from the base, where the app is already loaded. 107 | 108 | You will note that instead waiting for 10 seconds, your new vassals will start immediately. Pretty cool, huh? 109 | -------------------------------------------------------------------------------- /GeoIP.rst: -------------------------------------------------------------------------------- 1 | The GeoIP plugin 2 | ================ 3 | 4 | The ``geoip`` plugin adds new routing vars to your internal routing subsystem. 5 | GeoIP's vars are prefixed with the "geoip" tag. To build the geoip plugin you 6 | need the official GeoIP C library and its headers. The supported databases are 7 | the country and city one, and they are completely loaded on memory at startup. 8 | 9 | The country database give access to the following variables: 10 | 11 | * ``${geoip[country_code]}`` 12 | * ``${geoip[country_code3]}`` 13 | * ``${geoip[country_name]}`` 14 | 15 | while the city one offers a lot more at the cost of increased memory usage for 16 | storing the database 17 | 18 | * ``${geoip[continent]}`` 19 | * ``${geoip[country_code]}`` 20 | * ``${geoip[country_code3]}`` 21 | * ``${geoip[country_name]}`` 22 | * ``${geoip[region]}`` 23 | * ``${geoip[region_name]}`` 24 | * ``${geoip[city]}`` 25 | * ``${geoip[postal_code]}`` 26 | * ``${geoip[latitude]}`` (``${geoip[lat]}``) 27 | * ``${geoip[longitude]}`` (``${geoip[lon]}``) 28 | * ``${geoip[dma]}`` 29 | * ``${geoip[area]}`` 30 | 31 | Enabling geoip lookup 32 | ********************* 33 | 34 | To enable the GeoIP lookup system you need to load at least one database. After 35 | having loaded the geoip plugin you will get 2 new options: 36 | 37 | * ``--geoip-country`` specifies a country database 38 | * ``--geoip-city`` specifies a city database 39 | 40 | If you do not specify at least one of them, the system will always return empty strings. 41 | 42 | An example 43 | ********** 44 | 45 | .. code-block:: ini 46 | 47 | [uwsgi] 48 | plugin = geoip 49 | http-socket = :9090 50 | ; load the geoip city database 51 | geoip-city = GeoLiteCity.dat 52 | module = werkzeug.testapp:test_app 53 | ; first some debug info (addvar will ad WSGI variables you will see in the werkzeug testapp) 54 | route-run = log:${geoip[country_name]}/${geoip[country_code3]} 55 | route-run = addvar:COUNTRY=${geoip[country_name]} 56 | route-run = log:${geoip[city]}/${geoip[region]}/${geoip[continent]} 57 | route-run = addvar:COORDS=${geoip[lon]}/${geoip[lat]} 58 | route-run = log:${geoip[region_name]} 59 | route-run = log:${geoip[dma]}/${geoip[area]} 60 | 61 | ; then something more useful 62 | ; block access to all of the italians (hey i am italian do not start blasting me...) 63 | route-if = equal:${geoip[country_name]};Italy break:403 Italians cannot see this site :P 64 | ; try to serve a specific page translation 65 | route = ^/foo/bar/test.html static:/var/www/${geoip[country_code]}/test.html 66 | 67 | Memory usage 68 | ************ 69 | 70 | The country database is tiny so you will generally have no problem in using it. 71 | Instead, the city database can be huge (from 20MB to more than 40MB). If you 72 | have lot of instances using the GeoIP city database and you are on a recent 73 | Linux system, consider using :doc:`KSM` to reduce memory usage. All of the 74 | memory used by the GeoIP database can be shared by all instances with it. 75 | -------------------------------------------------------------------------------- /Glossary.rst: -------------------------------------------------------------------------------- 1 | Glossary 2 | ======== 3 | 4 | .. glossary:: 5 | :sorted: 6 | 7 | harakiri 8 | A feature of uWSGI that aborts workers that are serving requests for an 9 | excessively long time. Configured using the ``harakiri`` family of 10 | options. Every request that will take longer than the seconds specified 11 | in the harakiri timeout will be dropped and the corresponding worker 12 | recycled. 13 | 14 | master 15 | uWSGI's built-in prefork+threading multi-worker management mode, 16 | activated by flicking the ``master`` switch on. For all practical serving 17 | deployments it is generally a good idea to use master mode. 18 | -------------------------------------------------------------------------------- /HTTPS.rst: -------------------------------------------------------------------------------- 1 | HTTPS support (from 1.3) 2 | ============================ 3 | 4 | Use the ``https ,,`` option. This option may be 5 | specified multiple times. First generate your server key, certificate signing 6 | request, and self-sign the certificate using the OpenSSL toolset: 7 | 8 | .. note:: You'll want a real SSL certificate for production use. 9 | 10 | :: 11 | 12 | openssl genrsa -out foobar.key 2048 13 | openssl req -new -key foobar.key -out foobar.csr 14 | openssl x509 -req -days 365 -in foobar.csr -signkey foobar.key -out foobar.crt 15 | 16 | Then start the server using the SSL certificate and key just generated:: 17 | 18 | uwsgi --master --https 0.0.0.0:8443,foobar.crt,foobar.key 19 | 20 | As port 443, the port normally used by HTTPS, is privileged (ie. non-root 21 | processes may not bind to it), you can use the shared socket mechanism and drop 22 | privileges after binding like thus:: 23 | 24 | uwsgi --shared-socket 0.0.0.0:443 --uid roberto --gid roberto --https =0,foobar.crt,foobar.key 25 | 26 | uWSGI will bind to 443 on any IP, then drop privileges to those of ``roberto``, 27 | and use the shared socket 0 (``=0``) for HTTPS. 28 | 29 | .. note:: The =0 syntax is currently undocumented. 30 | 31 | .. note:: In order to use `https` option be sure that you have OpenSSL 32 | development headers installed (e.g. libssl-dev on Debian). Install them 33 | and rebuild uWSGI so the build system will automatically detect it. 34 | 35 | Setting SSL/TLS ciphers 36 | ----------------------- 37 | 38 | The ``https`` option takes an optional fourth argument you can use to specify 39 | the OpenSSL cipher suite. 40 | 41 | .. code-block:: ini 42 | 43 | [uwsgi] 44 | master = true 45 | shared-socket = 0.0.0.0:443 46 | uid = www-data 47 | gid = www-data 48 | 49 | https = =0,foobar.crt,foobar.key,HIGH 50 | http-to = /tmp/uwsgi.sock 51 | 52 | 53 | This will set all of the **HIGHest** ciphers (whenever possible) for your 54 | SSL/TLS transactions. 55 | 56 | Client certificate authentication 57 | --------------------------------- 58 | 59 | The ``https`` option can also take an optional 5th argument. You can use it to 60 | specify a CA certificate to authenticate your clients with. Generate your CA 61 | key and certificate (this time the key will be 4096 bits and 62 | password-protected):: 63 | 64 | openssl genrsa -des3 -out ca.key 4096 65 | openssl req -new -x509 -days 365 -key ca.key -out ca.crt 66 | 67 | Generate the server key and CSR (as before):: 68 | 69 | openssl genrsa -out foobar.key 2048 70 | openssl req -new -key foobar.key -out foobar.csr 71 | 72 | Sign the server certificate with your new CA:: 73 | 74 | openssl x509 -req -days 365 -in foobar.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out foobar.crt 75 | 76 | Create a key and a CSR for your client, sign it with your CA and package it as 77 | PKCS#12. Repeat these steps for each client. 78 | 79 | :: 80 | 81 | openssl genrsa -des3 -out client.key 2048 82 | openssl req -new -key client.key -out client.csr 83 | openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt 84 | openssl pkcs12 -export -in client.crt -inkey client.key -name "Client 01" -out client.p12 85 | 86 | 87 | Then configure uWSGI for certificate client authentication 88 | 89 | .. code-block:: ini 90 | 91 | [uwsgi] 92 | master = true 93 | shared-socket = 0.0.0.0:443 94 | uid = www-data 95 | gid = www-data 96 | https = =0,foobar.crt,foobar.key,HIGH,!ca.crt 97 | http-to = /tmp/uwsgi.sock 98 | 99 | .. note:: If you don't want the client certificate authentication to be 100 | mandatory, remove the '!' before ca.crt in the https options. 101 | 102 | If your client certificates are signed by intermediate certificates 103 | rather than directly by a CA, you will need to set the 104 | ``ssl-verify-depth`` option to a value large enough to accomodate 105 | the whole certificate chain. For example 106 | 107 | .. code-block:: ini 108 | 109 | [uwsgi] 110 | master = true 111 | shared-socket = 0.0.0.0:443 112 | uid = www-data 113 | gid = www-data 114 | ssl-verify-depth = 8 115 | https = =0,foobar.crt,foobar.key,HIGH,!ca.crt 116 | http-to = /tmp/uwsgi.sock 117 | 118 | .. note:: Due to an order dependency in configuration parsing, the 119 | ``ssl-verify-depth`` option must be specified *before* the 120 | ``https`` option. 121 | -------------------------------------------------------------------------------- /Inetd.rst: -------------------------------------------------------------------------------- 1 | Socket activation with inetd/xinetd 2 | =================================== 3 | 4 | Inetd and Xinetd are two daemons used to start network processes on demand. 5 | You can use this in uWSGI too. 6 | 7 | Inetd 8 | ----- 9 | 10 | 11 | .. code-block:: inetd 12 | 13 | 127.0.0.1:3031 stream tcp wait root /usr/bin/uwsgi uwsgi -M -p 4 --wsgi-file /root/uwsgi/welcome.py --log-syslog=uwsgi 14 | 15 | With this config you will run uWSGI on port 3031 as soon as the first 16 | connection is made. Note: the first argument (the one soon after 17 | /usr/bin/uwsgi) is mapped to ``argv[0]``. Do not forget this -- always set it 18 | to ``uwsgi`` if you want to be sure. 19 | 20 | Xinetd 21 | ------ 22 | 23 | .. code-block:: xinetd 24 | 25 | service uwsgi 26 | { 27 | disable = no 28 | id = uwsgi-000 29 | type = UNLISTED 30 | socket_type = stream 31 | server = /root/uwsgi/uwsgi 32 | server_args = --chdir /root/uwsgi/ --module welcome --logto /tmp/uwsgi.log 33 | port = 3031 34 | bind = 127.0.0.1 35 | user = root 36 | wait = yes 37 | } 38 | 39 | Again, you do not need to specify the socket in uWSGI, as it will be passed to 40 | the server by xinetd. 41 | -------------------------------------------------------------------------------- /Install.rst: -------------------------------------------------------------------------------- 1 | Installing uWSGI 2 | ================ 3 | 4 | Installing from a distribution package 5 | -------------------------------------- 6 | 7 | uWSGI is available as a package in several OS/distributions. 8 | 9 | Installing from source 10 | ---------------------- 11 | 12 | To build uWSGI you need Python and a C compiler (``gcc`` and ``clang`` are 13 | supported). Depending on the languages you wish to support you will need their 14 | development headers. On a Debian/Ubuntu system you can install them (and the 15 | rest of the infrastructure required to build software) with: 16 | 17 | .. code-block:: sh 18 | 19 | apt-get install build-essential python 20 | 21 | And if you want to build a binary with python/wsgi support (as an example) 22 | 23 | .. code-block:: sh 24 | 25 | apt-get install python-dev 26 | 27 | On a Fedora/Redhat system you can install them with: 28 | 29 | .. code-block:: sh 30 | 31 | yum groupinstall "Development Tools" 32 | yum install python 33 | 34 | For python/wsgi support: 35 | 36 | .. code-block:: sh 37 | 38 | yum install python-devel 39 | 40 | 41 | If you have a variant of `make` available in your system you can simply run 42 | `make`. If you do not have `make` (or want to have more control) simply run: 43 | 44 | .. code-block:: sh 45 | 46 | python uwsgiconfig.py --build 47 | 48 | You can also use pip to install uWSGI (it will build a binary with python support). 49 | 50 | .. code-block:: sh 51 | 52 | # Install the latest stable release: 53 | pip install uwsgi 54 | # ... or if you want to install the latest LTS (long term support) release, 55 | pip install https://projects.unbit.it/downloads/uwsgi-lts.tar.gz 56 | 57 | Or you can use ruby gems (it will build a binary with ruby/rack support). 58 | 59 | .. code-block:: sh 60 | 61 | # Install the latest stable release: 62 | gem install uwsgi 63 | 64 | 65 | At the end of the build, you will get a report of the enabled features. If 66 | something you require is missing, just add the development headers and rerun 67 | the build. For example to build uWSGI with ssl and perl regexp support you 68 | need libssl-dev and pcre headers. 69 | 70 | Alternative build profiles 71 | -------------------------- 72 | 73 | For historical reasons when you run 'make', uWSGI is built with Python as the 74 | only supported language. You can build customized uWSGI servers using build 75 | profiles, located in the `buildconf/` directory. You can use a specific 76 | profile with: 77 | 78 | .. code-block:: sh 79 | 80 | python uwsgiconfig.py --build 81 | 82 | Or you can pass it via an environment variable: 83 | 84 | .. code-block:: sh 85 | 86 | UWSGI_PROFILE=lua make 87 | # ... or even ... 88 | UWSGI_PROFILE=gevent pip install uwsgi 89 | 90 | 91 | Modular builds 92 | -------------- 93 | 94 | This is the approach your distribution should follow, and this is the approach 95 | you MUST follow if you want to build a commercial service over uWSGI (see 96 | below). The vast majority of uWSGI features are available as plugins. Plugins 97 | can be loaded using the --plugin option. If you want to give users the maximum 98 | amount of flexibility allowing them to use only the minimal amount of 99 | resources, just create a modular build. A build profile named "core" is 100 | available. 101 | 102 | .. code-block:: sh 103 | 104 | python uwsgiconfig.py --build core 105 | 106 | This will build a uWSGi binary without plugins. This is called the "server 107 | core". Now you can start building all of the plugins you need. Check the 108 | plugins/ directory in the source distribution for a full list. 109 | 110 | .. code-block:: sh 111 | 112 | python uwsgiconfig.py --plugin plugins/psgi core 113 | python uwsgiconfig.py --plugin plugins/rack core 114 | python uwsgiconfig.py --plugin plugins/python core 115 | python uwsgiconfig.py --plugin plugins/lua core 116 | python uwsgiconfig.py --plugin plugins/corerouter core 117 | python uwsgiconfig.py --plugin plugins/http core 118 | ... 119 | 120 | Remember to always pass the build profile ('core' in this case) as the third 121 | argument. 122 | 123 | -------------------------------------------------------------------------------- /KSM.rst: -------------------------------------------------------------------------------- 1 | Using Linux KSM in uWSGI 2 | ======================== 3 | 4 | `Kernel Samepage Merging `_ is a feature of 5 | Linux kernels >= 2.6.32 which allows processes to share pages of memory with 6 | the same content. This is accomplished by a kernel daemon that periodically 7 | performs scans, comparisons, and, if possible, merges of specific memory areas. 8 | Born as an enhancement for KVM it can be used for processes that use common data 9 | (such as uWSGI processes with language interpreters and standard libraries). 10 | 11 | If you are lucky, using KSM may exponentially reduce the memory usage of your 12 | uWSGI instances. Especially in massive :doc:`Emperor` deployments: 13 | enabling KSM for each vassal may result in massive memory savings. 14 | KSM in uWSGI was the idea of Giacomo Bagnoli of `Asidev s.r.l. 15 | `_. Many thanks to him. 16 | 17 | Enabling the KSM daemon 18 | ----------------------- 19 | 20 | To enable the KSM daemon (``ksmd``), simply set ``/sys/kernel/mm/ksm/run`` to 1, 21 | like so: 22 | 23 | .. code-block:: sh 24 | 25 | echo 1 > /sys/kernel/mm/ksm/run 26 | 27 | .. note:: 28 | 29 | Remember to do this on machine startup, as the KSM daemon does not run by 30 | default. 31 | 32 | .. note:: 33 | 34 | KSM is an opt-in feature that has to be explicitly requested by processes, 35 | so just enabling KSM will not be a savior for everything on your machine. 36 | 37 | Enabling KSM support in uWSGI 38 | ----------------------------- 39 | 40 | If you have compiled uWSGI on a kernel with KSM support, you will be able to 41 | use the ``ksm`` option. This option will instruct uWSGI to register process 42 | memory mappings (via ``madvise`` syscall) after each request or master cycle. 43 | If no page mapping has changed from the last scan, no expensive syscalls are 44 | used. 45 | 46 | Performance impact 47 | ------------------ 48 | 49 | Checking for process mappings requires parsing the ``/proc/self/maps`` file 50 | after each request. In some setups this may hurt performance. You can tune the 51 | frequency of the uWSGI page scanner by passing an argument to the ``ksm`` 52 | option. 53 | 54 | .. code-block:: sh 55 | 56 | # Scan for process mappings every 10 requests (or 10 master cycles) 57 | ./uwsgi -s :3031 -M -p 8 -w myapp --ksm=10 58 | 59 | Check if KSM is working well 60 | ---------------------------- 61 | 62 | The ``/sys/kernel/mm/ksm/pages_shared`` and ``/sys/kernel/mm/ksm/pages_sharing`` 63 | files contain statistics regarding KSM's efficiency. The higher values, the 64 | less memory consumption for your uWSGI instances. 65 | 66 | KSM statistics with collectd 67 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 68 | 69 | A simple Bash script like this is useful for keeping an eye on KSM's efficiency: 70 | 71 | .. code-block:: sh 72 | 73 | #!/bin/bash 74 | 75 | export LC_ALL=C 76 | 77 | if [ -e /sys/kernel/mm/ksm/pages_sharing ]; then 78 | pages_sharing=`cat /sys/kernel/mm/ksm/pages_sharing`; 79 | page_size=`getconf PAGESIZE`; 80 | saved=$(echo "scale=0;$pages_sharing * $page_size"|bc); 81 | echo "PUTVAL <%= cn %>/ksm/gauge-saved interval=60 N:$saved" 82 | fi 83 | 84 | In your `collectd `_ configuration, add something like 85 | this: 86 | 87 | .. code-block:: ini 88 | 89 | LoadPlugin exec 90 | 91 | Exec "nobody" "/usr/local/bin/ksm_stats.sh" 92 | 93 | -------------------------------------------------------------------------------- /LDAP.rst: -------------------------------------------------------------------------------- 1 | Configuring uWSGI with LDAP 2 | =========================== 3 | 4 | uWSGI can be configured using LDAP. LDAP is a flexible way to centralize 5 | configuration of large clusters of uWSGI servers. 6 | 7 | .. note:: 8 | 9 | LDAP support must be enabled while :doc:`building` uWSGI. The 10 | `libldap` library is required. 11 | 12 | 13 | Importing the uWSGIConfig schema 14 | -------------------------------- 15 | 16 | Running uWSGI with the `--ldap-schema` or `--ldap-schema-ldif` parameter will 17 | make it output a standard LDAP schema (or an LDIF file) that you can import 18 | into your server. 19 | 20 | An example LDIF dump 21 | -------------------- 22 | 23 | This is an LDIF dump of an OpenLDAP server with a `uWSGIConfig` entry, running 24 | a Trac instance. 25 | 26 | .. code-block:: ldif 27 | 28 | dn: dc=projects,dc=unbit,dc=it 29 | objectclass: uWSGIConfig 30 | objectclass: domain 31 | dc: projects 32 | uWSGIsocket: /var/run/uwsgi/projects.unbit.it.sock 33 | uWSGIhome: /accounts/unbit/tracvenv 34 | uWSGImodule: trac.web.main:dispatch_request 35 | uWSGImaster: TRUE 36 | uWSGIprocesses: 4 37 | uWSGIenv: TRAC_ENV=/accounts/unbit/trac/uwsgi 38 | 39 | Usage 40 | ----- 41 | 42 | You only need to pass a valid LDAP url to the `--ldap` option. Only the first 43 | entry returned will be used as configuration. 44 | 45 | .. 46 | 47 | uwsgi --ldap ldap://ldap.unbit.it/dc=projects,dc=unbit,dc=it 48 | 49 | 50 | If you want a filter with sub scope (this will return the first record under 51 | the tree `dc=projects,dc=unbit,dc=it` with `ou=Unbit`): 52 | 53 | .. 54 | 55 | uwsgi --ldap ldap://ldap.unbit.it/dc=projects,dc=unbit,dc=it?sub?ou=Unbit 56 | 57 | 58 | .. attention: 59 | 60 | Authentication is currently unsupported. 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Unbit 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LanguagesAndPlatforms.rst: -------------------------------------------------------------------------------- 1 | Supported languages and platforms 2 | ================================= 3 | 4 | .. list-table:: 5 | :header-rows: 1 6 | 7 | * - Technology 8 | - Available since 9 | - Notes 10 | - Status 11 | * - Python 12 | - 0.9.1 13 | - The first available plugin, supports WSGI (:pep:`333`, :pep:`3333`), 14 | Web3 (from version 0.9.7-dev) and Pump (from 0.9.8.4). Works with 15 | :doc:`Virtualenv`, multiple Python interpreters, :doc:`Python3` and 16 | has unique features like :doc:`PythonModuleAlias`, 17 | :doc:`DynamicVirtualenv` and :doc:`uGreen`. A module exporting handy 18 | :doc:`decorators` for the uWSGI API is available in 19 | the source distribution. PyPy :doc:`is supported` since 1.3. The 20 | :doc:`Tracebacker` was added in 1.3. 21 | - Stable, 100% uWSGI API support 22 | * - Lua 23 | - 0.9.5 24 | - Supports :doc:`LuaWSAPI`, coroutines and threads 25 | - Stable, 60% uWSGI API support 26 | * - Perl 27 | - 0.9.5 28 | - :doc:`Perl` (PSGI) support. Multiple interpreters, threading and async 29 | modes supported 30 | - Stable, 60% uWSGI API support 31 | * - Ruby 32 | - 0.9.7-dev 33 | - :doc:`Ruby` support. A loop engine for :doc:`Ruby 1.9 34 | fibers` is available as well as a handy :doc:`DSL ` 35 | module. 36 | - Stable, 80% uWSGI API support 37 | * - :doc:`Erlang` 38 | - 0.9.5 39 | - Allows message exchanging between uWSGI and Erlang nodes. 40 | - Stable, no uWSGI API support 41 | * - :doc:`CGI` 42 | - 1.0-dev 43 | - Run CGI scripts 44 | - Stable, no uWSGI API support 45 | * - :doc:`PHP` 46 | - 1.0-dev 47 | - Run PHP scripts 48 | - Stable from 1.1, 5% uWSGI API support 49 | * - :doc:`Go` 50 | - 1.4-dev 51 | - Allows integration with the Go language 52 | - 15% uWSGI API support 53 | * - :doc:`JVM` 54 | - 1.9-dev 55 | - Allows integration between uWSGI and the Java Virtual Machine 56 | :doc:`JWSGI` and :doc:`Clojure/Ring` handlers are available. 57 | - Stable 58 | * - :doc:`Mono` 59 | - 0.9.7-dev 60 | - Allows integration between uWSGI and Mono, and execution of ASP.NET 61 | applications. 62 | - Stable 63 | * - :doc:`V8` 64 | - 1.9.4 65 | - Allows integration between uWSGI and the V8 JavaScript engine. 66 | - Early stage of development 67 | -------------------------------------------------------------------------------- /Lighttpd.rst: -------------------------------------------------------------------------------- 1 | Lighttpd support 2 | ================ 3 | 4 | lighttpd >= 1.4.42 supports the uwsgi protocol with Python WSGI backends. 5 | The uwsgi protocol is similar to the SCGI protocol, and lighttpd supports 6 | both protocols in mod_scgi. 7 | 8 | Configuring Lighttpd 9 | -------------------- 10 | 11 | Modify your lighttpd.conf configuration file: 12 | 13 | :: 14 | 15 | server.modules += ( "mod_scgi" ) 16 | scgi.protocol = "uwsgi" 17 | scgi.server = ( 18 | "/" => (( "host" => "127.0.0.1", "port" => 3031, "check-local" => "disable" )), 19 | ) 20 | 21 | Further doc on configuring lighttpd and Python WSGI can be found at 22 | https://redmine.lighttpd.net/projects/lighttpd/wiki/HowToPythonWSGI 23 | including examples configuring uWSGI servers. 24 | -------------------------------------------------------------------------------- /Locks.rst: -------------------------------------------------------------------------------- 1 | Locks 2 | ===== 3 | 4 | uWSGI supports a configurable number of locks you can use to synchronize worker 5 | processes. Lock 0 (zero) is always available, but you can add more with the 6 | ``locks`` option. If your app has a lot of critical areas, holding and 7 | releasing the same lock over and over again can kill performance. 8 | 9 | .. code-block:: py 10 | 11 | def use_lock_zero_for_important_things(): 12 | uwsgi.lock() # Implicit parameter 0 13 | # Critical section 14 | uwsgi.unlock() # Implicit parameter 0 15 | 16 | def use_another_lock(): 17 | uwsgi.lock(1) 18 | time.sleep(1) # Take that, performance! Ha! 19 | uwsgi.unlock(1) 20 | -------------------------------------------------------------------------------- /ManagementFlag.rst: -------------------------------------------------------------------------------- 1 | Management Flags 2 | ================ 3 | 4 | .. warning:: This feature may be currently broken or deprecated. 5 | 6 | You can modify the behavior of some aspects of the uWSGI stack remotely, without taking the server offline using the Management Flag system. 7 | 8 | .. note:: A more comprehensive re-setup system may be in the works. 9 | 10 | All the flags take an unsigned 32-bit value (so the block size is always 4) that contains the value to set for the flag. 11 | If you do not specify this value, only sending the uWSGI header, the server will count it as a read request. 12 | 13 | 14 | ==== =============== =========== 15 | Flag Action Description 16 | ==== =============== =========== 17 | 0 logging enable/disable logging 18 | 1 max_requests set maximum number of requests per worker 19 | 2 socket_timeout modify the internal socket timeout 20 | 3 memory_debug enable/disable memory debug/report 21 | 4 master_interval set the master process check interval 22 | 5 harakiri set/unset the harakiri timeout 23 | 6 cgi_mode enable/disable cgi mode 24 | 7 threads enable/disable threads (currently unimplemented) 25 | 8 reaper enable/disable process reaper 26 | 9 log-zero enable/disable logging of request with zero response size 27 | 10 log-slow set/unset logging of slow requests 28 | 11 log-4xx enable/disable logging of request with 4xx response status 29 | 12 log-5xx enable/disable logging of request with 5xx response status 30 | 13 log-big set/unset logging of request with big response size 31 | 14 log-sendfile set/unset logging of sendfile requests 32 | 15 backlog-status report the current size of the backlog queue (linux on tcp only) 33 | 16 backlog-errors report the number of errors in the backlog queue (linux on tcp only) 34 | ==== =============== =========== 35 | 36 | myadmin tool 37 | ------------ 38 | 39 | A simple (and ugly) script, ``myadmin``, is included to remotely change management flags: 40 | 41 | .. code-block:: sh 42 | 43 | # disable logging on the uWSGI server listening on 192.168.173.17 port 3031 44 | ./uwsgi --no-server -w myadmin --pyargv "192.168.173.17:3031 0 0" 45 | # re-enable logging 46 | ./uwsgi --no-server -w myadmin --pyargv "192.168.173.17:3031 0 1" 47 | # read a value: 48 | ./uwsgi --no-server -w myadmin --pyargv "192.168.173.17:3031 15" 49 | -------------------------------------------------------------------------------- /MasterFIFO.rst: -------------------------------------------------------------------------------- 1 | The Master FIFO 2 | =============== 3 | 4 | Available from uWSGI 1.9.17. 5 | 6 | Generally you use UNIX signals to manage the master, but we are running out of signal numbers and (more importantly) not needing to mess with PIDs 7 | greatly simplifies the implementation of external management scripts. 8 | 9 | So, instead of signals, you can tell the master to create a UNIX named pipe (FIFO) that you may use to issue commands to the master. 10 | 11 | To create a FIFO just add ``--master-fifo `` then start issuing commands to it. 12 | 13 | .. code-block:: sh 14 | 15 | echo r > /tmp/yourfifo 16 | 17 | You can send multiple commands in one shot. 18 | 19 | .. code-block:: sh 20 | 21 | # add 3 workers and print stats 22 | echo +++s > /tmp/yourfifo 23 | 24 | Available commands 25 | ****************** 26 | 27 | * '0' to '9' - set the fifo slot (see below) 28 | * '+' - increase the number of workers when in cheaper mode (add ``--cheaper-algo manual`` for full control) 29 | * '-' - decrease the number of workers when in cheaper mode (add ``--cheaper-algo manual`` for full control) 30 | * 'B' - ask Emperor for reinforcement (broodlord mode, requires uWSGI >= 2.0.7) 31 | * 'C' - set cheap mode 32 | * 'c' - trigger chain reload 33 | * 'E' - trigger an Emperor rescan 34 | * 'f' - re-fork the master (dangerous, but very powerful) 35 | * 'l' - reopen log file (need --log-master and --logto/--logto2) 36 | * 'L' - trigger log rotation (need --log-master and --logto/--logto2) 37 | * 'p' - pause/resume the instance 38 | * 'P' - update pidfiles (can be useful after master re-fork) 39 | * 'Q' - brutally shutdown the instance 40 | * 'q' - gracefully shutdown the instance 41 | * 'R' - send brutal reload 42 | * 'r' - send graceful reload 43 | * 'S' - block/unblock subscriptions 44 | * 's' - print stats in the logs 45 | * 'W' - brutally reload workers 46 | * 'w' - gracefully reload workers 47 | 48 | FIFO slots 49 | ********** 50 | 51 | uWSGI supports up to 10 different FIFO files. By default the first specified is bound (mapped as '0'). 52 | 53 | During the instance's lifetime you can change from one FIFO to another by simply sending the number of the FIFO slot to use. 54 | 55 | .. code-block:: ini 56 | 57 | [uwsgi] 58 | master-fifo = /tmp/fifo0 59 | master-fifo = /tmp/fifo1 60 | master-fifo = /var/run/foofifo 61 | processes = 2 62 | ... 63 | 64 | By default ``/tmp/fifo0`` will be allocated, but after sending: 65 | 66 | .. code-block:: sh 67 | 68 | echo 1 > /tmp/fifo0 69 | 70 | the ``/tmp/fifo1`` file will be bound. 71 | 72 | This is very useful to map FIFO files to specific instance when you (ab)use the 'fork the master' command (the 'f' one). 73 | 74 | .. code-block:: sh 75 | 76 | echo 1fp > /tmp/fifo0 77 | 78 | After sending this command, a new uWSGI instance (inheriting all of the bound sockets) will be spawned, the old one will be put in "paused" mode (the 'p' command). 79 | 80 | As we have sent the '1' command before 'f' and 'p' the old instance will now accept commands on /tmp/fifo1 (the slot 1), and the new one will use the default one ('0'). 81 | 82 | There are lot of tricks you can accomplish, and lots of ways to abuse the forking of the master. 83 | 84 | Just take into account that corner-case problems can occur all over the place, especially if you use the most complex features of uWSGI. 85 | 86 | Notes 87 | ***** 88 | 89 | * The FIFO is created in non-blocking modes and recreated by the master every time a client disconnects. 90 | * You can override (or add) commands using the global array ``uwsgi_fifo_table`` via plugins or C hooks. 91 | * Only the uid running the master has write access to the fifo. 92 | -------------------------------------------------------------------------------- /Nagios.rst: -------------------------------------------------------------------------------- 1 | Monitoring uWSGI with Nagios 2 | ============================ 3 | 4 | The official uWSGI distribution includes a plugin adding Nagios_\ -friendly output. 5 | 6 | To monitor, and eventually get warning messages, via Nagios, launch the following command, where ``node`` is the socket (UNIX or TCP) to monitor. 7 | 8 | .. code-block:: sh 9 | 10 | uwsgi --socket --nagios 11 | 12 | Setting warning messages 13 | ------------------------ 14 | 15 | You can set a warning message directly from your app with the :func:`uwsgi.set_warning_message` function. All ping responses (used by Nagios too) will report this message. 16 | 17 | .. _Nagios: http://www.nagios.com/ -------------------------------------------------------------------------------- /OffloadSubsystem.rst: -------------------------------------------------------------------------------- 1 | The uWSGI offloading subsystem 2 | ============================== 3 | 4 | Offloading is a way to optimize tiny tasks, delegating them to one or more threads. 5 | 6 | These threads run such tasks in a non-blocking/evented way allowing for a huge amount of concurrency. 7 | 8 | Various components of the uWSGI stack are offload-friendly, and the long-term target is to allow 9 | application code to abuse them. 10 | 11 | 12 | To start the offloading subsystem just add --offload-threads , where is the number of threads (per-worker) to spawn. 13 | They are native threads, they are lock-free (no shared resources), thundering-herd free (requests to the system 14 | are made in round-robin) and they are the best way to abuse your CPU cores. 15 | 16 | The number of offloaded requests is accounted in the "offloaded_requests" metric of the stats subsystem. 17 | 18 | 19 | Offloading static files 20 | *********************** 21 | 22 | The first offload-aware component is the static file serving system. 23 | 24 | When offload threads are available, the whole transfer of the file is delegated to one of those threads, freeing your worker 25 | suddenly (so it will be ready to accept new requests) 26 | 27 | Example: 28 | 29 | .. code-block:: ini 30 | 31 | [uwsgi] 32 | socket = :3031 33 | check-static = /var/www 34 | offload-threads = 4 35 | 36 | Offloading internal routing 37 | *************************** 38 | 39 | The router_uwsgi and router_http plugins are offload-friendly. 40 | 41 | You can route requests to external uwsgi/HTTP servers without being worried about having a blocked worker during 42 | the response generation. 43 | 44 | Example: 45 | 46 | .. code-block:: ini 47 | 48 | [uwsgi] 49 | socket = :3031 50 | offload-threads = 8 51 | route = ^/foo http:127.0.0.1:8080 52 | route = ^/bar http:127.0.0.1:8181 53 | route = ^/node http:127.0.0.1:9090 54 | 55 | Since 1.9.11 the ``cache`` router is offload friendly too. 56 | 57 | .. code-block:: ini 58 | 59 | [uwsgi] 60 | socket = :3031 61 | offload-threads = 8 62 | route-run = cache:key=${REQUEST_URI} 63 | 64 | As soon as the object is retrieved from the cache, it will be transferred in one of the offload threads. 65 | 66 | The Future 67 | ********** 68 | 69 | The offloading subsystem has a great potential, you can think of it as a software DMA: you program it, and then it goes alone. 70 | 71 | Currently it is pretty monolithic, but the idea is to allow more complex plugins (a redis one is in the works). 72 | 73 | Next step is allowing the user to "program" it via the uwsgi api. 74 | 75 | -------------------------------------------------------------------------------- /OpenBSDhttpd.rst: -------------------------------------------------------------------------------- 1 | Using OpenBSD httpd as proxy 2 | ============================ 3 | 4 | Starting from version 5.7 OpenBSD includes a minimal (truly minimal) web server with FastCGI support 5 | 6 | (http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/httpd.8?query=httpd&sec=8) 7 | 8 | The first step to enable it is writing its configuration file ```/etc/httpd.conf``` 9 | 10 | .. code-block:: c 11 | 12 | server "default" { 13 | listen on 0.0.0.0 port 80 14 | 15 | fastcgi socket tcp 127.0.0.1 3031 16 | } 17 | 18 | then enable and start it with the ```rcctl``` tool: 19 | 20 | .. code-block:: sh 21 | 22 | rcctl enable httpd 23 | rcctl start httpd 24 | 25 | this minimal configuration will spawn a chrooted webserver on port 80, running as user 'www' and forwarding every request to the address 127.0.0.1:3031 using the FastCGI protocol. 26 | 27 | 28 | Now you only need to spawn uWSGI on the FastCGI address: 29 | 30 | .. code-block:: ini 31 | 32 | [uwsgi] 33 | fastcgi-socket = 127.0.0.1:3031 34 | ; a simple python app (eventually remember to load the python plugin) 35 | wsgi-file = app.py 36 | 37 | 38 | you can obviously use uWSGI as a full-featured CGI server (well, effectively it has way more features than every cgi server out there :P), 39 | just remember to force the modifier1 to the '9' one: 40 | 41 | .. code-block:: ini 42 | 43 | [uwsgi] 44 | fastcgi-socket = 127.0.0.1:3031 45 | fastcgi-modifier1 = 9 46 | ; a simple cgi-bin directory (eventually remember to load the cgi plugin) 47 | cgi = /var/www/cgi-bin 48 | 49 | now you can place your cgi scripts in /var/www/cgi-bin (remember to give them the executable permission) 50 | 51 | You can use UNIX domain sockets too, just remember the httpd servers runs chrooted in /var/www so you have to bind uWSGI sockets in a dir under it: 52 | 53 | .. code-block:: ini 54 | 55 | [uwsgi] 56 | fastcgi-socket = /var/www/run/uwsgi.socket 57 | fastcgi-modifier1 = 9 58 | ; a simple cgi-bin directory 59 | cgi = /var/www/cgi-bin 60 | 61 | .. code-block:: c 62 | 63 | server "default" { 64 | listen on 0.0.0.0 port 80 65 | 66 | fastcgi socket "/run/uwsgi.socket" 67 | } 68 | 69 | 70 | If you want to forward only specific paths to uWSGI, you can use a location directive: 71 | 72 | .. code-block:: c 73 | 74 | server "default" { 75 | listen on 0.0.0.0 port 80 76 | 77 | location "/foo/*" { 78 | fastcgi socket tcp 127.0.0.1 3031 79 | } 80 | 81 | location "/cgi-bin/*" { 82 | fastcgi socket tcp 128.0.0.1 3032 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /ParsingOrder.rst: -------------------------------------------------------------------------------- 1 | How uWSGI parses config files 2 | ============================= 3 | 4 | Until uWSGI 1.1 the parsing order has not been 'stable' or 'reliable'. 5 | 6 | Starting from uWSGI 1.1 (thanks to its new options subsystem) we have a general rule: top-bottom and expand asap. 7 | 8 | Top-bottom means options are internally ordered as they are parsed, while "expand asap" means to inject the options of a requested config file, interrupting the currently parsed one: 9 | 10 | Note that the ``inherit`` option behaves differently from the other include options: It is expanded *after* variable expansion, so any environment variables, external files and placeholders are *not* expanded. Magic variables (*e.g.* ``%n``) are expanded normally. 11 | 12 | file1.ini (the one requested from the command line) 13 | 14 | 15 | .. code-block:: ini 16 | 17 | [uwsgi] 18 | socket = :3031 19 | ini = file2.ini 20 | socket = :3032 21 | chdir = /var/www 22 | 23 | file2.ini 24 | 25 | .. code-block:: ini 26 | 27 | [uwsgi] 28 | master = true 29 | memory-report = true 30 | processes = 4 31 | 32 | internally will be assembled in: 33 | 34 | 35 | .. code-block:: ini 36 | 37 | [uwsgi] 38 | socket = :3031 39 | ini = file2.ini 40 | master = true 41 | memory-report = true 42 | processes = 4 43 | socket = :3032 44 | chdir = /var/www 45 | 46 | A more complex example: 47 | 48 | file1.ini (the one requested from the command line) 49 | 50 | .. code-block:: ini 51 | 52 | [uwsgi] 53 | socket = :3031 54 | ini = file2.ini 55 | socket = :3032 56 | chdir = /var/www 57 | 58 | file2.ini 59 | 60 | .. code-block:: ini 61 | 62 | [uwsgi] 63 | master = true 64 | xml = file3.xml 65 | memory-report = true 66 | processes = 4 67 | 68 | file3.xml 69 | 70 | .. code-block:: xml 71 | 72 | 73 | router_uwsgi 74 | ^/foo uwsgi:127.0.0.1:4040,0,0 75 | 76 | 77 | will result in: 78 | 79 | .. code-block:: ini 80 | 81 | [uwsgi] 82 | socket = :3031 83 | ini = file2.ini 84 | master = true 85 | xml = file3.xml 86 | plugins = router_uwsgi 87 | route = ^/foo uwsgi:127.0.0.1:4040,0,0 88 | memory-report = true 89 | processes = 4 90 | socket = :3032 91 | chdir = /var/www 92 | 93 | 94 | Expanding variables/placeholders 95 | ******************************** 96 | 97 | After the internal config tree is assembled, variables and placeholder substitution will be applied. 98 | 99 | The first step is substituting all of the $(VALUE) occurrences with the value of the environment variable VALUE. 100 | 101 | .. code-block:: ini 102 | 103 | [uwsgi] 104 | foobar = $(PATH) 105 | 106 | foobar value will be the content of shell's PATH variable 107 | 108 | The second step will expand text files embraced in @(FILENAME) 109 | 110 | .. code-block:: ini 111 | 112 | [uwsgi] 113 | nodename = @(/etc/hostname) 114 | 115 | nodename value will be the content of /etc/hostname 116 | 117 | The last step is placeholder substitution. A placeholder is a reference to another option: 118 | 119 | .. code-block:: ini 120 | 121 | [uwsgi] 122 | socket = :3031 123 | foobar = %(socket) 124 | 125 | 126 | the content of foobar will be mapped to the content of socket. 127 | 128 | A note on magic variables 129 | ************************* 130 | 131 | Config files, support another form of variables, called 'magic' variables. As they refer to the config file itself, they will be parsed asap: 132 | 133 | 134 | .. code-block:: ini 135 | 136 | [uwsgi] 137 | my_config_file = %p 138 | 139 | 140 | The content of my_config_file will be set to %p value (the current file's absolute path) as soon as it is parsed. That means %p (or whatever magic vars you need) will be always be consistent in the currently parsing config file. 141 | -------------------------------------------------------------------------------- /Pty.rst: -------------------------------------------------------------------------------- 1 | The Pty plugin 2 | ============== 3 | 4 | - Available since uWSGI 1.9.15, supported on Linux, OpenBSD, FreeBSD and OSX 5 | 6 | This plugin allows you to attach pseudo terminals to your applications. 7 | 8 | Currently the pseudoterminal server can be attached (and exposed over network) only on the first worker 9 | (this limit will be removed in the future). 10 | 11 | The plugin exposes a client mode too (avoiding you to mess with netcat, telnet or screen settings) 12 | 13 | 14 | Building it 15 | *********** 16 | 17 | The plugin is not included in the default build profiles, so you have to build it manually: 18 | 19 | .. code-block:: sh 20 | 21 | python uwsgiconfig.py --plugin plugins/pty [profile] 22 | 23 | (remember to specify the build profile if you are not using the default one) 24 | 25 | Example 1: Rack application shared debugging 26 | ******************************************** 27 | 28 | .. code-block:: sh 29 | 30 | UWSGI_PROFILE=ruby2 UWSGI_EMBED_PLUGINS=pty make 31 | 32 | .. code-block:: sh 33 | 34 | ./uwsgi --rbshell="require 'pry';binding.pry" --socket /tmp/foo.socket --master --pty-socket :5000 35 | 36 | .. code-block:: sh 37 | 38 | ./uwsgi --pty-connect :5000 39 | 40 | Example 2: IPython control thread 41 | ********************************* 42 | 43 | .. code-block:: py 44 | 45 | import IPython 46 | from uwsgidecorators import * 47 | 48 | # only worker 1 has the pty attached 49 | @postfork(1) 50 | @thread 51 | def tshell(): 52 | while True: 53 | IPython.embed() 54 | 55 | 56 | -------------------------------------------------------------------------------- /PushingStats.rst: -------------------------------------------------------------------------------- 1 | Pushing statistics (from 1.4) 2 | ============================= 3 | 4 | IMPORTANT: the Metrics subsystem offers a better introduction to the following concepts. See :doc:`Metrics` 5 | 6 | Starting from uWSGI 1.4 you can push statistics (the same JSON blob you get with the :doc:`StatsServer`) 7 | via various systems (called stats pushers). 8 | 9 | Statistics are pushed at regular intervals (default 3 seconds). 10 | 11 | The 'file' stats pusher 12 | *********************** 13 | 14 | By default the 'file' stats pusher is available up to 1.9.18. Starting from 1.9.19 is available as a plugin (stats_pusher_file). 15 | 16 | It allows you to save json chunks to a file (open in appended mode) 17 | 18 | .. code-block:: ini 19 | 20 | [uwsgi] 21 | socket = :3031 22 | module = foobar 23 | master = true 24 | stats-push = file:path=/tmp/foobar,freq=10 25 | 26 | this config will append JSON to the /tmp/foobar file every 10 seconds 27 | 28 | 29 | The 'mongodb' stats pusher 30 | ************************** 31 | 32 | This is the first developed stats pusher plugin, allowing you to store JSON 33 | data directly on a mongodb collection 34 | 35 | .. code-block:: ini 36 | 37 | [uwsgi] 38 | plugins = stats_pusher_mongodb 39 | socket = :3031 40 | module = foobar 41 | master = true 42 | stats-push = mongodb:addr=127.0.0.1:5151,collection=uwsgi.mystats,freq=4 43 | 44 | This config will insert JSON data to the collection uwsgi.mystats on the mongodb server 127.0.0.1:5151 45 | every 4 seconds. 46 | 47 | To build the plugin you need mongodb development headers (mongodb-dev on Debian/Ubuntu) 48 | 49 | .. code-block:: sh 50 | 51 | python uwsgiconfig.py --plugin plugins/stats_pusher_mongodb 52 | 53 | will do the trick 54 | 55 | 56 | Notes 57 | ***** 58 | 59 | You can configure all of the stats pusher you need, just specify multiple stats-push options 60 | 61 | .. code-block:: ini 62 | 63 | [uwsgi] 64 | plugins = stats_pusher_mongodb 65 | socket = :3031 66 | module = foobar 67 | master = true 68 | stats-push = mongodb:addr=127.0.0.1:5151,collection=uwsgi.mystats,freq=4 69 | stats-push = mongodb:addr=127.0.0.1:5152,collection=uwsgi.mystats,freq=4 70 | stats-push = mongodb:addr=127.0.0.1:5153,collection=uwsgi.mystats,freq=4 71 | stats-push = mongodb:addr=127.0.0.1:5154,collection=uwsgi.mystats,freq=4 72 | 73 | -------------------------------------------------------------------------------- /PythonModuleAlias.rst: -------------------------------------------------------------------------------- 1 | Aliasing Python modules 2 | ======================= 3 | 4 | Having multiple version of a Python package/module/file is very common. 5 | 6 | Manipulating PYTHONPATH or using virtualenvs are a way to use various versions without changing your code. 7 | 8 | But hey, why not have an aliasing system that lets you arbitrarily map module names to files? That's why we have the ``pymodule-alias`` option! 9 | 10 | 11 | Case 1 - Mapping a simple file to a virtual module 12 | -------------------------------------------------- 13 | 14 | Let's say we have ``swissknife.py`` that contains lots of useful classes and functions. 15 | 16 | It's imported in gazillions of places in your app. Now, we'll want to modify it, but keep the original file intact for whichever reason, and call it ``swissknife_mk2``. 17 | 18 | Your options would be 19 | 20 | 1) to modify all of your code to import and use swissknife_mk2 instead of swissknife. Yeah, no, not's going to happen. 21 | 2) modify the first line of all your files to read ``import swissknife_mk2 as swissknife``. A lot better but you make software for money... and time is money, so why the fuck not use something more powerful? 22 | 23 | So don't touch your files -- just remap! 24 | 25 | .. code-block:: sh 26 | 27 | ./uwsgi -s :3031 -w myproject --pymodule-alias swissknife=swissknife_mk2 28 | # Kapow! uWSGI one-two ninja punch right there! 29 | # You can put the module wherever you like, too: 30 | ./uwsgi -s :3031 -w myproject --pymodule-alias swissknife=/mnt/floppy/KNIFEFAC/SWISSK~1.PY 31 | # Or hey, why not use HTTP? 32 | ./uwsgi -s :3031 -w myproject --pymodule-alias swissknife=http://uwsgi.it/modules/swissknife_extreme.py 33 | 34 | You can specify multiple ``pymodule-alias`` directives. 35 | 36 | .. code-block:: yaml 37 | 38 | uwsgi: 39 | socket: :3031 40 | module: myproject 41 | pymodule-alias: funnymodule=/opt/foo/experimentalfunnymodule.py 42 | pymodule-alias: uglymodule=/opt/foo/experimentaluglymodule.py 43 | 44 | 45 | Case 2 - mapping a packages to directories 46 | ------------------------------------------ 47 | 48 | You have this shiny, beautiful Django project and something occurs to you: Would it work with Django trunk? On to set up a new virtualenv... nah. Let's just use ``pymodule-alias``! 49 | 50 | .. code-block:: py 51 | 52 | ./uwsgi -s :3031 -w django_uwsgi --pymodule-alias django=django-trunk/django 53 | 54 | 55 | Case 3 - override specific submodules 56 | ------------------------------------- 57 | 58 | You have a Werkzeug project where you want to override - for whichever reason - ``werkzeug.test_app`` with one of your own devising. Easy, of course! 59 | 60 | .. code-block:: python 61 | 62 | ./uwsgi -s :3031 -w werkzeug.testapp:test_app() --pymodule-alias werkzeug.testapp=mytestapp -------------------------------------------------------------------------------- /PythonPump.rst: -------------------------------------------------------------------------------- 1 | Pump support 2 | ============ 3 | 4 | .. note:: Pump is not a PEP nor a standard. 5 | 6 | Pump_ is a new project aiming at a "better" WSGI. 7 | 8 | An example Pump app, for your convenience: 9 | 10 | .. code-block:: python 11 | 12 | def app(req): 13 | return { 14 | "status": 200, 15 | "headers": {"content_type": "text/html"}, 16 | "body": "

Hello!

" 17 | } 18 | 19 | To load a Pump app simply use the ``pump`` option to declare the callable. 20 | 21 | .. code-block:: sh 22 | 23 | uwsgi --http-socket :8080 -M -p 4 --pump myapp:app 24 | 25 | ``myapp`` is the name of the module (that must be importable!) and app is the callable. The callable part is optional -- by default uWSGI will search for a callable named 'application'. 26 | 27 | .. _Pump: http://adeel.github.com/pump/ -------------------------------------------------------------------------------- /Queue.rst: -------------------------------------------------------------------------------- 1 | The uWSGI queue framework 2 | ========================= 3 | 4 | In addition to the :doc:`caching framework `, uWSGI includes a shared queue. 5 | 6 | At the low level it is a simple block-based shared array, with two optional counters, one for stack-style, LIFO usage, the other one for FIFO. 7 | 8 | The array is circular, so when one of the two pointers reaches the end (or the beginning), it is reset. Remember this! 9 | 10 | To enable the queue, use the ``queue`` option. Queue blocks are 8 KiB by default. Use ``queue-blocksize`` to change this. 11 | 12 | .. code-block:: sh 13 | 14 | # 100 slots, 8 KiB of data each 15 | uwsgi --socket :3031 --queue 100 16 | # 42 slots, 128 KiB of data each 17 | uwsgi --socket :3031 --queue 42 --queue-blocksize 131072 18 | 19 | Using the queue as a shared array 20 | --------------------------------- 21 | 22 | .. code-block:: py 23 | 24 | # Put a binary string in slot 17. 25 | uwsgi.queue_set(17, "Hello, uWSGI queue!") 26 | 27 | # Get it back. 28 | print uwsgi.queue_get(17) 29 | 30 | 31 | Using the queue as a shared stack 32 | --------------------------------- 33 | 34 | .. warning:: Remember that :py:meth:`uwsgi.queue_pop` and :py:meth:`uwsgi.queue_last` will remove the item or items from the queue. 35 | 36 | .. code-block:: py 37 | 38 | # Push a value onto the end of the stack. 39 | uwsgi.queue_push("Hello, uWSGI stack!") 40 | 41 | # Pop it back 42 | print uwsgi.queue_pop() 43 | 44 | # Get the number of the next available slot in the stack 45 | print uwsgi.queue_slot() 46 | 47 | # Pop the last N items from the stack 48 | items = uwsgi.queue_last(3) 49 | 50 | Using the queue as a FIFO queue 51 | ------------------------------- 52 | 53 | .. note:: Currently you can only pull, not push. To enqueue an item, use :py:meth:`uwsgi.queue_set`. 54 | 55 | .. code-block:: py 56 | 57 | # Grab an item from the queue 58 | uwsgi.queue_pull() 59 | # Get the current pull/slot position (this is independent from the stack-based one) 60 | print uwsgi.queue_pull_slot() 61 | 62 | Notes 63 | ----- 64 | 65 | * You can get the queue size with :py:data:`uwsgi.queue_size`. 66 | * Use the ``queue-store`` option to persist the queue on disk. Use ``queue-store-sync`` (in master cycles -- usually seconds) to force disk syncing of the queue. 67 | * The ``tests/queue.py`` application is a fully working example. -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | index.rst -------------------------------------------------------------------------------- /SNI.rst: -------------------------------------------------------------------------------- 1 | SNI - Server Name Identification (virtual hosting for SSL nodes) 2 | ================================================================ 3 | 4 | uWSGI 1.9 (codenamed "ssl as p0rn") added support for SNI (Server Name Identification) throughout the whole 5 | SSL subsystem. The HTTPS router, the SPDY router and the SSL router can all use it transparently. 6 | 7 | SNI is an extension to the SSL standard which allows a client to specify a "name" for the resource 8 | it wants. That name is generally the requested hostname, so you can implement virtual hosting-like behavior like you do using the HTTP ``Host:`` header without requiring extra IP addresses etc. 9 | 10 | In uWSGI an SNI object is composed of a name and a value. The name is the servername/hostname while the value is the "SSL context" (you can think of it as the sum of certificates, key and ciphers for a particular domain). 11 | 12 | Adding SNI objects 13 | ****************** 14 | 15 | To add an SNI object just use the ``--sni`` option: 16 | 17 | .. code-block:: sh 18 | 19 | --sni crt,key[,ciphers,client_ca] 20 | 21 | For example: 22 | 23 | .. code-block:: sh 24 | 25 | --sni "unbit.com unbit.crt,unbit.key" 26 | 27 | or for client-based SSL authentication and OpenSSL HIGH cipher levels 28 | 29 | .. code-block:: sh 30 | 31 | --sni "secure.unbit.com unbit.crt,unbit.key,HIGH,unbit.ca" 32 | 33 | Adding complex SNI objects 34 | ************************** 35 | 36 | Sometimes you need more complex keys for your SNI objects (like when using wildcard certificates) 37 | 38 | If you have built uWSGI with PCRE/regexp support (as you should) you can use the ``--sni-regexp`` option. 39 | 40 | .. code-block:: sh 41 | 42 | --sni-regexp "*.unbit.com unbit.crt,unbit.key,HIGH,unbit.ca" 43 | 44 | Massive SNI hosting 45 | ******************* 46 | 47 | One of uWSGI's main purposes is massive hosting, so SSL without support for that would be pretty annoying. 48 | 49 | If you have dozens (or hundreds, for that matter) of certificates mapped to the same IP address you can simply put them in a directory (following a simple convention we'll elaborate in a bit) and let uWSGI scan it whenever it needs to find a context for a domain. 50 | 51 | To add a directory just use 52 | 53 | .. code-block:: sh 54 | 55 | --sni-dir 56 | 57 | like 58 | 59 | .. code-block:: sh 60 | 61 | --sni-dir /etc/customers/certificates 62 | 63 | Now, if you have ``unbit.com`` and ``example.com`` certificates (.crt) and keys (.key) just drop them in there following these naming rules: 64 | 65 | * ``/etc/customers/certificates/unbit.com.crt`` 66 | * ``/etc/customers/certificates/unbit.com.key`` 67 | * ``/etc/customers/certificates/unbit.com.ca`` 68 | * ``/etc/customers/certificates/example.com.crt`` 69 | * ``/etc/customers/certificates/example.com.key`` 70 | 71 | As you can see, ``example.com`` has no .ca file, so client authentication will be disabled for it. 72 | 73 | If you want to force a default cipher set to the SNI contexts, use 74 | 75 | .. code-block:: sh 76 | 77 | --sni-dir-ciphers HIGH 78 | 79 | (or whatever other value you need) 80 | 81 | Note: Unloading SNI objects is not supported. Once they are loaded into memory they will be held onto until reload. 82 | 83 | Subscription system and SNI 84 | *************************** 85 | 86 | uWSGI 2.0 added support for SNI in the subscription system. 87 | 88 | The https/spdy router and the sslrouter can dynamically load certificates and keys from the paths specified in a subscription packet: 89 | 90 | .. code-block:: sh 91 | 92 | uwsgi --subscribe2 key=mydomain.it,socket=0,sni_key=/foo/bar.key,sni_crt=/foo/bar.crt 93 | 94 | 95 | the router will create a new SSL context based on the specified files (be sure the router can reach them) and will destroy it when the last node 96 | disconnect. 97 | 98 | This is useful for massive hosting where customers have their certificates in the home and you want them the change/update those files without bothering you. 99 | 100 | .. note:: 101 | 102 | We understand that directly encapsulating keys and cert in the subscription packets will be much more useful, but network transfer of keys is something 103 | really foolish from a security point of view. We are investigating if combining it with the secured subscription system (where each packet is encrypted) could be a solution. 104 | -------------------------------------------------------------------------------- /SNMP.rst: -------------------------------------------------------------------------------- 1 | The embedded SNMP server 2 | ======================== 3 | 4 | The uWSGI server embeds a tiny SNMP server that you can use to integrate your web apps with your monitoring infrastructure. 5 | 6 | To enable SNMP support, you must run the uWSGI UDP server and choose a SNMP community string (which is the rudimentary authentication system used by SNMP). 7 | 8 | .. code-block:: sh 9 | 10 | ./uwsgi -s :3031 -w staticfilesnmp --udp 192.168.0.1:2222 --snmp --snmp-community foo 11 | # or the following. Using the SNMP option to pass the UDP address is a lot more elegant. ;) 12 | ./uwsgi -s :3031 -w myapp --master --processes 4 --snmp=192.168.0.1:2222 --snmp-community foo 13 | 14 | This will run the uWSGI server on TCP port 3031 and UDP port 2222 with SNMP enabled with "foo" as the community string. 15 | 16 | Please note that the SNMP server is started in the master process after dropping the privileges. If you want it to listen on a privileged port, you can either use :doc:`Capabilities` on Linux, or use the ``master-as-root`` option to run the master process as root. The :file:`staticfilesnmp.py` file is included in the distribution and is a simple app that exports a counter via SNMP. 17 | 18 | The uWSGI SNMP server exports 2 group of information: 19 | 20 | * General information is managed by the uWSGI server itself. The base OID to access uWSGI SNMP information is ``1.3.6.1.4.1.35156.17`` (``iso.org.dod.internet.private.enterprise.unbit.uwsgi``). General options are mapped to ``1.3.6.1.4.1.35156.17.1.x``. 21 | * Custom information is managed by the apps and accessed via ``1.3.6.1.4.1.35156.17.2.x`` 22 | 23 | So, to get the number of requests managed by the uWSGI server, you could do 24 | 25 | .. code-block:: sh 26 | 27 | snmpget -v2c -c foo 192.168.0.1:2222 1.3.6.1.4.1.35156.17.1.1 # 1.1 corresponds to ``general.requests`` 28 | 29 | Exporting custom values 30 | ----------------------- 31 | 32 | To manage custom values from your app you have these Python functions, 33 | 34 | * :py:func:`uwsgi.snmp_set_counter32` 35 | * :py:func:`uwsgi.snmp_set_counter64` 36 | * :py:func:`uwsgi.snmp_set_gauge` 37 | * :py:func:`uwsgi.snmp_incr_counter32` 38 | * :py:func:`uwsgi.snmp_incr_counter64` 39 | * :py:func:`uwsgi.snmp_incr_gauge` 40 | * :py:func:`uwsgi.snmp_decr_counter32` 41 | * :py:func:`uwsgi.snmp_decr_counter64` 42 | * :py:func:`uwsgi.snmp_decr_gauge` 43 | 44 | So if you wanted to export the number of users currently logged in (this is a gauge as it can lower) as custom OID 40, you'd call 45 | 46 | .. code-block:: python 47 | 48 | users_logged_in = random.randint(0, 1024) # a more predictable source of information would be better. 49 | uwsgi.snmp_set_gauge(40, users_logged_in) 50 | 51 | and to look it up, 52 | 53 | .. code-block:: sh 54 | 55 | snmpget -v2c -c foo 192.168.0.1:2222 1.3.6.1.4.1.35156.17.2.40 56 | 57 | The system snmp daemon (net-snmp) can be configured to proxy SNMP requests to uwsgi. This allows you to run the system daemon and uwsgi at the same time, and runs all SNMP requests through the system daemon first. To configure the system snmp daemon (net-snmp) to proxy connections to uwsgi, add these lines to the bottom of /etc/snmp/snmpd.conf and restart the daemon: 58 | 59 | .. code-block:: sh 60 | 61 | proxy -v 2c -c foo 127.0.0.1:2222 .1.3.6.1.4.1.35156.17 62 | view systemview included .1.3.6.1.4.1.35156.17 63 | 64 | Replace 'foo' and '2222' with the community and port configured in uwsgi. 65 | 66 | -------------------------------------------------------------------------------- /SPDY.rst: -------------------------------------------------------------------------------- 1 | The SPDY router (uWSGI 1.9) 2 | =========================== 3 | 4 | Starting from uWSGI 1.9 the HTTPS router has been extended to support version 3 of the SPDY protocol. 5 | 6 | To run the HTTPS router with SPDY support, use the ``--https2`` option: 7 | 8 | .. code-block:: sh 9 | 10 | uwsgi --https2 addr=0.0.0.0:8443,cert=foobart.crt,key=foobar.key,spdy=1 --module werkzeug.testapp:test_app 11 | 12 | This will start an HTTPS router on port 8443 with SPDY support, forwarding requests to the Werkzeug's test app the instance is running. 13 | If you'll go to https://address:8443/ with a SPDY-enabled browser, you will see additional WSGI variables reported by 14 | `Werkzeug `_: 15 | 16 | * ``SPDY`` -- ``on`` 17 | * ``SPDY.version`` -- protocol version (generally ``3``) 18 | * ``SPDY.stream`` -- stream identifier (an odd number). 19 | 20 | Opening privileged ports as a non-root user will require the use of the `shared-socket` option and a slightly different syntax: 21 | 22 | .. code-block:: sh 23 | 24 | uwsgi --shared-socket :443 --https2 addr==0,cert=foobart.crt,key=foobar.key,spdy=1 --module werkzeug.testapp:test_app --uid user 25 | 26 | Both HTTP and HTTPS can be used at the same time (`=0` and `=1` are references to the privileged ports opened by `shared-socket` commands): 27 | 28 | .. code-block:: sh 29 | 30 | uwsgi --shared-socket :80 --shared-socket :443 --http =0 --https2 addr==1,cert=foobart.crt,key=foobar.key,spdy=1 --module werkzeug.testapp:test_app --uid user 31 | 32 | 33 | Notes 34 | ***** 35 | 36 | * You need at least OpenSSL 1.x to use SPDY (all modern Linux distributions should have it). 37 | * During uploads, the window size is constantly updated. 38 | * The ``--http-timeout`` directive is used to set the SPDY timeout. This is the maximum amount of inactivity after the SPDY connection is closed. 39 | * ``PING`` requests from the browsers are **all** acknowledged. 40 | * On connect, the SPDY router sends a settings packet to the client with optimal values. 41 | * If a stream fails in some catastrophic way, the whole connection is closed hard. 42 | * ``RST`` messages are always honoured. 43 | 44 | TODO 45 | **** 46 | 47 | * Add old SPDY v2 support (is it worth it?) 48 | * Allow PUSHing of resources from the uWSGI cache 49 | * Allow tuning internal buffers 50 | -------------------------------------------------------------------------------- /SPNEGO.rst: -------------------------------------------------------------------------------- 1 | SPNEGO authentication 2 | ===================== 3 | -------------------------------------------------------------------------------- /SSI.rst: -------------------------------------------------------------------------------- 1 | SSI (Server Side Includes) plugin 2 | ================================= 3 | 4 | Server Side Includes are an "old-fashioned" way to write dynamic web pages. 5 | 6 | It is generally recognized as a templating system instead of a full featured language. 7 | 8 | The main purpose of the uWSGI SSI plugin is to have a fast templating system that has access to the uWSGI API. 9 | 10 | At the time of writing, March 2013, the plugin is beta quality and implements less than 30% of the SSI standard, the focus being in exposing uWSGI API as SSI commands. 11 | 12 | Using it as a request handler 13 | ***************************** 14 | 15 | The plugin has an official modifier1, number 19. 16 | 17 | .. code-block:: ini 18 | 19 | [uwsgi] 20 | plugin = ssi 21 | http = :9090 22 | http-modifier1 = 19 23 | http-var = DOCUMENT_ROOT=/var/www 24 | 25 | The plugin builds the filename as ``DOCUMENT_ROOT``+``PATH_INFO``. This file is then parsed as a server side include document. 26 | 27 | Both ``DOCUMENT_ROOT`` and ``PATH_INFO`` are required, otherwise a 500 error will be returned. 28 | 29 | An example configuration for Nginx would be: 30 | 31 | .. code-block:: c 32 | 33 | location ~ \.shtml$ { 34 | root /var/www; 35 | include uwsgi_params; 36 | uwsgi_pass 127.0.0.1:3031; 37 | uwsgi_modifier1 19; 38 | } 39 | 40 | with something like this for uWSGI... 41 | 42 | .. code-block:: ini 43 | 44 | [uwsgi] 45 | plugin = ssi 46 | socket = 127.0.0.1:3031 47 | 48 | Using SSI as a routing action 49 | ***************************** 50 | 51 | A more versatile approach is using the SSI parser as a routing action. 52 | 53 | .. code-block:: ini 54 | 55 | [uwsgi] 56 | plugin = ssi 57 | http-socket = :9090 58 | route = ^/(.*) ssi:/var/www/$1.shtml 59 | 60 | .. warning:: As with all of the routing actions, no check on file paths is made to allow a higher level of customization. If you pass untrusted paths to the SSI action, you should sanitize them (you can use routing again, checking for the presence of .. or other dangerous symbols). 61 | 62 | And with the above admonition in mind, when used as a routing action, ``DOCUMENT_ROOT`` or ``PATH_INFO`` are not required, as the parameter passed contains the full filesystem path. 63 | 64 | Supported SSI commands 65 | ********************** 66 | 67 | This is the list of supported commands (and their arguments). If a command is not part of the SSI standard (that is, it's uWSGI specific) it will be reported. 68 | 69 | echo 70 | ^^^^ 71 | 72 | Arguments: ``var`` 73 | 74 | Print the content of the specified request variable. 75 | 76 | printenv 77 | ^^^^^^^^ 78 | 79 | Print a list of all request variables. 80 | 81 | include 82 | ^^^^^^^ 83 | 84 | Arguments: ``file`` 85 | 86 | Include the specified file (relative to the current directory). 87 | 88 | cache 89 | ^^^^^ 90 | 91 | .. note:: This is uWSGI specific/non-standard. 92 | 93 | Arguments: ``key`` ``name`` 94 | 95 | Print the value of the specified cache key in the named cache. 96 | 97 | Status 98 | ****** 99 | 100 | * The plugin is fully thread safe and very fast. 101 | * Very few commands are available, more will be added soon. 102 | -------------------------------------------------------------------------------- /SupportedPlatforms.rst: -------------------------------------------------------------------------------- 1 | Supported Platforms/Systems 2 | =========================== 3 | 4 | This is the list of officially supported operating systems and platforms. 5 | 6 | 7 | * Linux 2.6/3.x 8 | * FreeBSD 9 | * NetBSD 10 | * OpenBSD 11 | * DragonFlyBSD 12 | * Windows Cygwin 13 | * Mac OSX 14 | * Solaris >= 10 15 | * NexentaOS 16 | * SmartOS 17 | * OpenSolaris 18 | * OpenIndiana 19 | * OmniOS 20 | * Debian/kFreeBSD 21 | * GNU/Hurd 22 | -------------------------------------------------------------------------------- /Tracebacker.rst: -------------------------------------------------------------------------------- 1 | Python Tracebacker 2 | ================== 3 | 4 | .. versionadded:: 1.3-dev 5 | 6 | Usually if you want to get a real-time traceback from your app you'd have to modify your code to add a hook or entry point for that as described on the :doc:`TipsAndTricks` page. 7 | 8 | Starting from 1.3-dev, uWSGI includes a similar technique allowing you to get realtime traceback via a UNIX socket. 9 | 10 | To enable the tracebacker, add the option ``py-tracebacker=`` where ```` is the _basename_ for the created UNIX sockets. 11 | 12 | If you have 4 uWSGI workers and you add ``py-tracebacker=/tmp/tbsocket``, four sockets named ``/tmp/tbsocket1`` through ``/tmp/tbsocket4`` will be created. 13 | 14 | Connecting to one of them will return the current traceback of the threads running in the worker. To connect to those sockets you can use whatever application or method you like the best, but uWSGI includes a convenience option ``connect-and-read`` you can use:: 15 | 16 | uwsgi --connect-and-read /tmp/tbsocket1 17 | 18 | An example 19 | ---------- 20 | 21 | Let's write a silly test application called ``slow.py``: 22 | 23 | .. code-block:: python 24 | 25 | import time 26 | 27 | def dormi(): 28 | time.sleep(60) 29 | 30 | def dormi2(): 31 | dormi() 32 | 33 | def dormi3(): 34 | dormi2() 35 | 36 | def dormi4(): 37 | dormi3() 38 | 39 | def dormi5(): 40 | dormi4() 41 | 42 | def application(e, start_response): 43 | start_response('200 OK', [('Content-Type', 'text/html')]) 44 | dormi5() 45 | return "hello" 46 | 47 | And then run it:: 48 | 49 | uwsgi --http :8080 -w slow --master --processes 2 --threads 4 --py-tracebacker /tmp/tbsocket. 50 | 51 | Then make a bunch of requests into it:: 52 | 53 | curl http://localhost:8080 & 54 | curl http://localhost:8080 & 55 | curl http://localhost:8080 & 56 | curl http://localhost:8080 & 57 | 58 | Now, while these requests are running (they'll take pretty much exactly a minute to complete each), you can retrieve the traceback for, let's say, the two first workers:: 59 | 60 | ./uwsgi --connect-and-read /tmp/tbsocket.1 61 | ./uwsgi --connect-and-read /tmp/tbsocket.2 62 | 63 | The tracebacker output will be something like this:: 64 | 65 | *** uWSGI Python tracebacker output *** 66 | 67 | thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 22 function = application line = dormi5() 68 | thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 14 function = dormi5 line = def dormi5(): dormi4() 69 | thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 13 function = dormi4 line = def dormi4(): dormi3() 70 | thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 12 function = dormi3 line = def dormi3(): dormi2() 71 | thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 11 function = dormi2 line = def dormi2(): dormi() 72 | thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 9 function = dormi line = time.sleep(60) 73 | 74 | thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 22 function = application line = dormi5() 75 | thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 14 function = dormi5 line = def dormi5(): dormi4() 76 | thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 13 function = dormi4 line = def dormi4(): dormi3() 77 | thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 12 function = dormi3 line = def dormi3(): dormi2() 78 | thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 11 function = dormi2 line = def dormi2(): dormi() 79 | thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 9 function = dormi line = time.sleep(60) 80 | 81 | thread_id = MainThread filename = ./slow.py lineno = 22 function = application line = dormi5() 82 | thread_id = MainThread filename = ./slow.py lineno = 14 function = dormi5 line = def dormi5(): dormi4() 83 | thread_id = MainThread filename = ./slow.py lineno = 13 function = dormi4 line = def dormi4(): dormi3() 84 | thread_id = MainThread filename = ./slow.py lineno = 12 function = dormi3 line = def dormi3(): dormi2() 85 | thread_id = MainThread filename = ./slow.py lineno = 11 function = dormi2 line = def dormi2(): dormi() 86 | thread_id = MainThread filename = ./slow.py lineno = 9 function = dormi line = time.sleep(60) 87 | 88 | Combining the tracebacker with Harakiri 89 | --------------------------------------- 90 | 91 | If a request is killed by the :term:`harakiri` feature, a traceback is automatically logged during the Harakiri phase. -------------------------------------------------------------------------------- /Upstart.rst: -------------------------------------------------------------------------------- 1 | Running uWSGI via Upstart 2 | ========================= 3 | 4 | Upstart is the init system of Ubuntu-like distributions. 5 | 6 | It is based on declarative configuration files -- not shell scripts of yore -- that are put in the :file:`/etc/init` directory. 7 | 8 | A simple script (/etc/init/uwsgi.conf) 9 | -------------------------------------- 10 | 11 | .. code-block:: upstart 12 | 13 | # simple uWSGI script 14 | 15 | description "uwsgi tiny instance" 16 | start on runlevel [2345] 17 | stop on runlevel [06] 18 | 19 | respawn 20 | 21 | exec uwsgi --master --processes 4 --die-on-term --socket :3031 --wsgi-file /var/www/myapp.wsgi 22 | 23 | Using the Emperor 24 | ----------------- 25 | 26 | .. seealso:: :doc:`Emperor` 27 | 28 | A better approach than init files for each app would be to only start an Emperor via Upstart and let it deal with the rest. 29 | 30 | .. code-block:: upstart 31 | 32 | # Emperor uWSGI script 33 | 34 | description "uWSGI Emperor" 35 | start on runlevel [2345] 36 | stop on runlevel [06] 37 | 38 | respawn 39 | 40 | exec uwsgi --emperor /etc/uwsgi 41 | 42 | If you want to run the Emperor under the master process (for accessing advanced features) remember to add --die-on-term 43 | 44 | 45 | .. code-block:: upstart 46 | 47 | # Emperor uWSGI script 48 | 49 | description "uWSGI Emperor" 50 | start on runlevel [2345] 51 | stop on runlevel [06] 52 | 53 | respawn 54 | 55 | exec uwsgi --master --die-on-term --emperor /etc/uwsgi 56 | 57 | What is --die-on-term? 58 | ---------------------- 59 | 60 | By default uWSGI maps the SIGTERM signal to "a brutal reload procedure". 61 | 62 | However, Upstart uses SIGTERM to completely shutdown processes. ``die-on-term`` inverts the meanings of SIGTERM and SIGQUIT to uWSGI. 63 | 64 | The first will shutdown the whole stack, the second one will brutally reload it. 65 | 66 | Socket activation (from Ubuntu 12.04) 67 | ------------------------------------- 68 | 69 | Newer Upstart releases have an Inetd-like feature that lets processes start when connections are made to specific sockets. 70 | 71 | You can use this feature to start uWSGI only when a client (or the webserver) first connects to it. 72 | 73 | The 'start on socket' directive will trigger the behaviour. 74 | 75 | You do not need to specify the socket in uWSGI as it will be passed to it by Upstart itself. 76 | 77 | .. code-block:: upstart 78 | 79 | # simple uWSGI script 80 | 81 | description "uwsgi tiny instance" 82 | start on socket PROTO=inet PORT=3031 83 | stop on runlevel [06] 84 | 85 | respawn 86 | 87 | exec uwsgi --master --processes 4 --die-on-term --wsgi-file /var/www/myapp.wsgi 88 | 89 | -------------------------------------------------------------------------------- /V8.rst: -------------------------------------------------------------------------------- 1 | uWSGI V8 support 2 | ================ 3 | 4 | Building 5 | ******** 6 | 7 | You will need the ``libv8`` headers to build the plugin. The official modifier1 value for V8 is '24'. 8 | 9 | RPC 10 | *** 11 | 12 | .. code-block:: js 13 | 14 | function part1(request_uri, remote_addr) { 15 | return '

i am part1 for ' + request_uri + ' ' + remote_addr + "

" ; 16 | } 17 | 18 | function part2(request_uri, remote_addr) { 19 | return '

i am part2 for ' + request_uri + ' ' + remote_addr + "

" ; 20 | } 21 | 22 | function part3(request_uri, remote_addr) { 23 | return '

i am part3 for ' + request_uri + ' ' + remote_addr + "

" ; 24 | } 25 | 26 | uwsgi.register_rpc('part1', part1); 27 | uwsgi.register_rpc('part2', part2); 28 | uwsgi.register_rpc('part3', part3); 29 | 30 | ciao = function(saluta) { 31 | uwsgi.log("I have no idea what's going on."); 32 | return "Ciao Ciao"; 33 | } 34 | 35 | uwsgi.register_rpc('hello', ciao); 36 | 37 | 38 | Signal handlers 39 | *************** 40 | 41 | .. code-block:: js 42 | 43 | function tempo(signum) { 44 | uwsgi.log("e' passato 1 secondo"); 45 | } 46 | 47 | uwsgi.register_signal(17, '', tempo); 48 | 49 | Multitheading and multiprocess 50 | ****************************** 51 | 52 | Mules 53 | ***** 54 | 55 | 56 | The uWSGI API 57 | ************* 58 | 59 | JSGI 3.0 60 | ******** 61 | 62 | .. code-block:: js 63 | 64 | exports.app = function (request) { 65 | uwsgi.log("Hello! I am the app.\n"); 66 | uwsgi.log(request.scheme + ' ' + request.method + ' ' + request.scriptName + ' ' + request.pathInfo + ' ' + request.queryString + ' ' + request.host); 67 | uwsgi.log(request.serverSoftware); 68 | return { 69 | status: 200, 70 | headers: {"Content-Type": "text/plain", "Server": ["uWSGI", "v8/plugin"]}, 71 | body: ["Hello World!", "I am V8"] 72 | }; 73 | } 74 | 75 | .. code-block:: sh 76 | 77 | uwsgi --plugin v8 --v8-jsgi myapp.js --http-socket :8080 --http-socket-modifier1 24 78 | 79 | CommonJS 80 | ******** 81 | 82 | * Require: OK 83 | * Binary/B: NO 84 | * System/1.0: in progress 85 | * IO/A: NO 86 | * Filesystem/A: NO 87 | 88 | -------------------------------------------------------------------------------- /Vars.rst: -------------------------------------------------------------------------------- 1 | uwsgi protocol magic variables 2 | ============================== 3 | 4 | You can dynamically tune or configure various aspects of the uWSGI server using special variables passed by the web server (or in general by a uwsgi compliant client). 5 | 6 | * For Nginx, the ``uwsgi_param ;`` directive is used. 7 | * For Apache, the ``SetEnv `` directive is used. 8 | 9 | ``UWSGI_SCHEME`` 10 | ---------------- 11 | 12 | Set the URL scheme when it cannot be reliably determined. This may be used to force HTTPS (with the value ``https``), for instance. 13 | 14 | ``UWSGI_SCRIPT`` 15 | ---------------- 16 | 17 | Load the specified script as a new application mapped to ``SCRIPT_NAME``. The app will obviously only be loaded once, not on each request. 18 | 19 | :: 20 | 21 | uwsgi_param UWSGI_SCRIPT werkzeug.testapp:test_app; 22 | uwsgi_param SCRIPT_NAME /testapp; 23 | 24 | 25 | ``UWSGI_MODULE`` and ``UWSGI_CALLABLE`` 26 | --------------------------------------- 27 | 28 | Load a new app (defined as ``module:callable``) mapped into ``SCRIPT_NAME``. 29 | 30 | :: 31 | 32 | uwsgi_param UWSGI_MODULE werkzeug.testapp; 33 | uwsgi_param UWSGI_CALLABLE test_app; 34 | uwsgi_param SCRIPT_NAME /testapp; 35 | 36 | 37 | ``UWSGI_PYHOME`` 38 | ---------------- 39 | 40 | Dynamically set the Python :ref:`Virtualenv` for a :doc:`dynamic application`. 41 | 42 | .. seealso:: :ref:`DynamicVirtualenv` 43 | 44 | ``UWSGI_CHDIR`` 45 | --------------- 46 | 47 | ``chdir()`` to the specified directory before managing the request. 48 | 49 | ``UWSGI_FILE`` 50 | -------------- 51 | 52 | Load the specified file as a new dynamic app. 53 | 54 | ``UWSGI_TOUCH_RELOAD`` 55 | ---------------------- 56 | 57 | Reload the uWSGI stack when the specified file's modification time has changed since the last request. 58 | 59 | :: 60 | 61 | location / { 62 | include uwsgi_params; 63 | uwsgi_param UWSGI_TOUCH_RELOAD /tmp/touchme.foo; 64 | uwsgi_pass /tmp/uwsgi.sock; 65 | } 66 | 67 | ``UWSGI_CACHE_GET`` 68 | ------------------- 69 | 70 | .. seealso:: :doc:`Caching` 71 | 72 | Check the uWSGI cache for a specified key. If the value is found, it will be returned as raw HTTP output instead of the usual processing of the request. 73 | 74 | :: 75 | 76 | location / { 77 | include uwsgi_params; 78 | uwsgi_param UWSGI_CACHE_GET $request_uri; 79 | uwsgi_pass 127.0.0.1:3031; 80 | } 81 | 82 | 83 | ``UWSGI_SETENV`` 84 | ---------------- 85 | 86 | Set the specified environment variable for a new dynamic app. 87 | 88 | .. note:: To allow this in Python applications you need to enable the ``reload-os-env`` uWSGI option. 89 | 90 | Dynamically load a Django app without using a WSGI file/module:: 91 | 92 | location / { 93 | include uwsgi_params; 94 | uwsgi_param UWSGI_SCRIPT django.core.handlers.wsgi:WSGIHandler(); 95 | uwsgi_param UWSGI_CHDIR /mydjangoapp_path; 96 | uwsgi_param UWSGI_SETENV DJANGO_SETTINGS_MODULE=myapp.settings; 97 | } 98 | 99 | 100 | ``UWSGI_APPID`` 101 | --------------- 102 | 103 | .. note:: Available since 0.9.9. 104 | 105 | Bypass ``SCRIPT_NAME`` and :doc:`VirtualHosting` to let the user choose the mountpoint without limitations (or headaches). 106 | 107 | The concept is very generic: ``UWSGI_APPID`` is the identifier of an application. If it is not found in the internal list of apps, it will be loaded. 108 | 109 | :: 110 | 111 | server { 112 | server_name server001; 113 | location / { 114 | include uwsgi_params; 115 | uwsgi_param UWSGI_APPID myfunnyapp; 116 | uwsgi_param UWSGI_FILE /var/www/app1.py 117 | } 118 | } 119 | 120 | server { 121 | server_name server002; 122 | location / { 123 | include uwsgi_params; 124 | uwsgi_param UWSGI_APPID myamazingapp; 125 | uwsgi_param UWSGI_FILE /var/www/app2.py 126 | } 127 | } 128 | 129 | -------------------------------------------------------------------------------- /WebCaching.rst: -------------------------------------------------------------------------------- 1 | WebCaching framework 2 | =========================== 3 | 4 | .. note:: 5 | 6 | This is a port of the old caching subsystem to the new uWSGI caching API documented here :doc:`Caching`. 7 | Using the options here will create a new-style cache named "default". 8 | 9 | 10 | To enable web caching, allocate slots for your items using the ``cache`` option. The following command line would create a cache that can contain at most 1000 items. 11 | 12 | .. code-block:: sh 13 | 14 | ./uwsgi --socket 127.0.0.1:3031 --module mysimpleapp --master --processes 4 --cache 1000 15 | 16 | To use the cache in your application, 17 | 18 | .. code-block:: python 19 | 20 | uwsgi.cache_set("foo_key", "foo_value") # set a key 21 | value = uwsgi.cache_get("foo_key") # get a key. 22 | 23 | 24 | Persistent storage 25 | ------------------ 26 | 27 | You can store cache data in a backing store file to implement persistence. Simply add the ``cache-store `` option. 28 | Every kernel will commit data to the disk at a different rate. You can set if/when to force this with ``cache-store-sync ``, where ``n`` is the number of master cycles to wait before each disk sync. 29 | 30 | Cache sweeper 31 | ------------- 32 | 33 | Since uWSGI 1.2, cache item expiration is managed by a thread in the :term:`master` process, to reduce the risk of deadlock. This thread can be disabled (making item expiry a no-op) with the ``cache-no-expire`` option. 34 | 35 | The frequency of the cache sweeper thread can be set with ``cache-expire-freq ``. You can make the sweeper log the number of freed items with ``cache-report-freed-items``. 36 | 37 | Directly accessing the cache from your web server 38 | ------------------------------------------------- 39 | 40 | .. code-block:: nginx 41 | 42 | location / { 43 | uwsgi_pass 127.0.0.1:3031; 44 | uwsgi_modifier1 111; 45 | uwsgi_modifier2 3; 46 | uwsgi_param key $request_uri; 47 | } 48 | 49 | That's it! Nginx would now get HTTP responses from a remote uwsgi protocol compliant server. Although honestly this is not very useful, as if you get a cache miss, you will see a blank page. 50 | 51 | A better system, that will fallback to a real uwsgi request would be 52 | 53 | .. code-block:: nginx 54 | 55 | location / { 56 | uwsgi_pass 192.168.173.3:3032; 57 | uwsgi_modifier1 111; 58 | uwsgi_modifier2 3; 59 | uwsgi_param key $request_uri; 60 | uwsgi_pass_request_headers off; 61 | error_page 502 504 = @real; 62 | } 63 | 64 | location @real { 65 | uwsgi_pass 192.168.173.3:3032; 66 | uwsgi_modifier1 0; 67 | uwsgi_modifier2 0; 68 | include uwsgi_params; 69 | } 70 | 71 | Django cache backend 72 | -------------------- 73 | 74 | If you are running Django, there's a ready-to-use application called ``django-uwsgi-cache``. It is maintained by Ionel Cristian Mărieș at https://github.com/ionelmc/django-uwsgi-cache and available on pypi. 75 | 76 | 77 | .. _caching configuration: https://docs.djangoproject.com/en/dev/topics/cache/?from=olddocs#the-per-site-cache 78 | -------------------------------------------------------------------------------- /WebServers.rst: -------------------------------------------------------------------------------- 1 | Web server integration 2 | ====================== 3 | 4 | uWSGI supports several methods of integrating with web servers. It is also capable of serving HTTP requests by itself. 5 | 6 | Nginx 7 | ------------ 8 | 9 | .. seealso:: :doc:`Nginx` 10 | 11 | The uWSGI module is included in the official Nginx distribution since version 0.8.40. A version supporting Nginx 0.7.x is maintained in the uWSGI package. 12 | 13 | This is a stable handler commercially supported by Unbit. 14 | 15 | 16 | Apache 17 | ------ 18 | 19 | .. seealso:: :doc:`Apache` 20 | 21 | The Apache2 `mod_uwsgi` module was the first web server integration module developed for uWSGI. 22 | It is stable and supports both Unix and TCP sockets but could be better integrated with the Apache API. 23 | 24 | `mod_uwsgi` is commercially supported by Unbit. 25 | 26 | Since uWSGI 0.9.6-dev a second Apache2 module called `mod_Ruwsgi` is included. It's more Apache API friendly but currently lacks documentation. 27 | 28 | `mod_Ruwsgi` is *not* commercially supported by Unbit. 29 | 30 | During the 1.2 development cycle, another module called `mod_proxy_uwsgi` has been added. In the near future this should be the best choice for Apache based deployments. 31 | 32 | 33 | Lighttpd (Experimental) 34 | ----------------------- 35 | 36 | This module is the latest developed, but its inclusion in the official Lighttpd distribution has been rejected, as the main author considers the :doc:`uwsgi protocol` a "reinventing the wheel" technology while suggesting a FastCGI approach. We respect this position. The module will continue to reside in the uWSGI source tree, but it is currently unmaintained. 37 | 38 | There is currently no commercial support for this handler. We consider this module "experimental". 39 | 40 | 41 | Twisted 42 | ------- 43 | 44 | This is a "commodity" handler, useful mainly for testing applications without installing a full web server. If you want to develop an uWSGI server, look at this module. :doc:`Twisted`. 45 | 46 | 47 | Tomcat 48 | ------ 49 | 50 | The included servlet can be used to forward requests from Tomcat to the uWSGI server. 51 | It is stable, but currently lacks documentation. 52 | 53 | There is currently no commercial support for this handler. 54 | 55 | 56 | CGI 57 | --- 58 | 59 | The CGI handlers are for "lazy" installations. 60 | 61 | *Their use in production environments is discouraged.* 62 | 63 | 64 | Cherokee (Obsolete) 65 | ------------------- 66 | 67 | .. seealso:: :doc:`Cherokee` 68 | 69 | The Cherokee webserver officially supports uWSGI. 70 | Cherokee is fast and lightweight, has a beautiful admin interface and a great community. 71 | Their support for uWSGI has been awesome since the beginning and we recommend its use in most situations. 72 | The userbase of the Cherokee uWSGI handler is probably the biggest of all. 73 | 74 | The Cherokee uWSGI handler is commercially supported by Unbit. 75 | 76 | 77 | Mongrel2 (Obsolete) 78 | -------- 79 | 80 | .. seealso:: :doc:`Mongrel2` 81 | 82 | 83 | Support for the `Mongrel2 Project `_ has been available since 0.9.8-dev via the :doc:`ZeroMQ` protocol plugin. 84 | 85 | In our tests Mongrel2 survived practically all of the loads we sent. 86 | 87 | Very good and solid project. Try it :) 88 | -------------------------------------------------------------------------------- /WorkerOverride.rst: -------------------------------------------------------------------------------- 1 | Overriding Workers 2 | ================== 3 | 4 | You can override the code run by each uWSGI worker thanks to the "worker" hook exposed to plugins. 5 | 6 | Currently the python plugin is the only one exposing it: 7 | 8 | .. code-block:: ini 9 | 10 | [uwsgi] 11 | ; create a bunch of sockets 12 | socket = 127.0.0.1:3031 13 | socket = 127.0.0.1:3032 14 | ; spawn the master 15 | master = true 16 | ; spawn 4 processes 17 | processes = 4 18 | ; load a python script as the worker code 19 | python-worker-override = aioserver.py 20 | 21 | 22 | The python script has access to the uwsgi module so it can control/change its internals. 23 | 24 | The following examples shows the use of aiohttp (requires python 3.5) 25 | 26 | .. code-block:: python 27 | 28 | import asyncio 29 | from aiohttp import web 30 | 31 | import uwsgi 32 | import socket 33 | import sys 34 | import signal 35 | 36 | async def handle(request): 37 | name = request.match_info.get('name', "Anonymous") 38 | text = "Hello, " + name 39 | return web.Response(body=text.encode('utf-8')) 40 | 41 | async def wshandler(request): 42 | ws = web.WebSocketResponse() 43 | await ws.prepare(request) 44 | 45 | async for msg in ws: 46 | if msg.tp == web.MsgType.text: 47 | ws.send_str("Hello, {}".format(msg.data)) 48 | elif msg.tp == web.MsgType.binary: 49 | ws.send_bytes(msg.data) 50 | elif msg.tp == web.MsgType.close: 51 | break 52 | 53 | return ws 54 | 55 | async def init(loop, fd): 56 | app = web.Application(loop=loop) 57 | app.router.add_route('GET', '/echo', wshandler) 58 | app.router.add_route('GET', '/{name}', handle) 59 | 60 | srv = await loop.create_server(app.make_handler(), 61 | sock=socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)) 62 | print("asyncio server started on uWSGI {0}".format(uwsgi.version)) 63 | return srv 64 | 65 | def destroy(): 66 | print("destroy worker {0}".format(uwsgi.worker_id())) 67 | sys.exit(0) 68 | 69 | def graceful_reload(): 70 | print("graceful reload for worker {0}".format(uwsgi.worker_id())) 71 | # TODO do somethign meaningful 72 | sys.exit(0) 73 | 74 | loop = asyncio.get_event_loop() 75 | loop.add_signal_handler(signal.SIGINT, destroy) 76 | loop.add_signal_handler(signal.SIGHUP, graceful_reload) 77 | # spawn a handler for every uWSGI socket 78 | for fd in uwsgi.sockets: 79 | loop.run_until_complete(init(loop, fd)) 80 | uwsgi.accepting() 81 | loop.run_forever() 82 | 83 | 84 | In the example (taken from the official aiohttp docs) we see the uwsgi.sockets list (holding the list of uWSGI sockets file descriptors), and the override of SIGINT and SIGHUP to support reloading (SIGHUP should be adapted to support waiting for all the queued requests) 85 | 86 | :py:func:`uwsgi.accepting()` is called to notify the master that the worker is accepting requests, this is required for touch-chain-reload to work. 87 | 88 | The script should be extended to call uwsgi.log(...) after every request and to (eventually) update some metrics 89 | -------------------------------------------------------------------------------- /XSLT.rst: -------------------------------------------------------------------------------- 1 | The XSLT plugin 2 | =============== 3 | 4 | Since uWSGI 1.9.1 a new plugin named "xslt" is available, implementing XML Stylesheet Transformation both as request handler and routing instruction. 5 | 6 | To successfully apply a transformation you need a 'doc' (an XML document) and a stylesheet (the XSLT file). 7 | 8 | Additionally you can apply global params and set a specific content type (by default the generated output is set as text/html). 9 | 10 | The request handler 11 | ******************* 12 | 13 | Modifier1 23 has been assigned to the XSLT request handler. 14 | 15 | The document path is created appending the ``PATH_INFO`` to the ``DOCUMENT_ROOT``. 16 | 17 | The stylesheet path is created following these steps: 18 | 19 | * If a specific CGI variable is set (via ``--xslt-var``) it will be used as the stylesheet path. 20 | * If a file named like the document plus a specific extension (by default ``.xsl`` and ``.xslt`` are searched) exists it will be used as the stylesheet path. 21 | * Finally a series of static XSLT files (specified with ``--xslt-stylesheet``) is tried. 22 | 23 | Examples: 24 | 25 | .. code-block:: sh 26 | 27 | uwsgi --http-socket :9090 --http-socket-modifier1 23 --xslt-ext .bar 28 | 29 | If /foo.xml is requested (and the file exists) ``DOCUMENT_ROOT``+``foo.xml.bar`` will be searched as the xslt file. 30 | 31 | .. code-block:: sh 32 | 33 | uwsgi --http-socket :9090 --http-socket-modifier1 23 --xslt-stylesheet /var/www/myfile1.xslt --xslt-stylesheet /var/www/myfile2.xslt 34 | 35 | If /foo.xml is requested (and the file exists) ``/var/www/myfile1.xslt`` will be tried. If it does not exist, ``/var/www/myfile2.xslt`` will be tried instead. 36 | 37 | .. code-block:: sh 38 | 39 | uwsgi --http-socket :9090 --http-socket-modifier1 23 --xslt-var UWSGI_XSLT 40 | 41 | If /foo.xml is requested (and the file exists), the content of the ``UWSGI_XSLT`` variable (you can set it from your webserver) is used as the stylesheet path. 42 | 43 | If a ``QUERY_STRING`` is available, its items will be passed as global parameters to the stylesheet. 44 | 45 | As an example if you request ``/foo.xml?foo=bar&test=uwsgi``, "foo" (as "bar" and "test" (as "uwsgi") will be passed as global variables: 46 | 47 | .. code-block:: xml 48 | 49 | 50 | 51 | 52 | The routing instruction 53 | *********************** 54 | 55 | The plugin registers itself as internal routing instruction named "xslt". It is probably a lot more versatile then the request plugin. 56 | 57 | Its syntax is pretty simple: 58 | 59 | .. code-block:: ini 60 | 61 | [uwsgi] 62 | plugin = xslt 63 | route = ^/foo xslt:doc=${DOCUMENT_ROOT}/${PATH_INFO}.xml,stylesheet=/var/www/myfunction.xslt,content_type=text/html,params=foo=bar&test=unbit 64 | 65 | This will apply the ``/var/www/myfunction.xslt`` transformation to ``foo.xml`` and will return it as ``text/html``. 66 | 67 | The only required parameters for the routing instruction are ``doc`` and ``stylesheet``. 68 | -------------------------------------------------------------------------------- /_options/generate.py: -------------------------------------------------------------------------------- 1 | from optutil import Config 2 | import os 3 | import sys 4 | import json 5 | 6 | PRELUDE = """ 7 | .. ********************************************************************* 8 | .. This page has been automatically generated by `_options/generate.py`! 9 | .. ********************************************************************* 10 | 11 | %(title)s Options 12 | ------------------------------------------------------------------------ 13 | 14 | """.strip() 15 | 16 | 17 | FULL_PRELUDE = """ 18 | .. ********************************************************************* 19 | .. This page has been automatically generated by `_options/generate.py`! 20 | .. ********************************************************************* 21 | 22 | Configuration Options 23 | ===================== 24 | 25 | uWSGI and the various plugins it consists of is almost infinitely configurable. 26 | 27 | There's an exhaustive and exhausting list of all options below. Take a deep breath and don't panic -- the list below is long, but you don't need to know everything to start using uWSGI. 28 | 29 | """ 30 | 31 | 32 | def render_rst(config, prelude): 33 | output = [prelude % vars(config)] 34 | write = output.append 35 | 36 | for i, section in enumerate(config.sections): 37 | write("") 38 | refname = section.refname 39 | if not refname and i == 0: 40 | refname = "Options%s" % config.filename_part 41 | 42 | if refname: 43 | write(".. _%s:" % refname) 44 | write("") 45 | 46 | write("%s" % section.name) 47 | write("^" * len(section.name)) 48 | write("") 49 | if section.docs: 50 | write(u".. seealso::") 51 | write(u"") 52 | for doc in section.docs: 53 | write(u" :doc:`%s`" % doc) 54 | write("") 55 | 56 | for opt in section.options: 57 | write(".. _Option%s:" % opt.cc_name) 58 | write("") 59 | header = (", ".join("``%s``" % name for name in opt.names)) 60 | write(header) 61 | write("~" * len(header)) 62 | write("**Argument:** %s" % opt.get_argument()) 63 | if opt.default: 64 | write("**Default:** %s" % opt.default) 65 | write("") 66 | 67 | write(opt.get_description()) 68 | if opt.help: 69 | write("") 70 | write(opt.help) 71 | if opt.docs: 72 | write("") 73 | write(".. seealso:: %s" % ", ".join(u":doc:`%s`" % topic for topic in opt.docs)) 74 | write("") 75 | 76 | return output 77 | 78 | def write_output(output, filename): 79 | target_file = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", filename)) 80 | with file(target_file, "wb") as out_file: 81 | out_file.write("\n".join(output).encode("UTF-8").lstrip()) 82 | 83 | def read_configs(): 84 | import optdefs 85 | funcs = [(c, f) for (c, f) in [(c, getattr(optdefs, c)) for c in dir(optdefs) if c.endswith("_options")] if callable(f)] 86 | funcs.sort(key = lambda (c, f): ((-9000, None) if c.startswith("core_") else (0, c))) # Shunt core options up top, use alpha otherwise 87 | 88 | filenames = [] 89 | configs = [] 90 | for funcname, func in funcs: 91 | print >>sys.stderr, "Calling %r..." % funcname 92 | config = func() 93 | filename = "Options%s.rst" % config.filename_part 94 | configs.append((filename, config)) 95 | 96 | return configs 97 | 98 | def write_rst(): 99 | 100 | rst_lines = [] 101 | for filename, config in read_configs(): 102 | rst_lines.extend(render_rst(config, "")) 103 | 104 | print "Writing Options.rst..." 105 | write_output([FULL_PRELUDE] + rst_lines, "Options.rst") 106 | 107 | def find_documented_options(): 108 | options = set() 109 | for filename, config in read_configs(): 110 | for section in config.sections: 111 | for opt in section.options: 112 | options |= set(opt.names) 113 | print json.dumps(sorted(options)) 114 | 115 | def main(): 116 | import argparse 117 | ap = argparse.ArgumentParser() 118 | ap.add_argument("--action", default="generate", help="action (generate, list)") 119 | args = ap.parse_args() 120 | if args.action == "generate": 121 | return write_rst() 122 | if args.action == "list": 123 | return find_documented_options() 124 | 125 | if __name__ == '__main__': 126 | main() -------------------------------------------------------------------------------- /_options/optutil.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | import re 3 | import textwrap 4 | 5 | un_whitespace_re = re.compile(r"[\s_]+") 6 | first_word_re = re.compile("^(\w+)", re.I) 7 | 8 | class _Optional: 9 | def __init__(self, inner): 10 | self.inner = inner 11 | 12 | def transmogrify_name(name): 13 | if isinstance(name, basestring): 14 | return [unicode(name)] 15 | else: 16 | return [unicode(name) for name in name] 17 | 18 | class Option: 19 | def __init__(self, name, type, desc, short_name, optional, multiple, docs=(), default=None, help=None, since=None): 20 | self.names = transmogrify_name(name) 21 | self.type = type 22 | self.desc = desc 23 | self.short_name = short_name 24 | self.optional = optional 25 | self.multiple = multiple 26 | self.docs = sorted(docs) 27 | self.cc_name = self.names[0].replace("-", " ").title().replace(" ", "") 28 | self.help = textwrap.dedent((help or "").strip("\r\n")) 29 | self.default = default 30 | self.since = since 31 | 32 | def get_argument(self): 33 | if self.type is int or self.type is long: 34 | argument_desc = "number" 35 | elif self.type is str: 36 | argument_desc = "string" 37 | elif self.type is True: 38 | argument_desc = "no argument" 39 | else: 40 | argument_desc = "*%s*" % self.type 41 | 42 | if self.optional: 43 | argument_desc = "optional %s" % argument_desc 44 | 45 | return argument_desc 46 | 47 | def get_description(self): 48 | desc = self.desc.strip() 49 | 50 | # Fixup! 51 | if desc[0] == desc[0].lower(): 52 | desc = desc[0].upper() + desc[1:] 53 | if not desc.endswith("."): 54 | desc += "." 55 | 56 | if self.short_name: 57 | desc += u"\n\nThis option may be set with ``-%s`` from the command line." % self.short_name 58 | 59 | if self.multiple: 60 | desc += "\n\n*This option may be declared multiple times.*" 61 | 62 | if self.since: 63 | desc += "\n\nThis option is available since version %s." % self.since 64 | 65 | return desc 66 | 67 | class Section: 68 | def __init__(self, name, docs = [], refname=None): 69 | self.name = name 70 | self.options = [] 71 | self.refname = refname 72 | self.docs = sorted(docs) 73 | 74 | def __enter__(self): 75 | return self 76 | 77 | def __exit__(self, et, ev, tb): 78 | pass 79 | 80 | def define_option(self, name, type, desc, short_name=None, docs=(), default=None, help=None, since=None): 81 | if isinstance(type, _Optional): 82 | optional = True 83 | type = type.inner 84 | else: 85 | optional = False 86 | 87 | if isinstance(type, list): 88 | multiple = True 89 | type = type[0] 90 | else: 91 | multiple = False 92 | 93 | assert (not short_name or len(short_name) == 1) 94 | args = locals() 95 | args.pop("self") 96 | 97 | for option in self.options: 98 | if option.desc == desc: 99 | print "Found redeclared config entry %s, augmenting old one (%s)" % (name, option.names) 100 | option.names.extend(transmogrify_name(name)) 101 | return 102 | 103 | self.options.append(Option(**args)) 104 | 105 | o = define_option 106 | 107 | 108 | class Config(object): 109 | def __init__(self, title, filename_part=None): 110 | self.title = title 111 | if filename_part: 112 | self.filename_part = filename_part 113 | else: 114 | filename_part = first_word_re.search(self.title).group(1) 115 | if filename_part.upper() != filename_part: 116 | filename_part = (un_whitespace_re.sub("", filename_part).title()) 117 | self.filename_part = filename_part 118 | self.sections = [] 119 | 120 | def section(self, name, **kwargs): 121 | section = Section(name, **kwargs) 122 | self.sections.append(section) 123 | return section -------------------------------------------------------------------------------- /_tools/trac_miniparser.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | rules = [] 4 | rule_funcs = {} 5 | 6 | def rule(regexp, type, func=(lambda m: m.groupdict() or {}), update_prior_token=None): 7 | rules.append((re.compile(regexp), type, update_prior_token)) 8 | rule_funcs[type] = func 9 | 10 | def parse(text, coalesce=True): 11 | text = text.splitlines() 12 | tokens = [] 13 | for line in text: 14 | for regexp, type, update_prior_token in rules: 15 | m = regexp.match(line) 16 | if m: 17 | res = rule_funcs[type](m) 18 | if update_prior_token: 19 | for tok in reversed(tokens): 20 | if (not isinstance(tok, basestring)) and tok[0] == update_prior_token: 21 | tok[1].update(res) 22 | res = None 23 | break 24 | 25 | if res is not None: 26 | tokens.append((type, res)) 27 | break 28 | else: 29 | tokens.append(line + "\n") 30 | 31 | if coalesce: 32 | coalesce_bare(tokens) 33 | 34 | return tokens 35 | 36 | def coalesce_bare(tokens): 37 | i = 1 38 | while i < len(tokens) - 1: 39 | if isinstance(tokens[i], basestring) and isinstance(tokens[i-1], basestring): 40 | tokens[i-1] += tokens[i] 41 | tokens.pop(i) 42 | else: 43 | i += 1 44 | 45 | rule(r"^\{{3}$", "begin_code") 46 | rule(r"^\}{3}$", "end_code") 47 | rule(r"^#!(?P\w+)$", "lang", update_prior_token="begin_code") 48 | rule(r"^(?P=+)\s*(?P.+?)\s*=*$", "heading") 49 | -------------------------------------------------------------------------------- /_tools/wikitool.py: -------------------------------------------------------------------------------- 1 | import pprint 2 | import os 3 | import sys 4 | from trac_miniparser import parse 5 | 6 | class IndentingOutput(object): 7 | def __init__(self, stream): 8 | self.stream = stream 9 | self.indent = 0 10 | 11 | def _change_indent(self, delta, pre=None, post=None): 12 | if pre: 13 | self.write(pre) 14 | self.indent += delta 15 | assert self.indent >= 0 16 | if post: 17 | self.write(post) 18 | 19 | def begin(self, pre=None, post=None): self._change_indent(1, pre, post) 20 | def end(self, pre=None, post=None): self._change_indent(-1, pre, post) 21 | 22 | def write(self, str=""): 23 | indent = (" " * self.indent) 24 | for line in str.splitlines(): 25 | self.stream.write(indent + line + "\n") 26 | 27 | def rewrite_wiki_inline(str): 28 | return str 29 | 30 | 31 | def write_rst(tokens, output): 32 | iout = IndentingOutput(output) 33 | for token in tokens: 34 | if isinstance(token, basestring): 35 | iout.write(rewrite_wiki_inline(token)) 36 | continue 37 | else: 38 | type, data = token 39 | if type == "begin_code": 40 | iout.begin(".. code-block:: %s\n\n" % data.get("lang", "xxx")) 41 | continue 42 | elif type == "end_code": 43 | iout.end() 44 | elif type == "heading": 45 | level = len(data["n"]) 46 | text = data["text"] 47 | foot = '=-^^'[level] * len(text) 48 | iout.write(text) 49 | iout.write(foot) 50 | iout.write() 51 | else: 52 | raise NotImplementedError("No idea what to do with token %r" % token) 53 | 54 | 55 | def transmogrify(filename): 56 | basename = os.path.basename(filename).split(".")[0] 57 | text = file(filename, "rb").read().decode("UTF-8") 58 | tokens = parse(text, coalesce=True) 59 | write_rst(tokens, sys.stdout) 60 | 61 | #print basename 62 | 63 | if __name__ == '__main__': 64 | transmogrify(sys.argv[1]) 65 | -------------------------------------------------------------------------------- /articles/WSGIEnvBehaviour.rst: -------------------------------------------------------------------------------- 1 | WSGI env behaviour policies 2 | =========================== 3 | 4 | When using uWSGI two different strategies can be used for allocating/deallocating the WSGI env using either the 5 | ``wsgi-env-behaviour`` or ``wsgi-env-behavior`` option: 6 | 7 | ``cheat``: it preallocates the env dictionary on uWSGI startup and clears it after each request. 8 | This is the default behaviour in uWSGI<=2.0.x 9 | 10 | ``holy``: creates and destroys the environ dictionary at each request. This is the default behaviour in uWSGI>=2.1 11 | -------------------------------------------------------------------------------- /conf.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | extensions = [] 3 | templates_path = ['_templates'] 4 | source_suffix = '.rst' 5 | master_doc = 'index' 6 | project = 'uWSGI' 7 | copyright = '2012-2016, uWSGI' 8 | version = '2.0' 9 | release = '2.0' 10 | exclude_patterns = ['_build'] 11 | pygments_style = 'sphinx' 12 | html_theme = 'default' 13 | html_static_path = ['_static'] 14 | htmlhelp_basename = 'uWSGIdoc' 15 | latex_elements = {} 16 | latex_documents = [('index', 'uWSGI.tex', 'uWSGI Documentation', 'uWSGI', 'manual'),] 17 | man_pages = [('index', 'uwsgi', 'uWSGI Documentation', ['uWSGI'], 1)] 18 | texinfo_documents = [('index', 'uWSGI', 'uWSGI Documentation', 'The uWSGI application server.', 'Miscellaneous'),] 19 | -------------------------------------------------------------------------------- /examples/CPythonForkServer.rst: -------------------------------------------------------------------------------- 1 | Fork Server with CPython 2 | ======================== 3 | 4 | Our "base" app (myforkbase.py in /var/www): 5 | 6 | .. code-block:: py 7 | 8 | # you should see this message only in the base instance 9 | print "I AM THE MODULE" 10 | 11 | def application(e, sr): 12 | sr('200 OK',[('Content-Type','text/plain')]) 13 | return ['Hello World'] 14 | 15 | 16 | The base vassal (in /etc/forkvassals/base.ini) 17 | 18 | .. code-block:: ini 19 | 20 | [uwsgi] 21 | ; add /var/www to the PYTHONPATH (asap) 22 | early-python-path = /var/www 23 | ; import myforkbase.py (asap) 24 | early-pyimport = myforkbase 25 | ; spawn the fork server and suspend the vassal 26 | fork-server = /run/forkme 27 | 28 | 29 | and now two vassals inheriting from the base 30 | 31 | .. code-block:: ini 32 | 33 | [emperor] 34 | ; vassal's attribute 35 | myfork-base = /run/forkme 36 | 37 | [uwsgi] 38 | http-socket = :9090 39 | processes = 4 40 | ; the python VM will find myappfork already loaded 41 | wsgi = myappfork 42 | 43 | 44 | .. code-block:: ini 45 | 46 | [emperor] 47 | ; vassal's attribute 48 | myfork-base = /run/forkme 49 | 50 | [uwsgi] 51 | http-socket = :9091 52 | processes = 8 53 | threads = 2 54 | ; the python VM will find myappfork already loaded 55 | wsgi = myappfork 56 | 57 | 58 | And finally run the Emperor 59 | 60 | .. code-block:: sh 61 | 62 | uwsgi --emperor /etc/forkvassals --emperor-collect-attr myfork-base --emperor-fork-server-attr myfork-base 63 | 64 | the `--emperor-collect-attr` option tells the Emperor to search for a 'myfork-base' attribute in the [emperor] section, while `--emperor-fork-server-attr` 65 | instruct it to use the parameter as the fork-server to connect to. 66 | 67 | TODO 68 | ==== 69 | 70 | The --emperor-collect-attr could be implicited by emperor-fork-server-attr 71 | -------------------------------------------------------------------------------- /examples/README.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unbit/uwsgi-docs/5784c30866a94942a5200db4d5f6c2850afb1caa/examples/README.rst -------------------------------------------------------------------------------- /optdefs.pl: -------------------------------------------------------------------------------- 1 | $OPTIONS = { 2 | 'emperor' => {'ref' => 'Emperor', 'doc' => "The Emperor is a special uWSGI instance aimed at governing other uWSGI instances (named: vassals). By default it is configured to monitor a directory containing valid uWSGI config files, whenever a file is created a new instance is spawned, when the file is touched the instance is reloaded, when the file is removed the instance is destroyed. It can be extended to support more paradigms"}, 3 | 'thunder-lock' => {'ref' => 'articles/SerializingAccept'}, 4 | 'declare-option' => {'ref' => 'CustomOptions'}, 5 | 'fastrouter' => {'ref' => 'Fastrouter'}, 6 | 'freebind' => {'doc' => "set the IP_FREEBIND flag to every socket created by uWSGI. This kind of socket can bind to non-existent ip addresses. Its main purpose is for high availability (this is Linux only)"}, 7 | 'sharedarea' => {'ref' => 'SharedArea' }, 8 | 'metrics-no-cores' => {'ref' => 'Metrics', 'doc' => "Do not expose metrics of async cores."}, 9 | 'stats-no-cores' => {'ref' => 'Metrics', 'doc' => "Do not expose the information about cores in the stats server."}, 10 | 'stats-no-metrics' => {'ref' => 'Metrics', 'doc' => "Do not expose the metrics at all in the stats server."}, 11 | 'buffer-size' => {'doc' => "Set the max size of a request (request-body excluded), this generally maps to the size of request headers. By default it is 4k. If you receive a bigger request (for example with big cookies or query string) you may need to increase it. It is a security measure too, so adapt to your app needs instead of maxing it out."}, 12 | }; 13 | -------------------------------------------------------------------------------- /tips_and_tricks/README.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unbit/uwsgi-docs/5784c30866a94942a5200db4d5f6c2850afb1caa/tips_and_tricks/README.rst -------------------------------------------------------------------------------- /tutorials/DynamicProxying.rst: -------------------------------------------------------------------------------- 1 | Build a dynamic proxy using RPC and internal routing 2 | ==================================================== 3 | 4 | Work in progress (requires uWSGI 1.9.14, we use PyPy as the engine) 5 | 6 | step 1: build your mapping function 7 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 8 | 9 | we use the hostname as the mapping (you can use whatever you need) 10 | 11 | .. code-block:: py 12 | 13 | import uwsgi 14 | 15 | def my_mapper(hostname): 16 | return "127.0.0.1:3031" 17 | 18 | uwsgi.register_rpc('the_mapper', my_mapper) 19 | 20 | save it as myfuncs.py 21 | 22 | 23 | step 2: building a routing table 24 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 25 | 26 | .. code-block:: ini 27 | 28 | [uwsgi] 29 | ; enable the pypy engine 30 | pypy-home = /opt/pypy 31 | ; execute the myfuncs.py file (the 'the_mapper' rpc function will be registered) 32 | pypy-exec = myfuncs.py 33 | 34 | ; bind to a port 35 | http-socket = :9090 36 | 37 | ; let's define our routing table 38 | 39 | ; at every request (route-run execute the action without making check, use it instead of --route .*) run the_mapper passing HTTP_HOST as argument 40 | ; and place the result in the MYNODE variable 41 | route-run = rpcvar:MYNODE the_mapper ${HTTP_HOST} 42 | ; print the MYNODE variable (just for fun) 43 | route-run = log:${MYNODE} 44 | ; proxy the request to the chosen backend node 45 | route-run = http:${MYNODE} 46 | 47 | ; enable offloading for automagic non-blocking behaviour 48 | ; a good value for offloading is the number of cpu cores 49 | offload-threads = 2 50 | 51 | -------------------------------------------------------------------------------- /tutorials/EmperorSubscriptions.rst: -------------------------------------------------------------------------------- 1 | On demand vassals via subscriptions 2 | =================================== 3 | 4 | Spawn an Emperor with a command socket (it is a channel allowing external process to govern vassals) and instruct it to not spawn vassals until a 'spawn' command is received. 5 | 6 | .. code-block:: ini 7 | 8 | [uwsgi] 9 | emperor = /etc/uwsgi/vassals 10 | emperor-command-socket = /run/emperor.socket 11 | emperor-wait-for-command = true 12 | 13 | Spawn a Fastrouter on port :3031 with a subscription server on port :4041 and instruct it to contact the specific emperor socket whenever an inactive instance is found: 14 | 15 | .. code-block:: ini 16 | 17 | [uwsgi] 18 | master = true 19 | fastrouter = :3031 20 | fastrouter-subscription-server = 127.0.0.1:4041 21 | ; the emperor socket to contact 22 | fastrouter-emperor-socket = /tmp/emperor.socket 23 | fastrouter-stats-server = 127.0.0.1:4040 24 | 25 | 26 | Place your vassals in /etc/uwsgi/vassals ensuring each of them correctly subscribe to the fastrouter (this subscription is required to mark 'inactive subscruptions' as 'active' 27 | 28 | Now you can start putting 'inactive' subscriptions in the fastrouter, using raw datagrams. An example inactive subscription packets can be something like this in the --subscribe2 way: 29 | 30 | .. code-block:: sh 31 | 32 | addr=127.0.0.1:3036,vassal=one.ini,inactive=1,server=127.0.0.1:4041,key=127.0.0.1:9090 33 | 34 | this will instruct the fastrouter to map the Host 127.0.0.1:9090 to the inactive uWSGI server that will run on 127.0.0.1:3036 and to run the one.ini vassal at the first request. 35 | 36 | -------------------------------------------------------------------------------- /tutorials/README.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unbit/uwsgi-docs/5784c30866a94942a5200db4d5f6c2850afb1caa/tutorials/README.rst -------------------------------------------------------------------------------- /tutorials/WritingPlugins.rst: -------------------------------------------------------------------------------- 1 | Writing uWSGI plugins 2 | ===================== 3 | 4 | This tutorial will introduce you to uWSGI hacking. A bit of C knowledge and UNIX theory is required. 5 | 6 | The simplified (and safe) build system used in the tutorial has been added in uWSGI 1.9.21, on older versions you need the raw 7 | procedure (described at the end of the tutorial) 8 | 9 | What is an uWSGI plugin? 10 | ************************ 11 | 12 | uWSGI plugins are standard shared libraries (with the classic .so extension) exposing a specific C structure named "uwsgi_plugin". 13 | 14 | This structure exposes a bunch of handy information (like the name of the plugin) and "hooks". 15 | 16 | Hooks are simple functions registered to be run at specific server phases. 17 | 18 | The minimal plugin you can write it is something like this (the 'foobar' plugin): 19 | 20 | .. code-block:: c 21 | 22 | #include 23 | 24 | struct uwsgi_plugin foobar_plugin = { 25 | .name ="foobar", 26 | }; 27 | 28 | It announces itself as 'foobar' and exposes no hooks (yes, it is the most useless plugin out there, except for adding a teensy bit of memory use to uWSGI). 29 | 30 | Plugins are not required to define hooks -- they can simply expose functions that can be called using uWSGI advanced facilities (read: :doc:`Hooks`). 31 | 32 | Why (and when) plugins? 33 | *********************** 34 | 35 | Even if uWSGI is able to directly load shared libraries (with ``--dlopen``) and call their functions as hooks, sometimes you want to interface with 36 | uWSGI's internal structures. 37 | 38 | The first plugin 39 | **************** 40 | 41 | Our first plugin will be a simple "Hello world" one: 42 | 43 | .. code-block:: c 44 | 45 | #include 46 | 47 | static int foo_init() { 48 | uwsgi_log("Hello World\n"); 49 | return 0; 50 | } 51 | 52 | struct uwsgi_plugin foobar_plugin = { 53 | .name = "foobar", 54 | .init = foo_init, 55 | }; 56 | 57 | Save it as ``foobar.c``. 58 | 59 | Build it: 60 | 61 | .. code-block:: sh 62 | 63 | uwsgi --build-plugin foobar.c 64 | 65 | You will end up with a ``foobar_plugin.so`` that you can load in your uWSGI binary. 66 | 67 | .. code-block:: sh 68 | 69 | uwsgi --plugin ./foobar_plugin.so 70 | 71 | If all goes well, you should see "Hello World" on your terminal before uWSGI exiting with an error (as no socket is defined). 72 | 73 | The uwsgiplugin.py file 74 | *********************** 75 | 76 | How does the magic happen? 77 | ************************** 78 | 79 | As you have seen, the uwsgi binary by itself is able to build plugins without forcing the user/developer to care about build profiles, #ifdef or platform-specific configurations. 80 | 81 | This is possible because the uwsgi binary itself contains the raw 'uwsgi.h' file as well as the 'uwsgiconfig.py' script. 82 | 83 | In addition to this the CFLAGS used when building the binary are stored too. 84 | 85 | With these 3 components you have all you need to safely build a uWSGI plugin tuned for your uwsgi binary. 86 | 87 | General plugins VS request plugins 88 | ********************************** 89 | 90 | The wsgi_request struct 91 | *********************** 92 | 93 | Headers, body and sendfile 94 | ************************** 95 | 96 | Offloading 97 | ********** 98 | 99 | Available hooks 100 | *************** 101 | 102 | Defining options 103 | **************** 104 | 105 | Using C++ 106 | ********* 107 | 108 | Using Objective-C 109 | ***************** 110 | 111 | socket I/O 112 | ********** 113 | 114 | Whenever you make I/O operations on a socket you have to be sure to not-block the currently running thread/core/worker. 115 | 116 | The uwsgi API exposes some functions to ensure safety when dealing with I/O. They would be documented here, but aren't, yet. 117 | 118 | -------------------------------------------------------------------------------- /uGreen.rst: -------------------------------------------------------------------------------- 1 | uGreen -- uWSGI Green Threads 2 | ============================= 3 | 4 | uGreen is an implementation of `green threads`_ on top of the :doc:`uWSGI async platform`. 5 | 6 | It is very similar to Python's greenlet but built on top of the POSIX ``swapcontext()`` function. To take advantage of uGreen you have to set the number of async cores that will be mapped to green threads. 7 | 8 | For example if you want to spawn 30 green threads: 9 | 10 | .. code-block:: sh 11 | 12 | ./uwsgi -w tests.cpubound_green -s :3031 --async 30 --ugreen 13 | 14 | The ``ugreen`` option will enable uGreen on top of async mode. 15 | 16 | Now when you call :py:func:`uwsgi.suspend` in your app, you'll be switched off to another green thread. 17 | 18 | .. _green threads: http://en.wikipedia.org/wiki/Green_threads 19 | 20 | Security and performance 21 | ------------------------ 22 | 23 | To ensure (relative) isolation of green threads, every stack area is protected by so called "guard pages". 24 | 25 | An attempt to write out of the stack area of a green thread will result in a segmentation fault/bus error (and the process manager, if enabled, will respawn the worker without too much damage). 26 | 27 | The context switch is very fast, we can see it as: 28 | 29 | * On switch 30 | 31 | 1. Save the Python Frame pointer 32 | 2. Save the recursion depth of the Python environment (it is simply an int) 33 | 3. Switch to the main stack 34 | 35 | * On return 36 | 37 | 1. Re-set the uGreen stack 38 | 2. Re-set the recursion depth 39 | 3. Re-set the frame pointer 40 | 41 | The stack/registers switch is done by the POSIX ``swapcontext()`` call and we don't have to worry about it. 42 | 43 | 44 | Async I/O 45 | --------- 46 | 47 | For managing async I/O you can use the Async mode FD wait functions :py:func:`uwsgi.wait_fd_read` and :py:func:`uwsgi.wait_fd_write`. 48 | 49 | Stack size 50 | ---------- 51 | 52 | You can choose the uGreen stack size using the ``ugreen-stacksize `` option. The argument is in pages, not bytes. 53 | 54 | Is this better than Greenlet or Stackless Python? 55 | ------------------------------------------------- 56 | 57 | Weeeeelll... it depends. uGreen is faster (the stack is preallocated) but requires more memory (to allocate a stack area for every core). Stackless and Greenlet probably require less memory... but Stackless requires a heavily patched version of Python. 58 | 59 | If you're heavily invested in making your app as async-snappy as possible, it's always best to do some tests to choose the best one for you. As far as uWSGI is concerned, you can move from async engine to another without changing your code. 60 | 61 | What about ``python-coev``? 62 | --------------------------- 63 | 64 | Lots of uGreen has been inspired by it. The author's way to map Python threads to their implementation allows ``python-coev`` to be a little more "trustworthy" than Stackless Python. However, like Stackless, it requires a patched version of Python... :( 65 | 66 | Can I use uGreen to write Comet apps? 67 | ------------------------------------- 68 | 69 | Yeah! Sure! Go ahead. In the distribution you will find the ``ugreenchat.py`` script. It is a simple/dumb multiuser Comet chat. If you want to test it (for example 30 users) run it with 70 | 71 | .. code-block:: sh 72 | 73 | ./uwsgi -s :3031 -w ugreenchat --async 30 --ugreen 74 | 75 | The code has comments for every ugreen-related line. You'll need `Bottle`_, an amazing Python web micro framework to use it. 76 | 77 | .. _Bottle: http://bottlepy.org/docs/dev/ 78 | 79 | Psycopg2 improvements 80 | --------------------- 81 | 82 | uGreen can benefit from the new psycopg2 async extensions and the psycogreen project. See the :file:`tests/psycopg2_green.py` and :file:`tests/psycogreen_green.py` files for examples. --------------------------------------------------------------------------------