##// END OF EJS Templates
hgweb: pull cgitb into CGI script example, where it can easily be disabled...
mpm@selenic.com -
r391:5f65a108 default
parent child Browse files
Show More
@@ -1,10 +1,12 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # An example CGI script to use hgweb, edit as necessary
4 4
5 5 import cgitb, os, sys
6 cgitb.enable()
7
6 8 # sys.path.insert(0, "/path/to/python/lib") # if not a system-wide install
7 9 from mercurial import hgweb
8 10
9 11 h = hgweb.hgweb("/path/to/repo", "repository name")
10 12 h.run()
@@ -1,723 +1,719 b''
1 1 # hgweb.py - web interface to a mercurial repository
2 2 #
3 3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 4 # Copyright 2005 Matt Mackall <mpm@selenic.com>
5 5 #
6 6 # This software may be used and distributed according to the terms
7 7 # of the GNU General Public License, incorporated herein by reference.
8 8
9 # useful for debugging
10 import cgitb
11 cgitb.enable()
12
13 9 import os, cgi, time, re, difflib, sys, zlib
14 10 from mercurial.hg import *
15 11 from mercurial.ui import *
16 12
17 13 def templatepath():
18 14 for f in "templates", "../templates":
19 15 p = os.path.join(os.path.dirname(__file__), f)
20 16 if os.path.isdir(p): return p
21 17
22 18 def age(t):
23 19 def plural(t, c):
24 20 if c == 1: return t
25 21 return t + "s"
26 22 def fmt(t, c):
27 23 return "%d %s" % (c, plural(t, c))
28 24
29 25 now = time.time()
30 26 delta = max(1, int(now - t))
31 27
32 28 scales = [["second", 1],
33 29 ["minute", 60],
34 30 ["hour", 3600],
35 31 ["day", 3600 * 24],
36 32 ["week", 3600 * 24 * 7],
37 33 ["month", 3600 * 24 * 30],
38 34 ["year", 3600 * 24 * 365]]
39 35
40 36 scales.reverse()
41 37
42 38 for t, s in scales:
43 39 n = delta / s
44 40 if n >= 2 or s == 1: return fmt(t, n)
45 41
46 42 def nl2br(text):
47 43 return text.replace('\n', '<br/>\n')
48 44
49 45 def obfuscate(text):
50 46 return ''.join([ '&#%d' % ord(c) for c in text ])
51 47
52 48 def up(p):
53 49 if p[0] != "/": p = "/" + p
54 50 if p[-1] == "/": p = p[:-1]
55 51 up = os.path.dirname(p)
56 52 if up == "/":
57 53 return "/"
58 54 return up + "/"
59 55
60 56 def httphdr(type):
61 57 print 'Content-type: %s\n' % type
62 58
63 59 def write(*things):
64 60 for thing in things:
65 61 if hasattr(thing, "__iter__"):
66 62 for part in thing:
67 63 write(part)
68 64 else:
69 65 sys.stdout.write(str(thing))
70 66
71 67 def template(tmpl, filters = {}, **map):
72 68 while tmpl:
73 69 m = re.search(r"#([a-zA-Z0-9]+)((\|[a-zA-Z0-9]+)*)#", tmpl)
74 70 if m:
75 71 yield tmpl[:m.start(0)]
76 72 v = map.get(m.group(1), "")
77 73 v = callable(v) and v() or v
78 74
79 75 fl = m.group(2)
80 76 if fl:
81 77 for f in fl.split("|")[1:]:
82 78 v = filters[f](v)
83 79
84 80 yield v
85 81 tmpl = tmpl[m.end(0):]
86 82 else:
87 83 yield tmpl
88 84 return
89 85
90 86 class templater:
91 87 def __init__(self, mapfile, filters = {}):
92 88 self.cache = {}
93 89 self.map = {}
94 90 self.base = os.path.dirname(mapfile)
95 91 self.filters = filters
96 92
97 93 for l in file(mapfile):
98 94 m = re.match(r'(\S+)\s*=\s*"(.*)"$', l)
99 95 if m:
100 96 self.cache[m.group(1)] = m.group(2)
101 97 else:
102 98 m = re.match(r'(\S+)\s*=\s*(\S+)', l)
103 99 if m:
104 100 self.map[m.group(1)] = os.path.join(self.base, m.group(2))
105 101 else:
106 102 raise "unknown map entry '%s'" % l
107 103
108 104 def __call__(self, t, **map):
109 105 try:
110 106 tmpl = self.cache[t]
111 107 except KeyError:
112 108 tmpl = self.cache[t] = file(self.map[t]).read()
113 109 return template(tmpl, self.filters, **map)
114 110
115 111 class hgweb:
116 112 maxchanges = 10
117 113 maxfiles = 10
118 114
119 115 def __init__(self, path, name, templates = ""):
120 116 self.templates = templates or templatepath()
121 117 self.reponame = name
122 118 self.path = path
123 119 self.mtime = -1
124 120 self.viewonly = 0
125 121
126 122 self.filters = {
127 123 "escape": cgi.escape,
128 124 "age": age,
129 125 "date": (lambda x: time.asctime(time.gmtime(x))),
130 126 "addbreaks": nl2br,
131 127 "obfuscate": obfuscate,
132 128 "short": (lambda x: x[:12]),
133 129 "firstline": (lambda x: x.splitlines(1)[0]),
134 130 "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--")
135 131 }
136 132
137 133 def refresh(self):
138 134 s = os.stat(os.path.join(self.path, ".hg", "00changelog.i"))
139 135 if s.st_mtime != self.mtime:
140 136 self.mtime = s.st_mtime
141 137 self.repo = repository(ui(), self.path)
142 138
143 139 def date(self, cs):
144 140 return time.asctime(time.gmtime(float(cs[2].split(' ')[0])))
145 141
146 142 def listfiles(self, files, mf):
147 143 for f in files[:self.maxfiles]:
148 144 yield self.t("filenodelink", node = hex(mf[f]), file = f)
149 145 if len(files) > self.maxfiles:
150 146 yield self.t("fileellipses")
151 147
152 148 def listfilediffs(self, files, changeset):
153 149 for f in files[:self.maxfiles]:
154 150 yield self.t("filedifflink", node = hex(changeset), file = f)
155 151 if len(files) > self.maxfiles:
156 152 yield self.t("fileellipses")
157 153
158 154 def parent(self, t1, node=nullid, rev=-1, **args):
159 155 if node != hex(nullid):
160 156 yield self.t(t1, node = node, rev = rev, **args)
161 157
162 158 def diff(self, node1, node2, files):
163 159 def filterfiles(list, files):
164 160 l = [ x for x in list if x in files ]
165 161
166 162 for f in files:
167 163 if f[-1] != os.sep: f += os.sep
168 164 l += [ x for x in list if x.startswith(f) ]
169 165 return l
170 166
171 167 parity = [0]
172 168 def diffblock(diff, f, fn):
173 169 yield self.t("diffblock",
174 170 lines = prettyprintlines(diff),
175 171 parity = parity[0],
176 172 file = f,
177 173 filenode = hex(fn or nullid))
178 174 parity[0] = 1 - parity[0]
179 175
180 176 def prettyprintlines(diff):
181 177 for l in diff.splitlines(1):
182 178 if l.startswith('+'):
183 179 yield self.t("difflineplus", line = l)
184 180 elif l.startswith('-'):
185 181 yield self.t("difflineminus", line = l)
186 182 elif l.startswith('@'):
187 183 yield self.t("difflineat", line = l)
188 184 else:
189 185 yield self.t("diffline", line = l)
190 186
191 187 r = self.repo
192 188 cl = r.changelog
193 189 mf = r.manifest
194 190 change1 = cl.read(node1)
195 191 change2 = cl.read(node2)
196 192 mmap1 = mf.read(change1[0])
197 193 mmap2 = mf.read(change2[0])
198 194 date1 = self.date(change1)
199 195 date2 = self.date(change2)
200 196
201 197 c, a, d = r.diffrevs(node1, node2)
202 198 c, a, d = map(lambda x: filterfiles(x, files), (c, a, d))
203 199
204 200 for f in c:
205 201 to = r.file(f).read(mmap1[f])
206 202 tn = r.file(f).read(mmap2[f])
207 203 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f), f, tn)
208 204 for f in a:
209 205 to = None
210 206 tn = r.file(f).read(mmap2[f])
211 207 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f), f, tn)
212 208 for f in d:
213 209 to = r.file(f).read(mmap1[f])
214 210 tn = None
215 211 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f), f, tn)
216 212
217 213 def header(self):
218 214 yield self.t("header", repo = self.reponame)
219 215
220 216 def footer(self):
221 217 yield self.t("footer", repo = self.reponame)
222 218
223 219 def changelog(self, pos):
224 220 def changenav():
225 221 def seq(factor = 1):
226 222 yield 1 * factor
227 223 yield 3 * factor
228 224 #yield 5 * factor
229 225 for f in seq(factor * 10):
230 226 yield f
231 227
232 228 l = []
233 229 for f in seq():
234 230 if f < self.maxchanges / 2: continue
235 231 if f > count: break
236 232 r = "%d" % f
237 233 if pos + f < count: l.append(("+" + r, pos + f))
238 234 if pos - f >= 0: l.insert(0, ("-" + r, pos - f))
239 235
240 236 yield self.t("naventry", rev = 0, label="(0)")
241 237
242 238 for label, rev in l:
243 239 yield self.t("naventry", label = label, rev = rev)
244 240
245 241 yield self.t("naventry", label="tip")
246 242
247 243 def changelist():
248 244 parity = (start - end) & 1
249 245 cl = self.repo.changelog
250 246 l = [] # build a list in forward order for efficiency
251 247 for i in range(start, end):
252 248 n = cl.node(i)
253 249 changes = cl.read(n)
254 250 hn = hex(n)
255 251 p1, p2 = cl.parents(n)
256 252 t = float(changes[2].split(' ')[0])
257 253
258 254 l.insert(0, self.t(
259 255 'changelogentry',
260 256 parity = parity,
261 257 author = changes[1],
262 258 parent1 = self.parent("changelogparent",
263 259 hex(p1), cl.rev(p1)),
264 260 parent2 = self.parent("changelogparent",
265 261 hex(p2), cl.rev(p2)),
266 262 p1 = hex(p1), p2 = hex(p2),
267 263 p1rev = cl.rev(p1), p2rev = cl.rev(p2),
268 264 manifest = hex(changes[0]),
269 265 desc = changes[4],
270 266 date = t,
271 267 files = self.listfilediffs(changes[3], n),
272 268 rev = i,
273 269 node = hn))
274 270 parity = 1 - parity
275 271
276 272 yield l
277 273
278 274 cl = self.repo.changelog
279 275 mf = cl.read(cl.tip())[0]
280 276 count = cl.count()
281 277 start = max(0, pos - self.maxchanges + 1)
282 278 end = min(count, start + self.maxchanges)
283 279 pos = end - 1
284 280
285 281 yield self.t('changelog',
286 282 header = self.header(),
287 283 footer = self.footer(),
288 284 repo = self.reponame,
289 285 changenav = changenav,
290 286 manifest = hex(mf),
291 287 rev = pos, changesets = count, entries = changelist)
292 288
293 289 def changeset(self, nodeid):
294 290 n = bin(nodeid)
295 291 cl = self.repo.changelog
296 292 changes = cl.read(n)
297 293 p1, p2 = cl.parents(n)
298 294 p1rev, p2rev = cl.rev(p1), cl.rev(p2)
299 295 t = float(changes[2].split(' ')[0])
300 296
301 297 files = []
302 298 mf = self.repo.manifest.read(changes[0])
303 299 for f in changes[3]:
304 300 files.append(self.t("filenodelink",
305 301 filenode = hex(mf.get(f, nullid)), file = f))
306 302
307 303 def diff():
308 304 yield self.diff(p1, n, changes[3])
309 305
310 306 yield self.t('changeset',
311 307 header = self.header(),
312 308 footer = self.footer(),
313 309 repo = self.reponame,
314 310 diff = diff,
315 311 rev = cl.rev(n),
316 312 node = nodeid,
317 313 parent1 = self.parent("changesetparent",
318 314 hex(p1), cl.rev(p1)),
319 315 parent2 = self.parent("changesetparent",
320 316 hex(p2), cl.rev(p2)),
321 317 p1 = hex(p1), p2 = hex(p2),
322 318 p1rev = cl.rev(p1), p2rev = cl.rev(p2),
323 319 manifest = hex(changes[0]),
324 320 author = changes[1],
325 321 desc = changes[4],
326 322 date = t,
327 323 files = files)
328 324
329 325 def filelog(self, f, filenode):
330 326 cl = self.repo.changelog
331 327 fl = self.repo.file(f)
332 328 count = fl.count()
333 329
334 330 def entries():
335 331 l = []
336 332 parity = (count - 1) & 1
337 333
338 334 for i in range(count):
339 335
340 336 n = fl.node(i)
341 337 lr = fl.linkrev(n)
342 338 cn = cl.node(lr)
343 339 cs = cl.read(cl.node(lr))
344 340 p1, p2 = fl.parents(n)
345 341 t = float(cs[2].split(' ')[0])
346 342
347 343 l.insert(0, self.t("filelogentry",
348 344 parity = parity,
349 345 filenode = hex(n),
350 346 filerev = i,
351 347 file = f,
352 348 node = hex(cn),
353 349 author = cs[1],
354 350 date = t,
355 351 desc = cs[4],
356 352 p1 = hex(p1), p2 = hex(p2),
357 353 p1rev = fl.rev(p1), p2rev = fl.rev(p2)))
358 354 parity = 1 - parity
359 355
360 356 yield l
361 357
362 358 yield self.t("filelog",
363 359 header = self.header(),
364 360 footer = self.footer(),
365 361 repo = self.reponame,
366 362 file = f,
367 363 filenode = filenode,
368 364 entries = entries)
369 365
370 366 def filerevision(self, f, node):
371 367 fl = self.repo.file(f)
372 368 n = bin(node)
373 369 text = fl.read(n)
374 370 changerev = fl.linkrev(n)
375 371 cl = self.repo.changelog
376 372 cn = cl.node(changerev)
377 373 cs = cl.read(cn)
378 374 p1, p2 = fl.parents(n)
379 375 t = float(cs[2].split(' ')[0])
380 376 mfn = cs[0]
381 377
382 378 def lines():
383 379 for l, t in enumerate(text.splitlines(1)):
384 380 yield self.t("fileline", line = t,
385 381 linenumber = "% 6d" % (l + 1),
386 382 parity = l & 1)
387 383
388 384 yield self.t("filerevision", file = f,
389 385 header = self.header(),
390 386 footer = self.footer(),
391 387 repo = self.reponame,
392 388 filenode = node,
393 389 path = up(f),
394 390 text = lines(),
395 391 rev = changerev,
396 392 node = hex(cn),
397 393 manifest = hex(mfn),
398 394 author = cs[1],
399 395 date = t,
400 396 parent1 = self.parent("filerevparent",
401 397 hex(p1), fl.rev(p1), file=f),
402 398 parent2 = self.parent("filerevparent",
403 399 hex(p2), fl.rev(p2), file=f),
404 400 p1 = hex(p1), p2 = hex(p2),
405 401 permissions = self.repo.manifest.readflags(mfn)[f],
406 402 p1rev = fl.rev(p1), p2rev = fl.rev(p2))
407 403
408 404 def fileannotate(self, f, node):
409 405 bcache = {}
410 406 ncache = {}
411 407 fl = self.repo.file(f)
412 408 n = bin(node)
413 409 changerev = fl.linkrev(n)
414 410
415 411 cl = self.repo.changelog
416 412 cn = cl.node(changerev)
417 413 cs = cl.read(cn)
418 414 p1, p2 = fl.parents(n)
419 415 t = float(cs[2].split(' ')[0])
420 416 mfn = cs[0]
421 417
422 418 def annotate():
423 419 parity = 1
424 420 last = None
425 421 for r, l in fl.annotate(n):
426 422 try:
427 423 cnode = ncache[r]
428 424 except KeyError:
429 425 cnode = ncache[r] = self.repo.changelog.node(r)
430 426
431 427 try:
432 428 name = bcache[r]
433 429 except KeyError:
434 430 cl = self.repo.changelog.read(cnode)
435 431 name = cl[1]
436 432 f = name.find('@')
437 433 if f >= 0:
438 434 name = name[:f]
439 435 bcache[r] = name
440 436
441 437 if last != cnode:
442 438 parity = 1 - parity
443 439 last = cnode
444 440
445 441 yield self.t("annotateline",
446 442 parity = parity,
447 443 node = hex(cnode),
448 444 rev = r,
449 445 author = name,
450 446 file = f,
451 447 line = l)
452 448
453 449 yield self.t("fileannotate",
454 450 header = self.header(),
455 451 footer = self.footer(),
456 452 repo = self.reponame,
457 453 file = f,
458 454 filenode = node,
459 455 annotate = annotate,
460 456 path = up(f),
461 457 rev = changerev,
462 458 node = hex(cn),
463 459 manifest = hex(mfn),
464 460 author = cs[1],
465 461 date = t,
466 462 parent1 = self.parent("fileannotateparent",
467 463 hex(p1), fl.rev(p1), file=f),
468 464 parent2 = self.parent("fileannotateparent",
469 465 hex(p2), fl.rev(p2), file=f),
470 466 p1 = hex(p1), p2 = hex(p2),
471 467 permissions = self.repo.manifest.readflags(mfn)[f],
472 468 p1rev = fl.rev(p1), p2rev = fl.rev(p2))
473 469
474 470 def manifest(self, mnode, path):
475 471 mf = self.repo.manifest.read(bin(mnode))
476 472 rev = self.repo.manifest.rev(bin(mnode))
477 473 node = self.repo.changelog.node(rev)
478 474 mff=self.repo.manifest.readflags(bin(mnode))
479 475
480 476 files = {}
481 477
482 478 p = path[1:]
483 479 l = len(p)
484 480
485 481 for f,n in mf.items():
486 482 if f[:l] != p:
487 483 continue
488 484 remain = f[l:]
489 485 if "/" in remain:
490 486 short = remain[:remain.find("/") + 1] # bleah
491 487 files[short] = (f, None)
492 488 else:
493 489 short = os.path.basename(remain)
494 490 files[short] = (f, n)
495 491
496 492 def filelist():
497 493 parity = 0
498 494 fl = files.keys()
499 495 fl.sort()
500 496 for f in fl:
501 497 full, fnode = files[f]
502 498 if fnode:
503 499 yield self.t("manifestfileentry",
504 500 file = full,
505 501 manifest = mnode,
506 502 filenode = hex(fnode),
507 503 parity = parity,
508 504 basename = f,
509 505 permissions = mff[full])
510 506 else:
511 507 yield self.t("manifestdirentry",
512 508 parity = parity,
513 509 path = os.path.join(path, f),
514 510 manifest = mnode, basename = f[:-1])
515 511 parity = 1 - parity
516 512
517 513 yield self.t("manifest",
518 514 header = self.header(),
519 515 footer = self.footer(),
520 516 repo = self.reponame,
521 517 manifest = mnode,
522 518 rev = rev,
523 519 node = hex(node),
524 520 path = path,
525 521 up = up(path),
526 522 entries = filelist)
527 523
528 524 def tags(self):
529 525 cl = self.repo.changelog
530 526 mf = cl.read(cl.tip())[0]
531 527
532 528 i = self.repo.tagslist()
533 529 i.reverse()
534 530
535 531 def entries():
536 532 parity = 0
537 533 for k,n in i:
538 534 yield self.t("tagentry",
539 535 parity = parity,
540 536 tag = k,
541 537 node = hex(n))
542 538 parity = 1 - parity
543 539
544 540 yield self.t("tags",
545 541 header = self.header(),
546 542 footer = self.footer(),
547 543 repo = self.reponame,
548 544 manifest = hex(mf),
549 545 entries = entries)
550 546
551 547 def filediff(self, file, changeset):
552 548 n = bin(changeset)
553 549 cl = self.repo.changelog
554 550 p1 = cl.parents(n)[0]
555 551 cs = cl.read(n)
556 552 mf = self.repo.manifest.read(cs[0])
557 553
558 554 def diff():
559 555 yield self.diff(p1, n, file)
560 556
561 557 yield self.t("filediff",
562 558 header = self.header(),
563 559 footer = self.footer(),
564 560 repo = self.reponame,
565 561 file = file,
566 562 filenode = hex(mf.get(file, nullid)),
567 563 node = changeset,
568 564 rev = self.repo.changelog.rev(n),
569 565 p1 = hex(p1),
570 566 p1rev = self.repo.changelog.rev(p1),
571 567 diff = diff)
572 568
573 569 # add tags to things
574 570 # tags -> list of changesets corresponding to tags
575 571 # find tag, changeset, file
576 572
577 573 def run(self):
578 574 self.refresh()
579 575 args = cgi.parse()
580 576
581 577 m = os.path.join(self.templates, "map")
582 578 if args.has_key('style'):
583 579 b = os.path.basename("map-" + args['style'][0])
584 580 p = os.path.join(self.templates, b)
585 581 if os.path.isfile(p): m = p
586 582
587 583 self.t = templater(m, self.filters)
588 584
589 585 if not args.has_key('cmd') or args['cmd'][0] == 'changelog':
590 586 hi = self.repo.changelog.count() - 1
591 587 if args.has_key('rev'):
592 588 hi = args['rev'][0]
593 589 try:
594 590 hi = self.repo.changelog.rev(self.repo.lookup(hi))
595 591 except KeyError: pass
596 592
597 593 write(self.changelog(hi))
598 594
599 595 elif args['cmd'][0] == 'changeset':
600 596 write(self.changeset(args['node'][0]))
601 597
602 598 elif args['cmd'][0] == 'manifest':
603 599 write(self.manifest(args['manifest'][0], args['path'][0]))
604 600
605 601 elif args['cmd'][0] == 'tags':
606 602 write(self.tags())
607 603
608 604 elif args['cmd'][0] == 'filediff':
609 605 write(self.filediff(args['file'][0], args['node'][0]))
610 606
611 607 elif args['cmd'][0] == 'file':
612 608 write(self.filerevision(args['file'][0], args['filenode'][0]))
613 609
614 610 elif args['cmd'][0] == 'annotate':
615 611 write(self.fileannotate(args['file'][0], args['filenode'][0]))
616 612
617 613 elif args['cmd'][0] == 'filelog':
618 614 write(self.filelog(args['file'][0], args['filenode'][0]))
619 615
620 616 elif args['cmd'][0] == 'heads':
621 617 httphdr("text/plain")
622 618 h = self.repo.heads()
623 619 sys.stdout.write(" ".join(map(hex, h)) + "\n")
624 620
625 621 elif args['cmd'][0] == 'branches':
626 622 httphdr("text/plain")
627 623 nodes = []
628 624 if args.has_key('nodes'):
629 625 nodes = map(bin, args['nodes'][0].split(" "))
630 626 for b in self.repo.branches(nodes):
631 627 sys.stdout.write(" ".join(map(hex, b)) + "\n")
632 628
633 629 elif args['cmd'][0] == 'between':
634 630 httphdr("text/plain")
635 631 nodes = []
636 632 if args.has_key('pairs'):
637 633 pairs = [ map(bin, p.split("-"))
638 634 for p in args['pairs'][0].split(" ") ]
639 635 for b in self.repo.between(pairs):
640 636 sys.stdout.write(" ".join(map(hex, b)) + "\n")
641 637
642 638 elif args['cmd'][0] == 'changegroup':
643 639 httphdr("application/hg-changegroup")
644 640 nodes = []
645 641 if self.viewonly:
646 642 return
647 643
648 644 if args.has_key('roots'):
649 645 nodes = map(bin, args['roots'][0].split(" "))
650 646
651 647 z = zlib.compressobj()
652 648 for chunk in self.repo.changegroup(nodes):
653 649 sys.stdout.write(z.compress(chunk))
654 650
655 651 sys.stdout.write(z.flush())
656 652
657 653 else:
658 654 write(self.t("error"))
659 655
660 656 def server(path, name, templates, address, port):
661 657
662 658 import BaseHTTPServer
663 659 import sys, os
664 660
665 661 class hgwebhandler(BaseHTTPServer.BaseHTTPRequestHandler):
666 662 def do_POST(self):
667 663 try:
668 664 self.do_hgweb()
669 665 except socket.error, inst:
670 666 if inst.args[0] != 32: raise
671 667
672 668 def do_GET(self):
673 669 self.do_POST()
674 670
675 671 def do_hgweb(self):
676 672 query = ""
677 673 p = self.path.find("?")
678 674 if p:
679 675 query = self.path[p + 1:]
680 676 query = query.replace('+', ' ')
681 677
682 678 env = {}
683 679 env['GATEWAY_INTERFACE'] = 'CGI/1.1'
684 680 env['REQUEST_METHOD'] = self.command
685 681 if query:
686 682 env['QUERY_STRING'] = query
687 683 host = self.address_string()
688 684 if host != self.client_address[0]:
689 685 env['REMOTE_HOST'] = host
690 686 env['REMOTE_ADDR'] = self.client_address[0]
691 687
692 688 if self.headers.typeheader is None:
693 689 env['CONTENT_TYPE'] = self.headers.type
694 690 else:
695 691 env['CONTENT_TYPE'] = self.headers.typeheader
696 692 length = self.headers.getheader('content-length')
697 693 if length:
698 694 env['CONTENT_LENGTH'] = length
699 695 accept = []
700 696 for line in self.headers.getallmatchingheaders('accept'):
701 697 if line[:1] in "\t\n\r ":
702 698 accept.append(line.strip())
703 699 else:
704 700 accept = accept + line[7:].split(',')
705 701 env['HTTP_ACCEPT'] = ','.join(accept)
706 702
707 703 os.environ.update(env)
708 704
709 705 save = sys.argv, sys.stdin, sys.stdout, sys.stderr
710 706 try:
711 707 sys.stdin = self.rfile
712 708 sys.stdout = self.wfile
713 709 sys.argv = ["hgweb.py"]
714 710 if '=' not in query:
715 711 sys.argv.append(query)
716 712 self.send_response(200, "Script output follows")
717 713 hg.run()
718 714 finally:
719 715 sys.argv, sys.stdin, sys.stdout, sys.stderr = save
720 716
721 717 hg = hgweb(path, name, templates)
722 718 httpd = BaseHTTPServer.HTTPServer((address, port), hgwebhandler)
723 719 httpd.serve_forever()
General Comments 0
You need to be logged in to leave comments. Login now