cellog          Sun Dec 23 21:12:41 2007 UTC

  Added files:                 
    /pecl/phar/tests    frontcontroller2.phpt frontcontroller3.phpt 

  Modified files:              
    /pecl/phar  phar.c phar_internal.h phar_object.c 
    /pecl/phar/tests    frontcontroller1.phpt 
  Log:
  complete re-factoring of front controller.  Now it is done with
  Phar->webPhar():
  <?php
  Phar::webPhar();
  __HALT_COMPILER();
  
  With the above stub, the default front controller will kick in.  An array of 
mime type overrides, and another
  array mapping phar file entry -> redirected entry can be used to further 
customize
  [DOC]
  
http://cvs.php.net/viewvc.cgi/pecl/phar/phar.c?r1=1.234&r2=1.235&diff_format=u
Index: pecl/phar/phar.c
diff -u pecl/phar/phar.c:1.234 pecl/phar/phar.c:1.235
--- pecl/phar/phar.c:1.234      Sat Dec 22 07:46:52 2007
+++ pecl/phar/phar.c    Sun Dec 23 21:12:41 2007
@@ -17,7 +17,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: phar.c,v 1.234 2007/12/22 07:46:52 cellog Exp $ */
+/* $Id: phar.c,v 1.235 2007/12/23 21:12:41 cellog Exp $ */
 
 #define PHAR_MAIN
 #include "phar_internal.h"
@@ -185,11 +185,6 @@
  */
 static void phar_destroy_phar_data(phar_archive_data *data TSRMLS_DC) /* {{{ */
 {
-       if (!PHAR_G(request_ends)) {
-               if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_web_map))) {
-                       zend_hash_del(&(PHAR_GLOBALS->phar_web_map), 
data->fname, data->fname_len);
-               }
-       }
        if (data->alias && data->alias != data->fname) {
                efree(data->alias);
                data->alias = NULL;
@@ -504,7 +499,7 @@
  * appended, truncated, or read.  For read, if the entry is marked unmodified, 
it is
  * assumed that the file pointer, if present, is opened for reading
  */
-static int phar_get_entry_data(phar_entry_data **ret, char *fname, int 
fname_len, char *path, int path_len, char *mode, char **error TSRMLS_DC) /* {{{ 
*/
+int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, 
char *path, int path_len, char *mode, char **error TSRMLS_DC) /* {{{ */
 {
        phar_archive_data *phar;
        phar_entry_info *entry;
@@ -1334,13 +1329,6 @@
        mydata->sig_len = sig_len;
        mydata->signature = signature;
        phar_request_initialize(TSRMLS_C);
-       if ((manifest_flags & PHAR_HDR_WEB) != 0) {
-               mydata->is_web = 1;
-               if (!zend_hash_num_elements(&(PHAR_GLOBALS->phar_mimes))) {
-                       phar_init_mime_list(TSRMLS_C);
-               }
-               zend_hash_add(&(PHAR_GLOBALS->phar_web_map), mydata->fname, 
fname_len, (void*)&mydata, sizeof(void*),  NULL);
-       }
        zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, 
fname_len, (void*)&mydata, sizeof(phar_archive_data*),  NULL);
        if (register_alias) {
                mydata->is_explicit_alias = 1;
@@ -2780,13 +2768,8 @@
        manifest_len = offset + archive->alias_len + sizeof(manifest) + 
main_metadata_str.len;
        phar_set_32(manifest, manifest_len);
        phar_set_32(manifest+4, new_manifest_count);
-       if (archive->is_web) {
-               *(manifest + 8) = (unsigned char) (((PHAR_API_VERSION_NOWEB) >> 
8) & 0xFF);
-               *(manifest + 9) = (unsigned char) (((PHAR_API_VERSION_NOWEB) & 
0xF0));
-       } else {
-               *(manifest + 8) = (unsigned char) (((PHAR_API_VERSION) >> 8) & 
0xFF);
-               *(manifest + 9) = (unsigned char) (((PHAR_API_VERSION) & 0xF0));
-       }
+       *(manifest + 8) = (unsigned char) (((PHAR_API_VERSION) >> 8) & 0xFF);
+       *(manifest + 9) = (unsigned char) (((PHAR_API_VERSION) & 0xF0));
        phar_set_32(manifest+10, global_flags);
        phar_set_32(manifest+14, archive->alias_len);
 
@@ -3867,159 +3850,6 @@
 }
 /* }}} */
 
