Werkzeug: Werkzeug рдорд▓реНрдЯреАрд▓рд╛рдЗрди рд╣реЗрдбрд░ рдХреЛ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рд╣реИрдВрдбрд▓ рдХрд░рддрд╛ рд╣реИ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 10 рдорд╛рд░реНрдЪ 2017  ┬╖  8рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: pallets/werkzeug

рдЖрд░рдПрдлрд╕реА 2616 рдХреЗ рдЕрдиреБрд╕рд╛рд░:

рдпрджрд┐ рдирд┐рд░рдВрддрд░рддрд╛ рд░реЗрдЦрд╛ рдХрд┐рд╕реА рд╕реНрдерд╛рди рдпрд╛ рдХреНрд╖реИрддрд┐рдЬ рдЯреИрдм рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ, рддреЛ HTTP/1.1 рд╢реАрд░реНрд╖рд▓реЗрдЦ рдлрд╝реАрд▓реНрдб рдорд╛рдиреЛрдВ рдХреЛ рдПрдХрд╛рдзрд┐рдХ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдореЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рддрд╣ рд╕рд╣рд┐рдд рд╕рднреА рд░реИрдЦрд┐рдХ рд╕рдлреЗрдж рд╕реНрдерд╛рди рдореЗрдВ рдПрд╕рдкреА рдХреЗ рд╕рдорд╛рди рдЕрд░реНрдерд╢рд╛рд╕реНрддреНрд░ рд╣реИред рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рдлрд╝реАрд▓реНрдб рдорд╛рди рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рдиреЗ рдпрд╛ рд╕рдВрджреЗрд╢ рдХреЛ рдбрд╛рдЙрдирд╕реНрдЯреНрд░реАрдо рдореЗрдВ рдЕрдЧреНрд░реЗрд╖рд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐рд╕реА рднреА рд░реИрдЦрд┐рдХ рд╕рдлреЗрдж рд╕реНрдерд╛рди рдХреЛ рдПрдХрд▓ SP рд╕реЗ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИред

рд╣рд╛рд▓рд╛рдВрдХрд┐, Werkzeug рд╣реЗрдбрд░ рд╡реИрд▓реНрдпреВ рдХреЛ рдиреНрдпреВрд▓рд╛рдЗрдиреНрд╕ рдХреЗ рд╕рд╛рде рд╕реНрд╡реАрдХрд╛рд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рд╡реЗ рдЗрд╕ рдХрдиреНрд╡реЗрдВрд╢рди рдХрд╛ рдкрд╛рд▓рди рдХрд░рддреЗ рд╣реЛрдВред

