-
Rolf Niepraschk authoredRolf Niepraschk authored
server.py 2.81 KiB
from flask import Flask, Response, request, send_from_directory
from flask_cors import CORS
from urllib.parse import urlparse
import sys, requests
app = Flask(__name__)
VERSION = '1.1.0'
FLASK_RUN_PORT = sys.argv[1]
DATA_PATH = sys.argv[2]
FLASK_ENV = sys.argv[3]
FLASK_DEBUG = sys.argv[4]
app = Flask(__name__, static_url_path='')
app.url_map.strict_slashes = False
CORS(app)
'''
=================== URLs for Web Apps ======================
Works for any numbers of sub paths
'''
@app.route('/<p1>', methods=['GET'])
@app.route('/<p1>/<path:p2>', methods=['GET'])
def x(p1, p2=''):
path = p1
if p2:
path = path + '/' + p2
app.logger.debug('[path] ' + path)
return send_from_directory(DATA_PATH, path)
'''
=================== Proxy for CouchDB access ==============
The following works like a proxy server:
A flask server URL of the form
"http://127.0.0.1:8081/xxxx/vl_db/000_SERVERS"
will be forwarded to the real CouchDB URL
"http://127.0.0.1:xxxx/vl_db/000_SERVERS"
The part 'xxxx' can be any integer as a future port address for couchdb.
see:
https://stackoverflow.com/questions/6656363/proxying-to-another-web-service-with-flask
'''
@app.route('/<int:real_port>/', \
methods=['GET','PUT','POST','HEAD','DELETE','OPTIONS'])
@app.route('/<int:real_port>/<path:p>',
methods=['GET','PUT','POST','HEAD','DELETE','OPTIONS'])
def couchdb_proxy(real_port, p=''):
q = request.query_string.decode();
path = p
if q:
path = path + '?' + q
host = urlparse(request.base_url).hostname
scheme = urlparse(request.base_url).scheme
new_url = '{}://{}:{}/{}'.format(scheme, host, real_port, path)
app.logger.debug('[old couchdb url] ' + request.url)
app.logger.debug('[new couchdb url] ' + new_url)
resp = requests.request(
method=request.method,
url=new_url,
headers={key: value for (key, value) in request.headers if key != 'Host'},
data=request.get_data(),
cookies=request.cookies,
allow_redirects=False)
excluded_headers = ['content-encoding', 'content-length', \
'transfer-encoding', 'connection']
headers = [(name, value) for (name, value) in resp.raw.headers.items()
if name.lower() not in excluded_headers]
response = Response(resp.content, resp.status_code, headers)
return response
@app.route('/')
@app.route('/index.html')
def home():
return '''<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webapps Deliverer</title>
</head>
<body>
<h3>VacLab: Combined web and CouchDB proxy service</h3>Version: {}
</body>
</html>'''.format(VERSION)
@app.route('/version')
def version():
return VERSION + '\n'
if __name__ == '__main__':
app.config['ENV'] = FLASK_ENV
app.config['DEBUG'] = FLASK_DEBUG
app.run(host='0.0.0.0', port=FLASK_RUN_PORT)