view src/goodjava/lucene/backup/BackupServer.java @ 1689:af22d6c120e4

improve http/serve.luan
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 12 Jun 2022 18:48:01 -0600
parents 445048f9eca7
children 973d3039c421
line wrap: on
line source

package goodjava.lucene.backup;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.net.Socket;
import java.net.ServerSocket;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLServerSocket;
import goodjava.util.SoftCacheMap;
import goodjava.io.IoUtils;
import goodjava.rpc.RpcServer;
import goodjava.rpc.RpcCall;
import goodjava.rpc.RpcClient;
import goodjava.rpc.RpcResult;
import goodjava.rpc.Rpc;
import goodjava.rpc.RpcException;
import goodjava.logging.Logger;
import goodjava.logging.LoggerFactory;


public final class BackupServer {
	private static final Logger logger = LoggerFactory.getLogger(BackupServer.class);

	public static int port = 9102;
	public static String[] cipherSuites = new String[] {
		"TLS_DH_anon_WITH_AES_128_GCM_SHA256",
		"TLS_DH_anon_WITH_AES_128_CBC_SHA256",
		"TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
		"TLS_DH_anon_WITH_AES_128_CBC_SHA",
		"TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
		"SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
		"TLS_ECDH_anon_WITH_RC4_128_SHA",
		"SSL_DH_anon_WITH_RC4_128_MD5",
		"SSL_DH_anon_WITH_DES_CBC_SHA",
		"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
		"SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
	};

	private final File backupDir;
	private static final ExecutorService threadPool = Executors.newCachedThreadPool();
	private static final Map<String,Backup> backups = new SoftCacheMap<String,Backup>();

	public BackupServer(File backupDir) throws IOException {
		this.backupDir = backupDir;
		IoUtils.mkdirs(backupDir);
	}

	public synchronized void start() throws IOException {
		final ServerSocket ss;
		if( cipherSuites == null ) {
			ss = new ServerSocket(port);
		} else {
			ss = IoUtils.getSSLServerSocketFactory().createServerSocket(port);
			((SSLServerSocket)ss).setEnabledCipherSuites(cipherSuites);
		}
		threadPool.execute(new Runnable(){public void run() {
			try {
				while(!threadPool.isShutdown()) {
					final Socket socket = ss.accept();
					threadPool.execute(new Runnable(){public void run() {
						handle(socket);
					}});
				}
			} catch(IOException e) {
				logger.error("",e);
			}
		}});
		logger.info("started server on port "+port);
	}

	private void handle(Socket socket) {
		RpcServer rpc = new RpcServer(socket);
		Backup backup = null;
		while( !rpc.isClosed() ) {
			RpcCall call = rpc.read();
			if( call == null )
				break;
			if( call.cmd.equals("exists") ) {
				String name = (String)call.args[0];
				rpc.write( new RpcResult(new Object[]{new File(backupDir,name).exists()}) );
			} else if( call.cmd.equals("login") ) {
				String name = (String)call.args[0];
				synchronized(backups) {
					backup = backups.get(name);
					if( backup == null ) {
						backup = new Backup(new File(backupDir,name));
						backups.put(name,backup);
					}
				}
				rpc.write(Rpc.OK);
			} else if( backup != null ) {
				backup.handle(rpc,call);
			} else {
				rpc.write( new RpcException("login expected") );
				rpc.close();
				return;
			}
		}
	}


	// for client

	public static RpcClient rpcClient(String backupDomain) throws IOException {
		Socket socket;
		if( BackupServer.cipherSuites == null ) {
			socket = new Socket(backupDomain,BackupServer.port);
		} else {
			socket = IoUtils.getSSLSocketFactory().createSocket(backupDomain,BackupServer.port);
			((SSLSocket)socket).setEnabledCipherSuites(BackupServer.cipherSuites);
		}
		return new RpcClient(socket);
	}

}