googlecloud 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +4 -0
  3. data/LICENSE +674 -0
  4. data/Manifest +111 -0
  5. data/README.md +4 -3
  6. data/bin/gcutil +53 -0
  7. data/googlecloud.gemspec +4 -3
  8. data/packages/gcutil-1.7.1/CHANGELOG +197 -0
  9. data/packages/gcutil-1.7.1/LICENSE +202 -0
  10. data/packages/gcutil-1.7.1/VERSION +1 -0
  11. data/packages/gcutil-1.7.1/gcutil +53 -0
  12. data/packages/gcutil-1.7.1/lib/google_api_python_client/LICENSE +23 -0
  13. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/__init__.py +1 -0
  14. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/discovery.py +743 -0
  15. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/errors.py +123 -0
  16. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/ext/__init__.py +0 -0
  17. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/http.py +1443 -0
  18. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/mimeparse.py +172 -0
  19. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/model.py +385 -0
  20. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/schema.py +303 -0
  21. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/__init__.py +1 -0
  22. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/anyjson.py +32 -0
  23. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/appengine.py +528 -0
  24. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/client.py +1139 -0
  25. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/clientsecrets.py +105 -0
  26. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/crypt.py +244 -0
  27. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/django_orm.py +124 -0
  28. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/file.py +107 -0
  29. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/locked_file.py +343 -0
  30. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/multistore_file.py +379 -0
  31. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/tools.py +174 -0
  32. data/packages/gcutil-1.7.1/lib/google_api_python_client/uritemplate/__init__.py +147 -0
  33. data/packages/gcutil-1.7.1/lib/google_apputils/LICENSE +202 -0
  34. data/packages/gcutil-1.7.1/lib/google_apputils/google/__init__.py +3 -0
  35. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/__init__.py +3 -0
  36. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/app.py +356 -0
  37. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.py +783 -0
  38. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/basetest.py +1260 -0
  39. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/datelib.py +421 -0
  40. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/debug.py +60 -0
  41. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/file_util.py +181 -0
  42. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/resources.py +67 -0
  43. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/run_script_module.py +217 -0
  44. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/setup_command.py +159 -0
  45. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/shellutil.py +49 -0
  46. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/stopwatch.py +204 -0
  47. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/__init__.py +0 -0
  48. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auth_helper.py +140 -0
  49. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auth_helper_test.py +149 -0
  50. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auto_auth.py +130 -0
  51. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auto_auth_test.py +75 -0
  52. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/basic_cmds.py +128 -0
  53. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/basic_cmds_test.py +111 -0
  54. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/command_base.py +1808 -0
  55. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/command_base_test.py +1651 -0
  56. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/compute/v1beta13.json +2851 -0
  57. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/compute/v1beta14.json +3361 -0
  58. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/disk_cmds.py +342 -0
  59. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/disk_cmds_test.py +474 -0
  60. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/firewall_cmds.py +344 -0
  61. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/firewall_cmds_test.py +231 -0
  62. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/flags_cache.py +274 -0
  63. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/gcutil +89 -0
  64. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/gcutil_logging.py +69 -0
  65. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/image_cmds.py +262 -0
  66. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/image_cmds_test.py +172 -0
  67. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/instance_cmds.py +1506 -0
  68. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/instance_cmds_test.py +1904 -0
  69. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/kernel_cmds.py +91 -0
  70. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/kernel_cmds_test.py +56 -0
  71. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/machine_type_cmds.py +106 -0
  72. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/machine_type_cmds_test.py +59 -0
  73. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata.py +96 -0
  74. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata_lib.py +357 -0
  75. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata_test.py +84 -0
  76. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/mock_api.py +420 -0
  77. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/mock_metadata.py +58 -0
  78. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/move_cmds.py +824 -0
  79. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/move_cmds_test.py +307 -0
  80. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/network_cmds.py +178 -0
  81. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/network_cmds_test.py +133 -0
  82. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/operation_cmds.py +181 -0
  83. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/operation_cmds_test.py +196 -0
  84. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/path_initializer.py +38 -0
  85. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/project_cmds.py +173 -0
  86. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/project_cmds_test.py +111 -0
  87. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/scopes.py +61 -0
  88. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/scopes_test.py +50 -0
  89. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/snapshot_cmds.py +276 -0
  90. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/snapshot_cmds_test.py +260 -0
  91. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/ssh_keys.py +266 -0
  92. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/ssh_keys_test.py +128 -0
  93. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/table_formatter.py +563 -0
  94. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/thread_pool.py +188 -0
  95. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/thread_pool_test.py +88 -0
  96. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/utils.py +208 -0
  97. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/utils_test.py +193 -0
  98. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version.py +17 -0
  99. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version_checker.py +246 -0
  100. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version_checker_test.py +271 -0
  101. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/zone_cmds.py +151 -0
  102. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/zone_cmds_test.py +60 -0
  103. data/packages/gcutil-1.7.1/lib/httplib2/LICENSE +21 -0
  104. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/__init__.py +1630 -0
  105. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/cacerts.txt +714 -0
  106. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/iri2uri.py +110 -0
  107. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/socks.py +438 -0
  108. data/packages/gcutil-1.7.1/lib/iso8601/LICENSE +20 -0
  109. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/__init__.py +1 -0
  110. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/iso8601.py +102 -0
  111. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/test_iso8601.py +111 -0
  112. data/packages/gcutil-1.7.1/lib/python_gflags/AUTHORS +2 -0
  113. data/packages/gcutil-1.7.1/lib/python_gflags/LICENSE +28 -0
  114. data/packages/gcutil-1.7.1/lib/python_gflags/gflags.py +2862 -0
  115. data/packages/gcutil-1.7.1/lib/python_gflags/gflags2man.py +544 -0
  116. data/packages/gcutil-1.7.1/lib/python_gflags/gflags_validators.py +187 -0
  117. metadata +118 -5
  118. metadata.gz.sig +0 -0
