Skip to content

Commit 47d79de

Browse files
authored
Merge pull request #284 from fangfufu/feature/cache-size-thresholds
feat: add --cache-min-size and --cache-max-size file size threshold options
2 parents 73a992f + 1547e39 commit 47d79de

7 files changed

Lines changed: 295 additions & 5 deletions

File tree

USAGE.md

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,72 @@ configuration and usage flags supported by HTTPDirFS.
66

77
### Command Syntax
88

9+
Below is the raw help output displaying all available flags:
10+
911
```bash
10-
httpdirfs [options] URL mountpoint
12+
usage: httpdirfs [options] URL mountpoint
13+
14+
general options:
15+
--config Specify a configuration file
16+
-o opt,[opt...] Mount options
17+
-h --help Print help
18+
-V --version Print version
19+
-f Foreground operation
20+
-s Disable multi-threaded operation
21+
-d --debug Enable debug output (implies -f)
22+
23+
HTTPDirFS options:
24+
-u --username HTTP authentication username
25+
-p --password HTTP authentication password
26+
-P --proxy Proxy for libcurl, for more details refer to
27+
https://curl.haxx.se/libcurl/c/CURLOPT_PROXY.html
28+
--proxy-username Username for the proxy
29+
--proxy-password Password for the proxy
30+
--proxy-cacert Certificate authority for the proxy
31+
--proxy-capath Certificate authority directory for the proxy
32+
--cache Enable cache (default: off)
33+
--cache-location Set a custom cache location
34+
(default: "${XDG_CACHE_HOME}/httpdirfs")
35+
--cache-clear Delete the cache directory or the custom location
36+
specified with `--cache-location`, if the option is
37+
seen first. Then exit in either case.
38+
--cache-min-size Set minimum file size threshold for caching, in bytes
39+
(default: none)
40+
--cache-max-size Set maximum file size threshold for caching, in bytes
41+
(default: none)
42+
--cacert Certificate authority for the server
43+
--capath Certificate authority directory for the server
44+
--dl-seg-size Set cache download segment size, in MB (default: 8)
45+
Note: this setting is ignored if previously
46+
cached data is found for the requested file.
47+
--http-header Set one or more HTTP headers
48+
--max-conns Set maximum number of network connections that
49+
libcurl is allowed to make. (default: 6)
50+
--refresh-timeout The directories are refreshed after the specified
51+
time, in seconds (default: 3600)
52+
--retry-wait Set delay in seconds before retrying an HTTP request
53+
after encountering an error. (default: 5)
54+
--invalid-refresh Try refreshing invalid links when reading a directory.
55+
--user-agent Set user agent string (default: "HTTPDirFS-1.3.1")
56+
--no-range-check Disable the built-in check for the server's support
57+
for HTTP range requests
58+
--zero-len-is-dir If a file has a zero length, treat it as a directory
59+
--insecure-tls Disable libcurl TLS certificate verification by
60+
setting CURLOPT_SSL_VERIFYHOST to 0
61+
--external-links Include external (cross-origin) links from
62+
directory listings (default: off)
63+
--single-file-mode Single file mode - rather than mounting a whole
64+
directory, present a single file inside a virtual
65+
directory.
66+
67+
For mounting a Airsonic / Subsonic server:
68+
--sonic-username The username for your Airsonic / Subsonic server
69+
--sonic-password The password for your Airsonic / Subsonic server
70+
--sonic-id3 Enable ID3 mode - this present the server content in
71+
Artist/Album/Song layout
72+
--sonic-insecure Authenticate against your Airsonic / Subsonic server
73+
using the insecure username / hex encoded password
74+
scheme
1175
```
1276
1377
---
@@ -149,6 +213,20 @@ httpdirfs [options] URL mountpoint
149213
- **Note:** This setting is ignored for files that already have existing cached
150214
segment data on disk.
151215
216+
#### `--cache-min-size <bytes>`
217+
218+
- **Description:** Sets the minimum file size threshold for caching in bytes.
219+
Files with a size smaller than this threshold will bypass the local disk cache
220+
and be downloaded directly from the network upon access.
221+
- **Default:** None (no minimum limit is set).
222+
223+
#### `--cache-max-size <bytes>`
224+
225+
- **Description:** Sets the maximum file size threshold for caching in bytes.
226+
Files with a size larger than this threshold will bypass the local disk cache
227+
and be downloaded directly from the network upon access.
228+
- **Default:** None (no maximum limit is set).
229+
152230
---
153231
154232
### Network & Performance Options