>>> import werkzeug
>>> werkzeug.Headers().add('foo', 'bar\n baz')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../venv/local/lib/python2.7/site-packages/werkzeug/datastructures.py", line 1136, in add
    self._validate_value(_value)
  File ".../venv/local/lib/python2.7/site-packages/werkzeug/datastructures.py", line 1143, in _validate_value
    raise ValueError('Detected newline in header value.  This is '
ValueError: Detected newline in header value.  This is a potential security problem

рд╕рд╛рде рд╣реА, рдпрд╣ рдкреНрд░рддрд┐рдмрдВрдз рдЕрд╕рдВрдЧрдд рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред

>>> werkzeug.Headers([('foo', 'bar\n baz')])
Headers([('foo', 'bar\n baz')])

рд╣реЗрдбрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдкреНрд░рдорд╛рдгрдкрддреНрд░реЛрдВ рдХреЗ nginx рдЕрдЧреНрд░реЗрд╖рдг рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╕рдордп рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдореЗрдВ рднрд╛рдЧ рдЧрдпрд╛, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдареАрдХ рд╕реЗ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрдкрдпреЛрдЧ рдХреЗрд╕ рд╣реИред

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

@davidism рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд┐рдЫрд▓реА рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣рд╛рдВ рджреЛ рдмрдЧ рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рд╡рд░реНрддрдорд╛рди рдорд╛рд╕реНрдЯрд░ рд╢рд╛рдЦрд╛ рдкрд░ рддрдп рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рдкрд╣рд▓реА рдмрдЧ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рд╡рд░реНрдХрдЬрд╝реЗрдЧ рдбреЗрд╡рд▓рдкрдореЗрдВрдЯ рд╕рд░реНрд╡рд░ рд▓рд╛рдЗрди-рд░реИрдкреНрдб рд╣реЗрдбрд░ рдХреЛ рд╣реИрдВрдбрд▓ рдХрд░рддрд╛ рд╣реИред рдЗрд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд░реНрд╡рд░ рдХреЛрдб рдХреЗ рд╕рд╛рде рдкреБрди: рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ X-Example рд╣реЗрдбрд░ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдкреНрд░рд┐рдВрдЯ рдХрд░рддрд╛ рд╣реИ:

from werkzeug.serving import run_simple
from werkzeug.wrappers import Request, Response

def app(environ, start_response):
    request = Request(environ)
    print(repr(request.headers.get('X-Example')))
    response = Response(status=204)
    return response(environ, start_response)

run_simple('localhost', 8080, app)

рдлрд┐рд░ рд╣рдо рдЗрд╕реЗ рдХрдИ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдлреИрд▓реЗ рд╣реЗрдбрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдиреБрд░реЛрдз рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВ:

GET / HTTP/1.1
Host: localhost:8080
Connection: close
X-Example: foo
 bar

рдЕрдкреЗрдХреНрд╖рд┐рдд рд╕рд░реНрд╡рд░ рдЖрдЙрдЯрдкреБрдЯ:
рд╣реИрдбрд░ рд╡реИрд▓реНрдпреВ рдХреЛ рдПрдХ рд▓рд╛рдЗрди рдореЗрдВ рдорд░реНрдЬ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ

'foo bar'

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рд░реНрд╡рд░ рдЖрдЙрдЯрдкреБрдЯ (рдкрд╛рдпрдерди 2):

----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 57361)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 649, in __init__
    self.handle()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 320, in handle
    rv = BaseHTTPRequestHandler.handle(self)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 355, in handle_one_request
    return self.run_wsgi()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 238, in run_wsgi
    self.environ = environ = self.make_environ()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 217, in make_environ
    for key, value in self.get_header_items():
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 441, in get_header_items
    key, value = header[0:-2].split(":", 1)
ValueError: need more than 1 value to unpack
----------------------------------------

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рд░реНрд╡рд░ рдЖрдЙрдЯрдкреБрдЯ (рдкрд╛рдпрдерди 3):
рд╢реАрд░реНрд╖рд▓реЗрдЦ рдорд╛рди рдореЗрдВ WSGI рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рджреНрд╡рд╛рд░рд╛ рдЕрд╕реНрд╡реАрдХреГрдд рдиреНрдпреВрд▓рд╛рдЗрди рд╡рд░реНрдг рд╢рд╛рдорд┐рд▓ рд╣реИрдВ

'foo\r\n bar'

рджреВрд╕рд░рд╛ рдмрдЧ рдпрд╣ рд╣реИ рдХрд┐ рдХреИрд╕реЗ Headers рдСрдмреНрдЬреЗрдХреНрдЯ рдиреНрдпреВрд▓рд╛рдЗрди рдорд╛рдиреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред

