[BACK]Return to cgi.sm1 CVS log [TXT][DIR] Up to [local] / OpenXM / src / kan96xx / Doc

File: [local] / OpenXM / src / kan96xx / Doc / cgi.sm1 (download)

Revision 1.18, Thu Mar 12 07:33:03 2020 UTC (4 years, 2 months ago) by takayama
Branch: MAIN
CVS Tags: HEAD
Changes since 1.17: +14 -5 lines

bug fix of doPolymake; work files /tmp/sm1-q-* were not removed.

% $OpenXM: OpenXM/src/kan96xx/Doc/cgi.sm1,v 1.18 2020/03/12 07:33:03 takayama Exp $
%  OpenXM/src/polymake/cgi/cgi-polymake.sh
%   is a shell script to call sm1/polymake as a CGI script.
%  Override as /doPolymake {doPolymake.OoHG} def if you need.

/cgi.verbose 0 def

[(plugin-cgi)
[(Key words: )
 ( cgiUrlEncodingToKeyValuePair)
 ( cgiKeyValuePairToHttpString)
 ( cgiKeyValuePairToUrlEncodingString)
 ( cgiStringToUrlEncoding)
 ( cgiUrlEncodedStringToObj)
 ( cgiHttpToKeyValuePair)
]] putUsages

% A sample code
% (OpenXM) cgiQueryGoogle  --> it does not work well.
/cgiQueryGoogle {
   /key set
   [[(URL),(/search)],
    [(hl),(ja)],
    [(ie),(UTF-8)],
    [(q),key]] /kv set
   [(cgiKeyValuePairToUrlEncodingString) kv] extension /sss set
   [(GET ) , sss , ( HTTP/0.9) , nl , nl ] cat /sss2 set
   
   [(sm1.socket) (connect) [80 (www.google.co.jp)]] extension 0 get /goo set
   [(sm1.socket) (write) [goo sss2]]  extension 
   goo readHTTP0 /pp set
   pp message
   [(sm1.socket) (close) [goo]] extension
   [(cgiHttpToKeyValuePair) pp] extension /pp2 set
} def

% A sample
% (www.math.kobe-u.ac.jp) cgiGetIndex
/cgiGetIndex {
   /url set
   [[(URL),(/index.html)]
   ] /kv set
   [(cgiKeyValuePairToUrlEncodingString) kv] extension /sss set
%   [(GET ) , sss , ( HTTP/0.9) , nl , nl ] cat /sss2 set
   [(GET ) , sss , ( HTTP/0.9) ,  nl ,
    (HOST: ) , url , nl
    nl ] cat /sss2 set
   
   sss2 message
   [(sm1.socket) (connect) [80 url]] extension 0 get /goo set
   [(sm1.socket) (write) [goo sss2]]  extension 
   goo readHTTP0 /pp set
   pp message
   [(sm1.socket) (close) [goo]] extension
   [(cgiHttpToKeyValuePair) pp] extension /pp2 set
} def

[(readHTTP0)
[(fd readHTTP0 result-str)
 (Read data from fd until the connection is closed.)
 (Example:)
 $[(sm1.socket) (connect) [80 (www.math.kobe-u.ac.jp)]] extension $
 $ 0 get /goo set $
 $goo readHTTP0 /pp set pp message$
 $[(sm1.socket) (close) [goo]] extension $
]] putUsages
/readHTTP0 {
  /arg1 set
  [/fd /sss /pp /pp2 /nn] pushVariables
  [
    /fd arg1 def
    /sss [ ] def
    {
      [(sm1.socket) (select) [fd -1]] extension {
      } { (select error) error } ifelse

      [(sm1.socket) (read) [fd]] extension /pp set
      pp length 0 eq { exit } { } ifelse
      sss pp append /sss set
    } loop
    sss cat /arg1 set
  ] pop
  popVariables
  arg1
} def

