Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
cjsmeele committed Dec 17, 2018
2 parents 7f22271 + ceef508 commit e8e1524
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 11 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Expand Up @@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 2.8.12)

project(davrods C)

set(IRODSRT_VERSION "4.2.3" CACHE STRING "iRODS client library version")
set(IRODSRT_VERSION "4.2.4" CACHE STRING "iRODS client library version")

set(DAVRODS_FEATURE "1.4.1")
set(DAVRODS_FEATURE "1.4.2")
set(DAVRODS_VERSION "${IRODSRT_VERSION}_${DAVRODS_FEATURE}")
set(DAVRODS_VERSION_DEB "${IRODSRT_VERSION}-${DAVRODS_FEATURE}")

Expand Down
5 changes: 3 additions & 2 deletions README.md
Expand Up @@ -35,6 +35,7 @@ Please choose the right version for your platform:

| Davrods ver. | iRODS runtime ver. | Packages |
| ------------ | ------------------ | --------------------------------------------------------------------------------- |
| 1.4.2 | 4.2.4 | [RPM, DEB](https://github.com/UtrechtUniversity/davrods/releases/tag/4.2.4_1.4.2) |
| 1.4.1 | 4.2.3 | [RPM, DEB](https://github.com/UtrechtUniversity/davrods/releases/tag/4.2.3_1.4.1) |
| 1.4.1 | 4.1.x | [RPM](https://github.com/UtrechtUniversity/davrods/releases/tag/4.1_1.4.1) |
| 1.4.0 | 4.2.3 | [RPM, DEB](https://github.com/UtrechtUniversity/davrods/releases/tag/4.2.3_1.4.0) |
Expand Down Expand Up @@ -80,9 +81,9 @@ package using the RPM or DEB file from the
Download the Davrods package for your platform and install it using your
package manager, for example:

yum install davrods-4.2.3_1.4.1-1.rpm
yum install davrods-4.2.4_1.4.2-1.rpm
--or--
apt install davrods-4.2.3_1.4.1.deb
apt install davrods-4.2.4_1.4.2.deb

Now see the __Configuration__ section for instructions on how to
configure Davrods once it has been installed.
Expand Down
12 changes: 12 additions & 0 deletions aux/deb/davrods-anonymous-vhost.conf
Expand Up @@ -192,6 +192,18 @@
# #DavRodsHtmlHeader "/etc/apache2/irods/header.html"
# #DavRodsHtmlFooter "/etc/apache2/irods/footer.html"
#
# # Depending on file type, web browser clients will either display
# # files directly or offer a download to the user.
# # This behavior can be influenced with the 'Content-Disposition' header.
# #
# # By default (value 'Off'), no such header is sent by Davrods.
# # When DavRodsForceDownload is 'On', Davrods will send
# # 'Content-Disposition: attachment' for all data objects, signalling that
# # web browsers should not display files inline, but offer a download
# # instead.
# #
# #DavRodsForceDownload Off
#
# # }}}
#
# </Location>
Expand Down
12 changes: 12 additions & 0 deletions aux/deb/davrods-vhost.conf
Expand Up @@ -188,6 +188,18 @@
# #DavRodsHtmlHeader "/etc/apache2/irods/header.html"
# #DavRodsHtmlFooter "/etc/apache2/irods/footer.html"
#
# # Depending on file type, web browser clients will either display
# # files directly or offer a download to the user.
# # This behavior can be influenced with the 'Content-Disposition' header.
# #
# # By default (value 'Off'), no such header is sent by Davrods.
# # When DavRodsForceDownload is 'On', Davrods will send
# # 'Content-Disposition: attachment' for all data objects, signalling that
# # web browsers should not display files inline, but offer a download
# # instead.
# #
# #DavRodsForceDownload Off
#
# # }}}
#
# </Location>
Expand Down
12 changes: 12 additions & 0 deletions aux/rpm/davrods-anonymous-vhost.conf
Expand Up @@ -192,6 +192,18 @@
# #DavRodsHtmlHeader "/etc/httpd/irods/header.html"
# #DavRodsHtmlFooter "/etc/httpd/irods/footer.html"
#
# # Depending on file type, web browser clients will either display
# # files directly or offer a download to the user.
# # This behavior can be influenced with the 'Content-Disposition' header.
# #
# # By default (value 'Off'), no such header is sent by Davrods.
# # When DavRodsForceDownload is 'On', Davrods will send
# # 'Content-Disposition: attachment' for all data objects, signalling that
# # web browsers should not display files inline, but offer a download
# # instead.
# #
# #DavRodsForceDownload Off
#
# # }}}
#
# </Location>
Expand Down
12 changes: 12 additions & 0 deletions aux/rpm/davrods-vhost.conf
Expand Up @@ -188,6 +188,18 @@
# #DavRodsHtmlHeader "/etc/httpd/irods/header.html"
# #DavRodsHtmlFooter "/etc/httpd/irods/footer.html"
#
# # Depending on file type, web browser clients will either display
# # files directly or offer a download to the user.
# # This behavior can be influenced with the 'Content-Disposition' header.
# #
# # By default (value 'Off'), no such header is sent by Davrods.
# # When DavRodsForceDownload is 'On', Davrods will send
# # 'Content-Disposition: attachment' for all data objects, signalling that
# # web browsers should not display files inline, but offer a download
# # instead.
# #
# #DavRodsForceDownload Off
#
# # }}}
#
# </Location>
Expand Down
5 changes: 5 additions & 0 deletions changelog.txt
@@ -1,3 +1,8 @@
* Mon Dec 17 2018 Chris Smeele <c.j.smeele@uu.nl> - 4.2.4_1.4.2-1
- Fixed DavrodsExposedRoot config being ignored in some builds
- Added a Content-Disposition configuration setting (off by default)
- Fixed a URL encoding issue for relative paths in directory listings

* Sun Jul 15 2018 Chris Smeele <c.j.smeele@uu.nl> - 4.2.3_1.4.1-1
- Improved robustness of connection reuse

Expand Down
29 changes: 28 additions & 1 deletion src/config.c
Expand Up @@ -84,6 +84,8 @@ void *davrods_create_dir_config(apr_pool_t *p, char *dir) {
conf->html_head = "";
conf->html_header = "";
conf->html_footer = "";

conf->force_download = DAVRODS_FORCE_DOWNLOAD_OFF;
}
return conf;
}
Expand Down Expand Up @@ -123,12 +125,15 @@ void *davrods_merge_dir_config(apr_pool_t *p, void *_parent, void *_child) {
DAVRODS_PROP_MERGE(anonymous_auth_username);
DAVRODS_PROP_MERGE(anonymous_auth_password);

assert(set_exposed_root(conf, exposed_root) >= 0);
{ int ret = set_exposed_root(conf, exposed_root);
assert(ret >= 0); }

DAVRODS_PROP_MERGE(html_head);
DAVRODS_PROP_MERGE(html_header);
DAVRODS_PROP_MERGE(html_footer);

DAVRODS_PROP_MERGE(force_download);

#undef DAVRODS_PROP_MERGE

return conf;
Expand Down Expand Up @@ -388,6 +393,24 @@ static const char *cmd_davrodshtmlfooter(
return NULL;
}

static const char *cmd_davrodsforcedownload(
cmd_parms *cmd, void *config,
const char *arg1
) {
davrods_dir_conf_t *conf = (davrods_dir_conf_t*)config;

if (!strcasecmp(arg1, "on")) {
conf->force_download = DAVRODS_FORCE_DOWNLOAD_ON;
} else if (!strcasecmp(arg1, "off")) {
conf->force_download = DAVRODS_FORCE_DOWNLOAD_OFF;
} else {
return "This directive accepts only 'On' and 'Off' values";
}

return NULL;
}


// }}}

const command_rec davrods_directives[] = {
Expand Down Expand Up @@ -455,6 +478,10 @@ const command_rec davrods_directives[] = {
DAVRODS_CONFIG_PREFIX "HtmlFooter", cmd_davrodshtmlfooter,
NULL, ACCESS_CONF, "File that's inserted into HTML directory listings, in the body tag"
),
AP_INIT_TAKE1(
DAVRODS_CONFIG_PREFIX "ForceDownload", cmd_davrodsforcedownload,
NULL, ACCESS_CONF, "When On, prevents inline display of files in web browsers"
),

{ NULL }
};
7 changes: 7 additions & 0 deletions src/config.h
Expand Up @@ -86,6 +86,13 @@ typedef struct {
const char *html_header;
const char *html_footer;

enum {
// Relevant only for webbrowser-style clients.
// Prevents inline display of data objects.
DAVRODS_FORCE_DOWNLOAD_OFF = 1,
DAVRODS_FORCE_DOWNLOAD_ON,
} force_download;

} davrods_dir_conf_t;

extern const command_rec davrods_directives[];
Expand Down
96 changes: 90 additions & 6 deletions src/repo.c
Expand Up @@ -1050,6 +1050,14 @@ static dav_error *dav_repo_set_headers(
// This will be overwritten in byterange.c if the request turns out to be
// a valid range request.
ap_set_content_length(r, resource->info->stat->objSize);

davrods_dir_conf_t *conf = ap_get_module_config(r->per_dir_config,
&davrods_module);
assert(conf);

if (conf->force_download == DAVRODS_FORCE_DOWNLOAD_ON)
// Prevent inline display of files in web browsers.
apr_table_setn(r->headers_out, "Content-Disposition", "attachment");
}

return 0;
Expand Down Expand Up @@ -1125,6 +1133,82 @@ static dav_error *deliver_file(
return NULL;
}

/**
* \brief Encode a path such that it can be safely used in a URI.
*
* Used within HTML directory listings.
* If the input path is safe, no new string is allocated.
*
* \param pool A memory pool
* \param path The path to escape
*
* \return An escaped path (may be the same as the input pointer)
*/
static const char *escape_uri_path(
apr_pool_t *pool,
const char *path
) {
// Apache's ap_escape_uri is not sufficient, as it is OS-dependent(!?) and
// does not encode certain reserved characters that can be problematic in
// relative URLs.
//
// Given the lack of an Apache function that does what we need, we do URL
// encoding ourselves, as per RFC 1808:
// https://tools.ietf.org/html/rfc1808 (page 4)
//
// We encode everything outside of the 'unreserved' character class, except for '/'.
// That is, every char not in [a-zA-Z0-9$_.+!*'(),/-].

static const char escape_table[256] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0, // !"#$%&'()*+,-./
0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1, // 0123456789:;<=>?
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // @ABCDEFGHIJKLMNO
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0, // PQRSTUVWXYZ[\]^_
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // `abcdefghijklmno
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1, // pqrstuvwxyz{|}~
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
};

size_t length_orig = strlen(path);
size_t reserved_count = 0;

for (size_t i = 0; i < length_orig; ++i) {
if (escape_table[(unsigned char)path[i]])
++reserved_count;
}

if (!reserved_count)
return path; // Nothing to escape.

// Each reserved char will take up 2 extra characters ('&' => '%26').
size_t length_new = length_orig + reserved_count*2;

char *new_path = apr_pcalloc(pool, length_new + 1);
assert(new_path);
for (size_t i = 0, j = 0;
i < length_orig && j < length_new;
++i) {

if (escape_table[(unsigned char)path[i]]) {
sprintf(new_path + j, "%%%.2X", (unsigned char)path[i]);
j += 3;
} else {
new_path[j++] = path[i];
}
}

return new_path;
}

/**
* \brief Within a HTML directory listing, insert the contents of a local file.
*
Expand Down Expand Up @@ -1251,8 +1335,8 @@ static dav_error *deliver_directory(
ap_escape_html(pool, resource->info->relative_uri),
uri_ends_with_slash ? "" : "/",
ap_escape_html(pool, resource->info->conf->rods_zone),
ap_escape_html(pool, ap_escape_uri(pool, root_dir_without_trailing_slash)),
ap_escape_html(pool, ap_escape_uri(pool, resource->info->relative_uri)),
ap_escape_html(pool, escape_uri_path(pool, root_dir_without_trailing_slash)),
ap_escape_html(pool, escape_uri_path(pool, resource->info->relative_uri)),
uri_ends_with_slash ? "" : "/"); // Append a slash to fix relative links on this page.

deliver_directory_try_insert_local_file(resource, bb, resource->info->conf->html_head);
Expand Down Expand Up @@ -1283,8 +1367,8 @@ static dav_error *deliver_directory(
*p = '\0';
apr_brigade_printf(bb, NULL, NULL,
"<a href=\"%s%s/\">%s</a>%s",
ap_escape_html(pool, ap_escape_uri(pool, root_dir_without_trailing_slash)),
ap_escape_html(pool, ap_escape_uri(pool, path)),
ap_escape_html(pool, escape_uri_path(pool, root_dir_without_trailing_slash)),
ap_escape_html(pool, escape_uri_path(pool, path)),
p == path ? "/" : ap_escape_html(pool, part+1),
p == path ? "" : "/");
*p = '/';
Expand Down Expand Up @@ -1365,11 +1449,11 @@ static dav_error *deliver_directory(
if (coll_entry.objType == COLL_OBJ_T) {
// Collection links need a trailing slash for the '..' links to work correctly.
apr_brigade_printf(bb, NULL, NULL, "<td class=\"name\"><a href=\"%s/\">%s/</a></td>",
ap_escape_html(pool, ap_escape_uri(pool, name)),
ap_escape_html(pool, escape_uri_path(pool, name)),
ap_escape_html(pool, name));
} else {
apr_brigade_printf(bb, NULL, NULL, "<td class=\"name\"><a href=\"%s\">%s</a></td>",
ap_escape_html(pool, ap_escape_uri(pool, name)),
ap_escape_html(pool, escape_uri_path(pool, name)),
ap_escape_html(pool, name));
}

Expand Down

0 comments on commit e8e1524

Please sign in to comment.