# HG changeset patch # User Olaf Wintermann # Date 1483120046 -3600 # Node ID 55298bc9ed28100bfb51e2118e5fd28739b3525f # Parent ff311b63c3afb76ebcc6a3a83f7ba34bcbcf64fe adds new a pathcheck saf and improves content type matchin and improves content type matching diff -r ff311b63c3af -r 55298bc9ed28 src/server/daemon/httprequest.c --- a/src/server/daemon/httprequest.c Fri Dec 30 14:15:52 2016 +0100 +++ b/src/server/daemon/httprequest.c Fri Dec 30 18:47:26 2016 +0100 @@ -799,7 +799,7 @@ rq->rq.srvhdrs); } // compare types - if(strcmp(dtp, content_type) != 0) { + if(!contenttype_match(sstr(dtp), sstr(content_type))) { continue; } } @@ -1060,7 +1060,10 @@ return 1; } } else if(cmp[0] == 0) { - /* empty string */ + // empty string + log_ereport( + LOG_WARN, + "Skipped service saf with empty method parameter"); return 0; } @@ -1085,6 +1088,43 @@ } /* + * checks if the content type matches the cmp string + * the format of cmp is a single string with wildcards or a list + * of types (also with wildcard support) + * (type1|type2*) + */ +int contenttype_match(sstr_t cmp, sstr_t ctype) { + if(cmp.ptr[0] != '(') { + if(cmp.ptr[0] == '*') { + cmp.ptr++; + cmp.length--; + return sstrsuffix(ctype, cmp); + } else if(cmp.ptr[cmp.length-1] == '*') { + cmp.length--; + return sstrprefix(ctype, cmp); + } else { + return !sstrcmp(cmp, ctype); + } + } else if(cmp.ptr[0] == 0) { + log_ereport(LOG_WARN, "Skipped service saf with empty type parameter"); + return 0; + } + + cmp = sstrsubsl(cmp, 1, cmp.length - 2); + + int begin = 0; + for(int i=0;issl, buf, len); if(ret <= 0) { conn->ssl_error = SSL_get_error(conn->ssl, ret); - if(conn->ssl_error == SSL_ERROR_SYSCALL) { - log_ereport( - LOG_VERBOSE, - "Connection: %d: SSL_read failed: %s", - (int)conn, - strerror(errno)); - } } return ret; } @@ -76,22 +69,17 @@ int ret = SSL_write(conn->ssl, buf, len); if(ret <= 0) { conn->ssl_error = SSL_get_error(conn->ssl, ret); - if(conn->ssl_error == SSL_ERROR_SYSCALL) { - log_ereport( - LOG_VERBOSE, - "Connection: %d: SSL_write failed: %s", - (int)conn, - strerror(errno)); - } } return ret; } void connection_ssl_close(Connection *conn) { - int ret = SSL_shutdown(conn->ssl); - if(ret != 1) { - conn->ssl_error = SSL_get_error(conn->ssl, ret); - log_ereport(LOG_VERBOSE, "SSL_shutdown failed: %d", conn->ssl_error); + if(!conn->ssl_error) { + int ret = SSL_shutdown(conn->ssl); + if(ret != 1) { + conn->ssl_error = SSL_get_error(conn->ssl, ret); + log_ereport(LOG_VERBOSE, "SSL_shutdown failed: %d", conn->ssl_error); + } } close(conn->fd); } diff -r ff311b63c3af -r 55298bc9ed28 src/server/daemon/ws-fn.c --- a/src/server/daemon/ws-fn.c Fri Dec 30 14:15:52 2016 +0100 +++ b/src/server/daemon/ws-fn.c Fri Dec 30 18:47:26 2016 +0100 @@ -65,6 +65,7 @@ { "append-acl", append_acl, NULL, NULL, 0}, { "check-acl", check_acl, NULL, NULL, 0}, { "find-index", find_index, NULL, NULL, 0}, + { "dir-redirect", dir_redirect, NULL, NULL, 0}, { "print-message", print_message, NULL, NULL, 0}, { "common-log", common_log, NULL, NULL, 0}, { "send-cgi", send_cgi, NULL, NULL, 0}, diff -r ff311b63c3af -r 55298bc9ed28 src/server/safs/pathcheck.c --- a/src/server/safs/pathcheck.c Fri Dec 30 14:15:52 2016 +0100 +++ b/src/server/safs/pathcheck.c Fri Dec 30 18:47:26 2016 +0100 @@ -37,6 +37,8 @@ #include "../daemon/session.h" #include "../daemon/vserver.h" +#include "../daemon/vfs.h" + #include "../config/acl.h" int require_auth(pblock *pb, Session *sn, Request *rq) { @@ -157,3 +159,32 @@ return ret; } + +int dir_redirect(pblock *pb, Session *sn, Request *rq) { + char *path = pblock_findkeyval(pb_key_path, rq->vars); + + // TODO: VFS support + + struct stat s; + if(stat(path, &s) != 0) { + return REQ_NOACTION; + } + + // TODO: remove code duplication (service.c) + if(S_ISDIR(s.st_mode) && path[strlen(path)-1] != '/') { + pblock_nvinsert("content-length", "0", rq->srvhdrs); + pblock_removekey(pb_key_content_type, rq->srvhdrs); + char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); + size_t urilen = strlen(uri); + char *location = pool_malloc(sn->pool, urilen + 2); + memcpy(location, uri, urilen); + location[urilen] = '/'; + location[urilen+1] = '\0'; + pblock_kvinsert(pb_key_location, location, urilen + 1, rq->srvhdrs); + protocol_status(sn, rq, 302, NULL); + http_start_response(sn, rq); + return REQ_ABORTED; + } + + return REQ_PROCEED; +} diff -r ff311b63c3af -r 55298bc9ed28 src/server/safs/pathcheck.h --- a/src/server/safs/pathcheck.h Fri Dec 30 14:15:52 2016 +0100 +++ b/src/server/safs/pathcheck.h Fri Dec 30 18:47:26 2016 +0100 @@ -45,6 +45,8 @@ int find_index(pblock *pb, Session *sn, Request *rq); +int dir_redirect(pblock *pb, Session *sn, Request *rq); + #ifdef __cplusplus } #endif diff -r ff311b63c3af -r 55298bc9ed28 src/server/util/io.c --- a/src/server/util/io.c Fri Dec 30 14:15:52 2016 +0100 +++ b/src/server/util/io.c Fri Dec 30 18:47:26 2016 +0100 @@ -361,6 +361,7 @@ sstr_t buf = ucx_vasprintf(ucx_default_allocator(), format, arg); ssize_t r = net_write(fd, buf.ptr, buf.length); free(buf.ptr); + va_end(arg); return r; }