Skip to content

Commit 10e4a53

Browse files
committed
Dynamic configuration include now works.
1 parent fcf6f11 commit 10e4a53

12 files changed

+260
-350
lines changed

README.rst

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,24 +58,30 @@ Running tests::
5858
Directives
5959
==========
6060

61-
HTTP
62-
----
61+
62+
Global Scope
63+
------------
6364

6465
- ``python`` - execute Python code in config time
6566
- ``python_include`` - include and execute Python code in config time
6667
- ``python_stack_size`` - set stack size for unblocked code, default is 32k
68+
69+
HTTP Scope
70+
----------
71+
72+
- ``python`` - execute Python code in config time
73+
- ``python_include`` - include and execute Python code in config time
6774
- ``python_set`` - create Python variable (one-line)
6875
- ``python_access`` - set up Python access handler (one-line, blocking ops)
6976
- ``python_log`` - set up Python log handler (one-line)
7077
- ``python_content`` - set up Python location content handler (one-line,
7178
blocking ops)
7279

73-
Stream
74-
------
80+
Stream Scope
81+
------------
7582

7683
- ``python`` - execute Python code in config time
7784
- ``python_include`` - include and execute Python code in config time
78-
- ``python_stack_size`` - set stack size for unblocked code, default is 32k
7985
- ``python_set`` - create Python variable (one-line)
8086
- ``python_access`` - set up Python access handler (one-line, blocking ops)
8187
- ``python_preread`` - set up Python access handler (one-line, blocking ops)
@@ -154,29 +160,37 @@ changes transparent for user. That means, you can use common blocking Python
154160
operations, while their implementations will rely on Nginx non-blocking core.
155161
The list of classes and functions, unblocked by the module:
156162

157-
- ``time.sleep()`` function
158163
- ``socket.socket`` class
159164
- unconnected (UDP) sockets are not supported
160165
- standard Python SSL socket wrappers are not supported
161166
- ``socket.gethostbyname()`` and other resolve functions
162167
- nginx ``resolver`` directive in current location is required for these
163168
functions
169+
- ``time.sleep()`` function
164170

165171

166172
Default Python namespace
167173
========================
168174

169-
For each nginx configuration a new default Python namespace is created. That
170-
namespace is shared between all HTTP requests or Stream sessions. HTTP and
171-
Stream have separate namespaces however. The namespace can be initialized with
172-
the ``python`` and ``python_include`` directives, which operate at configuration
173-
time.
175+
For each nginx configuration a new default Python namespace is created. This
176+
namespace is shared among all global, HTTP or Stream scopes in configuration
177+
time, as well as HTTP requests and Stream sessions in runtime. The namespace
178+
can be initialized with the ``python`` and ``python_include`` directives, which
179+
operate at configuration time.
174180

175181

176182
Examples
177183
========
178184

179-
Example #1::
185+
Remote ``nginx.conf`` example. This example shows how to load the essential
186+
part of nginx configuration file from a remote server::
187+
188+
python 'from urllib import URLopener';
189+
python 'URLopener().retrieve("http://127.0.0.1:8888/nginx.conf", "/tmp/nginx.conf")';
190+
191+
include /tmp/nginx.conf;
192+
193+
Python variable::
180194

181195
# nginx.conf
182196

@@ -197,7 +211,7 @@ Example #1::
197211
}
198212
}
199213

200-
Example #2::
214+
Python access and content handlers::
201215

202216
# nginx.conf
203217

@@ -239,7 +253,7 @@ Example #2::
239253
r.send('1234567890');
240254
r.send('abcdefgefg', ngx.SEND_LAST)
241255

242-
Example #3::
256+
UDP reports in Python::
243257

244258
# nginx.conf
245259

@@ -276,7 +290,7 @@ Example #3::
276290

277291
ds.send(r.var['request'])
278292

279-
Example #4::
293+
Making HTTP requests from Python in runtime::
280294

281295
# nginx.conf
282296

@@ -316,7 +330,7 @@ Example #4::
316330
r.ho['x-reason'] = resp.reason;
317331
r.ho['x-body'] = resp.read()
318332

319-
Example #5::
333+
Simple echo server::
320334

321335
# nginx.conf
322336

TODO

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-
- dynamic compile warning when compiling with stream

config

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,27 +30,28 @@ ngx_module_libs=$PYTHON_CORE_LIBS
3030

3131
if [ $ngx_module_link = DYNAMIC ] ; then
3232

33-
if [ $HTTP != NO ]; then
34-
ngx_module_type=HTTP
35-
ngx_module_name=ngx_http_python_module
36-
ngx_module_deps="$PYTHON_CORE_DEPS $PYTHON_HTTP_DEPS"
37-
ngx_module_srcs="$PYTHON_CORE_SRCS $PYTHON_HTTP_SRCS"
33+
ngx_module_type=CORE
34+
ngx_module_name=ngx_python_module
35+
ngx_module_deps=$PYTHON_CORE_DEPS
36+
ngx_module_srcs=$PYTHON_CORE_SRCS
3837

