Commit dc5e90f6 authored by user's avatar user
Browse files

pyweb

parent 4a21d862
#!/usr/bin/env python
from hashlib import sha512
import json
import zlib
from base64 import b64decode
from functools import lru_cache
from typing import Union, AnyStr
from uuid import UUID
import SimpleHTTPServer
import SocketServer
import logging
PORT = 8000
class GetHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
logging.error(self.headers)
SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
print(self.client_address)
#https://github.com/pallets/flask/blob/master/src/flask/ctx.py
def _get_remote_addr():
address = request.headers.get('X-Forwarded-For', request.remote_addr)
if address is not None:
# An 'X-Forwarded-For' header includes a comma separated list of the
# addresses, the first address being the actual remote address.
address = address.encode('utf-8').split(b',')[0].strip()
return address
def create_identifier(ua, remote_addr):
user_agent = ua
if user_agent is not None:
user_agent = user_agent.encode('utf-8')
base = '{0}|{1}'.format(remote_addr, user_agent)
print('base: ' + base)
if str is bytes:
base = text_type(base, 'utf-8', errors='replace') # pragma: no cover
print('base: ' + base)
h = sha512()
h.update(base.encode('utf8'))
return h.hexdigest()
Handler = GetHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
httpd.serve_forever()
# -*- coding: utf-8 -*-
"""
Tagged JSON
~~~~~~~~~~~
A compact representation for lossless serialization of non-standard JSON types.
:class:`~flask.sessions.SecureCookieSessionInterface` uses this to serialize
the session data, but it may be useful in other places. It can be extended to
support other types.
.. autoclass:: TaggedJSONSerializer
:members:
.. autoclass:: JSONTag
:members:
Let's seen an example that adds support for :class:`~collections.OrderedDict`.
Dicts don't have an order in Python or JSON, so to handle this we will dump
the items as a list of ``[key, value]`` pairs. Subclass :class:`JSONTag` and
give it the new key ``' od'`` to identify the type. The session serializer
processes dicts first, so insert the new tag at the front of the order since
``OrderedDict`` must be processed before ``dict``. ::
from flask.json.tag import JSONTag
class TagOrderedDict(JSONTag):
__slots__ = ('serializer',)
key = ' od'
def check(self, value):
return isinstance(value, OrderedDict)
def to_json(self, value):
return [[k, self.serializer.tag(v)] for k, v in iteritems(value)]
def to_python(self, value):
return OrderedDict(value)
app.session_interface.serializer.register(TagOrderedDict, index=0)
:copyright: 2010 Pallets
:license: BSD-3-Clause
"""
from base64 import b64decode
from base64 import b64encode
from datetime import datetime
from uuid import UUID
from jinja2 import Markup
from werkzeug.http import http_date
from werkzeug.http import parse_date
from flask._compat import iteritems
from flask._compat import text_type
from flask.json import dumps
from flask.json import loads
class JSONTag(object):
"""Base class for defining type tags for :class:`TaggedJSONSerializer`."""
__slots__ = ("serializer",)
#: The tag to mark the serialized object with. If ``None``, this tag is
#: only used as an intermediate step during tagging.
key = None
def __init__(self, serializer):
"""Create a tagger for the given serializer."""
self.serializer = serializer
def check(self, value):
"""Check if the given value should be tagged by this tag."""
raise NotImplementedError
def to_json(self, value):
"""Convert the Python object to an object that is a valid JSON type.
The tag will be added later."""
raise NotImplementedError
def to_python(self, value):
"""Convert the JSON representation back to the correct type. The tag
will already be removed."""
raise NotImplementedError
def tag(self, value):
"""Convert the value to a valid JSON type and add the tag structure
around it."""
return {self.key: self.to_json(value)}
class TagDict(JSONTag):
"""Tag for 1-item dicts whose only key matches a registered tag.
Internally, the dict key is suffixed with `__`, and the suffix is removed
when deserializing.
"""
__slots__ = ()
key = " di"
def check(self, value):
return (
isinstance(value, dict)
and len(value) == 1
and next(iter(value)) in self.serializer.tags
)
def to_json(self, value):
key = next(iter(value))
return {key + "__": self.serializer.tag(value[key])}
def to_python(self, value):
key = next(iter(value))
return {key[:-2]: value[key]}
class PassDict(JSONTag):
__slots__ = ()
def check(self, value):
return isinstance(value, dict)
def to_json(self, value):
# JSON objects may only have string keys, so don't bother tagging the
# key here.
return dict((k, self.serializer.tag(v)) for k, v in iteritems(value))
tag = to_json
class TagTuple(JSONTag):
__slots__ = ()
key = " t"
def check(self, value):
return isinstance(value, tuple)
def to_json(self, value):
return [self.serializer.tag(item) for item in value]
def to_python(self, value):
return tuple(value)
class PassList(JSONTag):
__slots__ = ()
def check(self, value):
return isinstance(value, list)
def to_json(self, value):
return [self.serializer.tag(item) for item in value]
tag = to_json
class TagBytes(JSONTag):
__slots__ = ()
key = " b"
def check(self, value):
return isinstance(value, bytes)
def to_json(self, value):
return b64encode(value).decode("ascii")
def to_python(self, value):
return b64decode(value)
class TagMarkup(JSONTag):
"""Serialize anything matching the :class:`~flask.Markup` API by
having a ``__html__`` method to the result of that method. Always
deserializes to an instance of :class:`~flask.Markup`."""
__slots__ = ()
key = " m"
def check(self, value):
return callable(getattr(value, "__html__", None))
def to_json(self, value):
return text_type(value.__html__())
def to_python(self, value):
return Markup(value)
class TagUUID(JSONTag):
__slots__ = ()
key = " u"
def check(self, value):
return isinstance(value, UUID)
def to_json(self, value):
return value.hex
def to_python(self, value):
return UUID(value)
class TagDateTime(JSONTag):
__slots__ = ()
key = " d"
def check(self, value):
return isinstance(value, datetime)
def to_json(self, value):
return http_date(value)
def to_python(self, value):
return parse_date(value)
class TaggedJSONSerializer(object):
"""Serializer that uses a tag system to compactly represent objects that
are not JSON types. Passed as the intermediate serializer to
:class:`itsdangerous.Serializer`.
The following extra types are supported:
* :class:`dict`
* :class:`tuple`
* :class:`bytes`
* :class:`~flask.Markup`
* :class:`~uuid.UUID`
* :class:`~datetime.datetime`
"""
__slots__ = ("tags", "order")
#: Tag classes to bind when creating the serializer. Other tags can be
#: added later using :meth:`~register`.
default_tags = [
TagDict,
PassDict,
TagTuple,
PassList,
TagBytes,
TagMarkup,
TagUUID,
TagDateTime,
]
def __init__(self):
self.tags = {}
self.order = []
for cls in self.default_tags:
self.register(cls)
def register(self, tag_class, force=False, index=None):
"""Register a new tag with this serializer.
:param tag_class: tag class to register. Will be instantiated with this
serializer instance.
:param force: overwrite an existing tag. If false (default), a
:exc:`KeyError` is raised.
:param index: index to insert the new tag in the tag order. Useful when
the new tag is a special case of an existing tag. If ``None``
(default), the tag is appended to the end of the order.
:raise KeyError: if the tag key is already registered and ``force`` is
not true.
"""
tag = tag_class(self)
key = tag.key
if key is not None:
if not force and key in self.tags:
raise KeyError("Tag '{0}' is already registered.".format(key))
self.tags[key] = tag
if index is None:
self.order.append(tag)
else:
self.order.insert(index, tag)
def tag(self, value):
"""Convert a value to a tagged representation if necessary."""
for tag in self.order:
if tag.check(value):
return tag.tag(value)
return value
def untag(self, value):
"""Convert a tagged representation back to the original type."""
if len(value) != 1:
return value
key = next(iter(value))
if key not in self.tags:
return value
return self.tags[key].to_python(value[key])
def dumps(self, value):
"""Tag the value and dump it to a compact JSON string."""
print('dumps:')
print(dumps(self.tag(value), separators=(",", ":")))
return dumps(self.tag(value), separators=(",", ":"))
def loads(self, value):
"""Load data from a JSON string and deserialized any tagged objects."""
return loads(value, object_hook=self.untag)
#!/usr/bin/env python
import hmac
from hashlib import sha512
import json
import zlib
from base64 import b64decode
#from functools import lru_cache
#from typing import Union, AnyStr
from uuid import UUID
from itsdangerous import base64_decode, base64_encode, want_bytes, URLSafeTimedSerializer, BadSignature, TimestampSigner
from six import text_type
#from flask.json.tag import TaggedJSONSerializer
from tagjson import TaggedJSONSerializer
from itsdangerous.encoding import bytes_to_int, int_to_bytes
from itsdangerous import base64_decode, base64_encode, want_bytes, URLSafeTimedSerializer, BadSignature, TimestampSigner
import hashlib
import json
import zlib
from base64 import b64decode
#from functools import lru_cache
#from typing import Union, AnyStr
from uuid import UUID
import os
#import redis
#from urllib.parse import urlparse
import urlparse
from werkzeug.wrappers import Request, Response
from werkzeug.routing import Map, Rule
from werkzeug.exceptions import HTTPException, NotFound
from werkzeug.wsgi import SharedDataMiddleware
from werkzeug.utils import redirect
#from jinja2 import Environment, FileSystemLoader
import pprint
class Shortly(object):
def __init__(self, config):
return None
def encode_cookie(self, payload, key='We are the world'):
return u'{0}|{1}'.format(payload, self.cookie_digest(payload, key=key))
def hook(obj):
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(obj)
if len(obj) != 1:
print('len obj is 1')
return obj
key, val = next(iter(obj.items()))
print( 'KEY: ' + str(key) + ' VAL: ' + str(val))
if key == ' t':
return tuple(val)
elif key == ' u':
return UUID(val)
elif key == ' b':
return b64decode(val)
elif key == ' m':
return Markup(val)
elif key == ' d':
return parse_date(val)
return obj
def decode_cookie(self, cookie, key=None):
try:
payload, digest = cookie.rsplit(u'|', 1)
if hasattr(digest, 'decode'):
digest = digest.decode('ascii') # pragma: no cover
except ValueError:
print('cookie decode failede')
return
if safe_str_cmp(self, cookie_digest(payload, key=key), digest):
return payload
def get_serializer(self):
return URLSafeTimedSerializer(
secret_key='We are the world',
salt='cookie-session',
serializer=TaggedJSONSerializer(),
signer=TimestampSigner,
signer_kwargs={
'key_derivation': 'hmac',
'digest_method': hashlib.sha1})
def dispatch_request(self, request):
print(request.cookies)
ra = self._get_remote_addr(request)
#print(ra)
ua = request.headers.get('User-Agent')
cookieid = self.create_identifier(ua, ra)
print('identifier: ' + cookieid)
session = dict()
session['_fresh'] = True
session['_id'] = cookieid
session['user_id'] = 26
#print('cookieid: ' + cookieid)
#print('session: ' + str(session))
#b64c = base64_encode(cookieid)
#b64d = self.get_serializer().dumps(session)
#return json.loads(data), timestamp
#print('session b64: ', str(b64d))
## try decoding
compressed = False
payload = self.get_serializer().dumps(session)
print('payload: ' + payload)
if payload.startswith('.'):
print('compressed')
compressed = True
payload = payload[1:]
data = payload.split(".")[0]
data = base64_decode(data)
date64 = payload.split(".")[1]
sig64 = payload.split(".")[2]
print('sig ' + sig64)
timestamp = bytes_to_int(base64_decode(date64))
print('timestamp: ' + str(timestamp))
if compressed:
data = zlib.decompress(data)
data = data.decode("utf-8")
print('decoded: ' + data + ' ts: ' + str(timestamp) + ' digest: ' + str(sig64))
#print('decoded: ' + base64_decode(json.loads(b64d, object_hook=self.hook)))
#print('decoded: ' + base64_decode(json.loads(b64d, object_hook=self.hook)))
#b64d = self.get_signing_serializer(app).dumps(dict(session))
#b64d = base64_encode(dumps(session))
#cookie = self.encode_cookie(text_type(b64d), key='We are the world')
#return Response('Hello World! \n ' + cookieid + '\n' + str(b64c) + '\n' + b64c.decode("utf-8") + '\n cookie:\n ' + cookie)
return Response('hello world')
def secret_key(self, key=None):
if key is None:
key = current_app.config['SECRET_KEY']
if isinstance(key, text_type): # pragma: no cover
key = key.encode('latin1') # ensure bytes
return key
def cookie_digest(self, payload, key=None):
key = self.secret_key(key)
return hmac.new(key, payload.encode('utf-8'), sha512).hexdigest()
def _get_remote_addr(self, request):
# ff = request.headers.get('X-Forwarded-For', request.remote_addr)
address = request.headers.get('X-Forwarded-For', request.remote_addr)
print('addr: ' + address)
if address is not None:
# An 'X-Forwarded-For' header includes a comma separated list of the
# addresses, the first address being the actual remote address.
address = address.encode('utf-8').split(b',')[0].strip()
return address
def create_identifier(self,ua, remote_addr):
user_agent = ua
if user_agent is not None:
user_agent = user_agent.encode('utf-8')
base = '{0}|{1}'.format(remote_addr, user_agent)
print('base: ' + base)
if str is bytes:
base = text_type(base, 'utf-8', errors='replace') # pragma: no cover
print('base: ' + base)
h = sha512()
h.update(base.encode('utf8'))
return h.hexdigest()
def wsgi_app(self, environ, start_response):
request = Request(environ)
response = self.dispatch_request(request)
return response(environ, start_response)
def __call__(self, environ, start_response):
return self.wsgi_app(environ, start_response)
def create_app(redis_host='localhost', redis_port=6379, with_static=True):
app = Shortly({
'redis_host': redis_host,
'redis_port': redis_port
})
if with_static:
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
'/static': os.path.join(os.path.dirname(__file__), 'static')
})
return app
if __name__ == '__main__':
from werkzeug.serving import run_simple
app = create_app()
run_simple('0.0.0.0', 5000, app, use_debugger=True, use_reloader=True)
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