-static void phar_init_mime_list(TSRMLS_D)
-{
-       phar_mime_type mime;
-#define PHAR_SET_MIME(mimetype, ret, ...) \
-       mime.mime = mimetype; \
-       mime.len = sizeof((mimetype))+1; \
-       mime.type = ret; \
-       { \
-               char mimes[][5] = {__VA_ARGS__, "\0"}; \
-               int i = 0; \
-               for (; mimes[i][0]; i++) { \
-                       zend_hash_add(&(PHAR_GLOBALS->phar_mimes), mimes[i], 
strlen(mimes[i]), (void *)&mime, sizeof(phar_mime_type), NULL); \
-               } \
-       }
-
-       PHAR_SET_MIME("text/html", PHAR_MIME_PHPS, "phps")
-       PHAR_SET_MIME("text/plain", PHAR_MIME_OTHER, "c", "cc", "cpp", "c++", 
"dtd", "h", "log", "rng", "txt", "xsd")
-       PHAR_SET_MIME("", PHAR_MIME_PHP, "php", "inc")
-       PHAR_SET_MIME("video/avi", PHAR_MIME_OTHER, "avi")
-       PHAR_SET_MIME("image/bmp", PHAR_MIME_OTHER, "bmp")
-       PHAR_SET_MIME("text/css", PHAR_MIME_OTHER, "css")
-       PHAR_SET_MIME("image/gif", PHAR_MIME_OTHER, "gif")
-       PHAR_SET_MIME("text/html", PHAR_MIME_OTHER, "htm", "html", "htmls")
-       PHAR_SET_MIME("image/x-ico", PHAR_MIME_OTHER, "ico")
-       PHAR_SET_MIME("image/jpeg", PHAR_MIME_OTHER, "jpe", "jpg", "jpeg")
-       PHAR_SET_MIME("application/x-javascript", PHAR_MIME_OTHER, "js")
-       PHAR_SET_MIME("audio/midi", PHAR_MIME_OTHER, "mid", "midi")
-       PHAR_SET_MIME("audio/mod", PHAR_MIME_OTHER, "mod")
-       PHAR_SET_MIME("movie/quicktime", PHAR_MIME_OTHER, "mov")
-       PHAR_SET_MIME("audio/mp3", PHAR_MIME_OTHER, "mp3")
-       PHAR_SET_MIME("video/mpeg", PHAR_MIME_OTHER, "mpg", "mpeg")
-       PHAR_SET_MIME("application/pdf", PHAR_MIME_OTHER, "pdf")
-       PHAR_SET_MIME("image/png", PHAR_MIME_OTHER, "png")
-       PHAR_SET_MIME("application/shockwave-flash", PHAR_MIME_OTHER, "swf")
-       PHAR_SET_MIME("image/tiff", PHAR_MIME_OTHER, "tif", "tiff")
-       PHAR_SET_MIME("audio/wav", PHAR_MIME_OTHER, "wav")
-       PHAR_SET_MIME("image/xbm", PHAR_MIME_OTHER, "xbm")
-       PHAR_SET_MIME("text/xml", PHAR_MIME_OTHER, "xml")
-}
-
-static int phar_file_type(char *file, char **mime_type TSRMLS_DC)
-{
-       char *ext;
-       phar_mime_type *mime;
-       if (!mime_type) {
-               /* assume PHP */
-               return 0;
-       }
-       ext = strrchr(file, '.');
-       if (!ext) {
-               *mime_type = "text/plain";
-               /* no file extension = assume text/plain */
-               return PHAR_MIME_OTHER;
-       }
-       ext++;
-       if (SUCCESS != zend_hash_find(&(PHAR_GLOBALS->phar_mimes), ext, 
strlen(ext), (void **) &mime)) {
-               *mime_type = "application/octet-stream";
-               return PHAR_MIME_OTHER;
-       }
-       *mime_type = mime->mime;
-       return mime->type;
-}
-/* }}} */
-
-static zend_op_array *phar_file_action(char *entry, int entry_len, char *arch, 
int arch_len, char **ourname TSRMLS_DC)
-{
-       char *mime_type, *name = NULL, buf[8192], *error;
-       zend_syntax_highlighter_ini syntax_highlighter_ini;
-       sapi_header_line ctr = {0};
-       zend_op_array *nada;
-       zend_op *opline;
-       phar_entry_data *phar;
-       size_t got;
-
-       *ourname = name;
-
-#define PHAR_NOP() \
-       nada = (zend_op_array *) emalloc(sizeof(zend_op_array)); \
-       init_op_array(nada, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE 
TSRMLS_CC); \
-       opline = get_next_op(nada TSRMLS_CC); \
-       opline->opcode = ZEND_RETURN; \
-       opline->op1.op_type = IS_CONST; \
-       INIT_ZVAL(opline->op1.u.constant); \
-       SET_UNUSED(opline->op2); \
-       ZEND_VM_SET_OPCODE_HANDLER(opline); \
-       nada->done_pass_two = 1; \
-       return nada;
-
-       switch (phar_file_type(entry, &mime_type TSRMLS_CC)) {
-               case PHAR_MIME_PHPS:
-                       /* highlight source */
-                       spprintf(&name, 4096, "phar://%s/%s", arch, entry);
-                       efree(arch);
-                       php_get_highlight_struct(&syntax_highlighter_ini);
-
-                       if (highlight_file(name, &syntax_highlighter_ini 
TSRMLS_CC) == FAILURE) {
-                       }
-
-                       PHAR_NOP();
-               case PHAR_MIME_OTHER:
-                       /* send headers, output file contents */
-                       if (FAILURE == phar_get_entry_data(&phar, arch, 
arch_len, entry, entry_len, "r", &error TSRMLS_CC)) {
-                               ctr.response_code = 404;
-                               ctr.line_len = sizeof("HTTP/1.0 404")+1;
-                               ctr.line = "HTTP/1.0 404";
-                               sapi_header_op(SAPI_HEADER_REPLACE, &ctr 
TSRMLS_CC);
-
-                               PHAR_NOP();
-                       }
-                       ctr.line_len = spprintf(&(ctr.line), 0, "Content-type: 
%s", mime_type);
-                       sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
-                       efree(ctr.line);
-                       ctr.line_len = spprintf(&(ctr.line), 0, 
"Content-length: %d", phar->internal_file->uncompressed_filesize);
-                       sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
-                       efree(ctr.line);
-                       if (FAILURE == sapi_send_headers(TSRMLS_C)) {
-                               phar_entry_delref(phar TSRMLS_CC);
-                               zend_bailout();
-                       }
-
-                       /* prepare to output  */
-                       if (!phar->fp) {
-                               phar->internal_file->fp_refcount++;
-                               phar->fp = phar->phar->fp;
-                               phar->zero = phar->phar->internal_file_start + 
phar->internal_file->offset_within_phar;
-                       }
-                       php_stream_seek(phar->fp, phar->position + phar->zero, 
SEEK_SET);
-                       do {
-                               if (!phar->zero) {
-                                       got = php_stream_read(phar->fp, buf, 
8192);
-                                       PHPWRITE(buf, got);
-                                       if (phar->fp->eof) {
-                                               break;
-                                       }
-                               } else {
-                                       got = php_stream_read(phar->fp, buf, 
MIN(8192, phar->internal_file->uncompressed_filesize - phar->position));
-                                       PHPWRITE(buf, got);
-                                       phar->position = 
php_stream_tell(phar->fp) - phar->zero;
-                                       if (phar->position == (off_t) 
phar->internal_file->uncompressed_filesize) {
-                                               break;
-                                       }
-                               }
-                       } while (1);
-
-                       phar_entry_delref(phar TSRMLS_CC);
-                       PHAR_NOP();
-               case PHAR_MIME_PHP:
-                       /* fall through */
-                       break;
-       }
-       return NULL;
-}
-
 static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int 
type TSRMLS_DC) /* {{{ */
 {
        zend_op_array *res;
@@ -4035,19 +3865,6 @@
                int arch_len, entry_len;
                fname = zend_get_executed_filename(TSRMLS_C);
                fname_len = strlen(fname);
-               /* check for web front controller phars */
-               if (zend_hash_exists(&(PHAR_GLOBALS->phar_web_map), fname, 
fname_len)) {
-                       zend_op_array *retval;
-                       if (strncasecmp(file_handle->filename, "phar://", 7)) {
-                               goto skip_phar;
-                       }
-                       fname_len = strlen(file_handle->filename);
-                       if (SUCCESS == phar_split_fname(file_handle->filename, 
fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
-                               if ((retval = phar_file_action(entry, 
entry_len, arch, arch_len, &name TSRMLS_CC))) {
-                                       return retval;
-                               }
-                       }
-               }
                if (strncasecmp(fname, "phar://", 7)) {
                        goto skip_phar;
                }
@@ -4179,8 +3996,6 @@
                PHAR_GLOBALS->request_done = 0;
                zend_hash_init(&(PHAR_GLOBALS->phar_fname_map), 
sizeof(phar_archive_data*), zend_get_hash_value, destroy_phar_data,  0);
                zend_hash_init(&(PHAR_GLOBALS->phar_alias_map), 
sizeof(phar_archive_data*), zend_get_hash_value, NULL, 0);
-               zend_hash_init(&(PHAR_GLOBALS->phar_web_map), sizeof(void *), 
zend_get_hash_value, NULL, 0);
-               zend_hash_init(&(PHAR_GLOBALS->phar_mimes), 
sizeof(phar_mime_type *), zend_get_hash_value, NULL, 0);
                zend_hash_init(&(PHAR_GLOBALS->phar_plain_map), sizeof(const 
char *),       zend_get_hash_value, NULL, 0);
                phar_split_extract_list(TSRMLS_C);
                if (SUCCESS == zend_hash_find(CG(function_table), "fopen", 6, 
(void **)&orig)) {
@@ -4202,8 +4017,6 @@
                }
                zend_hash_destroy(&(PHAR_GLOBALS->phar_alias_map));
                zend_hash_destroy(&(PHAR_GLOBALS->phar_fname_map));
-               zend_hash_destroy(&(PHAR_GLOBALS->phar_web_map));
-               zend_hash_destroy(&(PHAR_GLOBALS->phar_mimes));
                zend_hash_destroy(&(PHAR_GLOBALS->phar_plain_map));
                PHAR_GLOBALS->request_init = 0;
        }
@@ -4218,7 +4031,7 @@
        php_info_print_table_header(2, "Phar: PHP Archive support", "enabled");
        php_info_print_table_row(2, "Phar EXT version", PHAR_EXT_VERSION_STR);
        php_info_print_table_row(2, "Phar API version", PHAR_API_VERSION_STR);
-       php_info_print_table_row(2, "CVS revision", "$Revision: 1.234 $");
+       php_info_print_table_row(2, "CVS revision", "$Revision: 1.235 $");
 #if HAVE_ZLIB
        if (phar_has_zlib) {
                php_info_print_table_row(2, "gzip compression", 
http://cvs.php.net/viewvc.cgi/pecl/phar/phar_internal.h?r1=1.47&r2=1.48&diff_format=u
Index: pecl/phar/phar_internal.h
diff -u pecl/phar/phar_internal.h:1.47 pecl/phar/phar_internal.h:1.48
--- pecl/phar/phar_internal.h:1.47      Sat Dec 22 07:46:52 2007
+++ pecl/phar/phar_internal.h   Sun Dec 23 21:12:41 2007
@@ -17,7 +17,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: phar_internal.h,v 1.47 2007/12/22 07:46:52 cellog Exp $ */
+/* $Id: phar_internal.h,v 1.48 2007/12/23 21:12:41 cellog Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -36,6 +36,8 @@
 #include "zend_vm.h"
 #include "main/php_streams.h"
 #include "main/streams/php_stream_plain_wrapper.h"
+#include "main/SAPI.h"
+#include "main/php_main.h"
 #include "ext/standard/info.h"
 #include "ext/standard/basic_functions.h"
 #include "ext/standard/file.h"
@@ -70,11 +72,9 @@
 #endif
 
 #define PHAR_EXT_VERSION_STR      "1.3.0"
-#define PHAR_API_VERSION_STR      "1.2.0"
+#define PHAR_API_VERSION_STR      "1.1.0"
 /* x.y.z maps to 0xyz0 */
-#define PHAR_API_VERSION          0x1200
-/* API version to use for is_web=0 in phar creation */
-#define PHAR_API_VERSION_NOWEB    0x1100
+#define PHAR_API_VERSION          0x1100
 #define PHAR_API_MIN_READ         0x1000
 #define PHAR_API_MAJORVERSION     0x1000
 #define PHAR_API_MAJORVER_MASK    0xF000
@@ -85,7 +85,6 @@
 #define PHAR_HDR_COMPRESSED_GZ    0x00001000
 #define PHAR_HDR_COMPRESSED_BZ2   0x00002000
 #define PHAR_HDR_SIGNATURE        0x00010000
-#define PHAR_HDR_WEB              0x00020000
 
 #define PHAR_SIG_MD5              0x0001
 #define PHAR_SIG_SHA1             0x0002
@@ -113,10 +112,6 @@
        HashTable   phar_fname_map;
        HashTable   phar_alias_map;
        HashTable   phar_plain_map;
-       /* phar archives that have is_web = 1, used for fast lookup in 
phar_compile_file */
-       HashTable   phar_web_map;
-       /* mapping of file extension to MIME type */
-       HashTable   phar_mimes;
        char*       extract_list;
        int         readonly;
        zend_bool   readonly_orig;
@@ -210,8 +205,6 @@
        int                      is_brandnew:1;
        /* defer phar creation */
        int                      donotflush:1;
-       /* this phar is intended to use a web front controller with non-CLI 
SAPI */
-       int                      is_web:1;
 };
 
 #define PHAR_MIME_PHP '\0'
@@ -273,7 +266,6 @@
 
 
 #ifdef PHAR_MAIN
-static void phar_init_mime_list(TSRMLS_D);
 static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS);
 static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char 
*alias, int alias_len, int options, phar_archive_data** pphar, char **error 
TSRMLS_DC);
 
