##// END OF EJS Templates
hgweb: support constructing URLs from an alternate base URL...
hgweb: support constructing URLs from an alternate base URL The web.baseurl config option allows server operators to define a custom URL for hosted content. The way it works today is that hgwebdir parses this config option into URL components then updates the appropriate WSGI environment variables so the request "lies" about its details. For example, SERVER_NAME is updated to reflect the alternate base URL's hostname. The WSGI environment should not be modified because WSGI applications may want to know the original request details (for debugging, etc). This commit teaches our request parser about the existence of an alternate base URL. If defined, the advertised URL and other self-reflected paths will take the alternate base URL into account. The hgweb WSGI application didn't use web.baseurl. But hgwebdir did. We update hgwebdir to alter the environment parsing accordingly. The old code around environment manipulation has been removed. With this change, parserequestfromenv() has grown to a bit unwieldy. Now that practically everyone is using it, it is obvious that there is some unused features that can be trimmed. So look for this in follow-up commits. Differential Revision: https://phab.mercurial-scm.org/D2822

File last commit:

r36233:464bedc0 default
r36916:219b2335 default
Show More
sshprotoext.py
98 lines | 3.6 KiB | text/x-python | PythonLexer
Gregory Szorc
tests: add low-level SSH protocol tests...
r35948 # sshprotoext.py - Extension to test behavior of SSH protocol
#
# Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
# This extension replaces the SSH server started via `hg serve --stdio`.
# The server behaves differently depending on environment variables.
from __future__ import absolute_import
from mercurial import (
error,
Gregory Szorc
sshpeer: move handshake outside of sshpeer...
r35956 extensions,
Gregory Szorc
tests: add low-level SSH protocol tests...
r35948 registrar,
sshpeer,
wireproto,
wireprotoserver,
)
configtable = {}
configitem = registrar.configitem(configtable)
Gregory Szorc
py3: add b'' to config options in test extension...
r36229 configitem(b'sshpeer', b'mode', default=None)
configitem(b'sshpeer', b'handshake-mode', default=None)
Gregory Szorc
tests: add low-level SSH protocol tests...
r35948
class bannerserver(wireprotoserver.sshserver):
"""Server that sends a banner to stdout."""
def serve_forever(self):
for i in range(10):
self._fout.write(b'banner: line %d\n' % i)
super(bannerserver, self).serve_forever()
class prehelloserver(wireprotoserver.sshserver):
"""Tests behavior when connecting to <0.9.1 servers.
The ``hello`` wire protocol command was introduced in Mercurial
0.9.1. Modern clients send the ``hello`` command when connecting
to SSH servers. This mock server tests behavior of the handshake
when ``hello`` is not supported.
"""
def serve_forever(self):
l = self._fin.readline()
assert l == b'hello\n'
# Respond to unknown commands with an empty reply.
Gregory Szorc
wireprotoserver: extract SSH response handling functions...
r36081 wireprotoserver._sshv1respondbytes(self._fout, b'')
Gregory Szorc
tests: add low-level SSH protocol tests...
r35948 l = self._fin.readline()
assert l == b'between\n'
Gregory Szorc
wireprotoserver: move SSH server operation to a standalone function...
r36232 proto = wireprotoserver.sshv1protocolhandler(self._ui, self._fin,
self._fout)
rsp = wireproto.dispatch(self._repo, proto, b'between')
Gregory Szorc
wireproto: introduce type for raw byte responses (API)...
r36091 wireprotoserver._sshv1respondbytes(self._fout, rsp.data)
Gregory Szorc
tests: add low-level SSH protocol tests...
r35948
super(prehelloserver, self).serve_forever()
Gregory Szorc
sshpeer: move handshake outside of sshpeer...
r35956 def performhandshake(orig, ui, stdin, stdout, stderr):
"""Wrapped version of sshpeer._performhandshake to send extra commands."""
mode = ui.config(b'sshpeer', b'handshake-mode')
if mode == b'pre-no-args':
ui.debug(b'sending no-args command\n')
stdin.write(b'no-args\n')
stdin.flush()
return orig(ui, stdin, stdout, stderr)
elif mode == b'pre-multiple-no-args':
ui.debug(b'sending unknown1 command\n')
stdin.write(b'unknown1\n')
ui.debug(b'sending unknown2 command\n')
stdin.write(b'unknown2\n')
ui.debug(b'sending unknown3 command\n')
stdin.write(b'unknown3\n')
stdin.flush()
return orig(ui, stdin, stdout, stderr)
else:
raise error.ProgrammingError(b'unknown HANDSHAKECOMMANDMODE: %s' %
mode)
Gregory Szorc
tests: add low-level SSH protocol tests...
r35948
def extsetup(ui):
# It's easier for tests to define the server behavior via environment
# variables than config options. This is because `hg serve --stdio`
# has to be invoked with a certain form for security reasons and
# `dummyssh` can't just add `--config` flags to the command line.
servermode = ui.environ.get(b'SSHSERVERMODE')
if servermode == b'banner':
wireprotoserver.sshserver = bannerserver
elif servermode == b'no-hello':
wireprotoserver.sshserver = prehelloserver
elif servermode:
raise error.ProgrammingError(b'unknown server mode: %s' % servermode)
peermode = ui.config(b'sshpeer', b'mode')
if peermode == b'extra-handshake-commands':
Gregory Szorc
sshpeer: move handshake outside of sshpeer...
r35956 extensions.wrapfunction(sshpeer, '_performhandshake', performhandshake)
Gregory Szorc
tests: add low-level SSH protocol tests...
r35948 elif peermode:
raise error.ProgrammingError(b'unknown peer mode: %s' % peermode)