Skip to content

Commit

Permalink
Merge pull request #4 from claudineyns/feature/improvements
Browse files Browse the repository at this point in the history
Improvements
  • Loading branch information
Claudiney Nascimento committed Sep 4, 2022
2 parents 8a3785a + fb2edb1 commit b5daa62
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 84 deletions.
5 changes: 5 additions & 0 deletions .gitignore
@@ -1 +1,6 @@
/target/
dependency-reduced-pom.xml
.classpath
.project
.settings/
Dockerfile
4 changes: 2 additions & 2 deletions pom.xml
Expand Up @@ -6,7 +6,7 @@

<groupId>net.rfc3507</groupId>
<artifactId>icap-server</artifactId>
<version>1.0.0-RC02</version>
<version>1.0.0-SNAPSHOT</version>

<name>icap-server</name>
<description>ICAP Server Implementation for RFC 3507</description>
Expand All @@ -20,7 +20,7 @@
</developer>
</developers>

<url>https://github.com/claudineyns/icap-server</url>
<url>https://github.com/claudineyns/icap-server.git</url>

<licenses>
<license>
Expand Down
155 changes: 81 additions & 74 deletions src/main/java/net/rfc3507/server/ClientHandler.java
Expand Up @@ -7,6 +7,7 @@
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
Expand Down Expand Up @@ -57,6 +58,8 @@ public void run() {
warning("\n### SERVER ### [Cleanup] [WARNING] General error:\n" + e.getMessage());
}

info("\n### SERVER ### [Cleanup] [INFO] Client request completed.\n");

}

private static final String OPTIONS = "OPTIONS";
Expand Down Expand Up @@ -416,54 +419,54 @@ private void analyseRequestHeader(byte[] memory) throws Exception {
}

private void finishResponse() throws IOException {
out.write("0\r\n\r\n".getBytes());
out.write("0\r\n\r\n".getBytes(StandardCharsets.US_ASCII));
}

private void sendCloseConnection() throws IOException {
out.write("Connection: close\r\n".getBytes());
out.write(("Encapsulated: null-body=0\r\n").getBytes());
out.write("\r\n".getBytes());
out.write("Connection: close\r\n".getBytes(StandardCharsets.US_ASCII));
out.write(("Encapsulated: null-body=0\r\n").getBytes(StandardCharsets.US_ASCII));
out.write("\r\n".getBytes(StandardCharsets.US_ASCII));
}

private void sendContinue() throws IOException {
out.write("ICAP/1.0 100 Continue\r\n".getBytes());
out.write("\r\n".getBytes());
out.write("ICAP/1.0 100 Continue\r\n".getBytes(StandardCharsets.US_ASCII));
out.write("\r\n".getBytes(StandardCharsets.US_ASCII));
}

