Skip to content

Commit eb5c86d

Browse files
add handling of 503 responses (#1184)
1 parent 7d3354d commit eb5c86d

File tree

5 files changed

+84
-0
lines changed

5 files changed

+84
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- chore: bump min python version 3.9->3.10
66
- fix: iCloud clean up with `--keep-icloud-recent-days` does not respect `--skip-*` params [#1180](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/1180)
77
- chore: replace build & test platform from retired windows-2019 to windows-2025
8+
- Service Temporary Unavailable responses are less ambiguous [#1078](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/1078)
89

910
## 1.28.1 (2025-06-08)
1011

src/pyicloud_ipd/base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,8 @@ def encode(self) -> bytes:
290290
if response.status_code == 401:
291291
raise PyiCloudAPIResponseException(response.text, str(response.status_code))
292292
except PyiCloudAPIResponseException as error:
293+
if response.status_code == 503:
294+
raise
293295
msg = "Failed to initiate srp authentication."
294296
raise PyiCloudFailedLoginException(msg, error) from error
295297

src/pyicloud_ipd/session.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ def request(self, method: str, url, **kwargs): # type: ignore
7070

7171
request_logger.debug(response.headers)
7272

73+
if response.status_code == 503:
74+
api_error = PyiCloudAPIResponseException(response.reason, str(response.status_code))
75+
LOGGER.error(api_error)
76+
raise api_error
77+
7378
for header, value in HEADER_DATA.items():
7479
if response.headers.get(header):
7580
session_arg = value

tests/test_authentication.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,34 @@ def test_non_2fa(self) -> None:
341341

342342
self.assertTrue(cass.all_played)
343343

344+
def test_failed_auth_503(self) -> None:
345+
base_dir = os.path.join(self.fixtures_path, inspect.stack()[0][3])
346+
cookie_dir = os.path.join(base_dir, "cookie")
347+
348+
for dir in [base_dir, cookie_dir]:
349+
recreate_path(dir)
350+
351+
with vcr.use_cassette(os.path.join(self.vcr_path, "failed_auth_503.yml")): # noqa: SIM117
352+
runner = CliRunner(env={"CLIENT_ID": "EC5646DE-9423-11E8-BF21-14109FE0B321"})
353+
result = runner.invoke(
354+
main,
355+
[
356+
"--username",
357+
"jdoe@gmail.com",
358+
"--password",
359+
"password1",
360+
"--no-progress-bar",
361+
"--cookie-directory",
362+
cookie_dir,
363+
"--auth-only",
364+
],
365+
)
366+
self.assertNotIn(
367+
"ERROR Failed to login with srp, falling back to old raw password authentication.",
368+
self._caplog.text,
369+
)
370+
self.assertIn("ERROR Service Temporary Unavailable (503)", self._caplog.text)
371+
assert result.exit_code == 1
344372

345373
class _TrustedDevice(NamedTuple):
346374
id: int
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
interactions:
2+
- request:
3+
body: !!python/unicode '{"accountName": "whatever_username", "protocols": ["s2k", "s2k_fo"]}'
4+
headers:
5+
Accept: ['*/*']
6+
Accept-Encoding: ['gzip, deflate']
7+
Connection: ['keep-alive']
8+
Content-Length: ['98']
9+
Content-Type: ['application/json']
10+
Origin: ['https://www.icloud.com']
11+
Referer: ['https://www.icloud.com/']
12+
User-Agent: ['Opera/9.52 (X11; Linux i686; U; en)']
13+
X-Apple-OAuth-Client-Id: ['d39ba9916b7251055b22c7f910e2ea796ee65e98b2ddecea8f5dde8d9d1a815d']
14+
X-Apple-OAuth-Client-Type: ['firstPartyAuth']
15+
X-Apple-OAuth-Redirect-URI: ['https://www.icloud.com']
16+
X-Apple-OAuth-Require-Grant-Code: ['true']
17+
X-Apple-OAuth-Response-Mode: ['web_message']
18+
X-Apple-OAuth-Response-Type: ['code']
19+
X-Apple-OAuth-State: ['EC5646DE-9423-11E8-BF21-14109FE0B321']
20+
X-Apple-Widget-Key: ['d39ba9916b7251055b22c7f910e2ea796ee65e98b2ddecea8f5dde8d9d1a815d']
21+
method: POST
22+
uri: https://idmsa.apple.com/appleauth/auth/signin/init
23+
response:
24+
body: {string: 'Service Temporary Unavailable'}
25+
headers:
26+
Cache-Control:
27+
- 'no-cache'
28+
- 'no-store'
29+
Connection: ['keep-alive']
30+
Content-Type: ['text/html;charset=UTF-8']
31+
Date: ['Fri, 15 Dec 2023 17:28:03 GMT']
32+
Pragma: ['no-cache']
33+
Referrer-Policy: ['origin']
34+
Server: ['Apple']
35+
Strict-Transport-Security: ['max-age=31536000; includeSubDomains; preload']
36+
Transfer-Encoding: ['chunked']
37+
X-Apple-I-Request-ID: ['12345678-1234-1234-1234-123456789012']
38+
X-BuildVersion: ['R4_1']
39+
X-Content-Type-Options: ['nosniff']
40+
X-FRAME-OPTIONS: ['DENY']
41+
X-XSS-Protection: ['1; mode=block']
42+
content-length: ['29']
43+
scnt: ['scnt-1234567890']
44+
vary: ['accept-encoding']
45+
status:
46+
code: 503
47+
message: 'Service Temporary Unavailable'
48+
version: 1

0 commit comments

Comments
 (0)