@@ -32,8 +32,10 @@ public abstract class Connection implements AutoCloseable {
3232 private static final int nonceLength = 24 ;
3333 private byte [] nonce ;
3434
35- final ExecutorService executorService = Executors .newFixedThreadPool (2 );
35+ final ExecutorService executorService = Executors .newFixedThreadPool (12 );
3636 protected MessagePublisher messagePublisher ;
37+ private final long QUEUE_CHECKING_INTERVAL_MS = 100 ;
38+ private final long SLOW_QUEUE_PROCESSING_MS = 500 ;
3739 private final ConcurrentLinkedQueue <JSONObject > queue = new ConcurrentLinkedQueue <>();
3840
3941 private final int MAX_ERROR_COUNT = 4 ;
@@ -76,6 +78,7 @@ public void run() {
7678 while (keepRunning ()) {
7779 var response = getCleartextResponse ();
7880 if (!response .isEmpty ()) {
81+ if (!isSignal (response )) log .trace ("Response added to queue: {}" , response );
7982 queue .offer (response );
8083 errorCount = 0 ;
8184 } else {
@@ -105,13 +108,25 @@ public JSONObject call() throws Exception {
105108 while (true ) {
106109 var response = queue .peek ();
107110 if (null == response ) {
108- Thread .sleep (200 );
111+ Thread .sleep (QUEUE_CHECKING_INTERVAL_MS );
109112 continue ;
110113 }
111- if (response .has ("error" )) break ;
112- var qit = queue .iterator ();
113- while (qit .hasNext ()) {
114- var message = qit .next ();
114+ if (isSignal (response )) {
115+ queue .remove (response );
116+ continue ;
117+ }
118+ if (response .toString ().equals ("{}" )) {
119+ queue .remove (response );
120+ log .trace ("KeePassXC send an empty response: {}" , response );
121+ continue ;
122+ }
123+ for (JSONObject message : queue ) {
124+ log .trace ("Checking in queue message {}, looking for action '{}' and nonce {}" , message , action , b64encode (incrementNonce (nonce )));
125+ if (message .has ("error" ) && message .getString ("action" ).equals (action )) {
126+ queue .remove (message );
127+ log .trace ("Found in and retrieved from queue: {}" , message );
128+ return message ;
129+ }
115130 if (message .has ("action" )
116131 && message .getString ("action" ).equals (action )
117132 && message .has ("nonce" )
@@ -121,19 +136,8 @@ public JSONObject call() throws Exception {
121136 return message ;
122137 }
123138 }
124- if (isSignal (response )) {
125- queue .poll ();
126- continue ;
127- }
128- if (response .toString ().equals ("{}" )) {
129- queue .poll ();
130- log .trace ("KeePassXC send an empty response: {}" , response );
131- continue ;
132- }
133- log .trace ("Response added to queue: {}" , response );
139+ Thread .sleep (SLOW_QUEUE_PROCESSING_MS );
134140 }
135- log .trace ("Retrieved from queue: {}" , queue .peek ());
136- return queue .poll ();
137141 }
138142 }
139143
@@ -263,7 +267,14 @@ private synchronized JSONObject getEncryptedResponseAndDecrypt(String action, by
263267 var response = new JSONObject ();
264268
265269 try {
266- response = executorService .submit (new MessageConsumer (action , nonce )).get ();
270+ // associate requires user input, other requests don't
271+ if (action .equals ("associate" )) {
272+ response = executorService .submit (new MessageConsumer (action , nonce )).get ();
273+ } else {
274+ response = executorService .submit (new MessageConsumer (action , nonce )).get (1 , TimeUnit .SECONDS );
275+ }
276+ } catch (TimeoutException toe ) {
277+ throw new KeepassProxyAccessException ("Timeout for action '" + action + "'" );
267278 } catch (InterruptedException | ExecutionException e ) {
268279 log .error (e .toString (), e .getCause ());
269280 }
0 commit comments