@@ -0,0 +1,110 @@
1
+ """
2
+ iri2uri
3
+
4
+ Converts an IRI to a URI.
5
+
6
+ """
7
+ __author__ = "Joe Gregorio (joe@bitworking.org)"
8
+ __copyright__ = "Copyright 2006, Joe Gregorio"
9
+ __contributors__ = []
10
+ __version__ = "1.0.0"
11
+ __license__ = "MIT"
12
+ __history__ = """
13
+ """
14
+
15
+ import urlparse
16
+
17
+
18
+ # Convert an IRI to a URI following the rules in RFC 3987
19
+ #
20
+ # The characters we need to enocde and escape are defined in the spec:
21
+ #
22
+ # iprivate = %xE000-F8FF / %xF0000-FFFFD / %x100000-10FFFD
23
+ # ucschar = %xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
24
+ # / %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
25
+ # / %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
26
+ # / %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
27
+ # / %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
28
+ # / %xD0000-DFFFD / %xE1000-EFFFD
29
+
30
+ escape_range = [
31
+ (0xA0, 0xD7FF ),
32
+ (0xE000, 0xF8FF ),
33
+ (0xF900, 0xFDCF ),
34
+ (0xFDF0, 0xFFEF),
35
+ (0x10000, 0x1FFFD ),
36
+ (0x20000, 0x2FFFD ),
37
+ (0x30000, 0x3FFFD),
38
+ (0x40000, 0x4FFFD ),
39
+ (0x50000, 0x5FFFD ),
40
+ (0x60000, 0x6FFFD),
41
+ (0x70000, 0x7FFFD ),
42
+ (0x80000, 0x8FFFD ),
43
+ (0x90000, 0x9FFFD),
44
+ (0xA0000, 0xAFFFD ),
45
+ (0xB0000, 0xBFFFD ),
46
+ (0xC0000, 0xCFFFD),
47
+ (0xD0000, 0xDFFFD ),
48
+ (0xE1000, 0xEFFFD),
49
+ (0xF0000, 0xFFFFD ),
50
+ (0x100000, 0x10FFFD)
51
+ ]
52
+
53
+ def encode(c):
54
+ retval = c
55
+ i = ord(c)
56
+ for low, high in escape_range:
57
+ if i < low:
58
+ break
59
+ if i >= low and i <= high:
60
+ retval = "".join(["%%%2X" % ord(o) for o in c.encode('utf-8')])
61
+ break
62
+ return retval
63
+
64
+
65
+ def iri2uri(uri):
66
+ """Convert an IRI to a URI. Note that IRIs must be
67
+ passed in a unicode strings. That is, do not utf-8 encode
68
+ the IRI before passing it into the function."""
69
+ if isinstance(uri ,unicode):
70
+ (scheme, authority, path, query, fragment) = urlparse.urlsplit(uri)
71
+ authority = authority.encode('idna')
72
+ # For each character in 'ucschar' or 'iprivate'
73
+ # 1. encode as utf-8
74
+ # 2. then %-encode each octet of that utf-8
75
+ uri = urlparse.urlunsplit((scheme, authority, path, query, fragment))
76
+ uri = "".join([encode(c) for c in uri])
77
+ return uri
78
+
79
+ if __name__ == "__main__":
80
+ import unittest
81
+
82
+ class Test(unittest.TestCase):
83
+
84
+ def test_uris(self):
85
+ """Test that URIs are invariant under the transformation."""
86
+ invariant = [
87
+ u"ftp://ftp.is.co.za/rfc/rfc1808.txt",
88
+ u"http://www.ietf.org/rfc/rfc2396.txt",
89
+ u"ldap://[2001:db8::7]/c=GB?objectClass?one",
90
+ u"mailto:John.Doe@example.com",
91
+ u"news:comp.infosystems.www.servers.unix",
92
+ u"tel:+1-816-555-1212",
93
+ u"telnet://192.0.2.16:80/",
94
+ u"urn:oasis:names:specification:docbook:dtd:xml:4.1.2" ]
95
+ for uri in invariant:
96
+ self.assertEqual(uri, iri2uri(uri))
97
+
98
+ def test_iri(self):
99
+ """ Test that the right type of escaping is done for each part of the URI."""
100
+ self.assertEqual("http://xn--o3h.com/%E2%98%84", iri2uri(u"http://\N{COMET}.com/\N{COMET}"))
101
+ self.assertEqual("http://bitworking.org/?fred=%E2%98%84", iri2uri(u"http://bitworking.org/?fred=\N{COMET}"))
102
+ self.assertEqual("http://bitworking.org/#%E2%98%84", iri2uri(u"http://bitworking.org/#\N{COMET}"))
103
+ self.assertEqual("#%E2%98%84", iri2uri(u"#\N{COMET}"))
104
+ self.assertEqual("/fred?bar=%E2%98%9A#%E2%98%84", iri2uri(u"/fred?bar=\N{BLACK LEFT POINTING INDEX}#\N{COMET}"))
105
+ self.assertEqual("/fred?bar=%E2%98%9A#%E2%98%84", iri2uri(iri2uri(u"/fred?bar=\N{BLACK LEFT POINTING INDEX}#\N{COMET}")))
106
+ self.assertNotEqual("/fred?bar=%E2%98%9A#%E2%98%84", iri2uri(u"/fred?bar=\N{BLACK LEFT POINTING INDEX}#\N{COMET}".encode('utf-8')))
107
+
108
+ unittest.main()
109
+
110
+
@@ -0,0 +1,438 @@
1
+ """SocksiPy - Python SOCKS module.
2
+ Version 1.00
3
+
4
+ Copyright 2006 Dan-Haim. All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without modification,
7
+ are permitted provided that the following conditions are met:
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+ 2. Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+ 3. Neither the name of Dan Haim nor the names of his contributors may be used
14
+ to endorse or promote products derived from this software without specific
15
+ prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY DAN HAIM "AS IS" AND ANY EXPRESS OR IMPLIED
18
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20
+ EVENT SHALL DAN HAIM OR HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA
23
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMANGE.
26
+
27
+
28
+ This module provides a standard socket-like interface for Python
29
+ for tunneling connections through SOCKS proxies.
30
+
31
+ """
32
+
33
+ """
34
+
35
+ Minor modifications made by Christopher Gilbert (http://motomastyle.com/)
36
+ for use in PyLoris (http://pyloris.sourceforge.net/)
37
+
38
+ Minor modifications made by Mario Vilas (http://breakingcode.wordpress.com/)
39
+ mainly to merge bug fixes found in Sourceforge
40
+
41
+ """
42
+
43
+ import base64
44
+ import socket
45
+ import struct
46
+ import sys
47
+
48
+ if getattr(socket, 'socket', None) is None:
49
+ raise ImportError('socket.socket missing, proxy support unusable')
50
+
51
+ PROXY_TYPE_SOCKS4 = 1
52
+ PROXY_TYPE_SOCKS5 = 2
53
+ PROXY_TYPE_HTTP = 3
54
+ PROXY_TYPE_HTTP_NO_TUNNEL = 4
55
+
56
+ _defaultproxy = None
57
+ _orgsocket = socket.socket
58
+
59
+ class ProxyError(Exception): pass
60
+ class GeneralProxyError(ProxyError): pass
61
+ class Socks5AuthError(ProxyError): pass
62
+ class Socks5Error(ProxyError): pass
63
+ class Socks4Error(ProxyError): pass
64
+ class HTTPError(ProxyError): pass
65
+
66
+ _generalerrors = ("success",
67
+ "invalid data",
68
+ "not connected",
69
+ "not available",
70
+ "bad proxy type",
71
+ "bad input")
72
+
73
+ _socks5errors = ("succeeded",
74
+ "general SOCKS server failure",
75
+ "connection not allowed by ruleset",
76
+ "Network unreachable",
77
+ "Host unreachable",
78
+ "Connection refused",
79
+ "TTL expired",
80
+ "Command not supported",
81
+ "Address type not supported",
82
+ "Unknown error")
83
+
84
+ _socks5autherrors = ("succeeded",
85
+ "authentication is required",
86
+ "all offered authentication methods were rejected",
87
+ "unknown username or invalid password",
88
+ "unknown error")
89
+
90
+ _socks4errors = ("request granted",
91
+ "request rejected or failed",
92
+ "request rejected because SOCKS server cannot connect to identd on the client",
93
+ "request rejected because the client program and identd report different user-ids",
94
+ "unknown error")
95
+
96
+ def setdefaultproxy(proxytype=None, addr=None, port=None, rdns=True, username=None, password=None):
97
+ """setdefaultproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
98
+ Sets a default proxy which all further socksocket objects will use,
99
+ unless explicitly changed.
100
+ """
101
+ global _defaultproxy
102
+ _defaultproxy = (proxytype, addr, port, rdns, username, password)
103
+
104
+ def wrapmodule(module):
105
+ """wrapmodule(module)
106
+ Attempts to replace a module's socket library with a SOCKS socket. Must set
107
+ a default proxy using setdefaultproxy(...) first.
108
+ This will only work on modules that import socket directly into the namespace;
109
+ most of the Python Standard Library falls into this category.
110
+ """
111
+ if _defaultproxy != None:
112
+ module.socket.socket = socksocket
113
+ else:
114
+ raise GeneralProxyError((4, "no proxy specified"))
115
+
116
+ class socksocket(socket.socket):
117
+ """socksocket([family[, type[, proto]]]) -> socket object
118
+ Open a SOCKS enabled socket. The parameters are the same as
119
+ those of the standard socket init. In order for SOCKS to work,
120
+ you must specify family=AF_INET, type=SOCK_STREAM and proto=0.
121
+ """
122
+
123
+ def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None):
124
+ _orgsocket.__init__(self, family, type, proto, _sock)
125
+ if _defaultproxy != None:
126
+ self.__proxy = _defaultproxy
127
+ else:
128
+ self.__proxy = (None, None, None, None, None, None)
129
+ self.__proxysockname = None
130
+ self.__proxypeername = None
131
+ self.__httptunnel = True
132
+
133
+ def __recvall(self, count):
134
+ """__recvall(count) -> data
135
+ Receive EXACTLY the number of bytes requested from the socket.
136
+ Blocks until the required number of bytes have been received.
137
+ """
138
+ data = self.recv(count)
139
+ while len(data) < count:
140
+ d = self.recv(count-len(data))
141
+ if not d: raise GeneralProxyError((0, "connection closed unexpectedly"))
142
+ data = data + d
143
+ return data
144
+
145
+ def sendall(self, content, *args):
146
+ """ override socket.socket.sendall method to rewrite the header
147
+ for non-tunneling proxies if needed
148
+ """
149
+ if not self.__httptunnel:
150
+ content = self.__rewriteproxy(content)
151
+ return super(socksocket, self).sendall(content, *args)
152
+
153
+ def __rewriteproxy(self, header):
154
+ """ rewrite HTTP request headers to support non-tunneling proxies
155
+ (i.e. those which do not support the CONNECT method).
156
+ This only works for HTTP (not HTTPS) since HTTPS requires tunneling.
157
+ """
158
+ host, endpt = None, None
159
+ hdrs = header.split("\r\n")
160
+ for hdr in hdrs:
161
+ if hdr.lower().startswith("host:"):
162
+ host = hdr
163
+ elif hdr.lower().startswith("get") or hdr.lower().startswith("post"):
164
+ endpt = hdr
165
+ if host and endpt:
166
+ hdrs.remove(host)
167
+ hdrs.remove(endpt)
168
+ host = host.split(" ")[1]
169
+ endpt = endpt.split(" ")
170
+ if (self.__proxy[4] != None and self.__proxy[5] != None):
171
+ hdrs.insert(0, self.__getauthheader())
172
+ hdrs.insert(0, "Host: %s" % host)
173
+ hdrs.insert(0, "%s http://%s%s %s" % (endpt[0], host, endpt[1], endpt[2]))
174
+ return "\r\n".join(hdrs)
175
+
176
+ def __getauthheader(self):
177
+ auth = self.__proxy[4] + ":" + self.__proxy[5]
178
+ return "Proxy-Authorization: Basic " + base64.b64encode(auth)
179
+
180
+ def setproxy(self, proxytype=None, addr=None, port=None, rdns=True, username=None, password=None):
181
+ """setproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
182
+ Sets the proxy to be used.
183
+ proxytype - The type of the proxy to be used. Three types
184
+ are supported: PROXY_TYPE_SOCKS4 (including socks4a),
185
+ PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP
186
+ addr - The address of the server (IP or DNS).
187
+ port - The port of the server. Defaults to 1080 for SOCKS
188
+ servers and 8080 for HTTP proxy servers.
189
+ rdns - Should DNS queries be preformed on the remote side
190
+ (rather than the local side). The default is True.
191
+ Note: This has no effect with SOCKS4 servers.
192
+ username - Username to authenticate with to the server.
193
+ The default is no authentication.
194
+ password - Password to authenticate with to the server.
195
+ Only relevant when username is also provided.
196
+ """
197
+ self.__proxy = (proxytype, addr, port, rdns, username, password)
198
+
199
+ def __negotiatesocks5(self, destaddr, destport):
200
+ """__negotiatesocks5(self,destaddr,destport)
201
+ Negotiates a connection through a SOCKS5 server.
202
+ """
203
+ # First we'll send the authentication packages we support.
204
+ if (self.__proxy[4]!=None) and (self.__proxy[5]!=None):
205
+ # The username/password details were supplied to the
206
+ # setproxy method so we support the USERNAME/PASSWORD
207
+ # authentication (in addition to the standard none).
208
+ self.sendall(struct.pack('BBBB', 0x05, 0x02, 0x00, 0x02))
209
+ else:
210
+ # No username/password were entered, therefore we
211
+ # only support connections with no authentication.
212
+ self.sendall(struct.pack('BBB', 0x05, 0x01, 0x00))
213
+ # We'll receive the server's response to determine which
214
+ # method was selected
215
+ chosenauth = self.__recvall(2)
216
+ if chosenauth[0:1] != chr(0x05).encode():
217
+ self.close()
218
+ raise GeneralProxyError((1, _generalerrors[1]))
219
+ # Check the chosen authentication method
220
+ if chosenauth[1:2] == chr(0x00).encode():
221
+ # No authentication is required
222
+ pass
223
+ elif chosenauth[1:2] == chr(0x02).encode():
224
+ # Okay, we need to perform a basic username/password
225
+ # authentication.
226
+ self.sendall(chr(0x01).encode() + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5])
227
+ authstat = self.__recvall(2)
228
+ if authstat[0:1] != chr(0x01).encode():
229
+ # Bad response
230
+ self.close()
231
+ raise GeneralProxyError((1, _generalerrors[1]))
232
+ if authstat[1:2] != chr(0x00).encode():
233
+ # Authentication failed
234
+ self.close()
235
+ raise Socks5AuthError((3, _socks5autherrors[3]))
236
+ # Authentication succeeded
237
+ else:
238
+ # Reaching here is always bad
239
+ self.close()
240
+ if chosenauth[1] == chr(0xFF).encode():
241
+ raise Socks5AuthError((2, _socks5autherrors[2]))
242
+ else:
243
+ raise GeneralProxyError((1, _generalerrors[1]))
244
+ # Now we can request the actual connection
245
+ req = struct.pack('BBB', 0x05, 0x01, 0x00)
246
+ # If the given destination address is an IP address, we'll
247
+ # use the IPv4 address request even if remote resolving was specified.
248
+ try:
249
+ ipaddr = socket.inet_aton(destaddr)
250
+ req = req + chr(0x01).encode() + ipaddr
251
+ except socket.error:
252
+ # Well it's not an IP number, so it's probably a DNS name.
253
+ if self.__proxy[3]:
254
+ # Resolve remotely
255
+ ipaddr = None
256
+ req = req + chr(0x03).encode() + chr(len(destaddr)).encode() + destaddr
257
+ else:
258
+ # Resolve locally
259
+ ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
260
+ req = req + chr(0x01).encode() + ipaddr
261
+ req = req + struct.pack(">H", destport)
262
+ self.sendall(req)
263
+ # Get the response
264
+ resp = self.__recvall(4)
265
+ if resp[0:1] != chr(0x05).encode():
266
+ self.close()
267
+ raise GeneralProxyError((1, _generalerrors[1]))
268
+ elif resp[1:2] != chr(0x00).encode():
269
+ # Connection failed
270
+ self.close()
271
+ if ord(resp[1:2])<=8:
272
+ raise Socks5Error((ord(resp[1:2]), _socks5errors[ord(resp[1:2])]))
273
+ else:
274
+ raise Socks5Error((9, _socks5errors[9]))
275
+ # Get the bound address/port
276
+ elif resp[3:4] == chr(0x01).encode():
277
+ boundaddr = self.__recvall(4)
278
+ elif resp[3:4] == chr(0x03).encode():
279
+ resp = resp + self.recv(1)
280
+ boundaddr = self.__recvall(ord(resp[4:5]))
281
+ else:
282
+ self.close()
283
+ raise GeneralProxyError((1,_generalerrors[1]))
284
+ boundport = struct.unpack(">H", self.__recvall(2))[0]
285
+ self.__proxysockname = (boundaddr, boundport)
286
+ if ipaddr != None:
287
+ self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)
288
+ else:
289
+ self.__proxypeername = (destaddr, destport)
290
+
291
+ def getproxysockname(self):
292
+ """getsockname() -> address info
293
+ Returns the bound IP address and port number at the proxy.
294
+ """
295
+ return self.__proxysockname
296
+
297
+ def getproxypeername(self):
298
+ """getproxypeername() -> address info
299
+ Returns the IP and port number of the proxy.
300
+ """
301
+ return _orgsocket.getpeername(self)
302
+
303
+ def getpeername(self):
304
+ """getpeername() -> address info
305
+ Returns the IP address and port number of the destination
306
+ machine (note: getproxypeername returns the proxy)
307
+ """
308
+ return self.__proxypeername
309
+
310
+ def __negotiatesocks4(self,destaddr,destport):
311
+ """__negotiatesocks4(self,destaddr,destport)
312
+ Negotiates a connection through a SOCKS4 server.
313
+ """
314
+ # Check if the destination address provided is an IP address
315
+ rmtrslv = False
316
+ try:
317
+ ipaddr = socket.inet_aton(destaddr)
318
+ except socket.error:
319
+ # It's a DNS name. Check where it should be resolved.
320
+ if self.__proxy[3]:
321
+ ipaddr = struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01)
322
+ rmtrslv = True
323
+ else:
324
+ ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
325
+ # Construct the request packet
326
+ req = struct.pack(">BBH", 0x04, 0x01, destport) + ipaddr
327
+ # The username parameter is considered userid for SOCKS4
328
+ if self.__proxy[4] != None:
329
+ req = req + self.__proxy[4]
330
+ req = req + chr(0x00).encode()
331
+ # DNS name if remote resolving is required
332
+ # NOTE: This is actually an extension to the SOCKS4 protocol
333
+ # called SOCKS4A and may not be supported in all cases.
334
+ if rmtrslv:
335
+ req = req + destaddr + chr(0x00).encode()
336
+ self.sendall(req)
337
+ # Get the response from the server
338
+ resp = self.__recvall(8)
339
+ if resp[0:1] != chr(0x00).encode():
340
+ # Bad data
341
+ self.close()
342
+ raise GeneralProxyError((1,_generalerrors[1]))
343
+ if resp[1:2] != chr(0x5A).encode():
344
+ # Server returned an error
345
+ self.close()
346
+ if ord(resp[1:2]) in (91, 92, 93):
347
+ self.close()
348
+ raise Socks4Error((ord(resp[1:2]), _socks4errors[ord(resp[1:2]) - 90]))
349
+ else:
350
+ raise Socks4Error((94, _socks4errors[4]))
351
+ # Get the bound address/port
352
+ self.__proxysockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0])
353
+ if rmtrslv != None:
354
+ self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)
355
+ else:
356
+ self.__proxypeername = (destaddr, destport)
357
+
358
+ def __negotiatehttp(self, destaddr, destport):
359
+ """__negotiatehttp(self,destaddr,destport)
360
+ Negotiates a connection through an HTTP server.
361
+ """
362
+ # If we need to resolve locally, we do this now
363
+ if not self.__proxy[3]:
364
+ addr = socket.gethostbyname(destaddr)
365
+ else:
366
+ addr = destaddr
367
+ headers = ["CONNECT ", addr, ":", str(destport), " HTTP/1.1\r\n"]
368
+ headers += ["Host: ", destaddr, "\r\n"]
369
+ if (self.__proxy[4] != None and self.__proxy[5] != None):
370
+ headers += [self.__getauthheader(), "\r\n"]
371
+ headers.append("\r\n")
372
+ self.sendall("".join(headers).encode())
373
+ # We read the response until we get the string "\r\n\r\n"
374
+ resp = self.recv(1)
375
+ while resp.find("\r\n\r\n".encode()) == -1:
376
+ resp = resp + self.recv(1)
377
+ # We just need the first line to check if the connection
378
+ # was successful
379
+ statusline = resp.splitlines()[0].split(" ".encode(), 2)
380
+ if statusline[0] not in ("HTTP/1.0".encode(), "HTTP/1.1".encode()):
381
+ self.close()
382
+ raise GeneralProxyError((1, _generalerrors[1]))
383
+ try:
384
+ statuscode = int(statusline[1])
385
+ except ValueError:
386
+ self.close()
387
+ raise GeneralProxyError((1, _generalerrors[1]))
388
+ if statuscode != 200:
389
+ self.close()
390
+ raise HTTPError((statuscode, statusline[2]))
391
+ self.__proxysockname = ("0.0.0.0", 0)
392
+ self.__proxypeername = (addr, destport)
393
+
394
+ def connect(self, destpair):
395
+ """connect(self, despair)
396
+ Connects to the specified destination through a proxy.
397
+ destpar - A tuple of the IP/DNS address and the port number.
398
+ (identical to socket's connect).
399
+ To select the proxy server use setproxy().
400
+ """
401
+ # Do a minimal input check first
402
+ if (not type(destpair) in (list,tuple)) or (len(destpair) < 2) or (not isinstance(destpair[0], basestring)) or (type(destpair[1]) != int):
403
+ raise GeneralProxyError((5, _generalerrors[5]))
404
+ if self.__proxy[0] == PROXY_TYPE_SOCKS5:
405
+ if self.__proxy[2] != None:
406
+ portnum = self.__proxy[2]
407
+ else:
408
+ portnum = 1080
409
+ _orgsocket.connect(self, (self.__proxy[1], portnum))
410
+ self.__negotiatesocks5(destpair[0], destpair[1])
411
+ elif self.__proxy[0] == PROXY_TYPE_SOCKS4:
412
+ if self.__proxy[2] != None:
413
+ portnum = self.__proxy[2]
414
+ else:
415
+ portnum = 1080
416
+ _orgsocket.connect(self,(self.__proxy[1], portnum))
417
+ self.__negotiatesocks4(destpair[0], destpair[1])
418
+ elif self.__proxy[0] == PROXY_TYPE_HTTP:
419
+ if self.__proxy[2] != None:
420
+ portnum = self.__proxy[2]
421
+ else:
422
+ portnum = 8080
423
+ _orgsocket.connect(self,(self.__proxy[1], portnum))
424
+ self.__negotiatehttp(destpair[0], destpair[1])
425
+ elif self.__proxy[0] == PROXY_TYPE_HTTP_NO_TUNNEL:
426
+ if self.__proxy[2] != None:
427
+ portnum = self.__proxy[2]
428
+ else:
429
+ portnum = 8080
430
+ _orgsocket.connect(self,(self.__proxy[1],portnum))
431
+ if destpair[1] == 443:
432
+ self.__negotiatehttp(destpair[0],destpair[1])
433
+ else:
434
+ self.__httptunnel = False
435
+ elif self.__proxy[0] == None:
436
+ _orgsocket.connect(self, (destpair[0], destpair[1]))
437
+ else:
438
+ raise GeneralProxyError((4, _generalerrors[4]))