Commit a55d0291 authored by Alain Takoudjou's avatar Alain Takoudjou

add POST method to simplehttpserver and support for access without hash url

parent 49f7d48d
...@@ -33,6 +33,7 @@ class Recipe(GenericBaseRecipe): ...@@ -33,6 +33,7 @@ class Recipe(GenericBaseRecipe):
def __init__(self, buildout, name, options): def __init__(self, buildout, name, options):
base_path = options['base-path'] base_path = options['base-path']
if options.get('use-hash-url', 'True') in ['true', 'True']:
pool = string.letters + string.digits pool = string.letters + string.digits
hash_string = ''.join(random.choice(pool) for i in xrange(64)) hash_string = ''.join(random.choice(pool) for i in xrange(64))
path = os.path.join(base_path, hash_string) path = os.path.join(base_path, hash_string)
...@@ -47,6 +48,9 @@ class Recipe(GenericBaseRecipe): ...@@ -47,6 +48,9 @@ class Recipe(GenericBaseRecipe):
options['root-dir'] = path options['root-dir'] = path
options['path'] = hash_string options['path'] = hash_string
else:
options['root-dir'] = base_path
options['path'] = ''
return GenericBaseRecipe.__init__(self, buildout, name, options) return GenericBaseRecipe.__init__(self, buildout, name, options)
...@@ -59,8 +63,9 @@ class Recipe(GenericBaseRecipe): ...@@ -59,8 +63,9 @@ class Recipe(GenericBaseRecipe):
'port': int(self.options['port']), 'port': int(self.options['port']),
'cwd': self.options['base-path'], 'cwd': self.options['base-path'],
'log-file': self.options['log-file'], 'log-file': self.options['log-file'],
'cert-file': self.options['cert-file'], 'cert-file': self.options.get('cert-file', ''),
'key-file': self.options['key-file'] 'key-file': self.options.get('key-file', ''),
'root-dir': self.options['root-dir']
} }
server = self.createPythonScript( server = self.createPythonScript(
......
# -*- coding: utf-8 -*-
from SimpleHTTPServer import SimpleHTTPRequestHandler from SimpleHTTPServer import SimpleHTTPRequestHandler
from BaseHTTPServer import HTTPServer from BaseHTTPServer import HTTPServer
import ssl import ssl
...@@ -5,23 +6,71 @@ import os ...@@ -5,23 +6,71 @@ import os
import logging import logging
from netaddr import valid_ipv4, valid_ipv6 from netaddr import valid_ipv4, valid_ipv6
import socket import socket
import cgi, errno
class ServerHandler(SimpleHTTPRequestHandler): class ServerHandler(SimpleHTTPRequestHandler):
def respond(self, code=200, type='text/plain'): document_path = ''
restrict_root_folder = True
def respond(self, code=200, type='text/html'):
self.send_response(code) self.send_response(code)
self.send_header("Content-type", type) self.send_header("Content-type", type)
self.end_headers() self.end_headers()
def do_GET(self): def restrictedRootAccess(self):
logging.info('%s - GET: %s \n%s' % (self.client_address[0], self.path, self.headers)) if self.restrict_root_folder and self.path and self.path == '/':
if not self.path or self.path == '/':
# no access to root path # no access to root path
self.respond(403) self.respond(403)
self.wfile.write("Forbidden") self.wfile.write("Forbidden")
return True
return False
def do_GET(self):
logging.info('%s - GET: %s \n%s' % (self.client_address[0], self.path, self.headers))
if self.restrictedRootAccess():
return return
SimpleHTTPRequestHandler.do_GET(self) SimpleHTTPRequestHandler.do_GET(self)
def do_POST(self):
logging.info('%s - POST: %s \n%s' % (self.client_address[0], self.path, self.headers))
if self.restrictedRootAccess():
return
form = cgi.FieldStorage(
fp=self.rfile,
headers=self.headers,
environ={'REQUEST_METHOD':'POST',
'CONTENT_TYPE':self.headers['Content-Type']}
)
name = form['path'].value
content = form['content'].value
method = 'a'
if form.has_key('clear') and form['clear'].value == '1':
method = 'w'
self.writeFile(name, content, method)
self.respond(200, type=self.headers['Content-Type'])
self.wfile.write("Content written to %s" % name)
def writeFile(self, filename, content, method='a'):
file_path = os.path.join(self.document_path, filename)
try:
os.makedirs(os.path.dirname(file_path))
except OSError as exception:
if exception.errno != errno.EEXIST:
logging.error('Failed to create file in %s. The error is \n%s' % (
file_path, str(exception)))
logging.info('Writing recieved content to file %s' % file_path)
try:
with open(file_path, method) as myfile:
myfile.write(content.decode('utf-8'))
logging.info('Done.')
except IOError as e:
logging.error('Something happened while processing \'writeFile\'. The message is %s' %
str(e))
class HTTPServerV6(HTTPServer): class HTTPServerV6(HTTPServer):
address_family = socket.AF_INET6 address_family = socket.AF_INET6
...@@ -38,6 +87,8 @@ def run(args): ...@@ -38,6 +87,8 @@ def run(args):
os.chdir(args['cwd']) os.chdir(args['cwd'])
Handler = ServerHandler Handler = ServerHandler
Handler.document_path = args['root-dir']
Handler.restrict_root_folder = (args['root-dir'] != args['cwd'])
if valid_ipv6(host): if valid_ipv6(host):
server = HTTPServerV6 server = HTTPServerV6
...@@ -45,11 +96,14 @@ def run(args): ...@@ -45,11 +96,14 @@ def run(args):
server = HTTPServer server = HTTPServer
httpd = server((host, port), Handler) httpd = server((host, port), Handler)
if args.has_key('cert-file') and args.has_key('key-file'): scheme = 'http'
if args.has_key('cert-file') and args.has_key('key-file') and \
os.path.exists(args['cert-file']) and os.path.exists(args['key-file']):
scheme = 'https'
httpd.socket = ssl.wrap_socket (httpd.socket, httpd.socket = ssl.wrap_socket (httpd.socket,
server_side=True, server_side=True,
certfile=args['cert-file'], certfile=args['cert-file'],
keyfile=args['key-file']) keyfile=args['key-file'])
logging.info("Starting simple http server at https://%s:%s" % (host, port)) logging.info("Starting simple http server at %s://%s:%s" % (scheme, host, port))
httpd.serve_forever() httpd.serve_forever()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment