Refresh the remote lock if it is about to expire
PATCH 4/4 Refresh the remote lock if it is about to expire
Refresh the remote lock if it is about to expire
Signed-off-by Nick Hengeveld <[email protected]>
---
http-push.c | 106 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 79 insertions(+), 27 deletions(-)
applies-to: 678d5afb150b94bf4a516f852cd41f6920e8642b 197abe5895bea9924c8f01398d9fc73ec013cbd5
http-push.c +79 -27
@@ -40,6 +40,9 @@ static const char http_push_usage[] =#define PROPFIND_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n<D:prop xmlns:R=\"%s\">\n<D:supportedlock/>\n</D:prop>\n</D:propfind>"#define LOCK_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:lockinfo xmlns:D=\"DAV:\">\n<D:lockscope><D:exclusive/></D:lockscope>\n<D:locktype><D:write/></D:locktype>\n<D:owner>\n<D:href>mailto:%s</D:href>\n</D:owner>\n</D:lockinfo>" +#define LOCK_TIME 600 +#define LOCK_REFRESH 30 +static int active_requests =0 ;static int data_received;static int pushing =0 ;
@@ -143,10 +146,12 @@ struct active_lockint ctx_timeout;int ctx_locktoken;int ctx_locktoken_href; +char *url;char *owner; +char *token;time_t start_time;long timeout; -char *token; +int refreshing; };struct lockprop
@@ -580,11 +585,65 @@ static void start_move(struct transfer_r } } +int refresh_lock (struct active_lock *lock) +{ +struct active_request_slot *slot; +char *if_header; +char timeout_header[25 ]; +struct curl_slist *dav_headers =NULL ; +int rc =0 ; + + lock->refreshing =1 ; + + if_header =xmalloc (strlen (lock->token) +25 ); +sprintf (if_header,"If: (<opaquelocktoken:%s>)" , lock->token); +sprintf (timeout_header,"Timeout: Second-%ld" , lock->timeout); + dav_headers =curl_slist_append (dav_headers, if_header); + dav_headers =curl_slist_append (dav_headers, timeout_header); + + slot =get_active_slot (); +curl_easy_setopt (slot->curl,CURLOPT_HTTPGET ,1 ); +curl_easy_setopt (slot->curl,CURLOPT_WRITEFUNCTION , fwrite_null); +curl_easy_setopt (slot->curl,CURLOPT_URL , lock->url); +curl_easy_setopt (slot->curl,CURLOPT_CUSTOMREQUEST ,DAV_LOCK ); +curl_easy_setopt (slot->curl,CURLOPT_HTTPHEADER , dav_headers); + +if (start_active_slot (slot)) { +run_active_slot (slot); +if (slot->curl_result !=CURLE_OK ) { +fprintf (stderr,"Got HTTP error %ld\n" , slot->http_code); + }else { + lock->start_time =time (NULL ); + rc =1 ; + } + } + + lock->refreshing =0 ; +curl_slist_free_all (dav_headers); +free (if_header); + +return rc; +} +static void finish_request (struct transfer_request *request) { +time_t current_time =time (NULL ); +int time_remaining; + request->curl_result = request->slot->curl_result; request->http_code = request->slot->http_code; request->slot =NULL ; + +/* Refresh the lock if it is close to timing out */ + time_remaining = request->lock->start_time + request->lock->timeout + - current_time; +if (time_remaining <LOCK_REFRESH && !request->lock->refreshing) { +if (!refresh_lock (request->lock)) { +fprintf (stderr,"Unable to refresh remote lock\n" ); + aborted =1 ; + } + } +if (request->headers !=NULL )curl_slist_free_all (request->headers);if (request->state ==RUN_HEAD ) {
@@ -1114,7 +1173,7 @@ end_lockprop_element(void *userData, con } } -struct active_lock *lock_remote (char *file,int timeout) +struct active_lock *lock_remote (char *file,long timeout) {struct active_request_slot *slot;struct buffer out_buffer;
@@ -1175,8 +1234,9 @@ struct active_lock *lock_remote(char *fi new_lock->owner =NULL ; new_lock->token =NULL ; new_lock->timeout =-1 ; + new_lock->refreshing =0 ; -sprintf (timeout_header,"Timeout: Second-%d" , timeout); +sprintf (timeout_header,"Timeout: Second-%ld" , timeout); dav_headers =curl_slist_append (dav_headers, timeout_header); dav_headers =curl_slist_append (dav_headers,"Content-Type: text/xml" );
@@ -1211,7 +1271,6 @@ struct active_lock *lock_remote(char *fireturn NULL ; } -free (url);free (out_data);XML_SetUserData (parser, new_lock);
@@ -1223,6 +1282,7 @@ struct active_lock *lock_remote(char *fiif (result !=XML_STATUS_OK ) {fprintf (stderr,"%s" ,XML_ErrorString (XML_GetErrorCode (parser))); +free (url);free (new_lock);return NULL ; }
@@ -1232,18 +1292,19 @@ struct active_lock *lock_remote(char *fifree (new_lock->token);if (new_lock->owner !=NULL )free (new_lock->owner); +free (url);free (new_lock);return NULL ; } + new_lock->url = url; new_lock->start_time =time (NULL );return new_lock; } -int unlock_remote (char *file,struct active_lock *lock) +int unlock_remote (struct active_lock *lock) {struct active_request_slot *slot; -char *url;char *lock_token_header;struct curl_slist *dav_headers =NULL ;int rc =0 ;
@@ -1251,13 +1312,11 @@ int unlock_remote(char *file, struct act lock_token_header =xmalloc (strlen (lock->token) +31 );sprintf (lock_token_header,"Lock-Token: <opaquelocktoken:%s>" , lock->token); - url =xmalloc (strlen (remote->url) +strlen (file) +1 ); -sprintf (url,"%s%s" , remote->url, file); dav_headers =curl_slist_append (dav_headers, lock_token_header); slot =get_active_slot ();curl_easy_setopt (slot->curl,CURLOPT_WRITEFUNCTION , fwrite_null); -curl_easy_setopt (slot->curl,CURLOPT_URL , url); +curl_easy_setopt (slot->curl,CURLOPT_URL , lock->url);curl_easy_setopt (slot->curl,CURLOPT_CUSTOMREQUEST ,DAV_UNLOCK );curl_easy_setopt (slot->curl,CURLOPT_HTTPHEADER , dav_headers);
@@ -1274,7 +1333,12 @@ int unlock_remote(char *file, struct actcurl_slist_free_all (dav_headers);free (lock_token_header); -free (url); + +if (lock->owner !=NULL ) +free (lock->owner); +free (lock->url); +free (lock->token); +free (lock);return rc; }
@@ -1423,20 +1487,15 @@ void get_delta(unsigned char *sha1, stru } } -int update_remote (char *remote_path,unsigned char *sha1, -struct active_lock *lock) +int update_remote (unsigned char *sha1,struct active_lock *lock) {struct active_request_slot *slot; -char *url;char *out_data;char *if_header;struct buffer out_buffer;struct curl_slist *dav_headers =NULL ;int i; - url =xmalloc (strlen (remote->url) +strlen (remote_path) +1 ); -sprintf (url,"%s%s" , remote->url, remote_path); - if_header =xmalloc (strlen (lock->token) +25 );sprintf (if_header,"If: (<opaquelocktoken:%s>)" , lock->token); dav_headers =curl_slist_append (dav_headers, if_header);
@@ -1460,13 +1519,12 @@ int update_remote(char *remote_path, unscurl_easy_setopt (slot->curl,CURLOPT_HTTPHEADER , dav_headers);curl_easy_setopt (slot->curl,CURLOPT_UPLOAD ,1 );curl_easy_setopt (slot->curl,CURLOPT_PUT ,1 ); -curl_easy_setopt (slot->curl,CURLOPT_URL , url); +curl_easy_setopt (slot->curl,CURLOPT_URL , lock->url);if (start_active_slot (slot)) {run_active_slot (slot);free (out_data);free (if_header); -free (url);if (slot->curl_result !=CURLE_OK ) { fprintf(stderr, "PUT error: curl result=%d, HTTP code=%ld\n",
@@ -1477,7 +1535,6 @@ int update_remote(char *remote_path, uns }else {free (out_data);free (if_header); -free (url);fprintf (stderr,"Unable to start PUT request\n" );return 0 ; }
@@ -1629,7 +1686,7 @@ int main(int argc, char **argv)free (remote_path); remote_path =xmalloc (strlen (remote_ref) +12 );sprintf (remote_path,"refs/heads/%s" , remote_ref); - remote_lock =lock_remote (remote_path,3600 ); + remote_lock =lock_remote (remote_path,LOCK_TIME );if (remote_lock ==NULL ) {fprintf (stderr,"Unable to lock remote branch %s\n" , remote_ref);
@@ -1701,8 +1758,7 @@ int main(int argc, char **argv)/* Update the remote branch if all went well */ if (do_remote_update) { -if (!aborted &&update_remote (remote_path, - local_sha1, +if (!aborted &&update_remote (local_sha1, remote_lock)) { fprintf(stderr, "%s remote branch %s\n", new_branch ? "Created" : "Updated",
@@ -1718,12 +1774,8 @@ int main(int argc, char **argv) } unlock: -unlock_remote (remote_path, remote_lock); +unlock_remote (remote_lock);free (remote_path); -if (remote_lock->owner !=NULL ) -free (remote_lock->owner); -free (remote_lock->token); -free (remote_lock); } cleanup:
---
0.99.9.GIT