191 lines
6.1 KiB
Java
191 lines
6.1 KiB
Java
package gov.nist.javax.sip.message;
|
|
|
|
import gov.nist.javax.sip.header.HeaderFactoryExt;
|
|
import gov.nist.javax.sip.header.HeaderFactoryImpl;
|
|
import gov.nist.javax.sip.parser.StringMsgParser;
|
|
|
|
import java.text.ParseException;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
|
|
import javax.sip.header.ContentDispositionHeader;
|
|
import javax.sip.header.ContentTypeHeader;
|
|
import javax.sip.header.Header;
|
|
import javax.sip.header.HeaderFactory;
|
|
import javax.sip.message.Message;
|
|
|
|
|
|
|
|
/**
|
|
* Content list for multipart mime content type.
|
|
*
|
|
* @author M. Ranganathan
|
|
*
|
|
*/
|
|
public class MultipartMimeContentImpl implements MultipartMimeContent {
|
|
private List<Content> contentList = new LinkedList<Content>();
|
|
|
|
private ContentTypeHeader multipartMimeContentTypeHeader;
|
|
|
|
private String boundary;
|
|
|
|
public static String BOUNDARY = "boundary";
|
|
|
|
/**
|
|
* Creates a default content list.
|
|
*/
|
|
public MultipartMimeContentImpl(ContentTypeHeader contentTypeHeader) {
|
|
this.multipartMimeContentTypeHeader = contentTypeHeader;
|
|
this.boundary = contentTypeHeader.getParameter(BOUNDARY);
|
|
|
|
}
|
|
|
|
/*
|
|
* (non-Javadoc)
|
|
*
|
|
* @see gov.nist.javax.sip.message.MultipartMimeContentExt#add(gov.nist.javax.sip.message.Content)
|
|
*/
|
|
public boolean add(Content content) {
|
|
return contentList.add((ContentImpl) content);
|
|
}
|
|
|
|
/*
|
|
* (non-Javadoc)
|
|
*
|
|
* @see gov.nist.javax.sip.message.MultipartMimeContentExt#getContentTypeHeader()
|
|
*/
|
|
public ContentTypeHeader getContentTypeHeader() {
|
|
return multipartMimeContentTypeHeader;
|
|
}
|
|
|
|
/*
|
|
* (non-Javadoc)
|
|
*
|
|
* @see gov.nist.javax.sip.message.MultipartMimeContentExt#toString()
|
|
*/
|
|
@Override
|
|
public String toString() {
|
|
StringBuffer stringBuffer = new StringBuffer();
|
|
|
|
for (Content content : this.contentList) {
|
|
stringBuffer.append(content.toString());
|
|
}
|
|
return stringBuffer.toString();
|
|
|
|
}
|
|
|
|
/**
|
|
* unpack a multipart mime packet and return a list of content packets.
|
|
*
|
|
* @return -- an iterator of Content blocks.
|
|
*
|
|
*/
|
|
public void createContentList(String body) throws ParseException {
|
|
try {
|
|
HeaderFactoryExt headerFactory = new HeaderFactoryImpl();
|
|
String delimiter = this.getContentTypeHeader().getParameter(BOUNDARY);
|
|
|
|
if (delimiter == null) {
|
|
this.contentList = new LinkedList<Content>();
|
|
ContentImpl content = new ContentImpl(body, delimiter);
|
|
content.setContentTypeHeader(this.getContentTypeHeader());
|
|
this.contentList.add(content);
|
|
return;
|
|
}
|
|
|
|
String[] fragments = body.split("--" + delimiter + "\r\n");
|
|
|
|
|
|
for (String nextPart : fragments) {
|
|
// NOTE - we are not hanlding line folding for the sip header here.
|
|
|
|
if (nextPart == null) {
|
|
return;
|
|
}
|
|
StringBuffer strbuf = new StringBuffer(nextPart);
|
|
while (strbuf.length() > 0
|
|
&& (strbuf.charAt(0) == '\r' || strbuf.charAt(0) == '\n'))
|
|
strbuf.deleteCharAt(0);
|
|
|
|
if (strbuf.length() == 0)
|
|
continue;
|
|
nextPart = strbuf.toString();
|
|
int position = nextPart.indexOf("\r\n\r\n");
|
|
int off = 4;
|
|
if (position == -1) {
|
|
position = nextPart.indexOf("\n");
|
|
off = 2;
|
|
}
|
|
if (position == -1)
|
|
throw new ParseException("no content type header found in " + nextPart, 0);
|
|
String rest = nextPart.substring(position + off);
|
|
|
|
if (rest == null)
|
|
throw new ParseException("No content [" + nextPart + "]", 0);
|
|
// logger.debug("rest = [[" + rest + "]]");
|
|
String headers = nextPart.substring(0, position);
|
|
ContentImpl content = new ContentImpl(rest, boundary);
|
|
|
|
String[] headerArray = headers.split("\r\n");
|
|
for (String hdr : headerArray) {
|
|
Header header = headerFactory.createHeader(hdr);
|
|
if (header instanceof ContentTypeHeader) {
|
|
content.setContentTypeHeader((ContentTypeHeader) header);
|
|
} else if (header instanceof ContentDispositionHeader) {
|
|
content.setContentDispositionHeader((ContentDispositionHeader) header);
|
|
} else {
|
|
throw new ParseException("Unexpected header type " + header.getName(), 0);
|
|
}
|
|
contentList.add(content);
|
|
}
|
|
|
|
}
|
|
} catch (StringIndexOutOfBoundsException ex) {
|
|
throw new ParseException("Invalid Multipart mime format", 0);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* (non-Javadoc)
|
|
*
|
|
* @see gov.nist.javax.sip.message.MultipartMimeContentExt#getContentByType(java.lang.String,
|
|
* java.lang.String)
|
|
*/
|
|
public Content getContentByType(String contentType, String contentSubtype) {
|
|
Content retval = null;
|
|
if (contentList == null)
|
|
return null;
|
|
for (Content content : contentList) {
|
|
if (content.getContentTypeHeader().getContentType().equalsIgnoreCase(contentType)
|
|
&& content.getContentTypeHeader().getContentSubType().equalsIgnoreCase(
|
|
contentSubtype)) {
|
|
retval = content;
|
|
break;
|
|
}
|
|
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
/*
|
|
* (non-Javadoc)
|
|
*
|
|
* @see gov.nist.javax.sip.message.MultipartMimeContentExt#setContent(java.lang.String,
|
|
* java.lang.String, gov.nist.javax.sip.message.Content)
|
|
*/
|
|
public void addContent(Content content) {
|
|
this.add(content);
|
|
}
|
|
|
|
public Iterator<Content> getContents() {
|
|
return this.contentList.iterator();
|
|
}
|
|
|
|
|
|
public int getContentCount() {
|
|
return this.contentList.size();
|
|
}
|
|
|
|
}
|