@@ -309,6 +301,7 @@
 phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int 
path_len, char **error TSRMLS_DC);
 phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, 
int path_len, char dir, char **error TSRMLS_DC);
 phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, 
char *path, int path_len, char *mode, char **error TSRMLS_DC);
+int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, 
char *path, int path_len, char *mode, char **error TSRMLS_DC);
 int phar_flush(phar_archive_data *archive, char *user_stub, long len, char 
**error TSRMLS_DC);
 int phar_detect_phar_fname_ext(const char *filename, int check_length, char 
**ext_str, int *ext_len);
 int phar_split_fname(char *filename, int filename_len, char **arch, int 
*arch_len, char **entry, int *entry_len TSRMLS_DC);
http://cvs.php.net/viewvc.cgi/pecl/phar/phar_object.c?r1=1.82&r2=1.83&diff_format=u
Index: pecl/phar/phar_object.c
diff -u pecl/phar/phar_object.c:1.82 pecl/phar/phar_object.c:1.83
--- pecl/phar/phar_object.c:1.82        Sat Dec 22 07:46:52 2007
+++ pecl/phar/phar_object.c     Sun Dec 23 21:12:41 2007
@@ -17,7 +17,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: phar_object.c,v 1.82 2007/12/22 07:46:52 cellog Exp $ */
+/* $Id: phar_object.c,v 1.83 2007/12/23 21:12:41 cellog Exp $ */
 
 #include "phar_internal.h"
 
