* [PATCH 4/4] Refresh the remote lock if it is about to expire
@ 2005-11-04 22:22 Nick Hengeveld
0 siblings, 0 replies; only message in thread
From: Nick Hengeveld @ 2005-11-04 22:22 UTC (permalink / raw)
To: git
Refresh the remote lock if it is about to expire
Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
---
http-push.c | 106 ++++++++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 79 insertions(+), 27 deletions(-)
applies-to: 678d5afb150b94bf4a516f852cd41f6920e8642b
197abe5895bea9924c8f01398d9fc73ec013cbd5
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 "<?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_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_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 *fi
return NULL;
}
- free(url);
free(out_data);
XML_SetUserData(parser, new_lock);
@@ -1223,6 +1282,7 @@ struct active_lock *lock_remote(char *fi
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 *fi
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 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 act
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, 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, uns
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, 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
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2005-11-04 22:22 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-04 22:22 [PATCH 4/4] Refresh the remote lock if it is about to expire Nick Hengeveld
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.