added code to check if the server supports range requests
This commit is contained in:
parent
cf700e5d3d
commit
a8ef8c88b5
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION=1.1.10
|
||||
|
||||
CFLAGS+= -O2 -Wall -Wextra -Wshadow\
|
||||
-rdynamic -D_XOPEN_SOURCE=700 -D_DEFAULT_SOURCE\
|
||||
-rdynamic -D_XOPEN_SOURCE=700 -D_DEFAULT_SOURCE -D_GNU_SOURCE\
|
||||
-D_FILE_OFFSET_BITS=64 -DVERSION=\"$(VERSION)\"\
|
||||
`pkg-config --cflags-only-I gumbo libcurl fuse uuid expat`
|
||||
LIBS = -pthread -lgumbo -lcurl -lfuse -lcrypto -luuid -lexpat
|
||||
|
|
71
src/cache.c
71
src/cache.c
|
@ -116,26 +116,45 @@ void CacheSystem_init(const char *path, int url_supplied)
|
|||
exit_failure();
|
||||
}
|
||||
|
||||
/* Handle the case of missing '/' */
|
||||
if (path[strnlen(path, MAX_PATH_LEN) - 1] == '/') {
|
||||
META_DIR = path_append(path, "meta/");
|
||||
DATA_DIR = path_append(path, "data/");
|
||||
} else {
|
||||
META_DIR = path_append(path, "/meta/");
|
||||
DATA_DIR = path_append(path, "/data/");
|
||||
}
|
||||
META_DIR = path_append(path, "meta/");
|
||||
DATA_DIR = path_append(path, "data/");
|
||||
|
||||
/* Check if directories exist, if not, create them */
|
||||
if (mkdir(META_DIR, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
|
||||
&& (errno != EEXIST)) {
|
||||
fprintf(stderr, "CacheSystem_init(): mkdir(): %s\n",
|
||||
strerror(errno));
|
||||
exit_failure();
|
||||
}
|
||||
|
||||
if (mkdir(DATA_DIR, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
|
||||
&& (errno != EEXIST)) {
|
||||
fprintf(stderr, "CacheSystem_init(): mkdir(): %s\n",
|
||||
strerror(errno));
|
||||
exit_failure();
|
||||
}
|
||||
|
||||
if (CONFIG.sonic_mode) {
|
||||
char *sonic_path;
|
||||
/* Create "rest" sub-directory for META_DIR */
|
||||
sonic_path = path_append(META_DIR, "rest/");
|
||||
if (mkdir(sonic_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
|
||||
&& (errno != EEXIST)) {
|
||||
fprintf(stderr, "CacheSystem_init(): mkdir(): %s\n",
|
||||
strerror(errno));
|
||||
exit_failure();
|
||||
}
|
||||
free(sonic_path);
|
||||
|
||||
/* Create "rest" sub-directory for DATA_DIR */
|
||||
sonic_path = path_append(DATA_DIR, "rest/");
|
||||
if (mkdir(sonic_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
|
||||
&& (errno != EEXIST)) {
|
||||
fprintf(stderr, "CacheSystem_init(): mkdir(): %s\n",
|
||||
strerror(errno));
|
||||
exit_failure();
|
||||
}
|
||||
free(sonic_path);
|
||||
}
|
||||
|
||||
CACHE_SYSTEM_INIT = 1;
|
||||
|
@ -410,6 +429,7 @@ static long Data_write(Cache *cf, const uint8_t *buf, off_t len,
|
|||
fprintf(stderr,
|
||||
"Data_write(): fwrite(): requested %ld, returned %ld!\n",
|
||||
len, byte_written);
|
||||
exit_failure();
|
||||
if (ferror(cf->dfp)) {
|
||||
/* filesystem error */
|
||||
fprintf(stderr,
|
||||
|
@ -558,6 +578,11 @@ static int Cache_exist(const char *fn)
|
|||
*/
|
||||
void Cache_delete(const char *fn)
|
||||
{
|
||||
if (CONFIG.sonic_mode) {
|
||||
Link *link = path_to_Link(fn);
|
||||
fn = link->sonic_id_str;
|
||||
}
|
||||
|
||||
char *metafn = path_append(META_DIR, fn);
|
||||
char *datafn = path_append(DATA_DIR, fn);
|
||||
if (!access(metafn, F_OK)) {
|
||||
|
@ -642,7 +667,12 @@ static int Meta_create(Cache *cf)
|
|||
int Cache_create(Link *this_link)
|
||||
{
|
||||
char *fn;
|
||||
fn = curl_easy_unescape(NULL, this_link->f_url + ROOT_LINK_OFFSET, 0, NULL);
|
||||
if (!CONFIG.sonic_mode) {
|
||||
fn = curl_easy_unescape(NULL, this_link->f_url + ROOT_LINK_OFFSET, 0,
|
||||
NULL);
|
||||
} else {
|
||||
fn = this_link->sonic_id_str;
|
||||
}
|
||||
fprintf(stderr, "Cache_create(): Creating cache files for %s.\n", fn);
|
||||
|
||||
Cache *cf = Cache_alloc();
|
||||
|
@ -655,6 +685,7 @@ int Cache_create(Link *this_link)
|
|||
|
||||
if (Meta_create(cf)) {
|
||||
fprintf(stderr, "Cache_create(): cannot create metadata.\n");
|
||||
exit_failure();
|
||||
}
|
||||
|
||||
if (fclose(cf->mfp)) {
|
||||
|
@ -689,23 +720,33 @@ int Cache_create(Link *this_link)
|
|||
* function returns 0 on success.
|
||||
*/
|
||||
int res = -(!Cache_exist(fn));
|
||||
curl_free(fn);
|
||||
if (!CONFIG.sonic_mode) {
|
||||
curl_free(fn);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Cache *Cache_open(const char *fn)
|
||||
{
|
||||
/* Check if both metadata and data file exist */
|
||||
if (!Cache_exist(fn)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Obtain the link structure memory pointer */
|
||||
Link *link = path_to_Link(fn);
|
||||
if (!link) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if both metadata and data file exist */
|
||||
if (!CONFIG.sonic_mode) {
|
||||
if (!Cache_exist(fn)) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (!Cache_exist(link->sonic_id_str)) {
|
||||
return NULL;
|
||||
}
|
||||
fn = link->sonic_id_str;
|
||||
}
|
||||
|
||||
/*---------------- Cache_open() critical section -----------------*/
|
||||
|
||||
#ifdef CACHE_LOCK_DEBUG
|
||||
|
|
40
src/link.c
40
src/link.c
|
@ -49,24 +49,24 @@ LinkTable *LinkSystem_init(const char *url)
|
|||
ROOT_LINK_OFFSET += 1;
|
||||
}
|
||||
|
||||
/* ----------- Enable cache system --------------------*/
|
||||
/* For now, disable cache mode if sonic mode is enabled */
|
||||
if (!CONFIG.sonic_mode) {
|
||||
if (CONFIG.cache_enabled) {
|
||||
if (CONFIG.cache_dir) {
|
||||
CacheSystem_init(CONFIG.cache_dir, 0);
|
||||
} else {
|
||||
CacheSystem_init(url, 1);
|
||||
}
|
||||
/* --------------------- Enable cache system -------------------- /
|
||||
*
|
||||
* Note that cache system is enabled automatically if sonic mode is
|
||||
* enabled
|
||||
*/
|
||||
if (CONFIG.cache_enabled || CONFIG.sonic_mode) {
|
||||
if (CONFIG.cache_dir) {
|
||||
CacheSystem_init(CONFIG.cache_dir, 0);
|
||||
} else {
|
||||
CacheSystem_init(url, 1);
|
||||
}
|
||||
} else {
|
||||
sonic_config_init(url, CONFIG.sonic_username, CONFIG.sonic_password);
|
||||
}
|
||||
|
||||
/* ----------- Create the root link table --------------*/
|
||||
if (!CONFIG.sonic_mode) {
|
||||
ROOT_LINK_TBL = LinkTable_new(url);
|
||||
} else {
|
||||
sonic_config_init(url, CONFIG.sonic_username, CONFIG.sonic_password);
|
||||
ROOT_LINK_TBL = sonic_LinkTable_new(0);
|
||||
}
|
||||
return ROOT_LINK_TBL;
|
||||
|
@ -360,9 +360,11 @@ DataStruct Link_to_DataStruct(Link *head_link)
|
|||
{
|
||||
char *url = head_link->f_url;
|
||||
CURL *curl = Link_to_curl(head_link);
|
||||
|
||||
DataStruct buf;
|
||||
buf.size = 0;
|
||||
buf.data = NULL;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&buf);
|
||||
|
||||
/* If we get temporary HTTP failure, wait for 5 seconds before retry */
|
||||
|
@ -385,7 +387,6 @@ DataStruct Link_to_DataStruct(Link *head_link)
|
|||
}
|
||||
} while (HTTP_temp_failure(http_resp));
|
||||
|
||||
|
||||
curl_easy_getinfo(curl, CURLINFO_FILETIME, &(head_link->time));
|
||||
curl_easy_cleanup(curl);
|
||||
return buf;
|
||||
|
@ -705,8 +706,23 @@ long path_download(const char *path, char *output_buf, size_t size,
|
|||
PTHREAD_MUTEX_LOCK(&link_lock);
|
||||
PTHREAD_MUTEX_UNLOCK(&link_lock);
|
||||
|
||||
DataStruct header;
|
||||
header.size = 0;
|
||||
header.data = NULL;
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *)&header);
|
||||
|
||||
transfer_blocking(curl);
|
||||
|
||||
/* Check for range seek support */
|
||||
if (!CONFIG.sonic_mode) {
|
||||
if (!strcasestr((header.data), "Accept-Ranges: bytes")) {
|
||||
fprintf(stderr, "Error: This web server does not support HTTP \
|
||||
range requests\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
free(header.data);
|
||||
|
||||
long http_resp;
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_resp);
|
||||
if ( !(
|
||||
|
|
|
@ -73,6 +73,10 @@ struct Link {
|
|||
* \details We use linkname to store filename
|
||||
*/
|
||||
int sonic_id;
|
||||
/**
|
||||
* \brief Sonic Music Directory ID in string format
|
||||
*/
|
||||
char sonic_id_str[MAX_FILENAME_LEN+1];
|
||||
};
|
||||
|
||||
struct LinkTable {
|
||||
|
|
|
@ -140,6 +140,8 @@ static void XMLCALL XML_process_single_element(void *data, const char *elem,
|
|||
for (int i = 0; attr[i]; i += 2) {
|
||||
if (!strcmp("id", attr[i])) {
|
||||
link->sonic_id = atoi(attr[i+1]);
|
||||
snprintf(link->sonic_id_str, MAX_FILENAME_LEN, "%d",
|
||||
link->sonic_id);
|
||||
id_set = 1;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -80,8 +80,7 @@ extern ConfigStruct CONFIG;
|
|||
* \brief append a path
|
||||
* \details This function appends a path with the next level, while taking the
|
||||
* trailing slash of the upper level into account.
|
||||
*
|
||||
* Please free the char * after use.
|
||||
* \note You need to free the char * after use.
|
||||
*/
|
||||
char *path_append(const char *path, const char *filename);
|
||||
|
||||
|
|
Loading…
Reference in New Issue