605 if v is not None: |
605 if v is not None: |
606 return v |
606 return v |
607 |
607 |
608 return ui.configbool('server', 'bundle1', True) |
608 return ui.configbool('server', 'bundle1', True) |
609 |
609 |
|
610 def supportedcompengines(ui, proto, role): |
|
611 """Obtain the list of supported compression engines for a request.""" |
|
612 assert role in (util.CLIENTROLE, util.SERVERROLE) |
|
613 |
|
614 compengines = util.compengines.supportedwireengines(role) |
|
615 |
|
616 # Allow config to override default list and ordering. |
|
617 if role == util.SERVERROLE: |
|
618 configengines = ui.configlist('server', 'compressionengines') |
|
619 config = 'server.compressionengines' |
|
620 else: |
|
621 # This is currently implemented mainly to facilitate testing. In most |
|
622 # cases, the server should be in charge of choosing a compression engine |
|
623 # because a server has the most to lose from a sub-optimal choice. (e.g. |
|
624 # CPU DoS due to an expensive engine or a network DoS due to poor |
|
625 # compression ratio). |
|
626 configengines = ui.configlist('experimental', |
|
627 'clientcompressionengines') |
|
628 config = 'experimental.clientcompressionengines' |
|
629 |
|
630 # No explicit config. Filter out the ones that aren't supposed to be |
|
631 # advertised and return default ordering. |
|
632 if not configengines: |
|
633 attr = 'serverpriority' if role == util.SERVERROLE else 'clientpriority' |
|
634 return [e for e in compengines |
|
635 if getattr(e.wireprotosupport(), attr) > 0] |
|
636 |
|
637 # If compression engines are listed in the config, assume there is a good |
|
638 # reason for it (like server operators wanting to achieve specific |
|
639 # performance characteristics). So fail fast if the config references |
|
640 # unusable compression engines. |
|
641 validnames = set(e.name() for e in compengines) |
|
642 invalidnames = set(e for e in configengines if e not in validnames) |
|
643 if invalidnames: |
|
644 raise error.Abort(_('invalid compression engine defined in %s: %s') % |
|
645 (config, ', '.join(sorted(invalidnames)))) |
|
646 |
|
647 compengines = [e for e in compengines if e.name() in configengines] |
|
648 compengines = sorted(compengines, |
|
649 key=lambda e: configengines.index(e.name())) |
|
650 |
|
651 if not compengines: |
|
652 raise error.Abort(_('%s config option does not specify any known ' |
|
653 'compression engines') % config, |
|
654 hint=_('usable compression engines: %s') % |
|
655 ', '.sorted(validnames)) |
|
656 |
|
657 return compengines |
|
658 |
610 # list of commands |
659 # list of commands |
611 commands = {} |
660 commands = {} |
612 |
661 |
613 def wireprotocommand(name, args=''): |
662 def wireprotocommand(name, args=''): |
614 """decorator for wire protocol command""" |
663 """decorator for wire protocol command""" |
720 if proto.name == 'http': |
769 if proto.name == 'http': |
721 caps.append('httpheader=%d' % |
770 caps.append('httpheader=%d' % |
722 repo.ui.configint('server', 'maxhttpheaderlen', 1024)) |
771 repo.ui.configint('server', 'maxhttpheaderlen', 1024)) |
723 if repo.ui.configbool('experimental', 'httppostargs', False): |
772 if repo.ui.configbool('experimental', 'httppostargs', False): |
724 caps.append('httppostargs') |
773 caps.append('httppostargs') |
|
774 |
|
775 # FUTURE advertise 0.2rx once support is implemented |
|
776 # FUTURE advertise minrx and mintx after consulting config option |
|
777 caps.append('httpmediatype=0.1rx,0.1tx,0.2tx') |
|
778 |
|
779 compengines = supportedcompengines(repo.ui, proto, util.SERVERROLE) |
|
780 if compengines: |
|
781 comptypes = ','.join(urlreq.quote(e.wireprotosupport().name) |
|
782 for e in compengines) |
|
783 caps.append('compression=%s' % comptypes) |
725 |
784 |
726 return caps |
785 return caps |
727 |
786 |
728 # If you are writing an extension and consider wrapping this function. Wrap |
787 # If you are writing an extension and consider wrapping this function. Wrap |
729 # `_capabilities` instead. |
788 # `_capabilities` instead. |