esoe
2 years ago
1 changed files with 220 additions and 0 deletions
@ -0,0 +1,220 @@ |
|||||||
|
package ru.molokoin.example; |
||||||
|
|
||||||
|
/** |
||||||
|
UploadServer program - simple file upload web-server |
||||||
|
Author: Denis Volkov (c) 2007 |
||||||
|
For information and support visit http://www.denvo.ru
|
||||||
|
|
||||||
|
This program is FREEWARE, you are free to use any part of code |
||||||
|
as well as whole program in your development provided that you |
||||||
|
remain original copyrights and site name in your source. |
||||||
|
|
||||||
|
The product is distributed "as is". The author of the Product will |
||||||
|
not be liable for any consequences, loss of profit or any other kind |
||||||
|
of loss, that may occur while using the product itself and/or together |
||||||
|
with any other software. |
||||||
|
|
||||||
|
*/ |
||||||
|
|
||||||
|
import java.net.*; |
||||||
|
import java.io.*; |
||||||
|
import java.security.*; |
||||||
|
import java.util.*; |
||||||
|
import java.util.regex.*; |
||||||
|
import java.nio.charset.*; |
||||||
|
|
||||||
|
public class UploadServer extends Thread |
||||||
|
{ |
||||||
|
private final static String httpHeader = "HTTP/1.1 200 OK\r\n" |
||||||
|
+ "Content-Type: text/html\r\n" |
||||||
|
+ "\r\n"; |
||||||
|
private final static String uploadFormString = httpHeader |
||||||
|
+ "<form method=\"POST\" enctype=\"multipart/form-data\">\r\n" |
||||||
|
+ "<input type=\"file\" name=\"upload_file\" size=100>\r\n" |
||||||
|
+ "<input type=\"submit\" value=\"Upload\">\r\n" |
||||||
|
+ "</form>\r\n\r\n"; |
||||||
|
|
||||||
|
private final Charset streamCharset = Charset.forName("ISO-8859-1"); |
||||||
|
|
||||||
|
private ServerSocket serverSocket; |
||||||
|
private Socket clientSocket; |
||||||
|
|
||||||
|
UploadServer(int port) throws Exception |
||||||
|
{ |
||||||
|
serverSocket = new ServerSocket(port); |
||||||
|
System.err.println("Server ready @" + port); |
||||||
|
} |
||||||
|
|
||||||
|
public void run() |
||||||
|
{ |
||||||
|
while(true) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
clientSocket = serverSocket.accept(); |
||||||
|
System.err.println("Client connection accepted from " |
||||||
|
+ clientSocket.getInetAddress().toString()); |
||||||
|
// Read and process data from socket
|
||||||
|
processConnection(); |
||||||
|
} |
||||||
|
catch(Exception e) |
||||||
|
{ |
||||||
|
System.err.println("Exception in run's main loop"); |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
// Close socket
|
||||||
|
try |
||||||
|
{ |
||||||
|
clientSocket.close(); |
||||||
|
} |
||||||
|
catch(Exception e) { } |
||||||
|
System.err.println("Client connection closed"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void processConnection() throws Exception |
||||||
|
{ |
||||||
|
InputStream inStream = clientSocket.getInputStream(); |
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(inStream, streamCharset)); |
||||||
|
OutputStream out = clientSocket.getOutputStream(); |
||||||
|
// Read requiest header
|
||||||
|
String headerLine, firstLine = null; |
||||||
|
Map headerData = new TreeMap(); |
||||||
|
Pattern headerPattern = Pattern.compile("([^\\:]+)\\:(.*)"); |
||||||
|
while((headerLine = in.readLine()).length() > 0) |
||||||
|
{ |
||||||
|
if(firstLine == null) |
||||||
|
firstLine = headerLine; |
||||||
|
else |
||||||
|
{ |
||||||
|
Matcher m = headerPattern.matcher(headerLine); |
||||||
|
if(m.matches()) |
||||||
|
{ |
||||||
|
headerData.put(m.group(1).trim(), m.group(2).trim()); |
||||||
|
} |
||||||
|
} |
||||||
|
System.out.println("HEADER: " + headerLine); |
||||||
|
} |
||||||
|
// Process first line of request
|
||||||
|
if(firstLine.startsWith("GET")) |
||||||
|
{ |
||||||
|
System.out.println("Send upload form"); |
||||||
|
// Show upload form
|
||||||
|
out.write(uploadFormString.getBytes()); |
||||||
|
} |
||||||
|
else if(firstLine.startsWith("POST")) |
||||||
|
{ |
||||||
|
// Get body info
|
||||||
|
int contentLength = Integer.parseInt((String)(headerData.get("Content-Length"))); |
||||||
|
String contentType = (String)(headerData.get("Content-Type")); |
||||||
|
String boundary = "\r\n--" + contentType.substring(contentType.indexOf("boundary=") + 9) + "--"; |
||||||
|
System.out.println("File upload, reading body: " + contentLength + " bytes"); |
||||||
|
// Prepare to reading
|
||||||
|
Pattern fileNamePattern = Pattern.compile("filename=\"([^\"]+)\""); |
||||||
|
OutputStreamWriter writer = null; |
||||||
|
MessageDigest digestMD5 = MessageDigest.getInstance("MD5"); |
||||||
|
String fileName = null; |
||||||
|
String prevBuffer = ""; |
||||||
|
char[] buffer = new char[16 << 10]; |
||||||
|
int totalLength = contentLength; |
||||||
|
// Reading loop
|
||||||
|
while(contentLength > 0) |
||||||
|
{ |
||||||
|
if(writer == null) |
||||||
|
{ |
||||||
|
// Read strings
|
||||||
|
String bodyLine = in.readLine(); |
||||||
|
contentLength -= bodyLine.length() + 2; |
||||||
|
// Find name of file
|
||||||
|
if(bodyLine.length() > 0) |
||||||
|
{ |
||||||
|
Matcher m = fileNamePattern.matcher(bodyLine); |
||||||
|
if(m.find()) |
||||||
|
{ |
||||||
|
fileName = m.group(1); |
||||||
|
} |
||||||
|
} |
||||||
|
else if(fileName != null) |
||||||
|
{ |
||||||
|
OutputStream stream = new FileOutputStream(fileName); |
||||||
|
if(digestMD5 != null) |
||||||
|
stream = new DigestOutputStream(stream, digestMD5); |
||||||
|
writer = new OutputStreamWriter(stream, streamCharset); |
||||||
|
} |
||||||
|
else |
||||||
|
throw new RuntimeException("Name of uploaded file not found"); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
// Read data from stream
|
||||||
|
int readLength = Math.min(contentLength, buffer.length); |
||||||
|
readLength = in.read(buffer, 0, readLength); |
||||||
|
if(readLength < 0) |
||||||
|
break; |
||||||
|
contentLength -= readLength; |
||||||
|
// Find boundary string
|
||||||
|
String curBuffer = new String(buffer, 0, readLength); |
||||||
|
String bothBuffers = prevBuffer + curBuffer; |
||||||
|
int boundaryPos = bothBuffers.indexOf(boundary); |
||||||
|
if(boundaryPos == -1) |
||||||
|
{ |
||||||
|
writer.write(prevBuffer, 0, prevBuffer.length()); |
||||||
|
prevBuffer = curBuffer; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
writer.write(bothBuffers, 0, boundaryPos); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
// Write stats
|
||||||
|
System.out.print("Read: " + (totalLength - contentLength) |
||||||
|
+ " Remains: " + contentLength + " Total: " + totalLength |
||||||
|
+ " bytes \r"); |
||||||
|
} |
||||||
|
System.out.println("Done "); |
||||||
|
writer.close(); |
||||||
|
// Finalize digest calculation
|
||||||
|
byte[] md5Sum = digestMD5.digest(); |
||||||
|
StringBuffer md5SumString = new StringBuffer(); |
||||||
|
for(int n = 0; n < md5Sum.length; ++ n) |
||||||
|
md5SumString.append(printByte(md5Sum[n])); |
||||||
|
// Output client info
|
||||||
|
String answer = httpHeader + "<p><b>Upload completed, " + totalLength |
||||||
|
+ " bytes, MD5 sum: " + md5SumString.toString() + "</b>" |
||||||
|
+ "<p><a href=\"/\">Next file</a>\r\n\r\n"; |
||||||
|
out.write(answer.getBytes()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static String printByte(byte b) |
||||||
|
{ |
||||||
|
int bi = ((int)b) & 0xFF; |
||||||
|
if(bi < 16) |
||||||
|
return "0" + Integer.toHexString(bi); |
||||||
|
else |
||||||
|
return Integer.toHexString(bi); |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
if(args.length < 1) |
||||||
|
{ |
||||||
|
System.out.println("Usage: UploadServer <port>"); |
||||||
|
int port = 8081; |
||||||
|
UploadServer server = new UploadServer(port); |
||||||
|
server.start(); |
||||||
|
return; |
||||||
|
} |
||||||
|
UploadServer server = new UploadServer(Integer.parseInt(args[0])); |
||||||
|
server.start(); |
||||||
|
} |
||||||
|
catch(Exception e) |
||||||
|
{ |
||||||
|
System.err.println("Error in main"); |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue