author | Bryan O'Sullivan <bos@serpentine.com> |
Sun, 21 Dec 2008 12:19:12 -0800 | |
changeset 7543 | 73268e317ad3 |
parent 7281 | f96c20e9b56a |
child 8109 | 496ae1ea4698 |
permissions | -rw-r--r-- |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
1 |
# |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
2 |
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
3 |
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
4 |
# |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
5 |
# This software may be used and distributed according to the terms |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
6 |
# of the GNU General Public License, incorporated herein by reference. |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
7 |
|
6212 | 8 |
import cStringIO, zlib, tempfile, errno, os, sys |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
9 |
from mercurial import util, streamclone |
6211
f89fd07fc51d
Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents:
6155
diff
changeset
|
10 |
from mercurial.node import bin, hex |
6154
ef1c5a3b653d
improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6152
diff
changeset
|
11 |
from mercurial import changegroup as changegroupmod |
7281
f96c20e9b56a
fix missing import, spotted by pychecker
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7180
diff
changeset
|
12 |
from common import ErrorResponse, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
13 |
|
5963
5be210afe1b8
hgweb: explicitly check if requested command exists
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5915
diff
changeset
|
14 |
# __all__ is populated with the allowed commands. Be sure to add to it if |
5be210afe1b8
hgweb: explicitly check if requested command exists
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5915
diff
changeset
|
15 |
# you're adding a new command, or the new command won't work. |
5be210afe1b8
hgweb: explicitly check if requested command exists
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5915
diff
changeset
|
16 |
|
5be210afe1b8
hgweb: explicitly check if requested command exists
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5915
diff
changeset
|
17 |
__all__ = [ |
5be210afe1b8
hgweb: explicitly check if requested command exists
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5915
diff
changeset
|
18 |
'lookup', 'heads', 'branches', 'between', 'changegroup', |
5be210afe1b8
hgweb: explicitly check if requested command exists
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5915
diff
changeset
|
19 |
'changegroupsubset', 'capabilities', 'unbundle', 'stream_out', |
5be210afe1b8
hgweb: explicitly check if requested command exists
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5915
diff
changeset
|
20 |
] |
5be210afe1b8
hgweb: explicitly check if requested command exists
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5915
diff
changeset
|
21 |
|
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
22 |
HGTYPE = 'application/mercurial-0.1' |
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
23 |
|
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
24 |
def lookup(repo, req): |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
25 |
try: |
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
26 |
r = hex(repo.lookup(req.form['key'][0])) |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
27 |
success = 1 |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
28 |
except Exception,inst: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
29 |
r = str(inst) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
30 |
success = 0 |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
31 |
resp = "%s %s\n" % (success, r) |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
32 |
req.respond(HTTP_OK, HGTYPE, length=len(resp)) |
6784
18c429ea3a0e
hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6782
diff
changeset
|
33 |
yield resp |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
34 |
|
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
35 |
def heads(repo, req): |
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
36 |
resp = " ".join(map(hex, repo.heads())) + "\n" |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
37 |
req.respond(HTTP_OK, HGTYPE, length=len(resp)) |
6784
18c429ea3a0e
hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6782
diff
changeset
|
38 |
yield resp |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
39 |
|
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
40 |
def branches(repo, req): |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
41 |
nodes = [] |
5915
d0576d065993
Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents:
5598
diff
changeset
|
42 |
if 'nodes' in req.form: |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
43 |
nodes = map(bin, req.form['nodes'][0].split(" ")) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
44 |
resp = cStringIO.StringIO() |
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
45 |
for b in repo.branches(nodes): |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
46 |
resp.write(" ".join(map(hex, b)) + "\n") |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
47 |
resp = resp.getvalue() |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
48 |
req.respond(HTTP_OK, HGTYPE, length=len(resp)) |
6784
18c429ea3a0e
hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6782
diff
changeset
|
49 |
yield resp |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
50 |
|
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
51 |
def between(repo, req): |
5915
d0576d065993
Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents:
5598
diff
changeset
|
52 |
if 'pairs' in req.form: |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
53 |
pairs = [map(bin, p.split("-")) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
54 |
for p in req.form['pairs'][0].split(" ")] |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
55 |
resp = cStringIO.StringIO() |
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
56 |
for b in repo.between(pairs): |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
57 |
resp.write(" ".join(map(hex, b)) + "\n") |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
58 |
resp = resp.getvalue() |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
59 |
req.respond(HTTP_OK, HGTYPE, length=len(resp)) |
6784
18c429ea3a0e
hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6782
diff
changeset
|
60 |
yield resp |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
61 |
|
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
62 |
def changegroup(repo, req): |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
63 |
req.respond(HTTP_OK, HGTYPE) |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
64 |
nodes = [] |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
65 |
|
5915
d0576d065993
Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents:
5598
diff
changeset
|
66 |
if 'roots' in req.form: |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
67 |
nodes = map(bin, req.form['roots'][0].split(" ")) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
68 |
|
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
69 |
z = zlib.compressobj() |
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
70 |
f = repo.changegroup(nodes, 'serve') |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
71 |
while 1: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
72 |
chunk = f.read(4096) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
73 |
if not chunk: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
74 |
break |
6784
18c429ea3a0e
hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6782
diff
changeset
|
75 |
yield z.compress(chunk) |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
76 |
|
6784
18c429ea3a0e
hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6782
diff
changeset
|
77 |
yield z.flush() |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
78 |
|
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
79 |
def changegroupsubset(repo, req): |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
80 |
req.respond(HTTP_OK, HGTYPE) |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
81 |
bases = [] |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
82 |
heads = [] |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
83 |
|
5915
d0576d065993
Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents:
5598
diff
changeset
|
84 |
if 'bases' in req.form: |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
85 |
bases = [bin(x) for x in req.form['bases'][0].split(' ')] |
5915
d0576d065993
Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents:
5598
diff
changeset
|
86 |
if 'heads' in req.form: |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
87 |
heads = [bin(x) for x in req.form['heads'][0].split(' ')] |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
88 |
|
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
89 |
z = zlib.compressobj() |
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
90 |
f = repo.changegroupsubset(bases, heads, 'serve') |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
91 |
while 1: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
92 |
chunk = f.read(4096) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
93 |
if not chunk: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
94 |
break |
6784
18c429ea3a0e
hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6782
diff
changeset
|
95 |
yield z.compress(chunk) |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
96 |
|
6784
18c429ea3a0e
hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6782
diff
changeset
|
97 |
yield z.flush() |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
98 |
|
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
99 |
def capabilities(repo, req): |
6780
4c1d67e0fa8c
hgweb: move capabilities calculation back into hgweb.protocol
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6779
diff
changeset
|
100 |
caps = ['lookup', 'changegroupsubset'] |
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
101 |
if repo.ui.configbool('server', 'uncompressed', untrusted=True): |
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
102 |
caps.append('stream=%d' % repo.changelog.version) |
6780
4c1d67e0fa8c
hgweb: move capabilities calculation back into hgweb.protocol
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6779
diff
changeset
|
103 |
if changegroupmod.bundlepriority: |
4c1d67e0fa8c
hgweb: move capabilities calculation back into hgweb.protocol
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6779
diff
changeset
|
104 |
caps.append('unbundle=%s' % ','.join(changegroupmod.bundlepriority)) |
4c1d67e0fa8c
hgweb: move capabilities calculation back into hgweb.protocol
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6779
diff
changeset
|
105 |
rsp = ' '.join(caps) |
4c1d67e0fa8c
hgweb: move capabilities calculation back into hgweb.protocol
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6779
diff
changeset
|
106 |
req.respond(HTTP_OK, HGTYPE, length=len(rsp)) |
6784
18c429ea3a0e
hgweb: all protocol functions have become generators
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6782
diff
changeset
|
107 |
yield rsp |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
108 |
|
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
109 |
def unbundle(repo, req): |
6335
e29557d687c9
hgweb: only accept POST requests for unbundle
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6265
diff
changeset
|
110 |
|
6779
d3147b4e3e8a
hgweb: centralize permission checks for protocol commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6630
diff
changeset
|
111 |
proto = req.env.get('wsgi.url_scheme') or 'http' |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
112 |
their_heads = req.form['heads'][0].split(' ') |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
113 |
|
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
114 |
def check_heads(): |
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
115 |
heads = map(hex, repo.heads()) |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
116 |
return their_heads == [hex('force')] or their_heads == heads |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
117 |
|
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
118 |
# fail early if possible |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
119 |
if not check_heads(): |
7180
a42d27bc809d
hgweb: be sure to drain request data even in early error conditions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6926
diff
changeset
|
120 |
req.drain() |
6926
57b954d8d003
hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6925
diff
changeset
|
121 |
raise ErrorResponse(HTTP_OK, 'unsynced changes') |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
122 |
|
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
123 |
# do not lock repo until all changegroup data is |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
124 |
# streamed. save to temporary file. |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
125 |
|
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
126 |
fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
127 |
fp = os.fdopen(fd, 'wb+') |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
128 |
try: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
129 |
length = int(req.env['CONTENT_LENGTH']) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
130 |
for s in util.filechunkiter(req, limit=length): |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
131 |
fp.write(s) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
132 |
|
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
133 |
try: |
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
134 |
lock = repo.lock() |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
135 |
try: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
136 |
if not check_heads(): |
6926
57b954d8d003
hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6925
diff
changeset
|
137 |
raise ErrorResponse(HTTP_OK, 'unsynced changes') |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
138 |
|
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
139 |
fp.seek(0) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
140 |
header = fp.read(6) |
6154
ef1c5a3b653d
improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6152
diff
changeset
|
141 |
if header.startswith('HG') and not header.startswith('HG10'): |
ef1c5a3b653d
improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6152
diff
changeset
|
142 |
raise ValueError('unknown bundle version') |
ef1c5a3b653d
improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6152
diff
changeset
|
143 |
elif header not in changegroupmod.bundletypes: |
ef1c5a3b653d
improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6152
diff
changeset
|
144 |
raise ValueError('unknown bundle compression type') |
ef1c5a3b653d
improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6152
diff
changeset
|
145 |
gen = changegroupmod.unbundle(header, fp) |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
146 |
|
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
147 |
# send addchangegroup output to client |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
148 |
|
6265
be76e54570f0
Issue937: error messages from hooks not sent over HTTP.
Jesse Glick <jesse.glick@sun.com>
parents:
6212
diff
changeset
|
149 |
oldio = sys.stdout, sys.stderr |
be76e54570f0
Issue937: error messages from hooks not sent over HTTP.
Jesse Glick <jesse.glick@sun.com>
parents:
6212
diff
changeset
|
150 |
sys.stderr = sys.stdout = cStringIO.StringIO() |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
151 |
|
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
152 |
try: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
153 |
url = 'remote:%s:%s' % (proto, |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
154 |
req.env.get('REMOTE_HOST', '')) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
155 |
try: |
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
156 |
ret = repo.addchangegroup(gen, 'serve', url) |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
157 |
except util.Abort, inst: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
158 |
sys.stdout.write("abort: %s\n" % inst) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
159 |
ret = 0 |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
160 |
finally: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
161 |
val = sys.stdout.getvalue() |
6265
be76e54570f0
Issue937: error messages from hooks not sent over HTTP.
Jesse Glick <jesse.glick@sun.com>
parents:
6212
diff
changeset
|
162 |
sys.stdout, sys.stderr = oldio |
6926
57b954d8d003
hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6925
diff
changeset
|
163 |
req.respond(HTTP_OK, HGTYPE) |
6788
88a1bcc5c6a7
hgweb: use a single-element tuple to return from protocol.unbundle()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6784
diff
changeset
|
164 |
return '%d\n%s' % (ret, val), |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
165 |
finally: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
166 |
del lock |
6154
ef1c5a3b653d
improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6152
diff
changeset
|
167 |
except ValueError, inst: |
6926
57b954d8d003
hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6925
diff
changeset
|
168 |
raise ErrorResponse(HTTP_OK, inst) |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
169 |
except (OSError, IOError), inst: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
170 |
filename = getattr(inst, 'filename', '') |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
171 |
# Don't send our filesystem layout to the client |
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
172 |
if filename.startswith(repo.root): |
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
173 |
filename = filename[len(repo.root)+1:] |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
174 |
else: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
175 |
filename = '' |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
176 |
error = getattr(inst, 'strerror', 'Unknown error') |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
177 |
if inst.errno == errno.ENOENT: |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
178 |
code = HTTP_NOT_FOUND |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
179 |
else: |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
180 |
code = HTTP_SERVER_ERROR |
6926
57b954d8d003
hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6925
diff
changeset
|
181 |
raise ErrorResponse(code, '%s: %s' % (error, filename)) |
5598
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
182 |
finally: |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
183 |
fp.close() |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
184 |
os.unlink(tempname) |
d534ba1c4eb4
separate the wire protocol commands from the user interface commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff
changeset
|
185 |
|
6781
b4b7261164d5
hgweb: protocol functions take repo instead of web
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6780
diff
changeset
|
186 |
def stream_out(repo, req): |
5993
948a41e77902
hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5963
diff
changeset
|
187 |
req.respond(HTTP_OK, HGTYPE) |
6925
87abfefafe02
make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6795
diff
changeset
|
188 |
try: |
87abfefafe02
make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6795
diff
changeset
|
189 |
for chunk in streamclone.stream_out(repo, untrusted=True): |
87abfefafe02
make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6795
diff
changeset
|
190 |
yield chunk |
87abfefafe02
make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6795
diff
changeset
|
191 |
except streamclone.StreamException, inst: |
87abfefafe02
make streamclone.stream_out() a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6795
diff
changeset
|
192 |
yield str(inst) |