2005-11-02 20:19:24 +01:00
|
|
|
#include "cache.h"
|
2018-06-29 03:21:51 +02:00
|
|
|
#include "repository.h"
|
2005-11-02 20:19:24 +01:00
|
|
|
#include "commit.h"
|
|
|
|
#include "tag.h"
|
|
|
|
#include "blob.h"
|
2005-11-18 20:02:58 +01:00
|
|
|
#include "http.h"
|
2006-03-08 01:13:20 +01:00
|
|
|
#include "refs.h"
|
2006-04-11 03:14:54 +02:00
|
|
|
#include "diff.h"
|
2006-03-08 01:13:20 +01:00
|
|
|
#include "revision.h"
|
2018-04-10 23:26:18 +02:00
|
|
|
#include "exec-cmd.h"
|
2007-05-12 17:45:59 +02:00
|
|
|
#include "remote.h"
|
2008-06-07 20:39:20 +02:00
|
|
|
#include "list-objects.h"
|
chain kill signals for cleanup functions
If a piece of code wanted to do some cleanup before exiting
(e.g., cleaning up a lockfile or a tempfile), our usual
strategy was to install a signal handler that did something
like this:
do_cleanup(); /* actual work */
signal(signo, SIG_DFL); /* restore previous behavior */
raise(signo); /* deliver signal, killing ourselves */
For a single handler, this works fine. However, if we want
to clean up two _different_ things, we run into a problem.
The most recently installed handler will run, but when it
removes itself as a handler, it doesn't put back the first
handler.
This patch introduces sigchain, a tiny library for handling
a stack of signal handlers. You sigchain_push each handler,
and use sigchain_pop to restore whoever was before you in
the stack.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-22 07:02:35 +01:00
|
|
|
#include "sigchain.h"
|
2020-07-28 22:23:39 +02:00
|
|
|
#include "strvec.h"
|
2017-08-19 00:20:34 +02:00
|
|
|
#include "packfile.h"
|
2018-03-23 18:20:59 +01:00
|
|
|
#include "object-store.h"
|
2018-07-20 18:33:04 +02:00
|
|
|
#include "commit-reach.h"
|
2018-06-29 03:21:51 +02:00
|
|
|
|
2013-02-11 23:03:45 +01:00
|
|
|
#ifdef EXPAT_NEEDS_XMLPARSE_H
|
|
|
|
#include <xmlparse.h>
|
|
|
|
#else
|
2005-11-06 22:07:45 +01:00
|
|
|
#include <expat.h>
|
2013-02-11 23:03:45 +01:00
|
|
|
#endif
|
2005-11-02 20:19:24 +01:00
|
|
|
|
|
|
|
static const char http_push_usage[] =
|
2008-07-13 15:36:15 +02:00
|
|
|
"git http-push [--all] [--dry-run] [--force] [--verbose] <remote> [<head>...]\n";
|
2005-11-02 20:19:24 +01:00
|
|
|
|
2005-11-07 19:23:11 +01:00
|
|
|
#ifndef XML_STATUS_OK
|
|
|
|
enum XML_Status {
|
|
|
|
XML_STATUS_OK = 1,
|
|
|
|
XML_STATUS_ERROR = 0
|
|
|
|
};
|
|
|
|
#define XML_STATUS_OK 1
|
|
|
|
#define XML_STATUS_ERROR 0
|
|
|
|
#endif
|
|
|
|
|
2006-03-11 05:18:18 +01:00
|
|
|
#define PREV_BUF_SIZE 4096
|
2005-11-02 20:19:24 +01:00
|
|
|
|
2005-11-18 20:03:18 +01:00
|
|
|
/* DAV methods */
|
2005-11-02 20:19:24 +01:00
|
|
|
#define DAV_LOCK "LOCK"
|
|
|
|
#define DAV_MKCOL "MKCOL"
|
|
|
|
#define DAV_MOVE "MOVE"
|
|
|
|
#define DAV_PROPFIND "PROPFIND"
|
|
|
|
#define DAV_PUT "PUT"
|
|
|
|
#define DAV_UNLOCK "UNLOCK"
|
2006-03-20 19:31:06 +01:00
|
|
|
#define DAV_DELETE "DELETE"
|
2005-11-18 20:03:18 +01:00
|
|
|
|
|
|
|
/* DAV lock flags */
|
|
|
|
#define DAV_PROP_LOCKWR (1u << 0)
|
|
|
|
#define DAV_PROP_LOCKEX (1u << 1)
|
|
|
|
#define DAV_LOCK_OK (1u << 2)
|
|
|
|
|
|
|
|
/* DAV XML properties */
|
|
|
|
#define DAV_CTX_LOCKENTRY ".multistatus.response.propstat.prop.supportedlock.lockentry"
|
|
|
|
#define DAV_CTX_LOCKTYPE_WRITE ".multistatus.response.propstat.prop.supportedlock.lockentry.locktype.write"
|
|
|
|
#define DAV_CTX_LOCKTYPE_EXCLUSIVE ".multistatus.response.propstat.prop.supportedlock.lockentry.lockscope.exclusive"
|
|
|
|
#define DAV_ACTIVELOCK_OWNER ".prop.lockdiscovery.activelock.owner.href"
|
|
|
|
#define DAV_ACTIVELOCK_TIMEOUT ".prop.lockdiscovery.activelock.timeout"
|
|
|
|
#define DAV_ACTIVELOCK_TOKEN ".prop.lockdiscovery.activelock.locktoken.href"
|
2006-03-08 01:13:20 +01:00
|
|
|
#define DAV_PROPFIND_RESP ".multistatus.response"
|
|
|
|
#define DAV_PROPFIND_NAME ".multistatus.response.href"
|
|
|
|
#define DAV_PROPFIND_COLLECTION ".multistatus.response.propstat.prop.resourcetype.collection"
|
2005-11-18 20:03:18 +01:00
|
|
|
|
|
|
|
/* DAV request body templates */
|
2006-03-08 01:13:20 +01:00
|
|
|
#define PROPFIND_SUPPORTEDLOCK_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 PROPFIND_ALL_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n<D:allprop/>\n</D:propfind>"
|
2005-11-02 20:19:24 +01:00
|
|
|
#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>"
|
|
|
|
|
2005-11-04 23:22:35 +01:00
|
|
|
#define LOCK_TIME 600
|
|
|
|
#define LOCK_REFRESH 30
|
|
|
|
|
2014-03-25 14:23:26 +01:00
|
|
|
/* Remember to update object flag allocation in object.h */
|
http-push: ensure unforced pushes fail when data would be lost
When we push using the DAV-based protocol, the client is the one that
performs the ref updates and therefore makes the checks to see whether
an unforced push should be allowed. We make this check by determining
if either (a) we lack the object file for the old value of the ref or
(b) the new value of the ref is not newer than the old value, and in
either case, reject the push.
However, the ref_newer function, which performs this latter check, has
an odd behavior due to the reuse of certain object flags. Specifically,
it will incorrectly return false in its first invocation and then
correctly return true on a subsequent invocation. This occurs because
the object flags used by http-push.c are the same as those used by
commit-reach.c, which implements ref_newer, and one piece of code
misinterprets the flags set by the other.
Note that this does not occur in all cases. For example, if the example
used in the tests is changed to use one repository instead of two and
rewind the head to add a commit, the test passes and we correctly reject
the push. However, the example provided does trigger this behavior, and
the code has been broken in this way since at least Git 2.0.0.
To solve this problem, let's move the two sets of object flags so that
they don't overlap, since we're clearly using them at the same time.
The new set should not conflict with other usage because other users are
either builtin code (which is not compiled into git http-push) or
upload-pack (which we similarly do not use here).
Reported-by: Michael Ward <mward@smartsoftwareinc.com>
Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-06-23 23:52:20 +02:00
|
|
|
#define LOCAL (1u<<11)
|
|
|
|
#define REMOTE (1u<<12)
|
|
|
|
#define FETCHING (1u<<13)
|
|
|
|
#define PUSHING (1u<<14)
|
2006-03-08 01:13:20 +01:00
|
|
|
|
2006-03-20 19:31:06 +01:00
|
|
|
/* We allow "recursive" symbolic refs. Only within reason, though */
|
|
|
|
#define MAXDEPTH 5
|
|
|
|
|
2006-08-15 19:23:48 +02:00
|
|
|
static int pushing;
|
|
|
|
static int aborted;
|
2006-03-20 20:50:51 +01:00
|
|
|
static signed char remote_dir_exists[256];
|
2005-11-02 20:19:24 +01:00
|
|
|
|
2006-08-15 19:23:48 +02:00
|
|
|
static int push_verbosely;
|
2007-11-10 00:32:10 +01:00
|
|
|
static int push_all = MATCH_REFS_NONE;
|
2006-08-15 19:23:48 +02:00
|
|
|
static int force_all;
|
2007-10-16 06:35:22 +02:00
|
|
|
static int dry_run;
|
2009-10-31 01:47:30 +01:00
|
|
|
static int helper_status;
|
2005-11-02 20:19:24 +01:00
|
|
|
|
2006-08-15 19:23:48 +02:00
|
|
|
static struct object_list *objects;
|
2006-03-08 01:13:20 +01:00
|
|
|
|
2011-03-16 08:08:34 +01:00
|
|
|
struct repo {
|
2005-11-02 20:19:24 +01:00
|
|
|
char *url;
|
2008-12-23 09:31:15 +01:00
|
|
|
char *path;
|
2006-03-08 01:13:20 +01:00
|
|
|
int path_len;
|
2006-03-11 05:18:18 +01:00
|
|
|
int has_info_refs;
|
|
|
|
int can_update_info_refs;
|
|
|
|
int has_info_packs;
|
2005-11-02 20:19:24 +01:00
|
|
|
struct packed_git *packs;
|
2006-03-11 05:18:12 +01:00
|
|
|
struct remote_lock *locks;
|
2005-11-02 20:19:24 +01:00
|
|
|
};
|
|
|
|
|
2009-03-19 00:43:53 +01:00
|
|
|
static struct repo *repo;
|
2005-11-02 20:19:24 +01:00
|
|
|
|
|
|
|
enum transfer_state {
|
2006-03-11 05:18:18 +01:00
|
|
|
NEED_FETCH,
|
|
|
|
RUN_FETCH_LOOSE,
|
|
|
|
RUN_FETCH_PACKED,
|
2005-11-02 20:19:24 +01:00
|
|
|
NEED_PUSH,
|
|
|
|
RUN_MKCOL,
|
|
|
|
RUN_PUT,
|
|
|
|
RUN_MOVE,
|
|
|
|
ABORTED,
|
2010-05-14 11:31:35 +02:00
|
|
|
COMPLETE
|
2005-11-02 20:19:24 +01:00
|
|
|
};
|
|
|
|
|
2011-03-16 08:08:34 +01:00
|
|
|
struct transfer_request {
|
2006-03-08 01:13:20 +01:00
|
|
|
struct object *obj;
|
http: refactor finish_http_pack_request()
finish_http_pack_request() does multiple tasks, including some
housekeeping on a struct packed_git - (1) closing its index, (2)
removing it from a list, and (3) installing it. These concerns are
independent of fetching a pack through HTTP: they are there only because
(1) the calling code opens the pack's index before deciding to fetch it,
(2) the calling code maintains a list of packfiles that can be fetched,
and (3) the calling code fetches it in order to make use of its objects
in the same process.
In preparation for a subsequent commit, which adds a feature that does
not need any of this housekeeping, remove (1), (2), and (3) from
finish_http_pack_request(). (2) and (3) are now done by a helper
function, and (1) is the responsibility of the caller (in this patch,
done closer to the point where the pack index is opened).
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-06-10 22:57:16 +02:00
|
|
|
struct packed_git *target;
|
2005-11-02 20:19:24 +01:00
|
|
|
char *url;
|
|
|
|
char *dest;
|
2006-03-08 01:13:20 +01:00
|
|
|
struct remote_lock *lock;
|
2005-11-02 20:19:24 +01:00
|
|
|
struct curl_slist *headers;
|
|
|
|
struct buffer buffer;
|
|
|
|
enum transfer_state state;
|
|
|
|
CURLcode curl_result;
|
|
|
|
char errorstr[CURL_ERROR_SIZE];
|
|
|
|
long http_code;
|
2006-03-11 05:18:18 +01:00
|
|
|
void *userData;
|
2005-11-02 20:19:24 +01:00
|
|
|
struct active_request_slot *slot;
|
|
|
|
struct transfer_request *next;
|
|
|
|
};
|
|
|
|
|
2006-08-15 19:23:48 +02:00
|
|
|
static struct transfer_request *request_queue_head;
|
2005-11-02 20:19:24 +01:00
|
|
|
|
2011-03-16 08:08:34 +01:00
|
|
|
struct xml_ctx {
|
2005-11-18 20:03:18 +01:00
|
|
|
char *name;
|
|
|
|
int len;
|
|
|
|
char *cdata;
|
|
|
|
void (*userFunc)(struct xml_ctx *ctx, int tag_closed);
|
|
|
|
void *userData;
|
|
|
|
};
|
|
|
|
|
2011-03-16 08:08:34 +01:00
|
|
|
struct remote_lock {
|
2005-11-04 23:22:35 +01:00
|
|
|
char *url;
|
2005-11-04 23:22:31 +01:00
|
|
|
char *owner;
|
2005-11-04 23:22:35 +01:00
|
|
|
char *token;
|
2019-02-19 01:05:09 +01:00
|
|
|
char tmpfile_suffix[GIT_MAX_HEXSZ + 1];
|
2005-11-04 23:22:31 +01:00
|
|
|
time_t start_time;
|
|
|
|
long timeout;
|
2005-11-04 23:22:35 +01:00
|
|
|
int refreshing;
|
2006-03-08 01:13:20 +01:00
|
|
|
struct remote_lock *next;
|
|
|
|
};
|
|
|
|
|
2006-03-11 05:18:08 +01:00
|
|
|
/* Flags that control remote_ls processing */
|
|
|
|
#define PROCESS_FILES (1u << 0)
|
|
|
|
#define PROCESS_DIRS (1u << 1)
|
|
|
|
#define RECURSIVE (1u << 2)
|
|
|
|
|
|
|
|
/* Flags that remote_ls passes to callback functions */
|
|
|
|
#define IS_DIR (1u << 0)
|
|
|
|
|
2011-03-16 08:08:34 +01:00
|
|
|
struct remote_ls_ctx {
|
2006-03-11 05:18:08 +01:00
|
|
|
char *path;
|
|
|
|
void (*userFunc)(struct remote_ls_ctx *ls);
|
|
|
|
void *userData;
|
|
|
|
int flags;
|
|
|
|
char *dentry_name;
|
|
|
|
int dentry_flags;
|
|
|
|
struct remote_ls_ctx *parent;
|
2005-11-04 23:22:31 +01:00
|
|
|
};
|
|
|
|
|
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 03:00:22 +01:00
|
|
|
/* get_dav_token_headers options */
|
|
|
|
enum dav_header_flag {
|
|
|
|
DAV_HEADER_IF = (1u << 0),
|
|
|
|
DAV_HEADER_LOCK = (1u << 1),
|
|
|
|
DAV_HEADER_TIMEOUT = (1u << 2)
|
|
|
|
};
|
|
|
|
|
2011-05-03 17:47:28 +02:00
|
|
|
static char *xml_entities(const char *s)
|
2009-04-10 00:25:37 +02:00
|
|
|
{
|
|
|
|
struct strbuf buf = STRBUF_INIT;
|
2012-11-25 12:08:35 +01:00
|
|
|
strbuf_addstr_xml_quoted(&buf, s);
|
2009-04-10 00:25:37 +02:00
|
|
|
return strbuf_detach(&buf, NULL);
|
|
|
|
}
|
|
|
|
|
2011-05-03 17:47:29 +02:00
|
|
|
static void curl_setup_http_get(CURL *curl, const char *url,
|
|
|
|
const char *custom_req)
|
|
|
|
{
|
|
|
|
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, custom_req);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite_null);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void curl_setup_http(CURL *curl, const char *url,
|
|
|
|
const char *custom_req, struct buffer *buffer,
|
|
|
|
curl_write_callback write_fn)
|
|
|
|
{
|
|
|
|
curl_easy_setopt(curl, CURLOPT_PUT, 1);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_INFILE, buffer);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_INFILESIZE, buffer->buf.len);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);
|
|
|
|
#ifndef NO_CURL_IOCTL
|
|
|
|
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
|
2014-07-06 02:43:48 +02:00
|
|
|
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer);
|
2011-05-03 17:47:29 +02:00
|
|
|
#endif
|
|
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, custom_req);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
|
|
|
|
}
|
|
|
|
|
2009-01-25 09:04:15 +01:00
|
|
|
static struct curl_slist *get_dav_token_headers(struct remote_lock *lock, enum dav_header_flag options)
|
|
|
|
{
|
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 03:00:22 +01:00
|
|
|
struct strbuf buf = STRBUF_INIT;
|
2016-04-27 14:20:37 +02:00
|
|
|
struct curl_slist *dav_headers = http_copy_default_headers();
|
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 03:00:22 +01:00
|
|
|
|
2009-01-25 09:04:15 +01:00
|
|
|
if (options & DAV_HEADER_IF) {
|
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 03:00:22 +01:00
|
|
|
strbuf_addf(&buf, "If: (<%s>)", lock->token);
|
|
|
|
dav_headers = curl_slist_append(dav_headers, buf.buf);
|
|
|
|
strbuf_reset(&buf);
|
|
|
|
}
|
2009-01-25 09:04:15 +01:00
|
|
|
if (options & DAV_HEADER_LOCK) {
|
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 03:00:22 +01:00
|
|
|
strbuf_addf(&buf, "Lock-Token: <%s>", lock->token);
|
|
|
|
dav_headers = curl_slist_append(dav_headers, buf.buf);
|
|
|
|
strbuf_reset(&buf);
|
|
|
|
}
|
2009-01-25 09:04:15 +01:00
|
|
|
if (options & DAV_HEADER_TIMEOUT) {
|
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 03:00:22 +01:00
|
|
|
strbuf_addf(&buf, "Timeout: Second-%ld", lock->timeout);
|
|
|
|
dav_headers = curl_slist_append(dav_headers, buf.buf);
|
|
|
|
strbuf_reset(&buf);
|
|
|
|
}
|
|
|
|
strbuf_release(&buf);
|
|
|
|
|
|
|
|
return dav_headers;
|
|
|
|
}
|
|
|
|
|
2005-11-18 20:02:58 +01:00
|
|
|
static void finish_request(struct transfer_request *request);
|
2006-03-11 05:18:18 +01:00
|
|
|
static void release_request(struct transfer_request *request);
|
2005-11-02 20:19:24 +01:00
|
|
|
|
2005-11-18 20:02:58 +01:00
|
|
|
static void process_response(void *callback_data)
|
2005-11-02 20:19:24 +01:00
|
|
|
{
|
2005-11-18 20:02:58 +01:00
|
|
|
struct transfer_request *request =
|
|
|
|
(struct transfer_request *)callback_data;
|
2005-11-02 20:19:24 +01:00
|
|
|
|
2005-11-18 20:02:58 +01:00
|
|
|
finish_request(request);
|
2005-11-02 20:19:24 +01:00
|
|
|
}
|
|
|
|
|
2006-06-06 23:26:57 +02:00
|
|
|
#ifdef USE_CURL_MULTI
|
2009-02-03 07:24:40 +01:00
|
|
|
|
2006-03-11 05:18:18 +01:00
|
|
|
static void start_fetch_loose(struct transfer_request *request)
|
|
|
|
{
|
|
|
|
struct active_request_slot *slot;
|
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 10:44:02 +02:00
|
|
|
struct http_object_request *obj_req;
|
2006-03-11 05:18:18 +01:00
|
|
|
|
2019-01-07 09:34:40 +01:00
|
|
|
obj_req = new_http_object_request(repo->url, &request->obj->oid);
|
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 10:44:02 +02:00
|
|
|
if (obj_req == NULL) {
|
2006-03-11 05:18:18 +01:00
|
|
|
request->state = ABORTED;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 10:44:02 +02:00
|
|
|
slot = obj_req->slot;
|
2006-03-11 05:18:18 +01:00
|
|
|
slot->callback_func = process_response;
|
|
|
|
slot->callback_data = request;
|
|
|
|
request->slot = slot;
|
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 10:44:02 +02:00
|
|
|
request->userData = obj_req;
|
2006-03-11 05:18:18 +01:00
|
|
|
|
|
|
|
/* Try to get the request started, abort the request on error */
|
|
|
|
request->state = RUN_FETCH_LOOSE;
|
|
|
|
if (!start_active_slot(slot)) {
|
|
|
|
fprintf(stderr, "Unable to start GET request\n");
|
2009-03-19 00:43:53 +01:00
|
|
|
repo->can_update_info_refs = 0;
|
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 10:44:02 +02:00
|
|
|
release_http_object_request(obj_req);
|
2006-03-11 05:18:18 +01:00
|
|
|
release_request(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-06-06 23:26:57 +02:00
|
|
|
static void start_mkcol(struct transfer_request *request)
|
|
|
|
{
|
2015-11-10 03:22:28 +01:00
|
|
|
char *hex = oid_to_hex(&request->obj->oid);
|
2006-06-06 23:26:57 +02:00
|
|
|
struct active_request_slot *slot;
|
|
|
|
|
2009-03-19 00:43:53 +01:00
|
|
|
request->url = get_remote_object_url(repo->url, hex, 1);
|
2006-06-06 23:26:57 +02:00
|
|
|
|
|
|
|
slot = get_active_slot();
|
|
|
|
slot->callback_func = process_response;
|
|
|
|
slot->callback_data = request;
|
2011-05-03 17:47:29 +02:00
|
|
|
curl_setup_http_get(slot->curl, request->url, DAV_MKCOL);
|
2006-06-06 23:26:57 +02:00
|
|
|
curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);
|
|
|
|
|
|
|
|
if (start_active_slot(slot)) {
|
|
|
|
request->slot = slot;
|
|
|
|
request->state = RUN_MKCOL;
|
|
|
|
} else {
|
|
|
|
request->state = ABORTED;
|
2017-06-16 01:15:46 +02:00
|
|
|
FREE_AND_NULL(request->url);
|
2006-06-06 23:26:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-03-11 05:18:18 +01:00
|
|
|
static void start_fetch_packed(struct transfer_request *request)
|
|
|
|
{
|
|
|
|
struct packed_git *target;
|
|
|
|
|
|
|
|
struct transfer_request *check_request = request_queue_head;
|
2009-06-06 10:44:01 +02:00
|
|
|
struct http_pack_request *preq;
|
2006-03-11 05:18:18 +01:00
|
|
|
|
2015-11-10 03:22:29 +01:00
|
|
|
target = find_sha1_pack(request->obj->oid.hash, repo->packs);
|
2006-03-11 05:18:18 +01:00
|
|
|
if (!target) {
|
2015-11-10 03:22:28 +01:00
|
|
|
fprintf(stderr, "Unable to fetch %s, will not be able to update server info refs\n", oid_to_hex(&request->obj->oid));
|
2009-03-19 00:43:53 +01:00
|
|
|
repo->can_update_info_refs = 0;
|
2006-03-11 05:18:18 +01:00
|
|
|
release_request(request);
|
|
|
|
return;
|
|
|
|
}
|
http: refactor finish_http_pack_request()
finish_http_pack_request() does multiple tasks, including some
housekeeping on a struct packed_git - (1) closing its index, (2)
removing it from a list, and (3) installing it. These concerns are
independent of fetching a pack through HTTP: they are there only because
(1) the calling code opens the pack's index before deciding to fetch it,
(2) the calling code maintains a list of packfiles that can be fetched,
and (3) the calling code fetches it in order to make use of its objects
in the same process.
In preparation for a subsequent commit, which adds a feature that does
not need any of this housekeeping, remove (1), (2), and (3) from
finish_http_pack_request(). (2) and (3) are now done by a helper
function, and (1) is the responsibility of the caller (in this patch,
done closer to the point where the pack index is opened).
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-06-10 22:57:16 +02:00
|
|
|
close_pack_index(target);
|
|
|
|
request->target = target;
|
2006-03-11 05:18:18 +01:00
|
|
|
|
2019-02-19 01:05:03 +01:00
|
|
|
fprintf(stderr, "Fetching pack %s\n",
|
2019-02-19 01:05:11 +01:00
|
|
|
hash_to_hex(target->hash));
|
2015-11-10 03:22:28 +01:00
|
|
|
fprintf(stderr, " which contains %s\n", oid_to_hex(&request->obj->oid));
|
2006-03-11 05:18:18 +01:00
|
|
|
|
http: refactor finish_http_pack_request()
finish_http_pack_request() does multiple tasks, including some
housekeeping on a struct packed_git - (1) closing its index, (2)
removing it from a list, and (3) installing it. These concerns are
independent of fetching a pack through HTTP: they are there only because
(1) the calling code opens the pack's index before deciding to fetch it,
(2) the calling code maintains a list of packfiles that can be fetched,
and (3) the calling code fetches it in order to make use of its objects
in the same process.
In preparation for a subsequent commit, which adds a feature that does
not need any of this housekeeping, remove (1), (2), and (3) from
finish_http_pack_request(). (2) and (3) are now done by a helper
function, and (1) is the responsibility of the caller (in this patch,
done closer to the point where the pack index is opened).
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-06-10 22:57:16 +02:00
|
|
|
preq = new_http_pack_request(target->hash, repo->url);
|
2009-06-06 10:44:01 +02:00
|
|
|
if (preq == NULL) {
|
|
|
|
repo->can_update_info_refs = 0;
|
|
|
|
return;
|
|
|
|
}
|
2006-03-11 05:18:18 +01:00
|
|
|
|
|
|
|
/* Make sure there isn't another open request for this pack */
|
|
|
|
while (check_request) {
|
|
|
|
if (check_request->state == RUN_FETCH_PACKED &&
|
2009-06-06 10:44:01 +02:00
|
|
|
!strcmp(check_request->url, preq->url)) {
|
|
|
|
release_http_pack_request(preq);
|
2006-03-11 05:18:18 +01:00
|
|
|
release_request(request);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
check_request = check_request->next;
|
|
|
|
}
|
|
|
|
|
2009-06-06 10:44:01 +02:00
|
|
|
preq->slot->callback_func = process_response;
|
|
|
|
preq->slot->callback_data = request;
|
|
|
|
request->slot = preq->slot;
|
|
|
|
request->userData = preq;
|
2006-03-11 05:18:18 +01:00
|
|
|
|
|
|
|
/* Try to get the request started, abort the request on error */
|
|
|
|
request->state = RUN_FETCH_PACKED;
|
2009-06-06 10:44:01 +02:00
|
|
|
if (!start_active_slot(preq->slot)) {
|
2006-03-11 05:18:18 +01:00
|
|
|
fprintf(stderr, "Unable to start GET request\n");
|
2009-06-06 10:44:01 +02:00
|
|
|
release_http_pack_request(preq);
|
2009-03-19 00:43:53 +01:00
|
|
|
repo->can_update_info_refs = 0;
|
2006-03-11 05:18:18 +01:00
|
|
|
release_request(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-11-02 20:19:24 +01:00
|
|
|
static void start_put(struct transfer_request *request)
|
|
|
|
{
|
2015-11-10 03:22:28 +01:00
|
|
|
char *hex = oid_to_hex(&request->obj->oid);
|
2005-11-02 20:19:24 +01:00
|
|
|
struct active_request_slot *slot;
|
2009-01-31 00:51:55 +01:00
|
|
|
struct strbuf buf = STRBUF_INIT;
|
2007-02-26 20:55:59 +01:00
|
|
|
enum object_type type;
|
2005-11-02 20:19:24 +01:00
|
|
|
char hdr[50];
|
|
|
|
void *unpacked;
|
|
|
|
unsigned long len;
|
|
|
|
int hdrlen;
|
|
|
|
ssize_t size;
|
2011-06-10 20:52:15 +02:00
|
|
|
git_zstream stream;
|
2005-11-02 20:19:24 +01:00
|
|
|
|
sha1_file: convert read_sha1_file to struct object_id
Convert read_sha1_file to take a pointer to struct object_id and rename
it read_object_file. Do the same for read_sha1_file_extended.
Convert one use in grep.c to use the new function without any other code
change, since the pointer being passed is a void pointer that is already
initialized with a pointer to struct object_id. Update the declaration
and definitions of the modified functions, and apply the following
semantic patch to convert the remaining callers:
@@
expression E1, E2, E3;
@@
- read_sha1_file(E1.hash, E2, E3)
+ read_object_file(&E1, E2, E3)
@@
expression E1, E2, E3;
@@
- read_sha1_file(E1->hash, E2, E3)
+ read_object_file(E1, E2, E3)
@@
expression E1, E2, E3, E4;
@@
- read_sha1_file_extended(E1.hash, E2, E3, E4)
+ read_object_file_extended(&E1, E2, E3, E4)
@@
expression E1, E2, E3, E4;
@@
- read_sha1_file_extended(E1->hash, E2, E3, E4)
+ read_object_file_extended(E1, E2, E3, E4)
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-03-12 03:27:53 +01:00
|
|
|
unpacked = read_object_file(&request->obj->oid, &type, &len);
|
2018-11-11 08:05:04 +01:00
|
|
|
hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1;
|
2005-11-02 20:19:24 +01:00
|
|
|
|
|
|
|
/* Set it up */
|
2011-06-10 19:55:10 +02:00
|
|
|
git_deflate_init(&stream, zlib_compression_level);
|
2011-06-10 20:18:17 +02:00
|
|
|
size = git_deflate_bound(&stream, len + hdrlen);
|
2007-12-09 20:30:59 +01:00
|
|
|
strbuf_init(&request->buffer.buf, size);
|
|
|
|
request->buffer.posn = 0;
|
2005-11-02 20:19:24 +01:00
|
|
|
|
|
|
|
/* Compress it */
|
2007-12-09 20:30:59 +01:00
|
|
|
stream.next_out = (unsigned char *)request->buffer.buf.buf;
|
2005-11-02 20:19:24 +01:00
|
|
|
stream.avail_out = size;
|
|
|
|
|
|
|
|
/* First header.. */
|
|
|
|
stream.next_in = (void *)hdr;
|
|
|
|
stream.avail_in = hdrlen;
|
2011-06-10 19:55:10 +02:00
|
|
|
while (git_deflate(&stream, 0) == Z_OK)
|
|
|
|
; /* nothing */
|
2005-11-02 20:19:24 +01:00
|
|
|
|
|
|
|
/* Then the data itself.. */
|
|
|
|
stream.next_in = unpacked;
|
|
|
|
stream.avail_in = len;
|
2011-06-10 19:55:10 +02:00
|
|
|
while (git_deflate(&stream, Z_FINISH) == Z_OK)
|
|
|
|
; /* nothing */
|
|
|
|
git_deflate_end(&stream);
|
2005-11-02 20:19:24 +01:00
|
|
|
free(unpacked);
|
|
|
|
|
2007-12-09 20:30:59 +01:00
|
|
|
request->buffer.buf.len = stream.total_out;
|
2005-11-02 20:19:24 +01:00
|
|
|
|
2009-01-31 00:51:55 +01:00
|
|
|
strbuf_addstr(&buf, "Destination: ");
|
2009-03-19 00:43:53 +01:00
|
|
|
append_remote_object_url(&buf, repo->url, hex, 0);
|
2009-01-31 00:51:55 +01:00
|
|
|
request->dest = strbuf_detach(&buf, NULL);
|
|
|
|
|
2009-03-19 00:43:53 +01:00
|
|
|
append_remote_object_url(&buf, repo->url, hex, 0);
|
2019-02-19 01:05:09 +01:00
|
|
|
strbuf_add(&buf, request->lock->tmpfile_suffix, the_hash_algo->hexsz + 1);
|
2009-01-31 00:51:55 +01:00
|
|
|
request->url = strbuf_detach(&buf, NULL);
|
2005-11-02 20:19:24 +01:00
|
|
|
|
|
|
|
slot = get_active_slot();
|
2005-11-18 20:02:58 +01:00
|
|
|
slot->callback_func = process_response;
|
|
|
|
slot->callback_data = request;
|
2011-05-03 17:47:29 +02:00
|
|
|
curl_setup_http(slot->curl, request->url, DAV_PUT,
|
|
|
|
&request->buffer, fwrite_null);
|
2005-11-02 20:19:24 +01:00
|
|
|
|
|
|
|
if (start_active_slot(slot)) {
|
|
|
|
request->slot = slot;
|
|
|
|
request->state = RUN_PUT;
|
|
|
|
} else {
|
|
|
|
request->state = ABORTED;
|
2017-06-16 01:15:46 +02:00
|
|
|
FREE_AND_NULL(request->url);
|
2005-11-02 20:19:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void start_move(struct transfer_request *request)
|
|
|
|
{
|
|
|
|
struct active_request_slot *slot;
|
2016-04-27 14:20:37 +02:00
|
|
|
struct curl_slist *dav_headers = http_copy_default_headers();
|
2005-11-02 20:19:24 +01:00
|
|
|
|
|
|
|
slot = get_active_slot();
|
2005-11-18 20:02:58 +01:00
|
|
|
slot->callback_func = process_response;
|
|
|
|
slot->callback_data = request;
|
2011-05-03 17:47:29 +02:00
|
|
|
curl_setup_http_get(slot->curl, request->url, DAV_MOVE);
|
2005-11-02 20:19:24 +01:00
|
|
|
dav_headers = curl_slist_append(dav_headers, request->dest);
|
|
|
|
dav_headers = curl_slist_append(dav_headers, "Overwrite: T");
|
|
|
|
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
|
|
|
|
|
|
|
|
if (start_active_slot(slot)) {
|
|
|
|
request->slot = slot;
|
|
|
|
request->state = RUN_MOVE;
|
|
|
|
} else {
|
|
|
|
request->state = ABORTED;
|
2017-06-16 01:15:46 +02:00
|
|
|
FREE_AND_NULL(request->url);
|
2005-11-02 20:19:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-03-11 05:18:12 +01:00
|
|
|
static int refresh_lock(struct remote_lock *lock)
|
2005-11-04 23:22:35 +01:00
|
|
|
{
|
|
|
|
struct active_request_slot *slot;
|
2006-03-11 05:18:01 +01:00
|
|
|
struct slot_results results;
|
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 03:00:22 +01:00
|
|
|
struct curl_slist *dav_headers;
|
2006-03-11 05:18:12 +01:00
|
|
|
int rc = 0;
|
2005-11-04 23:22:35 +01:00
|
|
|
|
2006-03-11 05:18:12 +01:00
|
|
|
lock->refreshing = 1;
|
2005-11-04 23:22:35 +01:00
|
|
|
|
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 03:00:22 +01:00
|
|
|
dav_headers = get_dav_token_headers(lock, DAV_HEADER_IF | DAV_HEADER_TIMEOUT);
|
2005-11-04 23:22:35 +01:00
|
|
|
|
2006-03-11 05:18:12 +01:00
|
|
|
slot = get_active_slot();
|
|
|
|
slot->results = &results;
|
2011-05-03 17:47:29 +02:00
|
|
|
curl_setup_http_get(slot->curl, lock->url, DAV_LOCK);
|
2006-03-11 05:18:12 +01:00
|
|
|
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
|
2005-11-04 23:22:35 +01:00
|
|
|
|
2006-03-11 05:18:12 +01:00
|
|
|
if (start_active_slot(slot)) {
|
|
|
|
run_active_slot(slot);
|
|
|
|
if (results.curl_result != CURLE_OK) {
|
|
|
|
fprintf(stderr, "LOCK HTTP error %ld\n",
|
|
|
|
results.http_code);
|
|
|
|
} else {
|
|
|
|
lock->start_time = time(NULL);
|
|
|
|
rc = 1;
|
|
|
|
}
|
|
|
|
}
|
2006-03-08 01:13:20 +01:00
|
|
|
|
2006-03-11 05:18:12 +01:00
|
|
|
lock->refreshing = 0;
|
|
|
|
curl_slist_free_all(dav_headers);
|
2006-03-08 01:13:20 +01:00
|
|
|
|
2006-03-11 05:18:12 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2006-04-02 13:13:10 +02:00
|
|
|
static void check_locks(void)
|
2006-03-11 05:18:12 +01:00
|
|
|
{
|
2009-03-19 00:43:53 +01:00
|
|
|
struct remote_lock *lock = repo->locks;
|
2006-03-11 05:18:12 +01:00
|
|
|
time_t current_time = time(NULL);
|
|
|
|
int time_remaining;
|
|
|
|
|
|
|
|
while (lock) {
|
|
|
|
time_remaining = lock->start_time + lock->timeout -
|
|
|
|
current_time;
|
|
|
|
if (!lock->refreshing && time_remaining < LOCK_REFRESH) {
|
|
|
|
if (!refresh_lock(lock)) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"Unable to refresh lock for %s\n",
|
|
|
|
lock->url);
|
|
|
|
aborted = 1;
|
|
|
|
return;
|
2006-03-08 01:13:20 +01:00
|
|
|
}
|
2005-11-04 23:22:35 +01:00
|
|
|
}
|
2006-03-11 05:18:12 +01:00
|
|
|
lock = lock->next;
|
2005-11-04 23:22:35 +01:00
|
|
|
}
|
2006-03-08 01:13:20 +01:00
|
|
|
}
|
2005-11-04 23:22:35 +01:00
|
|
|
|
2006-03-08 01:13:20 +01:00
|
|
|
static void release_request(struct transfer_request *request)
|
|
|
|
{
|
|
|
|
struct transfer_request *entry = request_queue_head;
|
|
|
|
|
|
|
|
if (request == request_queue_head) {
|
|
|
|
request_queue_head = request->next;
|
|
|
|
} else {
|
2019-10-13 14:49:17 +02:00
|
|
|
while (entry && entry->next != request)
|
2006-03-08 01:13:20 +01:00
|
|
|
entry = entry->next;
|
2019-10-13 14:49:17 +02:00
|
|
|
if (entry)
|
|
|
|
entry->next = request->next;
|
2006-03-08 01:13:20 +01:00
|
|
|
}
|
|
|
|
|
Avoid unnecessary "if-before-free" tests.
This change removes all obvious useless if-before-free tests.
E.g., it replaces code like this:
if (some_expression)
free (some_expression);
with the now-equivalent:
free (some_expression);
It is equivalent not just because POSIX has required free(NULL)
to work for a long time, but simply because it has worked for
so long that no reasonable porting target fails the test.
Here's some evidence from nearly 1.5 years ago:
http://www.winehq.org/pipermail/wine-patches/2006-October/031544.html
FYI, the change below was prepared by running the following:
git ls-files -z | xargs -0 \
perl -0x3b -pi -e \
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*NULL)?\s*\)\s+(free\s*\(\s*\1\s*\))/$2/s'
Note however, that it doesn't handle brace-enclosed blocks like
"if (x) { free (x); }". But that's ok, since there were none like
that in git sources.
Beware: if you do use the above snippet, note that it can
produce syntactically invalid C code. That happens when the
affected "if"-statement has a matching "else".
E.g., it would transform this
if (x)
free (x);
else
foo ();
into this:
free (x);
else
foo ();
There were none of those here, either.
If you're interested in automating detection of the useless
tests, you might like the useless-if-before-free script in gnulib:
[it *does* detect brace-enclosed free statements, and has a --name=S
option to make it detect free-like functions with different names]
http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=blob;f=build-aux/useless-if-before-free
Addendum:
Remove one more (in imap-send.c), spotted by Jean-Luc Herren <jlh@gmx.ch>.
Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-31 18:26:32 +01:00
|
|
|
free(request->url);
|
2006-03-08 01:13:20 +01:00
|
|
|
free(request);
|
2005-11-04 23:22:35 +01:00
|
|
|
}
|
|
|
|
|
2005-11-02 20:19:24 +01:00
|
|
|
static void finish_request(struct transfer_request *request)
|
|
|
|
{
|
2009-06-06 10:44:01 +02:00
|
|
|
struct http_pack_request *preq;
|
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 10:44:02 +02:00
|
|
|
struct http_object_request *obj_req;
|
2006-03-11 05:18:18 +01:00
|
|
|
|
|
|
|
request->curl_result = request->slot->curl_result;
|
2005-11-02 20:19:24 +01:00
|
|
|
request->http_code = request->slot->http_code;
|
|
|
|
request->slot = NULL;
|
2005-11-04 23:22:35 +01:00
|
|
|
|
2006-03-08 01:13:20 +01:00
|
|
|
/* Keep locks active */
|
2006-03-11 05:18:12 +01:00
|
|
|
check_locks();
|
2005-11-04 23:22:35 +01:00
|
|
|
|
2005-11-02 20:19:24 +01:00
|
|
|
if (request->headers != NULL)
|
|
|
|
curl_slist_free_all(request->headers);
|
2005-11-18 20:03:25 +01:00
|
|
|
|
2019-05-14 23:11:17 +02:00
|
|
|
/* URL is reused for MOVE after PUT and used during FETCH */
|
|
|
|
if (request->state != RUN_PUT && request->state != RUN_FETCH_PACKED) {
|
2017-06-16 01:15:46 +02:00
|
|
|
FREE_AND_NULL(request->url);
|
2006-03-08 01:13:20 +01:00
|
|
|
}
|
2005-11-18 20:03:25 +01:00
|
|
|
|
2006-03-08 01:13:20 +01:00
|
|
|
if (request->state == RUN_MKCOL) {
|
2005-11-02 20:19:24 +01:00
|
|
|
if (request->curl_result == CURLE_OK ||
|
|
|
|
request->http_code == 405) {
|
2015-11-10 03:22:29 +01:00
|
|
|
remote_dir_exists[request->obj->oid.hash[0]] = 1;
|
2005-11-02 20:19:24 +01:00
|
|
|
start_put(request);
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "MKCOL %s failed, aborting (%d/%ld)\n",
|
2015-11-10 03:22:28 +01:00
|
|
|
oid_to_hex(&request->obj->oid),
|
2005-11-02 20:19:24 +01:00
|
|
|
request->curl_result, request->http_code);
|
|
|
|
request->state = ABORTED;
|
|