Skip to content

Commit 0b1cbfb

Browse files
committed
Merge pull request #120 from longbai/retry-host
Retry host
2 parents 8200fdf + 778268f commit 0b1cbfb

File tree

7 files changed

+59
-29
lines changed

7 files changed

+59
-29
lines changed

qiniu/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
RS_HOST = "rs.qbox.me"
77
RSF_HOST = "rsf.qbox.me"
88
UP_HOST = "up.qiniu.com"
9+
UP_HOST2 = "up.qbox.me"
910

1011
from . import __version__
1112
import platform

qiniu/io.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,12 @@ def put(uptoken, key, data, extra=None):
5252
files = [
5353
{'filename': fname, 'data': data, 'mime_type': extra.mime_type},
5454
]
55-
return rpc.Client(conf.UP_HOST).call_with_multipart("/", fields, files)
55+
ret, err, code = rpc.Client(conf.UP_HOST).call_with_multipart("/", fields, files)
56+
if err is None or code == 571 or code == 614 or code == 301:
57+
return ret, err
58+
59+
ret, err, code = rpc.Client(conf.UP_HOST2).call_with_multipart("/", fields, files)
60+
return ret, err
5661

5762

5863
def put_file(uptoken, key, localfile, extra=None):

qiniu/resumable_io.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,35 @@ def put_file(uptoken, key, localfile, extra):
6666
""" 上传文件 """
6767
f = open(localfile, "rb")
6868
statinfo = os.stat(localfile)
69-
ret = put(uptoken, key, f, statinfo.st_size, extra)
69+
ret, err = put(uptoken, key, f, statinfo.st_size, extra)
7070
f.close()
71-
return ret
71+
return ret, err
7272

7373

7474
def put(uptoken, key, f, fsize, extra):
7575
""" 上传二进制流, 通过将data "切片" 分段上传 """
7676
if not isinstance(extra, PutExtra):
7777
print("extra must the instance of PutExtra")
7878
return
79+
host = conf.UP_HOST
80+
try:
81+
ret, err, code = put_with_host(uptoken, key, f, fsize, extra, host)
82+
if err is None or code == 571 or code == 614 or code == 301:
83+
return ret, err
84+
except:
85+
pass
7986

87+
ret, err, code = put_with_host(uptoken, key, f, fsize, extra, conf.UP_HOST2)
88+
return ret, err
89+
90+
91+
def put_with_host(uptoken, key, f, fsize, extra, host):
8092
block_cnt = block_count(fsize)
8193
if extra.progresses is None:
8294
extra.progresses = [None] * block_cnt
8395
else:
8496
if not len(extra.progresses) == block_cnt:
85-
return None, err_invalid_put_progress
97+
return None, err_invalid_put_progress, 0
8698

8799
if extra.try_times is None:
88100
extra.try_times = _try_times
@@ -97,28 +109,29 @@ def put(uptoken, key, f, fsize, extra):
97109
read_length = fsize - i * _block_size
98110
data_slice = f.read(read_length)
99111
while True:
100-
err = resumable_block_put(data_slice, i, extra, uptoken)
112+
err = resumable_block_put(data_slice, i, extra, uptoken, host)
101113
if err is None:
102114
break
103115

104116
try_time -= 1
105117
if try_time <= 0:
106-
return None, err_put_failed
118+
return None, err_put_failed, 0
107119
print err, ".. retry"
108120

109-
mkfile_host = extra.progresses[-1]["host"] if block_cnt else conf.UP_HOST
121+
mkfile_host = extra.progresses[-1]["host"] if block_cnt else host
110122
mkfile_client = auth_up.Client(uptoken, mkfile_host)
111-
return mkfile(mkfile_client, key, fsize, extra)
123+
124+
return mkfile(mkfile_client, key, fsize, extra, host)
112125

113126

114-
def resumable_block_put(block, index, extra, uptoken):
127+
def resumable_block_put(block, index, extra, uptoken, host):
115128
block_size = len(block)
116129

117-
mkblk_client = auth_up.Client(uptoken, conf.UP_HOST)
130+
mkblk_client = auth_up.Client(uptoken, host)
118131
if extra.progresses[index] is None or "ctx" not in extra.progresses[index]:
119132
crc32 = gen_crc32(block)
120133
block = bytearray(block)
121-
extra.progresses[index], err = mkblock(mkblk_client, block_size, block)
134+
extra.progresses[index], err, code = mkblock(mkblk_client, block_size, block, host)
122135
if err is not None:
123136
extra.notify_err(index, block_size, err)
124137
return err
@@ -133,8 +146,8 @@ def block_count(size):
133146
return (size + _block_mask) / _block_size
134147

135148

136-
def mkblock(client, block_size, first_chunk):
137-
url = "http://%s/mkblk/%s" % (conf.UP_HOST, block_size)
149+
def mkblock(client, block_size, first_chunk, host):
150+
url = "http://%s/mkblk/%s" % (host, block_size)
138151
content_type = "application/octet-stream"
139152
return client.call_with(url, first_chunk, content_type, len(first_chunk))
140153

@@ -146,8 +159,8 @@ def putblock(client, block_ret, chunk):
146159
return client.call_with(url, chunk, content_type, len(chunk))
147160

148161

149-
def mkfile(client, key, fsize, extra):
150-
url = ["http://%s/mkfile/%s" % (conf.UP_HOST, fsize)]
162+
def mkfile(client, key, fsize, extra, host):
163+
url = ["http://%s/mkfile/%s" % (host, fsize)]
151164

152165
if extra.mimetype:
153166
url.append("mimeType/%s" % urlsafe_b64encode(extra.mimetype))

qiniu/rpc.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ def merged_headers(self, header):
3131
return _header
3232

