|  | @@ -11945,16 +11945,40 @@ send_options(struct mg_connection *conn)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* Writes PROPFIND properties for a collection element */
 | 
	
		
			
				|  |  | -static void
 | 
	
		
			
				|  |  | +static int
 | 
	
		
			
				|  |  |  print_props(struct mg_connection *conn,
 | 
	
		
			
				|  |  |              const char *uri,
 | 
	
		
			
				|  |  | +            const char *name,
 | 
	
		
			
				|  |  |              struct mg_file_stat *filep)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	char mtime[64];
 | 
	
		
			
				|  |  | +	size_t href_size, i, j;
 | 
	
		
			
				|  |  | +	int len;
 | 
	
		
			
				|  |  | +	char *href, mtime[64];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	if ((conn == NULL) || (uri == NULL) || (filep == NULL)) {
 | 
	
		
			
				|  |  | -		return;
 | 
	
		
			
				|  |  | +	if ((conn == NULL) || (uri == NULL) || (name == NULL) || (filep == NULL)) {
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	/* Estimate worst case size for encoding */
 | 
	
		
			
				|  |  | +	href_size = (strlen(uri) + strlen(name)) * 3 + 1;
 | 
	
		
			
				|  |  | +	href = (char *)mg_malloc(href_size);
 | 
	
		
			
				|  |  | +	if (href == NULL) {
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	len = mg_url_encode(uri, href, href_size);
 | 
	
		
			
				|  |  | +	if (len >= 0) {
 | 
	
		
			
				|  |  | +		/* Append an extra string */
 | 
	
		
			
				|  |  | +		mg_url_encode(name, href + len, href_size - (size_t)len);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	/* Directory separator should be preserved. */
 | 
	
		
			
				|  |  | +	for (i = j = 0; href[i]; j++) {
 | 
	
		
			
				|  |  | +		if (!strncmp(href + i, "%2f", 3)) {
 | 
	
		
			
				|  |  | +			href[j] = '/';
 | 
	
		
			
				|  |  | +			i += 3;
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			href[j] = href[i++];
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | +	href[j] = '\0';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	gmt_time_string(mtime, sizeof(mtime), &filep->last_modified);
 | 
	
		
			
				|  |  |  	mg_printf(conn,
 | 
	
	
		
			
				|  | @@ -11969,45 +11993,23 @@ print_props(struct mg_connection *conn,
 | 
	
		
			
				|  |  |  	          "<d:status>HTTP/1.1 200 OK</d:status>"
 | 
	
		
			
				|  |  |  	          "</d:propstat>"
 | 
	
		
			
				|  |  |  	          "</d:response>\n",
 | 
	
		
			
				|  |  | -	          uri,
 | 
	
		
			
				|  |  | +	          href,
 | 
	
		
			
				|  |  |  	          filep->is_directory ? "<d:collection/>" : "",
 | 
	
		
			
				|  |  |  	          filep->size,
 | 
	
		
			
				|  |  |  	          mtime);
 | 
	
		
			
				|  |  | +	mg_free(href);
 | 
	
		
			
				|  |  | +	return 1;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static int
 | 
	
		
			
				|  |  |  print_dav_dir_entry(struct de *de, void *data)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	char href[PATH_MAX];
 | 
	
		
			
				|  |  | -	int truncated;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	struct mg_connection *conn = (struct mg_connection *)data;
 | 
	
		
			
				|  |  | -	if (!de || !conn) {
 | 
	
		
			
				|  |  | +	if (!de || !conn || !print_props(conn, conn->request_info.local_uri,
 | 
	
		
			
				|  |  | +	                                 de->file_name, &de->file)) {
 | 
	
		
			
				|  |  |  		return -1;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	mg_snprintf(conn,
 | 
	
		
			
				|  |  | -	            &truncated,
 | 
	
		
			
				|  |  | -	            href,
 | 
	
		
			
				|  |  | -	            sizeof(href),
 | 
	
		
			
				|  |  | -	            "%s%s",
 | 
	
		
			
				|  |  | -	            conn->request_info.local_uri,
 | 
	
		
			
				|  |  | -	            de->file_name);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if (!truncated) {
 | 
	
		
			
				|  |  | -		size_t href_encoded_size;
 | 
	
		
			
				|  |  | -		char *href_encoded;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		href_encoded_size = PATH_MAX * 3; /* worst case */
 | 
	
		
			
				|  |  | -		href_encoded = (char *)mg_malloc(href_encoded_size);
 | 
	
		
			
				|  |  | -		if (href_encoded == NULL) {
 | 
	
		
			
				|  |  | -			return -1;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		mg_url_encode(href, href_encoded, href_encoded_size);
 | 
	
		
			
				|  |  | -		print_props(conn, href_encoded, &de->file);
 | 
	
		
			
				|  |  | -		mg_free(href_encoded);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -12045,7 +12047,7 @@ handle_propfind(struct mg_connection *conn,
 | 
	
		
			
				|  |  |  	          "<d:multistatus xmlns:d='DAV:'>\n");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* Print properties for the requested resource itself */
 | 
	
		
			
				|  |  | -	print_props(conn, conn->request_info.local_uri, filep);
 | 
	
		
			
				|  |  | +	print_props(conn, conn->request_info.local_uri, "", filep);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* If it is a directory, print directory entries too if Depth is not 0
 | 
	
		
			
				|  |  |  	 */
 |