Squid url redirector

Hex Artifact Content
anonymous

Hex Artifact Content

Artifact 9360d0ecb7f178a4373bf53efc6a8d0b30c1894ba36543fa542daabd59a2ff10:


0000: 23 21 2f 75 73 72 2f 62 69 6e 2f 65 6e 76 20 70  #!/usr/bin/env p
0010: 79 74 68 6f 6e 33 2e 31 0a 0a 69 6d 70 6f 72 74  ython3.1..import
0020: 20 63 6f 6e 66 69 67 70 61 72 73 65 72 2c 20 63   configparser, c
0030: 73 76 2c 20 6f 70 74 70 61 72 73 65 2c 20 6f 73  sv, optparse, os
0040: 2c 20 70 6f 73 74 67 72 65 73 71 6c 2e 61 70 69  , postgresql.api
0050: 2c 20 73 79 73 0a 0a 23 20 77 72 61 70 70 65 72  , sys..# wrapper
0060: 20 61 72 6f 75 6e 64 20 73 79 73 6c 6f 67 2c 20   around syslog, 
0070: 63 61 6e 20 62 65 20 6d 75 74 65 64 0a 63 6c 61  can be muted.cla
0080: 73 73 20 4c 6f 67 67 65 72 3a 0a 09 5f 5f 73 6c  ss Logger:..__sl
0090: 6f 74 73 5f 5f 20 3d 20 66 72 6f 7a 65 6e 73 65  ots__ = frozense
00a0: 74 28 5b 27 5f 73 79 73 6c 6f 67 27 5d 29 0a 0a  t(['_syslog'])..
00b0: 09 64 65 66 20 5f 5f 69 6e 69 74 5f 5f 28 73 65  .def __init__(se
00c0: 6c 66 29 3a 0a 09 09 63 6f 6e 66 69 67 2e 73 65  lf):...config.se
00d0: 63 74 69 6f 6e 28 27 6c 6f 67 27 29 0a 09 09 69  ction('log')...i
00e0: 66 20 63 6f 6e 66 69 67 5b 27 73 69 6c 65 6e 74  f config['silent
00f0: 27 5d 20 3d 3d 20 27 79 65 73 27 3a 0a 09 09 09  '] == 'yes':....
0100: 73 65 6c 66 2e 5f 73 79 73 6c 6f 67 20 3d 20 4e  self._syslog = N
0110: 6f 6e 65 0a 09 09 65 6c 73 65 3a 0a 09 09 09 69  one...else:....i
0120: 6d 70 6f 72 74 20 73 79 73 6c 6f 67 0a 09 09 09  mport syslog....
0130: 73 65 6c 66 2e 5f 73 79 73 6c 6f 67 20 3d 20 73  self._syslog = s
0140: 79 73 6c 6f 67 0a 09 09 09 73 65 6c 66 2e 5f 73  yslog....self._s
0150: 79 73 6c 6f 67 2e 6f 70 65 6e 6c 6f 67 28 27 73  yslog.openlog('s
0160: 71 75 69 64 54 61 67 27 29 0a 0a 09 64 65 66 20  quidTag')...def 
0170: 69 6e 66 6f 28 73 65 6c 66 2c 20 6d 65 73 73 61  info(self, messa
0180: 67 65 29 3a 0a 09 09 69 66 20 73 65 6c 66 2e 5f  ge):...if self._
0190: 73 79 73 6c 6f 67 3a 0a 09 09 09 73 65 6c 66 2e  syslog:....self.
01a0: 5f 73 79 73 6c 6f 67 2e 73 79 73 6c 6f 67 28 73  _syslog.syslog(s
01b0: 65 6c 66 2e 5f 73 79 73 6c 6f 67 2e 4c 4f 47 5f  elf._syslog.LOG_
01c0: 49 4e 46 4f 2c 20 6d 65 73 73 61 67 65 29 0a 0a  INFO, message)..
01d0: 09 64 65 66 20 6e 6f 74 69 63 65 28 73 65 6c 66  .def notice(self
01e0: 2c 20 6d 65 73 73 61 67 65 29 3a 0a 09 09 69 66  , message):...if
01f0: 20 73 65 6c 66 2e 5f 73 79 73 6c 6f 67 3a 0a 09   self._syslog:..
0200: 09 09 73 65 6c 66 2e 5f 73 79 73 6c 6f 67 2e 73  ..self._syslog.s
0210: 79 73 6c 6f 67 28 73 65 6c 66 2e 5f 73 79 73 6c  yslog(self._sysl
0220: 6f 67 2e 4c 4f 47 5f 4e 4f 54 49 43 45 2c 20 6d  og.LOG_NOTICE, m
0230: 65 73 73 61 67 65 29 0a 0a 23 20 77 72 61 70 70  essage)..# wrapp
0240: 65 72 20 61 72 6f 75 6e 64 20 64 61 74 61 62 61  er around databa
0250: 73 65 0a 63 6c 61 73 73 20 74 61 67 44 42 3a 0a  se.class tagDB:.
0260: 09 5f 5f 73 6c 6f 74 73 5f 5f 20 3d 20 66 72 6f  .__slots__ = fro
0270: 7a 65 6e 73 65 74 28 5b 27 5f 70 72 65 70 61 72  zenset(['_prepar
0280: 65 64 27 2c 20 27 5f 64 75 6d 70 5f 73 74 6d 74  ed', '_dump_stmt
0290: 27 2c 20 27 5f 64 62 27 5d 29 0a 0a 09 64 65 66  ', '_db'])...def
02a0: 20 5f 5f 69 6e 69 74 5f 5f 28 73 65 6c 66 29 3a   __init__(self):
02b0: 0a 09 09 73 65 6c 66 2e 5f 70 72 65 70 61 72 65  ...self._prepare
02c0: 64 20 3d 20 73 65 74 28 29 0a 09 09 73 65 6c 66  d = set()...self
02d0: 2e 5f 64 62 20 3d 20 46 61 6c 73 65 0a 09 09 73  ._db = False...s
02e0: 65 6c 66 2e 5f 64 75 6d 70 5f 73 74 6d 74 20 3d  elf._dump_stmt =
02f0: 20 73 65 6c 66 2e 5f 63 75 72 73 28 29 2e 70 72   self._curs().pr
0300: 65 70 61 72 65 28 22 73 65 6c 65 63 74 20 75 6e  epare("select un
0310: 74 72 69 70 28 73 69 74 65 29 2c 20 74 61 67 2c  trip(site), tag,
0320: 20 72 65 67 65 78 70 20 66 72 6f 6d 20 75 72 6c   regexp from url
0330: 73 20 6e 61 74 75 72 61 6c 20 6a 6f 69 6e 20 73  s natural join s
0340: 69 74 65 20 6e 61 74 75 72 61 6c 20 6a 6f 69 6e  ite natural join
0350: 20 74 61 67 20 6f 72 64 65 72 20 62 79 20 73 69   tag order by si
0360: 74 65 2c 20 74 61 67 22 29 0a 0a 09 64 65 66 20  te, tag")...def 
0370: 5f 63 75 72 73 28 73 65 6c 66 29 3a 0a 09 09 69  _curs(self):...i
0380: 66 20 6e 6f 74 20 73 65 6c 66 2e 5f 64 62 3a 0a  f not self._db:.
0390: 09 09 09 63 6f 6e 66 69 67 2e 73 65 63 74 69 6f  ...config.sectio
03a0: 6e 28 27 64 61 74 61 62 61 73 65 27 29 0a 09 09  n('database')...
03b0: 09 73 65 6c 66 2e 5f 64 62 20 3d 20 70 6f 73 74  .self._db = post
03c0: 67 72 65 73 71 6c 2e 6f 70 65 6e 28 0a 09 09 09  gresql.open(....
03d0: 09 27 70 71 3a 2f 2f 7b 7d 3a 7b 7d 40 7b 7d 2f  .'pq://{}:{}@{}/
03e0: 7b 7d 27 2e 66 6f 72 6d 61 74 28 0a 09 09 09 09  {}'.format(.....
03f0: 09 63 6f 6e 66 69 67 5b 27 75 73 65 72 27 5d 2c  .config['user'],
0400: 0a 09 09 09 09 09 63 6f 6e 66 69 67 5b 27 70 61  ......config['pa
0410: 73 73 77 6f 72 64 27 5d 2c 0a 09 09 09 09 09 63  ssword'],......c
0420: 6f 6e 66 69 67 5b 27 68 6f 73 74 27 5d 2c 0a 09  onfig['host'],..
0430: 09 09 09 09 63 6f 6e 66 69 67 5b 27 64 61 74 61  ....config['data
0440: 62 61 73 65 27 5d 2c 0a 09 09 09 29 20 29 0a 09  base'],....) )..
0450: 09 72 65 74 75 72 6e 28 73 65 6c 66 2e 5f 64 62  .return(self._db
0460: 29 0a 0a 09 64 65 66 20 64 75 6d 70 28 73 65 6c  )...def dump(sel
0470: 66 29 3a 0a 09 09 72 65 74 75 72 6e 28 73 65 6c  f):...return(sel
0480: 66 2e 5f 64 75 6d 70 5f 73 74 6d 74 28 29 29 0a  f._dump_stmt()).
0490: 0a 23 20 74 68 69 73 20 63 6c 61 73 73 65 73 20  .# this classes 
04a0: 70 72 6f 63 65 73 73 65 73 20 63 6f 6e 66 69 67  processes config
04b0: 20 66 69 6c 65 20 61 6e 64 20 73 75 62 73 74 69   file and substi
04c0: 74 75 74 65 73 20 64 65 66 61 75 6c 74 20 76 61  tutes default va
04d0: 6c 75 65 73 0a 63 6c 61 73 73 20 43 6f 6e 66 69  lues.class Confi
04e0: 67 3a 0a 09 5f 5f 73 6c 6f 74 73 5f 5f 20 3d 20  g:..__slots__ = 
04f0: 66 72 6f 7a 65 6e 73 65 74 28 5b 27 5f 63 6f 6e  frozenset(['_con
0500: 66 69 67 27 2c 20 27 5f 64 65 66 61 75 6c 74 27  fig', '_default'
0510: 2c 20 27 5f 73 65 63 74 69 6f 6e 27 5d 29 0a 09  , '_section'])..
0520: 5f 64 65 66 61 75 6c 74 20 3d 20 7b 0a 09 09 27  _default = {...'
0530: 72 65 61 63 74 6f 72 27 3a 20 7b 0a 09 09 09 27  reactor': {....'
0540: 72 65 61 63 74 6f 72 27 3a 20 27 74 68 72 65 61  reactor': 'threa
0550: 64 27 2c 0a 09 09 7d 2c 0a 09 09 27 6c 6f 67 27  d',...},...'log'
0560: 3a 20 7b 0a 09 09 09 27 73 69 6c 65 6e 74 27 3a  : {....'silent':
0570: 20 27 6e 6f 27 2c 0a 09 09 7d 2c 0a 09 09 27 64   'no',...},...'d
0580: 61 74 61 62 61 73 65 27 3a 20 7b 0a 09 09 09 27  atabase': {....'
0590: 68 6f 73 74 27 3a 20 27 6c 6f 63 61 6c 68 6f 73  host': 'localhos
05a0: 74 27 2c 0a 09 09 09 27 64 61 74 61 62 61 73 65  t',....'database
05b0: 27 3a 20 27 73 71 75 69 64 54 61 67 27 2c 0a 09  ': 'squidTag',..
05c0: 7d 2c 7d 0a 0a 09 23 20 66 75 6e 63 74 69 6f 6e  },}...# function
05d0: 20 74 6f 20 72 65 61 64 20 69 6e 20 63 6f 6e 66   to read in conf
05e0: 69 67 20 66 69 6c 65 0a 09 64 65 66 20 5f 5f 69  ig file..def __i
05f0: 6e 69 74 5f 5f 28 73 65 6c 66 29 3a 0a 09 09 70  nit__(self):...p
0600: 61 72 73 65 72 20 3d 20 6f 70 74 70 61 72 73 65  arser = optparse
0610: 2e 4f 70 74 69 6f 6e 50 61 72 73 65 72 28 29 0a  .OptionParser().
0620: 09 09 70 61 72 73 65 72 2e 61 64 64 5f 6f 70 74  ..parser.add_opt
0630: 69 6f 6e 28 27 2d 63 27 2c 20 27 2d 2d 63 6f 6e  ion('-c', '--con
0640: 66 69 67 27 2c 20 64 65 73 74 20 3d 20 27 63 6f  fig', dest = 'co
0650: 6e 66 69 67 27 2c 0a 09 09 09 68 65 6c 70 20 3d  nfig',....help =
0660: 20 27 63 6f 6e 66 69 67 20 66 69 6c 65 20 6c 6f   'config file lo
0670: 63 61 74 69 6f 6e 27 2c 20 6d 65 74 61 76 61 72  cation', metavar
0680: 20 3d 20 27 46 49 4c 45 27 2c 0a 09 09 09 64 65   = 'FILE',....de
0690: 66 61 75 6c 74 20 3d 20 27 2f 75 73 72 2f 6c 6f  fault = '/usr/lo
06a0: 63 61 6c 2f 65 74 63 2f 73 71 75 69 64 2d 74 61  cal/etc/squid-ta
06b0: 67 67 65 72 2e 63 6f 6e 66 27 29 0a 0a 09 09 28  gger.conf')....(
06c0: 6f 70 74 69 6f 6e 73 2c 20 61 72 67 73 29 20 3d  options, args) =
06d0: 20 70 61 72 73 65 72 2e 70 61 72 73 65 5f 61 72   parser.parse_ar
06e0: 67 73 28 29 0a 0a 09 09 69 66 20 6e 6f 74 20 6f  gs()....if not o
06f0: 73 2e 61 63 63 65 73 73 28 6f 70 74 69 6f 6e 73  s.access(options
0700: 2e 63 6f 6e 66 69 67 2c 20 6f 73 2e 52 5f 4f 4b  .config, os.R_OK
0710: 29 3a 0a 09 09 09 70 72 69 6e 74 28 22 43 61 6e  ):....print("Can
0720: 27 74 20 72 65 61 64 20 7b 7d 3a 20 65 78 69 74  't read {}: exit
0730: 74 69 6e 67 22 2e 66 6f 72 6d 61 74 28 6f 70 74  ting".format(opt
0740: 69 6f 6e 73 2e 63 6f 6e 66 69 67 29 29 0a 09 09  ions.config))...
0750: 09 73 79 73 2e 65 78 69 74 28 32 29 0a 0a 09 09  .sys.exit(2)....
0760: 73 65 6c 66 2e 5f 63 6f 6e 66 69 67 20 3d 20 63  self._config = c
0770: 6f 6e 66 69 67 70 61 72 73 65 72 2e 43 6f 6e 66  onfigparser.Conf
0780: 69 67 50 61 72 73 65 72 28 29 0a 09 09 73 65 6c  igParser()...sel
0790: 66 2e 5f 63 6f 6e 66 69 67 2e 72 65 61 64 66 70  f._config.readfp
07a0: 28 6f 70 65 6e 28 6f 70 74 69 6f 6e 73 2e 63 6f  (open(options.co
07b0: 6e 66 69 67 29 29 0a 0a 09 23 20 66 75 6e 63 74  nfig))...# funct
07c0: 69 6f 6e 20 74 6f 20 73 65 6c 65 63 74 20 63 6f  ion to select co
07d0: 6e 66 69 67 20 66 69 6c 65 20 73 65 63 74 69 6f  nfig file sectio
07e0: 6e 20 6f 72 20 63 72 65 61 74 65 20 6f 6e 65 0a  n or create one.
07f0: 09 64 65 66 20 73 65 63 74 69 6f 6e 28 73 65 6c  .def section(sel
0800: 66 2c 20 73 65 63 74 69 6f 6e 29 3a 0a 09 09 69  f, section):...i
0810: 66 20 6e 6f 74 20 73 65 6c 66 2e 5f 63 6f 6e 66  f not self._conf
0820: 69 67 2e 68 61 73 5f 73 65 63 74 69 6f 6e 28 73  ig.has_section(s
0830: 65 63 74 69 6f 6e 29 3a 0a 09 09 09 73 65 6c 66  ection):....self
0840: 2e 5f 63 6f 6e 66 69 67 2e 61 64 64 5f 73 65 63  ._config.add_sec
0850: 74 69 6f 6e 28 73 65 63 74 69 6f 6e 29 0a 09 09  tion(section)...
0860: 73 65 6c 66 2e 5f 73 65 63 74 69 6f 6e 20 3d 20  self._section = 
0870: 73 65 63 74 69 6f 6e 0a 0a 09 23 20 66 75 6e 63  section...# func
0880: 74 69 6f 6e 20 74 6f 20 67 65 74 20 63 6f 6e 66  tion to get conf
0890: 69 67 20 70 61 72 61 6d 65 74 65 72 2c 20 69 66  ig parameter, if
08a0: 20 70 61 72 61 6d 65 74 65 72 20 64 6f 65 73 6e   parameter doesn
08b0: 27 74 20 65 78 69 73 74 73 20 74 68 65 20 64 65  't exists the de
08c0: 66 61 75 6c 74 0a 09 23 20 76 61 6c 75 65 20 6f  fault..# value o
08d0: 72 20 4e 6f 6e 65 20 69 73 20 73 75 62 73 74 69  r None is substi
08e0: 74 75 74 65 64 0a 09 64 65 66 20 5f 5f 67 65 74  tuted..def __get
08f0: 69 74 65 6d 5f 5f 28 73 65 6c 66 2c 20 6e 61 6d  item__(self, nam
0900: 65 29 3a 0a 09 09 69 66 20 6e 6f 74 20 73 65 6c  e):...if not sel
0910: 66 2e 5f 63 6f 6e 66 69 67 2e 68 61 73 5f 6f 70  f._config.has_op
0920: 74 69 6f 6e 28 73 65 6c 66 2e 5f 73 65 63 74 69  tion(self._secti
0930: 6f 6e 2c 20 6e 61 6d 65 29 3a 0a 09 09 09 69 66  on, name):....if
0940: 20 73 65 6c 66 2e 5f 73 65 63 74 69 6f 6e 20 69   self._section i
0950: 6e 20 73 65 6c 66 2e 5f 64 65 66 61 75 6c 74 3a  n self._default:
0960: 0a 09 09 09 09 69 66 20 6e 61 6d 65 20 69 6e 20  .....if name in 
0970: 73 65 6c 66 2e 5f 64 65 66 61 75 6c 74 5b 73 65  self._default[se
0980: 6c 66 2e 5f 73 65 63 74 69 6f 6e 5d 3a 0a 09 09  lf._section]:...
0990: 09 09 09 73 65 6c 66 2e 5f 63 6f 6e 66 69 67 2e  ...self._config.
09a0: 73 65 74 28 73 65 6c 66 2e 5f 73 65 63 74 69 6f  set(self._sectio
09b0: 6e 2c 20 6e 61 6d 65 2c 20 73 65 6c 66 2e 5f 64  n, name, self._d
09c0: 65 66 61 75 6c 74 5b 73 65 6c 66 2e 5f 73 65 63  efault[self._sec
09d0: 74 69 6f 6e 5d 5b 6e 61 6d 65 5d 29 0a 09 09 09  tion][name])....
09e0: 09 65 6c 73 65 3a 0a 09 09 09 09 09 73 65 6c 66  .else:......self
09f0: 2e 5f 63 6f 6e 66 69 67 2e 73 65 74 28 73 65 6c  ._config.set(sel
0a00: 66 2e 5f 73 65 63 74 69 6f 6e 2c 20 6e 61 6d 65  f._section, name
0a10: 2c 20 4e 6f 6e 65 29 0a 09 09 09 65 6c 73 65 3a  , None)....else:
0a20: 0a 09 09 09 09 73 65 6c 66 2e 5f 63 6f 6e 66 69  .....self._confi
0a30: 67 2e 73 65 74 28 73 65 6c 66 2e 5f 73 65 63 74  g.set(self._sect
0a40: 69 6f 6e 2c 20 6e 61 6d 65 2c 20 4e 6f 6e 65 29  ion, name, None)
0a50: 0a 09 09 72 65 74 75 72 6e 28 73 65 6c 66 2e 5f  ...return(self._
0a60: 63 6f 6e 66 69 67 2e 67 65 74 28 73 65 6c 66 2e  config.get(self.
0a70: 5f 73 65 63 74 69 6f 6e 2c 20 6e 61 6d 65 29 29  _section, name))
0a80: 0a 0a 23 20 69 6e 69 74 69 61 6c 69 7a 69 6e 67  ..# initializing
0a90: 20 61 6e 64 20 72 65 61 64 69 6e 67 20 69 6e 20   and reading in 
0aa0: 63 6f 6e 66 69 67 20 66 69 6c 65 0a 63 6f 6e 66  config file.conf
0ab0: 69 67 20 3d 20 43 6f 6e 66 69 67 28 29 0a 0a 74  ig = Config()..t
0ac0: 61 67 64 62 20 3d 20 74 61 67 44 42 28 29 0a 0a  agdb = tagDB()..
0ad0: 63 73 76 5f 77 72 69 74 65 72 20 3d 20 63 73 76  csv_writer = csv
0ae0: 2e 77 72 69 74 65 72 28 73 79 73 2e 73 74 64 6f  .writer(sys.stdo
0af0: 75 74 29 0a 63 73 76 5f 77 72 69 74 65 72 2e 77  ut).csv_writer.w
0b00: 72 69 74 65 72 6f 77 28 5b 27 73 69 74 65 27 2c  riterow(['site',
0b10: 20 27 74 61 67 73 27 2c 20 27 72 65 67 65 78 70   'tags', 'regexp
0b20: 27 5d 29 0a 66 6f 72 20 72 6f 77 20 69 6e 20 74  ']).for row in t
0b30: 61 67 64 62 2e 64 75 6d 70 28 29 3a 0a 09 63 73  agdb.dump():..cs
0b40: 76 5f 77 72 69 74 65 72 2e 77 72 69 74 65 72 6f  v_writer.writero
0b50: 77 28 5b 72 6f 77 5b 30 5d 2c 20 27 7b 27 20 2b  w([row[0], '{' +
0b60: 20 27 2c 27 2e 6a 6f 69 6e 28 72 6f 77 5b 31 5d   ','.join(row[1]
0b70: 29 20 2b 20 27 7d 27 2c 20 72 6f 77 5b 32 5d 5d  ) + '}', row[2]]
0b80: 29 0a                                            ).