2.2.x patch: http://people.apache.org/~minfrin/httpd-mod_cache-304-fix-2.patch
+1: minfrin, jim, covener
- * mod_dav: If a malformed Content-Range header is received for a PUT request,
- we must not use the supplied content per RFC 2616 14.16. Send 400 response
- instead of ignoring the Content-Range.
- PR: 49825
- Trunk version of patch:
- http://svn.apache.org/viewvc?rev=1026743&view=rev
- Backport version for 2.2.x of patch:
- Trunk version of patch works
- +1: rpluem, jorton, covener
-
* mod_dav: If an unknown Content-* header is received for a PUT request, we
must not ignore it but reply with 501 per RFC 2616 9.6.
PR: 42978
return (*hooks->open_lockdb)(r, ro, 0, lockdb);
}
+/**
+ * @return 1 if valid content-range,
+ * 0 if no content-range,
+ * -1 if malformed content-range
+ */
static int dav_parse_range(request_rec *r,
apr_off_t *range_start, apr_off_t *range_end)
{
if (strncasecmp(range, "bytes ", 6) != 0
|| (dash = ap_strchr(range, '-')) == NULL
|| (slash = ap_strchr(range, '/')) == NULL) {
- /* malformed header. ignore it (per S14.16 of RFC2616) */
- return 0;
+ /* malformed header */
+ return -1;
}
*dash++ = *slash++ = '\0';
- /* ignore invalid ranges. (per S14.16 of RFC2616) */
+ /* detect invalid ranges */
if (apr_strtoff(range_start, range + 6, &errp, 10)
|| *errp || *range_start < 0) {
- return 0;
+ return -1;
}
-
if (apr_strtoff(range_end, dash, &errp, 10)
|| *errp || *range_end < 0 || *range_end < *range_start) {
- return 0;
+ return -1;
}
if (*slash != '*') {
if (apr_strtoff(&dummy, slash, &errp, 10)
|| *errp || dummy <= *range_end) {
- return 0;
+ return -1;
}
}
return dav_handle_err(r, err, multi_response);
}
+ has_range = dav_parse_range(r, &range_start, &range_end);
+ if (has_range < 0) {
+ /* RFC 2616 14.16: If we receive an invalid Content-Range we must
+ * not use the content.
+ */
+ body = apr_psprintf(r->pool,
+ "Malformed Content-Range header for PUT %s.",
+ ap_escape_html(r->pool, r->uri));
+ return dav_error_response(r, HTTP_BAD_REQUEST, body);
+ } else if (has_range) {
+ mode = DAV_MODE_WRITE_SEEKABLE;
+ }
+ else {
+ mode = DAV_MODE_WRITE_TRUNC;
+ }
+
/* make sure the resource can be modified (if versioning repository) */
if ((err = dav_auto_checkout(r, resource,
0 /* not parent_only */,
return dav_handle_err(r, err, NULL);
}
- /* truncate and rewrite the file unless we see a Content-Range */
- mode = DAV_MODE_WRITE_TRUNC;
-
- has_range = dav_parse_range(r, &range_start, &range_end);
- if (has_range) {
- mode = DAV_MODE_WRITE_SEEKABLE;
- }
-
/* Create the new file in the repository */
if ((err = (*resource->hooks->open_stream)(resource, mode,
&stream)) != NULL) {