src/config.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ void Config_init(void)
8686

8787
CONFIG.data_blksz = DEFAULT_DATA_BLKSZ;
8888

89+
CONFIG.cache_min_size = -1;
90+
CONFIG.cache_max_size = -1;
91+
8992
/*-------------- Sonic related -------------*/
9093
CONFIG.sonic_username = NULL;
9194

src/config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
*/
3030

3131
#include <limits.h>
32+
#include <sys/types.h>
3233

3334
/**
3435
* \brief the default user agent string
@@ -126,6 +127,10 @@ typedef struct {
126127
int data_blksz;
127128
/** \brief The maximum segment count for a single cache file */
128129
int max_segbc;
130+
/** \brief The minimum file size threshold for caching */
131+
off_t cache_min_size;
132+
/** \brief The maximum file size threshold for caching */
133+
off_t cache_max_size;
129134
/*-------------- Sonic related -------------*/
130135
/** \brief The Sonic server username */
131136
char *sonic_username;

src/fuse_local.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,14 @@
2929
#include "fuse_local.h"
3030

3131
#include "cache.h"
32+
#include "config.h"
3233
#include "link.h"
3334
#include "log.h"
3435

36+
/* clang-format off */
37+
#define BYPASS_FH ((uint64_t)-1)
38+
/* clang-format on */
39+
3540
/*
3641
* must be included before including <fuse.h>
3742
*/
@@ -58,7 +63,7 @@ static int fs_release(const char *path, struct fuse_file_info *fi)
5863
{
5964
lprintf(info, "%s\n", path);
6065
(void)path;
61-
if (CACHE_SYSTEM_INIT && fi->fh) {
66+
if (CACHE_SYSTEM_INIT && fi->fh && fi->fh != BYPASS_FH) {
6267
Cache_close((Cache *)fi->fh);
6368
}
6469
return 0;
@@ -119,10 +124,11 @@ static int fs_read(const char *path, char *buf, size_t size, off_t offset,
119124
{
120125
long received;
121126
if (CACHE_SYSTEM_INIT) {
122-
if (fi->fh) {
127+
if (fi->fh == BYPASS_FH) {
128+
received = path_download(path, buf, size, offset);
129+
} else if (fi->fh) {
123130
received = Cache_read((Cache *)fi->fh, buf, size, offset);
124131
} else {
125-
/* zero-length file: fi->fh was set to 0 in fs_open; return EOF */
126132
received = 0;
127133
}
128134
} else {
@@ -149,6 +155,20 @@ static int fs_open(const char *path, struct fuse_file_info *fi)
149155
LinkTable_unref(link->parent_table);
150156
return 0;
151157
}
158+
int bypass_cache = 0;
159+
off_t file_size = (off_t)link->content_length;
160+
if (file_size < 0 || (size_t)file_size != link->content_length
161+
|| (CONFIG.cache_min_size >= 0 && file_size < CONFIG.cache_min_size)
162+
|| (CONFIG.cache_max_size >= 0
163+
&& file_size > CONFIG.cache_max_size)) {
164+
bypass_cache = 1;
165+
}
166+
if (bypass_cache) {
167+
/* bypass cache creation due to size thresholds */
168+
fi->fh = BYPASS_FH;
169+
LinkTable_unref(link->parent_table);
170+
return 0;
171+
}
152172
fi->fh = (uint64_t)Cache_open(path);
153173
/*
154174
* The cache definitely cannot be opened for some reason.

src/main.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,8 @@ static int parse_arg_list(int argc, char **argv, char ***fuse_argv,
353353
{"capath", required_argument, NULL, 'L'}, /* 29 */
354354
{"proxy-capath", required_argument, NULL, 'L'}, /* 30 */
355355
{"external-links", no_argument, NULL, 'L'}, /* 31 */
356+
{"cache-min-size", required_argument, NULL, 'L'}, /* 32 */
357+
{"cache-max-size", required_argument, NULL, 'L'}, /* 33 */
356358
{0, 0, 0, 0}};
357359
while ((c = getopt_long(argc, argv, short_opts, long_opts, &long_index))
358360
!= -1) {
@@ -475,6 +477,32 @@ static int parse_arg_list(int argc, char **argv, char ***fuse_argv,
475477
case 31:
476478
CONFIG.external_links = 1;
477479
break;
480+
case 32: {
481+
char *endptr;
482+
errno = 0;
483+
long long val = strtoll(optarg, &endptr, 10);
484+
if (errno != 0 || endptr == optarg || *endptr != '\0' || val < 0
485+
|| (long long)(off_t)val != val) {
486+
fprintf(stderr,
487+
"Error: --cache-min-size requires a "
488+
"non-negative integer within off_t range\n");
489+
return 1;
490+
}
491+
CONFIG.cache_min_size = (off_t)val;
492+
} break;
493+
case 33: {
494+
char *endptr;
495+
errno = 0;
496+
long long val = strtoll(optarg, &endptr, 10);
497+
if (errno != 0 || endptr == optarg || *endptr != '\0' || val < 0
498+
|| (long long)(off_t)val != val) {
499+
fprintf(stderr,
500+
"Error: --cache-max-size requires a "
501+
"non-negative integer within off_t range\n");
502+
return 1;
503+
}
504+
CONFIG.cache_max_size = (off_t)val;
505+
} break;
478506
default:
479507
fprintf(stderr, "see httpdirfs -h for usage\n");
480508
return 1;
@@ -485,6 +513,12 @@ static int parse_arg_list(int argc, char **argv, char ***fuse_argv,
485513
return 1;
486514
}
487515
};
516+
if (CONFIG.cache_min_size >= 0 && CONFIG.cache_max_size >= 0
517+
&& CONFIG.cache_min_size > CONFIG.cache_max_size) {
518+
fprintf(stderr, "Error: --cache-min-size cannot be greater than "
519+
"--cache-max-size\n");
520+
return 1;
521+
}
488522
return 0;
489523
}
490524

@@ -530,6 +564,10 @@ HTTPDirFS options:\n\
530564
--cache-clear Delete the cache directory or the custom location\n\
531565
specified with `--cache-location`, if the option is\n\
532566
seen first. Then exit in either case.\n\
567+
--cache-min-size Set minimum file size threshold for caching, in bytes\n\
568+
(default: none)\n\
569+
--cache-max-size Set maximum file size threshold for caching, in bytes\n\
570+
(default: none)\n\
533571
--cacert Certificate authority for the server\n\
534572
--capath Certificate authority directory for the server\n\
535573
--dl-seg-size Set cache download segment size, in MB (default: " XSTR(
@@ -548,7 +586,7 @@ HTTPDirFS options:\n\
548586
--no-range-check Disable the built-in check for the server's support\n\
549587
for HTTP range requests\n\
550588
--zero-len-is-dir If a file has a zero length, treat it as a directory\n\
551-
--insecure-tls Disable licurl TLS certificate verification by\n\
589+
--insecure-tls Disable libcurl TLS certificate verification by\n\
552590
setting CURLOPT_SSL_VERIFYHOST to 0\n\
553591
--external-links Include external (cross-origin) links from\n\
554592
directory listings (default: off)\n\

0 commit comments

Comments
 (0)