39-
. auto/module
38+
if [ $HTTP != NO ]; then
39+
ngx_module_name="$ngx_module_name ngx_http_python_module"
40+
ngx_module_deps="$ngx_module_deps $PYTHON_HTTP_DEPS"
41+
ngx_module_srcs="$ngx_module_srcs $PYTHON_HTTP_SRCS"
4042
fi
4143

4244
if [ $STREAM != NO ]; then
43-
ngx_module_type=STREAM
44-
ngx_module_name=ngx_stream_python_module
45-
ngx_module_deps="$PYTHON_CORE_DEPS $PYTHON_STREAM_DEPS"
46-
ngx_module_srcs="$PYTHON_CORE_SRCS $PYTHON_STREAM_SRCS"
47-
48-
. auto/module
45+
ngx_module_name="$ngx_module_name ngx_stream_python_module"
46+
ngx_module_deps="$ngx_module_deps $PYTHON_STREAM_DEPS"
47+
ngx_module_srcs="$ngx_module_srcs $PYTHON_STREAM_SRCS"
4948
fi
5049

50+
. auto/module
51+
5152
else
5253
ngx_module_type=CORE
53-
ngx_module_name=
54+
ngx_module_name=ngx_python_module
5455
ngx_module_deps=$PYTHON_CORE_DEPS
5556
ngx_module_srcs=$PYTHON_CORE_SRCS
5657

src/ngx_http_python_module.c

