From 76f90f184cf0ed975aed5f002031891f9e494da2 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Thu, 15 Oct 2015 21:58:09 +0200 Subject: [PATCH 1/2] Added extra logging for observer. --- .../java/com/nutomic/syncthingandroid/util/FolderObserver.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/nutomic/syncthingandroid/util/FolderObserver.java b/src/main/java/com/nutomic/syncthingandroid/util/FolderObserver.java index 94f57da5..ab527fd4 100644 --- a/src/main/java/com/nutomic/syncthingandroid/util/FolderObserver.java +++ b/src/main/java/com/nutomic/syncthingandroid/util/FolderObserver.java @@ -95,6 +95,8 @@ public class FolderObserver extends FileObserver { ? new File(mPath, path) : new File(mPath); + Log.v(TAG, "Received inotify event " + Integer.toHexString(event) + " at " + + fullPath.getAbsolutePath()); switch (event) { case MOVED_FROM: // fall through From dc31cd1cb60f0d91db0d94bf7162aee5e9d603c9 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Thu, 15 Oct 2015 21:58:17 +0200 Subject: [PATCH 2/2] Fixed inotify events not passing parameters to Syncthing (ref #465). The parameters set in RestApi#onFolderFileChanged() were not actually used by PostTask#doInBackground(). --- .../{PostTask.java => PostConfigTask.java} | 24 +++--- .../syncthing/PostScanTask.java | 83 +++++++++++++++++++ .../syncthingandroid/syncthing/RestApi.java | 9 +- 3 files changed, 97 insertions(+), 19 deletions(-) rename src/main/java/com/nutomic/syncthingandroid/syncthing/{PostTask.java => PostConfigTask.java} (63%) create mode 100644 src/main/java/com/nutomic/syncthingandroid/syncthing/PostScanTask.java diff --git a/src/main/java/com/nutomic/syncthingandroid/syncthing/PostTask.java b/src/main/java/com/nutomic/syncthingandroid/syncthing/PostConfigTask.java similarity index 63% rename from src/main/java/com/nutomic/syncthingandroid/syncthing/PostTask.java rename to src/main/java/com/nutomic/syncthingandroid/syncthing/PostConfigTask.java index ae2f0580..83f4d013 100644 --- a/src/main/java/com/nutomic/syncthingandroid/syncthing/PostTask.java +++ b/src/main/java/com/nutomic/syncthingandroid/syncthing/PostConfigTask.java @@ -14,41 +14,37 @@ import org.apache.http.protocol.HTTP; import java.io.IOException; /** - * Performs a POST request with no parameters to the URL in uri[0] with the path in uri[1]. + * Sends a new config to {@link #URI_CONFIG}. */ -public class PostTask extends AsyncTask { +public class PostConfigTask extends AsyncTask { - private static final String TAG = "PostTask"; + private static final String TAG = "PostConfigTask"; public static final String URI_CONFIG = "/rest/system/config"; - public static final String URI_SCAN = "/rest/db/scan"; private String mHttpsCertPath; - public PostTask(String httpsCertPath) { + public PostConfigTask(String httpsCertPath) { mHttpsCertPath = httpsCertPath; } /** * params[0] Syncthing hostname - * params[1] URI to call - * params[2] Syncthing API key - * params[3] The request content (optional) + * params[1] Syncthing API key + * params[2] The new config */ @Override protected Boolean doInBackground(String... params) { - String fullUri = params[0] + params[1]; + String fullUri = params[0] + URI_CONFIG; Log.v(TAG, "Calling Rest API at " + fullUri); HttpClient httpclient = Https.createHttpsClient(mHttpsCertPath); HttpPost post = new HttpPost(fullUri); - post.addHeader(new BasicHeader(RestApi.HEADER_API_KEY, params[2])); + post.addHeader(new BasicHeader(RestApi.HEADER_API_KEY, params[1])); try { - if (params.length > 3) { - post.setEntity(new StringEntity(params[3], HTTP.UTF_8)); - Log.v(TAG, "API call parameters: " + params[3]); - } + post.setEntity(new StringEntity(params[3], HTTP.UTF_8)); + Log.v(TAG, "API call parameters: " + params[3]); httpclient.execute(post); } catch (IOException|IllegalArgumentException e) { Log.w(TAG, "Failed to call Rest API at " + fullUri, e); diff --git a/src/main/java/com/nutomic/syncthingandroid/syncthing/PostScanTask.java b/src/main/java/com/nutomic/syncthingandroid/syncthing/PostScanTask.java new file mode 100644 index 00000000..e42a27cd --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/syncthing/PostScanTask.java @@ -0,0 +1,83 @@ +package com.nutomic.syncthingandroid.syncthing; + +import android.os.AsyncTask; +import android.util.Log; + +import com.nutomic.syncthingandroid.util.Https; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URLEncodedUtils; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.protocol.HTTP; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.LinkedList; + +/** + * Performs a POST request to {@link #URI_SCAN} to notify Syncthing of a changed file or folder. + */ +public class PostScanTask extends AsyncTask { + + private static final String TAG = "PostScanTask"; + + public static final String URI_SCAN = "/rest/db/scan"; + + private String mHttpsCertPath; + + public PostScanTask(String httpsCertPath) { + mHttpsCertPath = httpsCertPath; + } + + /** + * params[0] Syncthing hostname + * params[1] Syncthing API key + * params[2] folder parameter (the Syncthing folder to update) + * params[3] sub parameter (the subfolder to update + */ + @Override + protected Void doInBackground(String... params) { + String fullUri = params[0] + URI_SCAN; + + LinkedList urlParams = new LinkedList<>(); + urlParams.add(new BasicNameValuePair("folder", params[2])); + urlParams.add(new BasicNameValuePair("sub", params[3])); + fullUri += "?" + URLEncodedUtils.format(urlParams, HTTP.UTF_8); + Log.v(TAG, "Calling Rest API at " + fullUri); + + // Retry at most 10 times before failing + for (int i = 0; i < 10; i++) { + HttpClient httpclient = Https.createHttpsClient(mHttpsCertPath); + HttpPost post = new HttpPost(fullUri); + post.addHeader(new BasicHeader(RestApi.HEADER_API_KEY, params[1])); + + if (isCancelled()) + return null; + + try { + HttpResponse response = httpclient.execute(post); + if (response.getEntity() != null) + return null; + } catch (IOException | IllegalArgumentException e) { + Log.w(TAG, "Failed to call Rest API at " + fullUri, e); + } + try { + // Don't push the API too hard + Thread.sleep(500 * i); + } catch (InterruptedException e) { + Log.w(TAG, e); + } + Log.w(TAG, "Retrying GetTask Rest API call ("+(i+1)+"/10)"); + } + return null; + } + +} diff --git a/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java b/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java index e89068fa..f47e12df 100644 --- a/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java +++ b/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java @@ -347,10 +347,10 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, */ public void requireRestart(Activity activity, boolean updateConfig) { if (updateConfig) { - new PostTask(mHttpsCertPath) - .execute(mUrl, PostTask.URI_CONFIG, mApiKey, mConfig.toString()); + new PostConfigTask(mHttpsCertPath) + .execute(mUrl, mApiKey, mConfig.toString()); } - // TODO Should wait until PostTask is completed, see #398 + // TODO Should wait until PostConfigTask is completed, see #398 if (mRestartPostponed) return; @@ -941,8 +941,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, */ @Override public void onFolderFileChange(String folderId, String relativePath) { - new PostTask(mHttpsCertPath).execute(mUrl, PostTask.URI_SCAN, mApiKey, "folder", folderId, "sub", - relativePath); + new PostScanTask(mHttpsCertPath).execute(mUrl, mApiKey, folderId, relativePath); } /**