SOCKET实现ICAP协议通讯
首先基于springboot搭一个socket即时通讯
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return "上传失败,请选择文件";
}
String fileName = file.getOriginalFilename();
try {
byte[] bytes = file.getBytes();
ICAPClientUtil socket = new ICAPClientUtil("*.*.*.*", 1111, "icap服务端", fileName, 3000, 3000, InetAddress.getLocalHost().toString(), LOGGER);
String icap = socket.scanFile(bytes, fileName);
int i = socket.resultCode(icap);
return icap + "\n" + "====resultCode==" + i+"服务器端口==="+port;
} catch (Exception e) {
return e.toString();
}
}
ICAPClientUtil工具类
private String serverAddress;
private int serverPort;
private String serviceName;
private String profileName;
private int conTimeOut;
private int soTimeOut;
private java.io.BufferedReader input = null;
private java.io.DataOutputStream output = null;
private java.net.Socket socket = null;
private String[] results;
private String clientIP;
private Logger logger;
public ICAPClientUtil(String serverAddress, int serverPort, String serviceName,
String profileName, int conTimeOut, int soTimeOut, String clientIP, Logger log) {
this.serverAddress = serverAddress;
this.serverPort = serverPort;
this.serviceName = serviceName;
this.profileName = profileName;
this.conTimeOut = conTimeOut;
this.soTimeOut = soTimeOut;
this.clientIP = clientIP;
this.logger = log;
}
private int connect(String serverAddress, int serverPort) {
int retValue = 0;
if (this.socket == null) {
try {
InetAddress ip_address = InetAddress.getByName(serverAddress);
this.socket = new Socket();
socket.connect(new InetSocketAddress(ip_address, serverPort), conTimeOut);
this.socket.setSoTimeout(soTimeOut);
this.output = new DataOutputStream(this.socket.getOutputStream());
this.input = new java.io.BufferedReader(new InputStreamReader(this.socket.getInputStream()));
} catch (Exception e) {
retValue = -1;
logger.error("ICAP:Error:connect(" + serverAddress + ":" + serverPort + "):" + e);
}
}
return retValue;
}
/**
* disconnect socket
**/
private void disconnect() {
try {
this.output.flush();
this.output.close();
this.input.close();
this.socket.close();
this.socket = null;
} catch (Exception e) {
logger.error("ICAP:Error:disconnect():" + e);
}
}
/**
* receive response from ICAP server
*/
private String receive() {
String value = " ";
String returnString = new String();
this.results = new String[10240];
int array_location = 0;
try {
while ((value = this.input.readLine()) != null && value.length() != 0) {
logger.info("ICAP:stdOut:" + value);
returnString = returnString + value + "\n";
this.results[array_location] = value;
array_location++;
}
} catch (Exception e) {
logger.error("ICAP:Error:receive():" + e);
returnString = "Error:receive():" + e;
}
return returnString;
}
/**
* enter here if you only want integer result codes
*/
public int resultCode(String returnString) {
int retValue = 0;
//if (returnString.startsWith("Error") || returnString.startsWith("Undefined") || "".equals(returnString)) {
// retValue = -1;
//}
if (returnString.startsWith("Infected") || returnString.startsWith("Blocked")) {
if (returnString.contains(":")) {
try {
String[] responses = returnString.split(":", 3);
retValue = Integer.parseInt(responses[1]);
} catch (Exception e) {
logger.error("ICAP:Error:scanfiletext:parsereturnString:" + returnString + ":" + e);
retValue = 0;
}
}
}
if (returnString.startsWith("Clean")) {
retValue = 0;
}
return retValue;
}
/**
* enter here if you want text results
* 入口
*
*/
public String scanFile(byte[] downloadByte, String fileMd5) {
int retValue = 0;
long fileLen = downloadByte.length;
String serverResponse = "";
if (fileLen > 1 && (fileLen > Long.MAX_VALUE)) {
retValue = -1;
serverResponse = "Error:scanfiletext:fileio:too_large:(" + fileLen + "):\"" + fileMd5 + "\"";
}
if (retValue < 0) {
logger.error("ICAP:" + serverResponse);
return serverResponse;
}
retValue = connect(this.serverAddress, this.serverPort);
ICAPResponse icapResponse = new ICAPResponse();
java.text.DateFormat dateFormat = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
// where file is sent to be scanned.
while (retValue == 0) {
int req_header = 0;
int res_header;
int res_body;
String requestHeader = "GET http://" + this.clientIP + "/" + dateFormat.format(new java.util.Date()) + "/" + fileMd5 + " HTTP/1.1\r\n" + "Host: " + this.clientIP + "\r\n\r\n";
String responseHeader = "HTTP/1.1 200 OK\r\n" + "Transfer-Encoding: chunked\r\n\r\n";
res_header = requestHeader.getBytes().length;
res_body = res_header + (responseHeader.length());
String profile = "";
if (!"".equals(this.profileName)) {
profile = "?profile=" + this.profileName;
}
String icapRequest = "RESPMOD icap://" + this.serverAddress + ":" + this.serverPort + "/" + this.serviceName + profile + " ICAP/1.0\r\n" + "Allow: 204\r\n"
// added connection: close
+ "Connection: close\r\n" + "Encapsulated: req-hdr=" + req_header + " res-hdr=" + res_header + " res-body=" + res_body + "\r\n" + "Host: " + this.serverAddress + "\r\n"
// + "Preview: " + Long.toString(this.previewBytes) + "\r\n"
+ "User-Agent: JavaICAPClient\r\n" + "X-Client-IP: " + this.clientIP + "\r\n\r\n";
logger.info("监听请求值===" + icapRequest);
retValue = send(icapRequest);
logger.warn("写入返回值=====" + retValue);
if (retValue == -1) {
break;
}
retValue = send(requestHeader);
if (retValue == -1) {
break;
}
retValue = send(responseHeader);
if (retValue == -1) {
break;
}
try {
retValue = send(Long.toHexString(fileLen) + "\r\n");
this.output.write(downloadByte);
retValue = send("\r\n");
retValue = send("0\r\n\r\n");
this.output.flush();
serverResponse = icapResponse.request(receive());
} catch (Exception e) {
logger.error("ICAP:Error:filesend:" + e);
return "false";
}
disconnect();
break;
}
return serverResponse;
}
private int send(String str) {
int retValue = 0;
try {
this.output.write(str.getBytes());
this.output.flush();
} catch (Exception e) {
logger.error("ICAP:Error:send(" + str + "):" + e);
retValue = -1;
}
return retValue;
}
配置属性类
public boolean continue_check(String server_response) {
boolean retValue = true;
if (server_response.length() != 12) {
server_response = server_response.substring(0, 12);
}
if (server_response.startsWith("ICAP/1.0 100")) {
retValue = true;
} else {
retValue = false;
}
return retValue;
}
public String request(String serverResponse) {
String returnString = "";
String status = "Undefined";
String blockResult = "";
String virusName = ";";
String[] lines = serverResponse.split("\n");
for (int i = 0; i < lines.length; i++) {
if (lines[i].startsWith("ICAP/1.0 204")) {
status = "Clean:";
blockResult = "0";
virusName = "No malware detected;";
break;
}
if (lines[i].startsWith("ICAP/1.0 200")) {
status = "Blocked:";
blockResult = "200";
continue;
}
if (lines[i].startsWith("X-Virus-Name:")) {
status = "Infected:";
if ((lines[i].substring(14)).startsWith(virusName.substring(0, virusName.length() - 1))) {
virusName = lines[i].substring(14);
} else {
virusName += lines[i].substring(14);
}
virusName += ";";
continue;
}
if (lines[i].startsWith("X-WWBlockResult:")) {
blockResult = lines[i].substring(17);
switch (Integer.parseInt(blockResult)) {
case 90:
virusName += "Policy:Unwanted Unsigned Content;";
break;
case 81:
virusName += "Policy:Authorization needed;";
break;
case 45:
virusName += "Policy:Macros unwanted;";
break;
case 44:
virusName += "Policy:Office document unreadable;";
break;
case 43:
virusName += "Policy:Encrypted document unwanted;";
break;
case 42:
virusName += "Policy:ActiveX unwanted;";
break;
case 41:
virusName += "Policy:Document Inspector;";
break;
case 40:
virusName += "Policy:Text Categorization unwanted;";
break;
case 34:
virusName += "Policy:Encrypted archive unwanted;";
break;
case 33:
virusName += "Policy:Archive recursion level exceeded;";
break;
case 32:
virusName += "Policy:Mailbomb unwanted;";
break;
case 31:
virusName += "Policy:Corrupted archive unwanted;";
break;
case 30:
virusName += "Policy:Multipart archive unwanted;";
break;
case 23:
virusName += "Policy:Generic Body Filter;";
break;
case 22:
virusName += "Policy:Media type blacklisted;";
break;
case 21:
virusName += "Policy:Media type mismatch;";
break;
default:
status = "Infected:";
break;
}
continue;
}
if (lines[i].startsWith("ICAP/1.0 ")) {
status = "Error:" + lines[i];
}
}
if (virusName.endsWith(";"))
virusName = virusName.substring(0, virusName.length() - 1);
virusName.trim();
if ("".equals(virusName))
virusName = "Unknown";
returnString = status + blockResult + ":\"" + virusName + "\"";
return returnString;
}
注意事项:
1.icap有自己的通讯协议格式,在百度文档里面有详细介绍
按照这个模板来写也是没什么问题的。存个档,万一以后又遇到怎么办。