From 75187c9debdc57d47e0842f97e30cb912d364ff2 Mon Sep 17 00:00:00 2001 From: Nick Hengeveld Date: Fri, 4 Nov 2005 14:22:35 -0800 Subject: 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 Signed-off-by: Junio C Hamano diff --git a/http-push.c b/http-push.c index 85cd595..c10067c 100644 --- a/http-push.c +++ b/http-push.c @@ -40,6 +40,9 @@ static const char http_push_usage[] = #define PROPFIND_REQUEST "\n\n\n\n\n" #define LOCK_REQUEST "\n\n\n\n\nmailto:%s\n\n" +#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_lock int 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_request *request) } } +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: ()", 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, const char *name) } } -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 *file, int timeout) 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 *file, int timeout) return NULL; } - free(url); free(out_data); XML_SetUserData(parser, new_lock); @@ -1223,6 +1282,7 @@ struct active_lock *lock_remote(char *file, int timeout) if (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 *file, int timeout) free(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 active_lock *lock) lock_token_header = xmalloc(strlen(lock->token) + 31); sprintf(lock_token_header, "Lock-Token: ", 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 active_lock *lock) curl_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, struct object *obj, } } -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: ()", lock->token); dav_headers = curl_slist_append(dav_headers, if_header); @@ -1460,13 +1519,12 @@ int update_remote(char *remote_path, unsigned char *sha1, curl_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, unsigned char *sha1, } 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: -- cgit v0.10.2-6-g49f6