Commit cc4f7c9c authored by tobias.friedrich's avatar tobias.friedrich

MWB-818: Submit ETag and Schedule-Tag header values as quoted string

parent 5901c5b6
Pipeline #134160 passed with stages
in 6 minutes and 32 seconds
......@@ -77,7 +77,7 @@ public class CalDAVGETAction extends GETAction {
protected void setResponseHeaders(WebdavResource resource, WebdavResponse response) throws WebdavProtocolException {
super.setResponseHeaders(resource, response);
if (EventResource.class.isInstance(resource)) {
setHeaderOpt("Schedule-Tag", ((EventResource) resource).getScheduleTag(), response);
setHeaderOpt("Schedule-Tag", ((EventResource) resource).getScheduleTag(), true, response);
}
}
......
......@@ -77,7 +77,7 @@ public class CalDAVHEADAction extends HEADAction {
protected void setResponseHeaders(WebdavResource resource, WebdavResponse response) throws WebdavProtocolException {
super.setResponseHeaders(resource, response);
if (EventResource.class.isInstance(resource)) {
setHeaderOpt("Schedule-Tag", ((EventResource) resource).getScheduleTag(), response);
setHeaderOpt("Schedule-Tag", ((EventResource) resource).getScheduleTag(), true, response);
}
}
......
......@@ -90,6 +90,7 @@ public class CalDAVIfScheduleTagMatchAction extends DAVAction {
if (null == resource || false == resource.exists()) {
throw DAVProtocol.protocolException(request.getUrl(), OXException.notFound(String.valueOf(request.getUrl())), HttpServletResponse.SC_NOT_FOUND);
}
expectedScheduleTag = Strings.unquote(expectedScheduleTag);
if (false == EventResource.class.isInstance(resource) || false == Objects.equals(expectedScheduleTag, ((EventResource) resource).getScheduleTag())) {
throw DAVProtocol.protocolException(request.getUrl(), OXException.conflict(), HttpServletResponse.SC_PRECONDITION_FAILED);
}
......
......@@ -124,7 +124,7 @@ public class CalDAVPOSTAction extends POSTAction {
*/
WebdavResource updatedResource = factory.resolveResource(request.getUrl());
WebdavResource newResource = factory.resolveResource(splitComponentUrl);
response.setHeader("ETag", updatedResource.getETag());
setHeaderOpt("ETag", updatedResource.getETag(), true, response);
PropfindResponseMarshaller marshaller = new PropfindResponseMarshaller(request.getURLPrefix(), request.getCharset(), request.isBrief())
.addProperty(DAVProtocol.DAV_NS.getURI(), "getetag")
.addProperty(DAVProtocol.CAL_NS.getURI(), "calendar-data")
......
......@@ -202,7 +202,7 @@ public class EventResource extends DAVObjectResource<Event> {
if (null == object || false == object.containsSequence()) {
return null;
}
return '"' + String.valueOf(object.getSequence()) + '"';
return String.valueOf(object.getSequence());
}
/**
......
......@@ -384,14 +384,26 @@ public abstract class DAVAction extends AbstractAction {
* @param response The response to set the header in
*/
protected void setHeaderOpt(String header, Object value, WebdavResponse response) {
setHeaderOpt(header, value, false, response);
}
/**
* Optionally sets a response header if the supplied value reference is not <code>null</code>.
*
* @param header The name of the header name to set
* @param value The value to set, or <code>null</code> to do nothing
* @param quote <code>true</code> to put quotation marks around the value, <code>false</code> to set the value as-is
* @param response The response to set the header in
*/
protected void setHeaderOpt(String header, Object value, boolean quote, WebdavResponse response) {
if (null != value) {
response.setHeader(header, value.toString());
response.setHeader(header, quote ? Strings.quote(String.valueOf(value), true) : String.valueOf(value));
}
}
/**
* Gets the decoded WebDAV paths from all <code>DAV:href</code> children of the supplied parent element.
*
*
* @param request The underlying WebDAV request
* @param parentElement The parent element to extract the paths of the children from
* @return The extracted WebDAV paths, or an empty list if there are none
......@@ -410,7 +422,7 @@ public abstract class DAVAction extends AbstractAction {
/**
* Gets the WebDAV path from the supplied <code>href</code> value.
*
*
* @param request The underlying WebDAV request
* @param href The <code>href</code> value to get the WebDAV path from
* @return The WebDAV path
......
......@@ -79,7 +79,7 @@ public class HEADAction extends DAVAction {
* <ul>
* <li>Content-Type</li>
* <li>Content-Length</li>
* <li>ETag</li>
* <li>ETag (implicitly as quoted string)</li>
* <li>Content-Disposition</li>
* </ul>
*
......@@ -91,7 +91,7 @@ public class HEADAction extends DAVAction {
if (false == resource.isCollection()) {
setHeaderOpt("Content-Length", resource.getLength(), response);
}
setHeaderOpt("ETag", resource.getETag(), response);
setHeaderOpt("ETag", resource.getETag(), true, response);
setHeaderOpt("Content-Disposition", "attachment", response);
}
......
......@@ -227,7 +227,7 @@ public class POSTAction extends DAVAction {
response.setStatus(HttpServletResponse.SC_CREATED);
response.setContentType(resource.getContentType());
response.setHeader("Content-Location", resource.getUrl().toString());
response.setHeader("ETag", resource.getETag());
setHeaderOpt("ETag", resource.getETag(), true, response);
response.setHeader("Cal-Managed-ID", String.valueOf(attachmenId));
}
......@@ -296,7 +296,7 @@ public class POSTAction extends DAVAction {
response.setStatus(HttpServletResponse.SC_CREATED);
response.setContentType(resource.getContentType());
response.setHeader("Content-Location", resource.getUrl().toString());
response.setHeader("ETag", resource.getETag());
setHeaderOpt("ETag", resource.getETag(), true, response);
response.setHeader("Cal-Managed-ID", String.valueOf(attachmentId));
}
......
......@@ -54,7 +54,6 @@ import java.io.InputStream;
import javax.servlet.http.HttpServletResponse;
import com.openexchange.dav.resources.DAVResource;
import com.openexchange.java.Streams;
import com.openexchange.java.Strings;
import com.openexchange.webdav.action.WebdavPutAction.SizeExceededInputStream;
import com.openexchange.webdav.action.WebdavRequest;
import com.openexchange.webdav.action.WebdavResponse;
......@@ -132,10 +131,7 @@ public abstract class PUTAction extends DAVAction {
}
response.setStatus(HttpServletResponse.SC_CREATED);
if (includeResponseETag()) {
String eTag = resource.getETag();
if (Strings.isNotEmpty(eTag)) {
response.setHeader("ETag", eTag);
}
setHeaderOpt("ETag", resource.getETag(), true, response);
}
}
......
......@@ -1261,6 +1261,18 @@ public class Strings {
return concat(Character.valueOf('"'), s, Character.valueOf('"'));
}
/**
* Puts double quotes around a string, optionally escaping quotes within the string.
*
* @param s The string to quote.
* @param escape <code>true</code> to escape quotes within the given string prior quoting, <code>false</code>, otherwise
* @return The quoted string.
*/
public static String quote(final String s, boolean escape) {
String value = escape && null != s && s.contains("\"") ? s.replaceAll("\"", "\\\\\"") : s;
return concat(Character.valueOf('"'), value, Character.valueOf('"'));
}
/**
* Removes single or double quotes from a string if its quoted.
*
......
......@@ -50,6 +50,7 @@
package com.openexchange.webdav.action;
import java.util.Date;
import com.openexchange.java.Strings;
import com.openexchange.tools.servlet.http.Tools;
import com.openexchange.webdav.protocol.WebdavProtocolException;
import com.openexchange.webdav.protocol.WebdavResource;
......@@ -70,7 +71,10 @@ public class WebdavHeadAction extends AbstractAction {
if (!resource.isCollection()) {
res.setHeader("Content-Length", (overrideLength == -1) ? resource.getLength().toString() : Long.toString(overrideLength));
}
res.setHeader("ETag", resource.getETag());
String eTag = resource.getETag();
if (null != eTag) {
res.setHeader("ETag", Strings.quote(eTag, true));
}
res.setHeader("Accept-Ranges", "bytes");
Date lastModified = resource.getLastModified();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment