package com.upload.http;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class MultipartRequest implements HttpServletRequest{
private static final String TEMP_PATH = "c:/temp/";
private long userId_;
private HttpServletRequest req_;
private File dir_ = new File(TEMP_PATH);
private HashMap<String, ArrayList<String>> parameters_ = new HashMap<String, ArrayList<String>>();
private HashMap<String, UploadedFile> files_ = new HashMap<String, UploadedFile>();
private HashMap<File, String> exactFileNameTable_ = new HashMap<File, String>();
public static boolean isMultipart(HttpServletRequest req) {
String type = null;
String type1 = req.getHeader("Content-Type");
String type2 = req.getContentType();
if (type1 == null && type2 != null) {
type = type2;
}
else if (type2 == null && type1 != null) {
type = type1;
}
else if (type1 != null && type2 != null) {
type = (type1.length() > type2.length() ? type1 : type2);
}
if (type == null ||!type.toLowerCase().startsWith("multipart/form-data")) {
return false ;
}else{
return true ;
}
}
public MultipartRequest(HttpServletRequest req, long userId) throws IOException {
if (req == null)
throw new IllegalArgumentException("request cannot be null");
if (!dir_.isDirectory())
dir_.mkdir();
if (!dir_.canWrite())
throw new IllegalArgumentException("服务器上 " + TEMP_PATH + " 这个目录没有写的权限");
req_ = req;
userId_ = userId;
readRequest();
}
protected void readRequest()
throws IOException {
int length = req_.getContentLength();
String type = null;
String type1 = req_.getHeader("Content-Type");
String type2 = req_.getContentType();
if (type1 == null && type2 != null) {
type = type2;
}
else if (type2 == null && type1 != null) {
type = type1;
}
else if (type1 != null && type2 != null) {
type = (type1.length() > type2.length() ? type1 : type2);
}
if (type == null ||
!type.toLowerCase().startsWith("multipart/form-data")) {
throw new IOException("Posted content type isn't multipart/form-data");
}
String boundary = extractBoundary(type);
if (boundary == null) {
throw new IOException("Separation boundary was not specified");
}
MultipartInputStreamHandler in =
new MultipartInputStreamHandler(req_.getInputStream(), length);
String line = in.readLine();
if (line == null) {
throw new IOException("Corrupt form data: premature ending");
}
if (!line.startsWith(boundary)) {
throw new IOException("Corrupt form data: no leading boundary");
}
boolean done = false;
while (!done) {
done = readNextPart(in, boundary);
}
}
private String extractBoundary(String line) {
int index = line.lastIndexOf("boundary=");
if (index == -1) {
return null;
}
String boundary = line.substring(index + 9);
boundary = "--" + boundary;
return boundary;
}
protected boolean readNextPart(MultipartInputStreamHandler in,
String boundary)
throws IOException {
String line = in.readLine();
if (line == null) {
return true;
}
else if (line.length() == 0) {
return true;
}
String[] dispInfo = extractDispositionInfo(line);
String strHttpParameterName = dispInfo[1];
String strExactFileName = dispInfo[2];
line = in.readLine();
if (line == null) {
return true;
}
String contentType = extractContentType(line);
if (contentType != null) {
line = in.readLine();
if (line == null || line.length() > 0) {
throw new IOException("Malformed line after content type: " + line);
}
}
else {
contentType = "application/octet-stream";
}
if (strExactFileName == null) {
String value = readParameter(in, boundary);
ArrayList<String> existingValues = (ArrayList<String>)parameters_.get(strHttpParameterName);
if (existingValues == null) {
existingValues = new ArrayList<String>();
parameters_.put(strHttpParameterName, existingValues);
}
existingValues.add(value);
}
else {
File temporaryFile;
if (!strExactFileName.equals("unknown")) {
String tempfilename = userId_ + strHttpParameterName
+ System.currentTimeMillis() + ".bin";
temporaryFile = new File(dir_, tempfilename);
} else {
temporaryFile = null;
}
readAndSaveFile(in, boundary, temporaryFile, contentType);
if (!strExactFileName.equals("unknown")) {
files_.put(strHttpParameterName,
new UploadedFile(temporaryFile, contentType));
}
exactFileNameTable_.put(temporaryFile, strExactFileName);
}
return false;
}
protected void readAndSaveFile(MultipartInputStreamHandler in,
String boundary,
File temporaryFile,
String contentType) throws IOException {
OutputStream out = null;
if (temporaryFile == null) {
out = new ByteArrayOutputStream();
} else {
if (contentType.equals("application/x-macbinary")){
out = new MacBinaryDecoderOutputStream(
new BufferedOutputStream(
new FileOutputStream(temporaryFile), 8 * 1024));
}
else {
out = new BufferedOutputStream(
new FileOutputStream(temporaryFile), 8 * 1024);
}
}
byte[] bbuf = new byte[100 * 1024];
int result;
String line;
boolean rnflag = false;
while ((result = in.readLine(bbuf, 0, bbuf.length)) != -1) {
if (result > 2 && bbuf[0] == '-' && bbuf[1] == '-') {
line = new String(bbuf, 0, result, "GB2312");
if (line.startsWith(boundary)) break;
}
if (rnflag) {
out.write('\r'); out.write('\n');
rnflag = false;
}
if (result >= 2 &&
bbuf[result - 2] == '\r' &&
bbuf[result - 1] == '\n') {
out.write(bbuf, 0, result - 2);
rnflag = true;
}
else {
out.write(bbuf, 0, result);
}
}
out.close();
}
private String[] extractDispositionInfo(String line) throws IOException {
String[] retval = new String[3];
String origline = line;
line = origline.toLowerCase();
int start = line.indexOf("content-disposition: ");
int end = line.indexOf(";");
if (start == -1 || end == -1) {
throw new IOException("Content disposition corrupt: " + origline);
}
String disposition = line.substring(start + 21, end);
if (!disposition.equals("form-data")) {
throw new IOException("Invalid content disposition: " + disposition);
}
start = line.indexOf("name=\"", end);
end = line.indexOf("\"", start + 7);
if (start == -1 || end == -1) {
throw new IOException("Content disposition corrupt: " + origline);
}
String name = origline.substring(start + 6, end);
String filename = null;
start = line.indexOf("filename=\"", end + 2);
end = line.indexOf("\"", start + 10);
if (start != -1 && end != -1) {
filename = origline.substring(start + 10, end);
int slash =
Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
if (slash > -1) {
filename = filename.substring(slash + 1);
}
if (filename.equals("")) filename = "unknown";
}
retval[0] = disposition;
retval[1] = name;
retval[2] = filename;
return retval;
}
private String extractContentType(String line) throws IOException {
String contentType = null;
String origline = line;
line = origline.toLowerCase();
if (line.startsWith("content-type")) {
int start = line.indexOf(" ");
if (start == -1) {
throw new IOException("Content type corrupt: " + origline);
}
contentType = line.substring(start + 1);
}
else if (line.length() != 0) {
throw new IOException("Malformed line after disposition: " + origline);
}
return contentType;
}
protected String readParameter(MultipartInputStreamHandler in,
String boundary) throws IOException {
StringBuffer sbuf = new StringBuffer();
String line;
while ((line = in.readLine()) != null) {
if (line.startsWith(boundary)) break;
sbuf.append(line + "\r\n");
}
if (sbuf.length() == 0) {
return "";
}
sbuf.setLength(sbuf.length() - 2);
return sbuf.toString();
}
public File getFile(String strParameterName) {
UploadedFile file = (UploadedFile)files_.get(strParameterName);
if (file != null) {
return file.getFile();
} else {
return null;
}
}
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class MultipartRequest implements HttpServletRequest{
private static final String TEMP_PATH = "c:/temp/";
private long userId_;
private HttpServletRequest req_;
private File dir_ = new File(TEMP_PATH);
private HashMap<String, ArrayList<String>> parameters_ = new HashMap<String, ArrayList<String>>();
private HashMap<String, UploadedFile> files_ = new HashMap<String, UploadedFile>();
private HashMap<File, String> exactFileNameTable_ = new HashMap<File, String>();
public static boolean isMultipart(HttpServletRequest req) {
String type = null;
String type1 = req.getHeader("Content-Type");
String type2 = req.getContentType();
if (type1 == null && type2 != null) {
type = type2;
}
else if (type2 == null && type1 != null) {
type = type1;
}
else if (type1 != null && type2 != null) {
type = (type1.length() > type2.length() ? type1 : type2);
}
if (type == null ||!type.toLowerCase().startsWith("multipart/form-data")) {
return false ;
}else{
return true ;
}
}
public MultipartRequest(HttpServletRequest req, long userId) throws IOException {
if (req == null)
throw new IllegalArgumentException("request cannot be null");
if (!dir_.isDirectory())
dir_.mkdir();
if (!dir_.canWrite())
throw new IllegalArgumentException("服务器上 " + TEMP_PATH + " 这个目录没有写的权限");
req_ = req;
userId_ = userId;
readRequest();
}
protected void readRequest()
throws IOException {
int length = req_.getContentLength();
String type = null;
String type1 = req_.getHeader("Content-Type");
String type2 = req_.getContentType();
if (type1 == null && type2 != null) {
type = type2;
}
else if (type2 == null && type1 != null) {
type = type1;
}
else if (type1 != null && type2 != null) {
type = (type1.length() > type2.length() ? type1 : type2);
}
if (type == null ||
!type.toLowerCase().startsWith("multipart/form-data")) {
throw new IOException("Posted content type isn't multipart/form-data");
}
String boundary = extractBoundary(type);
if (boundary == null) {
throw new IOException("Separation boundary was not specified");
}
MultipartInputStreamHandler in =
new MultipartInputStreamHandler(req_.getInputStream(), length);
String line = in.readLine();
if (line == null) {
throw new IOException("Corrupt form data: premature ending");
}
if (!line.startsWith(boundary)) {
throw new IOException("Corrupt form data: no leading boundary");
}
boolean done = false;
while (!done) {
done = readNextPart(in, boundary);
}
}
private String extractBoundary(String line) {
int index = line.lastIndexOf("boundary=");
if (index == -1) {
return null;
}
String boundary = line.substring(index + 9);
boundary = "--" + boundary;
return boundary;
}
protected boolean readNextPart(MultipartInputStreamHandler in,
String boundary)
throws IOException {
String line = in.readLine();
if (line == null) {
return true;
}
else if (line.length() == 0) {
return true;
}
String[] dispInfo = extractDispositionInfo(line);
String strHttpParameterName = dispInfo[1];
String strExactFileName = dispInfo[2];
line = in.readLine();
if (line == null) {
return true;
}
String contentType = extractContentType(line);
if (contentType != null) {
line = in.readLine();
if (line == null || line.length() > 0) {
throw new IOException("Malformed line after content type: " + line);
}
}
else {
contentType = "application/octet-stream";
}
if (strExactFileName == null) {
String value = readParameter(in, boundary);
ArrayList<String> existingValues = (ArrayList<String>)parameters_.get(strHttpParameterName);
if (existingValues == null) {
existingValues = new ArrayList<String>();
parameters_.put(strHttpParameterName, existingValues);
}
existingValues.add(value);
}
else {
File temporaryFile;
if (!strExactFileName.equals("unknown")) {
String tempfilename = userId_ + strHttpParameterName
+ System.currentTimeMillis() + ".bin";
temporaryFile = new File(dir_, tempfilename);
} else {
temporaryFile = null;
}
readAndSaveFile(in, boundary, temporaryFile, contentType);
if (!strExactFileName.equals("unknown")) {
files_.put(strHttpParameterName,
new UploadedFile(temporaryFile, contentType));
}
exactFileNameTable_.put(temporaryFile, strExactFileName);
}
return false;
}
protected void readAndSaveFile(MultipartInputStreamHandler in,
String boundary,
File temporaryFile,
String contentType) throws IOException {
OutputStream out = null;
if (temporaryFile == null) {
out = new ByteArrayOutputStream();
} else {
if (contentType.equals("application/x-macbinary")){
out = new MacBinaryDecoderOutputStream(
new BufferedOutputStream(
new FileOutputStream(temporaryFile), 8 * 1024));
}
else {
out = new BufferedOutputStream(
new FileOutputStream(temporaryFile), 8 * 1024);
}
}
byte[] bbuf = new byte[100 * 1024];
int result;
String line;
boolean rnflag = false;
while ((result = in.readLine(bbuf, 0, bbuf.length)) != -1) {
if (result > 2 && bbuf[0] == '-' && bbuf[1] == '-') {
line = new String(bbuf, 0, result, "GB2312");
if (line.startsWith(boundary)) break;
}
if (rnflag) {
out.write('\r'); out.write('\n');
rnflag = false;
}
if (result >= 2 &&
bbuf[result - 2] == '\r' &&
bbuf[result - 1] == '\n') {
out.write(bbuf, 0, result - 2);
rnflag = true;
}
else {
out.write(bbuf, 0, result);
}
}
out.close();
}
private String[] extractDispositionInfo(String line) throws IOException {
String[] retval = new String[3];
String origline = line;
line = origline.toLowerCase();
int start = line.indexOf("content-disposition: ");
int end = line.indexOf(";");
if (start == -1 || end == -1) {
throw new IOException("Content disposition corrupt: " + origline);
}
String disposition = line.substring(start + 21, end);
if (!disposition.equals("form-data")) {
throw new IOException("Invalid content disposition: " + disposition);
}
start = line.indexOf("name=\"", end);
end = line.indexOf("\"", start + 7);
if (start == -1 || end == -1) {
throw new IOException("Content disposition corrupt: " + origline);
}
String name = origline.substring(start + 6, end);
String filename = null;
start = line.indexOf("filename=\"", end + 2);
end = line.indexOf("\"", start + 10);
if (start != -1 && end != -1) {
filename = origline.substring(start + 10, end);
int slash =
Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
if (slash > -1) {
filename = filename.substring(slash + 1);
}
if (filename.equals("")) filename = "unknown";
}
retval[0] = disposition;
retval[1] = name;
retval[2] = filename;
return retval;
}
private String extractContentType(String line) throws IOException {
String contentType = null;
String origline = line;
line = origline.toLowerCase();
if (line.startsWith("content-type")) {
int start = line.indexOf(" ");
if (start == -1) {
throw new IOException("Content type corrupt: " + origline);
}
contentType = line.substring(start + 1);
}
else if (line.length() != 0) {
throw new IOException("Malformed line after disposition: " + origline);
}
return contentType;
}
protected String readParameter(MultipartInputStreamHandler in,
String boundary) throws IOException {
StringBuffer sbuf = new StringBuffer();
String line;
while ((line = in.readLine()) != null) {
if (line.startsWith(boundary)) break;
sbuf.append(line + "\r\n");
}
if (sbuf.length() == 0) {
return "";
}
sbuf.setLength(sbuf.length() - 2);
return sbuf.toString();
}
public File getFile(String strParameterName) {
UploadedFile file = (UploadedFile)files_.get(strParameterName);
if (file != null) {
return file.getFile();
} else {
return null;
}
}