added code to check if the server supports range requests

This commit is contained in:
Fufu Fang 2019-10-24 00:44:18 +01:00
parent cf700e5d3d
commit a8ef8c88b5
No known key found for this signature in database
GPG Key ID: 0F6BB5EF6F8BB729
6 changed files with 92 additions and 30 deletions

View File

@ -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

View File

@ -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

View File

@ -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 ( !(

View File

@ -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 {

View File

@ -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;
}

View File

@ -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);