Fix -gzip removal from etag

Removes when the etag is both "foo-gzip" or "foo"-gzip

Add to patch for
https://github.com/owncloud/mirall/issues/1195
This commit is contained in:
Olivier Goffart 2013-11-26 11:55:47 +01:00
parent 8ed02302ca
commit 87792b59e6
7 changed files with 71 additions and 24 deletions

View file

@ -178,8 +178,7 @@ csync_vio_method_handle_t *csync_dbtree_opendir(CSYNC *ctx, const char *name)
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
column = list->vector[base+8]; /* type */
fs->etag = c_strdup(column);
csync_normalize_etag(fs->etag);
fs->etag = csync_normalize_etag(column);
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG;
/* store into result list. */

View file

@ -261,19 +261,37 @@ CSYNC_STATUS csync_errno_to_status(int error, CSYNC_STATUS default_status)
return status;
}
/* Remove "-gzip" at the end (cf. https://github.com/owncloud/mirall/issues/1195)
/* Remove possible quotes, and also the -gzip at the end
* Remove "-gzip" at the end (cf. https://github.com/owncloud/mirall/issues/1195)
* The caller must take ownership of the resulting string.
* (work in place)
*/
char *csync_normalize_etag(char *etag)
char *csync_normalize_etag(const char *etag)
{
int len = 0;
if (!etag) return etag;
char *buf = NULL;
if (!etag)
return NULL;
len = strlen(etag);
if (len > 5 && c_streq(etag + len - 5, "-gzip")) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Removing -gzip from etag: %s", etag);
etag[len-5] = '\0';
/* strip "XXXX-gzip" */
if(len >= 7 && etag[0] == '"' && c_streq(etag + len - 6, "-gzip\"")) {
etag++;
len -= 7;
}
return etag;
/* strip leading -gzip */
if(len >= 5 && c_streq(etag + len - 5, "-gzip")) {
len -= 5;
}
/* strip normal quotes */
if (etag[0] == '"' && etag[len-1] == '"') {
etag++;
len -= 2;
}
buf = c_malloc( len+1 );
strncpy( buf, etag, len );
buf[len] = '\0';
return buf;
}

View file

@ -64,6 +64,6 @@ typedef struct {
} csync_overall_progress_t;
char *csync_normalize_etag(char *);
char *csync_normalize_etag(const char *);
#endif /* _CSYNC_MISC_H */

View file

@ -954,16 +954,7 @@ static const char* owncloud_get_etag( const char *path )
/* In case the result is surrounded by "" cut them away. */
if( header ) {
if( header [0] == '"' && header[ strlen(header)-1] == '"') {
int len = strlen( header )-2;
buf = c_malloc( len+1 );
strncpy( buf, header+1, len );
buf[len] = '\0';
cbuf = buf;
/* do not free header here, as it belongs to the request */
} else {
cbuf = c_strdup(header);
}
cbuf = csync_normalize_etag(header);
}
/* fix server problem: If we end up with an empty string, set something strange... */
@ -977,7 +968,7 @@ static const char* owncloud_get_etag( const char *path )
if( req ) ne_request_destroy(req);
SAFE_FREE(uri);
csync_normalize_etag(cbuf);
return cbuf;
}

View file

@ -392,7 +392,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_hash(sqlite3 *db,
}
if(column_count > 9 && sqlite3_column_text(_by_hash_stmt, 9)) {
st->etag = csync_normalize_etag(c_strdup( (char*) sqlite3_column_text(_by_hash_stmt, 9) ));
st->etag = csync_normalize_etag( (char*) sqlite3_column_text(_by_hash_stmt, 9) );
}
}
} else {
@ -461,7 +461,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_file_id( sqlite3 *db,
st->modtime = strtoul(result->vector[7], NULL, 10);
st->type = atoi(result->vector[8]);
if( result->vector[9] )
st->etag = csync_normalize_etag(c_strdup(result->vector[9]));
st->etag = csync_normalize_etag(result->vector[9]);
csync_vio_set_file_id(st->file_id, file_id);
@ -516,7 +516,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_inode(sqlite3 *db,
st->modtime = strtoul(result->vector[7], NULL, 10);
st->type = atoi(result->vector[8]);
if( result->vector[9] )
st->etag = csync_normalize_etag(c_strdup(result->vector[9]));
st->etag = csync_normalize_etag(result->vector[9]);
csync_vio_set_file_id( st->file_id, result->vector[10]);
c_strlist_destroy(result);

View file

@ -45,6 +45,7 @@ add_cmocka_test(check_csync_exclude csync_tests/check_csync_exclude.c ${TEST_TAR
add_cmocka_test(check_csync_statedb_load csync_tests/check_csync_statedb_load.c ${TEST_TARGET_LIBRARIES})
add_cmocka_test(check_csync_time csync_tests/check_csync_time.c ${TEST_TARGET_LIBRARIES})
add_cmocka_test(check_csync_util csync_tests/check_csync_util.c ${TEST_TARGET_LIBRARIES})
add_cmocka_test(check_csync_misc csync_tests/check_csync_misc.c ${TEST_TARGET_LIBRARIES})
# csync tests which require init
add_cmocka_test(check_csync_init csync_tests/check_csync_init.c ${TEST_TARGET_LIBRARIES})

View file

@ -0,0 +1,38 @@
#include "torture.h"
#include "csync_misc.h"
#include <stdlib.h>
static void check_csync_normalize_etag(void **state)
{
char *str;
(void) state; /* unused */
#define CHECK_NORMALIZE_ETAG(TEST, EXPECT) \
str = csync_normalize_etag(TEST); \
assert_string_equal(str, EXPECT); \
free(str);
CHECK_NORMALIZE_ETAG("foo", "foo");
CHECK_NORMALIZE_ETAG("\"foo\"", "foo");
CHECK_NORMALIZE_ETAG("\"nar123\"", "nar123");
CHECK_NORMALIZE_ETAG("", "");
CHECK_NORMALIZE_ETAG("\"\"", "");
/* Test with -gzip (all combinaison) */
CHECK_NORMALIZE_ETAG("foo-gzip", "foo");
CHECK_NORMALIZE_ETAG("\"foo\"-gzip", "foo");
CHECK_NORMALIZE_ETAG("\"foo-gzip\"", "foo");
}
int torture_run_tests(void)
{
const UnitTest tests[] = {
unit_test(check_csync_normalize_etag),
};
return run_tests(tests);
}