home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / srev13h.zip / sreproxy.rxx < prev    next >
Text File  |  1998-12-17  |  9KB  |  340 lines

  1. /* sre=proxy caching daemon */
  2.  
  3. /*  ----------- User Configurable Parameters */
  4. /*BEGIN  --- */
  5.  
  6. /* default max-age (if none specified), in seconds */
  7. max_age_default=86400
  8.  
  9. /* maximum number of selectors to cache */
  10. cache_size=1250
  11.  
  12.  
  13. /*END --- */
  14.  
  15. /*  ----------- End Configurable Parameters */
  16.  
  17. parse upper arg  tdir,usequeue , USESEM, max_semwait,port,dafilter
  18. crlf='0d0a'x
  19.  
  20. signal on error name perr ; signal on syntax name perr 
  21. storage_dir=strip(storage_dir,'t','\')
  22.  
  23. verbose=value('SREF_'port'_VERBOSE',,'OS2ENVIRONMENT')
  24. if verbose='' then verbose=1
  25. if verbose<2 then verbose=0
  26.  
  27. numeric digits 11
  28.  
  29. /* no initializations, just wait for requests:
  30.  1) L - lookup something in cache
  31.  2) A - add to cache
  32.  3) R - remove expired entries from cache 
  33.  4) S - construct and return list of current cache entries
  34. */
  35.  
  36. /* load srefiltr into macrospace */
  37. oo=macroadd('SREF_SREFILTR',dafilter,'b')
  38. if oo=0 then do 
  39.   call pmprintf('SRE-http: Proxy error, could not load main filter into macrospace ')
  40. /* do NOT set sref_proxy; hence, sreproxy.80 will ALWAYS call srefiltr.80 */
  41.   exit
  42. end
  43. else do
  44.   call pmprintf(' SRE-http Proxy: SREFILTR loaded into macrospace ')
  45. end
  46.  
  47. cshl=''           /* entries in cache (space delimited) */
  48.  
  49. aa=value('SREF_PROXY_BYTES',0,'os2environment')       /* enable proxy */
  50. aa=value('SREF_PROXY_HITS',0,'os2environment')       /* enable proxy */
  51. aa=value('SREF_PROXY',1,'os2environment')       /* enable proxy */
  52. aa=value('SREF_PROXY_BYTES2',0,'os2environment')       /* enable proxy */
  53. aa=value('SREF_PROXY_HITS2',0,'os2environment')       /* enable proxy */
  54.  
  55.  
  56.  
  57. /* Start Infinite Loop */
  58. bakme:
  59.  a=rxqueue('s',usequeue)
  60.  aq=queued()
  61.  if aq=0 then do
  62.     WOW=EVENTSEM_WAIT(USESEM,max_semwait)
  63.     aq=-1
  64.     if wow=640 then do
  65.          signal bakme
  66.          verbose=value('SREF_'port'_VERBOSE',,'OS2ENVIRONMENT')
  67.          if verbose<2 then verbose=0
  68.     end
  69.     IF WOW<>0 THEN do         /* FATAL ERROR */
  70.         call pmprintf(' SRE-http Sreproxy ERROR: fatal semaphore error: 'wow)
  71.         FOO=VALUE('SREF_PROXY',-2,'OS2ENVIRONMENT') /* DISALBE SREPROXY */
  72.         EXIT
  73.     end
  74.  end
  75.  wow=EVENTSEM_RESET(usesem)
  76.  
  77.  if aq=-1 then do
  78.     if queued()=0 then signal bakme
  79.   end
  80.  
  81.  PARSE pull isit0
  82.  
  83.  isit0=translate(isit0,' ','0009'x)
  84.  
  85.  if isit0=" " then signal bakme
  86.  
  87. /* die command? */
  88.  if abbrev(isit0,'*DIE*')=1 then
  89.           exit
  90.  
  91. goobs:
  92. nowtime=date('b')+ (time('s')/(24*60*60))
  93.  
  94. parse var isit0  idnum   ',' newq ',' newsem ','type','lookfor
  95. TYPE=UPPER(STRIP(TYPE))
  96. if lookfor='' then lookfor='/'
  97.  
  98. if type='L' then do             /* look for */
  99.   if verbose>1 then do
  100.       call pmprintf_sref(' SRE-http Proxy: looking for: 'lookfor)
  101.   end
  102.   lookfor=upper(space(upper(lookfor),0))
  103.   crc1=stringcrc(lookfor)
  104.   
  105.   if cshl.crc1.!got<>1 then do
  106.      a=rxqueue('s',newq)
  107.      push idnum ',' 0
  108.      wow=eventsem_post(newsem)
  109.      signal bakme
  110.    end
  111.  
  112. /* got an entry, check expiration */
  113.    atail=crc1
  114.    aexp=cshl.atail.!EXP
  115.    asel=cshl.atail.!sel
  116.    if aexp< nowtime |  asel<>lookfor then  do            /* expired entry, or bad crc */
  117.      if verbose>3 then  call pmprintf(' SRE-http Proxy: Expired sreproxy entry: 'crc1)
  118.       cshl.atail.!GOT=0
  119.       a=rxqueue('s',newq)
  120.       push idnum ',' 0
  121.       wow=eventsem_post(newsem)
  122.       signal bakme
  123.    end   
  124.  
  125. /* got a match, it's not expired or bad crc. 
  126.    Return cache_Type,filename,type,lastmod,etag,maxage,headers (crlf delimited ) */
  127.  
  128. /* maxage is used in sreproxy, and shrinks to keep cache-control consistent to
  129.    original posting */
  130.    maxage=trunc( (aexp-nowtime)*60*60*24)
  131.    oo=cshl.atail.!ct','cshl.atail.!reqp||crlf||cshl.atail' , 'cshl.atail.!tf||crlf|| ,
  132.       cshl.atail.!type|| ,
  133.       crlf||cshl.atail.!lmod||crlf|| ,
  134.       cshl.atail.!etag||crlf||maxage','cshl.atail.!npf||crlf||cshl.atail.!hdr
  135.    a=rxqueue('s',newq)
  136.    push idnum ','oo
  137.    wow=eventsem_post(newsem)
  138.    signal bakme
  139. end
  140.  
  141.  
  142. if type='A' then do             /* add an entry -- no return expected */
  143. /* read filename, age, headers. Convert age to an expiration relative to now */
  144.    call add_cache  
  145. end
  146.  
  147.  
  148. if type='SHOW'  then do             /* reset entries -- no return expected */
  149.    call showit lookfor
  150. end
  151.  
  152.  
  153. if WORDPOS(TYPE,'R RESET')>0  then do            /* CALLED ON RESET */
  154.    call CLEANUP                 /* NOTHING TO RETURN */
  155. end
  156.  
  157.  
  158. signal bakme
  159.  
  160.  
  161. perr:
  162. call pmprintf(' sreproxy.rxx error at 'sigl': 'RESULT','RC)
  163. FOO=VALUE('SREF_PROXY',-2,'OS2ENVIRONMENT') /* DISABLE SREPROXY */
  164. exit
  165.  
  166.  
  167.  
  168. /*************************************************************/
  169. /* add stuff to cache */
  170. /* 1: Add host_nickname//selector to cshl 
  171.    2: Create a host_nickname//selector cshl. entry with
  172.       atail=stringcrc(selector)
  173.      cshl.atail=absolute file name
  174.      cshl.atail.!sel=selector
  175.      cshl.atail.!EXP=expire date (julian)
  176.      cshl.atail.!type=type
  177.      cshl.atail.!etag=etag
  178.      cshl.atail.!lmod=last modification date
  179.      cshl.atail.!npf=nopostfilte flag
  180.      cshl.atail.!ct=cache type (static or semi dynamic ) & goserve cacheable flag
  181.      cshl.atail.!reqp= required priviliegs (if ct =2 or 4 )
  182.      cshl.atail.!tf = trigger file or timestamp
  183.      cshl.atail.!hdr=misc headers
  184. */
  185.  
  186. add_cache:  /* stuff sent here by sref_gos */
  187.  
  188. /* first, parse stuffout (from queued input),
  189.    all crlf delimited */
  190.  
  191. /* note: cshtype: 0= public static , 1= public semi-dynamic
  192.                   2= private static, 3=private semi-dynamic 
  193.                 0 1= public static & goserve cacheable 
  194.  */
  195.  
  196. parse var lookfor  cshtype0 (crlf) asel (crlf) absfile0 (crlf) amaxage (crlf) lastmod (crlf) type (crlf) etag ,
  197.            (crlf) headers
  198.  
  199. parse var absfile0 absfile ',' trigfile
  200.  
  201. if asel='' then asel='/'
  202. asel=upper(space(upper(asel),0))
  203.  
  204. parse var amaxage maxage ',' nopostf 
  205. parse var cshtype0 cshtype ',' reqprivs
  206.  
  207. if length(asel)>100 then return 0       /* selector too long to store */
  208.  
  209. crc1=stringcrc(asel)
  210. if cshl.crc1.!got=1 then return 0       /* crc being used (should never happen */
  211.  
  212. if verbose>0 then  call pmprintf_sref(' SRE-http Proxy: adding: 'asel)
  213.  
  214. if maxage<0 then  max_age=0
  215. if maxage='' | datatype(maxage)<>'NUM' then maxage=max_age_default
  216.  
  217. expires=nowtime+(maxage/(60*60*24))
  218.  
  219. if type='' then type='application/octet-stream'
  220.  
  221. /* trigfile is either a trigger file (i.e.; the original of an ssi cached file), or
  222.    the time stamp of a static document */
  223.  
  224. /* cache too big? */
  225. if length(cshl)>(cache_size*4) then do    /* max length of cache */
  226.   zz=trunc(cache_size/10)*4
  227.   do mmx=1 to zz by 4         /* get rid of first 10% */
  228.      att=substr(cshl,mmx,4)
  229.      cshl.att.!got=0
  230.    end
  231.    call cleanup
  232. end   
  233.  
  234. /* add stuff to cshl. */
  235. atail=crc1
  236. cshl.crc1.!got=1
  237. cshl.crc1.!sel=asel
  238. cshl.atail=absfile
  239. cshl.atail.!EXP=expires
  240. cshl.atail.!type=type
  241. cshl.atail.!etag=etag
  242. cshl.atail.!lmod=lastmod
  243. cshl.atail.!npf=nopostf
  244. cshl.atail.!ct=cshtype
  245. cshl.atail.!reqp=reqprivs
  246. cshl.atail.!hdr=headers
  247. cshl.atail.!tf=trigfile
  248.  
  249. cshl=cshl||atail                /* list of cache identifiers */
  250.  
  251. return 1
  252.  
  253.    
  254. /************/
  255. /* remove expired entries from cache */
  256. cleanup:
  257.  
  258. verbose=value('SREF_'port'_VERBOSE',,'OS2ENVIRONMENT')
  259.  
  260. if verbose>0 then  call pmprintf_sref(' SRE-http Proxy: removing old entries ')
  261. new1=''
  262. nold=length(cshl)/4
  263.  
  264. do mm=1 to length(cshl) by 4
  265.   atail=substr(cshl,mm,4)
  266.   atim=cshl.atail.!EXP
  267.   if atim<nowtime | cshl.atail.!got<>1 then do               /* zap this one */
  268.         drop cshl.atail.!SEL
  269.         drop cshl.atail.!GOT
  270.         drop cshl.atail.!EXP
  271.         drop cshl.atail.!type
  272.         drop cshl.atail.!etag
  273.         drop cshl.atail.!lmod
  274.         drop cshl.atail.!ct
  275.         drop cshl.atail.!reqp
  276.         drop cshl.atail.!tf
  277.         drop cshl.atail.!hdr
  278.         drop cshl.atail
  279.   end
  280.   else do
  281.      new1=new1||atail
  282.    end
  283. end
  284.  
  285. cshl=new1
  286. nnew=length(new1)/4
  287. if verbose>0 then
  288.     call pmprintf_sref('SRE-Proxy thread: retained '||nnew||' of 'nold' entries')
  289.  
  290. return 1
  291.   
  292.  
  293. /***************/
  294. /* write out current status */
  295. showit:
  296. parse arg alist
  297. parse var alist i1 i2
  298. ll1=length(cshl)/4
  299.  
  300. if datatype(i1)<>"NUM" then i1=1
  301. if datatype(i2)<>"NUM" then i2=length(cshl)/4
  302. if i2<i1 then do
  303.    i2=ll1 ; i1=1
  304. end
  305. if i1<0 then i1=1 ; if i2>ll1 then i2=ll1
  306.  
  307. crlf='0d0a'x
  308.  
  309. mess=' There are currently '||ll1|| ' entries in the SREPROXY cache.'crlf||crlf
  310.  
  311. do il=i1 to i2
  312.   istart=1+((il-1)*4)
  313.   atail=substr(cshl,istart,4)
  314.   if cshl.atail.!GOT<>1 then iterate
  315.  
  316.   tt=il||' : 'cshl.atail.!sel
  317.   tt=tt'        File:'cshl.atail
  318.   parse var cshl.atail.!ct actt .
  319.   if actt=1 | actt=3 then  tt=tt' (semi-dynamics)'
  320.   if actt=2 | acct=4 then  tt=tt' (private)'
  321.  
  322.   tt=tt||crlf
  323.   etime=sref_gmt(0,cshl.atail.!exp,'I',0)
  324.  
  325.   tt=tt'     Expires: '||etime
  326.   if cshl.atail.!tf<>'' then do 
  327.         tt=tt' ::  TimeStamp/Triggerfile: 'cshl.atail.!tf
  328.   end
  329.   tt=tt||crlf
  330.  
  331.   mess=mess||tt
  332. end
  333.  
  334. a=rxqueue('s',newq)
  335. push idnum ','mess
  336. wow=eventsem_post(newsem)
  337. return 0
  338.  
  339.    
  340.