Skip to content

Commit

Permalink
added preference to stop server after some idle time, see GH issue #318
Browse files Browse the repository at this point in the history
  • Loading branch information
wolpi committed Mar 29, 2024
1 parent 7e53466 commit 476676a
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 1 deletion.
2 changes: 2 additions & 0 deletions primitiveFTPd/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@
<string name="prefSummaryFtpPassivePorts">Ports for FTP passive data connection. May be a single port, a list or range of ports. E.g. 5678,5700-5710,5800,5900.</string>
<string name="prefTitleIdleTimeout">Server Idle Timeout</string>
<string name="prefSummaryIdleTimeout">Server will terminate idle connections after this time in seconds (FTP only)</string>
<string name="prefTitleIdleTimeoutServerStop">Idle timeout to stop server</string>
<string name="prefSummaryIdleTimeoutServerStop">Server(s) will be stopped after this time in minutes if no client activity takes place. Set to 0 to disable.</string>
<string name="prefSummaryIdleTimeoutV2">Server will terminate idle connections after this time in seconds. Set to 0 to disable.</string>
<string name="prefTitleLogging">Log</string>
<string name="prefSummaryLogging">Log serves analyzing of errors. If the app does not work properly on your device you can send a log to developers. May require to restart the app.</string>
Expand Down
10 changes: 9 additions & 1 deletion primitiveFTPd/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@
android:title="@string/prefTitleIdleTimeout"
android:summary="@string/prefSummaryIdleTimeoutV2"
android:defaultValue="0"
android:numeric="integer"
android:inputType="number"
/>
<EditTextPreference
android:name="idleTimeoutServerStop"
android:key="idleTimeoutServerStopPref"
android:title="@string/prefTitleIdleTimeoutServerStop"
android:summary="@string/prefSummaryIdleTimeoutServerStop"
android:defaultValue="30"
android:inputType="number"
/>
<EditTextPreference
android:name="allowedIpsPattern"
Expand Down
3 changes: 3 additions & 0 deletions primitiveFTPd/src/org/primftpd/prefs/LoadPrefsUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class LoadPrefsUtil
public static final String PREF_KEY_FTP_PASSIVE_PORTS = "ftpPassivePortsPref";
public static final String PREF_KEY_BIND_IP = "bindIpPref";
public static final String PREF_KEY_IDLE_TIMEOUT = "idleTimeoutPref";

public static final String PREF_KEY_IDLE_TIMEOUT_SERVER_STOP = "idleTimeoutServerStopPref";
public static final String PREF_KEY_STORAGE_TYPE = "storageTypePref";
public static final String PREF_KEY_SAF_URL = "safUrlPref";
public static final String PREF_KEY_ALLOWED_IPS_PATTERN = "allowedIpsPatternPref";
Expand All @@ -50,6 +52,7 @@ public class LoadPrefsUtil
static final String PORT_PASSIVE_DEFAULT_VAL_STR = String.valueOf(PORT_PASSIVE_DEFAULT_VAL);
public static final int IDLE_TIMEOUT_DEFAULT_VAL = 0;
static final String IDLE_TIMEOUT_DEFAULT_VAL_STR = String.valueOf(IDLE_TIMEOUT_DEFAULT_VAL);
public static final String IDLE_TIMEOUT_SERVER_STOP_DEFAULT_VAL = "30";

/**
* @return Android {@link SharedPreferences} object.
Expand Down
48 changes: 48 additions & 0 deletions primitiveFTPd/src/org/primftpd/services/AbstractServerService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.preference.PreferenceManager;
import android.widget.Toast;

import org.greenrobot.eventbus.EventBus;
Expand All @@ -22,6 +25,7 @@
import org.primftpd.events.ServerInfoRequestEvent;
import org.primftpd.events.ServerInfoResponseEvent;
import org.primftpd.events.ServerStateChangedEvent;
import org.primftpd.prefs.LoadPrefsUtil;
import org.primftpd.prefs.PrefsBean;
import org.primftpd.R;
import org.primftpd.share.QuickShareBean;
Expand Down Expand Up @@ -61,6 +65,13 @@ public abstract class AbstractServerService
QuickShareBean quickShareBean;
private NsdManager.RegistrationListener nsdRegistrationListener;

private Handler timerHandler;
private long timerTimeout;
private final Runnable timerTask = () -> {
logger.info("stopping server due to idle timeout");
ServicesStartStopUtil.stopServers(AbstractServerService.this);
};

protected abstract ServerServiceHandler createServiceHandler(
Looper serviceLooper,
AbstractServerService service);
Expand Down Expand Up @@ -125,6 +136,20 @@ public int onStartCommand(Intent intent, int flags, int startId) {
// post event
EventBus.getDefault().post(new ServerStateChangedEvent());

// handle server stop on idle timeout
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
try {
long timeout = Long.parseLong(sharedPreferences.getString(
LoadPrefsUtil.PREF_KEY_IDLE_TIMEOUT_SERVER_STOP,
LoadPrefsUtil.IDLE_TIMEOUT_SERVER_STOP_DEFAULT_VAL));
if (timeout > 0) {
this.timerTimeout = timeout * 60 * 1000;
startTimer();
}
} catch (Exception e) {
logger.error("could not start timer", e);
}

// we don't want the system to kill the ftp server
//return START_NOT_STICKY;
return START_STICKY;
Expand All @@ -139,6 +164,11 @@ public void onDestroy() {
msg.arg1 = MSG_STOP;
serviceHandler.sendMessage(msg);

// stop on idle timer not needed anymore
if (this.timerHandler != null) {
stopTimer();
}

// post event
EventBus.getDefault().post(new ServerStateChangedEvent());

Expand All @@ -153,6 +183,24 @@ public void onEvent(ServerInfoRequestEvent event) {
EventBus.getDefault().post(new ServerInfoResponseEvent(quickShareNumberOfFiles));
}

@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onEvent(ClientActionEvent event) {
if (timerHandler != null) {
stopTimer();
startTimer();
}
}

private synchronized void stopTimer() {
this.timerHandler.removeCallbacks(timerTask);
}
private synchronized void startTimer() {
if (this.timerHandler == null) {
this.timerHandler = new Handler();
}
this.timerHandler.postDelayed(timerTask, this.timerTimeout);
}

@Override
public void postClientAction(
ClientActionEvent.Storage storage,
Expand Down

0 comments on commit 476676a

Please sign in to comment.