1 /* 2 * libwebsockets - small server side websockets and web server implementation 3 * 4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25 /*! \defgroup diskcache LWS disk cache 26 * ## Disk cache API 27 * 28 * Lws provides helper apis useful if you need a disk cache containing hashed 29 * files and need to delete files from it on an LRU basis to keep it below some 30 * size limit. 31 * 32 * The API `lws_diskcache_prepare()` deals with creating the cache dir and 33 * 256 subdirs, which are used according to the first two chars of the hex 34 * hash of the cache file. 35 * 36 * `lws_diskcache_create()` and `lws_diskcache_destroy()` allocate and free 37 * an opaque struct that represents the disk cache. 38 * 39 * `lws_diskcache_trim()` should be called at eg, 1s intervals to perform the 40 * cache dir monitoring and LRU autodelete in the background lazily. It can 41 * be done in its own thread or on a timer... it monitors the directories in a 42 * stateful way that stats one or more file in the cache per call, and keeps 43 * a list of the oldest files as it goes. When it completes a scan, if the 44 * aggregate size is over the limit, it will delete oldest files first to try 45 * to keep it under the limit. 46 * 47 * The cache size monitoring is extremely efficient in time and memory even when 48 * the cache directory becomes huge. 49 * 50 * `lws_diskcache_query()` is used to determine if the file already exists in 51 * the cache, or if it must be created. If it must be created, then the file 52 * is opened using a temp name that must be converted to a findable name with 53 * `lws_diskcache_finalize_name()` when the generation of the file contents are 54 * complete. Aborted cached files that did not complete generation will be 55 * flushed by the LRU eventually. If the file already exists, it is 'touched' 56 * to make it new again and the fd returned. 57 * 58 */ 59 ///@{ 60 61 struct lws_diskcache_scan; 62 63 /** 64 * lws_diskcache_create() - creates an opaque struct representing the disk cache 65 * 66 * \param cache_dir_base: The cache dir path, eg `/var/cache/mycache` 67 * \param cache_size_limit: maximum size on disk the cache is allowed to use 68 * 69 * This returns an opaque `struct lws_diskcache_scan *` which represents the 70 * disk cache, the trim scanning state and so on. You should use 71 * `lws_diskcache_destroy()` to free it to destroy it. 72 */ 73 LWS_VISIBLE LWS_EXTERN struct lws_diskcache_scan * 74 lws_diskcache_create(const char *cache_dir_base, uint64_t cache_size_limit); 75 76 /** 77 * lws_diskcache_destroy() - destroys the pointer returned by ...create() 78 * 79 * \param lds: pointer to the pointer returned by lws_diskcache_create() 80 * 81 * Frees *lds and any allocations it did, and then sets *lds to NULL and 82 * returns. 83 */ 84 LWS_VISIBLE LWS_EXTERN void 85 lws_diskcache_destroy(struct lws_diskcache_scan **lds); 86 87 /** 88 * lws_diskcache_prepare() - ensures the cache dir structure exists on disk 89 * 90 * \param cache_base_dir: The cache dir path, eg `/var/cache/mycache` 91 * \param mode: octal dir mode to enforce, like 0700 92 * \param uid: uid the cache dir should belong to 93 * 94 * This should be called while your app is still privileged. It will create 95 * the cache directory structure on disk as necessary, enforce the given access 96 * mode on it and set the given uid as the owner. It won't make any trouble 97 * if the cache already exists. 98 * 99 * Typically the mode is 0700 and the owner is the user that your application 100 * will transition to use when it drops root privileges. 101 */ 102 LWS_VISIBLE LWS_EXTERN int 103 lws_diskcache_prepare(const char *cache_base_dir, int mode, uid_t uid); 104 105 #define LWS_DISKCACHE_QUERY_NO_CACHE 0 106 #define LWS_DISKCACHE_QUERY_EXISTS 1 107 #define LWS_DISKCACHE_QUERY_CREATING 2 108 #define LWS_DISKCACHE_QUERY_ONGOING 3 /* something else is creating it */ 109 110 /** 111 * lws_diskcache_query() - ensures the cache dir structure exists on disk 112 * 113 * \param lds: The opaque struct representing the disk cache 114 * \param is_bot: nonzero means the request is from a bot. Don't create new cache contents if so. 115 * \param hash_hex: hex string representation of the cache object hash 116 * \param _fd: pointer to the fd to be set 117 * \param cache: destination string to take the cache filepath 118 * \param cache_len: length of the buffer at `cache` 119 * \param extant_cache_len: pointer to a size_t to take any extant cached file size 120 * 121 * This function is called when you want to find if the hashed name already 122 * exists in the cache. The possibilities for the return value are 123 * 124 * - LWS_DISKCACHE_QUERY_NO_CACHE: It's not in the cache and you can't create 125 * it in the cache for whatever reason. 126 * - LWS_DISKCACHE_QUERY_EXISTS: It exists in the cache. It's open RDONLY and 127 * *_fd has been set to the file descriptor. *extant_cache_len has been set 128 * to the size of the cached file in bytes. cache has been set to the 129 * full filepath of the cached file. Closing _fd is your responsibility. 130 * - LWS_DISKCACHE_QUERY_CREATING: It didn't exist, but a temp file has been 131 * created in the cache and *_fd set to a file descriptor opened on it RDWR. 132 * You should create the contents, and call `lws_diskcache_finalize_name()` 133 * when it is done. Closing _fd is your responsibility. 134 * - LWS_DISKCACHE_QUERY_ONGOING: not returned by this api, but you may find it 135 * desirable to make a wrapper function which can handle another asynchronous 136 * process that is already creating the cached file. This can be used to 137 * indicate that situation externally... how to determine the same thing is 138 * already being generated is out of scope of this api. 139 */ 140 LWS_VISIBLE LWS_EXTERN int 141 lws_diskcache_query(struct lws_diskcache_scan *lds, int is_bot, 142 const char *hash_hex, int *_fd, char *cache, int cache_len, 143 size_t *extant_cache_len); 144 145 /** 146 * lws_diskcache_query() - ensures the cache dir structure exists on disk 147 * 148 * \param cache: The cache file temp name returned with LWS_DISKCACHE_QUERY_CREATING 149 * 150 * This renames the cache file you are creating to its final name. It should 151 * be called on the temp name returned by `lws_diskcache_query()` if it gave a 152 * LWS_DISKCACHE_QUERY_CREATING return, after you have filled the cache file and 153 * closed it. 154 */ 155 LWS_VISIBLE LWS_EXTERN int 156 lws_diskcache_finalize_name(char *cache); 157 158 /** 159 * lws_diskcache_trim() - performs one or more file checks in the cache for size management 160 * 161 * \param lds: The opaque object representing the cache 162 * 163 * This should be called periodically to statefully walk the cache on disk 164 * collecting the oldest files. When it has visited every file, if the cache 165 * is oversize it will delete the oldest files until it's back under size again. 166 * 167 * Each time it's called, it will look at one or more dir in the cache. If 168 * called when the cache is oversize, it increases the amount of work done each 169 * call until it is reduced again. Typically it will take 256 calls before it 170 * deletes anything, so if called once per second, it will delete files once 171 * every 4 minutes. Each call is very inexpensive both in memory and time. 172 */ 173 LWS_VISIBLE LWS_EXTERN int 174 lws_diskcache_trim(struct lws_diskcache_scan *lds); 175 176 177 /** 178 * lws_diskcache_secs_to_idle() - see how long to idle before calling trim 179 * 180 * \param lds: The opaque object representing the cache 181 * 182 * If the cache is undersize, there's no need to monitor it immediately. This 183 * suggests how long to "sleep" before calling `lws_diskcache_trim()` again. 184 */ 185 LWS_VISIBLE LWS_EXTERN int 186 lws_diskcache_secs_to_idle(struct lws_diskcache_scan *lds); 187 ///@} 188