You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
7.7 KiB

/*
* Copyright (C), 2018-2022
* Project: starter
* FileName: BodyRequestWrapper
* Author: xx
* Date: 2022/5/27 11:39
*/
package com.fr.plugin.gb.filter;
import com.fanruan.api.log.LogKit;
import com.fr.base.ConfigManager;
import com.fr.base.FRContext;
import com.fr.data.NetworkHelper;
import com.fr.general.IOUtils;
import com.fr.general.http.HttpClient;
import com.fr.general.web.ParameterConsts;
import com.fr.plugin.gb.utils.InteKeyHandler;
import com.fr.stable.StringUtils;
import com.fr.web.utils.WebUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
public class BodyRequestWrapper extends HttpServletRequestWrapper {
private static final int SPEC_HEADER_CHAR = 13;
private byte[] body;
private File file;
private HttpServletRequest m_request;
protected byte m_binArray[];
private int m_totalBytes;
private int m_currentIndex;
private int m_startData;
private int m_endData;
private String fileName;
private String m_boundary = StringUtils.EMPTY;
public BodyRequestWrapper(HttpServletRequest request) {
super(request);
m_request = request;
try {
init();
if (m_startData >= m_endData) {
body = m_binArray;
} else {
file = createNewFile();
byte[] bytes = IOUtils.inputStream2Bytes(new FileInputStream(file));
int fileLen = bytes.length;
int len = m_startData + (m_binArray.length - m_endData - 1) + bytes.length;
body = new byte[len];
for (int i = 0, j = m_endData + 1; i < len; i++) {
if (i < m_startData) {
body[i] = m_binArray[i];
} else if (i >= m_startData && (i - m_startData <= fileLen - 1)) {
body[i] = bytes[i - m_startData];
} else {
body[i] = m_binArray[j];
j++;
}
}
}
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
}
}
@Override
public ServletInputStream getInputStream() throws IOException {
try {
final ByteArrayInputStream localByteArrayInputStream = new ByteArrayInputStream(this.body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return localByteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
} catch (Exception e) {
e.printStackTrace();
}
return super.getInputStream();
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
public File createNewFile() {
byte[] var1 = new byte[this.m_endData - this.m_startData + 1];
System.arraycopy(this.m_binArray, this.m_startData, var1, 0, var1.length);
return InteKeyHandler.getInstance().decrypt(new ByteArrayInputStream(var1));
}
/**
* 初始化方法,
* 里面的方法都是从smartUpload里面copy出来的
* 主要是为了找出输入流中 真正的关于文件的部分,吧这个部分替换掉
*/
public void init() {
int i = 0;
boolean flag1 = false;
long length = 0;
m_totalBytes = m_request.getContentLength();
if (m_totalBytes < 0) {
return;
}
if (WebUtils.getHTTPRequestParameter(m_request, ParameterConsts.REDIRECT_FROM) != null) {
//从HttpClient里再捞一把, 因为有可能是集群转发作为正文传过来的.
InputStream in = HttpClient.getInputStream(m_request);
m_binArray = IOUtils.inputStream2Bytes(in);
} else {
InputStream in = NetworkHelper.getRequestInputStream(m_request);
m_binArray = IOUtils.inputStream2Bytes(in);
}
for (; !flag1 && m_currentIndex < m_totalBytes; m_currentIndex++) {
if (m_binArray[m_currentIndex] == SPEC_HEADER_CHAR) {
flag1 = true;
} else {
m_boundary = m_boundary + (char) m_binArray[m_currentIndex];
}
}
if (m_currentIndex == 1) {
return;
}
m_currentIndex++;
String header = getDataHeader();
String pathName = getDataFieldValue(header, "filename");
fileName = getFileName(pathName);
m_currentIndex = m_currentIndex + 2;
getDataSection();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
// if (file != null) {
// file.delete();
// }
}
private String getDataHeader() {
// boolean flag = false;
int i = m_currentIndex;
int j = 0;
for (boolean flag1 = false; !flag1; ) {
if (m_binArray[m_currentIndex] == SPEC_HEADER_CHAR && m_binArray[m_currentIndex + 2] == SPEC_HEADER_CHAR) {
flag1 = true;
j = m_currentIndex - 1;
m_currentIndex = m_currentIndex + 2;
} else {
m_currentIndex++;
}
}
String header = StringUtils.EMPTY;
try {
// 字符编码要与服务器端设置的保持一致
header = new String(m_binArray, i, (j - i) + 1, ConfigManager.getProviderInstance().getServerCharset());
} catch (UnsupportedEncodingException e) {
FRContext.getLogger().error(e.getMessage());
}
return header;
}
private void getDataSection() {
// boolean flag = false;
// String s = "";
// String s = new String();
int i = m_currentIndex;
int j = 0;
int k = m_boundary.length();
m_startData = m_currentIndex;
m_endData = 0;
while (i < m_totalBytes) {
if (m_binArray[i] == (byte) m_boundary.charAt(j)) {
if (j == k - 1) {
m_endData = ((i - k) + 1) - 3;
break;
}
i++;
j++;
} else {
i++;
j = 0;
}
}
m_currentIndex = m_endData + k + 3;
}
private String getDataFieldValue(String s, String s1) {
String s2 = ""; // = new String();
String s3 = ""; // = new String();
int i = 0;
// boolean flag = false;
// boolean flag1 = false;
// boolean flag2 = false;
s2 = s1 + "=" + '"';
i = s.indexOf(s2);
if (i > 0) {
int j = i + s2.length();
int k = j;
s2 = "\"";
int l = s.indexOf(s2, j);
if (k > 0 && l > 0) {
s3 = s.substring(k, l);
}
}
return s3;
}
private String getFileName(String fileName) {
int i = 0;
i = fileName.lastIndexOf('/');
if (i != -1) {
return fileName.substring(i + 1, fileName.length());
}
i = fileName.lastIndexOf('\\');
if (i != -1) {
return fileName.substring(i + 1, fileName.length());
} else {
return fileName;
}
}
}