source: trunk/zoo-project/zoo-kernel/service_internal_js.c @ 752

Last change on this file since 752 was 752, checked in by djay, 5 years ago

Add optional CORS support. Fix issue when dealing with Array in JavaScript? support.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 26.6 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2012 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#include "service_internal_js.h"
26#include "response_print.h"
27
28#ifndef JSCLASS_GLOBAL_FLAGS
29#define JSCLSAS_GLOBAL_FLAGS 0
30#endif
31
32static char dbg[1024];
33
34/**
35 * The function used as alert from the JavaScript environment (ZOO-API)
36 *
37 * @param cx the JavaScript context
38 * @param argc the number of parameters
39 * @param argv1 the parameter values
40 * @return true
41 */
42JSBool
43JSAlert(JSContext *cx, uintN argc, jsval *argv1)
44{
45  jsval *argv = JS_ARGV(cx,argv1);
46  int i=0;
47  JS_MaybeGC(cx);
48  for(i=0;i<argc;i++){
49    JSString* jsmsg = JS_ValueToString(cx,argv[i]);
50    char *tmp=JS_EncodeString(cx,jsmsg);
51    fprintf(stderr,"[ZOO-API:JS] %s\n",tmp);
52    free(tmp);
53  }
54  JS_MaybeGC(cx);
55 
56  return JS_TRUE;
57}
58
59/**
60 * The function used as importScript from the JavaScript environment (ZOO-API)
61 *
62 * @param cx the JavaScript context
63 * @param argc the number of parameters
64 * @param argv1 the parameter values
65 * @return true
66 */
67JSBool
68JSLoadScripts(JSContext *cx, uintN argc, jsval *argv1)
69{
70  JS_MaybeGC(cx);
71
72  char ntmp[1024];
73  getcwd(ntmp,1024);
74
75  jsval *argv = JS_ARGV(cx,argv1);
76  int i=0;
77  JS_MaybeGC(cx);
78  for(i=0;i<argc;i++){
79    char *filename = JSValToChar(cx,&argv[i]);
80    char *api0=(char*)malloc((strlen(ntmp)+strlen(filename)+2)*sizeof(char));
81    sprintf(api0,"%s/%s",ntmp,filename);
82#ifdef JS_DEBUG
83    fprintf(stderr,"Trying to load %s\n",api0);
84    fflush(stderr);
85#endif
86    JSObject *api_script1=loadZooApiFile(cx,JS_GetGlobalObject(cx),api0);
87    free(api0);
88  }
89  JS_MaybeGC(cx);
90  JS_SET_RVAL(cx, argv1, JSVAL_VOID);
91 
92  return JS_TRUE;
93}
94
95/**
96 * Load a JavaScript file then run the function corresponding to the service by
97 * passing the conf, inputs and outputs parameters by value as JavaScript
98 * Objects.
99 *
100 * @param main_conf the conf maps containing the main.cfg settings
101 * @param request the map containing the HTTP request
102 * @param s the service structure
103 * @param inputs the maps containing the inputs
104 * @param outputs the maps containing the outputs
105 * @return SERVICE_SUCCEEDED or SERVICE_FAILED if the service run, -1
106 *  if the service failed to load or throw error at runtime.
107 */
108int zoo_js_support(maps** main_conf,map* request,service* s,maps **inputs,maps **outputs)
109{
110  /*maps* main=*main_conf;
111  maps* _inputs=*inputs;
112  maps* _outputs=*outputs;*/
113
114  /* The class of the global object. */
115  JSClass global_class= {
116    "global", JSCLASS_GLOBAL_FLAGS,
117    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
118    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
119    JSCLASS_NO_OPTIONAL_MEMBERS
120  };
121
122  /* JS variables. */
123  JSRuntime *rt;
124  JSContext *cx;
125  JSObject  *global;
126
127  /* Create a JS runtime. */
128  rt = JS_NewRuntime(8L * 1024L * 1024L);
129  if (rt == NULL)
130    return 1;
131 
132  /* Create a context. */
133  cx = JS_NewContext(rt,8192);
134  if (cx == NULL){
135    return 1;
136  }
137  JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
138  JS_SetVersion(cx, JSVERSION_LATEST);
139  JS_SetErrorReporter(cx, reportError);
140
141  /* Create the global object. */
142  global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
143
144  /* Populate the global object with the standard globals,
145     like Object and Array. */
146  if (!JS_InitStandardClasses(cx, global)){
147    return 1;
148  }
149
150  /* Define specific function and global variable to share with JS runtime
151   */
152  jsval tmp=INT_TO_JSVAL(3);
153  if (!JS_SetProperty(cx, global, "SERVICE_SUCCEEDED", &tmp))
154    return 1;
155  tmp=INT_TO_JSVAL(4);
156  if (!JS_SetProperty(cx, global, "SERVICE_FAILED", &tmp))
157    return 1;
158  if (!JS_DefineFunction(cx, global, "ZOORequest", JSRequest, 4, 0))
159    return 1;
160  if (!JS_DefineFunction(cx, global, "ZOOTranslate", JSTranslate, 4, 0))
161    return 1;
162  if (!JS_DefineFunction(cx, global, "ZOOUpdateStatus", JSUpdateStatus, 2, 0))
163    return 1;
164  if (!JS_DefineFunction(cx, global, "alert", JSAlert, 2, 0))
165    return 1; 
166  if (!JS_DefineFunction(cx, global, "importScripts", JSLoadScripts, 1, 0))
167    return 1;
168
169  /**
170   * Add private context object
171   */
172  void* cxPrivate = request;
173  JS_SetContextPrivate(cx,cxPrivate);
174
175  map* tmpm1=getMap(request,"metapath");
176  char ntmp[1024];
177  getcwd(ntmp,1024);
178
179  /**
180   * Load the first part of the ZOO-API
181   */
182  char *api0=(char*)malloc((strlen(ntmp)+17)*sizeof(char));
183  sprintf(api0,"%s/ZOO-proj4js.js",ntmp);
184#ifdef JS_DEBUG
185  fprintf(stderr,"Trying to load %s\n",api0);
186#endif
187  JSObject *api_script1=loadZooApiFile(cx,global,api0);
188  free(api0);
189  fflush(stderr);
190
191  char *api1=(char*)malloc((strlen(ntmp)+13)*sizeof(char));
192  sprintf(api1,"%s/ZOO-api.js",ntmp);
193#ifdef JS_DEBUG
194  fprintf(stderr,"Trying to load %s\n",api1);
195#endif
196  JSObject *api_script2=loadZooApiFile(cx,global,api1);
197  free(api1);
198  fflush(stderr);
199
200  /* Your application code here. This may include JSAPI calls
201     to create your own custom JS objects and run scripts. */
202  //maps* out=*outputs;
203  int res=SERVICE_FAILED;
204  //maps* mc=*main_conf;
205  map* tmpm2=getMap(s->content,"serviceProvider");
206
207  char *filename=(char*)malloc(strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+3);
208  sprintf(filename,"%s/%s/%s",ntmp,tmpm1->value,tmpm2->value);
209  filename[strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+2]=0;
210#ifdef JS_DEBUG
211  fprintf(stderr,"FILENAME %s\n",filename);
212#endif
213  struct stat file_status;
214  stat(filename, &file_status);
215  //char *source=(char*)malloc(file_status.st_size);
216  //uint16 lineno;
217  jsval rval;
218  JSBool ok ;
219  JSObject *script = JS_CompileFile(cx, global, filename);
220  if(script!=NULL){
221    (void)JS_ExecuteScript(cx, global, script, &rval);
222  }
223  else{
224    char tmp1[1024];
225    sprintf(tmp1,"Unable to load JavaScript file %s",filename);
226    free(filename);
227    errorException(*main_conf,tmp1,"NoApplicableCode",NULL);
228    JS_MaybeGC(cx);
229    JS_DestroyContext(cx);
230    JS_DestroyRuntime(rt);
231    JS_ShutDown();
232    return -1;
233  }
234 
235
236  /* Call a function in obj's scope. */
237  jsval argv[3];
238  JSObject *jsargv1=JSObject_FromMaps(cx,*main_conf);
239  argv[0] = OBJECT_TO_JSVAL(jsargv1);
240  JSObject *jsargv2=JSObject_FromMaps(cx,*inputs);
241  argv[1] = OBJECT_TO_JSVAL(jsargv2);
242  JSObject *jsargv3=JSObject_FromMaps(cx,*outputs);
243  argv[2] = OBJECT_TO_JSVAL(jsargv3);
244  jsval rval1=JSVAL_NULL;
245#ifdef JS_DEBUG
246  fprintf(stderr, "object %p\n", (void *) argv[2]);
247#endif
248
249  ok = JS_CallFunctionName(cx, global, s->name, 3, argv, &rval1);
250
251#ifdef JS_DEBUG
252  fprintf(stderr, "object %p\n", (void *) argv[2]);
253#endif
254
255  JSObject *d;
256  if (ok==JS_TRUE && JSVAL_IS_OBJECT(rval1)==JS_TRUE) {
257#ifdef JS_DEBUG
258    fprintf(stderr,"Function run sucessfully !\n");
259#endif
260    /* Should get a number back from the service function call. */
261    ok = JS_ValueToObject(cx, rval1, &d);
262  }else{
263    /* Unable to run JS function */
264    char tmp1[1024];
265    if(strlen(dbg)==0)
266      sprintf(dbg,"No result was found after the function call");
267    sprintf(tmp1,"Unable to run %s from the JavaScript file %s : \n %s",s->name,filename,dbg);
268#ifdef JS_DEBUG
269    fprintf(stderr,"%s",tmp1);
270#endif
271    errorException(*main_conf,tmp1,"NoApplicableCode",NULL);
272    free(filename);
273    JS_MaybeGC(cx);
274    JS_DestroyContext(cx);
275    JS_DestroyRuntime(rt);
276    JS_ShutDown();
277    // Should return -1 here but the unallocation won't work from zoo_service_loader.c line 1847
278    return -1;
279  }
280
281  //jsval t=OBJECT_TO_JSVAL(d);
282  if(JS_IsArrayObject(cx,d)){
283#ifdef JS_DEBUG
284    fprintf(stderr,"An array was returned !\n");
285#endif
286    jsuint       len;
287    if((JS_GetArrayLength(cx, d, &len)==JS_FALSE)){
288#ifdef JS_DEBUG
289      fprintf(stderr,"outputs array is empty\n");
290#endif
291    }
292    jsval tmp1;
293    JSBool hasResult=JS_GetElement(cx,d,0,&tmp1);
294    res=JSVAL_TO_INT(tmp1);
295#ifdef JS_DEBUG
296    fprintf(stderr," * %d * \n",res);
297#endif
298    if(res==SERVICE_SUCCEEDED){
299      jsval tmp2;
300      JSBool hasElement=JS_GetElement(cx,d,1,&tmp2);
301      if(hasElement==JS_TRUE){
302        freeMaps(outputs);
303        free(*outputs);
304        *outputs=mapsFromJSObject(cx,tmp2);
305      }
306    }else{
307      jsval tmp3;
308      JSBool hasConf=JS_GetElement(cx,d,1,&tmp3);
309      if(hasConf==JS_TRUE){
310        freeMaps(main_conf);
311        free(*main_conf);
312        *main_conf=mapsFromJSObject(cx,tmp3);
313      }
314    }
315
316  }
317  else{
318#ifdef JS_DEBUG
319    fprintf(stderr,"The service didn't return an array !\n");
320#endif
321    /**
322     * Extract result
323     */
324    jsval tmp1;
325    JSBool hasResult=JS_GetProperty(cx,d,"result",&tmp1);
326    res=JSVAL_TO_INT(tmp1);
327
328#ifdef JS_DEBUG
329    fprintf(stderr," * %d * \n",res);
330#endif
331    /**
332     * Extract outputs when available.
333     */
334    jsval tmp2;
335    JSBool hasElement=JS_GetProperty(cx,d,"outputs",&tmp2);
336    if(!JSVAL_IS_VOID(tmp2) && hasElement==JS_TRUE){
337      freeMaps(outputs);
338      free(*outputs);   
339      *outputs=mapsFromJSObject(cx,tmp2);
340    }
341    JS_MaybeGC(cx);
342#ifdef JS_DEBUG
343    if(JSVAL_IS_VOID(tmp2))
344      fprintf(stderr,"No outputs property returned\n");
345    else{
346      if(JS_IsArrayObject(cx,JSVAL_TO_OBJECT(tmp2)))
347        fprintf(stderr,"outputs is an array as expected\n");
348      else
349        fprintf(stderr,"outputs is not an array as expected\n");
350    }
351    JS_MaybeGC(cx);
352#endif
353
354    /**
355     * Extract conf when available.
356     */
357    jsval tmp3;
358    JSBool hasConf=JS_GetProperty(cx,d,"conf",&tmp3);
359    if(!JSVAL_IS_VOID(tmp3) && hasConf==JS_TRUE){
360      freeMaps(main_conf);
361      free(*main_conf);
362      *main_conf=mapsFromJSObject(cx,tmp3);
363    }
364    JS_MaybeGC(cx);
365
366#ifdef JS_DEBUG
367    dumpMaps(*outputs);
368#endif
369  }
370  /* Cleanup. */
371  JS_MaybeGC(cx);
372  JS_DestroyContext(cx);
373  JS_DestroyRuntime(rt);
374  JS_ShutDown();
375  free(filename);
376#ifdef JS_DEBUG
377  fprintf(stderr,"Returned value %d\n",res);
378#endif
379  return res;
380}
381
382/**
383 * Load a JavaScript file
384 *
385 * @param cx the JavaScript context
386 * @param global the global JavaScript object (not used)
387 * @param filename the file name to load
388 * @return a JavaScript Object on success, NULL if an errro occured
389 */
390JSObject * loadZooApiFile(JSContext *cx,JSObject  *global, char* filename){
391  struct stat api_status;
392  int s=stat(filename, &api_status);
393  if(s==0){
394    jsval rval;
395    JSObject *script = JS_CompileFile(cx, JS_GetGlobalObject(cx), filename);
396    if(script!=NULL){
397      (void)JS_ExecuteScript(cx, JS_GetGlobalObject(cx), script, &rval);
398#ifdef JS_DEBUG
399      fprintf(stderr,"**************\n%s correctly loaded\n**************\n",filename);
400#endif
401      return script;
402    }
403#ifdef JS_DEBUG
404    else
405      fprintf(stderr,"\n**************\nUnable to run %s\n**************\n",filename);
406#endif
407  }
408#ifdef JS_DEBUG
409  else
410    fprintf(stderr,"\n**************\nUnable to load %s\n**************\n",filename);
411#endif
412  return NULL;
413}
414
415/**
416 * Convert a maps to a JavaScript Object
417 *
418 * @param cx the JavaScript context
419 * @param t the maps to convert
420 * @return a new JavaScript Object
421 */
422JSObject* JSObject_FromMaps(JSContext *cx,maps* t){
423  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
424  if(res==NULL)
425    fprintf(stderr,"Array Object is NULL!\n");
426  maps* tmp=t;
427  while(tmp!=NULL){
428    JSObject *pval=JSObject_FromMap(cx,tmp->content);
429    jsval pvalj=OBJECT_TO_JSVAL(pval);
430    JS_SetProperty(cx, res, tmp->name, &pvalj);
431#ifdef JS_DEBUG
432    fprintf(stderr,"Length of the Array %d, element : %s added \n",len,tmp->name);
433#endif
434    tmp=tmp->next;
435  } 
436  return res;
437}
438
439/**
440 * Convert a map to a JavaScript Object
441 *
442 * @param cx the JavaScript context
443 * @param t the map to convert
444 * @return a new JavaScript Object
445 */
446JSObject* JSObject_FromMap(JSContext *cx,map* t){
447  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
448  map* tmpm=t;
449  map* isArray=getMap(t,"isArray");
450  map* isBinary=getMap(t,"size");
451  map* tmap=getMapType(t);
452#ifdef JS_DEBUG
453  if(tmap==NULL)
454    fprintf(stderr,"tmap is null !\n");
455  else
456    fprintf(stderr,"tmap is not null ! (%s = %s)\n",tmap->name,tmap->value);
457#endif
458  while(isArray==NULL && tmpm!=NULL){
459    jsval jsstr;
460    if(isBinary!=NULL && strncasecmp(tmpm->name,"value",5)==0)
461      jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,atoi(isBinary->value)));
462    else
463      jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
464    JS_SetProperty(cx, res, tmpm->name,&jsstr);
465#ifdef JS_DEBUG
466    fprintf(stderr,"[JS] %s => %s\n",tmpm->name,tmpm->value);
467#endif
468    tmpm=tmpm->next;
469  }
470  if(isArray!=NULL){
471    map* len=getMap(t,"length");
472    int cnt=atoi(len->value);
473    JSObject* values=JS_NewArrayObject( cx, cnt, NULL );
474    JSObject* mvalues=JS_NewArrayObject( cx, cnt, NULL );
475    map *tmpm1,*tmpm2,*tmpm3;
476    int i=0;
477    for(i=0;i<cnt;i++){
478      tmpm1=getMapArray(t,"value",i);
479      tmpm2=getMapArray(t,tmap->name,i);
480      tmpm3=getMapArray(t,"size",i);
481      if(tmpm1!=NULL){
482        jsval jsstr;
483        if(tmpm3!=NULL)
484          jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm1->value,atoi(tmpm3->value)));
485        else
486          jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm1->value,strlen(tmpm1->value)));
487        JS_SetElement( cx, values, i, &jsstr );
488      }
489      if(tmpm2!=NULL){
490        jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm2->value,strlen(tmpm2->value)));
491        JS_SetElement( cx, mvalues, i, &jsstr );
492      }
493    }
494    jsval jvalues=OBJECT_TO_JSVAL(values);
495    jsval jmvalues=OBJECT_TO_JSVAL(mvalues);
496    JS_SetProperty(cx, res,"value",&jvalues);
497    JS_SetProperty(cx, res,tmap->name,&jmvalues);
498    while(tmpm!=NULL){
499      if(strncasecmp(tmpm->name,"value",5)!=0 && strncasecmp(tmpm->name,"size",4)!=0 && strncasecmp(tmpm->name,tmap->name,strlen(tmap->name))!=0){
500        jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
501        JS_SetProperty(cx, res, tmpm->name,&jsstr);
502      }
503#ifdef JS_DEBUG
504      fprintf(stderr,"[JS] %s => %s\n",tmpm->name,tmpm->value);
505#endif
506      tmpm=tmpm->next;
507    }
508  }
509  return res;
510}
511
512/**
513 * Convert a JavaScript Object to a maps
514 *
515 * @param cx the JavaScript context
516 * @param t the JavaScript Object to convert
517 * @return a new maps containing the JavaScript Object
518 */
519maps* mapsFromJSObject(JSContext *cx,jsval t){
520  maps *res=NULL;
521  maps *tres=NULL;
522  jsint oi=0;
523  JSObject* tt=JSVAL_TO_OBJECT(t);
524  if(JS_IsArrayObject(cx,tt)){
525#ifdef JS_DEBUG
526    fprintf(stderr,"Is finally an array !\n");
527#endif
528  }
529  else{
530#ifdef JS_DEBUG
531    fprintf(stderr,"Is not an array !\n");
532#endif
533    JSIdArray *idp=JS_Enumerate(cx,tt);
534    if(idp!=NULL) {
535      int index;
536      jsdouble argNum;
537#ifdef JS_DEBUG
538      fprintf(stderr,"Properties length :  %d \n",idp->length);
539#endif
540     
541      for (index=0,argNum=idp->length;index<argNum;index++) { 
542        jsval id = idp->vector[index];
543        jsval vp;
544        JS_IdToValue(cx,id,&vp);
545        char *tmp;
546        JSString *jsmsg;
547        size_t len1;
548        jsmsg = JS_ValueToString(cx,vp);
549        len1 = JS_GetStringLength(jsmsg);
550       
551        tmp=JS_EncodeString(cx,jsmsg);
552        tres=(maps*)malloc(MAPS_SIZE);
553        tres->name=zStrdup(tmp);
554        tres->content=NULL;
555        tres->next=NULL;
556
557        jsval nvp=JSVAL_NULL;
558        if((JS_GetProperty(cx, tt, tmp, &nvp)==JS_FALSE)){
559#ifdef JS_DEBUG
560          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
561#endif
562        }
563        free(tmp);
564        JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
565        JS_ValueToObject(cx,nvp,&nvp1);
566        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
567        if(JSVAL_IS_OBJECT(nvp1j)){
568          tres->content=mapFromJSObject(cx,nvp1j);
569        }
570
571        if(res==NULL)
572          res=dupMaps(&tres);
573        else
574          addMapsToMaps(&res,tres);
575        freeMaps(&tres);
576        free(tres);
577        tres=NULL;
578               
579      }
580      JS_DestroyIdArray(cx,idp);
581    }
582  }
583
584  jsuint len;
585  JSBool hasLen=JS_GetArrayLength(cx, tt, &len);
586#ifdef JS_DEBUG
587  if(hasLen==JS_FALSE){
588    fprintf(stderr,"outputs array is empty\n");
589  }
590  fprintf(stderr,"outputs array length : %d\n",len);
591#endif
592  for(oi=0;hasLen && oi < len;oi++){
593#ifdef JS_DEBUG
594    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
595#endif
596    jsval tmp1;
597    JSBool hasElement=JS_GetElement(cx,tt,oi,&tmp1);
598    JSObject *otmp1=JSVAL_TO_OBJECT(tmp1);
599    JSIdArray *idp=JS_Enumerate(cx,otmp1);
600    if(idp!=NULL) {
601      int index;
602      jsdouble argNum;
603#ifdef JS_DEBUG
604      fprintf(stderr,"Properties length :  %d \n",idp->length);
605#endif
606      tres=(maps*)malloc(MAPS_SIZE);
607      tres->name=NULL;
608      tres->content=NULL;
609      tres->next=NULL;
610
611      for (index=0,argNum=idp->length;index<argNum;index++) { 
612        jsval id = idp->vector[index];
613        jsval vp;
614        JS_IdToValue(cx,id,&vp);
615        char *tmp;
616        JSString *jsmsg;
617        size_t len1;
618        jsmsg = JS_ValueToString(cx,vp);
619        len1 = JS_GetStringLength(jsmsg);
620        tmp=JS_EncodeString(cx,jsmsg);
621#ifdef JS_DEBUG
622        fprintf(stderr,"Enumerate id : %d => %s\n",oi,tmp);
623#endif
624        jsval nvp=JSVAL_NULL;
625        if((JS_GetProperty(cx, JSVAL_TO_OBJECT(tmp1), tmp, &nvp)==JS_FALSE)){
626#ifdef JS_DEBUG
627          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
628#endif
629        }
630        free(tmp);
631        if(JSVAL_IS_OBJECT(nvp)){
632#ifdef JS_DEBUG
633          fprintf(stderr,"JSVAL NVP IS OBJECT\n");
634#endif
635        }
636
637        JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
638        JS_ValueToObject(cx,nvp,&nvp1);
639        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
640        if(JSVAL_IS_OBJECT(nvp1j)){
641          JSString *jsmsg1;
642          char *tmp1, *tmp2;
643          JSObject *nvp2=JSVAL_TO_OBJECT(JSVAL_NULL);
644          jsmsg1 = JS_ValueToString(cx,nvp1j);
645          len1 = JS_GetStringLength(jsmsg1);
646          tmp1=JS_EncodeString(cx,jsmsg1);
647          tmp2=JS_EncodeString(cx,jsmsg);
648#ifdef JS_DEBUG
649          fprintf(stderr,"JSVAL NVP1J IS OBJECT %s = %s\n",JS_EncodeString(cx,jsmsg),tmp1);
650#endif
651          if(strcasecmp(tmp1,"[object Object]")==0){
652            tres->name=zStrdup(tmp2);
653            tres->content=mapFromJSObject(cx,nvp1j);
654          }
655          else
656            if(strcasecmp(tmp2,"name")==0){
657              tres->name=zStrdup(tmp1);
658            }
659            else{
660              if(tres->content==NULL)
661                tres->content=createMap(tmp2,tmp1);
662              else
663                addToMap(tres->content,tmp2,tmp1);
664            }
665          free(tmp1);
666          free(tmp2);
667        }
668#ifdef JS_DEBUG
669        else
670          fprintf(stderr,"JSVAL NVP1J IS NOT OBJECT !!\n");
671#endif
672      }
673#ifdef JS_DEBUG
674      dumpMaps(tres);
675#endif
676      if(res==NULL)
677        res=dupMaps(&tres);
678      else
679        addMapsToMaps(&res,tres);
680      freeMaps(&tres);
681      free(tres);
682      tres=NULL;
683      JS_DestroyIdArray(cx,idp);
684    }
685  }
686#ifdef JS_DEBUG
687  dumpMaps(res);
688#endif
689  return res;
690}
691
692/**
693 * Convert a JavaScript Object to a map
694 *
695 * @param cx the JavaScript context
696 * @param t the JavaScript Object to convert
697 * @return a new map containing the JavaScript Object
698 */
699map* mapFromJSObject(JSContext *cx,jsval t){
700  map *res=NULL;
701  JSIdArray *idp=JS_Enumerate(cx,JSVAL_TO_OBJECT(t));
702#ifdef JS_DEBUG
703  fprintf(stderr,"Properties %p\n",(void*)t);
704#endif
705  if(idp!=NULL) {
706    int index;
707    jsdouble argNum;
708#ifdef JS_DEBUG
709    fprintf(stderr,"Properties length :  %d \n",idp->length);
710#endif
711    for (index=0,argNum=idp->length;index<argNum;index++) { 
712      jsval id = idp->vector[index];
713      jsval vp;
714      JS_IdToValue(cx,id,&vp);
715      char *tmp, *tmp1;
716      JSString *jsmsg,*jsmsg1;
717      size_t len,len1;
718      jsmsg = JS_ValueToString(cx,vp);
719      len = JS_GetStringLength(jsmsg);
720      jsval nvp;
721      tmp=JS_EncodeString(cx,jsmsg);
722      JS_GetProperty(cx, JSVAL_TO_OBJECT(t), tmp, &nvp);
723      jsmsg1 = JS_ValueToString(cx,nvp);
724      len1 = JS_GetStringLength(jsmsg1);
725      tmp1=JS_EncodeString(cx,jsmsg1);
726#ifdef JS_DEBUG
727      fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,tmp,tmp1);
728#endif
729      if(res!=NULL){
730#ifdef JS_DEBUG
731        fprintf(stderr,"%s - %s\n",tmp,tmp1);
732#endif
733        addToMap(res,tmp,tmp1);
734      }
735      else{
736        res=createMap(tmp,tmp1);
737        res->next=NULL;
738      }
739      free(tmp);
740      free(tmp1);
741#ifdef JS_DEBUG
742      dumpMap(res);
743#endif
744    }
745    JS_DestroyIdArray(cx,idp);
746  }
747#ifdef JS_DEBUG
748  dumpMap(res);
749#endif
750  return res;
751}
752
753/**
754 * Print debug information messages on stderr
755 *
756 * @param cx the JavaScript context
757 * @param message the error message
758 * @param report the JavaScript Error Report
759 */
760void reportError(JSContext *cx, const char *message, JSErrorReport *report)
761{
762  sprintf(dbg,"%s:%u:%s\n",
763          report->filename ? report->filename : "<no filename>",
764          (unsigned int) report->lineno,
765          message);
766#ifdef JS_DEBUG
767  fprintf(stderr,"%s",dbg);
768#endif
769  fflush(stderr);
770}
771
772/**
773 * Convert a JavaScript value to a char*
774 *
775 * @param context the JavaScript context
776 * @param arg the JavaScript value
777 * @return a new char*
778 * @warning be sure to free the ressources returned by this function
779 */
780char* JSValToChar(JSContext* context, jsval* arg) {
781  char *c;
782  char *tmp;
783  JSString *jsmsg;
784  size_t len;
785  int i;
786  if(!JSVAL_IS_STRING(*arg)) {
787    return NULL;
788  }
789  jsmsg = JS_ValueToString(context,*arg);
790  len = JS_GetStringLength(jsmsg);
791  tmp = JS_EncodeString(context,jsmsg);
792  c = (char*)malloc((len+1)*sizeof(char));
793  c[len] = '\0';
794#ifdef ULINET_DEBUG
795  fprintf(stderr,"%d \n",len);
796#endif
797  for(i = 0;i < len;i++) {
798    c[i] = tmp[i];
799    c[i+1] = 0;
800  }
801#ifdef ULINET_DEBUG
802  fprintf(stderr,"%s \n",c);
803#endif
804  return c;
805}
806
807/**
808 * Set the HTTP header of a request
809 *
810 * @param handle the HINTERNET handle
811 * @param cx the JavaScript context
812 * @param header the JavaScript Array containing the headers to send
813 * @return the HINTERNET handle
814 */
815HINTERNET setHeader(HINTERNET* handle,JSContext *cx,JSObject *header){
816  jsuint length=0;
817  jsint i=0;
818  char *tmp1;
819#ifdef ULINET_DEBUG
820  fprintf(stderr,"setHeader\n");
821#endif
822  if(JS_IsArrayObject(cx,header)){
823#ifdef ULINET_DEBUG
824    fprintf(stderr,"header is an array\n");
825#endif
826    JS_GetArrayLength(cx,header,&length);
827#ifdef ULINET_DEBUG
828    fprintf(stderr,"header is an array of %d elements\n",length);
829#endif
830    handle->ihandle[handle->nb].header=NULL;
831    for(i=0;i<length;i++){
832      jsval tmp;
833      JS_GetElement(cx,header,i,&tmp);
834      tmp1=JSValToChar(cx,&tmp);
835#ifdef ULINET_DEBUG
836      curl_easy_setopt(handle->ihandle[handle->nb].handle,CURLOPT_VERBOSE,1);
837      fprintf(stderr,"Element of array n° %d, value : %s\n",i,tmp1);
838#endif
839      handle->ihandle[handle->nb].header=curl_slist_append(handle->ihandle[handle->nb].header, tmp1);
840      free(tmp1);
841    }
842  }
843  else{
844    fprintf(stderr,"not an array !!!!!!!\n");
845  }
846  return *handle;
847}
848
849/**
850 * The function used as ZOOTranslate from the JavaScript environment.
851 * Use the ZOO-Services messages translation function from the Python
852 * environment (ZOO-API)
853 *
854 * @param cx the JavaScript context
855 * @param argc the number of parameters
856 * @param argv1 the parameter values
857 * @return true
858 */
859JSBool
860JSTranslate(JSContext *cx, uintN argc, jsval *argv1)
861{
862  jsval *argv = JS_ARGV(cx,argv1);
863  char *str=JSValToChar(cx,&argv[0]);
864  char *tmpValue=_ss(str);
865  JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpValue,strlen(tmpValue)))); 
866  JS_MaybeGC(cx);
867  return JS_TRUE;
868}
869
870/**
871 * The function used as ZOORequest from the JavaScript environment (ZOO-API)
872 *
873 * @param cx the JavaScript context
874 * @param argc the number of parameters
875 * @param argv1 the parameter values
876 * @return true
877 * @see setHeader
878 */
879JSBool
880JSRequest(JSContext *cx, uintN argc, jsval *argv1)
881{
882  jsval *argv = JS_ARGV(cx,argv1);
883  HINTERNET hInternet;
884  JSObject *header;
885  char *url;
886  char *method;
887  char* tmpValue;
888  size_t dwRead;
889  JS_MaybeGC(cx);
890  hInternet=InternetOpen("ZooWPSClient\0",
891                         INTERNET_OPEN_TYPE_PRECONFIG,
892                         NULL,NULL, 0);
893  if(!CHECK_INET_HANDLE(hInternet))
894    return JS_FALSE;
895  if(argc>=2){
896    method=JSValToChar(cx,&argv[0]);
897    url=JSValToChar(cx,&argv[1]);
898  }
899  else{
900    method=zStrdup("GET");
901    url=JSValToChar(cx,argv);
902  }
903  hInternet.waitingRequests[hInternet.nb]=strdup(url);
904  if(argc==4){
905    char *body;
906    body=JSValToChar(cx,&argv[2]);
907    header=JSVAL_TO_OBJECT(argv[3]);
908#ifdef ULINET_DEBUG
909    fprintf(stderr,"URL (%s) \nBODY (%s)\n",url,body);
910#endif
911    if(JS_IsArrayObject(cx,header))
912      setHeader(&hInternet,cx,header);
913#ifdef ULINET_DEBUG
914    fprintf(stderr,"BODY (%s)\n",body);
915#endif
916    InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],body,strlen(body),
917                    INTERNET_FLAG_NO_CACHE_WRITE,0);   
918    processDownloads(&hInternet);
919    free(body);
920  }else{
921    if(argc==3){
922      char *body=JSValToChar(cx,&argv[2]);
923      InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],body,strlen(body),
924                      INTERNET_FLAG_NO_CACHE_WRITE,0);
925      processDownloads(&hInternet);
926      free(body);
927    }else{
928      InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],NULL,0,
929                      INTERNET_FLAG_NO_CACHE_WRITE,0);
930      processDownloads(&hInternet);
931    }
932  }
933  tmpValue=(char*)malloc((hInternet.ihandle[0].nDataLen+1)*sizeof(char));
934  InternetReadFile(hInternet.ihandle[0],(LPVOID)tmpValue,hInternet.ihandle[0].nDataLen,&dwRead);
935#ifdef ULINET_DEBUG
936  fprintf(stderr,"content downloaded (%d) (%s) \n",dwRead,tmpValue);
937#endif
938  if(dwRead==0){
939    JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,"Unable to access the file.",strlen("Unable to access the file."))));
940    return JS_TRUE;
941  }
942
943#ifdef ULINET_DEBUG
944  fprintf(stderr,"content downloaded (%d) (%s) \n",dwRead,tmpValue);
945#endif
946  JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpValue,strlen(tmpValue))));
947  free(url);
948  if(argc>=2)
949    free(method);
950  InternetCloseHandle(&hInternet);
951  JS_MaybeGC(cx);
952  return JS_TRUE;
953}
954
955/**
956 * The function used as ZOOUpdateStatus from the JavaScript environment
957 * (ZOO-API).
958 *
959 * @param cx the JavaScript context
960 * @param argc the number of parameters
961 * @param argv1 the parameter values
962 * @return true
963 * @see setHeader,_updateStatus
964 */
965JSBool
966JSUpdateStatus(JSContext *cx, uintN argc, jsval *argv1)
967{
968  jsval *argv = JS_ARGV(cx,argv1);
969  JS_MaybeGC(cx);
970  int istatus=0;
971  char *status=NULL;
972  maps *conf;
973  if(argc>2){
974#ifdef JS_DEBUG
975    fprintf(stderr,"Number of arguments used to call the function : %i",argc);
976#endif
977    return JS_FALSE;
978  }
979  conf=mapsFromJSObject(cx,argv[0]);
980  if(JS_ValueToInt32(cx,argv[1],&istatus)==JS_TRUE){
981    char tmpStatus[4];
982    sprintf(tmpStatus,"%i",istatus);
983    tmpStatus[3]=0;
984    status=strdup(tmpStatus);
985  }
986  if(getMapFromMaps(conf,"lenv","status")!=NULL){
987    if(status!=NULL){
988      setMapInMaps(conf,"lenv","status",status);
989      free(status);
990    }
991    else
992      setMapInMaps(conf,"lenv","status","15");
993    _updateStatus(conf);
994  }
995  freeMaps(&conf);
996  free(conf);
997  JS_MaybeGC(cx);
998  return JS_TRUE;
999}
1000
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