@@ -65,6 +65,301 @@
 }
 /* }}} */
 
+static int phar_file_type(HashTable *mimes, char *file, char **mime_type 
TSRMLS_DC)
+{
+       char *ext;
+       phar_mime_type *mime;
+       if (!mime_type) {
+               /* assume PHP */
+               return 0;
+       }
+       ext = strrchr(file, '.');
+       if (!ext) {
+               *mime_type = "text/plain";
+               /* no file extension = assume text/plain */
+               return PHAR_MIME_OTHER;
+       }
+       ext++;
+       if (SUCCESS != zend_hash_find(mimes, ext, strlen(ext), (void **) 
&mime)) {
+               *mime_type = "application/octet-stream";
+               return PHAR_MIME_OTHER;
+       }
+       *mime_type = mime->mime;
+       return mime->type;
+}
+/* }}} */
+
+static int phar_file_action(phar_entry_data *phar, char *mime_type, int code, 
char *entry, int entry_len, char *arch, int arch_len TSRMLS_DC)
+{
+       char *name = NULL, buf[8192];
+       zend_syntax_highlighter_ini syntax_highlighter_ini;
+       sapi_header_line ctr = {0};
+       size_t got;
+       int dummy = 1, name_len, ret;
+       zend_file_handle file_handle;
+       zend_op_array *new_op_array;
+       zval *result = NULL;
+
+       switch (code) {
+               case PHAR_MIME_PHPS:
+                       /* highlight source */
+                       spprintf(&name, 4096, "phar://%s%s", arch, entry);
+                       php_get_highlight_struct(&syntax_highlighter_ini);
+
+                       if (highlight_file(name, &syntax_highlighter_ini 
TSRMLS_CC) == FAILURE) {
+                       }
+
+                       phar_entry_delref(phar TSRMLS_CC);
+                       efree(name);
+                       zend_bailout();
+                       return PHAR_MIME_PHPS;
+               case PHAR_MIME_OTHER:
+                       /* send headers, output file contents */
+                       ctr.line_len = spprintf(&(ctr.line), 0, "Content-type: 
%s", mime_type);
+                       sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
+                       efree(ctr.line);
+                       ctr.line_len = spprintf(&(ctr.line), 0, 
"Content-length: %d", phar->internal_file->uncompressed_filesize);
+                       sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
+                       efree(ctr.line);
+                       if (FAILURE == sapi_send_headers(TSRMLS_C)) {
+                               phar_entry_delref(phar TSRMLS_CC);
+                               zend_bailout();
+                       }
+
+                       /* prepare to output  */
+                       if (!phar->fp) {
+                               phar->internal_file->fp_refcount++;
+                               phar->fp = phar->phar->fp;
+                               phar->zero = phar->phar->internal_file_start + 
phar->internal_file->offset_within_phar;
+                               phar->internal_file->fp = phar->phar->fp;
+                       }
+                       php_stream_seek(phar->fp, phar->position + phar->zero, 
SEEK_SET);
+                       do {
+                               if (!phar->zero) {
+                                       got = php_stream_read(phar->fp, buf, 
8192);
+                                       PHPWRITE(buf, got);
+                                       if (phar->fp->eof) {
+                                               break;
+                                       }
+                               } else {
+                                       got = php_stream_read(phar->fp, buf, 
MIN(8192, phar->internal_file->uncompressed_filesize - phar->position));
+                                       PHPWRITE(buf, got);
+                                       phar->position = 
php_stream_tell(phar->fp) - phar->zero;
+                                       if (phar->position == (off_t) 
phar->internal_file->uncompressed_filesize) {
+                                               break;
+                                       }
+                               }
+                       } while (1);
+
+                       phar_entry_delref(phar TSRMLS_CC);
+                       return PHAR_MIME_OTHER;
+               case PHAR_MIME_PHP:
+                       phar_entry_delref(phar TSRMLS_CC);
+                       name_len = spprintf(&name, 4096, "phar://%s%s", arch, 
entry);
+
+                       ret = php_stream_open_for_zend_ex(name, &file_handle, 
ENFORCE_SAFE_MODE|USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC);
+                       
+                       if (ret != SUCCESS) {
+                               efree(name);
+                               return -1;
+                       }
+                       if (!file_handle.opened_path) {
+                               file_handle.opened_path = estrndup(name, 
name_len);
+                       }
+                       if (zend_hash_add(&EG(included_files), 
file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, 
sizeof(int), NULL)==SUCCESS) {
+                               new_op_array = zend_compile_file(&file_handle, 
ZEND_REQUIRE TSRMLS_CC);
+                               zend_destroy_file_handle(&file_handle 
TSRMLS_CC);
+                       } else {
+                               new_op_array = NULL;
+                               zend_file_handle_dtor(&file_handle);
+                       }
+                       if (new_op_array) {
+                               EG(return_value_ptr_ptr) = &result;
+                               EG(active_op_array) = new_op_array;
+               
+                               zend_execute(new_op_array TSRMLS_CC);
+               
+                               destroy_op_array(new_op_array TSRMLS_CC);
+                               efree(new_op_array);
+                               if (!EG(exception)) {
+                                       if (EG(return_value_ptr_ptr)) {
+                                               
zval_ptr_dtor(EG(return_value_ptr_ptr));
+                                       }
+                               }
+               
+                               efree(name);
+                               zend_bailout();
+                       }
+                       return PHAR_MIME_PHP;
+       }
+       return -1;
+}
+
+/* {{{ proto void Phar::webPhar([string alias, [int dataoffset, [array 
mimetypes, [array redirects]]]])
+ * mapPhar for web-based phars. Reads the currently executed file (a phar)
+ * and registers its manifest.
+ */
+PHP_METHOD(Phar, webPhar)
+{
+       HashTable mimetypes;
+       phar_mime_type mime;
+       zval *mimeoverride = NULL, *redirects = NULL;
+       char *alias = NULL, *error, *plain_map;
+       int alias_len = 0, ret;
+       long dataoffset;
+       char *fname, *basename, *path_info, *mime_type, *entry;
+       int fname_len, entry_len, code;
+       phar_entry_data *phar;
+       zval **_SERVER, **stuff;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!laa", &alias, 
&alias_len, &dataoffset, &mimeoverride, &redirects) == FAILURE) {
+               return;
+       }
+
+       phar_request_initialize(TSRMLS_C);
+       if (phar_open_compiled_file(alias, alias_len, &error TSRMLS_CC) != 
SUCCESS) {
+               if (error) {
+                       zend_throw_exception_ex(phar_ce_PharException, 0 
TSRMLS_CC, error);
+                       efree(error);
+               }
+               return;
+       }
+
+       /* retrieve requested file within phar */
+       if (!(SG(request_info).request_method && SG(request_info).request_uri 
&& (!strcmp(SG(request_info).request_method, "GET") || 
!strcmp(SG(request_info).request_method, "POST")))) {
+               return;
+       }
+
+       fname = zend_get_executed_filename(TSRMLS_C);
+       fname_len = strlen(fname);
+       basename = strrchr(fname, DEFAULT_SLASH);
+       if (!basename) {
+               basename = fname;
+       } else {
+               basename++;
+       }
+       path_info = SG(request_info).request_uri;
+       entry_len = strlen(path_info);
+       if (strstr(path_info, basename)) {
+               entry_len -= fname_len - (basename - fname) + 1;
+               entry = estrndup(path_info + (fname_len - (basename - fname) + 
1), entry_len);
+       } else {
+               // error
+       }
+
+       /* "tweak" $_SERVER variables */
+       if (SUCCESS == zend_hash_find(&EG(symbol_table), "_SERVER", 
sizeof("_SERVER"), (void **) &_SERVER)) {
+               if (SUCCESS == zend_hash_find(Z_ARRVAL_PP(_SERVER), 
"REQUEST_URI", sizeof("REQUEST_URI"), (void **) &stuff)) {
+                       zval *temp;
+                       path_info = Z_STRVAL_PP(stuff);
+                       code = Z_STRLEN_PP(stuff);
+                       Z_STRVAL_PP(stuff) = entry;
+                       Z_STRLEN_PP(stuff) = entry_len;
+                       MAKE_STD_ZVAL(temp);
+                       Z_TYPE_P(temp) = IS_STRING;
+                       Z_STRVAL_P(temp) = path_info;
+                       Z_STRLEN_P(temp) = code;
+                       zend_hash_update(Z_ARRVAL_PP(_SERVER), 
"PHAR_SCRIPT_FILENAME", sizeof("PHAR_SCRIPT_FILENAME"), (void *) &temp, 
sizeof(zval **), NULL);
+               }
+               if (SUCCESS == zend_hash_find(Z_ARRVAL_PP(_SERVER), 
"SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &stuff)) {
+                       path_info = Z_STRVAL_PP(stuff);
+                       Z_STRLEN_PP(stuff) = spprintf(&(Z_STRVAL_PP(stuff)), 
4096, "phar://%s%s", fname, entry);
+                       efree(path_info);
+               }
+       }
+       
+       if (FAILURE == phar_get_entry_data(&phar, fname, fname_len, entry, 
entry_len, "r", &error TSRMLS_CC)) {
+               sapi_header_line ctr = {0};
+               ctr.response_code = 404;
+               ctr.line_len = sizeof("HTTP/1.0 404")+1;
+               ctr.line = "HTTP/1.0 404";
+               sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
+               return;
+       }
+
+       /* set up mime types */
+       zend_hash_init(&mimetypes, sizeof(phar_mime_type *), 
zend_get_hash_value, NULL, 0);
+#define PHAR_SET_MIME(mimetype, ret, ...) \
+               mime.mime = mimetype; \
+               mime.len = sizeof((mimetype))+1; \
+               mime.type = ret; \
+               { \
+                       char mimes[][5] = {__VA_ARGS__, "\0"}; \
+                       int i = 0; \
+                       for (; mimes[i][0]; i++) { \
+                               zend_hash_add(&mimetypes, mimes[i], 
strlen(mimes[i]), (void *)&mime, sizeof(phar_mime_type), NULL); \
+                       } \
+               }
+
+       PHAR_SET_MIME("text/html", PHAR_MIME_PHPS, "phps")
+       PHAR_SET_MIME("text/plain", PHAR_MIME_OTHER, "c", "cc", "cpp", "c++", 
"dtd", "h", "log", "rng", "txt", "xsd")
+       PHAR_SET_MIME("", PHAR_MIME_PHP, "php", "inc")
+       PHAR_SET_MIME("video/avi", PHAR_MIME_OTHER, "avi")
+       PHAR_SET_MIME("image/bmp", PHAR_MIME_OTHER, "bmp")
+       PHAR_SET_MIME("text/css", PHAR_MIME_OTHER, "css")
+       PHAR_SET_MIME("image/gif", PHAR_MIME_OTHER, "gif")
+       PHAR_SET_MIME("text/html", PHAR_MIME_OTHER, "htm", "html", "htmls")
+       PHAR_SET_MIME("image/x-ico", PHAR_MIME_OTHER, "ico")
+       PHAR_SET_MIME("image/jpeg", PHAR_MIME_OTHER, "jpe", "jpg", "jpeg")
+       PHAR_SET_MIME("application/x-javascript", PHAR_MIME_OTHER, "js")
+       PHAR_SET_MIME("audio/midi", PHAR_MIME_OTHER, "mid", "midi")
+       PHAR_SET_MIME("audio/mod", PHAR_MIME_OTHER, "mod")
+       PHAR_SET_MIME("movie/quicktime", PHAR_MIME_OTHER, "mov")
+       PHAR_SET_MIME("audio/mp3", PHAR_MIME_OTHER, "mp3")
+       PHAR_SET_MIME("video/mpeg", PHAR_MIME_OTHER, "mpg", "mpeg")
+       PHAR_SET_MIME("application/pdf", PHAR_MIME_OTHER, "pdf")
+       PHAR_SET_MIME("image/png", PHAR_MIME_OTHER, "png")
+       PHAR_SET_MIME("application/shockwave-flash", PHAR_MIME_OTHER, "swf")
+       PHAR_SET_MIME("image/tiff", PHAR_MIME_OTHER, "tif", "tiff")
+       PHAR_SET_MIME("audio/wav", PHAR_MIME_OTHER, "wav")
+       PHAR_SET_MIME("image/xbm", PHAR_MIME_OTHER, "xbm")
+       PHAR_SET_MIME("text/xml", PHAR_MIME_OTHER, "xml")
+
+       /* set up user overrides */
+#define PHAR_SET_USER_MIME(ret) \
+               mime.mime = Z_STRVAL_P(val); \
+               mime.len = Z_STRLEN_P(val); \
+               mime.type = ret; \
+               zend_hash_update(&mimetypes, key, keylen, (void *)&mime, 
sizeof(phar_mime_type), NULL);
+
+       if (mimeoverride) {
+               for 
(zend_hash_internal_pointer_reset(Z_ARRVAL_P(mimeoverride)); 
zend_hash_has_more_elements(Z_ARRVAL_P(mimeoverride)); 
zend_hash_move_forward(Z_ARRVAL_P(mimeoverride))) {
+                       zval *val;
+                       char *key;
+                       uint keylen;
+                       ulong intkey;
+                       if (HASH_KEY_IS_LONG == 
zend_hash_get_current_key_ex(Z_ARRVAL_P(mimeoverride), &key, &keylen, &intkey, 
0, NULL)) {
+                               
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Key of 
MIME type overrides array must be a file extension, was \"%d\"", intkey);
+                               RETURN_FALSE;
+                       }
+                       if (FAILURE == 
zend_hash_get_current_data(Z_ARRVAL_P(mimeoverride), (void **) &val)) {
+                               
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Failed 
to retrieve Mime type for extension \"%s\"", key);
+                               RETURN_FALSE;
+                       }
+                       switch (Z_TYPE_P(val)) {
+                               case IS_LONG :
+                                       if (Z_LVAL_P(val) == PHAR_MIME_PHP || 
Z_LVAL_P(val) == PHAR_MIME_PHPS) {
+                                               
PHAR_SET_USER_MIME(Z_LVAL_P(val))
+                                       } else {
+                                               
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Unknown 
mime type specifier used, only Phar::PHP, Phar::PHPS and a mime type string are 
allowed");
+                                               RETURN_FALSE;
+                                       }
+                                       break;
+                               case IS_STRING :
+                                       PHAR_SET_USER_MIME(PHAR_MIME_OTHER)
+                                       break;
+                               default :
+                                       
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Unknown 
mime type specifier used, only Phar::PHP, Phar::PHPS and a mime type string are 
allowed");
+                                       RETURN_FALSE;
+                       }
+               }
+       }
+       code = phar_file_type(&mimetypes, entry, &mime_type TSRMLS_CC);
+       ret = phar_file_action(phar, mime_type, code, entry, entry_len, fname, 
fname_len TSRMLS_CC);
+       zend_hash_destroy(&mimetypes);
+       RETURN_LONG(ret);
+}
+
 /* {{{ proto mixed Phar::mapPhar([string alias, [int dataoffset]])
  * Reads the currently executed file (a phar) and registers its manifest */
 PHP_METHOD(Phar, mapPhar)
