Show More
@@ -0,0 +1,16 b'' | |||||
|
1 | #!/usr/bin/env python | |||
|
2 | ||||
|
3 | __doc__ = """This does HTTP get requests given a host:port and path and returns | |||
|
4 | a subset of the headers plus the body of the result.""" | |||
|
5 | ||||
|
6 | import httplib, sys | |||
|
7 | headers = [h.lower() for h in sys.argv[3:]] | |||
|
8 | conn = httplib.HTTPConnection(sys.argv[1]) | |||
|
9 | conn.request("GET", sys.argv[2]) | |||
|
10 | response = conn.getresponse() | |||
|
11 | print response.status, response.reason | |||
|
12 | for h in headers: | |||
|
13 | if response.getheader(h, None) is not None: | |||
|
14 | print "%s: %s" % (h, response.getheader(h)) | |||
|
15 | ||||
|
16 | sys.stdout.write(response.read()) |
@@ -0,0 +1,103 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | hg init test | |||
|
4 | ||||
|
5 | cat >hgweb.cgi <<HGWEB | |||
|
6 | #!/usr/bin/env python | |||
|
7 | # | |||
|
8 | # An example CGI script to use hgweb, edit as necessary | |||
|
9 | ||||
|
10 | import cgitb, os, sys | |||
|
11 | cgitb.enable() | |||
|
12 | ||||
|
13 | # sys.path.insert(0, "/path/to/python/lib") # if not a system-wide install | |||
|
14 | from mercurial import hgweb | |||
|
15 | ||||
|
16 | h = hgweb.hgweb("test", "Empty test repository") | |||
|
17 | h.run() | |||
|
18 | HGWEB | |||
|
19 | chmod 755 hgweb.cgi | |||
|
20 | ||||
|
21 | cat >hgweb.config <<HGWEBDIRCONF | |||
|
22 | [paths] | |||
|
23 | test = test | |||
|
24 | HGWEBDIRCONF | |||
|
25 | ||||
|
26 | cat >hgwebdir.cgi <<HGWEBDIR | |||
|
27 | #!/usr/bin/env python | |||
|
28 | # | |||
|
29 | # An example CGI script to export multiple hgweb repos, edit as necessary | |||
|
30 | ||||
|
31 | import cgitb, sys | |||
|
32 | cgitb.enable() | |||
|
33 | ||||
|
34 | # sys.path.insert(0, "/path/to/python/lib") # if not a system-wide install | |||
|
35 | from mercurial import hgweb | |||
|
36 | ||||
|
37 | # The config file looks like this. You can have paths to individual | |||
|
38 | # repos, collections of repos in a directory tree, or both. | |||
|
39 | # | |||
|
40 | # [paths] | |||
|
41 | # virtual/path = /real/path | |||
|
42 | # virtual/path = /real/path | |||
|
43 | # | |||
|
44 | # [collections] | |||
|
45 | # /prefix/to/strip/off = /root/of/tree/full/of/repos | |||
|
46 | # | |||
|
47 | # collections example: say directory tree /foo contains repos /foo/bar, | |||
|
48 | # /foo/quux/baz. Give this config section: | |||
|
49 | # [collections] | |||
|
50 | # /foo = /foo | |||
|
51 | # Then repos will list as bar and quux/baz. | |||
|
52 | ||||
|
53 | # Alternatively you can pass a list of ('virtual/path', '/real/path') tuples | |||
|
54 | # or use a dictionary with entries like 'virtual/path': '/real/path' | |||
|
55 | ||||
|
56 | h = hgweb.hgwebdir("hgweb.config") | |||
|
57 | h.run() | |||
|
58 | HGWEBDIR | |||
|
59 | chmod 755 hgwebdir.cgi | |||
|
60 | ||||
|
61 | declare -x DOCUMENT_ROOT="/var/www/hg" | |||
|
62 | declare -x GATEWAY_INTERFACE="CGI/1.1" | |||
|
63 | declare -x HTTP_ACCEPT="text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" | |||
|
64 | declare -x HTTP_ACCEPT_CHARSET="ISO-8859-1,utf-8;q=0.7,*;q=0.7" | |||
|
65 | declare -x HTTP_ACCEPT_ENCODING="gzip,deflate" | |||
|
66 | declare -x HTTP_ACCEPT_LANGUAGE="en-us,en;q=0.5" | |||
|
67 | declare -x HTTP_CACHE_CONTROL="max-age=0" | |||
|
68 | declare -x HTTP_CONNECTION="keep-alive" | |||
|
69 | declare -x HTTP_HOST="hg.omnifarious.org" | |||
|
70 | declare -x HTTP_KEEP_ALIVE="300" | |||
|
71 | declare -x HTTP_USER_AGENT="Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.0.4) Gecko/20060608 Ubuntu/dapper-security Firefox/1.5.0.4" | |||
|
72 | declare -x OLDPWD | |||
|
73 | declare -x PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin" | |||
|
74 | declare -x PATH_INFO="/" | |||
|
75 | declare -x PATH_TRANSLATED="/var/www/hg/index.html" | |||
|
76 | declare -x PWD="/home/hopper/hg_public" | |||
|
77 | declare -x QUERY_STRING="" | |||
|
78 | declare -x REMOTE_ADDR="127.0.0.2" | |||
|
79 | declare -x REMOTE_PORT="44703" | |||
|
80 | declare -x REQUEST_METHOD="GET" | |||
|
81 | declare -x REQUEST_URI="/test/" | |||
|
82 | declare -x SCRIPT_FILENAME="/home/hopper/hg_public/test.cgi" | |||
|
83 | declare -x SCRIPT_NAME="/test" | |||
|
84 | declare -x SCRIPT_URI="http://hg.omnifarious.org/test/" | |||
|
85 | declare -x SCRIPT_URL="/test/" | |||
|
86 | declare -x SERVER_ADDR="127.0.0.1" | |||
|
87 | declare -x SERVER_ADMIN="eric@localhost" | |||
|
88 | declare -x SERVER_NAME="hg.omnifarious.org" | |||
|
89 | declare -x SERVER_PORT="80" | |||
|
90 | declare -x SERVER_PROTOCOL="HTTP/1.1" | |||
|
91 | declare -x SERVER_SIGNATURE="<address>Apache/2.0.53 (Fedora) Server at hg.omnifarious.org Port 80</address>\ | |||
|
92 | " | |||
|
93 | declare -x SERVER_SOFTWARE="Apache/2.0.53 (Fedora)" | |||
|
94 | ./hgweb.cgi >page1 2>&1 ; echo $? | |||
|
95 | ./hgwebdir.cgi >page2 2>&1 ; echo $? | |||
|
96 | PATH_INFO="/test/" | |||
|
97 | PATH_TRANSLATED="/var/something/test.cgi" | |||
|
98 | REQUEST_URI="/test/test/" | |||
|
99 | SCRIPT_URI="http://hg.omnifarious.org/test/test/" | |||
|
100 | SCRIPT_URL="/test/test/" | |||
|
101 | ./hgwebdir.cgi >page3 2>&1 ; echo $? | |||
|
102 | fgrep -i error page1 page2 page3 && exit 1 | |||
|
103 | exit 0 |
@@ -0,0 +1,20 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | hg init test | |||
|
4 | cd test | |||
|
5 | cat >sometext.txt <<ENDSOME | |||
|
6 | This is just some random text | |||
|
7 | that will go inside the file and take a few lines. | |||
|
8 | It is very boring to read, but computers don't | |||
|
9 | care about things like that. | |||
|
10 | ENDSOME | |||
|
11 | hg add sometext.txt | |||
|
12 | hg commit -d "1 0" -m "Just some text" | |||
|
13 | hg serve -p 20059 -A access.log -E error.log -d --pid-file=hg.pid | |||
|
14 | ("$TESTDIR/get-with-headers.py" localhost:20059 '/?f=f165dc289438;file=sometext.txt;style=raw' content-type content-length content-disposition) >getoutput.txt & | |||
|
15 | ||||
|
16 | sleep 5 | |||
|
17 | kill `cat hg.pid` | |||
|
18 | sleep 1 # wait for server to scream and die | |||
|
19 | cat getoutput.txt | |||
|
20 | cat access.log error.log | sed 's/^\([^[]*\[\)[^]]*\(\].*\)$/\1date\2/g' |
@@ -0,0 +1,10 b'' | |||||
|
1 | 200 Script output follows | |||
|
2 | content-type: text/plain | |||
|
3 | content-length: 157 | |||
|
4 | content-disposition: filename=sometext.txt | |||
|
5 | ||||
|
6 | This is just some random text | |||
|
7 | that will go inside the file and take a few lines. | |||
|
8 | It is very boring to read, but computers don't | |||
|
9 | care about things like that. | |||
|
10 | localhost - - [date] "GET /?f=f165dc289438;file=sometext.txt;style=raw HTTP/1.1" 200 - |
@@ -650,13 +650,28 b' class hgweb(object):' | |||||
650 | raise Exception("suspicious path") |
|
650 | raise Exception("suspicious path") | |
651 | return p |
|
651 | return p | |
652 |
|
652 | |||
653 |
def run(self |
|
653 | def run(self): | |
|
654 | if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."): | |||
|
655 | raise RuntimeError("This function is only intended to be called while running as a CGI script.") | |||
|
656 | import mercurial.hgweb.wsgicgi as wsgicgi | |||
|
657 | from request import wsgiapplication | |||
|
658 | def make_web_app(): | |||
|
659 | return self | |||
|
660 | wsgicgi.launch(wsgiapplication(make_web_app)) | |||
|
661 | ||||
|
662 | def run_wsgi(self, req): | |||
654 | def header(**map): |
|
663 | def header(**map): | |
655 | header_file = cStringIO.StringIO(''.join(self.t("header", **map))) |
|
664 | header_file = cStringIO.StringIO(''.join(self.t("header", **map))) | |
656 | msg = mimetools.Message(header_file, 0) |
|
665 | msg = mimetools.Message(header_file, 0) | |
657 | req.header(msg.items()) |
|
666 | req.header(msg.items()) | |
658 | yield header_file.read() |
|
667 | yield header_file.read() | |
659 |
|
668 | |||
|
669 | def rawfileheader(**map): | |||
|
670 | req.header([('Content-type', map['mimetype']), | |||
|
671 | ('Content-disposition', 'filename=%s' % map['file']), | |||
|
672 | ('Content-length', str(len(map['raw'])))]) | |||
|
673 | yield '' | |||
|
674 | ||||
660 | def footer(**map): |
|
675 | def footer(**map): | |
661 | yield self.t("footer", |
|
676 | yield self.t("footer", | |
662 | motd=self.repo.ui.config("web", "motd", ""), |
|
677 | motd=self.repo.ui.config("web", "motd", ""), | |
@@ -714,6 +729,7 b' class hgweb(object):' | |||||
714 | "repo": self.reponame, |
|
729 | "repo": self.reponame, | |
715 | "header": header, |
|
730 | "header": header, | |
716 | "footer": footer, |
|
731 | "footer": footer, | |
|
732 | "rawfileheader": rawfileheader, | |||
717 | }) |
|
733 | }) | |
718 |
|
734 | |||
719 | if not req.form.has_key('cmd'): |
|
735 | if not req.form.has_key('cmd'): |
@@ -46,7 +46,16 b' class hgwebdir(object):' | |||||
46 | self.repos.append((name.lstrip(os.sep), repo)) |
|
46 | self.repos.append((name.lstrip(os.sep), repo)) | |
47 | self.repos.sort() |
|
47 | self.repos.sort() | |
48 |
|
48 | |||
49 |
def run(self |
|
49 | def run(self): | |
|
50 | if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."): | |||
|
51 | raise RuntimeError("This function is only intended to be called while running as a CGI script.") | |||
|
52 | import mercurial.hgweb.wsgicgi as wsgicgi | |||
|
53 | from request import wsgiapplication | |||
|
54 | def make_web_app(): | |||
|
55 | return self | |||
|
56 | wsgicgi.launch(wsgiapplication(make_web_app)) | |||
|
57 | ||||
|
58 | def run_wsgi(self, req): | |||
50 | def header(**map): |
|
59 | def header(**map): | |
51 | header_file = cStringIO.StringIO(''.join(tmpl("header", **map))) |
|
60 | header_file = cStringIO.StringIO(''.join(tmpl("header", **map))) | |
52 | msg = mimetools.Message(header_file, 0) |
|
61 | msg = mimetools.Message(header_file, 0) | |
@@ -124,7 +133,7 b' class hgwebdir(object):' | |||||
124 | real = dict(self.repos).get(virtual) |
|
133 | real = dict(self.repos).get(virtual) | |
125 | if real: |
|
134 | if real: | |
126 | try: |
|
135 | try: | |
127 | hgweb(real).run(req) |
|
136 | hgweb(real).run_wsgi(req) | |
128 | except IOError, inst: |
|
137 | except IOError, inst: | |
129 | req.write(tmpl("error", error=inst.strerror)) |
|
138 | req.write(tmpl("error", error=inst.strerror)) | |
130 | except hg.RepoError, inst: |
|
139 | except hg.RepoError, inst: |
@@ -48,7 +48,7 b' class _wsgirequest(object):' | |||||
48 | self.form = cgi.parse(self.inp, self.env, keep_blank_values=1) |
|
48 | self.form = cgi.parse(self.inp, self.env, keep_blank_values=1) | |
49 | self.start_response = start_response |
|
49 | self.start_response = start_response | |
50 | self.headers = [] |
|
50 | self.headers = [] | |
51 | destination.run(self) |
|
51 | destination.run_wsgi(self) | |
52 |
|
52 | |||
53 | def __iter__(self): |
|
53 | def __iter__(self): | |
54 | return iter([]) |
|
54 | return iter([]) |
@@ -202,7 +202,7 b' def fill(text, width):' | |||||
202 | if para_re is None: |
|
202 | if para_re is None: | |
203 | para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M) |
|
203 | para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M) | |
204 | space_re = re.compile(r' +') |
|
204 | space_re = re.compile(r' +') | |
205 |
|
205 | |||
206 | def findparas(): |
|
206 | def findparas(): | |
207 | start = 0 |
|
207 | start = 0 | |
208 | while True: |
|
208 | while True: |
@@ -8,7 +8,7 b" diffline = '#line#'" | |||||
8 | changesetparent = '# Parent #node#' |
|
8 | changesetparent = '# Parent #node#' | |
9 | changesetchild = '# Child #node#' |
|
9 | changesetchild = '# Child #node#' | |
10 | filenodelink = '' |
|
10 | filenodelink = '' | |
11 | filerevision = 'Content-Type: #mimetype#\nContent-Disposition: filename=#file#\n\n#raw#' |
|
11 | filerevision = '#rawfileheader##raw#' | |
12 | fileline = '#line#' |
|
12 | fileline = '#line#' | |
13 | diffblock = '#lines#' |
|
13 | diffblock = '#lines#' | |
14 | filediff = filediff-raw.tmpl |
|
14 | filediff = filediff-raw.tmpl |
General Comments 0
You need to be logged in to leave comments.
Login now