diff --git a/cherokee/admin/ModuleUwsgi.py b/cherokee/admin/ModuleUwsgi.py
index f85e18c2..afdbcb32 100644
--- a/cherokee/admin/ModuleUwsgi.py
+++ b/cherokee/admin/ModuleUwsgi.py
@@ -16,7 +16,11 @@ HELPS = [
class ModuleUwsgi (ModuleCgiBase):
PROPERTIES = ModuleCgiBase.PROPERTIES + [
- 'balancer'
+ 'balancer',
+ 'modifier1',
+ 'modifier2',
+ 'pass_wsgi_vars',
+ 'pass_request_body'
]
def __init__ (self, cfg, prefix, submit):
@@ -32,13 +36,45 @@ class ModuleUwsgi (ModuleCgiBase):
txt += '
%s
' % (_('UWSGI specific'))
table = TableProps()
- prefix = "%s!balancer" % (self._prefix)
- e = self.AddPropOptions_Reload_Module (table, _("Balancer"), prefix,
+
+
+ opt = "%s!modifier1" % (self._prefix)
+ self.AddPropEntry(table, _('Modifier1'), opt, 'a number between 0 and 255', size=3);
+
+ opt = "%s!modifier2" % (self._prefix)
+ self.AddPropEntry(table, _('Modifier2'), opt, 'a number between 0 and 255', size=3);
+
+ opt = "%s!pass_wsgi_vars" % (self._prefix)
+ self.AddPropCheck (table, _("Pass WSGI vars"), opt, True, 'pass all the wsgi vars to the application')
+
+ opt = "%s!pass_request_body" % (self._prefix)
+ self.AddPropCheck (table, _("Pass Request body"), opt, True, 'pass the request body to the application')
+
+ opt = "%s!balancer" % (self._prefix)
+ e = self.AddPropOptions_Reload_Module (table, _("Balancer"), opt,
modules_available(BALANCERS), _(NOTE_BALANCER))
+
txt += self.Indent(str(table) + e)
+
return txt
def _op_apply_changes (self, uri, post):
+
+ # Apply modifier1
+ opt = "%s!modifier1" % (self._prefix)
+ mod1 = post.pop(opt)
+ if mod1:
+ self._cfg[opt] = mod1
+
+ # Apply modifier2
+ opt = "%s!modifier2" % (self._prefix)
+ mod2 = post.pop(opt)
+ if mod2:
+ self._cfg[opt] = mod2
+
+ # Apply pass_request_body and pass_wsgi_vars
+ self.ApplyChangesPrefix (self._prefix, ['pass_wsgi_vars','pass_request_body'], post)
+
# Apply balancer changes
pre = "%s!balancer" % (self._prefix)
diff --git a/cherokee/handler_uwsgi.c b/cherokee/handler_uwsgi.c
index 36489a37..935cfad4 100644
--- a/cherokee/handler_uwsgi.c
+++ b/cherokee/handler_uwsgi.c
@@ -20,7 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
- */
+ */
#include "common-internal.h"
#include "handler_uwsgi.h"
@@ -38,9 +38,15 @@
*/
CGI_LIB_INIT (uwsgi, http_all_methods);
+#if BYTE_ORDER == BIG_ENDIAN
+static uint16_t uwsgi_swap16(uint16_t x) {
+ return (uint16_t) ((x & 0xff) << 8 | (x & 0xff00) >> 8);
+}
+#endif
+
/* Methods implementation
*/
-static ret_t
+static ret_t
props_free (cherokee_handler_uwsgi_props_t *props)
{
if (props->balancer)
@@ -49,27 +55,31 @@ props_free (cherokee_handler_uwsgi_props_t *props)
return cherokee_handler_cgi_base_props_free (PROP_CGI_BASE(props));
}
-ret_t
+ret_t
cherokee_handler_uwsgi_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props)
{
ret_t ret;
cherokee_list_t *i;
cherokee_handler_uwsgi_props_t *props;
-
+
/* Instance a new property object
*/
if (*_props == NULL) {
CHEROKEE_NEW_STRUCT (n, handler_uwsgi_props);
- cherokee_handler_cgi_base_props_init_base (PROP_CGI_BASE(n),
+ cherokee_handler_cgi_base_props_init_base (PROP_CGI_BASE(n),
MODULE_PROPS_FREE(props_free));
n->balancer = NULL;
+ n->modifier1 = 0 ;
+ n->modifier2 = 0 ;
+ n->pass_wsgi_vars = true;
+ n->pass_request_body = true;
*_props = MODULE_PROPS(n);
}
- props = PROP_UWSGI(*_props);
+ props = PROP_UWSGI(*_props);
/* Parse the configuration tree
*/
@@ -77,9 +87,21 @@ cherokee_handler_uwsgi_configure (cherokee_config_node_t *conf, cherokee_server_
cherokee_config_node_t *subconf = CONFIG_NODE(i);
if (equal_buf_str (&subconf->key, "balancer")) {
- ret = cherokee_balancer_instance (&subconf->val, subconf, srv, &props->balancer);
+ ret = cherokee_balancer_instance (&subconf->val, subconf, srv, &props->balancer);
if (ret != ret_ok) return ret;
}
+ else if (equal_buf_str (&subconf->key, "modifier1")) {
+ props->modifier1 = (uint8_t) atoi(subconf->val.buf);
+ }
+ else if (equal_buf_str (&subconf->key, "modifier2")) {
+ props->modifier2 = (uint8_t) atoi(subconf->val.buf);
+ }
+ else if (equal_buf_str (&subconf->key, "pass_wsgi_vars")) {
+ props->pass_wsgi_vars = !! atoi (subconf->val.buf);
+ }
+ else if (equal_buf_str (&subconf->key, "pass_request_body")) {
+ props->pass_request_body = !! atoi (subconf->val.buf);
+ }
}
/* Init base class
@@ -90,7 +112,7 @@ cherokee_handler_uwsgi_configure (cherokee_config_node_t *conf, cherokee_server_
/* Final checks
*/
if (props->balancer == NULL) {
- LOG_CRITICAL_S ("ERROR: UWSGI handler needs a balancer\n");
+ LOG_CRITICAL_S (CHEROKEE_ERROR_HANDLER_NO_BALANCER);
return ret_error;
}
@@ -98,24 +120,35 @@ cherokee_handler_uwsgi_configure (cherokee_config_node_t *conf, cherokee_server_
}
-static void
-add_env_pair (cherokee_handler_cgi_base_t *cgi_base,
- const char *key, int key_len,
+static void
+add_env_pair (cherokee_handler_cgi_base_t *cgi_base,
+ const char *key, int key_len,
const char *val, int val_len)
{
cherokee_handler_uwsgi_t *uwsgi = HDL_UWSGI(cgi_base);
- unsigned short u_key_len = (unsigned short) key_len ;
- unsigned short u_val_len = (unsigned short) val_len ;
+ uint16_t u_key_len = (uint16_t) key_len ;
+ uint16_t u_val_len = (uint16_t) val_len ;
/* 2 bytes for every string (16 bit le) */
cherokee_buffer_ensure_size (&uwsgi->header, uwsgi->header.len + key_len + val_len + 4);
- /* TODO: force to le if cherokee is big-endian */
-
+ /* force to le if cherokee is big-endian */
+#if BYTE_ORDER == BIG_ENDIAN
+ u_key_len = uwsgi_swap16(u_key_len);
+#endif
cherokee_buffer_add (&uwsgi->header, (const char *) &u_key_len, 2);
+#if BYTE_ORDER == BIG_ENDIAN
+ u_key_len = uwsgi_swap16(u_key_len);
+#endif
cherokee_buffer_add (&uwsgi->header, key, key_len);
+#if BYTE_ORDER == BIG_ENDIAN
+ u_val_len = uwsgi_swap16(u_val_len);
+#endif
cherokee_buffer_add (&uwsgi->header, (const char *) &u_val_len, 2);
+#if BYTE_ORDER == BIG_ENDIAN
+ u_val_len = uwsgi_swap16(u_val_len);
+#endif
cherokee_buffer_add (&uwsgi->header, val, val_len);
}
@@ -126,12 +159,12 @@ read_from_uwsgi (cherokee_handler_cgi_base_t *cgi_base, cherokee_buffer_t *buffe
ret_t ret;
size_t read = 0;
cherokee_handler_uwsgi_t *uwsgi = HDL_UWSGI(cgi_base);
-
+
ret = cherokee_socket_bufread (&uwsgi->socket, buffer, 4096, &read);
switch (ret) {
case ret_eagain:
- cherokee_thread_deactive_to_polling (HANDLER_THREAD(cgi_base), HANDLER_CONN(cgi_base),
+ cherokee_thread_deactive_to_polling (HANDLER_THREAD(cgi_base), HANDLER_CONN(cgi_base),
uwsgi->socket.socket, 0, false);
return ret_eagain;
@@ -149,20 +182,20 @@ read_from_uwsgi (cherokee_handler_cgi_base_t *cgi_base, cherokee_buffer_t *buffe
}
SHOULDNT_HAPPEN;
- return ret_error;
+ return ret_error;
}
-ret_t
+ret_t
cherokee_handler_uwsgi_new (cherokee_handler_t **hdl, void *cnt, cherokee_module_props_t *props)
{
CHEROKEE_NEW_STRUCT (n, handler_uwsgi);
-
+
/* Init the base class
*/
cherokee_handler_cgi_base_init (
HDL_CGI_BASE(n), cnt,
- PLUGIN_INFO_HANDLER_PTR(uwsgi),
+ PLUGIN_INFO_HANDLER_PTR(uwsgi),
HANDLER_PROPS(props),
add_env_pair, read_from_uwsgi);
@@ -187,11 +220,11 @@ cherokee_handler_uwsgi_new (cherokee_handler_t **hdl, void *cnt, cherokee_module
/* Return the object
*/
*hdl = HANDLER(n);
- return ret_ok;
+ return ret_ok;
}
-ret_t
+ret_t
cherokee_handler_uwsgi_free (cherokee_handler_uwsgi_t *hdl)
{
/* Free the rest of the handler CGI memory
@@ -210,14 +243,18 @@ cherokee_handler_uwsgi_free (cherokee_handler_uwsgi_t *hdl)
static ret_t
-uwsgi_fix_packet (cherokee_buffer_t *buf)
+uwsgi_fix_packet (cherokee_buffer_t *buf, uint8_t modifier1, uint8_t modifier2)
{
uwsgi_header uh;
- uh.arg1 = 0 ;
- uh.arg2 = 0 ;
- uh.env_size = (unsigned short) buf->len ;
+ uh.modifier1 = modifier1 ;
+ uh.modifier2 = modifier2 ;
+#if BYTE_ORDER == BIG_ENDIAN
+ uh.env_size = uwsgi_swap16((uint16_t) buf->len) ;
+#else
+ uh.env_size = (uint16_t) buf->len ;
+#endif
/* TODO: check endianess */
@@ -231,22 +268,27 @@ uwsgi_fix_packet (cherokee_buffer_t *buf)
static ret_t
build_header (cherokee_handler_uwsgi_t *hdl)
{
+
+ cherokee_handler_uwsgi_props_t *props = HANDLER_UWSGI_PROPS(hdl);
cuint_t len;
char tmp[64];
- len = snprintf (tmp, sizeof(tmp), FMT_OFFSET, (CST_OFFSET)hdl->post_len);
+ if (props->pass_request_body == true && props->pass_wsgi_vars == true) {
+ len = snprintf (tmp, sizeof(tmp), FMT_OFFSET, (CST_OFFSET)hdl->post_len);
+ add_env_pair(HDL_CGI_BASE(hdl), "CONTENT_LENGTH", 14, tmp, len);
+ }
- add_env_pair(HDL_CGI_BASE(hdl), "CONTENT_LENGTH", 14, tmp, len);
+ if (props->pass_wsgi_vars == true) {
+ cherokee_handler_cgi_base_build_envp (HDL_CGI_BASE(hdl), HANDLER_CONN(hdl));
+ }
- cherokee_handler_cgi_base_build_envp (HDL_CGI_BASE(hdl), HANDLER_CONN(hdl));
-
- return uwsgi_fix_packet (&hdl->header);
+ return uwsgi_fix_packet (&hdl->header, props->modifier1, props->modifier2);
}
-static ret_t
+static ret_t
connect_to_server (cherokee_handler_uwsgi_t *hdl)
{
ret_t ret;
@@ -284,14 +326,14 @@ send_header (cherokee_handler_uwsgi_t *hdl)
ret_t ret;
size_t written = 0;
cherokee_connection_t *conn = HANDLER_CONN(hdl);
-
+
ret = cherokee_socket_bufwrite (&hdl->socket, &hdl->header, &written);
if (ret != ret_ok) {
conn->error_code = http_bad_gateway;
return ret;
}
-#if 0
+#if 0
cherokee_buffer_print_debug (&hdl->header, -1);
#endif
cherokee_buffer_move_to_begin (&hdl->header, written);
@@ -300,7 +342,7 @@ send_header (cherokee_handler_uwsgi_t *hdl)
if (! cherokee_buffer_is_empty (&hdl->header))
return ret_eagain;
-
+
return ret_ok;
}
@@ -312,9 +354,9 @@ send_post (cherokee_handler_uwsgi_t *hdl)
int e_fd = -1;
int mode = 0;
cherokee_connection_t *conn = HANDLER_CONN(hdl);
-
+
ret = cherokee_post_walk_to_fd (&conn->post, hdl->socket.socket, &e_fd, &mode);
-
+
switch (ret) {
case ret_ok:
break;
@@ -331,24 +373,25 @@ send_post (cherokee_handler_uwsgi_t *hdl)
}
-ret_t
+ret_t
cherokee_handler_uwsgi_init (cherokee_handler_uwsgi_t *hdl)
{
ret_t ret;
cherokee_connection_t *conn = HANDLER_CONN(hdl);
+ cherokee_handler_uwsgi_props_t *props = HANDLER_UWSGI_PROPS(hdl);
switch (HDL_CGI_BASE(hdl)->init_phase) {
case hcgi_phase_build_headers:
TRACE (ENTRIES, "Init: %s\n", "begins");
- /* Extracts PATH_INFO and filename from request uri
+ /* Extracts PATH_INFO and filename from request uri
*/
ret = cherokee_handler_cgi_base_extract_path (HDL_CGI_BASE(hdl), false);
if (unlikely (ret < ret_ok)) {
conn->error_code = http_internal_error;
return ret_error;
}
-
+
/* Prepare Post
*/
if (! cherokee_post_is_empty (&conn->post)) {
@@ -369,7 +412,7 @@ cherokee_handler_uwsgi_init (cherokee_handler_uwsgi_t *hdl)
case hcgi_phase_connect:
TRACE (ENTRIES, "Init: %s\n", "connect");
- /* Connect
+ /* Connect
*/
ret = connect_to_server (hdl);
switch (ret) {
@@ -384,7 +427,7 @@ cherokee_handler_uwsgi_init (cherokee_handler_uwsgi_t *hdl)
conn->error_code = http_service_unavailable;
return ret_error;
}
-
+
HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_send_headers;
case hcgi_phase_send_headers:
@@ -393,7 +436,7 @@ cherokee_handler_uwsgi_init (cherokee_handler_uwsgi_t *hdl)
/* Send the header
*/
ret = send_header (hdl);
- if (ret != ret_ok)
+ if (ret != ret_ok)
return ret;
HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_send_post;
@@ -401,7 +444,7 @@ cherokee_handler_uwsgi_init (cherokee_handler_uwsgi_t *hdl)
case hcgi_phase_send_post:
/* Send the Post
*/
- if (hdl->post_len > 0) {
+ if (hdl->post_len > 0 && props->pass_request_body == true) {
return send_post (hdl);
}
break;
diff --git a/cherokee/handler_uwsgi.h b/cherokee/handler_uwsgi.h
index a666ec7b..2283c027 100644
--- a/cherokee/handler_uwsgi.h
+++ b/cherokee/handler_uwsgi.h
@@ -20,7 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
- */
+ */
#ifndef CHEROKEE_HANDLER_UWSGI_H
#define CHEROKEE_HANDLER_UWSGI_H
@@ -35,15 +35,19 @@
#include "balancer.h"
typedef struct __attribute__((packed)) {
- unsigned char arg1;
- unsigned short env_size;
- unsigned char arg2;
+ uint8_t modifier1;
+ uint16_t env_size;
+ uint8_t modifier2;
} uwsgi_header ;
typedef struct {
cherokee_handler_cgi_base_t base;
cherokee_balancer_t *balancer;
+ uint8_t modifier1;
+ uint8_t modifier2;
+ cherokee_boolean_t pass_wsgi_vars;
+ cherokee_boolean_t pass_request_body;
} cherokee_handler_uwsgi_props_t;
@@ -60,7 +64,7 @@ typedef struct {
#define PROP_UWSGI(x) ((cherokee_handler_uwsgi_props_t *)(x))
#define HANDLER_UWSGI_PROPS(x) (PROP_UWSGI(MODULE(x)->props))
-
+
/* Library init function
*/
void PLUGIN_INIT_NAME(uwsgi) (cherokee_plugin_loader_t *loader);
diff --git a/uwsgi.c b/uwsgi.c
index f0da0d68..af6883f1 100644
--- a/uwsgi.c
+++ b/uwsgi.c
@@ -1413,7 +1413,6 @@ int main(int argc, char *argv[], char *envp[]) {
continue;
}
-
if (wsgi_req.modifier == UWSGI_MODIFIER_FASTFUNC) {
zero = PyList_GetItem(uwsgi_fastfuncslist, wsgi_req.modifier_arg) ;
if (zero) {
diff --git a/uwsgi.h b/uwsgi.h
index 5a8e59fd..f0377685 100644
--- a/uwsgi.h
+++ b/uwsgi.h
@@ -103,9 +103,9 @@ struct __attribute__((packed)) uwsgi_worker {
};
struct __attribute__((packed)) wsgi_request {
- unsigned char modifier;
- unsigned short size ;
- unsigned char modifier_arg;
+ uint8_t modifier;
+ uint16_t size ;
+ uint8_t modifier_arg;
// temporary attr
#ifndef ROCK_SOLID
int app_id ;