% -----------------------  server side -----------------------
%  command filename action
/cgiPolymake.polymakeName (polymake) def
%/cgiPolymake.polymakeName (polymake_dummy) def
%/cgiPolymake.polymakeName (hoge) def
/cgiPolymake.log 1 def

[(cgiPolymake)
[(Make sm1 to a polymake server based on CGI/OoHG)
 $ sm1 -q -s "[(parse) (cgi.sm1) pushfile] extension cgiPolymake quit " $
]] putUsages
% Server-side-script
% oxMessageBody=action input-data-for-polymake
% t.t : oxMessageBody=FACETS++POINTS%0A1+0+0+%0A1+1+0+%0A1+0+1%0A
%   t?oxMe...
% env CONTENT_LENGTH=57 sm1 -q -s "[(parse) (cgi.sm1) pushfile] extension cgiPolymake quit " <t.t
/cgiPolymake {
  {
   [(getenv) (CONTENT_LENGTH)] extension /cgi.content_length set
   cgi.content_length isString {
   } {
       cgiPolymake.errorMessage message  exit
   } ifelse 
   cgi.content_length .. (integer) dc /cgi.content_length set
   cgi.content_length 1 lt {
       cgiPolymake.errorMessage message  exit
   } { } ifelse
   [(read) 0 cgi.content_length] extension /cgi.query_string set
   cgiPolymake.log {
      cgi.query_string (string) dc sm1log
   } { } ifelse
   cgi.query_string isString { 
     cgi.query_string length 0 eq  {
       cgiPolymake.errorMessage message  exit
     } { } ifelse
   }
   {  
     cgiPolymake.errorMessage message  exit
   } ifelse  
   cgi.body.http0 message 
   cgi.query_string cgiPolymake.0
   cgi.body cgiReplyInHttp0 /cgi.body.http set
   cgi.body.http message
   exit
  } loop
  [(flush)] extension
} def
/cgiPolymake.errorMessage 
  [ (Content-Type: text/html) nl
    nl
    (<html><body>) nl
    (Input <br> action polymake-data <br> ) nl
    (Example: <pre> ) nl
    (FACETS  POINTS) nl
    (1 0 0 ) nl
    (1 1 0 ) nl
    (1 0 1 ) nl
    (</pre>) nl
    (<form method="POST">) nl
    (<input type=submit>) nl
    (<textarea name="oxMessageBody") nl
    ( rows=10 cols="80" wrap="soft"></textarea>) nl
    (</form>) nl
    (</body></html>) nl
  ] cat
def

/cgi.body.http0 
  (Content-Type: text/plain)
