mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-13 11:12:22 -05:00
Dav: patch filter on invalid Exchange Webdav response
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1262 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
3418daed65
commit
722be0aeb1
@ -44,6 +44,8 @@ import org.apache.jackrabbit.webdav.property.DavProperty;
|
|||||||
import org.apache.jackrabbit.webdav.property.DavPropertyName;
|
import org.apache.jackrabbit.webdav.property.DavPropertyName;
|
||||||
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
|
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
|
||||||
import org.apache.jackrabbit.webdav.property.DavPropertySet;
|
import org.apache.jackrabbit.webdav.property.DavPropertySet;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
import javax.mail.MessagingException;
|
import javax.mail.MessagingException;
|
||||||
@ -616,12 +618,7 @@ public class DavExchangeSession extends ExchangeSession {
|
|||||||
*/
|
*/
|
||||||
public ItemResult createOrUpdate() throws IOException {
|
public ItemResult createOrUpdate() throws IOException {
|
||||||
int status = 0;
|
int status = 0;
|
||||||
ExchangePropPatchMethod propPatchMethod = new ExchangePropPatchMethod(URIUtil.encodePath(getHref()), buildProperties()) {
|
ExchangePropPatchMethod propPatchMethod = new ExchangePropPatchMethod(URIUtil.encodePath(getHref()), buildProperties());
|
||||||
@Override
|
|
||||||
protected void processResponseBody(HttpState httpState, HttpConnection httpConnection) {
|
|
||||||
// ignore response body, sometimes invalid with exchange mapi properties
|
|
||||||
}
|
|
||||||
};
|
|
||||||
propPatchMethod.setRequestHeader("Translate", "f");
|
propPatchMethod.setRequestHeader("Translate", "f");
|
||||||
if (etag != null) {
|
if (etag != null) {
|
||||||
propPatchMethod.setRequestHeader("If-Match", etag);
|
propPatchMethod.setRequestHeader("If-Match", etag);
|
||||||
@ -632,6 +629,7 @@ public class DavExchangeSession extends ExchangeSession {
|
|||||||
try {
|
try {
|
||||||
status = httpClient.executeMethod(propPatchMethod);
|
status = httpClient.executeMethod(propPatchMethod);
|
||||||
if (status == HttpStatus.SC_MULTI_STATUS) {
|
if (status == HttpStatus.SC_MULTI_STATUS) {
|
||||||
|
List<MultiStatusResponse> responses = propPatchMethod.getResponses();
|
||||||
//noinspection VariableNotUsedInsideIf
|
//noinspection VariableNotUsedInsideIf
|
||||||
if (etag == null) {
|
if (etag == null) {
|
||||||
status = HttpStatus.SC_CREATED;
|
status = HttpStatus.SC_CREATED;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
package davmail.exchange.dav;
|
package davmail.exchange.dav;
|
||||||
|
|
||||||
import org.apache.commons.httpclient.*;
|
import org.apache.commons.httpclient.*;
|
||||||
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
|
import org.apache.commons.httpclient.methods.PostMethod;
|
||||||
import org.apache.commons.httpclient.methods.RequestEntity;
|
import org.apache.commons.httpclient.methods.RequestEntity;
|
||||||
import org.apache.jackrabbit.webdav.MultiStatusResponse;
|
import org.apache.jackrabbit.webdav.MultiStatusResponse;
|
||||||
import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
|
import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
|
||||||
@ -37,7 +37,7 @@ import java.util.*;
|
|||||||
* Custom Exchange PROPPATCH method.
|
* Custom Exchange PROPPATCH method.
|
||||||
* Supports extended property update with type.
|
* Supports extended property update with type.
|
||||||
*/
|
*/
|
||||||
public class ExchangePropPatchMethod extends EntityEnclosingMethod {
|
public class ExchangePropPatchMethod extends PostMethod {
|
||||||
protected static final Logger logger = Logger.getLogger(ExchangePropPatchMethod.class);
|
protected static final Logger logger = Logger.getLogger(ExchangePropPatchMethod.class);
|
||||||
|
|
||||||
static final String TYPE_NAMESPACE = "urn:schemas-microsoft-com:datatypes";
|
static final String TYPE_NAMESPACE = "urn:schemas-microsoft-com:datatypes";
|
||||||
@ -196,9 +196,23 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod {
|
|||||||
try {
|
try {
|
||||||
XMLInputFactory xmlInputFactory = getXmlInputFactory();
|
XMLInputFactory xmlInputFactory = getXmlInputFactory();
|
||||||
reader = xmlInputFactory.createXMLStreamReader(new FilterInputStream(getResponseBodyAsStream()) {
|
reader = xmlInputFactory.createXMLStreamReader(new FilterInputStream(getResponseBodyAsStream()) {
|
||||||
|
final byte[] lastbytes = new byte[3];
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read() throws IOException {
|
public int read(byte b[], int off, int len) throws IOException {
|
||||||
return in.read();
|
int count = in.read(b, off, len);
|
||||||
|
// patch invalid element name
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
byte currentByte = b[off + i];
|
||||||
|
if ((lastbytes[0] == '<') && (currentByte >= '0' && currentByte <= '9')) {
|
||||||
|
// move invalid first tag char to valid range
|
||||||
|
b[off + i] = (byte) (currentByte + 49);
|
||||||
|
}
|
||||||
|
lastbytes[0] = lastbytes[1];
|
||||||
|
lastbytes[1] = lastbytes[2];
|
||||||
|
lastbytes[2] = currentByte;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -218,9 +232,8 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void handleResponse(XMLStreamReader reader) throws XMLStreamException {
|
protected void handleResponse(XMLStreamReader reader) throws XMLStreamException {
|
||||||
MultiStatusResponse multiStatusResponse = null;
|
|
||||||
int status = 0;
|
|
||||||
String href = null;
|
String href = null;
|
||||||
|
String responseStatus = "";
|
||||||
while (reader.hasNext() && !isEndTag(reader, "response")) {
|
while (reader.hasNext() && !isEndTag(reader, "response")) {
|
||||||
int event = reader.next();
|
int event = reader.next();
|
||||||
if (event == XMLStreamConstants.START_ELEMENT) {
|
if (event == XMLStreamConstants.START_ELEMENT) {
|
||||||
@ -228,15 +241,11 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod {
|
|||||||
if ("href".equals(tagLocalName)) {
|
if ("href".equals(tagLocalName)) {
|
||||||
href = reader.getElementText();
|
href = reader.getElementText();
|
||||||
} else if ("status".equals(tagLocalName)) {
|
} else if ("status".equals(tagLocalName)) {
|
||||||
String responseStatus = reader.getElementText();
|
responseStatus = reader.getElementText();
|
||||||
if ("HTTP/1.1 200 OK".equals(responseStatus)) {
|
|
||||||
status = HttpStatus.SC_OK;
|
|
||||||
} else if ("HTTP/1.1 201 Created".equals(responseStatus)) {
|
|
||||||
status = HttpStatus.SC_CREATED;
|
|
||||||
}
|
|
||||||
multiStatusResponse = new MultiStatusResponse(href, status);
|
|
||||||
} else if ("propstat".equals(tagLocalName)) {
|
} else if ("propstat".equals(tagLocalName)) {
|
||||||
|
MultiStatusResponse multiStatusResponse = new MultiStatusResponse(href, responseStatus);
|
||||||
handlePropstat(reader, multiStatusResponse);
|
handlePropstat(reader, multiStatusResponse);
|
||||||
|
responses.add(multiStatusResponse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,6 +261,8 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod {
|
|||||||
if ("status".equals(tagLocalName)) {
|
if ("status".equals(tagLocalName)) {
|
||||||
if ("HTTP/1.1 200 OK".equals(reader.getElementText())) {
|
if ("HTTP/1.1 200 OK".equals(reader.getElementText())) {
|
||||||
propstatStatus = HttpStatus.SC_OK;
|
propstatStatus = HttpStatus.SC_OK;
|
||||||
|
} else {
|
||||||
|
propstatStatus = 0;
|
||||||
}
|
}
|
||||||
} else if ("prop".equals(tagLocalName) && propstatStatus == HttpStatus.SC_OK) {
|
} else if ("prop".equals(tagLocalName) && propstatStatus == HttpStatus.SC_OK) {
|
||||||
handleProperty(reader, multiStatusResponse);
|
handleProperty(reader, multiStatusResponse);
|
||||||
@ -263,18 +274,13 @@ public class ExchangePropPatchMethod extends EntityEnclosingMethod {
|
|||||||
|
|
||||||
|
|
||||||
protected void handleProperty(XMLStreamReader reader, MultiStatusResponse multiStatusResponse) throws XMLStreamException {
|
protected void handleProperty(XMLStreamReader reader, MultiStatusResponse multiStatusResponse) throws XMLStreamException {
|
||||||
while (reader.hasNext() && !isEndTag(reader, "prop")) {
|
while (reader.hasNext() && !isEndTag(reader, "prop")){
|
||||||
try {
|
int event = reader.nextTag();
|
||||||
int event = reader.next();
|
|
||||||
if (event == XMLStreamConstants.START_ELEMENT) {
|
if (event == XMLStreamConstants.START_ELEMENT) {
|
||||||
String tagLocalName = reader.getLocalName();
|
String tagLocalName = reader.getLocalName();
|
||||||
Namespace namespace = Namespace.getNamespace(reader.getNamespaceURI());
|
Namespace namespace = Namespace.getNamespace(reader.getNamespaceURI());
|
||||||
multiStatusResponse.add(new DefaultDavProperty(tagLocalName, reader.getElementText(), namespace));
|
multiStatusResponse.add(new DefaultDavProperty(tagLocalName, reader.getElementText(), namespace));
|
||||||
}
|
}
|
||||||
} catch (XMLStreamException e) {
|
|
||||||
// ignore, exchange invalid response
|
|
||||||
logger.debug("Ignore invalid response tag name");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,7 +490,7 @@ public class Field {
|
|||||||
// multivalued field, split values separated by \n
|
// multivalued field, split values separated by \n
|
||||||
String[] values = value.split("\n");
|
String[] values = value.split("\n");
|
||||||
for (final String singleValue : values) {
|
for (final String singleValue : values) {
|
||||||
buffer.append("<v xmlns=\"xml:\">");
|
buffer.append("<v>");
|
||||||
buffer.append(StringUtil.xmlEncode(singleValue));
|
buffer.append(StringUtil.xmlEncode(singleValue));
|
||||||
buffer.append("</v>");
|
buffer.append("</v>");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user