webserver.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #!/usr/bin/env python
  2. # -*- coding: iso-8859-15 -*-
  3. """
  4. BC (Border-Check) is a tool to retrieve info of traceroute tests over website navigation routes.
  5. GPLv3 - 2013-2014-2015 by psy (epsylon@riseup.net)
  6. """
  7. import os
  8. import sys
  9. import urllib2
  10. from SocketServer import ForkingMixIn, ThreadingMixIn
  11. from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
  12. from runpy import run_module
  13. from urlparse import urlparse
  14. from cgi import parse_qs #, parse_header, parse_multipart
  15. import cgi
  16. from options import BCOptions
  17. port = 8080
  18. wwwroot = "web/"
  19. http = {} # global storage
  20. class ForkingTCPServer(ForkingMixIn, HTTPServer): pass
  21. class ThreadingTCPServer(ThreadingMixIn, HTTPServer): pass
  22. def print_exception(type=None, value=None, tb=None, limit=None):
  23. if type is None:
  24. type, value, tb = sys.exc_info()
  25. import traceback
  26. ret = "<html><body><h2>Traceback (most recent call last):<h2 />"
  27. ret += "<pre>"
  28. list = traceback.format_tb(tb, limit) + \
  29. traceback.format_exception_only(type, value)
  30. ret += "exception error"
  31. ret += "%s: %s<br/>\n" % ( ("\n".join(list[:-1])), (list[-1]))
  32. ret +="</body></html>"
  33. del tb
  34. return ret
  35. def set_options(self, options):
  36. self.options = options
  37. def create_options(self, args=None):
  38. self.optionParser = BCOptions()
  39. self.options = self.optionParser.get_options(args)
  40. if not self.options:
  41. return False
  42. return self.options
  43. class HttpHandler(BaseHTTPRequestHandler):
  44. def client_not_allowed(self, addr):
  45. return False
  46. if addr == "127.0.0.1":
  47. return False
  48. print ("Client not allowed ",addr)
  49. return True
  50. def is_valid_url(self,url):
  51. import re
  52. regex = re.compile(
  53. r'^https?://' # http:// or https://
  54. r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain...
  55. r'localhost|' # localhost...
  56. r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
  57. r'(?::\d+)?' # optional port
  58. r'(?:/?|[/?]\S+)$', re.IGNORECASE)
  59. return url is not None and regex.search(url)
  60. def is_online_url(self,url):
  61. status_reply = urllib2.urlopen("http://downforeveryoneorjustme.com/"+str(url)).read()
  62. if not 'is up' in status_reply:
  63. self.online_url = False
  64. else:
  65. self.online_url = True
  66. def serve(self):
  67. output = ""
  68. uri = self.path
  69. tmp = uri.find ('?')
  70. args = parse_qs(urlparse(uri)[4])
  71. if 'hostname' in args:
  72. if (self.is_valid_url(args['hostname'][0])):
  73. online = self.is_online_url(args['hostname'][0])
  74. if self.online_url == True:
  75. options = create_options(BCOptions)
  76. if options.debug == True:
  77. print "saving hostname : "+str(args['hostname'])
  78. with open('hostname.submit', 'w') as file:
  79. file.write(str(args['hostname'][0]))
  80. else:
  81. args['error']='invalid url !'
  82. else:
  83. args['error']='invalid url !'
  84. if tmp != -1 :
  85. uri = uri[0:tmp]
  86. file = wwwroot + "/" + uri
  87. if self.client_not_allowed (self.client_address[0]):
  88. self.wfile.write ("HTTP/1.0 503 Not allowed\r\n\r\nYou are not whitelisted")
  89. return
  90. content = ""
  91. try:
  92. ctype,pdict = cgi.parse_header(self.headers.getheader('content-type'))
  93. print "CTYPE IS ",ctype
  94. if ctype == 'multipart/form-data':
  95. query = cgi.parse_multipart(self.rfile, pdict)
  96. content = query.get('upfile')
  97. except:
  98. pass
  99. #print "Request from %s:%d"%self.client_address + " " + uri
  100. # print interactions w server
  101. options = create_options(BCOptions)
  102. if options.debug == True:
  103. print "Request from %s:%d"%self.client_address + " " + uri
  104. if uri[-1] == '/' or os.path.isdir(file):
  105. file = file + "/index.py"
  106. if os.path.isfile(file + ".py"):
  107. file = file + ".py"
  108. if file.find("py") != -1:
  109. modname = file.replace(".py", "")
  110. cwd = modname[0:modname.rfind('/')] + "/"
  111. modname = modname.replace("/", ".")
  112. while modname.find("..") != -1:
  113. modname = modname.replace("..",".")
  114. globals = {
  115. "output": output,
  116. "http": http,
  117. "uri": uri,
  118. "args": args,
  119. "cwd": cwd,
  120. "content": content
  121. }
  122. try:
  123. a = run_module(modname, init_globals=globals)
  124. output = a["output"]
  125. except:
  126. output = print_exception()
  127. else:
  128. try:
  129. f = open (file, "r")
  130. output = f.read ()
  131. f.close ()
  132. except:
  133. output = "404"
  134. if output == "404":
  135. self.wfile.write ("HTTP/1.0 404 Not found\r\n\r\n")
  136. else:
  137. self.wfile.write ("HTTP/1.0 200 OK\r\n\r\n")
  138. self.wfile.write (output)
  139. def do_POST (self):
  140. self.serve ()
  141. def do_GET (self):
  142. self.serve ()
  143. class BorderCheckWebserver():
  144. def __init__(self, ref, *args):
  145. HttpHandler.ref = ref
  146. httpd = HTTPServer(('', port), HttpHandler)
  147. print '='*45 + "\n", "Data Visualization:\n" + '='*45 + "\n"
  148. print "Mode: Webserver\n"
  149. print "Host: http://127.0.0.1:%d/\n\nPath: '%s/web'" % (port, os.getcwd()), "\n"
  150. try:
  151. httpd.serve_forever()
  152. except KeyboardInterrupt:
  153. print 'Server killed on user request (keyboard interrupt).'
  154. if __name__=="__main__":
  155. wwwroot = "web"
  156. httpd = HTTPServer(('', port), HttpHandler)
  157. print "http://127.0.0.1:%d/ : Serving directory '%s/web'" % (port, os.getcwd())
  158. try:
  159. httpd.serve_forever()
  160. except KeyboardInterrupt:
  161. print 'Server killed on user request (keyboard interrupt).'