def
/cgiPolymake.0 {
  /arg1 set
  [/sss /kv /comm /i /acti0 /pError] pushVariables
  [ 
    /sss arg1 def
% Step 1.  analyze the query string in URL encoding.
    [(cgiUrlEncodingToKeyValuePair) sss] extension /kv set
    kv (oxMessageBody) getNode /comm set
%   [nl nl] cat message sss message kv message  % for debug.
% Step 2. Extract action part and file part for polymake. 
    comm (array) dc /comm set
    /i 0 def
    [
       0 1, comm length 1 sub {
         /i set
         comm,i,get 33 lt {
           exit
         } { comm,i,get } ifelse
       } for
    ] /acti0 set
    acti0 { (string) dc } map cat /acti0 set

    /cgi.body comm def
    0 1 i {
      cgi.body rest /cgi.body set
    } for
    cgi.body { (string) dc } map cat /cgi.body set

% Step 3. Calling polymake
% acti0  cgi.body
    /pError [ ] def
%  cgi.body --> oxsVarToFile(), value is not a string object ...
%    [(polymake) (stringInOut://cgi.body) acti0] addStdoutStderr 
%  It is not a bug; .body is removed from the variable name.
    /cgi_body cgi.body def
    [cgiPolymake.polymakeName (stringInOut://cgi_body.poly) acti0] addStdoutStderr 
    oxshell pop
    pError [@@@stdout @@@stderr] append /pError set
    /cgi.body cgi_body def    
  ] pop
  popVariables
} def

/cgi.test0 {
  [[(URL) (hoge)]
   [(oxMessageBody)
   [(FACETS )
    (POINTS) nl
    (1 0 0) nl
    (1 1 0) nl
    (1 0 1) nl
    (1 1 1) nl ] cat
   ]] /ff set
   [(cgiKeyValuePairToUrlEncodingString) ff] extension /ff1 set
   ff1 message
   ff1 cgiPolymake.0
   cgi.body message
} def

/cgiReplyInHttp0 {
  /arg1 set
  [/ss /sskv] pushVariables
  [
    /ss arg1 def
    [[(Content-Body) ss]
%     [(Content-Type) (text/plain)]
     [(oxshell-stdout) [(cgiStringToUrlEncoding) @@@stdout] extension]
     [(oxshell-stderr) [(cgiStringToUrlEncoding) @@@stderr] extension]
    ] /sskv set
    [(cgiKeyValuePairToHttpString) sskv] extension /arg1 set
  ] pop
  arg1
} def

% ------------  client side script ---------------
/cgiQueryPolymake.hostname (polymake.math.kobe-u.ac.jp) def
/cgiQueryPolymake.cginame (/cgi-bin/cgi-polymake.sh) def
%This host and cgi are version 2.0 polymake.  dim, ... are different with new versions.
/cgiQueryPolymake { cgiQueryPolymake.curl } def
%/cgiQueryPolymake { cgiQueryPolymake.native } def
/cgiQueryPolymake.curl {
  /arg2 set /arg1 set
  [/saction /sfile /ff /ff1 /sss2 /goo /pp /pp2 /key /body /fd /pid] pushVariables
  [
    /saction arg1 def /sfile arg2 def
% step1. Generate query in URL encoding.
     [(http://) cgiQueryPolymake.hostname cgiQueryPolymake.cginame] cat
     /ff1 set
% full URL necessary for virtual host of apache.
     [[(oxMessageBody)
       [saction ( )
        sfile nl ] cat
       ]
     ] /ff set

     ff 0 get 0 get /key set
     ff 0 get 1 get /body set

     /pid [(getpid)] extension toString def

% step 2. Call the server and get the response in pp  
     /cgi.verbose 1 def
     [(/tmp/sm1-q-cgi.txt) pid] cat (w) file /fd set
     fd body writestring
     fd closefile

%     [(curl) (--form) [key (=@/tmp/sm1-q-cgi.txt)] cat  ff1] /ff set
%     ff  addStdoutStderr oxshell  @@@stdout /pp set
     [(curl  --form ) [key (=@/tmp/sm1-q-cgi.txt) pid ( )] cat  ff1 (>/tmp/sm1-q-cgi-out.txt) pid] cat /ff set
     ff system 
     [nl [(/tmp/sm1-q-cgi-out.txt) pid] cat pushfile] cat /pp set

%% Store workfiles under OpenXM_tmp
     [(mkdir -p ) [(getenv) (OpenXM_tmp)] extension] cat system
     [(mv /tmp/sm1-q-cgi.txt) pid ( ) [(getenv) (OpenXM_tmp)] extension] cat system
     [(mv /tmp/sm1-q-cgi-out.txt) pid ( ) [(getenv) (OpenXM_tmp)] extension] cat system

     cgi.verbose { pp message } {  } ifelse
     [(cgiHttpToKeyValuePair) pp] extension /pp2 set
     pp2 message
% step 3. Analyze the response.
     [pp2 (Content-Body) getNode
      pp2 (oxshell-stdout) getNode
      pp2 (oxshell-stderr) getNode 
     ] /arg1 set
  ] pop
  popVariables
  arg1
} def

/cgiQueryPolymake.native {
  /arg2 set /arg1 set
  [/saction /sfile /ff /ff1 /sss2 /goo /pp /pp2] pushVariables
  [
    /saction arg1 def /sfile arg2 def
% step1. Generate query in URL encoding.
     [(http://) cgiQueryPolymake.hostname cgiQueryPolymake.cginame] cat
     /ff1 set
% full URL necessary for virtual host of apache.
     [[(oxMessageBody)
       [saction ( )
        sfile nl ] cat
       ]
     ] /ff set
     [(cgiKeyValuePairToUrlEncodingString) ff] extension /ff set
     [(POST ) , ff1 , ( HTTP/0.9) , nl , 
%      (Connection: Keep-Alive) , nl ,
      (HOST: ) cgiQueryPolymake.hostname , nl ,     
      (Content-length: ) , ff length (dollar) dc , nl , nl 
      ff nl] cat /sss2 set
% step 2. Call the server and get the response in pp  
     [(sm1.socket) (connect) 
        [80 cgiQueryPolymake.hostname]] extension 0 get /goo set
     [(sm1.socket) (write) [goo sss2]]  extension 
     goo readHTTP0 /pp set

     % For the case of error.
     [(regexec) (200 OK) [pp]] extension length 0 eq {
        (sss2=) message
        sss2 message
        (pp=) message
        pp message
        (cgi.sm1: there seems to be an error in the HTTP connection.) 
     } { } ifelse

     cgi.verbose { pp message } {  } ifelse
     [(sm1.socket) (close) [goo]] extension
     [(cgiHttpToKeyValuePair) pp] extension /pp2 set

% step 3. Analyze the response.
     [pp2 (Content-Body) getNode
      pp2 (oxshell-stdout) getNode
      pp2 (oxshell-stderr) getNode 
     ] /arg1 set
  ] pop
  popVariables
  arg1
} def

/cgi.test1 {
  (FACETS)
  [(POINTS) nl
   (1 0 0 ) nl
   (1 1 0 ) nl
   (1 0 1 ) nl
  ] cat
  cgiQueryPolymake message
} def
% Overrides doPolymake
%/doPolymake { doPolymake.OoHG } def
%/polymake.start { polymake.start.OoHG } def

[(doPolymake.OoHG)
[(doPolymake.local calls the local polymake.)
 (This function calls http://polymake.math.kobe-u.ac.jp/cgi-bin/cgi-polymake.sh)
 (to make a computation in polymake.)
 (The host name and the cgi name are set to the variable)
 (   cgiQueryPolymake.hostname  and cgiQueryPolymake.cginame)
 (See doPolymake for the syntax. doPolymake.OoHG may overrides doPolymake.)
 (If you use curl to call the server execute) 
 (   usePolymake.OoHG.curl)
 (after loading cgi.sm1) 
]] putUsages
/doPolymake.OoHG  {
  /arg1 set
  [/in-doPolymake.OoHG  /pAction /pData /pNative /ptree
   /pResult  /pError
  ] pushVariables
  [
    arg1 0 get /pAction set
    arg1 1 get /pData set
    polymake.start.OoHG

    /pError [ ] def
%% step 1:  polymake tfb ===> polymake native data
    @@@polymake.k0.ccc ( polymake=Object; ) oxexecutestring 
    @@@polymake.k0.ccc ( QuoteMode(1); ) oxexecutestring 
    @@@polymake.k0.ccc [pData ( ;)] cat oxexecutestring 
    @@@polymake.k0.ccc oxpopcmo /ptree set 
    @@@polymake.k0.ccc ( QuoteMode(0); ) oxexecutestring 
    [(treeToPolymake) ptree] extension /pNative set 
%% step 2: calling the polymake
%    [(which) (polymake)] oxshell tag 0 eq
    1  % always call web service 
    {
% cgi-polymake
       (Trying web service.) message
       pAction pNative  cgiQueryPolymake /doPolymake.OoHG.result set
       doPolymake.OoHG.result /@@@doPolymake.vars set
      [(regexec) (Not Found) [doPolymake.OoHG.result 0 get ]] 
      extension length 0 eq not {
         doPolymake.OoHG.result message
         (The polymake cgi seems to be out of service.) error
      } {  } ifelse

      doPolymake.OoHG.result 0 get /pNative set


      pError doPolymake.OoHG.result rest append /pError set
    } {
% local polymake
      [(polymake) (stringInOut://pNative.poly) pAction] addStdoutStderr 
      oxshell pop
      pError [@@@stdout @@@stderr] append /pError set
    } ifelse
%% step 3: polymake native data to polymake tfb
    [(polymake2tfb) (<) (stringIn://pNative) (>) (stringOut://pResult)
     (2>) (stringOut://@@@stderr)] oxshell pop
    pError [@@@stderr] append /pError set
%% step 4: get also tree style data.
    @@@polymake.k0.ccc ( polymake=Object; ) oxexecutestring 
    @@@polymake.k0.ccc ( QuoteMode(1); ) oxexecutestring 
    @@@polymake.k0.ccc [pResult ( ;)] cat oxexecutestring 
    @@@polymake.k0.ccc oxpopcmo /ptree set 
    @@@polymake.k0.ccc ( QuoteMode(0); ) oxexecutestring 
    [pResult ptree pError] /arg1 set
  ] pop
  popVariables
  arg1
} def

/polymake.start.OoHG {
  (ox.k0.loaded) boundp {  }
  { [(parse) (ox.sm1) pushfile] extension 
    /@@@polymake.k0.ccc [ ] def
  } ifelse
  @@@polymake.k0.ccc [ ] eq { 
     k0connectr /@@@polymake.k0.ccc oxk0.ccc def /oxk0.ccc [ ] def
     @@@polymake.k0.ccc oxsetmathcap @@@polymake.k0.ccc oxmathcap
  } {  } ifelse
  @@@polymake.k0.ccc 0 get (closed) eq {
     k0connectr /@@@polymake.k0.ccc oxk0.ccc def /oxk0.ccc [ ] def
     @@@polymake.k0.ccc oxsetmathcap @@@polymake.k0.ccc oxmathcap
  } {  } ifelse
  [(which) (polymake2tfb)] oxshell tag 0 eq {
     (polymake2tfb is not installed in this system.) error
  } {  } ifelse
} def


/usePolymake.local {
  /doPolymake { doPolymake.local } def
  /polymake.start { polymake.start.local } def
} def

/usePolymake.OoHG.native {
  /doPolymake { doPolymake.OoHG } def
  /polymake.start { polymake.start.OoHG } def
  /cgiQueryPolymake { cgiQueryPolymake.native } def
} def

/usePolymake.OoHG.curl {
  [(which) (curl)] oxshell tag 0 eq {
     (Error in usePolymake.OoHG.curl: curl is not found.) error
  } { } ifelse
  /doPolymake { doPolymake.OoHG } def
  /polymake.start { polymake.start.OoHG } def
  /cgiQueryPolymake { cgiQueryPolymake.curl } def
} def

[(usePolymake.local)
[(doPolymake calls local polymake) 
]] putUsages

[(usePolymake.OoHG.native)
[(doPolymake = doPolymake.OoHG with cgiQueryPolymake.native)
 (cf. doPolymake.OoHG)
 (hostname is set in cgiQueryPolymake.hostname)
 (cginame is set in  cgiQueryPolymake.cginame)
]] putUsages

[(usePolymake.OoHG.curl)
[(doPolymake = doPolymake.OoHG with cgiQueryPolymake.curl)
 (It should be used when cgiQueryPolymake.native does not work)
 (over, e.g., a reverse proxy.)
 (The command curl is required.  cf. cgi.verbose, doPolymake.OoHG)
 (hostname is set in cgiQueryPolymake.hostname)
 (cginame is set in  cgiQueryPolymake.cginame)
]] putUsages