@@ -18,11 +18,13 @@ public class IPFS {
18
18
public enum PinType {all , direct , indirect , recursive }
19
19
public List <String > ObjectTemplates = Arrays .asList ("unixfs-dir" );
20
20
public List <String > ObjectPatchTypes = Arrays .asList ("add-link" , "rm-link" , "set-data" , "append-data" );
21
+ private static final int DEFAULT_TIMEOUT = 0 ;
21
22
22
23
public final String host ;
23
24
public final int port ;
24
25
public final String protocol ;
25
26
private final String version ;
27
+ private int timeout = DEFAULT_TIMEOUT ;
26
28
public final Key key = new Key ();
27
29
public final Pin pin = new Pin ();
28
30
public final Repo repo = new Repo ();
@@ -73,6 +75,17 @@ public IPFS(String host, int port, String version, boolean ssl) {
73
75
throw new RuntimeException (e );
74
76
}
75
77
}
78
+
79
+ /**
80
+ * Configure a HTTP client timeout
81
+ * @param timeout (default 0: infinite timeout)
82
+ * @return current IPFS object with configured timeout
83
+ */
84
+ public IPFS timeout (int timeout ) {
85
+ if (timeout < 0 ) throw new IllegalArgumentException ("timeout must be zero or positive" );
86
+ this .timeout = timeout ;
87
+ return this ;
88
+ }
76
89
77
90
public List <MerkleNode > add (NamedStreamable file ) throws IOException {
78
91
return add (file , false );
@@ -659,13 +672,11 @@ private void retrieveAndParseStream(String path, Consumer<Object> results, Consu
659
672
660
673
private byte [] retrieve (String path ) throws IOException {
661
674
URL target = new URL (protocol , host , port , version + path );
662
- return IPFS .get (target );
675
+ return IPFS .get (target , timeout );
663
676
}
664
677
665
- private static byte [] get (URL target ) throws IOException {
666
- HttpURLConnection conn = (HttpURLConnection ) target .openConnection ();
667
- conn .setRequestMethod ("GET" );
668
- conn .setRequestProperty ("Content-Type" , "application/json" );
678
+ private static byte [] get (URL target , int timeout ) throws IOException {
679
+ HttpURLConnection conn = configureConnection (target , "GET" , timeout );
669
680
670
681
try {
671
682
InputStream in = conn .getInputStream ();
@@ -678,8 +689,12 @@ private static byte[] get(URL target) throws IOException {
678
689
return resp .toByteArray ();
679
690
} catch (ConnectException e ) {
680
691
throw new RuntimeException ("Couldn't connect to IPFS daemon at " +target +"\n Is IPFS running?" );
692
+ } catch (SocketTimeoutException e ) {
693
+ throw new RuntimeException (String .format ("timeout (%d ms) has been exceeded" , timeout ));
681
694
} catch (IOException e ) {
682
- String err = new String (readFully (conn .getErrorStream ()));
695
+ String err = Optional .ofNullable (conn .getErrorStream ())
696
+ .map (s ->new String (readFully (s )))
697
+ .orElse (e .getMessage ());
683
698
throw new RuntimeException ("IOException contacting IPFS daemon.\n Trailer: " + conn .getHeaderFields ().get ("Trailer" ) + " " + err , e );
684
699
}
685
700
}
@@ -725,28 +740,24 @@ private List<Object> getAndParseStream(String path) throws IOException {
725
740
726
741
private InputStream retrieveStream (String path ) throws IOException {
727
742
URL target = new URL (protocol , host , port , version + path );
728
- return IPFS .getStream (target );
743
+ return IPFS .getStream (target , timeout );
729
744
}
730
745
731
- private static InputStream getStream (URL target ) throws IOException {
732
- HttpURLConnection conn = (HttpURLConnection ) target .openConnection ();
733
- conn .setRequestMethod ("GET" );
734
- conn .setRequestProperty ("Content-Type" , "application/json" );
746
+ private static InputStream getStream (URL target , int timeout ) throws IOException {
747
+ HttpURLConnection conn = configureConnection (target , "GET" , timeout );
735
748
return conn .getInputStream ();
736
749
}
737
750
738
751
private Map postMap (String path , byte [] body , Map <String , String > headers ) throws IOException {
739
752
URL target = new URL (protocol , host , port , version + path );
740
- return (Map ) JSONParser .parse (new String (post (target , body , headers )));
753
+ return (Map ) JSONParser .parse (new String (post (target , body , headers , timeout )));
741
754
}
742
755
743
- private static byte [] post (URL target , byte [] body , Map <String , String > headers ) throws IOException {
744
- HttpURLConnection conn = ( HttpURLConnection ) target . openConnection ( );
756
+ private static byte [] post (URL target , byte [] body , Map <String , String > headers , int timeout ) throws IOException {
757
+ HttpURLConnection conn = configureConnection ( target , "POST" , timeout );
745
758
for (String key : headers .keySet ())
746
759
conn .setRequestProperty (key , headers .get (key ));
747
760
conn .setDoOutput (true );
748
- conn .setRequestMethod ("POST" );
749
- conn .setRequestProperty ("Content-Type" , "application/json" );
750
761
OutputStream out = conn .getOutputStream ();
751
762
out .write (body );
752
763
out .flush ();
@@ -756,16 +767,29 @@ private static byte[] post(URL target, byte[] body, Map<String, String> headers)
756
767
return readFully (in );
757
768
}
758
769
759
- private static final byte [] readFully (InputStream in ) throws IOException {
760
- ByteArrayOutputStream resp = new ByteArrayOutputStream ();
761
- byte [] buf = new byte [4096 ];
762
- int r ;
763
- while ((r =in .read (buf )) >= 0 )
764
- resp .write (buf , 0 , r );
765
- return resp .toByteArray ();
770
+ private static final byte [] readFully (InputStream in ) {
771
+ try {
772
+ ByteArrayOutputStream resp = new ByteArrayOutputStream ();
773
+ byte [] buf = new byte [4096 ];
774
+ int r ;
775
+ while ((r =in .read (buf )) >= 0 )
776
+ resp .write (buf , 0 , r );
777
+ return resp .toByteArray ();
778
+
779
+ } catch (IOException ex ) {
780
+ throw new RuntimeException ("Error reading InputStrean" , ex );
781
+ }
766
782
}
767
783
768
784
private static boolean detectSSL (MultiAddress multiaddress ) {
769
785
return multiaddress .toString ().contains ("/https" );
770
786
}
787
+
788
+ private static HttpURLConnection configureConnection (URL target , String method , int timeout ) throws IOException {
789
+ HttpURLConnection conn = (HttpURLConnection ) target .openConnection ();
790
+ conn .setRequestMethod (method );
791
+ conn .setRequestProperty ("Content-Type" , "application/json" );
792
+ conn .setReadTimeout (timeout );
793
+ return conn ;
794
+ }
771
795
}
0 commit comments