@@ -342,31 +637,6 @@
                return; \
        }
 
-/* {{{ proto void Phar::useWebFrontController()
- * This method is used in Phar creation to specify that this phar
- * is intended to be executed as a self-contained website, and the
- * built-in fast front controller should be used.
- */
-PHP_METHOD(Phar, useWebFrontController)
-{
-       char *error;
-       PHAR_ARCHIVE_OBJECT();
-
-       if (PHAR_G(readonly)) {
-               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 
TSRMLS_CC,
-                       "Cannot specify use of default front controller, phar 
is read-only");
-               return;
-       }
-
-       phar_obj->arc.archive->is_web = 1;
-       phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
-       if (error) {
-               zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, 
error);
-               efree(error);
-       }
-}
-/* }}} */
-
 static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC)
 {
        zval **value;
@@ -1932,6 +2202,15 @@
 static
 ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mapPhar, 0, 0, 0)
        ZEND_ARG_INFO(0, alias)
+       ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO();
+
+static
+ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_webPhar, 0, 0, 0)
+       ZEND_ARG_INFO(0, alias)
+       ZEND_ARG_INFO(0, offset)
+       ZEND_ARG_INFO(0, mimetypes)
+       ZEND_ARG_INFO(0, redirects)
 ZEND_END_ARG_INFO();
 
 static
