New PHP5 APC - version 3.0.19, using PHP5 5.2.0-8+etch11,
[php5-apc.git] / apc_rfc1867.c
1 /*
2   +----------------------------------------------------------------------+
3   | APC                                                                  |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 2008 The PHP Group                                     |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 3.01 of the PHP license,      |
8   | that is bundled with this package in the file LICENSE, and is        |
9   | available through the world-wide-web at the following url:           |
10   | http://www.php.net/license/3_01.txt                                  |
11   | If you did not receive a copy of the PHP license and are unable to   |
12   | obtain it through the world-wide-web, please send a note to          |
13   | license@php.net so we can mail you a copy immediately.               |
14   +----------------------------------------------------------------------+
15   | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
16   +----------------------------------------------------------------------+
17
18    This software was contributed to PHP by Community Connect Inc. in 2002
19    and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
20    Future revisions and derivatives of this source code must acknowledge
21    Community Connect Inc. as the original contributor of this module by
22    leaving this note intact in the source code.
23
24    All other licensing and usage conditions are those of the PHP Group.
25
26  */
27
28 /* $Id: apc_rfc1867.c,v 3.12.2.1 2008/05/11 18:57:00 rasmus Exp $*/
29
30 #include "apc.h"
31 #include "apc_globals.h"
32 #include "rfc1867.h"
33
34 #ifdef PHP_WIN32
35 #include "win32/time.h"
36 #endif
37
38 #ifdef MULTIPART_EVENT_FORMDATA
39 extern int _apc_store(char *strkey, int strkey_len, const zval *val, const unsigned int ttl, const int exclusive TSRMLS_DC);
40
41 static double my_time() {
42     struct timeval a;
43     double t;
44     gettimeofday(&a, NULL);
45     t = a.tv_sec + (a.tv_usec/1000000.00);
46     return t;
47 }
48
49 void apc_rfc1867_progress(unsigned int event, void *event_data, void **extra TSRMLS_DC) {
50     static char tracking_key[64];
51     static int  key_length = 0;
52     static size_t content_length = 0;
53     static char filename[128];
54     static char name[64];
55     static char *temp_filename=NULL;
56     static int cancel_upload = 0;
57     static double start_time;
58     static size_t bytes_processed = 0;
59     static size_t prev_bytes_processed = 0;
60     static int update_freq = 0;
61     static double rate;
62     zval *track = NULL;
63
64         switch (event) {
65                 case MULTIPART_EVENT_START:
66                         {
67                 multipart_event_start *data = (multipart_event_start *) event_data;
68                 content_length = data->content_length;
69                 *tracking_key = '\0';
70                 *name = '\0';
71                 cancel_upload = 0;
72                 temp_filename = NULL;
73                 *filename= '\0';
74                 key_length = 0;
75                 start_time = my_time();
76                 bytes_processed = 0;
77                 rate = 0;
78                 update_freq = APCG(rfc1867_freq);
79                 if(update_freq < 0) {  // frequency is a percentage, not bytes
80                     update_freq = content_length * APCG(rfc1867_freq) / 100; 
81                 }
82                         }
83                         break;
84
85                 case MULTIPART_EVENT_FORMDATA:
86                         {
87                 int prefix_len = strlen(APCG(rfc1867_prefix));
88                 multipart_event_formdata *data = (multipart_event_formdata *) event_data;
89                                 if(data->name && !strncasecmp(data->name, APCG(rfc1867_name), strlen(APCG(rfc1867_name))) && data->value && data->length && data->length < sizeof(tracking_key) - prefix_len) {
90                     strlcat(tracking_key, APCG(rfc1867_prefix), 63);
91                     strlcat(tracking_key, *data->value, 63);
92                     key_length = data->length + prefix_len;
93                     bytes_processed = data->post_bytes_processed;
94                                 }
95                         }
96                         break;
97
98                 case MULTIPART_EVENT_FILE_START:
99             if(*tracking_key) {
100                 multipart_event_file_start *data = (multipart_event_file_start *) event_data;
101
102                 bytes_processed = data->post_bytes_processed;
103                 strncpy(filename,*data->filename,127);
104                 temp_filename = NULL;
105                 strncpy(name,data->name,63);
106                 ALLOC_INIT_ZVAL(track);
107                 array_init(track);
108                 add_assoc_long(track, "total", content_length);
109                 add_assoc_long(track, "current", bytes_processed);
110                 add_assoc_string(track, "filename", filename, 1);
111                 add_assoc_string(track, "name", name, 1);
112                 add_assoc_long(track, "done", 0);
113                 add_assoc_double(track, "start_time", start_time);
114                 _apc_store(tracking_key, key_length, track, 3600, 0 TSRMLS_CC);
115                 zval_ptr_dtor(&track);
116             }
117             break;
118
119                 case MULTIPART_EVENT_FILE_DATA:
120             if(*tracking_key) {
121                 multipart_event_file_data *data = (multipart_event_file_data *) event_data;
122                 bytes_processed = data->post_bytes_processed;
123                 ALLOC_INIT_ZVAL(track);
124                 array_init(track);
125                 add_assoc_long(track, "total", content_length);
126                 add_assoc_long(track, "current", bytes_processed);
127                 add_assoc_string(track, "filename", filename, 1);
128                 add_assoc_string(track, "name", name, 1);
129                 add_assoc_long(track, "done", 0);
130                 add_assoc_double(track, "start_time", start_time);
131                 if(bytes_processed - prev_bytes_processed > update_freq) {
132                     _apc_store(tracking_key, key_length, track, 3600, 0 TSRMLS_CC);
133                     prev_bytes_processed = bytes_processed;
134                 }
135                 zval_ptr_dtor(&track);
136                         }
137                         break;
138
139                 case MULTIPART_EVENT_FILE_END:
140             if(*tracking_key) {
141                 multipart_event_file_end *data = (multipart_event_file_end *) event_data;
142                 bytes_processed = data->post_bytes_processed;
143                 cancel_upload = data->cancel_upload;
144                 temp_filename = data->temp_filename;
145                 ALLOC_INIT_ZVAL(track);
146                 array_init(track);
147                 add_assoc_long(track, "total", content_length);
148                 add_assoc_long(track, "current", bytes_processed);
149                 add_assoc_string(track, "filename", filename, 1);
150                 add_assoc_string(track, "name", name, 1);
151                 add_assoc_string(track, "temp_filename", temp_filename, 1);
152                 add_assoc_long(track, "cancel_upload", cancel_upload);
153                 add_assoc_long(track, "done", 0);
154                 add_assoc_double(track, "start_time", start_time);
155                 _apc_store(tracking_key, key_length, track, 3600, 0 TSRMLS_CC);
156                 zval_ptr_dtor(&track);
157                         }
158                         break;
159
160                 case MULTIPART_EVENT_END:
161             if(*tracking_key) {
162                 double now = my_time(); 
163                 multipart_event_end *data = (multipart_event_end *) event_data;
164                 bytes_processed = data->post_bytes_processed;
165                 if(now>start_time) rate = 8.0*bytes_processed/(now-start_time);
166                 else rate = 8.0*bytes_processed;  /* Too quick */
167                 ALLOC_INIT_ZVAL(track);
168                 array_init(track);
169                 add_assoc_long(track, "total", content_length);
170                 add_assoc_long(track, "current", bytes_processed);
171                 add_assoc_double(track, "rate", rate);
172                 add_assoc_string(track, "filename", filename, 1);
173                 add_assoc_string(track, "name", name, 1);
174                 if(temp_filename) {
175                     add_assoc_string(track, "temp_filename", temp_filename, 1);
176                 }
177                 add_assoc_long(track, "cancel_upload", cancel_upload);
178                 add_assoc_long(track, "done", 1);
179                 add_assoc_double(track, "start_time", start_time);
180                 _apc_store(tracking_key, key_length, track, 3600, 0 TSRMLS_CC);
181                 zval_ptr_dtor(&track);
182                         }
183                         break;
184         }
185 }
186
187 #endif
188 /*
189  * Local variables:
190  * tab-width: 4
191  * c-basic-offset: 4
192  * End:
193  * vim600: expandtab sw=4 ts=4 sts=4 fdm=marker
194  * vim<600: expandtab sw=4 ts=4 sts=4
195  */