home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / SREFV12J / SREFAST.80 < prev    next >
Text File  |  1997-07-12  |  18KB  |  532 lines

  1. /* 11 July 1997: This is the SREFAST variant of SRE-Filter.
  2.  
  3. For details on how to configure SREFAST, please see SREFAST.DOC
  4.  
  5. *******************/
  6. /* Begin  USER CHANGABLE PARMETERS  *******************/
  7. /* Begin  USER CHANGABLE PARMETERS  *******************/
  8. /* Begin  USER CHANGABLE PARMETERS  *******************/
  9.  
  10. /*BEGIN  ---  (this line is used by the EDITSREF.CMD SRE-Filter utility)*/
  11.  
  12. /* SREFAST configuration information is read from a special
  13.    configuration file (SREFAST.HTM can be used to create modify this file).
  14.    Alternatively, if you set USE_CFG=0 you can specify entries here.
  15.    NOTE: we do NOT recommend use of use_cfg=0 (SSI will NOT be supported).*/
  16. use_cfg=1
  17.  
  18.  
  19. /* If you've set USE_CFG=0, then you must set the DOIT. stem variable here.
  20.     DOIT.0 should contain the number of  entries.
  21.     Note that DOIT. is ignored if use_cfg=1 */
  22. DOIT.0=0
  23.  
  24. /*  Changes in the following variables (REFRESH, FORCE_REFRESH,
  25.     VERBOSE, KEY_PREFACE,DISK_FREE) will only
  26.     take effect when you restart GoServe 
  27.    ------------------------------------
  28.    Refresh check rate of the SSI cache, in seconds. */
  29. Refresh=60
  30.  
  31. /* Force refresh, in # of REFRESH cycles 
  32.   Note: if refresh=30, and force_refresh=90, then rebuild cache every 45 minutes*/
  33. Force_refresh=60      
  34.  
  35. /* Set verbose to 1 for verbose status info,  2 for VERY verbose */
  36. verbose=1
  37.  
  38. /* alternative "preface" for SSI keyphrases.  Set to 0 to suppress
  39.    MUST match the value used in SREFILTR.80! */
  40. key_preface=0
  41.  
  42. /* amount of space that must be available after a SSI-cache file is written.
  43.    This is used to prevent overfilling your disk. Value is in megabytes */
  44. disk_free=10
  45.  
  46. /* spaced delimited list of numeric IP addresses to not allow access to. Wildcards
  47.    are NOT allowed.  */
  48. unallowedips=' '
  49.  
  50. /*END  ---  (this line is used by the EDITSREF.CMD utility)*/
  51.  
  52. /*      --------- END OF USER CHANGEABLE SECTION  ----------------*/
  53. /*      --------- END OF USER CHANGEABLE SECTION  ----------------*/
  54. /*      --------- END OF USER CHANGEABLE SECTION  ----------------*/
  55. /*      --------- END OF USER CHANGEABLE SECTION  ----------------*/
  56.  
  57.  
  58. is_csh=0
  59.  
  60. parse arg source, request , seloriginal
  61.  
  62. if request=" " then return 'NODATA'
  63.  
  64. parse var source myaddr port transaction who whoport .
  65.  
  66. parse var request verb uri protocol .        /* split up the request line */
  67. enmadd="SREF_"||port||"_"
  68. basesem='\SEM32\'||enmadd
  69. os2e='os2environment'
  70. servdir=directory()
  71.  
  72. if transaction<2 then do         /* initialize */
  73.    foo=srefast1(port)     /* load srefiltr.port into macropace */
  74.    if aport=80 then do
  75.         foo=sref_main_80(source,request,seloriginal)
  76.     end
  77.     else do
  78.         aroutine='SREF_MAIN_'||port
  79.         foo2='foo='||aroutine||'(source,request,seloriginal)'
  80.         interpret foo2
  81.    end
  82.    afilt2=servdir'\srefast2.cmd'
  83.    tempdata_dir=' '
  84.    do while tempdata_dir=' '     /* wait for stuff to stabilize */
  85.        tempdata_dir=get_value('TEMPDATA_DIR')
  86.        call syssleep 1
  87.     end
  88.    foo=rexxthread('f',afilt2,port,servdir,refresh,force_refresh,datadir(),tempdata_dir,verbose,key_preface,enmadd,servername(),disk_free)
  89.    if verbose>0 then call pmprintf_sref(' Done initializing SREFAST ')
  90.    return ' '
  91. end
  92.  
  93.  
  94. /* if here, not transaction 1 */
  95. sem_status=eventsem_query(basesem)
  96.  
  97. if sem_status<0 then do         /* patience */
  98.    'STRING Server Initalizing: Please try again in a minute '
  99.    return ' '
  100. end
  101.  
  102. /* Check for basic grooviness */
  103. if left(protocol,4)\='HTTP' & protocol\='' then
  104.    signal call_bigone
  105.  
  106. /* if no semaphore/queue for this thread, call bigone */
  107. mytid=dostid()
  108. mysem=basesem||"t"||mytid
  109. myqueue="SREF_"||port||'_t'||mytid
  110. wow=eventsem_query(mysem)
  111. if wow=-187 then signal call_bigone
  112.  
  113. /* if not a get request,   xx?yy, or CGI-BIN, then can't do it here. */
  114. if verb<>'GET' then signal call_bigone
  115. if pos('?',seloriginal)>0 then signal call_bigone
  116. if left(seloriginal,1)='!' then signal call_bigone
  117.  
  118. tsel=strip(upper(seloriginal))
  119.  
  120. if pos('CGI-BIN',tsel) then signal call_bigone
  121.  
  122. temp_dir=get_value("TEMPDATA_DIR")
  123. temp_dir=strip(TEMP_DIR,'t','\')||'\'
  124.  
  125. /* read in DOIT from a special configuration file? */
  126. if use_cfg=1 then do
  127.    afilt2=temp_dir||'_fstindx.'||port
  128.    foo=cvread(afilt2,doit)
  129.    if verbose>0 & foo=0 then call pmprintf_sref(afilt2', the SREFAST index, is not available')
  130.    if foo=0 then signal call_bigone
  131. end
  132.  
  133. /* fix up seloriginal */
  134. gotit=0
  135. afile=' '
  136. do m=1 to doit.0
  137.     asel=strip(upper(doit.m.!sel),'l','/')
  138.     ifl= f_wildcard(tsel,asel)
  139.     if ifl=0 then iterate    /* sel does not match */
  140.  
  141.     host_Nickname=' ' ;aservername=' '
  142.     if symbol('DOIT.'m'.!SERVER')='VAR' then do  /* check server */
  143.          aservername=doit.m.!server
  144.          if symbol('DOIT.'m'.!HOST')='VAR' then host_nickname=doit.m.!host  /* get host_nickname */
  145.          if myaddr<>doit.m.!server then do    /* not canonical, perhaps host: header? */
  146.                ahost=reqfield('host')
  147.                if ahost<>doit.m.!server then iterate   /* did not match ip number or host-alias */
  148.                if symbol('DOIT.'m'.!HOST')='VAR' then host_nickname=doit.m.!host  /* get host_nickname */
  149.           end
  150.     end
  151.     if symbol('DOIT.'m'.!NODO')='VAR' then do  /* check nodo*/
  152.        if doit.m.!nodo=1 then do
  153.            if verbose>1 then say "SREFAST: explicit call to main filter for: " seloriginal
  154.            signal call_bigone   /* explicit "don't use srefast" entry */
  155.        end
  156.      end
  157.     gotit=m
  158.     leave
  159. end
  160. if gotit=0 then signal call_bigone      /* no matches, call srefiltr */
  161. if wordpos(who,unallowedips)>0 then signal call_bigone
  162.  
  163. if verbose>1 then say " SREFAST: Using entry " doit.gotit.!sel ' for ' seloriginal
  164. tempfile=temp_dir'$'transaction'.'port
  165. nocache=' '
  166. privset=' '
  167. /* check for username or password -- if required but not found, call_bigone */
  168. if symbol('DOIT.'gotit'.!USERS')='VAR' then do
  169.    owners=get_value('OWNERS')
  170.    if wordpos(who,owners)=0 then do
  171.        if symbol('DOIT.'gotit'.!PWDS')<>'VAR' then signal call_bigone  /* no pwds */
  172.        astuff=reqfield('Authorization')
  173.        if astuff=' ' then signal call_bigone
  174.        parse var astuff  . m64 .              /* get the encoded cookie */
  175.        dec=pack64(m64)                       /* and decode it */
  176.        parse upper var dec auser ':' apwd      /* parse out user and pwd */
  177.        ii=wordpos(auser,upper(doit.gotit.!users))    /* check for username */
  178.        if ii=0 then signal call big_one
  179.        bpwd=upper(strip(word(doit.gotit.!pwds,ii)))
  180.        if bpwd<>apwd & bpwd<>'*' then signal call_bigone
  181.        nocache='NOCACHE'
  182.        if symbol('DOIT.'gotit'.!Privset')="VAR" then privset=doit.gotit.!privset  /* no pwds */
  183.    end          /* owners */
  184. end             /*authorized */
  185.  
  186. /* accept this one.  Determine file name */
  187. dnameonly=0
  188. if symbol('DOIT.'gotit'.!DIR')<>'VAR' then do
  189.      ddir=datadir()
  190.  end
  191.  else do                /* check for "HTTP://", and redirect if found */
  192.      ddir=strip(upper(doit.gotit.!dir))
  193.      if symbol('DOIT.'gotit'.!DIR_NAMEONLY')='VAR' then do
  194.         if doit.gotit.!dir_nameonly=1 then dnameonly=1
  195.      end
  196.      if abbrev(ddir,'HTTP://')=1 then do
  197.           if right(ddir,1)='*' then do
  198.                 aurl1=left(ddir,1,length(ddir)-1)
  199.                 aurl1=strip(aurl1,'t','/')||'/'
  200.                 addme=seloriginal
  201.                 if dnameonly=1 then do
  202.                    addme=translate(addme,'\','/')
  203.                    addme=filespec('n',addme)
  204.                 end
  205.                 aurl=aurl1||addme
  206.            end
  207.            else do
  208.                 aurl=ddir
  209.            end
  210.           'HEADER ADD Location:' aurl
  211.           'RESPONSE HTTP/1.0 301 Moved Permanently'  /* Set HTTP response line */
  212.           'STRING  '||seloriginal||' moved to  '|| aurl
  213.            runtot=extract('bytessent') ; rstatus=301
  214.           signal checkpost
  215.       end
  216.  end
  217.  
  218.  addme=strip(translate(seloriginal,'\','/'),,'\')
  219.  if dnameonly=1 then addme=filespec('n',addme)
  220.  ddir=strip(translate(ddir,'\','/'),,'\')||'\'
  221.  afile=ddir||addme
  222.  
  223. /* see if file exists */
  224.   if stream(afile,'c','query exists')=' ' then do
  225.        signal call_bigone                 /* not found, let main filter handle
  226.                                          it (perhaps using an alias, etc. */
  227.   end
  228. /* got name, but has it been already completed from goserve cache? */
  229. if completed()<>0 then do
  230.    if verbose>1 then   say " SREFAST:  Got from cache: " seloriginal
  231.    runtot=extract('bytessent')
  232.     rstatus=200
  233.     is_csh=1
  234.     signal checkpost
  235. end
  236. /* got filename, it's still alive -- get mimetype and suppress caching flag */
  237.  
  238. /* get no cache flag */
  239.  
  240. if symbol('DOIT.'gotit'.!NOCACHE')='VAR' & nocache=' ' then do  /* but check cache status first*/
  241.         if doit.gotit.!nocache=1 then nocache='NOCACHE'
  242. end
  243. /* get mime type ? */
  244. if symbol('DOIT.'gotit'.!MIME')='VAR' then
  245.      mimetype=doit.gotit.!mime
  246. else
  247.      mimetype=sref_mediatype(afile)
  248.  
  249.  
  250. /* is it an ssi'able file ? */
  251. issii=0
  252. if symbol('DOIT.'gotit'.!SSI')='VAR' then do
  253.   if doit.gotit.!ssi=1  then  issi=1
  254. end
  255. if issi=1 & (doit.!nossi=1 | use_cfg=0 ) then signal call_bigone
  256.  
  257. if issi=1 then do                       /* ssi -- used pre compiled asis or with dynamics */
  258.  
  259.   if doit.gotit.!type='SKIP' then do
  260.       if verbose>1 then call pmprintf_sref(' SREFAST: SSI can not be done for 'seloriginal)
  261.       signal call_bigone
  262.   end
  263.  
  264.   oobfile=doit.gotit.!origfile
  265.   anent=sysfiletree(oobfile,yow1,'T')
  266.   if space(upper(yow1.1))<>doit.gotit.!stamp then do
  267.       if verbose>0 then call pmprintf_sref(' SREFAST: File stamp mismatch, use main filter ('oobfile)
  268.       signal call_bigone
  269.   end
  270.  
  271.   if symbol('DOIT.'||gotit||'.!TRIGGER')="VAR" then do
  272.         atrigger=doit.gotit.!trigger
  273.         atfile=strip(word(atrigger,words(atrigger)))
  274.         anent=sysfiletree(atfile,yow1,'T')
  275.         if yow.0=0 then do
  276.             if verbose>0 then call pmprintf_sref(' SREFAST: Missing trigger file: use main filter ('atfile)
  277.             signal call_bigone
  278.         end
  279.         if space(upper(yow1.1))<>doit.gotit.!trigger then do
  280.            if verbose>0 then call pmprintf_sref(' SREFAST: Trigger mismatch, use main filter ('atfile)
  281.            signal call_bigone
  282.         end
  283.    end
  284.  
  285.    if doit.gotit.!type='ASIS' then do
  286.        if stream(doit.gotit.!file,'c','query exists')=' ' then do
  287.                 if verbose>0 then call pmprintf_sref(' SREFAST: ASIS cache file missing 'doit.gotit.!file)
  288.                 signal call_bigone
  289.         end
  290.         'FILE type text/html nocache  name ' doit.gotit.!file
  291. /* unfortunately, the current srefast ssi cache is not robust enough to handle goserve cache */
  292.          runtot=dosdir(doit.gotit.!file,'s') ; rstatus=200
  293.    end
  294.  
  295.    if doit.gotit.!type='DYNAMIC' then do
  296.        AA=CVREAD(doit.gotit.!file,DASTUFF)
  297.        IF AA=0 THEN DO
  298.           if verbose>0 then say " SREFAST: Dynamic Cache file missing: " doit.gotit.!file ' , for ' seloriginal
  299.           SIGNAL CALL_BIGONE
  300.        end
  301.        sendp=get_value('DO_SEND_PIECE')
  302.        if sendp=1 then do
  303.           'SET NETBUFFER OFF '
  304.           'SEND TYPE text/html as ' afile
  305.        end
  306.        else do
  307.             sendit=""
  308.         end
  309.        runtot=0
  310.        cgi_inc_timefmt="%c"
  311.        do ip=1 to dastuff.0
  312.              if dastuff.ip.!type=1 then  do
  313.                  aay=DASTUFF.ip
  314.                  if verbose>1 then say ' SREFAST:  chunk '||length( dastuff.ip)
  315.              end
  316.              else do
  317.                  aay=process_dynamic(ip,doit.gotit.!origfile)
  318.                  if symbol('DASTUFF.'||ip||'.!ARGS')='VAR' then
  319.                          if completed() then leave
  320.                  if verbose>1 then say ' SREFAST: send dynamic '|| left(dastuff.ip,80)
  321.              end
  322.              if aay<>' ' then do
  323.                 if sendp=1 then do
  324.                    'VAR NAME AAY '
  325.                    runtot=runtot+length(aay)
  326.                 end
  327.                 else do
  328.                     sendit=sendit||aay
  329.                 end
  330.              end
  331.         end             /* ip loop */
  332.         if sendp=1 then do
  333.            'SEND COMPLETE '
  334.            rstatus=200
  335.         end
  336.         else do
  337.            fix_expire=get_value('FIX_EXPIRE')
  338.            runtot=length(sendit)
  339.            if fix_expire>0 then  foo=sref_expire_response(fix_expire,runtot)
  340.            'VAR type  text/html   name sendit '
  341.         end
  342.    end
  343. end             /* issi */
  344.  
  345. else do                 /* non ssi stuff */
  346.    'FILE type ' mimetype ' ' nocache ' name ' afile
  347.    runtot=dosdir(afile,'s') ; rstatus=200
  348. end
  349.  
  350. /* post filter it? */
  351. checkpost:
  352.  
  353. eej='FAST'
  354. if is_csh=1 then eej='CACHE'
  355. mm=get_value('SREF_FAST_'||eej); if mm=' ' then mm=0
  356. foo=value(enmadd||'SREF_FAST_'||eej,mm+1,'os2environment')
  357. mm=get_value('SREF_FAST_BYTES_'||eej); if mm=' ' then mm=0
  358. if datatype(RUNTOT)<>'NUM' then runtot=extract('bytessent')
  359. foo=value(enmadd||'SREF_FAST_BYTES_'||eej,mm+runtot,'os2environment')
  360.  
  361.  
  362. norec=0
  363. if symbol('DOIT.'gotit'.!NORECORD')='VAR' then do
  364.   if doit.gotit.!norecord=1 then do
  365.       norec=1
  366.   end
  367. end
  368. if norec<>1 then do
  369.      response_status=rstatus' 'runtot
  370.      if aservername=' ' then aservername=servername()
  371.      foo=sref_fast_postf(source,request,seloriginal,  ,
  372.                       enmadd,basesem,mysem,myqueue,aservername,host_nickname, ,
  373.                        response_status,verbose,tempfile,afile)
  374.   end
  375.   return ' '
  376. end
  377.  
  378.  
  379. /* jump here to call srefiltr.80 */
  380. call_bigone:
  381.  
  382. if verbose>1 then call pmprintf_sref(" SREFAST: calling main filter for " seloriginal)
  383. if aport=80 then do
  384.     foo=sref_main_80(source,request,seloriginal)
  385. end
  386. else do
  387.     aroutine='SREF_MAIN_'||port
  388.     foo2='foo='||aroutine||'(source,request,seloriginal)'
  389.     interpret foo2
  390. end
  391.  
  392. mm=get_value('SREF_FAST_MAIN');if mm=' ' then mm=0
  393. foo=value(enmadd||'SREF_FAST_MAIN',mm+1,'os2environment')
  394. runtot=extract('bytessent')
  395. mm=get_value('SREF_FAST_BYTES_MAIN'); if mm=' ' then mm=0
  396. foo=value(enmadd||'SREF_FAST_BYTES_MAIN',mm+runtot,'os2environment')
  397.  
  398.  
  399. return ' '
  400.  
  401.  
  402. /********************************/
  403. /* see if needle matches haystack (* wildcards permitted) */
  404. f_wildcard:
  405. parse arg tn ,tc
  406. tn=strip(tn); tc=strip(tc)
  407. if tn=tc then   return 1              /* exact match */
  408.  
  409. /* check for wildcard */
  410. astc=pos('*',tc)
  411. if astc=0 then  return 0          /* not a wildcard candidate */
  412.  
  413. if astc=1 then do
  414.    tc1=""
  415.    tn1=tc1
  416.    len1=0
  417. end
  418. else do
  419.    tc1=substr(tc,1,astc-1)
  420.    len1=length(tc1)
  421.    tn1=left(tn,len1)
  422. end
  423. if astc=length(tc) then do
  424.    tn2=""
  425.    tc2=""
  426.    len2=0
  427. end
  428. else do
  429.    tc2=substr(tc,astc+1)
  430.    len2=length(tc2)
  431.    tn2=right(tn,len2)
  432. end
  433.  
  434. if tn1<>tc1 | tn2<>tc2 then     /* not a wildcard match */
  435.   return  0
  436.  
  437. return 1                /* have a wildcard match */
  438.  
  439. /* ----------- */
  440. /* get environment value, possibly host specific */
  441.  
  442. get_value: procedure expose enmadd
  443. parse upper arg vname
  444. vname=strip(vname) ;
  445. aval=value(enmadd||vname,,'os2environment')
  446. return aval
  447.  
  448. /**************************/
  449. /* the dynamic replacements done by srefast
  450. The include                      the marker
  451. ----------------------------------
  452.  HTTPD variables:
  453. cgi_inc_timefmt  (used by date_local and date_gmt)
  454. DATE_LOCAL                DATE_GMT    SERVER_PROTOCOL
  455. REQUEST_METHOD           REMOTE_ADDR  AUTH_NAME
  456. HTTP_ACCEPT
  457.  
  458. REPLACE (and sometimes HTTPD) variables:
  459. DATEGMT                    DATE                  READ_HEAD
  460. REFER                       TIME     TIME_GMT
  461. USERNAME                   USER-AGENT
  462. */
  463. process_dynamic:procedure expose cgi_inc_timefmt transaction basesem enmadd who mysem myqueue dastuff. ,
  464.                 privset host_nickname aservername seloriginal verbose
  465.  
  466.  
  467. parse upper arg i1,origfile
  468. dome=dastuff.i1
  469.  
  470. putme=' '
  471.  
  472. select
  473.   when dome="CGI_INC_TIMEFMT" then
  474.          parse var dome foo cgi_inc_timefmt
  475.   when dome='DATE_LOCAL' then putme=sref_datetime_convert(cgi_inc_timefmt)
  476.   when dome='DATE_GMT' then do
  477.          putme=sref_new_gmt(,,,1)
  478.          parse var putme adate atime
  479.          putme=sref_datetime_convert(cgi_inc_timefmt,adate,atime)
  480.   end
  481.   when dome='SERVER_PROTOCOL' then putme=extract( 'serverprotocol')
  482.   when dome="REQUEST_METHOD" then  putme=extract('clientmethod')
  483.   when dome="USERNAME" then do
  484.         putme=sref_clientname(who,mysem,myqueue,basesem,enmadd,transaction)
  485.  end
  486.   when dome="REMOTE_ADDR" then putme=who
  487.   when dome="AUTH_NAME" then do
  488.             afield=reqfield('Authorization')
  489.             parse var afield . m64 .              /* get the encoded cookie */
  490.             dec=pack64(m64)                       /* and decode it */
  491.             parse upper var dec putme ':' .
  492.   end
  493.   when dome="HTTP_ACCEPT" then do
  494.                i = 1
  495.                 _acc = REQFIELD("accept")
  496.                acc = '%'
  497.                ClientAccepts = ''
  498.                do while (acc \= _acc)
  499.                    acc = REQFIELD("accept", i)
  500.                    if (ClientAccepts \= '') then ClientAccepts = ClientAccepts', 'acc
  501.                    else ClientAccepts = acc
  502.                    i = i+1
  503.              end
  504.              putme=clientaccepts
  505.   end
  506.   when dome="BROWSER" then  putme=reqfield("User-Agent")
  507.   when dome="REFERER" then do
  508.       putme=reqfield("REFERER")
  509.   end
  510.   when dome="DATE_LOCAL2" then putme=date('N')
  511.   when dome="TIME" then putme=time('N')
  512.   when dome="TIME_GMT" then do
  513.               fii=sref_new_gmt()
  514.               parse var fii eek ',' d1 d2 d3 t1
  515.               putme=t1||'  GMT '
  516.   end
  517.   when dome="DATE_GMT2" then do
  518.            fii=sref_new_gmt()
  519.            parse var fii eek ',' d1 d2 d3 .
  520.            putme=d1||' '||d2||' '||d3
  521.   end
  522.   when dome="READ_HEAD" then do
  523.             'READ HEADER VAR PUTME '
  524.            putme='<PRE>'||putme||'</pre>'
  525.   end
  526.   otherwise
  527.     nop
  528. end
  529.  
  530. return putme
  531.  
  532.