Lines changed: 40 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ static ngx_int_t ngx_http_python_variable(ngx_http_request_t *r,
3535
static PyObject *ngx_http_python_eval(ngx_http_request_t *r, PyCodeObject *code,
3636
ngx_event_t *wake);
3737

38+
static void *ngx_http_python_create_loc_conf(ngx_conf_t *cf);
39+
static char *ngx_http_python_merge_loc_conf(ngx_conf_t *cf, void *parent,
40+
void *child);
3841
static char *ngx_http_python_set(ngx_conf_t *cf, ngx_command_t *cmd,
3942
void *conf);
4043
static char *ngx_http_python_access(ngx_conf_t *cf, ngx_command_t *cmd,
@@ -43,30 +46,29 @@ static char *ngx_http_python_log(ngx_conf_t *cf, ngx_command_t *cmd,
4346
void *conf);
4447
static char *ngx_http_python_content(ngx_conf_t *cf, ngx_command_t *cmd,
4548
void *conf);
46-
static void *ngx_http_python_create_loc_conf(ngx_conf_t *cf);
47-
static char *ngx_http_python_merge_loc_conf(ngx_conf_t *cf, void *parent,
48-
void *child);
4949
static ngx_int_t ngx_http_python_init(ngx_conf_t *cf);
50-
static ngx_int_t ngx_http_python_init_namespace(ngx_conf_t *cf);
5150

5251

5352
static ngx_command_t ngx_http_python_commands[] = {
5453

5554
{ ngx_string("python"),
56-
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
55+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
56+
|NGX_HTTP_UPS_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LIF_CONF
57+
|NGX_CONF_TAKE1,
5758
ngx_python_set_slot,
5859
0,
5960
0,
6061
NULL },
6162

6263
{ ngx_string("python_include"),
63-
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
64+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
65+
|NGX_HTTP_UPS_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LIF_CONF
66+
|NGX_CONF_TAKE1,
6467
ngx_python_include_set_slot,
6568
0,
6669
0,
6770
NULL },
6871

69-
7072
{ ngx_string("python_set"),
7173
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2,
7274
ngx_http_python_set,
@@ -330,7 +332,7 @@ static PyObject *
330332
ngx_http_python_eval(ngx_http_request_t *r, PyCodeObject *code,
331333
ngx_event_t *wake)
332334
{
333-
PyObject *result, *pr;
335+
PyObject *result, *old;
334336
ngx_http_python_ctx_t *ctx;
335337
ngx_http_core_loc_conf_t *clcf;
336338

@@ -347,18 +349,16 @@ ngx_http_python_eval(ngx_http_request_t *r, PyCodeObject *code,
347349
ngx_http_set_ctx(r, ctx, ngx_http_python_module);
348350
}
349351

350-
if (ctx->request == NULL) {
351-
ctx->request = ngx_http_python_request_create(r);
352-
if (ctx->request == NULL) {
353-
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
354-
"python error: %s", ngx_python_get_error(r->pool));
352+
if (ctx->python == NULL) {
353+
ctx->python = ngx_python_create_ctx(r->pool, r->connection->log);
354+
if (ctx->python == NULL) {
355355
return NULL;
356356
}
357357
}
358358

359-
if (ctx->python == NULL) {
360-
ctx->python = ngx_python_create_ctx(r->pool, r->connection->log);
361-
if (ctx->python == NULL) {
359+
if (ctx->request == NULL) {
360+
ctx->request = ngx_http_python_request_create(r);
361+
if (ctx->request == NULL) {
362362
return NULL;
363363
}
364364
}
@@ -368,23 +368,11 @@ ngx_http_python_eval(ngx_http_request_t *r, PyCodeObject *code,
368368
ngx_python_set_resolver(ctx->python, clcf->resolver,
369369
clcf->resolver_timeout);
370370

371-
pr = PyDict_GetItemString(ctx->python->ns, "r");
372-
373-
if (pr == NULL) {
374-
if (PyDict_SetItemString(ctx->python->ns, "r", ctx->request) < 0) {
375-
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
376-
"python error: %s", ngx_python_get_error(r->pool));
377-
}
378-
}
371+
old = ngx_python_set_value(ctx->python, "r", ctx->request);
379372

380373
result = ngx_python_eval(ctx->python, code, wake);
381374

382-
if (pr == NULL) {
383-
if (PyDict_DelItemString(ctx->python->ns, "r") < 0) {
384-
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
385-
"python error: %s", ngx_python_get_error(r->pool));
386-
}
387-
}
375+
ngx_python_reset_value(ctx->python, "r", old);
388376

389377
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
390378
"http python eval end code:%p, wake:%p, result:%p",
@@ -430,32 +418,6 @@ ngx_http_python_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
430418
}
431419

432420

433-
static ngx_int_t
434-
ngx_http_python_init(ngx_conf_t *cf)
435-
{
436-
ngx_http_handler_pt *h;
437-
ngx_http_core_main_conf_t *cmcf;
438-
439-
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
440-
441-
h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
442-
if (h == NULL) {
443-
return NGX_ERROR;
444-
}
445-
446-
*h = ngx_http_python_access_handler;
447-
448-
h = ngx_array_push(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers);
449-
if (h == NULL) {
450-
return NGX_ERROR;
451-
}
452-
453-
*h = ngx_http_python_log_handler;
454-
455-
return NGX_OK;
456-
}
457-
458-
459421
static char *
460422
ngx_http_python_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
461423
{
@@ -479,10 +441,6 @@ ngx_http_python_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
479441
return NGX_CONF_ERROR;
480442
}
481443

482-
if (ngx_http_python_init_namespace(cf) != NGX_OK) {
483-
return NGX_CONF_ERROR;
484-
}
485-
486444
code = ngx_python_compile(cf, value[2].data);
487445
if (code == NULL) {
488446
return NGX_CONF_ERROR;
@@ -517,10 +475,6 @@ ngx_http_python_access(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
517475
return NGX_CONF_ERROR;
518476
}
519477

520-
if (ngx_http_python_init_namespace(cf) != NGX_OK) {
521-
return NGX_CONF_ERROR;
522-
}
523-
524478
*pcode = ngx_python_compile(cf, value[1].data);
525479
if (*pcode == NULL) {
526480
return NGX_CONF_ERROR;
@@ -552,10 +506,6 @@ ngx_http_python_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
552506
return NGX_CONF_ERROR;
553507
}
554508

555-
if (ngx_http_python_init_namespace(cf) != NGX_OK) {
556-
return NGX_CONF_ERROR;
557-
}
558-
559509
*pcode = ngx_python_compile(cf, value[1].data);
560510
if (*pcode == NULL) {
561511
return NGX_CONF_ERROR;
@@ -579,10 +529,6 @@ ngx_http_python_content(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
579529
return "is duplicate";
580530
}
581531

582-
if (ngx_http_python_init_namespace(cf) != NGX_OK) {
583-
return NGX_CONF_ERROR;
584-
}
585-
586532
plcf->content = ngx_python_compile(cf, value[1].data);
587533
if (plcf->content == NULL) {
588534
return NGX_CONF_ERROR;
@@ -597,15 +543,34 @@ ngx_http_python_content(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
597543

598544

599545
static ngx_int_t
600-
ngx_http_python_init_namespace(ngx_conf_t *cf)
546+
ngx_http_python_init(ngx_conf_t *cf)
601547
{
602-
if (ngx_python_get_namespace(cf) == NULL) {
603-
return NGX_ERROR;
548+
ngx_http_handler_pt *h;
549+
ngx_http_core_main_conf_t *cmcf;
550+
551+
if (ngx_python_active(cf) != NGX_OK) {
552+
return NGX_OK;
604553
}
605554

606555
if (ngx_http_python_request_init(cf) != NGX_OK) {
607556
return NGX_ERROR;
608557
}
609558

559+
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
560+
561+
h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
562+
if (h == NULL) {
563+
return NGX_ERROR;
564+
}
565+
566+
*h = ngx_http_python_access_handler;
567+
568+
h = ngx_array_push(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers);
569+
if (h == NULL) {
570+
return NGX_ERROR;
571+
}
572+
573+
*h = ngx_http_python_log_handler;
574+
610575
return NGX_OK;
611576
}

0 commit comments

Comments
 (0)