gratily improved the php plugin

This commit is contained in:
roberto@oneiric64
2011-12-21 15:00:14 +01:00
parent fcd1a36420
commit 545f3ee608
7 changed files with 240 additions and 38 deletions
+6 -1
View File
@@ -415,7 +415,7 @@ int uwsgi_cgi_walk(struct wsgi_request *wsgi_req, char *full_path, char *docroot
// not a directory, stop walking
if (!S_ISDIR(st.st_mode)) {
if (i < (wsgi_req->path_info_len-discard_base)-1) {
*path_info = ptr + i + 1;
*path_info = ptr + i;
}
return 0;
@@ -736,6 +736,11 @@ clear:
uwsgi_error("setenv()");
}
// for newer php
if (setenv("REDIRECT_STATUS", "200", 0)) {
uwsgi_error("setenv()");
}
if (path_info && wsgi_req->path_info_len-discard_base > 0) {
if (setenv("PATH_INFO", uwsgi_concat2n(path_info, wsgi_req->path_info_len-discard_base, "", 0), 1)) {
uwsgi_error("setenv()");
+1 -1
View File
@@ -40,7 +40,7 @@ extern "C" int uwsgi_cplusplus_request(struct wsgi_request *wsgi_req) {
fc = new FakeClass();
// get PATH_INFO
fc->foobar = uwsgi_get_var(wsgi_req, (char *) "PATH_INFO", &fc->foobar_len);
fc->foobar = uwsgi_get_var(wsgi_req, (char *) "PATH_INFO", 9, &fc->foobar_len);
if (fc->foobar) {
// send output
+217 -18
View File
@@ -9,21 +9,43 @@
extern struct uwsgi_server uwsgi;
// http status codes list
extern struct http_status_codes hsc[];
static int sapi_uwsgi_ub_write(const char *str, uint str_length TSRMLS_DC)
{
struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);
size_t len = wsgi_req->socket->proto_write(wsgi_req, (char *) str, str_length);
ssize_t len = wsgi_req->socket->proto_write(wsgi_req, (char *) str, str_length);
if (len != str_length) {
php_handle_aborted_connection();
return -1;
}
wsgi_req->response_size += len;
return len;
return str_length;
}
void uwsgi_php_404(struct wsgi_request *wsgi_req) {
wsgi_req->status = 404;
wsgi_req->headers_size += wsgi_req->socket->proto_write(wsgi_req, "HTTP/1.0 404 Not Found\r\n\r\nNot Found", 35);
}
void uwsgi_php_403(struct wsgi_request *wsgi_req) {
wsgi_req->status = 403;
wsgi_req->headers_size += wsgi_req->socket->proto_write(wsgi_req, "HTTP/1.0 403 Forbidden\r\n\r\nForbidden", 35);
}
static int sapi_uwsgi_send_headers(sapi_headers_struct *sapi_headers)
{
sapi_header_struct *h;
zend_llist_position pos;
struct iovec iov[4];
struct iovec iov[6];
char status[4];
struct http_status_codes *http_sc;
struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);
wsgi_req->status = SG(sapi_headers).http_response_code;
@@ -41,10 +63,27 @@ static int sapi_uwsgi_send_headers(sapi_headers_struct *sapi_headers)
iov[2].iov_base = status;
iov[2].iov_len = 3;
iov[3].iov_base = " Test\r\n";
iov[3].iov_len = 7;
iov[3].iov_base = " ";
iov[3].iov_len = 1;
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, iov, 4);
// get the status code
for (http_sc = hsc; http_sc->message != NULL; http_sc++) {
if (!strncmp(http_sc->key, status, 3)) {
iov[4].iov_base = (char *) http_sc->message;
iov[4].iov_len = http_sc->message_size;
break;
}
}
if (iov[4].iov_len == 0) {
iov[4].iov_base = "Unknown";
iov[4].iov_len = 7;
}
iov[5].iov_base = "\r\n";
iov[5].iov_len = 2;
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, iov, 6);
h = zend_llist_get_first_ex(&sapi_headers->headers, &pos);
while (h) {
@@ -66,29 +105,54 @@ static int sapi_uwsgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
{
uint read_bytes = 0;
size_t len;
int fd = -1;
struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);
if (wsgi_req->body_as_file) {
fd = fileno((FILE *)wsgi_req->async_post);
}
else if (uwsgi.post_buffering > 0) {
if (wsgi_req->post_cl > (size_t) uwsgi.post_buffering) {
fd = fileno((FILE *)wsgi_req->async_post);
}
}
else {
fd = wsgi_req->poll.fd;
}
count_bytes = MIN(count_bytes, wsgi_req->post_cl - SG(read_post_bytes));
// data in memory
if (fd == -1) {
if (count_bytes > 0) {
memcpy(buffer, wsgi_req->post_buffering_buf + wsgi_req->post_pos, count_bytes);
wsgi_req->post_pos += count_bytes;
}
return count_bytes;
}
while (read_bytes < count_bytes) {
len = read(wsgi_req->poll.fd, buffer + read_bytes, count_bytes - read_bytes);
len = read(fd, buffer + read_bytes, count_bytes - read_bytes);
if (len <= 0) {
break;
}
read_bytes += len;
}
return read_bytes;
}
static char *sapi_uwsgi_read_cookies(void)
{
int i;
uint16_t len = 0;
struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
if (!uwsgi_strncmp((char *)"HTTP_COOKIE", 11, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len)) {
return estrndup(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
}
char *cookie = uwsgi_get_var(wsgi_req, (char *)"HTTP_COOKIE", 11, &len);
if (cookie) {
return estrndup(cookie, len);
}
return NULL;
@@ -106,7 +170,21 @@ static void sapi_uwsgi_register_variables(zval *track_vars_array TSRMLS_DC)
track_vars_array TSRMLS_CC);
}
php_register_variable_safe("PHP_SELF", wsgi_req->path_info, wsgi_req->path_info_len, track_vars_array TSRMLS_CC);
php_register_variable_safe("PATH_INFO", wsgi_req->path_info, wsgi_req->path_info_len, track_vars_array TSRMLS_CC);
php_register_variable_safe("SCRIPT_NAME", wsgi_req->script_name, wsgi_req->script_name_len, track_vars_array TSRMLS_CC);
php_register_variable_safe("SCRIPT_FILENAME", wsgi_req->file, wsgi_req->file_len, track_vars_array TSRMLS_CC);
if (wsgi_req->path_info_len) {
char *path_translated = ecalloc(1, (wsgi_req->file_len - wsgi_req->script_name_len) + wsgi_req->path_info_len + 1);
memcpy(path_translated, wsgi_req->file, (wsgi_req->file_len - wsgi_req->script_name_len));
memcpy(path_translated + (wsgi_req->file_len - wsgi_req->script_name_len), wsgi_req->path_info, wsgi_req->path_info_len);
php_register_variable_safe("PATH_TRANSLATED", path_translated, (wsgi_req->file_len - wsgi_req->script_name_len) + wsgi_req->path_info_len , track_vars_array TSRMLS_CC);
}
php_register_variable_safe("PHP_SELF", wsgi_req->script_name, wsgi_req->script_name_len, track_vars_array TSRMLS_CC);
}
@@ -124,8 +202,6 @@ static int php_uwsgi_startup(sapi_module_struct *sapi_module)
static void sapi_uwsgi_log_message(char *message) {
TSRMLS_FETCH();
uwsgi_log(message);
}
@@ -162,23 +238,142 @@ static sapi_module_struct uwsgi_sapi_module = {
int uwsgi_php_init(void) {
struct http_status_codes *http_sc;
sapi_startup(&uwsgi_sapi_module);
uwsgi_sapi_module.startup(&uwsgi_sapi_module);
uwsgi_log("*** PHP plugin initialized ***\n");
// filling http status codes
for (http_sc = hsc; http_sc->message != NULL; http_sc++) {
http_sc->message_size = strlen(http_sc->message);
}
uwsgi_log("*** PHP %s plugin initialized ***\n", PHP_VERSION);
return 0;
}
int uwsgi_php_walk(struct wsgi_request *wsgi_req, char *full_path, char *docroot, size_t docroot_len, char **path_info) {
// and now start walking...
uint16_t i;
char *ptr = wsgi_req->path_info;
char *dst = full_path+docroot_len;
char *part = ptr;
int part_size = 0;
struct stat st;
if (ptr[0] == '/') part_size++;
for(i=0;i<wsgi_req->path_info_len;i++) {
if (ptr[i] == '/') {
memcpy(dst, part, part_size-1);
*(dst+part_size-1) = 0;
if (stat(full_path, &st)) {
uwsgi_php_404(wsgi_req);
return -1;
}
// not a directory, stop walking
if (!S_ISDIR(st.st_mode)) {
if (i < (wsgi_req->path_info_len)-1) {
*path_info = ptr + i;
}
return 0;
}
// check for buffer overflow !!!
*(dst+part_size-1) = '/';
*(dst+part_size) = 0;
dst += part_size ;
part_size = 0;
part = ptr + i + 1;
}
part_size++;
}
if (part < wsgi_req->path_info+wsgi_req->path_info_len) {
memcpy(dst, part, part_size-1);
*(dst+part_size-1) = 0;
}
return 0;
}
int uwsgi_php_request(struct wsgi_request *wsgi_req) {
char real_filename[PATH_MAX+1];
uint16_t docroot_len = 0;
char *path_info = NULL;
zend_file_handle file_handle;
SG(server_context) = (void *) wsgi_req;
if (uwsgi_parse_vars(wsgi_req)) {
return -1;
}
char *docroot = uwsgi_get_var(wsgi_req, (char *) "DOCUMENT_ROOT", 13, &docroot_len);
if (!docroot) {
docroot = uwsgi.cwd;
docroot_len = strlen(uwsgi.cwd);
}
char *filename = uwsgi_concat4n(docroot, docroot_len, "/", 1, wsgi_req->path_info, wsgi_req->path_info_len, "", 0);
if (uwsgi_php_walk(wsgi_req, filename, docroot, docroot_len, &path_info)) {
free(filename);
return -1;
}
if (path_info) {
wsgi_req->path_info = path_info;
wsgi_req->path_info_len = strlen(wsgi_req->path_info);
}
else {
wsgi_req->path_info = "";
wsgi_req->path_info_len = 0;
}
if (!realpath(filename, real_filename)) {
free(filename);
uwsgi_php_404(wsgi_req);
return -1;
}
free(filename);
wsgi_req->file = real_filename;
wsgi_req->file_len = strlen(wsgi_req->file);
if (docroot[docroot_len-1] == '/') {
wsgi_req->script_name = real_filename + (docroot_len-1);
}
else {
wsgi_req->script_name = real_filename + docroot_len;
}
wsgi_req->script_name_len = strlen(wsgi_req->script_name);
#ifdef UWSGI_DEBUG
uwsgi_log("php filename = %s\n", real_filename);
#endif
// now check for allowed paths and extensions
SG(request_info).request_uri = estrndup(wsgi_req->uri, wsgi_req->uri_len);
SG(request_info).request_method = estrndup(wsgi_req->method, wsgi_req->method_len);
SG(request_info).proto_num = 1001;
@@ -187,12 +382,16 @@ int uwsgi_php_request(struct wsgi_request *wsgi_req) {
SG(request_info).content_length = wsgi_req->post_cl;
SG(request_info).content_type = estrndup(wsgi_req->content_type, wsgi_req->content_type_len);
SG(request_info).path_translated = wsgi_req->file;
file_handle.type = ZEND_HANDLE_FILENAME;
file_handle.filename = uwsgi_concat3n("/root/uwsgi/", 12, wsgi_req->path_info, wsgi_req->path_info_len, "", 0);
file_handle.free_filename = 1;
file_handle.filename = real_filename;
file_handle.free_filename = 0;
file_handle.opened_path = NULL;
if (php_request_startup(TSRMLS_C) == FAILURE) {
internal_server_error(wsgi_req, "unable to start php request");
return -1;
}
+1 -1
View File
@@ -87,7 +87,7 @@ XS(XS_input_read) {
}
else if (uwsgi.post_buffering > 0) {
fd = -1;
if (wsgi_req->post_cl <= (size_t) uwsgi.post_buffering) {
if (wsgi_req->post_cl > (size_t) uwsgi.post_buffering) {
fd = fileno((FILE *)wsgi_req->async_post);
}
}
-15
View File
@@ -1688,18 +1688,3 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
return -1;
}
char *uwsgi_get_var(struct wsgi_request *wsgi_req, char *key, uint16_t *len) {
int i;
*len = 0;
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
if (!uwsgi_strncmp(key, strlen(key), wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len)) {
*len = wsgi_req->hvec[i + 1].iov_len;
return wsgi_req->hvec[i + 1].iov_base;
}
}
return NULL;
}
+14
View File
@@ -3553,6 +3553,20 @@ void http_url_decode(char *buf, uint16_t *len, char *dst) {
}
char *uwsgi_get_var(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *len) {
int i;
for (i = 0; i < wsgi_req->var_cnt; i += 2) {
if (!uwsgi_strncmp(key, keylen, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len)) {
*len = wsgi_req->hvec[i + 1].iov_len;
return wsgi_req->hvec[i + 1].iov_base;
}
}
return NULL;
}
void uwsgi_add_app(int id, uint8_t modifier1, char *mountpoint, int mountpoint_len) {
struct uwsgi_app *wi = &uwsgi_apps[id];
+1 -2
View File
@@ -2436,8 +2436,6 @@ int uwsgi_signal_registered(uint8_t);
int uwsgi_endswith(char *, char *);
char *uwsgi_get_var(struct wsgi_request *, char *, uint16_t *);
int uwsgi_cache_server(char *, int);
void uwsgi_chown(char *, char *);
@@ -2574,6 +2572,7 @@ void uwsgi_register_logger(char *, ssize_t (*func)(struct uwsgi_logger *, char *
struct uwsgi_logger *uwsgi_get_logger(char *);
char *uwsgi_getsockname(int);
char *uwsgi_get_var(struct wsgi_request *, char *, uint16_t, uint16_t *);
#ifdef UWSGI_AS_SHARED_LIBRARY
int uwsgi_init(int, char **, char **);