Skip to content

Commit 580ed6a

Browse files
committed
Direct download BuildManifest if available, minor code cleanup
1 parent 8625f24 commit 580ed6a

File tree

5 files changed

+164
-130
lines changed

5 files changed

+164
-130
lines changed

src/main/java/airsquared/blobsaver/app/Controller.java

+1-7
Original file line numberDiff line numberDiff line change
@@ -704,13 +704,7 @@ private void parseException(Throwable t) {
704704
} else if (message.contains("not being signed") && !allSignedVersionsCheckBox.isSelected()) {
705705
versionField.setEffect(Utils.errorBorder);
706706
}
707-
if (e.isReportable && e.tssLog != null) {
708-
Utils.showReportableError(e.getMessage(), e.tssLog);
709-
} else if (e.isReportable) {
710-
Utils.showReportableError(e.getMessage(), Utils.exceptionToString(e));
711-
} else {
712-
Utils.showUnreportableError(e.getMessage());
713-
}
707+
e.showErrorAlert();
714708
} else {
715709
Utils.showReportableError("An unknown error occurred.", Utils.exceptionToString(t));
716710
}

src/main/java/airsquared/blobsaver/app/DebugWindow.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@
3030
class DebugWindow {
3131

3232
private static final PrintStream sysOut = System.out;
33+
private static final PrintStream sysErr = System.err;
3334
private static final Stage debugStage = new Stage();
3435
private static final PrintStream myPrintStream;
3536

3637
static {
37-
VBox vBox = new VBox();
38+
var vBox = new VBox();
3839
vBox.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
39-
TextArea textArea = new TextArea();
40+
var textArea = new TextArea();
4041
VBox.setVgrow(textArea, Priority.ALWAYS);
4142
textArea.setEditable(false);
4243
textArea.setWrapText(true);
@@ -67,7 +68,7 @@ static void show() {
6768
static void hide() {
6869
debugStage.hide();
6970
System.setOut(sysOut);
70-
System.setErr(sysOut);
71+
System.setErr(sysErr);
7172
}
7273

7374
static boolean isShowing() {

src/main/java/airsquared/blobsaver/app/Network.java

+102
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
package airsquared.blobsaver.app;
22

33
import com.google.gson.Gson;
4+
import com.google.gson.JsonElement;
5+
import com.google.gson.JsonParser;
46

7+
import java.io.BufferedReader;
58
import java.io.IOException;
9+
import java.io.InputStreamReader;
610
import java.net.URI;
11+
import java.net.URL;
12+
import java.net.URLConnection;
713
import java.net.URLEncoder;
814
import java.net.http.HttpClient;
915
import java.net.http.HttpRequest;
1016
import java.net.http.HttpRequest.BodyPublishers;
1117
import java.net.http.HttpResponse;
18+
import java.nio.ByteBuffer;
19+
import java.nio.channels.Channels;
20+
import java.nio.channels.ReadableByteChannel;
21+
import java.nio.channels.SeekableByteChannel;
1222
import java.nio.charset.StandardCharsets;
1323
import java.util.Map;
1424

@@ -50,4 +60,96 @@ private static HttpRequest.BodyPublisher buildFormDataFromMap(Map<Object, Object
5060
}
5161
return HttpRequest.BodyPublishers.ofString(builder.toString());
5262
}
63+
64+
static JsonElement makeRequest(String url) throws IOException {
65+
try (var inputStream = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) {
66+
return JsonParser.parseReader(inputStream);
67+
}
68+
}
69+
70+
/**
71+
* Source: https://github.com/jcodec/jcodec/blob/6e1ec651eca92d21b41f9790143a0e6e4d26811e/android/src/main/org/jcodec/common/io/HttpChannel.java
72+
*
73+
* @author The JCodec project
74+
*/
75+
static final class HttpChannel implements SeekableByteChannel {
76+
77+
private final URL url;
78+
private ReadableByteChannel ch;
79+
private long pos;
80+
private long length;
81+
82+
public HttpChannel(URL url) {
83+
this.url = url;
84+
}
85+
86+
@Override
87+
public long position() {
88+
return pos;
89+
}
90+
91+
@Override
92+
public SeekableByteChannel position(long newPosition) throws IOException {
93+
if (newPosition == pos) {
94+
return this;
95+
} else if (ch != null) {
96+
ch.close();
97+
ch = null;
98+
}
99+
pos = newPosition;
100+
return this;
101+
}
102+
103+
@Override
104+
public long size() throws IOException {
105+
ensureOpen();
106+
return length;
107+
}
108+
109+
@Override
110+
public SeekableByteChannel truncate(long size) {
111+
throw new UnsupportedOperationException("Truncate on HTTP is not supported.");
112+
}
113+
114+
@Override
115+
public int read(ByteBuffer buffer) throws IOException {
116+
ensureOpen();
117+
int read = ch.read(buffer);
118+
if (read != -1)
119+
pos += read;
120+
return read;
121+
}
122+
123+
@Override
124+
public int write(ByteBuffer buffer) {
125+
throw new UnsupportedOperationException("Write to HTTP is not supported.");
126+
}
127+
128+
@Override
129+
public boolean isOpen() {
130+
return ch != null && ch.isOpen();
131+
}
132+
133+
@Override
134+
public void close() throws IOException {
135+
ch.close();
136+
}
137+
138+
private void ensureOpen() throws IOException {
139+
if (ch == null) {
140+
URLConnection connection = url.openConnection();
141+
if (pos > 0)
142+
connection.addRequestProperty("Range", "bytes=" + pos + "-");
143+
ch = Channels.newChannel(connection.getInputStream());
144+
String resp = connection.getHeaderField("Content-Range");
145+
if (resp != null) {
146+
length = Long.parseLong(resp.split("/")[1]);
147+
} else {
148+
resp = connection.getHeaderField("Content-Length");
149+
length = Long.parseLong(resp);
150+
}
151+
}
152+
}
153+
154+
}
53155
}

src/main/java/airsquared/blobsaver/app/TSS.java

+28-15
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import java.util.List;
3737
import java.util.Map;
3838
import java.util.Objects;
39-
import java.util.regex.Matcher;
4039
import java.util.regex.Pattern;
4140
import java.util.stream.Stream;
4241

@@ -49,9 +48,8 @@
4948

5049
public class TSS extends Task<String> {
5150

52-
// note: Matcher is NOT thread safe
53-
private static final Matcher ipswURLMatcher = Pattern.compile("(https?://|file:/).*\\.ipsw").matcher("");
54-
private static final Matcher versionMatcher = Pattern.compile("[0-9]+\\.[0-9]+\\.?[0-9]*(?<!\\.)").matcher("");
51+
private static final Pattern ipswURLPattern = Pattern.compile("(https?://|file:/).*\\.ipsw");
52+
private static final Pattern versionPattern = Pattern.compile("[0-9]+\\.[0-9]+\\.?[0-9]*(?<!\\.)");
5553

5654
private final String deviceIdentifier;
5755
private final String ecid;
@@ -103,7 +101,15 @@ protected String call() throws TSSException {
103101

104102
// can't use forEach() because exception won't be caught
105103
for (Utils.IOSVersion iosVersion : iosVersions) {
106-
saveFor(iosVersion, args);
104+
try {
105+
saveFor(iosVersion, args);
106+
} catch (TSSException e) {
107+
if ((manualVersion == null && manualIpswURL == null) && e.getMessage().contains("not being signed")) {
108+
System.out.println("Warning: ignoring unsigned version; API is likely out of date");
109+
continue; // ignore not being signed (API might not be updated)
110+
}
111+
throw e;
112+
}
107113

108114
if (iosVersion.versionString() != null) {
109115
responseBuilder.append(iosVersion.versionString());
@@ -140,12 +146,6 @@ private void saveFor(Utils.IOSVersion iosVersion, ArrayList<String> args) throws
140146
parseTSSLog(tssLog);
141147
} catch (IOException e) {
142148
throw new TSSException("There was an error starting tsschecker.", true, e);
143-
} catch (TSSException e) {
144-
if ((manualVersion == null && manualIpswURL == null) && e.getMessage().contains("not being signed")) {
145-
System.out.println("Warning: ignoring unsigned version; API might be out of date");
146-
return; // ignore not being signed (API might not be updated)
147-
}
148-
throw e;
149149
}
150150
}
151151

@@ -160,7 +160,7 @@ private void checkInputs() throws TSSException {
160160
}
161161
if (manualIpswURL != null) { // check URL
162162
try {
163-
if (!ipswURLMatcher.reset(manualIpswURL).matches()) {
163+
if (!ipswURLPattern.matcher(manualIpswURL).matches()) {
164164
throw new MalformedURLException("Doesn't match ipsw URL regex");
165165
}
166166
new URL(manualIpswURL); // check URL
@@ -172,7 +172,7 @@ private void checkInputs() throws TSSException {
172172
} catch (IllegalArgumentException | URISyntaxException | IOException e) {
173173
throw new TSSException("The IPSW URL is not valid.\n\nMake sure it's a valid file URL to a local .ipsw file.", false, e);
174174
}
175-
} else if (manualVersion != null && !versionMatcher.reset(manualVersion).matches()) {
175+
} else if (manualVersion != null && !versionPattern.matcher(manualVersion).matches()) {
176176
throw new TSSException("Invalid version. Make sure it follows the convention X.X.X or X.X, like \"13.1\" or \"13.5.5\"", false);
177177
}
178178
}
@@ -198,7 +198,11 @@ private List<Utils.IOSVersion> getIOSVersions() throws TSSException {
198198
return getSignedFirmwares(deviceIdentifier).toList();
199199
}
200200
} catch (FileNotFoundException e) {
201-
throw new TSSException("The device \"" + deviceIdentifier + "\" could not be found.", false, e);
201+
var message = "The device \"" + deviceIdentifier + "\" could not be found.";
202+
if (includeBetas) {
203+
message += " This device may not have any beta versions available; try without including beta versions.";
204+
}
205+
throw new TSSException(message, false, e);
202206
} catch (IOException e) {
203207
throw new TSSException("Saving blobs failed. Check your internet connection.", false, e);
204208
}
@@ -225,7 +229,7 @@ private ArrayList<String> constructArgs() {
225229
}
226230

227231
private String getBoardConfig() {
228-
return Objects.requireNonNullElse(boardConfig, Devices.getBoardConfig(deviceIdentifier));
232+
return Utils.defaultIfNull(boardConfig, Devices.getBoardConfig(deviceIdentifier));
229233
}
230234

231235
@SuppressWarnings("TextBlockMigration")
@@ -363,6 +367,15 @@ public TSSException(String message, boolean isReportable, Throwable cause) {
363367
this.tssLog = null;
364368
}
365369

370+
public void showErrorAlert() {
371+
if (isReportable && tssLog != null) {
372+
Utils.showReportableError(getMessage(), tssLog);
373+
} else if (isReportable) {
374+
Utils.showReportableError(getMessage(), Utils.exceptionToString(this));
375+
} else {
376+
Utils.showUnreportableError(getMessage());
377+
}
378+
}
366379
}
367380

368381
private void saveBlobsTSSSaver(StringBuilder responseBuilder) {

0 commit comments

Comments
 (0)