private void sendBadRequest(String cause) throws IOException {
out.write("ICAP/1.0 400 Bad request\r\n".getBytes());
out.write("ICAP/1.0 400 Bad request\r\n".getBytes(StandardCharsets.US_ASCII));
if( cause == null ) {
sendCloseConnection();
} else {
out.write("Connection: close\r\n".getBytes());
out.write(("Encapsulated: opt-body=0\r\n").getBytes());
out.write("\r\n".getBytes());
out.write((Integer.toHexString(cause.length())+"\r\n").getBytes());
out.write((cause+"\r\n").getBytes());
out.write("Connection: close\r\n".getBytes(StandardCharsets.US_ASCII));
out.write(("Encapsulated: opt-body=0\r\n").getBytes(StandardCharsets.US_ASCII));
out.write("\r\n".getBytes(StandardCharsets.US_ASCII));
out.write((Integer.toHexString(cause.length())+"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write((cause+"\r\n").getBytes(StandardCharsets.US_ASCII));
finishResponse();
}
}

private void sendServiceNotFound() throws IOException {
out.write("ICAP/1.0 404 Service not found\r\n".getBytes());
out.write("ICAP/1.0 404 Service not found\r\n".getBytes(StandardCharsets.US_ASCII));
sendCloseConnection();
}

private void sendMethodNotAllowed() throws IOException {
out.write("ICAP/1.0 405 Method not allowed\r\n".getBytes());
out.write("ICAP/1.0 405 Method not allowed\r\n".getBytes(StandardCharsets.US_ASCII));
sendCloseConnection();
}

private void sendServerError(String cause) throws IOException {
out.write("ICAP/1.0 500 Server Error\r\n".getBytes());
out.write("ICAP/1.0 500 Server Error\r\n".getBytes(StandardCharsets.US_ASCII));
if( cause == null ) {
sendCloseConnection();
} else {
out.write("Connection: close\r\n".getBytes());
out.write(("Encapsulated: opt-body=0\r\n").getBytes());
out.write("\r\n".getBytes());
out.write((Integer.toHexString(cause.length())+"\r\n").getBytes());
out.write((cause+"\r\n").getBytes());
out.write("Connection: close\r\n".getBytes(StandardCharsets.US_ASCII));
out.write(("Encapsulated: opt-body=0\r\n").getBytes(StandardCharsets.US_ASCII));
out.write("\r\n".getBytes(StandardCharsets.US_ASCII));
out.write((Integer.toHexString(cause.length())+"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write((cause+"\r\n").getBytes(StandardCharsets.US_ASCII));
finishResponse();
}
}
Expand Down Expand Up @@ -503,25 +506,25 @@ private void handleOptions(

String date = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US).format(new Date());

out.write(("ICAP/1.0 200 OK\r\n").getBytes());
out.write(("Date: "+date+"\r\n").getBytes());
out.write(("Server: "+serverName+"\r\n").getBytes());
out.write(("ICAP/1.0 200 OK\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("Date: "+date+"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("Server: "+serverName+"\r\n").getBytes(StandardCharsets.US_ASCII));

if( service2.startsWith("info")) {
out.write(("Methods: "+RESPMOD+"\r\n").getBytes());
out.write(("Methods: "+RESPMOD+"\r\n").getBytes(StandardCharsets.US_ASCII));
} else if( service2.startsWith("echo")) {
out.write(("Methods: "+REQMOD+", "+RESPMOD+"\r\n").getBytes());
out.write(("Methods: "+REQMOD+", "+RESPMOD+"\r\n").getBytes(StandardCharsets.US_ASCII));
} else if( service2.startsWith("virus_scan")) {
out.write(("Methods: "+REQMOD+", "+RESPMOD+"\r\n").getBytes());
out.write(("Methods: "+REQMOD+", "+RESPMOD+"\r\n").getBytes(StandardCharsets.US_ASCII));
}

out.write(("Service: ICAP-Server-Java/1.0\r\n").getBytes());
out.write(("ISTag:\""+UUID.randomUUID().toString()+"\"\r\n").getBytes());
out.write(("Allow: 204\r\n").getBytes());
out.write(("Preview: 0\r\n").getBytes());
out.write(("Transfer-Complete: *\r\n").getBytes());
out.write(("Encapsulated: null-body=0\r\n").getBytes());
out.write(("\r\n").getBytes());
out.write(("Service: ICAP-Server-Java/1.0\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("ISTag:\""+UUID.randomUUID().toString()+"\"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("Allow: 204\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("Preview: 0\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("Transfer-Complete: *\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("Encapsulated: null-body=0\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("\r\n").getBytes(StandardCharsets.US_ASCII));

methodInProgress = OPTIONS;

Expand Down Expand Up @@ -577,15 +580,15 @@ private void continueRequestModification() throws Exception {
String date = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US).format(new Date());

if( serviceInProgress.startsWith("echo") && httpRequestBody.size() == 0 ) {
out.write(("ICAP/1.0 204 No Content\r\n").getBytes());
out.write(("ICAP/1.0 204 No Content\r\n").getBytes(StandardCharsets.US_ASCII));
} else {
out.write(("ICAP/1.0 200 OK\r\n").getBytes());
out.write(("ICAP/1.0 200 OK\r\n").getBytes(StandardCharsets.US_ASCII));
}

out.write(("Date: "+date+"\r\n").getBytes());
out.write(("Server: "+serverName+"\r\n").getBytes());
out.write(("ISTag:\"ALPHA-B123456-GAMA\"\r\n").getBytes());
out.write(("Connection: close\r\n").getBytes());
out.write(("Date: "+date+"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("Server: "+serverName+"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("ISTag:\"ALPHA-B123456-GAMA\"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("Connection: close\r\n").getBytes(StandardCharsets.US_ASCII));

if( serviceInProgress.startsWith("echo") ) {
completeHandleEcho();
Expand All @@ -605,18 +608,18 @@ private void continueResponseModification() throws Exception {

if( serviceInProgress.startsWith("echo") && httpResponseBody.size() == 0 ) {

out.write(("ICAP/1.0 204 No Content\r\n").getBytes());
out.write(("ICAP/1.0 204 No Content\r\n").getBytes(StandardCharsets.US_ASCII));

} else {

out.write(("ICAP/1.0 200 OK\r\n").getBytes());
out.write(("ICAP/1.0 200 OK\r\n").getBytes(StandardCharsets.US_ASCII));

}

out.write(("Date: "+date+"\r\n").getBytes());
out.write(("Server: "+serverName+"\r\n").getBytes());
out.write(("ISTag: \"ALPHA-B123456-GAMA\"\r\n").getBytes());
out.write(("Connection: close\r\n").getBytes());
out.write(("Date: "+date+"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("Server: "+serverName+"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("ISTag: \"ALPHA-B123456-GAMA\"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write(("Connection: close\r\n").getBytes(StandardCharsets.US_ASCII));

if( serviceInProgress.startsWith("info") ) {
completeHandleInfo(date);
Expand Down Expand Up @@ -660,11 +663,11 @@ private void completeHandleInfo(String date) throws Exception {
httpResponseHeader.append(("Via: 1.0 "+serverName+"\r\n"));
httpResponseHeader.append("\r\n");

out.write(("Encapsulated: res-hdr=0, res-body="+httpResponseHeader.length()+"\r\n").getBytes());
out.write("\r\n".getBytes());
out.write(("Encapsulated: res-hdr=0, res-body="+httpResponseHeader.length()+"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write("\r\n".getBytes(StandardCharsets.US_ASCII));

out.write(httpResponseHeader.toString().getBytes());
out.write(chunkedBody.toString().getBytes());
out.write(httpResponseHeader.toString().getBytes(StandardCharsets.US_ASCII));
out.write(chunkedBody.toString().getBytes(StandardCharsets.US_ASCII));

}

Expand All @@ -682,9 +685,9 @@ private void completeHandleEcho() throws Exception {

ByteArrayOutputStream outHttpRequestBody = new ByteArrayOutputStream();
if( httpRequestBody.size() > 0 ) {
outHttpRequestBody.write((Integer.toHexString(httpRequestBody.size())+"\r\n").getBytes());
outHttpRequestBody.write((Integer.toHexString(httpRequestBody.size())+"\r\n").getBytes(StandardCharsets.US_ASCII));
outHttpRequestBody.write(httpRequestBody.toByteArray());
outHttpRequestBody.write("\r\n".getBytes());
outHttpRequestBody.write("\r\n".getBytes(StandardCharsets.US_ASCII));
if(encapsulatedHeaderEcho.length()>0) encapsulatedHeaderEcho.append(", ");
encapsulatedHeaderEcho.append("req-body=").append(offset);
offset += outHttpRequestBody.size();
Expand All @@ -698,9 +701,9 @@ private void completeHandleEcho() throws Exception {

ByteArrayOutputStream outHttpResponseBody = new ByteArrayOutputStream();
if( httpResponseBody.size() > 0 ) {
outHttpResponseBody.write((Integer.toHexString(httpResponseBody.size())+"\r\n").getBytes());
outHttpResponseBody.write((Integer.toHexString(httpResponseBody.size())+"\r\n").getBytes(StandardCharsets.US_ASCII));
outHttpResponseBody.write(httpResponseBody.toByteArray());
outHttpResponseBody.write("\r\n".getBytes());
outHttpResponseBody.write("\r\n".getBytes(StandardCharsets.US_ASCII));
if(encapsulatedHeaderEcho.length()>0) encapsulatedHeaderEcho.append(", ");
encapsulatedHeaderEcho.append("res-body=").append(offset);
offset += outHttpResponseBody.size();
Expand All @@ -711,8 +714,8 @@ private void completeHandleEcho() throws Exception {
encapsulatedHeaderEcho.append("null-body=").append(offset);
}

out.write(("Encapsulated: "+encapsulatedHeaderEcho+"\r\n").getBytes());
out.write("\r\n".getBytes());
out.write(("Encapsulated: "+encapsulatedHeaderEcho+"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write("\r\n".getBytes(StandardCharsets.US_ASCII));

boolean eof = false;
if(httpRequestHeaders.size() > 0) {
Expand Down Expand Up @@ -753,35 +756,35 @@ private void completeHandleVirusScan() throws Exception {
ByteArrayOutputStream outHttpResponseBody = new ByteArrayOutputStream();

if( icapThreatsHeader.size() > 0 ) {
outHttpResponseHeaders.write("HTTP/1.1 403 Forbidden\r\n".getBytes());
outHttpResponseHeaders.write("HTTP/1.1 403 Forbidden\r\n".getBytes(StandardCharsets.US_ASCII));
} else {
outHttpResponseHeaders.write("HTTP/1.1 200 OK\r\n".getBytes());
outHttpResponseHeaders.write("HTTP/1.1 200 OK\r\n".getBytes(StandardCharsets.US_ASCII));
}

outHttpResponseHeaders.write(("Server: "+serverName+"\r\n").getBytes());
outHttpResponseHeaders.write(("Server: "+serverName+"\r\n").getBytes(StandardCharsets.US_ASCII));

StringBuilder responseMessage = new StringBuilder("");

if( threatName != null ) {

responseMessage.append("Virus Found: ").append(threatName).append("\n");

outHttpResponseHeaders.write(("Content-Type: text/plain\r\n").getBytes());
outHttpResponseHeaders.write(("Content-Length: "+responseMessage.length()+"\r\n").getBytes());
outHttpResponseHeaders.write(("Content-Type: text/plain\r\n").getBytes(StandardCharsets.US_ASCII));
outHttpResponseHeaders.write(("Content-Length: "+responseMessage.length()+"\r\n").getBytes(StandardCharsets.US_ASCII));

outHttpResponseBody.write((Integer.toHexString(responseMessage.length())+"\r\n").getBytes());
outHttpResponseBody.write(responseMessage.toString().getBytes());
outHttpResponseBody.write("\r\n".getBytes());
outHttpResponseBody.write((Integer.toHexString(responseMessage.length())+"\r\n").getBytes(StandardCharsets.US_ASCII));
outHttpResponseBody.write(responseMessage.toString().getBytes(StandardCharsets.US_ASCII));
outHttpResponseBody.write("\r\n".getBytes(StandardCharsets.US_ASCII));

}

outHttpResponseHeaders.write(("Via: "+serverName+"\r\n").getBytes());
outHttpResponseHeaders.write(("Via: "+serverName+"\r\n").getBytes(StandardCharsets.US_ASCII));

if( icapThreatsHeader.size() > 0 ) {
outHttpResponseHeaders.write(icapThreatsHeader.toByteArray());
}

outHttpResponseHeaders.write("\r\n".getBytes());
outHttpResponseHeaders.write("\r\n".getBytes(StandardCharsets.US_ASCII));

if(outHttpRequestHeaders.size() > 0) {
if(encapsulatedHeaderEcho.length()>0) encapsulatedHeaderEcho.append(", ");
Expand Down Expand Up @@ -812,8 +815,8 @@ private void completeHandleVirusScan() throws Exception {
encapsulatedHeaderEcho.append("null-body=").append(offset);
}

out.write(("Encapsulated: "+encapsulatedHeaderEcho+"\r\n").getBytes());
out.write("\r\n".getBytes());
out.write(("Encapsulated: "+encapsulatedHeaderEcho+"\r\n").getBytes(StandardCharsets.US_ASCII));
out.write("\r\n".getBytes(StandardCharsets.US_ASCII));

boolean eof = false;
if(outHttpRequestHeaders.size() > 0) {
Expand Down Expand Up @@ -871,9 +874,9 @@ private void findThreatsInPayloadOnWindows() throws Exception {

for( String threat: response.getThreatList() ) {
threatName = threat;
icapThreatsHeader.write(("X-Threat-Description: "+threatName+"\r\n").getBytes());
icapThreatsHeader.write(("X-Threat-Resolution: None\r\n").getBytes());
icapThreatsHeader.write(("X-Threat-Type: Threat\r\n").getBytes());
icapThreatsHeader.write(("X-Threat-Description: "+threatName+"\r\n").getBytes(StandardCharsets.US_ASCII));
icapThreatsHeader.write(("X-Threat-Resolution: None\r\n").getBytes(StandardCharsets.US_ASCII));
icapThreatsHeader.write(("X-Threat-Type: Threat\r\n").getBytes(StandardCharsets.US_ASCII));
break;
}

Expand All @@ -893,9 +896,9 @@ private void findThreatsInPayloadOnLinux() throws Exception {

if( response.getThreat() != null ) {
threatName = response.getThreat();
icapThreatsHeader.write(("X-Threat-Description: "+threatName+"\r\n").getBytes());
icapThreatsHeader.write(("X-Threat-Resolution: None\r\n").getBytes());
icapThreatsHeader.write(("X-Threat-Type: Threat\r\n").getBytes());
icapThreatsHeader.write(("X-Threat-Description: "+threatName+"\r\n").getBytes(StandardCharsets.US_ASCII));
icapThreatsHeader.write(("X-Threat-Resolution: None\r\n").getBytes(StandardCharsets.US_ASCII));
icapThreatsHeader.write(("X-Threat-Type: Threat\r\n").getBytes(StandardCharsets.US_ASCII));
}

}
Expand Down Expand Up @@ -928,6 +931,10 @@ private void warning(String message) {
Logger.getGlobal().warning(message);
}

private void info(String message) {
Logger.getGlobal().info(message);
}

private static void reset( int[]c ){
for(int i = 0; i < c.length; ++i) c[i]=-1;
}
Expand All @@ -937,7 +944,7 @@ private static void shift( int[]c ) {
}

public static void main(String[] args) throws Exception {
Daemon.main(args);
Worker.main(args);
}

}

0 comments on commit b5daa62

Please sign in to comment.