##// END OF EJS Templates
py3: encode JSON str to bytes...
Gregory Szorc -
r40190:fe11fc7e default
parent child Browse files
Show More
@@ -1,112 +1,113 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2
2
3 """This does HTTP GET requests given a host:port and path and returns
3 """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."""
4 a subset of the headers plus the body of the result."""
5
5
6 from __future__ import absolute_import
6 from __future__ import absolute_import
7
7
8 import argparse
8 import argparse
9 import json
9 import json
10 import os
10 import os
11 import sys
11 import sys
12
12
13 from mercurial import (
13 from mercurial import (
14 pycompat,
14 util,
15 util,
15 )
16 )
16
17
17 httplib = util.httplib
18 httplib = util.httplib
18
19
19 try:
20 try:
20 import msvcrt
21 import msvcrt
21 msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
22 msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
22 msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
23 msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
23 except ImportError:
24 except ImportError:
24 pass
25 pass
25
26
26 stdout = getattr(sys.stdout, 'buffer', sys.stdout)
27 stdout = getattr(sys.stdout, 'buffer', sys.stdout)
27
28
28 parser = argparse.ArgumentParser()
29 parser = argparse.ArgumentParser()
29 parser.add_argument('--twice', action='store_true')
30 parser.add_argument('--twice', action='store_true')
30 parser.add_argument('--headeronly', action='store_true')
31 parser.add_argument('--headeronly', action='store_true')
31 parser.add_argument('--json', action='store_true')
32 parser.add_argument('--json', action='store_true')
32 parser.add_argument('--hgproto')
33 parser.add_argument('--hgproto')
33 parser.add_argument('--requestheader', nargs='*', default=[],
34 parser.add_argument('--requestheader', nargs='*', default=[],
34 help='Send an additional HTTP request header. Argument '
35 help='Send an additional HTTP request header. Argument '
35 'value is <header>=<value>')
36 'value is <header>=<value>')
36 parser.add_argument('--bodyfile',
37 parser.add_argument('--bodyfile',
37 help='Write HTTP response body to a file')
38 help='Write HTTP response body to a file')
38 parser.add_argument('host')
39 parser.add_argument('host')
39 parser.add_argument('path')
40 parser.add_argument('path')
40 parser.add_argument('show', nargs='*')
41 parser.add_argument('show', nargs='*')
41
42
42 args = parser.parse_args()
43 args = parser.parse_args()
43
44
44 twice = args.twice
45 twice = args.twice
45 headeronly = args.headeronly
46 headeronly = args.headeronly
46 formatjson = args.json
47 formatjson = args.json
47 hgproto = args.hgproto
48 hgproto = args.hgproto
48 requestheaders = args.requestheader
49 requestheaders = args.requestheader
49
50
50 tag = None
51 tag = None
51 def request(host, path, show):
52 def request(host, path, show):
52 assert not path.startswith('/'), path
53 assert not path.startswith('/'), path
53 global tag
54 global tag
54 headers = {}
55 headers = {}
55 if tag:
56 if tag:
56 headers['If-None-Match'] = tag
57 headers['If-None-Match'] = tag
57 if hgproto:
58 if hgproto:
58 headers['X-HgProto-1'] = hgproto
59 headers['X-HgProto-1'] = hgproto
59
60
60 for header in requestheaders:
61 for header in requestheaders:
61 key, value = header.split('=', 1)
62 key, value = header.split('=', 1)
62 headers[key] = value
63 headers[key] = value
63
64
64 conn = httplib.HTTPConnection(host)
65 conn = httplib.HTTPConnection(host)
65 conn.request("GET", '/' + path, None, headers)
66 conn.request("GET", '/' + path, None, headers)
66 response = conn.getresponse()
67 response = conn.getresponse()
67 stdout.write(b'%d %s\n' % (response.status,
68 stdout.write(b'%d %s\n' % (response.status,
68 response.reason.encode('ascii')))
69 response.reason.encode('ascii')))
69 if show[:1] == ['-']:
70 if show[:1] == ['-']:
70 show = sorted(h for h, v in response.getheaders()
71 show = sorted(h for h, v in response.getheaders()
71 if h.lower() not in show)
72 if h.lower() not in show)
72 for h in [h.lower() for h in show]:
73 for h in [h.lower() for h in show]:
73 if response.getheader(h, None) is not None:
74 if response.getheader(h, None) is not None:
74 stdout.write(b"%s: %s\n" % (h.encode('ascii'),
75 stdout.write(b"%s: %s\n" % (h.encode('ascii'),
75 response.getheader(h).encode('ascii')))
76 response.getheader(h).encode('ascii')))
76 if not headeronly:
77 if not headeronly:
77 stdout.write(b'\n')
78 stdout.write(b'\n')
78 data = response.read()
79 data = response.read()
79
80
80 if args.bodyfile:
81 if args.bodyfile:
81 bodyfh = open(args.bodyfile, 'wb')
82 bodyfh = open(args.bodyfile, 'wb')
82 else:
83 else:
83 bodyfh = stdout
84 bodyfh = stdout
84
85
85 # Pretty print JSON. This also has the beneficial side-effect
86 # Pretty print JSON. This also has the beneficial side-effect
86 # of verifying emitted JSON is well-formed.
87 # of verifying emitted JSON is well-formed.
87 if formatjson:
88 if formatjson:
88 # json.dumps() will print trailing newlines. Eliminate them
89 # json.dumps() will print trailing newlines. Eliminate them
89 # to make tests easier to write.
90 # to make tests easier to write.
90 data = json.loads(data)
91 data = json.loads(data)
91 lines = json.dumps(data, sort_keys=True, indent=2).splitlines()
92 lines = json.dumps(data, sort_keys=True, indent=2).splitlines()
92 for line in lines:
93 for line in lines:
93 bodyfh.write(line.rstrip())
94 bodyfh.write(pycompat.sysbytes(line.rstrip()))
94 bodyfh.write(b'\n')
95 bodyfh.write(b'\n')
95 else:
96 else:
96 bodyfh.write(data)
97 bodyfh.write(data)
97
98
98 if args.bodyfile:
99 if args.bodyfile:
99 bodyfh.close()
100 bodyfh.close()
100
101
101 if twice and response.getheader('ETag', None):
102 if twice and response.getheader('ETag', None):
102 tag = response.getheader('ETag')
103 tag = response.getheader('ETag')
103
104
104 return response.status
105 return response.status
105
106
106 status = request(args.host, args.path, args.show)
107 status = request(args.host, args.path, args.show)
107 if twice:
108 if twice:
108 status = request(args.host, args.path, args.show)
109 status = request(args.host, args.path, args.show)
109
110
110 if 200 <= status <= 305:
111 if 200 <= status <= 305:
111 sys.exit(0)
112 sys.exit(0)
112 sys.exit(1)
113 sys.exit(1)
General Comments 0
You need to be logged in to leave comments. Login now