@@ -2007,7 +2286,6 @@
        PHP_ME(Phar, offsetUnset,           arginfo_phar_offsetExists, 
ZEND_ACC_PUBLIC)
        PHP_ME(Phar, uncompressAllFiles,    NULL,                      
ZEND_ACC_PUBLIC)
        PHP_ME(Phar, buildFromIterator,     arginfo_phar_build,        
ZEND_ACC_PUBLIC)
-       PHP_ME(Phar, useWebFrontController, NULL,                      
ZEND_ACC_PUBLIC)
 #endif
        /* static member functions */
        PHP_ME(Phar, apiVersion,            NULL,                      
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
@@ -2015,6 +2293,7 @@
        PHP_ME(Phar, canWrite,              NULL,                      
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        PHP_ME(Phar, loadPhar,              arginfo_phar_loadPhar,     
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        PHP_ME(Phar, mapPhar,               arginfo_phar_mapPhar,      
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
+       PHP_ME(Phar, webPhar,               arginfo_phar_webPhar,      
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        PHP_ME(Phar, getExtractList,        NULL,                      
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        PHP_ME(Phar, getSupportedSignatures,NULL,                      
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        PHP_ME(Phar, getSupportedCompression,NULL,                     
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
@@ -2094,6 +2373,8 @@
        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "SHA256", 
PHAR_SIG_SHA256)
        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "SHA512", 
PHAR_SIG_SHA512)
        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "PGP", PHAR_SIG_PGP)
+       REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "PHP", PHAR_MIME_PHP)
+       REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "PHPS", PHAR_MIME_PHPS)
 }
 /* }}} */
 
http://cvs.php.net/viewvc.cgi/pecl/phar/tests/frontcontroller1.phpt?r1=1.1&r2=1.2&diff_format=u
Index: pecl/phar/tests/frontcontroller1.phpt
diff -u pecl/phar/tests/frontcontroller1.phpt:1.1 
pecl/phar/tests/frontcontroller1.phpt:1.2
--- pecl/phar/tests/frontcontroller1.phpt:1.1   Sat Dec 22 07:47:14 2007
+++ pecl/phar/tests/frontcontroller1.phpt       Sun Dec 23 21:12:41 2007
@@ -9,20 +9,14 @@
 <?php
 $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
 $pname = 'phar://' . $fname;
-$file = '<?php echo "first stub\n"; __HALT_COMPILER(); ?>';
-
-$files = array();
-$gflags = 0x020000;
-$files['a.jpg'] = 'hio';
-
-include 'phar_test.inc';
 
 $a = new Phar($fname);
+$a['a.jpg'] = 'hio';
 $a->setStub('<?php
-Phar::mapPhar();
-include "phar://" . __FILE__ . "/a.jpg";
+Phar::webPhar();
 __HALT_COMPILER();');
 
+$_SERVER['REQUEST_URI'] = '/' . basename(__FILE__, '.php') . '.phar.php/a.jpg';
 include $fname;
 ?>
 ===DONE===

http://cvs.php.net/viewvc.cgi/pecl/phar/tests/frontcontroller2.phpt?view=markup&rev=1.1
Index: pecl/phar/tests/frontcontroller2.phpt
+++ pecl/phar/tests/frontcontroller2.phpt
--TEST--
Phar front controller php
--SKIPIF--
<?php if (!extension_loaded("phar")) print "skip"; ?>
--INI--
phar.require_hash=0
phar.readonly=0
--FILE--
<?php
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
$pname = 'phar://' . $fname;

$a = new Phar($fname);
$a['a.php'] = 'hio';
$a->setStub('<?php
Phar::webPhar();
__HALT_COMPILER();');

$_SERVER['REQUEST_URI'] = '/' . basename(__FILE__, '.php') . '.phar.php/a.php';
include $fname;
?>
===DONE===
--CLEAN--
<?php 
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . 
'.phar.php');
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . 
'.phartmp.php');
__HALT_COMPILER();
?>
--EXPECTHEADERS--
Content-type: text/html
--EXPECT--
hio

http://cvs.php.net/viewvc.cgi/pecl/phar/tests/frontcontroller3.phpt?view=markup&rev=1.1
Index: pecl/phar/tests/frontcontroller3.phpt
+++ pecl/phar/tests/frontcontroller3.phpt
--TEST--
Phar front controller phps
--SKIPIF--
<?php if (!extension_loaded("phar")) print "skip"; ?>
--INI--
phar.require_hash=0
phar.readonly=0
--FILE--
<?php
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
$pname = 'phar://' . $fname;

$a = new Phar($fname);
$a['a.phps'] = '<?php function hio(){}';
$a->setStub('<?php
Phar::webPhar();
__HALT_COMPILER();');

$_SERVER['REQUEST_URI'] = '/' . basename(__FILE__, '.php') . '.phar.php/a.phps';
include $fname;
?>
===DONE===
--CLEAN--
<?php 
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . 
'.phar.php');
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . 
'.phartmp.php');
__HALT_COMPILER();
?>
--EXPECTHEADERS--
Content-type: text/html
--EXPECT--
<code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php&nbsp;</span><span style="color: 
#007700">function&nbsp;</span><span style="color: #0000BB">hio</span><span 
style="color: #007700">(){}</span>
</span>
</code>

Reply via email to