快速解决commons-fileupload组件无法处理自定义head信息的bug
程序员文章站
2023-12-17 17:40:04
jakarta commons fileupload组件可以处理http请求及响应,很多时候被用来处理文件上传,但是近期发现,当我们自定义文件上传、自己组装mime信息、文...
jakarta commons fileupload组件可以处理http请求及响应,很多时候被用来处理文件上传,但是近期发现,当我们自定义文件上传、自己组装mime信息、文件上传时加入自定义head节点时,fileupload组件无法获得自定义的head节点,仔细分析了fileupload组件源代码后,发现核心方法在fileuploadbase文件的findnextitem方法中,问题在于fileupload组件解析完自定义的head节点后,却忘记传递到fileitemstreamimpl中了,稍作修订,即可修正该bug。
/**解析文件列表
* called for finding the nex item, if any.
* @return true, if an next item was found, otherwise false.
* @throws ioexception an i/o error occurred.
*/
private boolean findnextitem() throws ioexception {
if (eof) {
return false;
}
if (currentitem != null) {
currentitem.close();
currentitem = null;
}
for (;;) {
boolean nextpart;
if (skippreamble) {
nextpart = multi.skippreamble();
} else {
nextpart = multi.readboundary();
}
if (!nextpart) {
if (currentfieldname == null) {
// outer multipart terminated -> no more data
eof = true;
return false;
}
// inner multipart terminated -> return to parsing the outer
multi.setboundary(boundary);
currentfieldname = null;
continue;
}
fileitemheaders headers = getparsedheaders(multi.readheaders());
if (currentfieldname == null) {
// we're parsing the outer multipart
string fieldname = getfieldname(headers);
if (fieldname != null) {
string subcontenttype = headers.getheader(content_type);
if (subcontenttype != null
&& subcontenttype.tolowercase()
.startswith(multipart_mixed)) {
currentfieldname = fieldname;
// multiple files associated with this field name
byte[] subboundary = getboundary(subcontenttype);
multi.setboundary(subboundary);
skippreamble = true;
continue;
}
string filename = getfilename(headers);
currentitem = new fileitemstreamimpl(filename,
fieldname, headers.getheader(content_type),
filename == null, getcontentlength(headers));
notifier.noteitem();
itemvalid = true;
return true;
}
} else {
string filename = getfilename(headers);
if (filename != null) {
//这里代码要修订
//这是原来的代码,没有传入header
//currentitem = new fileitemstreamimpl(filename, currentfieldname,headers.getheader(content_type),false, getcontentlength(headers));
//这是新的代码,我们要传入header
currentitem = new fileitemstreamimpl(filename, currentfieldname,headers.getheader(content_type),false, getcontentlength(headers),headers);
notifier.noteitem();
itemvalid = true;
return true;
}
}
multi.discardbodydata();
}
}
/**原始代码,存在丢失fileitemheaders信息的bug
* creates a new instance.
* @param pname the items file name, or null.
* @param pfieldname the items field name.
* @param pcontenttype the items content type, or null.
* @param pformfield whether the item is a form field.
* @param pcontentlength the items content length, if known, or -1
* @throws ioexception creating the file item failed.
*/
fileitemstreamimpl(string pname, string pfieldname,
string pcontenttype, boolean pformfield,
long pcontentlength) throws ioexception {
name = pname;
fieldname = pfieldname;
contenttype = pcontenttype;
formfield = pformfield;
final iteminputstream itemstream = multi.newinputstream();
inputstream istream = itemstream;
if (filesizemax != -1) {
if (pcontentlength != -1
&& pcontentlength > filesizemax) {
fileuploadexception e =
new filesizelimitexceededexception(
"the field " + fieldname
+ " exceeds its maximum permitted "
+ " size of " + filesizemax
+ " characters.",
pcontentlength, filesizemax);
throw new fileuploadioexception(e);
}
istream = new limitedinputstream(istream, filesizemax) {
protected void raiseerror(long psizemax, long pcount)
throws ioexception {
itemstream.close(true);
fileuploadexception e =
new filesizelimitexceededexception(
"the field " + fieldname
+ " exceeds its maximum permitted "
+ " size of " + psizemax
+ " characters.",
pcount, psizemax);
throw new fileuploadioexception(e);
}
};
}
stream = istream;
}
/**创建fileitem,修订后的代码,解决丢失fileitemheaders信息的bug
* @param pname
* @param pfieldname
* @param pcontenttype
* @param pformfield
* @param pcontentlength
* @param headers
* @throws ioexception
*/
fileitemstreamimpl(string pname, string pfieldname,
string pcontenttype, boolean pformfield,
long pcontentlength,fileitemheaders headers) throws ioexception {
name = pname;
fieldname = pfieldname;
contenttype = pcontenttype;
formfield = pformfield;
if(headers!=null){
this.headers = headers;
}
final iteminputstream itemstream = multi.newinputstream();
inputstream istream = itemstream;
if (filesizemax != -1) {
if (pcontentlength != -1
&& pcontentlength > filesizemax) {
fileuploadexception e =
new filesizelimitexceededexception(
"the field " + fieldname
+ " exceeds its maximum permitted "
+ " size of " + filesizemax
+ " characters.",
pcontentlength, filesizemax);
throw new fileuploadioexception(e);
}
istream = new limitedinputstream(istream, filesizemax) {
protected void raiseerror(long psizemax, long pcount)
throws ioexception {
itemstream.close(true);
fileuploadexception e =
new filesizelimitexceededexception(
"the field " + fieldname
+ " exceeds its maximum permitted "
+ " size of " + psizemax
+ " characters.",
pcount, psizemax);
throw new fileuploadioexception(e);
}
};
}
stream = istream;
}
复制代码 代码如下:
/**解析文件列表
* called for finding the nex item, if any.
* @return true, if an next item was found, otherwise false.
* @throws ioexception an i/o error occurred.
*/
private boolean findnextitem() throws ioexception {
if (eof) {
return false;
}
if (currentitem != null) {
currentitem.close();
currentitem = null;
}
for (;;) {
boolean nextpart;
if (skippreamble) {
nextpart = multi.skippreamble();
} else {
nextpart = multi.readboundary();
}
if (!nextpart) {
if (currentfieldname == null) {
// outer multipart terminated -> no more data
eof = true;
return false;
}
// inner multipart terminated -> return to parsing the outer
multi.setboundary(boundary);
currentfieldname = null;
continue;
}
fileitemheaders headers = getparsedheaders(multi.readheaders());
if (currentfieldname == null) {
// we're parsing the outer multipart
string fieldname = getfieldname(headers);
if (fieldname != null) {
string subcontenttype = headers.getheader(content_type);
if (subcontenttype != null
&& subcontenttype.tolowercase()
.startswith(multipart_mixed)) {
currentfieldname = fieldname;
// multiple files associated with this field name
byte[] subboundary = getboundary(subcontenttype);
multi.setboundary(subboundary);
skippreamble = true;
continue;
}
string filename = getfilename(headers);
currentitem = new fileitemstreamimpl(filename,
fieldname, headers.getheader(content_type),
filename == null, getcontentlength(headers));
notifier.noteitem();
itemvalid = true;
return true;
}
} else {
string filename = getfilename(headers);
if (filename != null) {
//这里代码要修订
//这是原来的代码,没有传入header
//currentitem = new fileitemstreamimpl(filename, currentfieldname,headers.getheader(content_type),false, getcontentlength(headers));
//这是新的代码,我们要传入header
currentitem = new fileitemstreamimpl(filename, currentfieldname,headers.getheader(content_type),false, getcontentlength(headers),headers);
notifier.noteitem();
itemvalid = true;
return true;
}
}
multi.discardbodydata();
}
}
/**原始代码,存在丢失fileitemheaders信息的bug
* creates a new instance.
* @param pname the items file name, or null.
* @param pfieldname the items field name.
* @param pcontenttype the items content type, or null.
* @param pformfield whether the item is a form field.
* @param pcontentlength the items content length, if known, or -1
* @throws ioexception creating the file item failed.
*/
fileitemstreamimpl(string pname, string pfieldname,
string pcontenttype, boolean pformfield,
long pcontentlength) throws ioexception {
name = pname;
fieldname = pfieldname;
contenttype = pcontenttype;
formfield = pformfield;
final iteminputstream itemstream = multi.newinputstream();
inputstream istream = itemstream;
if (filesizemax != -1) {
if (pcontentlength != -1
&& pcontentlength > filesizemax) {
fileuploadexception e =
new filesizelimitexceededexception(
"the field " + fieldname
+ " exceeds its maximum permitted "
+ " size of " + filesizemax
+ " characters.",
pcontentlength, filesizemax);
throw new fileuploadioexception(e);
}
istream = new limitedinputstream(istream, filesizemax) {
protected void raiseerror(long psizemax, long pcount)
throws ioexception {
itemstream.close(true);
fileuploadexception e =
new filesizelimitexceededexception(
"the field " + fieldname
+ " exceeds its maximum permitted "
+ " size of " + psizemax
+ " characters.",
pcount, psizemax);
throw new fileuploadioexception(e);
}
};
}
stream = istream;
}
/**创建fileitem,修订后的代码,解决丢失fileitemheaders信息的bug
* @param pname
* @param pfieldname
* @param pcontenttype
* @param pformfield
* @param pcontentlength
* @param headers
* @throws ioexception
*/
fileitemstreamimpl(string pname, string pfieldname,
string pcontenttype, boolean pformfield,
long pcontentlength,fileitemheaders headers) throws ioexception {
name = pname;
fieldname = pfieldname;
contenttype = pcontenttype;
formfield = pformfield;
if(headers!=null){
this.headers = headers;
}
final iteminputstream itemstream = multi.newinputstream();
inputstream istream = itemstream;
if (filesizemax != -1) {
if (pcontentlength != -1
&& pcontentlength > filesizemax) {
fileuploadexception e =
new filesizelimitexceededexception(
"the field " + fieldname
+ " exceeds its maximum permitted "
+ " size of " + filesizemax
+ " characters.",
pcontentlength, filesizemax);
throw new fileuploadioexception(e);
}
istream = new limitedinputstream(istream, filesizemax) {
protected void raiseerror(long psizemax, long pcount)
throws ioexception {
itemstream.close(true);
fileuploadexception e =
new filesizelimitexceededexception(
"the field " + fieldname
+ " exceeds its maximum permitted "
+ " size of " + psizemax
+ " characters.",
pcount, psizemax);
throw new fileuploadioexception(e);
}
};
}
stream = istream;
}