@@ -876,48 +876,50 @@ private Optional<MetadataBLOB> refreshBlobInternal(
876876
877877 try {
878878 log .debug ("Attempting to download new BLOB..." );
879- final ByteArray downloadedBytes =
879+ final DownloadResult downloadResult =
880880 download (
881881 blobUrl ,
882882 // This should ideally use the value of the ETag response header from when the cached
883883 // BLOB was downloaded, but we don't have anywhere to store that without changing the
884884 // format of the cache serialization. This is good enough as the MDS explicitly
885885 // specifies that the ETag is set to the "no" of the BLOB.
886886 cached .map (cachedBlob -> String .format ("%d" , cachedBlob .getPayload ().getNo ())));
887- final MetadataBLOB downloadedBlob = parseAndVerifyBlob (downloadedBytes , trustRoot );
888- log .debug ("New BLOB downloaded." );
887+ if (downloadResult .isNotModified ()) {
888+ log .debug ("Remote BLOB not modified - using cached BLOB." );
889+ return cached ;
889890
890- if (cached .isPresent ()) {
891- log .debug ("Cached BLOB exists - checking if new BLOB has a higher \" no\" ..." );
892- if (downloadedBlob .getPayload ().getNo () <= cached .get ().getPayload ().getNo ()) {
893- log .debug ("New BLOB does not have a higher \" no\" - using cached BLOB instead." );
894- return cached ;
891+ } else {
892+ ByteArray downloadedBytes = downloadResult .getContent ();
893+ final MetadataBLOB downloadedBlob = parseAndVerifyBlob (downloadedBytes , trustRoot );
894+ log .debug ("New BLOB downloaded." );
895+
896+ if (cached .isPresent ()) {
897+ log .debug ("Cached BLOB exists - checking if new BLOB has a higher \" no\" ..." );
898+ if (downloadedBlob .getPayload ().getNo () <= cached .get ().getPayload ().getNo ()) {
899+ log .debug ("New BLOB does not have a higher \" no\" - using cached BLOB instead." );
900+ return cached ;
901+ }
902+ log .debug ("New BLOB has a higher \" no\" - proceeding with new BLOB." );
895903 }
896- log .debug ("New BLOB has a higher \" no\" - proceeding with new BLOB." );
897- }
898-
899- log .debug ("Checking legalHeader in new BLOB..." );
900- if (!expectedLegalHeaders .contains (downloadedBlob .getPayload ().getLegalHeader ())) {
901- throw new UnexpectedLegalHeader (cached .orElse (null ), downloadedBlob );
902- }
903904
904- log .debug ("Writing new BLOB to cache..." );
905- if (blobCacheFile != null ) {
906- try (FileOutputStream f = new FileOutputStream (blobCacheFile )) {
907- f .write (downloadedBytes .getBytes ());
905+ log .debug ("Checking legalHeader in new BLOB..." );
906+ if (!expectedLegalHeaders .contains (downloadedBlob .getPayload ().getLegalHeader ())) {
907+ throw new UnexpectedLegalHeader (cached .orElse (null ), downloadedBlob );
908908 }
909- }
910-
911- if (blobCacheConsumer != null ) {
912- blobCacheConsumer .accept (downloadedBytes );
913- }
914909
915- return Optional .of (downloadedBlob );
910+ log .debug ("Writing new BLOB to cache..." );
911+ if (blobCacheFile != null ) {
912+ try (FileOutputStream f = new FileOutputStream (blobCacheFile )) {
913+ f .write (downloadedBytes .getBytes ());
914+ }
915+ }
916916
917- } catch ( NotModified e ) {
918- log . debug ( "Remote BLOB not modified - using cached BLOB." );
919- return cached ;
917+ if ( blobCacheConsumer != null ) {
918+ blobCacheConsumer . accept ( downloadedBytes );
919+ }
920920
921+ return Optional .of (downloadedBlob );
922+ }
921923 } catch (FidoMetadataDownloaderException e ) {
922924 if (e .getReason () == Reason .BAD_SIGNATURE && cached .isPresent ()) {
923925 log .warn ("New BLOB has bad signature - falling back to cached BLOB." );
@@ -1074,17 +1076,18 @@ Optional<ByteArray> readCacheFile(File cacheFile) throws IOException {
10741076 }
10751077
10761078 private ByteArray download (URL url ) throws IOException {
1077- try {
1078- return download (url , Optional .empty ());
1079- } catch (NotModified e ) {
1079+ final DownloadResult downloadResult = download (url , Optional .empty ());
1080+ if (downloadResult .isOk ()) {
1081+ return downloadResult .getContent ();
1082+ } else {
10801083 final String msg =
1081- "NotModified thrown by download(URL, Optional.empty()). This should be impossible, please file a bug report." ;
1084+ "download(URL, Optional.empty()) returned non-OK success response . This should be impossible, please file a bug report." ;
10821085 log .error (msg );
1083- throw new RuntimeException (msg , e );
1086+ throw new RuntimeException (msg );
10841087 }
10851088 }
10861089
1087- private ByteArray download (URL url , Optional <String > etag ) throws IOException , NotModified {
1090+ private DownloadResult download (URL url , Optional <String > etag ) throws IOException {
10881091 URLConnection conn = url .openConnection ();
10891092
10901093 if (conn instanceof HttpsURLConnection ) {
@@ -1114,7 +1117,7 @@ private ByteArray download(URL url, Optional<String> etag) throws IOException, N
11141117 switch (httpsConn .getResponseCode ()) {
11151118 case 304 : // Not Modified
11161119 log .debug ("Received 304 Not Modified response to download request: {}" , url );
1117- throw new NotModified ();
1120+ return DownloadResult . notModified ();
11181121 }
11191122
11201123 log .warn (
@@ -1135,13 +1138,13 @@ private ByteArray download(URL url, Optional<String> etag) throws IOException, N
11351138 et .equals (responseEtag ) || String .format ("\" %s\" " , et ).equals (responseEtag ))
11361139 .orElse (false )) {
11371140 log .debug ("Response ETag matches local ETag - interpreting as not modified." );
1138- throw new NotModified ();
1141+ return DownloadResult . notModified ();
11391142 }
11401143 }
11411144 }
11421145 }
11431146
1144- return readAll (conn .getInputStream ());
1147+ return DownloadResult . ok ( readAll (conn .getInputStream () ));
11451148 }
11461149
11471150 private MetadataBLOB parseAndVerifyBlob (ByteArray jwt , X509Certificate trustRootCertificate )
@@ -1379,5 +1382,26 @@ private Optional<CertStore> fetchCrlDistributionPoints(
13791382 }
13801383 }
13811384
1382- private static class NotModified extends Throwable {}
1385+ @ Value
1386+ @ AllArgsConstructor (access = AccessLevel .PRIVATE )
1387+ private static class DownloadResult {
1388+ private boolean notModified ;
1389+ private Optional <ByteArray > content ;
1390+
1391+ static DownloadResult notModified () {
1392+ return new DownloadResult (true , Optional .empty ());
1393+ }
1394+
1395+ static DownloadResult ok (@ NonNull ByteArray content ) {
1396+ return new DownloadResult (false , Optional .of (content ));
1397+ }
1398+
1399+ ByteArray getContent () {
1400+ return content .get ();
1401+ }
1402+
1403+ boolean isOk () {
1404+ return content .isPresent ();
1405+ }
1406+ }
13831407}
0 commit comments