##// END OF EJS Templates
configitems: register the 'server.zliblevel' config
marmoute -
r33225:35c23397 default
parent child Browse files
Show More
@@ -1,151 +1,154
1 # configitems.py - centralized declaration of configuration option
1 # configitems.py - centralized declaration of configuration option
2 #
2 #
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import functools
10 import functools
11
11
12 from . import (
12 from . import (
13 error,
13 error,
14 )
14 )
15
15
16 def loadconfigtable(ui, extname, configtable):
16 def loadconfigtable(ui, extname, configtable):
17 """update config item known to the ui with the extension ones"""
17 """update config item known to the ui with the extension ones"""
18 for section, items in configtable.items():
18 for section, items in configtable.items():
19 knownitems = ui._knownconfig.setdefault(section, {})
19 knownitems = ui._knownconfig.setdefault(section, {})
20 knownkeys = set(knownitems)
20 knownkeys = set(knownitems)
21 newkeys = set(items)
21 newkeys = set(items)
22 for key in sorted(knownkeys & newkeys):
22 for key in sorted(knownkeys & newkeys):
23 msg = "extension '%s' overwrite config item '%s.%s'"
23 msg = "extension '%s' overwrite config item '%s.%s'"
24 msg %= (extname, section, key)
24 msg %= (extname, section, key)
25 ui.develwarn(msg, config='warn-config')
25 ui.develwarn(msg, config='warn-config')
26
26
27 knownitems.update(items)
27 knownitems.update(items)
28
28
29 class configitem(object):
29 class configitem(object):
30 """represent a known config item
30 """represent a known config item
31
31
32 :section: the official config section where to find this item,
32 :section: the official config section where to find this item,
33 :name: the official name within the section,
33 :name: the official name within the section,
34 :default: default value for this item,
34 :default: default value for this item,
35 """
35 """
36
36
37 def __init__(self, section, name, default=None):
37 def __init__(self, section, name, default=None):
38 self.section = section
38 self.section = section
39 self.name = name
39 self.name = name
40 self.default = default
40 self.default = default
41
41
42 coreitems = {}
42 coreitems = {}
43
43
44 def _register(configtable, *args, **kwargs):
44 def _register(configtable, *args, **kwargs):
45 item = configitem(*args, **kwargs)
45 item = configitem(*args, **kwargs)
46 section = configtable.setdefault(item.section, {})
46 section = configtable.setdefault(item.section, {})
47 if item.name in section:
47 if item.name in section:
48 msg = "duplicated config item registration for '%s.%s'"
48 msg = "duplicated config item registration for '%s.%s'"
49 raise error.ProgrammingError(msg % (item.section, item.name))
49 raise error.ProgrammingError(msg % (item.section, item.name))
50 section[item.name] = item
50 section[item.name] = item
51
51
52 # Registering actual config items
52 # Registering actual config items
53
53
54 def getitemregister(configtable):
54 def getitemregister(configtable):
55 return functools.partial(_register, configtable)
55 return functools.partial(_register, configtable)
56
56
57 coreconfigitem = getitemregister(coreitems)
57 coreconfigitem = getitemregister(coreitems)
58
58
59 coreconfigitem('auth', 'cookiefile',
59 coreconfigitem('auth', 'cookiefile',
60 default=None,
60 default=None,
61 )
61 )
62 # bookmarks.pushing: internal hack for discovery
62 # bookmarks.pushing: internal hack for discovery
63 coreconfigitem('bookmarks', 'pushing',
63 coreconfigitem('bookmarks', 'pushing',
64 default=list,
64 default=list,
65 )
65 )
66 # bundle.mainreporoot: internal hack for bundlerepo
66 # bundle.mainreporoot: internal hack for bundlerepo
67 coreconfigitem('bundle', 'mainreporoot',
67 coreconfigitem('bundle', 'mainreporoot',
68 default='',
68 default='',
69 )
69 )
70 # bundle.reorder: experimental config
70 # bundle.reorder: experimental config
71 coreconfigitem('bundle', 'reorder',
71 coreconfigitem('bundle', 'reorder',
72 default='auto',
72 default='auto',
73 )
73 )
74 coreconfigitem('color', 'mode',
74 coreconfigitem('color', 'mode',
75 default='auto',
75 default='auto',
76 )
76 )
77 coreconfigitem('devel', 'all-warnings',
77 coreconfigitem('devel', 'all-warnings',
78 default=False,
78 default=False,
79 )
79 )
80 coreconfigitem('devel', 'bundle2.debug',
80 coreconfigitem('devel', 'bundle2.debug',
81 default=False,
81 default=False,
82 )
82 )
83 coreconfigitem('devel', 'check-locks',
83 coreconfigitem('devel', 'check-locks',
84 default=False,
84 default=False,
85 )
85 )
86 coreconfigitem('devel', 'check-relroot',
86 coreconfigitem('devel', 'check-relroot',
87 default=False,
87 default=False,
88 )
88 )
89 coreconfigitem('devel', 'disableloaddefaultcerts',
89 coreconfigitem('devel', 'disableloaddefaultcerts',
90 default=False,
90 default=False,
91 )
91 )
92 coreconfigitem('devel', 'legacy.exchange',
92 coreconfigitem('devel', 'legacy.exchange',
93 default=list,
93 default=list,
94 )
94 )
95 coreconfigitem('devel', 'servercafile',
95 coreconfigitem('devel', 'servercafile',
96 default='',
96 default='',
97 )
97 )
98 coreconfigitem('devel', 'serverexactprotocol',
98 coreconfigitem('devel', 'serverexactprotocol',
99 default='',
99 default='',
100 )
100 )
101 coreconfigitem('devel', 'serverrequirecert',
101 coreconfigitem('devel', 'serverrequirecert',
102 default=False,
102 default=False,
103 )
103 )
104 coreconfigitem('devel', 'strip-obsmarkers',
104 coreconfigitem('devel', 'strip-obsmarkers',
105 default=True,
105 default=True,
106 )
106 )
107 coreconfigitem('hostsecurity', 'ciphers',
107 coreconfigitem('hostsecurity', 'ciphers',
108 default=None,
108 default=None,
109 )
109 )
110 coreconfigitem('hostsecurity', 'disabletls10warning',
110 coreconfigitem('hostsecurity', 'disabletls10warning',
111 default=False,
111 default=False,
112 )
112 )
113 coreconfigitem('patch', 'fuzz',
113 coreconfigitem('patch', 'fuzz',
114 default=2,
114 default=2,
115 )
115 )
116 coreconfigitem('server', 'bundle1',
116 coreconfigitem('server', 'bundle1',
117 default=True,
117 default=True,
118 )
118 )
119 coreconfigitem('server', 'bundle1gd',
119 coreconfigitem('server', 'bundle1gd',
120 default=None,
120 default=None,
121 )
121 )
122 coreconfigitem('server', 'compressionengines',
122 coreconfigitem('server', 'compressionengines',
123 default=list,
123 default=list,
124 )
124 )
125 coreconfigitem('server', 'concurrent-push-mode',
125 coreconfigitem('server', 'concurrent-push-mode',
126 default='strict',
126 default='strict',
127 )
127 )
128 coreconfigitem('server', 'disablefullbundle',
128 coreconfigitem('server', 'disablefullbundle',
129 default=False,
129 default=False,
130 )
130 )
131 coreconfigitem('server', 'maxhttpheaderlen',
131 coreconfigitem('server', 'maxhttpheaderlen',
132 default=1024,
132 default=1024,
133 )
133 )
134 coreconfigitem('server', 'preferuncompressed',
134 coreconfigitem('server', 'preferuncompressed',
135 default=False,
135 default=False,
136 )
136 )
137 coreconfigitem('server', 'uncompressedallowsecret',
137 coreconfigitem('server', 'uncompressedallowsecret',
138 default=False,
138 default=False,
139 )
139 )
140 coreconfigitem('server', 'validate',
140 coreconfigitem('server', 'validate',
141 default=False,
141 default=False,
142 )
142 )
143 coreconfigitem('server', 'zliblevel',
144 default=-1,
145 )
143 coreconfigitem('ui', 'clonebundleprefers',
146 coreconfigitem('ui', 'clonebundleprefers',
144 default=list,
147 default=list,
145 )
148 )
146 coreconfigitem('ui', 'interactive',
149 coreconfigitem('ui', 'interactive',
147 default=None,
150 default=None,
148 )
151 )
149 coreconfigitem('ui', 'quiet',
152 coreconfigitem('ui', 'quiet',
150 default=False,
153 default=False,
151 )
154 )
@@ -1,198 +1,198
1 #
1 #
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import cgi
10 import cgi
11 import struct
11 import struct
12
12
13 from .common import (
13 from .common import (
14 HTTP_OK,
14 HTTP_OK,
15 )
15 )
16
16
17 from .. import (
17 from .. import (
18 util,
18 util,
19 wireproto,
19 wireproto,
20 )
20 )
21 stringio = util.stringio
21 stringio = util.stringio
22
22
23 urlerr = util.urlerr
23 urlerr = util.urlerr
24 urlreq = util.urlreq
24 urlreq = util.urlreq
25
25
26 HGTYPE = 'application/mercurial-0.1'
26 HGTYPE = 'application/mercurial-0.1'
27 HGTYPE2 = 'application/mercurial-0.2'
27 HGTYPE2 = 'application/mercurial-0.2'
28 HGERRTYPE = 'application/hg-error'
28 HGERRTYPE = 'application/hg-error'
29
29
30 def decodevaluefromheaders(req, headerprefix):
30 def decodevaluefromheaders(req, headerprefix):
31 """Decode a long value from multiple HTTP request headers."""
31 """Decode a long value from multiple HTTP request headers."""
32 chunks = []
32 chunks = []
33 i = 1
33 i = 1
34 while True:
34 while True:
35 v = req.env.get('HTTP_%s_%d' % (
35 v = req.env.get('HTTP_%s_%d' % (
36 headerprefix.upper().replace('-', '_'), i))
36 headerprefix.upper().replace('-', '_'), i))
37 if v is None:
37 if v is None:
38 break
38 break
39 chunks.append(v)
39 chunks.append(v)
40 i += 1
40 i += 1
41
41
42 return ''.join(chunks)
42 return ''.join(chunks)
43
43
44 class webproto(wireproto.abstractserverproto):
44 class webproto(wireproto.abstractserverproto):
45 def __init__(self, req, ui):
45 def __init__(self, req, ui):
46 self.req = req
46 self.req = req
47 self.response = ''
47 self.response = ''
48 self.ui = ui
48 self.ui = ui
49 self.name = 'http'
49 self.name = 'http'
50
50
51 def getargs(self, args):
51 def getargs(self, args):
52 knownargs = self._args()
52 knownargs = self._args()
53 data = {}
53 data = {}
54 keys = args.split()
54 keys = args.split()
55 for k in keys:
55 for k in keys:
56 if k == '*':
56 if k == '*':
57 star = {}
57 star = {}
58 for key in knownargs.keys():
58 for key in knownargs.keys():
59 if key != 'cmd' and key not in keys:
59 if key != 'cmd' and key not in keys:
60 star[key] = knownargs[key][0]
60 star[key] = knownargs[key][0]
61 data['*'] = star
61 data['*'] = star
62 else:
62 else:
63 data[k] = knownargs[k][0]
63 data[k] = knownargs[k][0]
64 return [data[k] for k in keys]
64 return [data[k] for k in keys]
65 def _args(self):
65 def _args(self):
66 args = self.req.form.copy()
66 args = self.req.form.copy()
67 postlen = int(self.req.env.get('HTTP_X_HGARGS_POST', 0))
67 postlen = int(self.req.env.get('HTTP_X_HGARGS_POST', 0))
68 if postlen:
68 if postlen:
69 args.update(cgi.parse_qs(
69 args.update(cgi.parse_qs(
70 self.req.read(postlen), keep_blank_values=True))
70 self.req.read(postlen), keep_blank_values=True))
71 return args
71 return args
72
72
73 argvalue = decodevaluefromheaders(self.req, 'X-HgArg')
73 argvalue = decodevaluefromheaders(self.req, 'X-HgArg')
74 args.update(cgi.parse_qs(argvalue, keep_blank_values=True))
74 args.update(cgi.parse_qs(argvalue, keep_blank_values=True))
75 return args
75 return args
76 def getfile(self, fp):
76 def getfile(self, fp):
77 length = int(self.req.env['CONTENT_LENGTH'])
77 length = int(self.req.env['CONTENT_LENGTH'])
78 for s in util.filechunkiter(self.req, limit=length):
78 for s in util.filechunkiter(self.req, limit=length):
79 fp.write(s)
79 fp.write(s)
80 def redirect(self):
80 def redirect(self):
81 self.oldio = self.ui.fout, self.ui.ferr
81 self.oldio = self.ui.fout, self.ui.ferr
82 self.ui.ferr = self.ui.fout = stringio()
82 self.ui.ferr = self.ui.fout = stringio()
83 def restore(self):
83 def restore(self):
84 val = self.ui.fout.getvalue()
84 val = self.ui.fout.getvalue()
85 self.ui.ferr, self.ui.fout = self.oldio
85 self.ui.ferr, self.ui.fout = self.oldio
86 return val
86 return val
87
87
88 def _client(self):
88 def _client(self):
89 return 'remote:%s:%s:%s' % (
89 return 'remote:%s:%s:%s' % (
90 self.req.env.get('wsgi.url_scheme') or 'http',
90 self.req.env.get('wsgi.url_scheme') or 'http',
91 urlreq.quote(self.req.env.get('REMOTE_HOST', '')),
91 urlreq.quote(self.req.env.get('REMOTE_HOST', '')),
92 urlreq.quote(self.req.env.get('REMOTE_USER', '')))
92 urlreq.quote(self.req.env.get('REMOTE_USER', '')))
93
93
94 def responsetype(self, v1compressible=False):
94 def responsetype(self, v1compressible=False):
95 """Determine the appropriate response type and compression settings.
95 """Determine the appropriate response type and compression settings.
96
96
97 The ``v1compressible`` argument states whether the response with
97 The ``v1compressible`` argument states whether the response with
98 application/mercurial-0.1 media types should be zlib compressed.
98 application/mercurial-0.1 media types should be zlib compressed.
99
99
100 Returns a tuple of (mediatype, compengine, engineopts).
100 Returns a tuple of (mediatype, compengine, engineopts).
101 """
101 """
102 # For now, if it isn't compressible in the old world, it's never
102 # For now, if it isn't compressible in the old world, it's never
103 # compressible. We can change this to send uncompressed 0.2 payloads
103 # compressible. We can change this to send uncompressed 0.2 payloads
104 # later.
104 # later.
105 if not v1compressible:
105 if not v1compressible:
106 return HGTYPE, None, None
106 return HGTYPE, None, None
107
107
108 # Determine the response media type and compression engine based
108 # Determine the response media type and compression engine based
109 # on the request parameters.
109 # on the request parameters.
110 protocaps = decodevaluefromheaders(self.req, 'X-HgProto').split(' ')
110 protocaps = decodevaluefromheaders(self.req, 'X-HgProto').split(' ')
111
111
112 if '0.2' in protocaps:
112 if '0.2' in protocaps:
113 # Default as defined by wire protocol spec.
113 # Default as defined by wire protocol spec.
114 compformats = ['zlib', 'none']
114 compformats = ['zlib', 'none']
115 for cap in protocaps:
115 for cap in protocaps:
116 if cap.startswith('comp='):
116 if cap.startswith('comp='):
117 compformats = cap[5:].split(',')
117 compformats = cap[5:].split(',')
118 break
118 break
119
119
120 # Now find an agreed upon compression format.
120 # Now find an agreed upon compression format.
121 for engine in wireproto.supportedcompengines(self.ui, self,
121 for engine in wireproto.supportedcompengines(self.ui, self,
122 util.SERVERROLE):
122 util.SERVERROLE):
123 if engine.wireprotosupport().name in compformats:
123 if engine.wireprotosupport().name in compformats:
124 opts = {}
124 opts = {}
125 level = self.ui.configint('server',
125 level = self.ui.configint('server',
126 '%slevel' % engine.name())
126 '%slevel' % engine.name())
127 if level is not None:
127 if level is not None:
128 opts['level'] = level
128 opts['level'] = level
129
129
130 return HGTYPE2, engine, opts
130 return HGTYPE2, engine, opts
131
131
132 # No mutually supported compression format. Fall back to the
132 # No mutually supported compression format. Fall back to the
133 # legacy protocol.
133 # legacy protocol.
134
134
135 # Don't allow untrusted settings because disabling compression or
135 # Don't allow untrusted settings because disabling compression or
136 # setting a very high compression level could lead to flooding
136 # setting a very high compression level could lead to flooding
137 # the server's network or CPU.
137 # the server's network or CPU.
138 opts = {'level': self.ui.configint('server', 'zliblevel', -1)}
138 opts = {'level': self.ui.configint('server', 'zliblevel')}
139 return HGTYPE, util.compengines['zlib'], opts
139 return HGTYPE, util.compengines['zlib'], opts
140
140
141 def iscmd(cmd):
141 def iscmd(cmd):
142 return cmd in wireproto.commands
142 return cmd in wireproto.commands
143
143
144 def call(repo, req, cmd):
144 def call(repo, req, cmd):
145 p = webproto(req, repo.ui)
145 p = webproto(req, repo.ui)
146
146
147 def genversion2(gen, compress, engine, engineopts):
147 def genversion2(gen, compress, engine, engineopts):
148 # application/mercurial-0.2 always sends a payload header
148 # application/mercurial-0.2 always sends a payload header
149 # identifying the compression engine.
149 # identifying the compression engine.
150 name = engine.wireprotosupport().name
150 name = engine.wireprotosupport().name
151 assert 0 < len(name) < 256
151 assert 0 < len(name) < 256
152 yield struct.pack('B', len(name))
152 yield struct.pack('B', len(name))
153 yield name
153 yield name
154
154
155 if compress:
155 if compress:
156 for chunk in engine.compressstream(gen, opts=engineopts):
156 for chunk in engine.compressstream(gen, opts=engineopts):
157 yield chunk
157 yield chunk
158 else:
158 else:
159 for chunk in gen:
159 for chunk in gen:
160 yield chunk
160 yield chunk
161
161
162 rsp = wireproto.dispatch(repo, p, cmd)
162 rsp = wireproto.dispatch(repo, p, cmd)
163 if isinstance(rsp, str):
163 if isinstance(rsp, str):
164 req.respond(HTTP_OK, HGTYPE, body=rsp)
164 req.respond(HTTP_OK, HGTYPE, body=rsp)
165 return []
165 return []
166 elif isinstance(rsp, wireproto.streamres):
166 elif isinstance(rsp, wireproto.streamres):
167 if rsp.reader:
167 if rsp.reader:
168 gen = iter(lambda: rsp.reader.read(32768), '')
168 gen = iter(lambda: rsp.reader.read(32768), '')
169 else:
169 else:
170 gen = rsp.gen
170 gen = rsp.gen
171
171
172 # This code for compression should not be streamres specific. It
172 # This code for compression should not be streamres specific. It
173 # is here because we only compress streamres at the moment.
173 # is here because we only compress streamres at the moment.
174 mediatype, engine, engineopts = p.responsetype(rsp.v1compressible)
174 mediatype, engine, engineopts = p.responsetype(rsp.v1compressible)
175
175
176 if mediatype == HGTYPE and rsp.v1compressible:
176 if mediatype == HGTYPE and rsp.v1compressible:
177 gen = engine.compressstream(gen, engineopts)
177 gen = engine.compressstream(gen, engineopts)
178 elif mediatype == HGTYPE2:
178 elif mediatype == HGTYPE2:
179 gen = genversion2(gen, rsp.v1compressible, engine, engineopts)
179 gen = genversion2(gen, rsp.v1compressible, engine, engineopts)
180
180
181 req.respond(HTTP_OK, mediatype)
181 req.respond(HTTP_OK, mediatype)
182 return gen
182 return gen
183 elif isinstance(rsp, wireproto.pushres):
183 elif isinstance(rsp, wireproto.pushres):
184 val = p.restore()
184 val = p.restore()
185 rsp = '%d\n%s' % (rsp.res, val)
185 rsp = '%d\n%s' % (rsp.res, val)
186 req.respond(HTTP_OK, HGTYPE, body=rsp)
186 req.respond(HTTP_OK, HGTYPE, body=rsp)
187 return []
187 return []
188 elif isinstance(rsp, wireproto.pusherr):
188 elif isinstance(rsp, wireproto.pusherr):
189 # drain the incoming bundle
189 # drain the incoming bundle
190 req.drain()
190 req.drain()
191 p.restore()
191 p.restore()
192 rsp = '0\n%s\n' % rsp.res
192 rsp = '0\n%s\n' % rsp.res
193 req.respond(HTTP_OK, HGTYPE, body=rsp)
193 req.respond(HTTP_OK, HGTYPE, body=rsp)
194 return []
194 return []
195 elif isinstance(rsp, wireproto.ooberror):
195 elif isinstance(rsp, wireproto.ooberror):
196 rsp = rsp.message
196 rsp = rsp.message
197 req.respond(HTTP_OK, HGERRTYPE, body=rsp)
197 req.respond(HTTP_OK, HGERRTYPE, body=rsp)
198 return []
198 return []
General Comments 0
You need to be logged in to leave comments. Login now