3333
def call(self, path):
34-
return self.call_with(path, None)
34+
ret, err, code = self.call_with(path, None)
35+
return ret, err
3536

3637
def call_with(self, path, body, content_type=None, content_length=None):
3738
ret = None
@@ -52,16 +53,16 @@ def call_with(self, path, body, content_type=None, content_length=None):
5253
except ValueError:
5354
pass
5455

55-
if resp.status / 100 != 2:
56+
if resp.status >= 400:
5657
err_msg = ret if "error" not in ret else ret["error"]
5758
reqid = resp.getheader("X-Reqid", None)
5859
# detail = resp.getheader("x-log", None)
5960
if reqid is not None:
6061
err_msg += ", reqid:%s" % reqid
6162

62-
return None, err_msg
63+
return None, err_msg, resp.status
6364

64-
return ret, None
65+
return ret, None, resp.status
6566

6667
def call_with_multipart(self, path, fields=None, files=None):
6768
"""
@@ -87,7 +88,8 @@ def call_with_form(self, path, ops):
8788
body = '&'.join(body)
8889

8990
content_type = "application/x-www-form-urlencoded"
90-
return self.call_with(path, body, content_type, len(body))
91+
ret, err, code = self.call_with(path, body, content_type, len(body))
92+
return ret, err
9193

9294
def set_header(self, field, value):
9395
self._header[field] = value

qiniu/rsf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def list_prefix(self, bucket, prefix=None, marker=None, limit=None):
3636
if prefix is not None:
3737
ops['prefix'] = prefix
3838
url = '%s?%s' % ('/list', urllib.urlencode(ops))
39-
ret, err = self.conn.call_with(
39+
ret, err, code = self.conn.call_with(
4040
url, body=None, content_type='application/x-www-form-urlencoded')
4141
if ret and not ret.get('marker'):
4242
err = EOF

qiniu/test/io_test.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ def test_put_quote_key():
6363
data = r(100)
6464
key = 'a\\b\\c"你好' + r(9)
6565
ret, err = io.put(policy.token(), key, data)
66-
print err
6766
assert err is None
6867
assert ret['key'].encode('utf8') == key
6968

@@ -114,7 +113,7 @@ def test_put_StringIO():
114113

115114
def test_put_urlopen():
116115
key = "test_%s" % r(9)
117-
data = urllib.urlopen('http://cheneya.qiniudn.com/hello_jpg')
116+
data = urllib.urlopen('http://pythonsdk.qiniudn.com/hello.jpg')
118117
ret, err = io.put(policy.token(), key, data)
119118
assert err is None
120119
assert ret['key'] == key
@@ -178,6 +177,17 @@ def test_put_fail_reqid(self):
178177
ret, err = io.put("", key, data, extra)
179178
assert "reqid" in err
180179

180+
def test_put_with_uphost2(self):
181+
conf.UP_HOST = "api.qiniu.com" # mistake up host
182+
localfile = "%s" % __file__
183+
key = "test_up2_%s" % r(9)
184+
185+
extra.check_crc = 1
186+
ret, err = io.put_file(policy.token(), key, localfile, extra)
187+
assert err is None
188+
assert ret['key'] == key
189+
conf.UP_HOST = "up.qiniu.com"
190+
181191

182192
class Test_get_file_crc32(unittest.TestCase):
183193

qiniu/test/resumable_io_test.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,15 @@ class TestBlock(unittest.TestCase):
3737
def test_block(self):
3838
if is_travis:
3939
return
40+
host = conf.UP_HOST
4041
policy = rs.PutPolicy(bucket)
4142
uptoken = policy.token()
4243
client = up.Client(uptoken)
4344

4445
# rets = [0, 0]
4546
data_slice_2 = "\nbye!"
46-
ret, err = resumable_io.mkblock(
47-
client, len(data_slice_2), data_slice_2)
47+
ret, err, code = resumable_io.mkblock(
48+
client, len(data_slice_2), data_slice_2, host)
4849
assert err is None, err
4950
self.assertEqual(ret["crc32"], binascii.crc32(data_slice_2))
5051

@@ -56,7 +57,7 @@ def test_block(self):
5657
lens += extra.progresses[i]["offset"]
5758

5859
key = u"sdk_py_resumable_block_4_%s" % r(9)
59-
ret, err = resumable_io.mkfile(client, key, lens, extra)
60+
ret, err, code = resumable_io.mkfile(client, key, lens, extra, host)
6061
assert err is None, err
6162
self.assertEqual(
6263
ret["hash"], "FtCFo0mQugW98uaPYgr54Vb1QsO0", "hash not match")
@@ -65,7 +66,7 @@ def test_block(self):
6566
def test_put(self):
6667
if is_travis:
6768
return
68-
src = urllib.urlopen("http://cheneya.qiniudn.com/hello_jpg")
69+
src = urllib.urlopen("http://pythonsdk.qiniudn.com/hello.jpg")
6970
ostype = platform.system()
7071
if ostype.lower().find("windows") != -1:
7172
tmpf = "".join([os.getcwd(), mktemp()])
@@ -84,7 +85,6 @@ def test_put(self):
8485
ret, err = resumable_io.put_file(policy.token(), key, localfile, extra)
8586
dst.close()
8687
os.remove(tmpf)
87-
8888
assert err is None, err
8989
assert ret.get("x:foo") == "test", "return data not contains 'x:foo'"
9090
self.assertEqual(
@@ -112,7 +112,6 @@ def test_put_4m(self):
112112
ret, err = resumable_io.put_file(policy.token(), key, localfile, extra)
113113
dst.close()
114114
os.remove(tmpf)
115-
116115
assert err is None, err
117116
assert ret.get("x:foo") == "test", "return data not contains 'x:foo'"
118117
self.assertEqual(

0 commit comments

Comments
 (0)