source: salt-server/trunk/fuentes/sltsrw.py @ 473

Last change on this file since 473 was 473, checked in by daduve, 4 years ago

Adding files

  • Property svn:executable set to *
File size: 9.4 KB
Line 
1#!/usr/bin/python2
2# -*- coding: latin-1 -*-
3
4# ----------------------------------------------
5# Llamar al servidor con interfaz web service
6# ----------------------------------------------
7# Inicio de programa python sltsrw.py [-d] [-portnnnn]
8# -d: Debug, imprime información de trace
9# -portnnnn: Escucha por el puerto nnnn en vez de escuchar por el puerto 8080
10#
11# El programa necesita que este escuchando el servidor sltsrv por el puerto que
12# se indica en salt.ini
13# Si sltsrv no está activo, lo inicia a partir de la información contenida
14# en el archivo salt.ini que ha de estar en la misma carpeta que sltsrw
15
16import sys
17import os
18import time
19import socket
20import threading
21
22import cgi
23import cStringIO
24import SimpleHTTPServer
25from StringIO import StringIO
26import Cookie
27
28class ScriptRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
29  """One instance of this class is created for each HTTP request"""
30
31  def do_GET(self):
32    """Begin serving a GET request"""
33    # build self.body from the query string
34    self.body = {}
35    if self.path.find('?')>-1:
36      qs = self.path.split('?',1)[1]
37      self.body = cgi.parse_qs(qs, keep_blank_values=1)
38    self.handle_data()
39   
40  def do_POST(self):
41    """Begin serving a POST request. The request data is readable
42    on a file-like object called self.rfile"""
43    ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
44    length = int(self.headers.getheader('content-length'))
45    if ctype == 'multipart/form-data':
46      self.body = cgi.parse_multipart(self.rfile, pdict)
47    elif ctype == 'application/x-www-form-urlencoded':
48      qs = self.rfile.read(length)
49      self.body = cgi.parse_qs(qs, keep_blank_values=1)
50    else:
51      self.body = {}                   # Unknown content-type
52    # some browsers send 2 more bytes...
53    [ready_to_read,x,y] = select.select([self.connection],[],[],0)
54    if ready_to_read:
55      self.rfile.read(2)
56    self.handle_data()
57
58  def handle_data(self):
59    """Process the data received"""
60    #Comprobar si es cliente autorizado
61    if _ini.Existe("sltsrw","ipsok"):
62      ipsok=eval(_ini("sltsrw","ipsok"))
63      if ipsok!=[]:
64        if ipsok.count(self.client_address[0])==0:
65          self.send_error(401,"Cliente no autorizado")
66          return
67    self.resp_headers = {"Content-type":'text/html'} # default
68    self.cookie=Cookie.SimpleCookie()
69    if self.headers.has_key('cookie'):
70      self.cookie=Cookie.SimpleCookie(self.headers.getheader("cookie"))
71    if self.body!={}:
72      if dbg:
73        print "conectat (web) client",self.client_address
74      sck=socketConnect()
75      if sck!=None:
76        sck.send(self.body['salt4msg'][0])
77        datos=sck.recv(128000)
78      else:
79        self.send_error(503,"No responde el server (sltsrv)")
80        return
81      ctype='text/plain'
82      f=StringIO()
83      f.write(datos)
84      f.seek(0)
85      self.resp_headers['Content-type'] = ctype
86      self.resp_headers['Content-length'] = str(len(datos))
87      self.done(200,f)
88      return
89    path = self.get_file() # return a file name or None
90    if os.path.isdir(path):
91      # list directory
92      dir_list = self.list_directory(path)
93      self.copyfile(dir_list, self.wfile)
94      return
95    ext = os.path.splitext(path)[1].lower()
96    if len(ext)>1 and hasattr(self,"run_%s" %ext[1:]):
97      # if run_some_extension() exists
98      exec ("self.run_%s(path)" %ext[1:])
99    else:
100      # other files
101      ctype = self.guess_type(path)
102      if ctype.startswith('text/'):
103        mode = 'r'
104      else:
105        mode = 'rb'
106      try:
107        f = open(path,mode)
108        self.resp_headers['Content-type'] = ctype
109        self.resp_headers['Content-length'] = str(os.fstat(f.fileno())[6])
110        self.done(200,f)
111      except IOError:
112        self.send_error(404, "File not found")
113
114  def done(self, code, infile):
115    """Send response, cookies, response headers
116    and the data read from infile"""
117    self.send_response(code)
118    for morsel in self.cookie.values():
119      self.send_header('Set-Cookie', morsel.output(header='').lstrip())
120    for (k,v) in self.resp_headers.items():
121      self.send_header(k,v)
122    self.end_headers()
123    infile.seek(0)
124    self.copyfile(infile, self.wfile)
125
126  def get_file(self):
127    """Set the Content-type header and return the file open
128    for reading, or None"""
129    path = self.path
130    if path.find('?')>1:
131      # remove query string, otherwise the file will not be found
132      path = path.split('?',1)[0]
133    path = self.translate_path(path)
134    if os.path.isdir(path):
135
136      for index in "index.html", "index.htm":
137        index = os.path.join(path, index)
138        if os.path.exists(index):
139          path = index
140          break
141    return path
142
143  def run_py(self, script):
144    """Run a Python script"""
145    # redirect standard output so that the "print" statements
146    # in the script will be sent to the web browser
147    sys.stdout = cStringIO.StringIO()
148
149    # build the namespace in which the script will be run
150    namespace = {'request':self.body, 'headers' : self.headers,
151      'resp_headers':self.resp_headers, 'Session':self.Session,
152      'HTTP_REDIRECTION':HTTP_REDIRECTION}
153    try:
154      execfile (script,namespace)
155    except HTTP_REDIRECTION,url:
156      self.resp_headers['Location'] = url
157      self.done(301,cStringIO.StringIO())
158    except:
159      # print a traceback
160      # first reset the output stream
161      sys.stdout = cStringIO.StringIO()
162      exc_type,exc_value,tb=sys.exc_info()
163      msg = exc_value.args[0]
164      if tb.tb_next is None:     # errors (detected by the parser)
165        line = exc_value.lineno
166        text = exc_value.text
167      else:                      # exceptions
168        line = tb.tb_next.tb_lineno
169        text = open(script).readlines()[line-1]
170      print '%s in file %s : %s' %(exc_type.__name__,
171        os.path.basename(script), cgi.escape(msg))
172      print '<br>Line %s' %line
173      print '<br><pre><b>%s</b></pre>' %cgi.escape(text)
174    self.resp_headers['Content-length'] = sys.stdout.tell()
175    self.done(200,sys.stdout)
176
177  def run_tpl(self,script):
178    """Templating system with the string substitution syntax
179    introduced in Python 2.4"""
180
181    # values must be strings, not lists
182    dic = dict([ (k,v[0]) for k,v in self.body.items() ])
183    # first check if the string.Template class is available
184    if hasattr(string,"Template"): # Python 2.4 or above
185      try:
186        data = string.Template(open(script).read()).substitute(dic)
187      except:
188        exc_type,exc_value,tb=sys.exc_info()
189        msg = exc_value.args[0]
190        data = '%s in file %s : %s' \
191          %(exc_type.__name__,os.path.basename(script), 
192          cgi.escape(msg))
193    else:
194      data = "Unable to handle this syntax for " + \
195        "string substitution. Python version must be 2.4 or above"
196    self.resp_headers['Content-length'] = len(data)
197    self.done(200,cStringIO.StringIO(data))
198
199  def Session(self):
200    """Session management
201    If the client has sent a cookie named sessionId, take its value and
202    return the corresponding SessionElement objet, stored in
203    sessionDict
204    Otherwise create a new SessionElement objet and generate a random
205    8-letters value sent back to the client as the value for a cookie
206    called sessionId"""
207    if self.cookie.has_key("sessionId"):
208      sessionId=self.cookie["sessionId"].value
209    else:
210      sessionId=generateRandom(8)
211      self.cookie["sessionId"]=sessionId
212    try:
213      sessionObject = sessionDict[sessionId]
214    except KeyError:
215      sessionObject = SessionElement()
216      sessionDict[sessionId] = sessionObject
217    return sessionObject
218
219# end of class ScriptRequestHandler
220
221import SocketServer
222class ThreadingTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
223  pass
224# end of class ThreadingTCPServer
225
226class CfgFile:
227  def __init__(self,file=None):
228    import ConfigParser
229    self.cfg=ConfigParser.ConfigParser()
230    if file==None:
231      miCfg=os.path.dirname(os.path.abspath(__file__))
232      if os.path.basename(miCfg)[-3:].lower()=='zip':
233        miCfg=os.path.dirname(miCfg)
234      miCfg=os.path.abspath(miCfg+"/salt.cfg")
235    else:
236      miCfg=file
237    self.cfg.read(miCfg)
238 
239  def __call__(self,sec,opt):
240    ret=None
241    if self.cfg.has_option(sec,opt):
242      ret=self.cfg.get(sec,opt)
243      lret=ret.lower()
244      if lret=="true" or lret=="sí" or lret=="si" or lret=="1" or lret=="s":
245        ret=True
246      elif lret=="false" or lret=="no" or lret=="0" or lret=="n":
247        ret=False
248      elif ret.isdigit():
249        ret=eval(ret)
250    return ret
251 
252  def Existe(self,sec,opt):
253    ret=False
254    if self.cfg.has_option(sec,opt):
255      if self.cfg.get(sec,opt) != "":
256        ret=True
257    return ret   
258
259# End of Class CfgFile
260
261_ini=CfgFile()
262
263def socketConnect():
264  try:
265    sck=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
266    sck.connect(('localhost',20001))
267  except:
268    print 'Cal iniciar el servidor Salt4 (sltsrv)'
269    sck=None
270     
271  return sck
272
273miPath=os.path.dirname(os.path.abspath(__file__))
274if os.path.basename(miPath)[-3:].lower()=='zip':
275  miPath=os.path.dirname(miPath)
276
277esprod=True
278port=8080
279dbg=False
280if _ini.Existe("sltsrw","port"):
281  port=_ini("sltsrw","port")
282for arg in sys.argv:
283  if arg[0:2]=="-d":
284    dbg=True
285  elif arg[0:5]=="-port":
286    port=arg[5:]
287
288if esprod:
289  s=SocketServer.ThreadingTCPServer(('',port),ScriptRequestHandler)
290else:
291  s=SocketServer.TCPServer(('',port),ScriptRequestHandler)
292if dbg:
293  print "Esperant conexió web",port
294  print "exe,prefix,args,miPath",sys.executable,sys.exec_prefix,sys.argv,miPath
295s.serve_forever()
296 
Note: See TracBrowser for help on using the repository browser.