16
16
*/
17
17
package com .textuality .keybase .lib ;
18
18
19
- import android . util . Log ;
19
+ import com . textuality . keybase . lib . prover . Fetch ;
20
20
21
- import com .squareup .okhttp .OkHttpClient ;
22
- import com .squareup .okhttp .Request ;
23
- import com .squareup .okhttp .Response ;
24
21
import org .json .JSONArray ;
25
22
import org .json .JSONException ;
26
23
import org .json .JSONObject ;
27
24
28
25
import java .io .ByteArrayOutputStream ;
29
26
import java .io .IOException ;
30
27
import java .io .InputStream ;
28
+ import java .net .HttpURLConnection ;
29
+ import java .net .MalformedURLException ;
31
30
import java .net .Proxy ;
32
31
import java .net .URL ;
33
32
import java .net .URLEncoder ;
34
33
import java .util .Iterator ;
35
34
import java .util .NoSuchElementException ;
36
- import java .util .concurrent .TimeUnit ;
37
35
38
- public class Search {
39
-
36
+ public class KeybaseQuery {
37
+
40
38
private static final String TAG = "KEYBASE-LIB" ;
41
39
42
- public static Iterable <Match > search (String query , Proxy proxy ) throws KeybaseException {
43
- JSONObject result = getFromKeybase ("_/api/1.0/user/autocomplete.json?q=" , query , proxy );
40
+ private KeybaseUrlConnectionClient connectionClient ;
41
+ private Proxy proxy ;
42
+
43
+ public KeybaseQuery (KeybaseUrlConnectionClient connectionClient ) {
44
+ this .connectionClient = connectionClient ;
45
+ }
46
+
47
+ public void setProxy (Proxy proxy ) {
48
+ this .proxy = proxy ;
49
+ }
50
+
51
+ public Iterable <Match > search (String query ) throws KeybaseException {
52
+ JSONObject result = getFromKeybase ("_/api/1.0/user/autocomplete.json?q=" , query );
44
53
try {
45
54
return new MatchIterator (JWalk .getArray (result , "completions" ));
46
55
} catch (JSONException e ) {
47
56
throw KeybaseException .keybaseScrewup (e );
48
57
}
49
58
}
50
59
51
- public static JSONObject getFromKeybase (String path , String query , Proxy proxy ) throws KeybaseException {
60
+ public JSONObject getFromKeybase (String path , String query ) throws KeybaseException {
52
61
try {
53
62
String url = "https://keybase.io/" + path + URLEncoder .encode (query , "utf8" );
54
63
55
64
URL realUrl = new URL (url );
56
65
57
- OkHttpClient client = new OkHttpClient ( );
58
- client . setProxy ( proxy );
66
+ HttpURLConnection conn = ( HttpURLConnection ) connectionClient . openConnection ( realUrl , proxy );
67
+ conn . connect ( );
59
68
60
- if (proxy != null ) {
61
- client .setConnectTimeout (30000 , TimeUnit .MILLISECONDS );
62
- client .setReadTimeout (40000 , TimeUnit .MILLISECONDS );
63
- } else {
64
- client .setConnectTimeout (5000 , TimeUnit .MILLISECONDS ); // TODO: Reasonable values for keybase
65
- client .setReadTimeout (25000 , TimeUnit .MILLISECONDS );
66
- }
67
-
68
- Response resp = client .newCall (new Request .Builder ().url (realUrl ).build ()).execute ();
69
-
70
- int response = resp .code ();
71
-
72
- String text = resp .body ().string ();
69
+ int response = conn .getResponseCode ();
73
70
74
71
if (response >= 200 && response < 300 ) {
72
+ String text = snarf (conn .getInputStream ());
75
73
try {
76
74
JSONObject json = new JSONObject (text );
77
75
if (JWalk .getInt (json , "status" , "code" ) != 0 ) {
@@ -83,7 +81,8 @@ public static JSONObject getFromKeybase(String path, String query, Proxy proxy)
83
81
throw KeybaseException .keybaseScrewup (e );
84
82
}
85
83
} else {
86
- throw KeybaseException .networkScrewup ("Keybase.io query error (status=" + response + "): " + text );
84
+ String message = snarf (conn .getErrorStream ());
85
+ throw KeybaseException .networkScrewup ("Keybase.io query error (status=" + response + "): " + message );
87
86
}
88
87
} catch (Exception e ) {
89
88
throw KeybaseException .networkScrewup (e );
@@ -95,25 +94,62 @@ public static String snarf(InputStream in)
95
94
byte [] buf = new byte [1024 ];
96
95
int count = 0 ;
97
96
ByteArrayOutputStream out = new ByteArrayOutputStream (1024 );
98
- while ((count = in .read (buf )) != -1 )
97
+ while ((count = in .read (buf )) != -1 )
99
98
out .write (buf , 0 , count );
100
99
return out .toString ();
101
100
}
102
101
102
+ public static final int REDIRECT_TRIES = 5 ;
103
+
104
+ public Fetch fetchProof (String urlString ) {
105
+ Fetch result = new Fetch ();
106
+
107
+ try {
108
+ HttpURLConnection conn = null ;
109
+ int status = 0 ;
110
+ int redirects = 0 ;
111
+ while (redirects < REDIRECT_TRIES ) {
112
+ result .mActualUrl = urlString ;
113
+ URL url = new URL (urlString );
114
+ conn = (HttpURLConnection ) connectionClient .openConnection (url , proxy );
115
+ conn .addRequestProperty ("User-Agent" , "Keybase Java client, github.com/timbray/KeybaseLib" );
116
+ conn .connect ();
117
+ status = conn .getResponseCode ();
118
+ if (status == 301 ) {
119
+ redirects ++;
120
+ urlString = conn .getHeaderFields ().get ("Location" ).get (0 );
121
+ } else {
122
+ break ;
123
+ }
124
+ }
125
+ if (status >= 200 && status < 300 ) {
126
+ result .mBody = KeybaseQuery .snarf (conn .getInputStream ());
127
+ } else {
128
+ result .mProblem = "Fetch failed, status " + status + ": " + KeybaseQuery .snarf (conn .getErrorStream ());
129
+ }
130
+
131
+ } catch (MalformedURLException e ) {
132
+ result .mProblem = "Bad URL: " + urlString ;
133
+ } catch (IOException e ) {
134
+ result .mProblem = "Network error: " + e .getLocalizedMessage ();
135
+ }
136
+
137
+ return result ;
138
+ }
139
+
103
140
static class MatchIterator implements Iterable <Match >, Iterator <Match > {
104
141
105
142
private final JSONArray mMatches ;
106
143
private int mLastIndex ;
107
144
private Match mNextMatch ;
108
145
109
146
public MatchIterator (JSONArray matches ) throws KeybaseException {
110
- Log .d (TAG , "match count=" + matches .length ());
111
147
mMatches = matches ;
112
148
mLastIndex = -1 ;
113
149
mNextMatch = null ;
114
150
hasNext ();
115
151
}
116
-
152
+
117
153
// caches mNextMatch but not the index
118
154
private int findNext () {
119
155
try {
@@ -148,7 +184,7 @@ public Match next() {
148
184
149
185
@ Override
150
186
public void remove () {
151
- throw new RuntimeException ("UserIterator.remove() not supported" );
187
+ throw new RuntimeException ("UserIterator.remove() not supported" );
152
188
}
153
189
154
190
@ Override
0 commit comments