Overview
Comment: | [server] update bottlepy 0.12.13 -> 0.12.18 |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk | server |
Files: | files | file ages | folders |
SHA3-256: |
ac85e5e83945237405f7fa1a6346d350 |
User & Date: | olr on 2020-03-27 13:53:44 |
Other Links: | manifest | tags |
Context
2020-03-27
| ||
15:45 | [fr] ajustements check-in: c905e0db0c user: olr tags: trunk, fr, v1.8.0 | |
13:53 | [server] update bottlepy 0.12.13 -> 0.12.18 check-in: ac85e5e839 user: olr tags: trunk, server | |
12:45 | [graphspell] suggestion: prevents splitting trailing numbers if not following an alpha character check-in: cbbb58a487 user: olr tags: trunk, graphspell | |
Changes
Modified 3rd/bottle.py from [0fd84d1675] to [a449f5dd2c].
︙ | ︙ | |||
12 13 14 15 16 17 18 | Copyright (c) 2016, Marcel Hellkamp. License: MIT (see LICENSE for details) """ from __future__ import with_statement __author__ = 'Marcel Hellkamp' | | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | Copyright (c) 2016, Marcel Hellkamp. License: MIT (see LICENSE for details) """ from __future__ import with_statement __author__ = 'Marcel Hellkamp' __version__ = '0.12.18' __license__ = 'MIT' # The gevent server adapter needs to patch some modules before they are imported # This is why we parse the commandline parameters here but handle them later if __name__ == '__main__': from optparse import OptionParser _cmd_parser = OptionParser(usage="usage: %prog [options] package.module:app") _opt = _cmd_parser.add_option _opt("--version", action="store_true", help="show version number.") _opt("-b", "--bind", metavar="ADDRESS", help="bind socket to ADDRESS.") _opt("-s", "--server", default='wsgiref', help="use SERVER as backend.") _opt("-p", "--plugin", action="append", help="install additional plugin/s.") _opt("--debug", action="store_true", help="start server in debug mode.") _opt("--reload", action="store_true", help="auto-reload on file changes.") _cmd_options, _cmd_args = _cmd_parser.parse_args() if _cmd_options.server and _cmd_options.server.startswith('gevent'): import gevent.monkey; gevent.monkey.patch_all() import base64, cgi, email.utils, functools, hmac, itertools, mimetypes,\ os, re, subprocess, sys, tempfile, threading, time, warnings, hashlib from datetime import date as datedate, datetime, timedelta from tempfile import TemporaryFile from traceback import format_exc, print_exc from inspect import getargspec from unicodedata import normalize |
︙ | ︙ | |||
80 81 82 83 84 85 86 | if py3k: import http.client as httplib import _thread as thread from urllib.parse import urljoin, SplitResult as UrlSplitResult from urllib.parse import urlencode, quote as urlquote, unquote as urlunquote urlunquote = functools.partial(urlunquote, encoding='latin1') from http.cookies import SimpleCookie | > > > > | > > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | if py3k: import http.client as httplib import _thread as thread from urllib.parse import urljoin, SplitResult as UrlSplitResult from urllib.parse import urlencode, quote as urlquote, unquote as urlunquote urlunquote = functools.partial(urlunquote, encoding='latin1') from http.cookies import SimpleCookie if py >= (3, 3, 0): from collections.abc import MutableMapping as DictMixin from types import ModuleType as new_module else: from collections import MutableMapping as DictMixin from imp import new_module import pickle from io import BytesIO from configparser import ConfigParser basestring = str unicode = str json_loads = lambda s: json_lds(touni(s)) callable = lambda x: hasattr(x, '__call__') imap = map def _raise(*a): raise a[0](a[1]).with_traceback(a[2]) else: # 2.x import httplib import thread from urlparse import urljoin, SplitResult as UrlSplitResult from urllib import urlencode, quote as urlquote, unquote as urlunquote from Cookie import SimpleCookie from itertools import imap import cPickle as pickle from imp import new_module from StringIO import StringIO as BytesIO from ConfigParser import SafeConfigParser as ConfigParser if py25: msg = "Python 2.5 support may be dropped in future versions of Bottle." warnings.warn(msg, DeprecationWarning) from UserDict import DictMixin def next(it): return it.next() |
︙ | ︙ | |||
1553 1554 1555 1556 1557 1558 1559 | def iter_headers(self): ''' Yield (header, value) tuples, skipping headers that are not allowed with the current response status code. ''' return self.headerlist @property def headerlist(self): | | | | > > | 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 | def iter_headers(self): ''' Yield (header, value) tuples, skipping headers that are not allowed with the current response status code. ''' return self.headerlist @property def headerlist(self): """ WSGI conform list of (header, value) tuples. """ out = [] headers = list(self._headers.items()) if 'Content-Type' not in self._headers: headers.append(('Content-Type', [self.default_content_type])) if self._status_code in self.bad_headers: bad_headers = self.bad_headers[self._status_code] headers = [h for h in headers if h[0] not in bad_headers] out += [(name, val) for (name, vals) in headers for val in vals] if self._cookies: for c in self._cookies.values(): out.append(('Set-Cookie', _hval(c.OutputString()))) if py3k: out = [(k, v.encode('utf8').decode('latin1')) for (k, v) in out] return out content_type = HeaderProperty('Content-Type') content_length = HeaderProperty('Content-Length', reader=int) expires = HeaderProperty('Expires', reader=lambda x: datetime.utcfromtimestamp(parse_date(x)), writer=lambda x: http_date(x)) |
︙ | ︙ | |||
1775 1776 1777 1778 1779 1780 1781 | #: Not a plugin, but part of the plugin API. TODO: Find a better place. class _ImportRedirect(object): def __init__(self, name, impmask): ''' Create a virtual package that redirects imports (see PEP 302). ''' self.name = name self.impmask = impmask | | | 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 | #: Not a plugin, but part of the plugin API. TODO: Find a better place. class _ImportRedirect(object): def __init__(self, name, impmask): ''' Create a virtual package that redirects imports (see PEP 302). ''' self.name = name self.impmask = impmask self.module = sys.modules.setdefault(name, new_module(name)) self.module.__dict__.update({'__file__': __file__, '__path__': [], '__all__': [], '__loader__': self}) sys.meta_path.append(self) def find_module(self, fullname, path=None): if '.' not in fullname: return packname = fullname.rsplit('.', 1)[0] |
︙ | ︙ | |||
2591 2592 2593 2594 2595 2596 2597 | Runtime is not affected by length of common prefix. ''' return not sum(0 if x==y else 1 for x, y in zip(a, b)) and len(a) == len(b) def cookie_encode(data, key): ''' Encode and sign a pickle-able object. Return a (byte) string ''' msg = base64.b64encode(pickle.dumps(data, -1)) | | | | 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 | Runtime is not affected by length of common prefix. ''' return not sum(0 if x==y else 1 for x, y in zip(a, b)) and len(a) == len(b) def cookie_encode(data, key): ''' Encode and sign a pickle-able object. Return a (byte) string ''' msg = base64.b64encode(pickle.dumps(data, -1)) sig = base64.b64encode(hmac.new(tob(key), msg, digestmod=hashlib.md5).digest()) return tob('!') + sig + tob('?') + msg def cookie_decode(data, key): ''' Verify and decode an encoded string. Return an object or None.''' data = tob(data) if cookie_is_encoded(data): sig, msg = data.split(tob('?'), 1) if _lscmp(sig[1:], base64.b64encode(hmac.new(tob(key), msg, digestmod=hashlib.md5).digest())): return pickle.loads(base64.b64decode(msg)) return None def cookie_is_encoded(data): ''' Return True if the argument looks like a encoded cookie.''' return bool(data.startswith(tob('!')) and tob('?') in data) |
︙ | ︙ | |||
2900 2901 2902 2903 2904 2905 2906 | """ Untested. Options: * `fast` (default: False) uses libevent's http server, but has some issues: No streaming, no pipelining, no SSL. * See gevent.wsgi.WSGIServer() documentation for more options. """ def run(self, handler): | | | > > | | | 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 | """ Untested. Options: * `fast` (default: False) uses libevent's http server, but has some issues: No streaming, no pipelining, no SSL. * See gevent.wsgi.WSGIServer() documentation for more options. """ def run(self, handler): from gevent import pywsgi, local if not isinstance(threading.local(), local.local): msg = "Bottle requires gevent.monkey.patch_all() (before import)" raise RuntimeError(msg) if self.options.pop('fast', None): depr('The "fast" option has been deprecated and removed by Gevent.') if self.quiet: self.options['log'] = None address = (self.host, self.port) server = pywsgi.WSGIServer(address, handler, **self.options) if 'BOTTLE_CHILD' in os.environ: import signal signal.signal(signal.SIGINT, lambda s, f: server.stop()) server.serve_forever() class GeventSocketIOServer(ServerAdapter): |
︙ | ︙ | |||
3150 3151 3152 3153 3154 3155 3156 | def run(self): exists = os.path.exists mtime = lambda path: os.stat(path).st_mtime files = dict() for module in list(sys.modules.values()): | | | 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 | def run(self): exists = os.path.exists mtime = lambda path: os.stat(path).st_mtime files = dict() for module in list(sys.modules.values()): path = getattr(module, '__file__', '') or '' if path[-4:] in ('.pyo', '.pyc'): path = path[:-1] if path and exists(path): files[path] = mtime(path) while not self.status: if not exists(self.lockfile)\ or mtime(self.lockfile) < time.time() - self.interval - 5: self.status = 'error' |
︙ | ︙ | |||
3414 3415 3416 3417 3418 3419 3420 | class StplParser(object): ''' Parser for stpl templates. ''' _re_cache = {} #: Cache for compiled re patterns # This huge pile of voodoo magic splits python code into 8 different tokens. # 1: All kinds of python strings (trust me, it works) | | | | | > | 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 | class StplParser(object): ''' Parser for stpl templates. ''' _re_cache = {} #: Cache for compiled re patterns # This huge pile of voodoo magic splits python code into 8 different tokens. # 1: All kinds of python strings (trust me, it works) _re_tok = '([urbURB]?(?:\'\'(?!\')|""(?!")|\'{6}|"{6}' \ '|\'(?:[^\\\\\']|\\\\.)+?\'|"(?:[^\\\\"]|\\\\.)+?"' \ '|\'{3}(?:[^\\\\]|\\\\.|\\n)+?\'{3}' \ '|"{3}(?:[^\\\\]|\\\\.|\\n)+?"{3}))' _re_inl = _re_tok.replace('|\\n','') # We re-use this string pattern later # 2: Comments (until end of line, but not the newline itself) _re_tok += '|(#.*)' # 3,4: Open and close grouping tokens _re_tok += '|([\\[\\{\\(])' _re_tok += '|([\\]\\}\\)])' # 5,6: Keywords that start or continue a python block (only start of line) _re_tok += '|^([ \\t]*(?:if|for|while|with|try|def|class)\\b)' \ '|^([ \\t]*(?:elif|else|except|finally)\\b)' # 7: Our special 'end' keyword (but only if it stands alone) _re_tok += '|((?:^|;)[ \\t]*end[ \\t]*(?=(?:%(block_close)s[ \\t]*)?\\r?$|;|#))' # 8: A customizable end-of-code-block template token (only end of line) _re_tok += '|(%(block_close)s[ \\t]*(?=\\r?$))' # 9: And finally, a single newline. The 10th token is 'everything else' _re_tok += '|(\\r?\\n)' # Match the start tokens of code areas in a template _re_split = '(?m)^[ \t]*(\\\\?)((%(line_start)s)|(%(block_start)s))(%%?)' # Match inline statements (may contain python strings) _re_inl = '(?m)%%(inline_start)s((?:%s|[^\'"\n]*?)+)%%(inline_end)s' % _re_inl _re_tok = '(?m)' + _re_tok default_syntax = '<% %> % {{ }}' def __init__(self, source, syntax=None, encoding='utf8'): self.source, self.encoding = touni(source, encoding), encoding self.set_syntax(syntax or self.default_syntax) self.code_buffer, self.text_buffer = [], [] |
︙ | ︙ |