source: trunk/zoo-project/zoo-kernel/service_internal_php.c @ 587

Last change on this file since 587 was 587, checked in by knut, 10 years ago

Implemented asynchronous HTTP POST Execute requests on Windows platform (via caching). Fixed bug that caused only the last output variable in a HTTP POST Execute request to be returned. Modified the addToCache function so that the path of the cached file can be retrieved. Changed the parsing of KVPs in zoo_loader.c so that keys with missing values (e.g. "metapath=") are assigned the empty string instead of NULL (avoids segmentation fault in some situations). Added conditional definition of ZEND_DEBUG in service_internal_php.c. Deallocation of memory in function createProcess. In zoo_loader.c, applied url_decode to CGI form string (WIN32 only, but should check if this should apply to other platforms as well).

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 10.9 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2010 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#ifdef WIN32
26  #define NO_FCGI_DEFINES
27#endif
28
29#ifndef ZEND_DEBUG
30  #define ZEND_DEBUG 0
31#endif 
32 
33#include "service_internal_php.h"
34
35#include <sapi/embed/php_embed.h>
36#include <zend_stream.h>
37
38zval *php_Array_from_maps(maps* t);
39zval*  php_Array_from_map(map*);
40maps* php_maps_from_Array(HashTable* t);
41map* php_map_from_HasTable(HashTable* t);
42
43#ifdef ZTS
44void ***tsrm_ls;
45#endif
46
47ZEND_BEGIN_MODULE_GLOBALS(zoo)
48long _SERVICE_SUCCEEDED;
49long _SERVICE_FAILED;
50ZEND_END_MODULE_GLOBALS(zoo)
51
52#ifdef ZTS
53#define ZOO_G(v) TSRMG(zoo_globals_id, zend_zoo_globals *, v)
54#else
55#define ZOO_G(v) (zoo_globals.v)
56#endif
57
58#define PHP_ZOO_VERSION "1.0"
59#define PHP_ZOO_EXTNAME "ZOO"
60
61PHP_MINIT_FUNCTION(zoo);
62PHP_MSHUTDOWN_FUNCTION(zoo);
63PHP_RINIT_FUNCTION(zoo);
64
65PHP_FUNCTION(zoo_Translate);
66PHP_FUNCTION(zoo_UpdateStatus);
67PHP_FUNCTION(zoo_SERVICE_SUCCEEDED);
68PHP_FUNCTION(zoo_SERVICE_FAILED);
69
70extern zend_module_entry zoo_module_entry;
71#define phpext_zoo_ptr &zoo_entry
72
73ZEND_DECLARE_MODULE_GLOBALS(zoo)
74
75static zend_function_entry zoo_functions[] = {
76  PHP_FE(zoo_Translate, NULL)
77  PHP_FE(zoo_UpdateStatus, NULL)
78  PHP_FE(zoo_SERVICE_SUCCEEDED, NULL)
79  PHP_FE(zoo_SERVICE_FAILED, NULL)
80  {NULL, NULL, NULL}
81};
82
83zend_module_entry zoo_module_entry = {
84#if ZEND_MODULE_API_NO >= 20010901
85    STANDARD_MODULE_HEADER,
86#endif
87    PHP_ZOO_EXTNAME,
88    zoo_functions,
89    PHP_MINIT(zoo),
90    PHP_MSHUTDOWN(zoo),
91    PHP_RINIT(zoo),
92    NULL,
93    NULL,
94#if ZEND_MODULE_API_NO >= 20010901
95    PHP_ZOO_VERSION,
96#endif
97    STANDARD_MODULE_PROPERTIES
98};
99
100ZEND_GET_MODULE(zoo)
101
102PHP_INI_BEGIN()
103PHP_INI_END()
104
105static void
106php_zoo_init_globals(zend_zoo_globals *zoo_globals)
107{
108  zoo_globals->_SERVICE_SUCCEEDED=3;
109  zoo_globals->_SERVICE_FAILED=4;
110}
111
112PHP_RINIT_FUNCTION(zoo)
113{
114  return SUCCESS;
115}
116
117PHP_MINIT_FUNCTION(zoo)
118{
119  ZEND_INIT_MODULE_GLOBALS(zoo, php_zoo_init_globals,NULL);
120  REGISTER_INI_ENTRIES();
121  return SUCCESS;
122}
123
124PHP_MSHUTDOWN_FUNCTION(zoo)
125{
126  UNREGISTER_INI_ENTRIES();
127  return SUCCESS;
128}
129
130PHP_FUNCTION(zoo_Translate)
131{
132  char *value;
133  int value_len;
134  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) {
135    RETURN_NULL();
136  }
137  RETURN_STRING(_ss(value), 1);
138}
139
140PHP_FUNCTION(zoo_UpdateStatus)
141{
142  zval *arr;
143  char *message;
144  int message_len;
145  long pourcent;
146  char *status=(char*)malloc(4*sizeof(char));
147  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "asl", &arr, &message, &message_len,&pourcent) == FAILURE) {
148    RETURN_NULL();
149  }
150  HashTable* t=HASH_OF(arr);
151  maps* conf=php_maps_from_Array(t);
152  setMapInMaps(conf,"lenv","message",message);
153  sprintf(status,"%d",pourcent);
154  setMapInMaps(conf,"lenv","status",status);
155  _updateStatus(conf);
156  freeMaps(&conf);
157  free(conf);
158  free(status);
159  RETURN_NULL();
160}
161
162PHP_FUNCTION(zoo_SERVICE_SUCCEEDED)
163{
164  RETURN_LONG(ZOO_G(_SERVICE_SUCCEEDED));
165}
166
167PHP_FUNCTION(zoo_SERVICE_FAILED)
168{
169  RETURN_LONG(ZOO_G(_SERVICE_FAILED));
170}
171
172/**
173 * Load a PHP script then run the function corresponding to the service by
174 * passing the conf, inputs and outputs parameters by reference.
175 *
176 * @param main_conf the conf maps containing the main.cfg settings
177 * @param request the map containing the HTTP request
178 * @param s the service structure
179 * @param real_inputs the maps containing the inputs
180 * @param real_outputs the maps containing the outputs
181 */
182int zoo_php_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){   
183  maps* m=*main_conf;
184  maps* inputs=*real_inputs;
185  maps* outputs=*real_outputs;
186  char ntmp[1024];
187  getcwd(ntmp,1024);
188  map* tmp=getMap(request,"metapath");
189
190  int res=SERVICE_FAILED;
191
192  tmp=getMap(s->content,"serviceProvider");
193  map* cwd=getMapFromMaps(m,"lenv","cwd");
194  map* mp=getMap(request,"metapath");
195  char *scriptName;
196  if(mp!=NULL && strlen(mp->value)>0){
197    scriptName=(char*)malloc((strlen(cwd->value)+strlen(mp->value)+strlen(tmp->value)+3)*sizeof(char));
198    sprintf(scriptName,"%s/%s/%s",cwd->value,mp->value,tmp->value);
199  }else{
200    scriptName=(char*)malloc((strlen(cwd->value)+strlen(tmp->value)+2)*sizeof(char));
201    sprintf(scriptName,"%s/%s",cwd->value,tmp->value);
202  }
203  zend_file_handle iscript;
204  iscript.type=ZEND_HANDLE_FD;
205  iscript.opened_path=NULL;
206  iscript.filename=tmp->value;
207  iscript.free_filename=0;
208  FILE* temp=fopen(scriptName,"rb");
209  if(temp==NULL){
210    char tmp1[1024];
211    sprintf(tmp1,_("Unable to load the PHP file %s"),tmp->value);
212    free(scriptName);
213    return errorException(m,tmp1,"NoApplicableCode",NULL);
214  }
215  iscript.handle.fd=fileno(temp);
216
217  php_embed_init(0,NULL PTSRMLS_CC);
218   
219  zend_try {
220    zend_startup_module(&zoo_module_entry);
221    php_execute_script(&iscript TSRMLS_CC);
222    zval *iargs[3];
223    zval iret, ifunc,ifile;
224     
225    ZVAL_STRING(&ifunc, s->name, 0);
226    iargs[0] = php_Array_from_maps(*main_conf);
227    iargs[1] = php_Array_from_maps(*real_inputs);
228    iargs[2] = php_Array_from_maps(*real_outputs);
229     
230    if((res=call_user_function(EG(function_table), NULL, &ifunc, &iret, 3, iargs TSRMLS_CC))==SUCCESS){
231     
232      HashTable* t=HASH_OF(iargs[2]);
233      HashTable* t1=HASH_OF(iargs[0]);
234      *real_outputs=php_maps_from_Array(t);
235      *main_conf=php_maps_from_Array(t1);
236
237      res=Z_LVAL(iret);
238    }else{
239      free(scriptName);
240      fclose(temp);
241      return errorException(m,"Unable to process.","NoApplicableCode",NULL);;
242    }
243  } zend_catch { 
244    free(scriptName);
245    fclose(temp);
246    return errorException(m,"Unable to process.","NoApplicableCode",NULL);;
247  } zend_end_try();
248  free(scriptName);
249  fclose(temp);
250  php_embed_shutdown(TSRMLS_C);
251
252  return res;
253}
254
255/**
256 * Convert a maps to a php Array
257 *
258 * @param t the maps to convert
259 * @return the php Array
260 */
261zval *php_Array_from_maps(maps* t){
262  zval *mapArray;
263  zval *mapArrayTmp;
264  maps* tmp=t;
265  int tres=0;
266  MAKE_STD_ZVAL(mapArray);
267  tres=array_init(mapArray);
268  while(tmp!=NULL){
269    add_assoc_zval(mapArray,tmp->name,php_Array_from_map(tmp->content));
270    tmp=tmp->next;
271  }
272  return mapArray;
273}
274
275/**
276 * Convert a map to a php Array
277 *
278 * @param t the map to convert
279 * @return the php Array
280 */
281zval *php_Array_from_map(map* t){
282  zval *mapArray;
283  zval *mapArrayTmp;
284  map* tmp=t;
285  int tres=0;
286  MAKE_STD_ZVAL(mapArray);
287  tres=array_init(mapArray);
288  while(tmp!=NULL){
289    map* sMap=getMapArray(tmp,"size",0);   
290        if(strncmp(tmp->name,"value",5)==0 && sMap!=NULL && tmp->value != NULL){
291      tres=add_assoc_stringl(mapArray,tmp->name,tmp->value,atoi(sMap->value),1);
292        } 
293        else if (tmp->value != NULL) {
294      tres=add_assoc_string(mapArray,tmp->name,tmp->value,1);
295        }
296    tmp=tmp->next;
297  }
298  return mapArray;
299}
300
301/**
302 * Convert a php Array to a maps
303 *
304 * @param t the php Array to convert
305 * @return the created maps
306 */
307maps* php_maps_from_Array(HashTable *t){
308  maps* final_res=NULL;
309  maps* cursor=final_res;
310  char key[1024];
311  for(zend_hash_internal_pointer_reset(t); 
312      zend_hash_has_more_elements(t) == SUCCESS; 
313      zend_hash_move_forward(t)) { 
314    char *key; 
315    uint keylen; 
316    ulong idx; 
317    int type; 
318    zval **ppzval, tmpcopy; 
319    type = zend_hash_get_current_key_ex(t, &key, &keylen, &idx, 0, NULL); 
320    if (zend_hash_get_current_data(t, (void**)&ppzval) == FAILURE) { 
321      /**
322       * Should never actually fail since the key is known to exist.
323       */
324      continue; 
325    }
326    /**
327     * Duplicate the zval so that * the orignal’s contents are not destroyed
328     */
329    tmpcopy = **ppzval;
330#ifdef DEBUG
331    fprintf(stderr,"key : %s\n",key);
332#endif
333    zval_copy_ctor(&tmpcopy); 
334#ifdef DEBUG
335    fprintf(stderr,"key : %s\n",key);
336#endif
337    /**
338     * Reset refcount & Convert
339     */
340    INIT_PZVAL(&tmpcopy); 
341    //convert_to_string(&tmpcopy);
342    if (type == HASH_KEY_IS_STRING) { 
343      /**
344       * String Key / Associative
345       */
346      cursor=(maps*)malloc(MAPS_SIZE);
347      cursor->name=strdup(key);
348    }
349#ifdef DEBUG   
350    fprintf(stderr,"key : %s\n",key);
351#endif 
352    HashTable* t=HASH_OF(*ppzval);
353#ifdef DEBUG
354    fprintf(stderr,"key : %s\n",key);
355#endif
356    cursor->content=php_map_from_HasTable(t);
357    cursor->next=NULL;
358    if(final_res==NULL)
359      final_res=cursor;
360    else{
361      addMapsToMaps(&final_res,cursor);
362      freeMaps(&cursor);
363      free(cursor);
364    }
365#ifdef DEBUG
366    fprintf(stderr,"key : %s\n",key);
367#endif
368    /**
369     * Toss out old copy
370     */
371    zval_dtor(&tmpcopy);
372  }
373  return final_res;
374}
375
376/**
377 * Convert a php Array to a map
378 *
379 * @param t the php Array to convert
380 * @return the created map
381 */
382map* php_map_from_HasTable(HashTable* t){
383#ifdef DEBUG
384  fprintf(stderr,"mapsFromPHPArray start\n");
385#endif
386  map* final_res=(map*)malloc(MAP_SIZE);
387  final_res=NULL;
388  char key[1024];
389  for(zend_hash_internal_pointer_reset(t);
390      zend_hash_has_more_elements(t) == SUCCESS;
391      zend_hash_move_forward(t)) {
392    char *key;
393    uint keylen;
394    ulong idx;
395    int type;
396    int len;
397    zval **ppzval, tmpcopy;
398    type = zend_hash_get_current_key_ex(t, &key, &keylen, &idx, 0, NULL); 
399    if (zend_hash_get_current_data(t, (void**)&ppzval) == FAILURE) { 
400      /* Should never actually fail * since the key is known to exist. */ 
401      continue; 
402    }
403    /**
404     * Duplicate the zval so that * the orignal’s contents are not destroyed
405     */ 
406    tmpcopy = **ppzval; 
407    zval_copy_ctor(&tmpcopy); 
408    /**
409     * Reset refcount & Convert
410     */ 
411    INIT_PZVAL(&tmpcopy); 
412    convert_to_string(&tmpcopy);
413    if(strncmp(key,"value",5)==0){
414      len=Z_STRLEN_P(&tmpcopy);
415      addToMapWithSize(final_res,key,Z_STRVAL_P(&tmpcopy),len);
416    }
417    else{
418      if(final_res==NULL){
419#ifdef DEBUG
420        fprintf(stderr,"%s => %s\n",key,Z_STRVAL(tmpcopy));
421#endif
422        final_res=createMap(key,Z_STRVAL(tmpcopy));
423      }
424      else{
425#ifdef DEBUG
426        fprintf(stderr,"%s => %s\n",key,Z_STRVAL(tmpcopy));
427#endif
428        addToMap(final_res,key,Z_STRVAL(tmpcopy));
429      }
430    }
431    /* Toss out old copy */ 
432    zval_dtor(&tmpcopy); 
433  }
434  return final_res;
435}
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png