package org.pasif.server.http;
import java.io.File;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.ServerSocket;
import java.net.Socket;
import org.apache.http.ConnectionClosedException;
import org.apache.http.HttpException;
import org.apache.http.HttpServerConnection;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.impl.DefaultHttpServerConnection;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestHandlerRegistry;
import org.apache.http.protocol.HttpService;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
import org.pas.utils.LoggerHandler;
import org.pas.utils.Utils;
public class PasHttpFileServer {
private static LoggerHandler log = null;
private String docRoot;
private int port;
private ServerSocket serversocket;
private static byte[] decryptPwd = new byte[128];
private String xsdFile;
public PasHttpFileServer(LoggerHandler log, String docRoot, int port, String xsdFile) {
PasHttpFileServer.log = log;
this.docRoot = docRoot;
this.port = port;
this.xsdFile = xsdFile;
}
public void start() {
File file = new File("license/license.lic");
if (file.exists()) {
try {
byte[] pwd = Utils.readPwdFromFile(file);
if (Utils.validatePwd(pwd)) {
for (int i = 0; i <= 127; i++) {
decryptPwd[i] = pwd[i];
}
Thread t = new RequestListenerThread(port, docRoot);
t.setDaemon(false);
t.start();
} else {
log.error("密钥文件已过期,请重新申请新的密钥。", true);
}
} catch (Exception ex) {
log.error(ex.toString(), true);
}
} else {
log.error("无法找到密钥文件,服务器无法正常启动!", true);
}
}
public void stop() {
try {
serversocket.close();
log.info("服务器关闭成功。", true);
} catch (Exception ex) {
log.error(ex.toString(), true);
}
}
class RequestListenerThread extends Thread {
private final HttpParams params;
private final HttpService httpService;
public RequestListenerThread(int port, final String docroot)
throws IOException {
serversocket = new ServerSocket(port);
this.params = new BasicHttpParams();
this.params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000).setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE,
8 * 1024).setBooleanParameter(
CoreConnectionPNames.STALE_CONNECTION_CHECK, false).setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true).setParameter(CoreProtocolPNames.ORIGIN_SERVER,
"HttpComponents/1.1");
// Set up the HTTP protocol processor
BasicHttpProcessor httpproc = new BasicHttpProcessor();
httpproc.addInterceptor(new ResponseDate());
httpproc.addInterceptor(new ResponseServer());
httpproc.addInterceptor(new ResponseContent());
httpproc.addInterceptor(new ResponseConnControl());
// Set up request handlers
HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
reqistry.register("*", new PasHttpFileHandler(docroot, decryptPwd, log, xsdFile));
// Set up the HTTP service
this.httpService = new HttpService(httpproc,
new DefaultConnectionReuseStrategy(),
new DefaultHttpResponseFactory());
this.httpService.setParams(this.params);
this.httpService.setHandlerResolver(reqistry);
}
@Override
public void run() {
log.info("服务器开启。", true);
while (!Thread.interrupted()) {
try {
// Set up HTTP connection
Socket socket = serversocket.accept();
DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
// log.info("接收到" + socket.getInetAddress() + "的请求。", true);
conn.bind(socket, this.params);
// Start worker thread
Thread t = new WorkerThread(this.httpService, conn);
t.setDaemon(true);
t.start();
} catch (InterruptedIOException ex) {
log.error(ex.toString(), false);
break;
} catch (IOException e) {
log.error(e.toString(), false);
break;
}
}
}
}
static class WorkerThread extends Thread {
private final HttpService httpservice;
private final HttpServerConnection conn;
public WorkerThread(final HttpService httpservice,
final HttpServerConnection conn) {
super();
this.httpservice = httpservice;
this.conn = conn;
}
@Override
public void run() {
HttpContext context = new BasicHttpContext(null);
try {
while (!Thread.interrupted() && this.conn.isOpen()) {
this.httpservice.handleRequest(this.conn, context);
}
} catch (ConnectionClosedException ex) {
log.info(ex.toString(), false);
} catch (IOException ex) {
log.error(ex.toString(), true);
} catch (HttpException ex) {
log.error(ex.toString(), true);
} finally {
try {
this.conn.shutdown();
} catch (IOException ignore) {
log.info(ignore.toString(), true);
}
}
}
}
}