>>> from werkzeug import Headers
>>> h1 = Headers([('X-Example', 'foo\r\n bar')])
>>> h2 = Headers()
>>> h2.add('X-Example', 'foo\r\n bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/.../venv3/lib/python3.6/site-packages/werkzeug/datastructures.py", line 1166, in add
    self._validate_value(_value)
  File "/home/.../venv3/lib/python3.6/site-packages/werkzeug/datastructures.py", line 1173, in _validate_value
    raise ValueError('Detected newline in header value.  This is '
ValueError: Detected newline in header value.  This is a potential security problem

рдЕрдкреЗрдХреНрд╖рд┐рдд рдкрд░рд┐рдгрд╛рдо:
рджреЛрдиреЛрдВ рдСрдкрд░реЗрд╢рдиреЛрдВ рдХрд╛ рдПрдХ рд╣реА рдкрд░рд┐рдгрд╛рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЪрд╛рд╣реЗ рд╡рд╣ ValueError рдпрд╛ рд╕рдлрд▓рддрд╛ред

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдгрд╛рдо:
Headers рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдиреНрдпреВрд▓рд╛рдЗрди рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬрдмрдХрд┐ Headers.add() ValueError рдмрдврд╝рд╛рддрд╛ рд╣реИред

рд╕рднреА 8 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

HTTP рд╢реАрд░реНрд╖рд▓реЗрдЦ рдиреНрдпреВрд▓рд╛рдЗрди рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВред рдЖрдк рдЬрд┐рд╕ рдЦрдВрдб рдХреЛ рдЙрджреНрдзреГрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рд╡рд╣ рддрд╣ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╕рд╛рдордиреЗ рд╡рд╛рд▓реЗ рдореВрд▓реНрдп рд╕реЗ рдирдИ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╣рдЯрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣:

"""foo
     bar"""

рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдкреНрд░рдХрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:

"foo bar"

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, Werkzeug рдЗрд╕ рд╕реНрддрд░ рдкрд░ HTTP рдХреЛ рдкрд╛рд░реНрд╕ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ WSGI рд╕рд░реНрд╡рд░ рдХрд╛ рдХрд╛рдо рд╣реИред рд╕реБрд░рдХреНрд╖рд╛ рдореБрджреНрджреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рд╕рдордп рдпрд╣ рдиреНрдпреВрд▓рд╛рдЗрди рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рдХрд╛рд░рдг рд╣реИред

рдпрд╣ рдЯрд┐рдХрдЯ nginx рдкреНрд░реЙрдХреНрд╕реА рдлрд╝реЙрд░рд╡рд░реНрдбрд┐рдВрдЧ рдХреНрд▓рд╛рдЗрдВрдЯ рдкреНрд░рдорд╛рдгрдкрддреНрд░реЛрдВ рдХреЗ рдкреАрдЫреЗ рд╡рд┐рдХрд╛рд╕ рдореЛрдб рдореЗрдВ рдлреНрд▓рд╛рд╕реНрдХ рдХреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди рд╡реНрдпрд╡рд╣рд╛рд░ рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рдерд╛ред рдЙрд╕ рд╕реЗрдЯрдЕрдк рдХреЗ рд╕рд╛рде, рдореИрдВрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдкрд╛рд╕ рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рд╣реЗрдбрд░ рдореЗрдВ рдиреНрдпреВрд▓рд╛рдЗрдиреНрд╕ рджреЗрдЦреАрдВред рд▓реЗрдХрд┐рди рдЬрдм рдореИрдВрдиреЗ рдЗрд╕реЗ рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯ рдореЗрдВ рджреЛрд╣рд░рд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рддреЛ рдореБрдЭреЗ рдЕрдиреБрд░реЛрдз рд╣реЗрдбрд░ рдмрдирд╛рддреЗ рд╕рдордп рдЙрдкрд░реЛрдХреНрдд ValueError рдорд┐рд▓рд╛ред

рдореИрдВрдиреЗ рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рдереЛрдбрд╝рд╛ рдФрд░ рд╢реЛрдз рдХрд┐рдпрд╛ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд╛рдпрд╛:

  • HTTP рдпреБрдХреНрддрд┐ ( RFC 2616 ) рдореЗрдВ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рд╢реАрд░реНрд╖рд▓реЗрдЦреЛрдВ рдореЗрдВ рдирдИ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдПрдХ рд╣реА рд╕реНрдерд╛рди рд╕реЗ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдирд╣реАрдВ рдХрд┐ рдЙрдирдХреЗ рд╣реЛрдиреЗ рдХреА рдЧрд╛рд░рдВрдЯреА рд╣реИ (рдКрдкрд░ рдЙрджреНрдзрд░рдг рджреЗрдЦреЗрдВ)ред

  • рд╕реАрдЬреАрдЖрдИ рд╕реНрдкреЗрдХ ( рдЖрд░рдПрдлрд╕реА 3875 ), рдЬрд┐рд╕реЗ рдбрдмреНрд▓реВрдПрд╕рдЬреАрдЖрдИ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рд╢реАрд░реНрд╖рд▓реЗрдЦреЛрдВ рдореЗрдВ рдирдИ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ:

    рдЗрд╕реА рддрд░рд╣, рдПрдХ рд╣реЗрдбрд░ рдлрд╝реАрд▓реНрдб рдЬреЛ рдХрдИ рдкрдВрдХреНрддрд┐рдпреЛрдВ рддрдХ рдлреИрд▓реА рд╣реБрдИ рд╣реИ, рдЙрд╕реЗ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдорд░реНрдЬ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

  • WSGI рдпреБрдХреНрддрд┐ ( PEP рейрейрей ) рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╢реАрд░реНрд╖рд▓реЗрдЦреЛрдВ рдореЗрдВ рдирдИ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рднреА рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рддреА рд╣реИ:

    рдкреНрд░рддреНрдпреЗрдХ header_value рдореЗрдВ рдХреЛрдИ рднреА рдирд┐рдпрдВрддреНрд░рдг рд╡рд░реНрдг рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд┐рд╕рдореЗрдВ рдХреИрд░рд┐рдЬ рд░рд┐рдЯрд░реНрди рдпрд╛ рд▓рд╛рдЗрдирдлрд╝реАрдб рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдпрд╛ рддреЛ рдПрдореНрдмреЗрдбреЗрдб рдпрд╛ рдЕрдВрдд рдореЗрдВред

рддреЛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рджреЛ рдмрдЧ рд╣реИрдВ:

  • Werkzeug рд╡рд┐рдХрд╛рд╕ рд╕рд░реНрд╡рд░ рдЕрдиреБрд░реЛрдз рд╢реАрд░реНрд╖рд▓реЗрдЦреЛрдВ рдореЗрдВ рдлрд╝реЛрд▓реНрдб рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

  • Headers рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реЗрдбрд░ рдорд╛рдиреЛрдВ рдореЗрдВ рдиреНрдпреВрд▓рд╛рдЗрди рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрд╕рдВрдЧрдд рд╣реИред рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдирдИ рд▓рд╛рдЗрдиреЗрдВ рд╕реНрд╡реАрдХрд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИрдВ, рд▓реЗрдХрд┐рди add() рдкрджреНрдзрддрд┐ рдореЗрдВ рдирд╣реАрдВред рдпрд╣ рд╢рд╛рдпрдж рдХреЗ рд▓рд┐рдП рдмреЗрд╣рддрд░ рд╣реИ Headers рд╡рд╕реНрддреБ рдЕрдиреБрдореЛрджрдХ рдмрдиреА рд░рд╣рддреА рд╣реИ рдФрд░ рдЬрдм рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореЗрдВ WSGI рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рд╕рддреНрдпрд╛рдкрди рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП BaseResponse ред рдЗрд╕ рддрд░рд╣ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдиреНрдпреВрд▓рд╛рдЗрдиреНрд╕ рдХреЛ рдордирд╛ рдХрд░рдиреЗ рд╕реЗ рд╕рдВрднрд╡рддрдГ рдЧреИрд░-рдЕрдиреБрд░реВрдк WSGI рд╕рд░реНрд╡рд░ (рдЬреИрд╕реЗ рдХрд┐ Werkzeug рдХрд╛ рдЕрдкрдирд╛ рдбреЗрд╡рд▓рдкрдореЗрдВрдЯ рд╕рд░реНрд╡рд░) рдХреЗ рд╕рд╛рде рд╕рдВрдЧрддрддрд╛ рдирд╣реАрдВ рдЯреВрдЯреЗрдЧреАред

рдХрд╛рдлреА рдЙрдЪрд┐рддред рдЗрд╕рдореЗрдВ #1070 рднреА рд╣реИ рдЬреЛ рдЗрд╕рдореЗрдВ рдЦреЗрд▓рддрд╛ рд╣реИред

рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдпрд╣ #1070 рдХреЗ рд▓рд┐рдП рдлрд┐рдХреНрд╕ рдХреЗ рд╕рд╛рде рддрдп рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдПрдХ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдмрддрд╛рдПрдВред

@davidism рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд┐рдЫрд▓реА рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣рд╛рдВ рджреЛ рдмрдЧ рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рд╡рд░реНрддрдорд╛рди рдорд╛рд╕реНрдЯрд░ рд╢рд╛рдЦрд╛ рдкрд░ рддрдп рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рдкрд╣рд▓реА рдмрдЧ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рд╡рд░реНрдХрдЬрд╝реЗрдЧ рдбреЗрд╡рд▓рдкрдореЗрдВрдЯ рд╕рд░реНрд╡рд░ рд▓рд╛рдЗрди-рд░реИрдкреНрдб рд╣реЗрдбрд░ рдХреЛ рд╣реИрдВрдбрд▓ рдХрд░рддрд╛ рд╣реИред рдЗрд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд░реНрд╡рд░ рдХреЛрдб рдХреЗ рд╕рд╛рде рдкреБрди: рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ X-Example рд╣реЗрдбрд░ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдкреНрд░рд┐рдВрдЯ рдХрд░рддрд╛ рд╣реИ:

from werkzeug.serving import run_simple
from werkzeug.wrappers import Request, Response

def app(environ, start_response):
    request = Request(environ)
    print(repr(request.headers.get('X-Example')))
    response = Response(status=204)
    return response(environ, start_response)

run_simple('localhost', 8080, app)

рдлрд┐рд░ рд╣рдо рдЗрд╕реЗ рдХрдИ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдлреИрд▓реЗ рд╣реЗрдбрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдиреБрд░реЛрдз рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВ:

GET / HTTP/1.1
Host: localhost:8080
Connection: close
X-Example: foo
 bar

рдЕрдкреЗрдХреНрд╖рд┐рдд рд╕рд░реНрд╡рд░ рдЖрдЙрдЯрдкреБрдЯ:
рд╣реИрдбрд░ рд╡реИрд▓реНрдпреВ рдХреЛ рдПрдХ рд▓рд╛рдЗрди рдореЗрдВ рдорд░реНрдЬ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ

'foo bar'

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рд░реНрд╡рд░ рдЖрдЙрдЯрдкреБрдЯ (рдкрд╛рдпрдерди 2):

----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 57361)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 649, in __init__
    self.handle()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 320, in handle
    rv = BaseHTTPRequestHandler.handle(self)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 355, in handle_one_request
    return self.run_wsgi()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 238, in run_wsgi
    self.environ = environ = self.make_environ()
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 217, in make_environ
    for key, value in self.get_header_items():
  File "/home/.../venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 441, in get_header_items
    key, value = header[0:-2].split(":", 1)
ValueError: need more than 1 value to unpack
----------------------------------------

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рд░реНрд╡рд░ рдЖрдЙрдЯрдкреБрдЯ (рдкрд╛рдпрдерди 3):
рд╢реАрд░реНрд╖рд▓реЗрдЦ рдорд╛рди рдореЗрдВ WSGI рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рджреНрд╡рд╛рд░рд╛ рдЕрд╕реНрд╡реАрдХреГрдд рдиреНрдпреВрд▓рд╛рдЗрди рд╡рд░реНрдг рд╢рд╛рдорд┐рд▓ рд╣реИрдВ

'foo\r\n bar'

рджреВрд╕рд░рд╛ рдмрдЧ рдпрд╣ рд╣реИ рдХрд┐ рдХреИрд╕реЗ Headers рдСрдмреНрдЬреЗрдХреНрдЯ рдиреНрдпреВрд▓рд╛рдЗрди рдорд╛рдиреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред

>>> from werkzeug import Headers
>>> h1 = Headers([('X-Example', 'foo\r\n bar')])
>>> h2 = Headers()
>>> h2.add('X-Example', 'foo\r\n bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/.../venv3/lib/python3.6/site-packages/werkzeug/datastructures.py", line 1166, in add
    self._validate_value(_value)
  File "/home/.../venv3/lib/python3.6/site-packages/werkzeug/datastructures.py", line 1173, in _validate_value
    raise ValueError('Detected newline in header value.  This is '
ValueError: Detected newline in header value.  This is a potential security problem

рдЕрдкреЗрдХреНрд╖рд┐рдд рдкрд░рд┐рдгрд╛рдо:
рджреЛрдиреЛрдВ рдСрдкрд░реЗрд╢рдиреЛрдВ рдХрд╛ рдПрдХ рд╣реА рдкрд░рд┐рдгрд╛рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЪрд╛рд╣реЗ рд╡рд╣ ValueError рдпрд╛ рд╕рдлрд▓рддрд╛ред

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдгрд╛рдо:
Headers рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдиреНрдпреВрд▓рд╛рдЗрди рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬрдмрдХрд┐ Headers.add() ValueError рдмрдврд╝рд╛рддрд╛ рд╣реИред

рдореИрдВ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рд╣рдорд╛рд░реА рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ ValueError рджреЗрдЦ рд░рд╣рд╛ рдерд╛ (рдкрд╛рдпрдерди 2.7 рдлреНрд▓рд╛рд╕реНрдХ рдХреЗ рд╕рд╛рде) рдЬреЛ рдПрдХ nginx рдкреНрд░реЙрдХреНрд╕реА рдХреЗ рдкреАрдЫреЗ рдмреИрдардиреЗ рдХреЗ рд▓рд┐рдП рд╣реЛрддрд╛ рд╣реИред рдореИрдВрдиреЗ 0.14.1 рд╡рд╛рдкрд╕ рд▓реМрдЯрдирд╛ рд╕рдорд╛рдкреНрдд рдХрд░ рджрд┐рдпрд╛ ( Flask рд╕рд╛рде рдмрдВрдбрд▓ рдХрд┐рдП рдЧрдП рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдирд╛) рдФрд░ рдореЗрд░реА рддреНрд░реБрдЯрд┐ рджреВрд░ рд╣реЛ рдЧрдИред рд╕реЛрдЪрд╛ рдерд╛ рдХрд┐ рдореИрдВ рдЬреЛрдбрд╝реВрдВрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ 0.15.x рд╢рд╛рдЦрд╛ рдиреЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдкреЗрд╢ рдХрд┐рдпрд╛ (рдпрд╛ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдЕрдиреБрд░реЛрдз рд╣реЗрдбрд░ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рд╕рд╛рде рдПрдХ рдирдИ рд╕рдорд╕реНрдпрд╛ рдмрдирд╛рдИ)ред

------рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ-------:

рдореИрдВрдиреЗ рдЯреНрд░реИрдХ рдХрд┐рдпрд╛ рдХрд┐ рд╣рдо рдХреМрди рд╕реЗ рд╣реЗрдбрд░ рдкрд╛рд╕ рдХрд░ рд░рд╣реЗ рдереЗ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдкреАрдИрдПрдо рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдПрдХ рдмрд╣реБ-рдкрдВрдХреНрддрд┐ рдкреНрд░рдорд╛рдг рдкрддреНрд░ рдерд╛ рдпрд╛рдиреА:

SSL_CLIENT_CERT: -----BEGIN CERTIFICATE-----
    MIIFHzCCAwegAwIBAgICEDgwDQYJKoZIhvcNAQELBQAwajELMAkGA1UEBhMCdXMx
    GDAWBgNVBAoMD3Uucy4gZ292ZXJubWVudDEPMA0GA1UECwwGcGVvcGxlMQwwCgYD
    VQQLDANkYWUxEDAOBgNVBAsMB2NoaW1lcmExEDAOBgNVBAMMB0ludGVyQ0EwHhcN
    MTcwODMxMTUwMzEwWhcNMjcwODI5MTUwMzEwWjBwMQswCQYDVQQGEwJVUzEYMBYG
    A1UECgwPVS5TLiBHb3Zlcm5tZW50MRAwDgYDVQQLDAdjaGltZXJhMQwwCgYDVQQL
    ....  
    -----END CERTIFICATE-----

рд╣рдорд╛рд░рд╛ nginx рд╕рд░реНрд╡рд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:

proxy_set_header SSL_CLIENT_CERT $ssl_client_cert;

рд╣рдо рд╢рд╛рдпрдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП $ssl_client_escaped_cert рдХреЗ рдмрдЬрд╛рдп $ssl_client_cert (рдХреЗ рдмрд╛рдж рд╕реЗ рдЗрд╕ рд╡реИрд╕реЗ рднреА рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ)ред рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрди рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╣реЗрдбрд░ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдареАрдХ рдХрд░реЗрдЧрд╛ред

рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдФрд░ рдХреА рдорджрдж рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдореЗрдВ рдЪрд▓ рд░рд╣рд╛ рд╣реИред рдРрд╕рд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ рдХрд┐ 0.15.1 рдЗрд╕ рд╕рдордп Python 2.7 рдХреЗ рд╕рд╛рде PEM рд╕рд░реНрдЯрд┐рдлрд┐рдХреЗрдЯ рдЬреИрд╕реЗ рдорд▓реНрдЯреА-рд▓рд╛рдЗрди рд╣реЗрдбрд░ рдХреЛ рдареАрдХ рд╕реЗ рд╣реИрдВрдбрд▓ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдпрд╣ рдПрдХ 2.7 рдореБрджреНрджрд╛ рд╣реИ рдЬреЛ рдлрд┐рд░ рд╕реЗ рд╡рд┐рдХрд╛рд╕ рд╕рд░реНрд╡рд░ рдХреЗ рд╣реЗрдбрд░ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рдХрд╛рд░рдг рд╣реЛрддрд╛ рд╣реИред рдореИрдВ рдЕрдиреБрд░реЛрдз рд╢реАрд░реНрд╖рд▓реЗрдЦреЛрдВ рдХреЗ рд▓рд┐рдП 2.7 рд╕рдВрдЧрддрддрд╛ рдХреЛрдб рдореЗрдВ рд╣реЗрдбрд░ рдХреЗ рдлреЛрд▓реНрдбрд┐рдВрдЧ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝ рд░рд╣рд╛ рд╣реВрдВред

рдкреБрд╖реНрдЯрд┐ рдХреА рд╣реИ рдХрд┐ рд╡рд┐рдХрд╛рд╕ рд╕рд░реНрд╡рд░ рдмрдЧ рдЕрдм рдкрд╛рдпрдерди 2 рдФрд░ 3 рджреЛрдиреЛрдВ рдореЗрдВ рддрдп рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред Headers рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рджреВрд╕рд░рд╛ рдореБрджреНрджрд╛ рдЕрднреА рднреА рдореМрдЬреВрдж рд╣реИред #1608 рдЦреЛрд▓рд╛ рдЧрдпрд╛ред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

SimonSapin picture SimonSapin  ┬╖  12рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

masklinn picture masklinn  ┬╖  11рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

mhelmetag picture mhelmetag  ┬╖  8рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

alexgurrola picture alexgurrola  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

asottile picture asottile  ┬╖  11рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