mirror of
https://github.com/nextcloud/desktop.git
synced 2024-10-24 21:35:47 +03:00
Make PROPFIND cache external unit
and introduce a csync_owncloud.h
This commit is contained in:
parent
980c176073
commit
52e2775292
4 changed files with 222 additions and 150 deletions
|
@ -64,7 +64,7 @@ endif (LIBSSH_FOUND)
|
|||
|
||||
if (NEON_FOUND)
|
||||
include_directories( ${NEON_INCLUDE_DIRS} )
|
||||
macro_add_plugin(${OWNCLOUD_PLUGIN} csync_owncloud.c)
|
||||
macro_add_plugin(${OWNCLOUD_PLUGIN} csync_owncloud.c csync_owncloud_recursive_propfind.c)
|
||||
target_link_libraries(${OWNCLOUD_PLUGIN} ${CSYNC_LIBRARY} ${NEON_LIBRARIES} ${HTTPBF_LIBRARY})
|
||||
|
||||
install(
|
||||
|
|
|
@ -18,87 +18,9 @@
|
|||
* along with this program = NULL, if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "csync_owncloud.h"
|
||||
|
||||
#include "config.h"
|
||||
#ifdef NEON_WITH_LFS /* Switch on LFS in libneon. Never remove the NE_LFS! */
|
||||
#define NE_LFS
|
||||
#endif
|
||||
|
||||
#include <neon/ne_basic.h>
|
||||
#include <neon/ne_socket.h>
|
||||
#include <neon/ne_session.h>
|
||||
#include <neon/ne_request.h>
|
||||
#include <neon/ne_props.h>
|
||||
#include <neon/ne_auth.h>
|
||||
#include <neon/ne_dates.h>
|
||||
#include <neon/ne_compress.h>
|
||||
#include <neon/ne_redirect.h>
|
||||
|
||||
#include "c_rbtree.h"
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "csync.h"
|
||||
#include "csync_misc.h"
|
||||
#include "csync_macros.h"
|
||||
#include "c_private.h"
|
||||
#include "httpbf.h"
|
||||
|
||||
#include "vio/csync_vio_module.h"
|
||||
#include "vio/csync_vio_file_stat.h"
|
||||
#include "vio/csync_vio.h"
|
||||
|
||||
#include "csync_log.h"
|
||||
|
||||
#define DEBUG_WEBDAV(...) csync_log( dav_session.csync_ctx, 9, "oc_module", __VA_ARGS__);
|
||||
|
||||
#define OC_TIMEDELTA_FAIL (NE_REDIRECT +1)
|
||||
#define OC_PROPFIND_FAIL (NE_REDIRECT +2)
|
||||
|
||||
|
||||
enum resource_type {
|
||||
resr_normal = 0,
|
||||
resr_collection,
|
||||
resr_reference,
|
||||
resr_error
|
||||
};
|
||||
|
||||
#define DAV_STRTOL strtoll
|
||||
|
||||
/* Struct to store data for each resource found during an opendir operation.
|
||||
* It represents a single file entry.
|
||||
*/
|
||||
|
||||
typedef struct resource {
|
||||
char *uri; /* The complete uri */
|
||||
char *name; /* The filename only */
|
||||
|
||||
enum resource_type type;
|
||||
off_t size;
|
||||
time_t modtime;
|
||||
char* md5;
|
||||
|
||||
struct resource *next;
|
||||
} resource;
|
||||
|
||||
/* Struct to hold the context of a WebDAV PropFind operation to fetch
|
||||
* a directory listing from the server.
|
||||
*/
|
||||
struct listdir_context {
|
||||
struct resource *list; /* The list of result resources */
|
||||
struct resource *currResource; /* A pointer to the current resource */
|
||||
char *target; /* Request-URI of the PROPFIND */
|
||||
unsigned int result_count; /* number of elements stored in list */
|
||||
int ref; /* reference count, only destroy when it reaches 0 */
|
||||
};
|
||||
|
||||
/*
|
||||
* free the fetchCtx
|
||||
|
@ -128,56 +50,6 @@ static void free_fetchCtx( struct listdir_context *ctx )
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* context to store info about a temp file for GET and PUT requests
|
||||
* which store the data in a local file to save memory and secure the
|
||||
* transmission.
|
||||
*/
|
||||
struct transfer_context {
|
||||
ne_request *req; /* the neon request */
|
||||
int fd; /* file descriptor of the file to read or write from */
|
||||
const char *method; /* the HTTP method, either PUT or GET */
|
||||
ne_decompress *decompress; /* the decompress context */
|
||||
char *url;
|
||||
};
|
||||
|
||||
/* Struct with the WebDAV session */
|
||||
struct dav_session_s {
|
||||
ne_session *ctx;
|
||||
char *user;
|
||||
char *pwd;
|
||||
|
||||
char *proxy_type;
|
||||
char *proxy_host;
|
||||
int proxy_port;
|
||||
char *proxy_user;
|
||||
char *proxy_pwd;
|
||||
|
||||
char *session_key;
|
||||
|
||||
char *error_string;
|
||||
|
||||
int read_timeout;
|
||||
|
||||
long int prev_delta;
|
||||
long int time_delta; /* The time delta to use. */
|
||||
long int time_delta_sum; /* What is the time delta average? */
|
||||
long int time_delta_cnt; /* How often was the server time gathered? */
|
||||
|
||||
CSYNC *csync_ctx;
|
||||
void *userdata;
|
||||
|
||||
csync_hbf_info_t *chunk_info;
|
||||
};
|
||||
|
||||
/* The list of properties that is fetched in PropFind on a collection */
|
||||
static const ne_propname ls_props[] = {
|
||||
{ "DAV:", "getlastmodified" },
|
||||
{ "DAV:", "getcontentlength" },
|
||||
{ "DAV:", "resourcetype" },
|
||||
{ "DAV:", "getetag"},
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
* local variables.
|
||||
|
@ -195,7 +67,7 @@ long long chunked_done = 0;
|
|||
struct listdir_context *propfind_cache = 0;
|
||||
|
||||
bool is_first_propfind = true;
|
||||
static void clear_propfind_recursive_cache();
|
||||
|
||||
|
||||
csync_vio_file_stat_t _stat_cache;
|
||||
/* id cache, cache the ETag: header of a GET request */
|
||||
|
@ -222,14 +94,14 @@ static void clean_caches() {
|
|||
char _buffer[PUT_BUFFER_SIZE];
|
||||
|
||||
/* ***************************************************************************** */
|
||||
static void set_error_message( const char *msg )
|
||||
void set_error_message( const char *msg )
|
||||
{
|
||||
SAFE_FREE(dav_session.error_string);
|
||||
if( msg )
|
||||
dav_session.error_string = c_strdup(msg);
|
||||
}
|
||||
|
||||
static void set_errno_from_http_errcode( int err ) {
|
||||
void set_errno_from_http_errcode( int err ) {
|
||||
int new_errno = 0;
|
||||
|
||||
switch(err) {
|
||||
|
@ -328,7 +200,7 @@ static void set_errno_from_session() {
|
|||
}
|
||||
}
|
||||
|
||||
static void set_errno_from_neon_errcode( int neon_code ) {
|
||||
void set_errno_from_neon_errcode( int neon_code ) {
|
||||
|
||||
if( neon_code != NE_OK ) {
|
||||
DEBUG_WEBDAV("Neon error code was %d", neon_code);
|
||||
|
@ -386,10 +258,6 @@ static char *_cleanPath( const char* uri ) {
|
|||
SAFE_FREE( path );
|
||||
return re;
|
||||
}
|
||||
/* ***************************************************************************** */
|
||||
#include "csync_owncloud_recursive_propfind.c"
|
||||
/* ***************************************************************************** */
|
||||
|
||||
|
||||
/*
|
||||
* helper method to build up a user text for SSL problems, called from the
|
||||
|
@ -872,7 +740,7 @@ static const char short_months[12][4] = {
|
|||
* needed.
|
||||
* This one uses timegm instead, which returns UTC.
|
||||
*/
|
||||
static time_t oc_httpdate_parse( const char *date ) {
|
||||
time_t oc_httpdate_parse( const char *date ) {
|
||||
struct tm gmt;
|
||||
char wkday[4], mon[4];
|
||||
int n;
|
||||
|
|
180
modules/csync_owncloud.h
Normal file
180
modules/csync_owncloud.h
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2011 by Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2012 by Klaas Freitag <freitag@owncloud.com>
|
||||
*
|
||||
* This program is free software = NULL, you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation = NULL, either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY = NULL, without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program = NULL, if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef CSYNC_OWNCLOUD_H
|
||||
#define CSYNC_OWNCLOUD_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "config.h"
|
||||
#ifdef NEON_WITH_LFS /* Switch on LFS in libneon. Never remove the NE_LFS! */
|
||||
#define NE_LFS
|
||||
#endif
|
||||
|
||||
#include <neon/ne_basic.h>
|
||||
#include <neon/ne_socket.h>
|
||||
#include <neon/ne_session.h>
|
||||
#include <neon/ne_request.h>
|
||||
#include <neon/ne_props.h>
|
||||
#include <neon/ne_auth.h>
|
||||
#include <neon/ne_dates.h>
|
||||
#include <neon/ne_compress.h>
|
||||
#include <neon/ne_redirect.h>
|
||||
|
||||
|
||||
#include "c_rbtree.h"
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "csync.h"
|
||||
#include "csync_misc.h"
|
||||
#include "csync_macros.h"
|
||||
#include "c_private.h"
|
||||
#include "httpbf.h"
|
||||
|
||||
#include "vio/csync_vio_module.h"
|
||||
#include "vio/csync_vio_file_stat.h"
|
||||
#include "vio/csync_vio.h"
|
||||
|
||||
#include "csync_log.h"
|
||||
|
||||
|
||||
#define DEBUG_WEBDAV(...) csync_log( dav_session.csync_ctx, 9, "oc_module", __VA_ARGS__);
|
||||
|
||||
#define OC_TIMEDELTA_FAIL (NE_REDIRECT +1)
|
||||
#define OC_PROPFIND_FAIL (NE_REDIRECT +2)
|
||||
|
||||
|
||||
enum resource_type {
|
||||
resr_normal = 0,
|
||||
resr_collection,
|
||||
resr_reference,
|
||||
resr_error
|
||||
};
|
||||
|
||||
#define DAV_STRTOL strtoll
|
||||
|
||||
/* Struct to store data for each resource found during an opendir operation.
|
||||
* It represents a single file entry.
|
||||
*/
|
||||
|
||||
typedef struct resource {
|
||||
char *uri; /* The complete uri */
|
||||
char *name; /* The filename only */
|
||||
|
||||
enum resource_type type;
|
||||
off_t size;
|
||||
time_t modtime;
|
||||
char* md5;
|
||||
|
||||
struct resource *next;
|
||||
} resource;
|
||||
|
||||
/* Struct to hold the context of a WebDAV PropFind operation to fetch
|
||||
* a directory listing from the server.
|
||||
*/
|
||||
struct listdir_context {
|
||||
struct resource *list; /* The list of result resources */
|
||||
struct resource *currResource; /* A pointer to the current resource */
|
||||
char *target; /* Request-URI of the PROPFIND */
|
||||
unsigned int result_count; /* number of elements stored in list */
|
||||
int ref; /* reference count, only destroy when it reaches 0 */
|
||||
};
|
||||
|
||||
|
||||
// Our cache, key is a char*
|
||||
extern c_rbtree_t *propfind_recursive_cache;
|
||||
// Values are propfind_recursive_element:
|
||||
struct propfind_recursive_element {
|
||||
struct resource *self;
|
||||
struct resource *children;
|
||||
};
|
||||
typedef struct propfind_recursive_element propfind_recursive_element_t;
|
||||
void clear_propfind_recursive_cache();
|
||||
struct listdir_context *get_listdir_context_from_cache(const char *curi);
|
||||
struct listdir_context *fetch_resource_list_recursive(const char *uri, const char *curi);
|
||||
|
||||
time_t oc_httpdate_parse( const char *date );
|
||||
|
||||
|
||||
/*
|
||||
* context to store info about a temp file for GET and PUT requests
|
||||
* which store the data in a local file to save memory and secure the
|
||||
* transmission.
|
||||
*/
|
||||
struct transfer_context {
|
||||
ne_request *req; /* the neon request */
|
||||
int fd; /* file descriptor of the file to read or write from */
|
||||
const char *method; /* the HTTP method, either PUT or GET */
|
||||
ne_decompress *decompress; /* the decompress context */
|
||||
char *url;
|
||||
};
|
||||
|
||||
/* Struct with the WebDAV session */
|
||||
struct dav_session_s {
|
||||
ne_session *ctx;
|
||||
char *user;
|
||||
char *pwd;
|
||||
|
||||
char *proxy_type;
|
||||
char *proxy_host;
|
||||
int proxy_port;
|
||||
char *proxy_user;
|
||||
char *proxy_pwd;
|
||||
|
||||
char *session_key;
|
||||
|
||||
char *error_string;
|
||||
|
||||
int read_timeout;
|
||||
|
||||
long int prev_delta;
|
||||
long int time_delta; /* The time delta to use. */
|
||||
long int time_delta_sum; /* What is the time delta average? */
|
||||
long int time_delta_cnt; /* How often was the server time gathered? */
|
||||
|
||||
CSYNC *csync_ctx;
|
||||
void *userdata;
|
||||
|
||||
csync_hbf_info_t *chunk_info;
|
||||
};
|
||||
extern struct dav_session_s dav_session;
|
||||
|
||||
/* The list of properties that is fetched in PropFind on a collection */
|
||||
static const ne_propname ls_props[] = {
|
||||
{ "DAV:", "getlastmodified" },
|
||||
{ "DAV:", "getcontentlength" },
|
||||
{ "DAV:", "resourcetype" },
|
||||
{ "DAV:", "getetag"},
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
void set_errno_from_http_errcode( int err );
|
||||
void set_error_message( const char *msg );
|
||||
void set_errno_from_neon_errcode( int neon_code );
|
||||
|
||||
#endif // CSYNC_OWNCLOUD_H
|
|
@ -1,13 +1,36 @@
|
|||
static time_t oc_httpdate_parse( const char *date );
|
||||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2011 by Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2012 by Klaas Freitag <freitag@owncloud.com>
|
||||
*
|
||||
* This program is free software = NULL, you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation = NULL, either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY = NULL, without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program = NULL, if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "csync_owncloud.h"
|
||||
|
||||
|
||||
|
||||
// Our cache, key is a char*
|
||||
c_rbtree_t *propfind_recursive_cache = NULL;
|
||||
// Values are propfind_recursive_element:
|
||||
struct propfind_recursive_element {
|
||||
struct resource *self;
|
||||
struct resource *children;
|
||||
};
|
||||
typedef struct propfind_recursive_element propfind_recursive_element_t;
|
||||
|
||||
|
||||
static struct resource* resource_dup(struct resource* o) {
|
||||
struct resource *r = c_malloc (sizeof( struct resource ));
|
||||
|
@ -39,13 +62,13 @@ static void _tree_destructor(void *data) {
|
|||
resource_free(element->children);
|
||||
SAFE_FREE(element);
|
||||
}
|
||||
static void clear_propfind_recursive_cache()
|
||||
void clear_propfind_recursive_cache()
|
||||
{
|
||||
c_rbtree_destroy(propfind_recursive_cache, _tree_destructor);
|
||||
propfind_recursive_cache = NULL;
|
||||
}
|
||||
|
||||
static struct listdir_context *get_listdir_context_from_cache(const char *curi)
|
||||
struct listdir_context *get_listdir_context_from_cache(const char *curi)
|
||||
{
|
||||
if (!propfind_recursive_cache) {
|
||||
DEBUG_WEBDAV("get_listdir_context_from_cache No cache");
|
||||
|
@ -197,7 +220,8 @@ static void results_recursive(void *userdata,
|
|||
/*
|
||||
* fetches a resource list from the WebDAV server. This is equivalent to list dir.
|
||||
*/
|
||||
static struct listdir_context *fetch_resource_list_recursive(const char *uri, const char *curi)
|
||||
extern csync_progress_callback _progresscb;
|
||||
struct listdir_context *fetch_resource_list_recursive(const char *uri, const char *curi)
|
||||
{
|
||||
int ret = 0;
|
||||
ne_propfind_handler *hdl = NULL;
|
||||
|
|
Loading…
Reference in a new issue