@@ -18,11 +18,13 @@ public class IPFS {
1818 public enum PinType {all , direct , indirect , recursive }
1919 public List <String > ObjectTemplates = Arrays .asList ("unixfs-dir" );
2020 public List <String > ObjectPatchTypes = Arrays .asList ("add-link" , "rm-link" , "set-data" , "append-data" );
21+ private static final int DEFAULT_TIMEOUT = 0 ;
2122
2223 public final String host ;
2324 public final int port ;
2425 public final String protocol ;
2526 private final String version ;
27+ private int timeout = DEFAULT_TIMEOUT ;
2628 public final Key key = new Key ();
2729 public final Pin pin = new Pin ();
2830 public final Repo repo = new Repo ();
@@ -73,6 +75,17 @@ public IPFS(String host, int port, String version, boolean ssl) {
7375 throw new RuntimeException (e );
7476 }
7577 }
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+ }
7689
7790 public List <MerkleNode > add (NamedStreamable file ) throws IOException {
7891 return add (file , false );
@@ -659,13 +672,11 @@ private void retrieveAndParseStream(String path, Consumer<Object> results, Consu
659672
660673 private byte [] retrieve (String path ) throws IOException {
661674 URL target = new URL (protocol , host , port , version + path );
662- return IPFS .get (target );
675+ return IPFS .get (target , timeout );
663676 }
664677
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 );
669680
670681 try {
671682 InputStream in = conn .getInputStream ();
@@ -678,6 +689,8 @@ private static byte[] get(URL target) throws IOException {
678689 return resp .toByteArray ();
679690 } catch (ConnectException e ) {
680691 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 ));
681694 } catch (IOException e ) {
682695 String err = new String (readFully (conn .getErrorStream ()));
683696 throw new RuntimeException ("IOException contacting IPFS daemon.\n Trailer: " + conn .getHeaderFields ().get ("Trailer" ) + " " + err , e );
@@ -725,28 +738,24 @@ private List<Object> getAndParseStream(String path) throws IOException {
725738
726739 private InputStream retrieveStream (String path ) throws IOException {
727740 URL target = new URL ("http" , host , port , version + path );
728- return IPFS .getStream (target );
741+ return IPFS .getStream (target , timeout );
729742 }
730743
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" );
744+ private static InputStream getStream (URL target , int timeout ) throws IOException {
745+ HttpURLConnection conn = configureConnection (target , "GET" , timeout );
735746 return conn .getInputStream ();
736747 }
737748
738749 private Map postMap (String path , byte [] body , Map <String , String > headers ) throws IOException {
739750 URL target = new URL (protocol , host , port , version + path );
740- return (Map ) JSONParser .parse (new String (post (target , body , headers )));
751+ return (Map ) JSONParser .parse (new String (post (target , body , headers , timeout )));
741752 }
742753
743- private static byte [] post (URL target , byte [] body , Map <String , String > headers ) throws IOException {
744- HttpURLConnection conn = ( HttpURLConnection ) target . openConnection ( );
754+ private static byte [] post (URL target , byte [] body , Map <String , String > headers , int timeout ) throws IOException {
755+ HttpURLConnection conn = configureConnection ( target , "POST" , timeout );
745756 for (String key : headers .keySet ())
746757 conn .setRequestProperty (key , headers .get (key ));
747758 conn .setDoOutput (true );
748- conn .setRequestMethod ("POST" );
749- conn .setRequestProperty ("Content-Type" , "application/json" );
750759 OutputStream out = conn .getOutputStream ();
751760 out .write (body );
752761 out .flush ();
@@ -768,4 +777,12 @@ private static final byte[] readFully(InputStream in) throws IOException {
768777 private static boolean detectSSL (MultiAddress multiaddress ) {
769778 return multiaddress .toString ().contains ("/https" );
770779 }
780+
781+ private static HttpURLConnection configureConnection (URL target , String method , int timeout ) throws IOException {
782+ HttpURLConnection conn = (HttpURLConnection ) target .openConnection ();
783+ conn .setRequestMethod (method );
784+ conn .setRequestProperty ("Content-Type" , "application/json" );
785+ conn .setReadTimeout (timeout );
786+ return conn ;
787+ }
771788}
0 commit comments