1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 module libgit2_d.sys.transport;
8 
9 
10 private static import libgit2_d.cert;
11 private static import libgit2_d.credential;
12 private static import libgit2_d.indexer;
13 private static import libgit2_d.proxy;
14 private static import libgit2_d.strarray;
15 private static import libgit2_d.sys.credential;
16 private static import libgit2_d.transport;
17 private static import libgit2_d.types;
18 
19 /**
20  * @file git2/sys/transport.h
21  * @brief Git custom transport registration interfaces and functions
22  * @defgroup git_transport Git custom transport registration
23  * @ingroup Git
24  * @{
25  */
26 
27 extern (C):
28 nothrow @nogc:
29 package(libgit2_d):
30 
31 /**
32  * Flags to pass to transport
33  *
34  * Currently unused.
35  */
36 enum git_transport_flags_t
37 {
38 	GIT_TRANSPORTFLAGS_NONE = 0,
39 }
40 
41 struct git_transport
42 {
43 	/**
44 	 * The struct version
45 	 */
46 	uint version_;
47 
48 	/**
49 	 * Set progress and error callbacks
50 	 */
51 	int function(.git_transport* transport, libgit2_d.transport.git_transport_message_cb progress_cb, libgit2_d.transport.git_transport_message_cb error_cb, libgit2_d.cert.git_transport_certificate_check_cb certificate_check_cb, void* payload) set_callbacks;
52 
53 	/**
54 	 * Set custom headers for HTTP requests
55 	 */
56 	int function(.git_transport* transport, const (libgit2_d.strarray.git_strarray)* custom_headers) set_custom_headers;
57 
58 	/**
59 	 * Connect the transport to the remote repository, using the given
60 	 * direction.
61 	 */
62 	int function(.git_transport* transport, const (char)* url, libgit2_d.credential.git_credential_acquire_cb cred_acquire_cb, void* cred_acquire_payload, const (libgit2_d.proxy.git_proxy_options)* proxy_opts, int direction, int flags) connect;
63 
64 	/**
65 	 * Get the list of available references in the remote repository.
66 	 *
67 	 * This function may be called after a successful call to
68 	 * `connect()`. The array returned is owned by the transport and
69 	 * must be kept valid until the next call to one of its functions.
70 	 */
71 	int function(const (libgit2_d.types.git_remote_head)*** out_, size_t* size, .git_transport* transport) ls;
72 
73 	/**
74 	 * Executes the push whose context is in the git_push object.
75 	 */
76 	int function(.git_transport* transport, libgit2_d.types.git_push* push, const (libgit2_d.types.git_remote_callbacks)* callbacks) push;
77 
78 	/**
79 	 * Negotiate a fetch with the remote repository.
80 	 *
81 	 * This function may be called after a successful call to `connect()`,
82 	 * when the direction is git_direction.GIT_DIRECTION_FETCH. The function performs a
83 	 * negotiation to calculate the `wants` list for the fetch.
84 	 */
85 	int function(.git_transport* transport, libgit2_d.types.git_repository* repo, const (libgit2_d.types.git_remote_head)* /+ const +/ * refs, size_t count) negotiate_fetch;
86 
87 	/**
88 	 * Start downloading the packfile from the remote repository.
89 	 *
90 	 * This function may be called after a successful call to
91 	 * negotiate_fetch(), when the direction is git_direction.GIT_DIRECTION_FETCH.
92 	 */
93 	int function(.git_transport* transport, libgit2_d.types.git_repository* repo, libgit2_d.indexer.git_indexer_progress* stats, libgit2_d.indexer.git_indexer_progress_cb progress_cb, void* progress_payload) download_pack;
94 
95 	/**
96 	 * Checks to see if the transport is connected
97 	 */
98 	int function(.git_transport* transport) is_connected;
99 
100 	/**
101 	 * Reads the flags value previously passed into connect()
102 	 */
103 	int function(.git_transport* transport, int* flags) read_flags;
104 
105 	/**
106 	 * Cancels any outstanding transport operation
107 	 */
108 	void function(.git_transport* transport) cancel;
109 
110 	/**
111 	 * Close the connection to the remote repository.
112 	 *
113 	 * This function is the reverse of connect() -- it terminates the
114 	 * connection to the remote end.
115 	 */
116 	int function(.git_transport* transport) close;
117 
118 	/**
119 	 * Frees/destructs the git_transport object.
120 	 */
121 	void function(.git_transport* transport) free;
122 }
123 
124 enum GIT_TRANSPORT_VERSION = 1;
125 
126 pragma(inline, true)
127 pure nothrow @safe @nogc
128 .git_transport GIT_TRANSPORT_INIT()
129 
130 	do
131 	{
132 		.git_transport OUTPUT =
133 		{
134 			version_: .GIT_TRANSPORT_VERSION,
135 		};
136 
137 		return OUTPUT;
138 	}
139 
140 /**
141  * Initializes a `git_transport` with default values. Equivalent to
142  * creating an instance with GIT_TRANSPORT_INIT.
143  *
144  * @param opts the `git_transport` struct to initialize
145  * @param version Version of struct; pass `GIT_TRANSPORT_VERSION`
146  * @return Zero on success; -1 on failure.
147  */
148 //GIT_EXTERN
149 int git_transport_init(.git_transport* opts, uint version_);
150 
151 /**
152  * Function to use to create a transport from a URL. The transport database
153  * is scanned to find a transport that implements the scheme of the URI (i.e.
154  * git:// or http://) and a transport object is returned to the caller.
155  *
156  * @param out_ The newly created transport (out)
157  * @param owner The git_remote which will own this transport
158  * @param url The URL to connect to
159  * @return 0 or an error code
160  */
161 //GIT_EXTERN
162 int git_transport_new(.git_transport** out_, libgit2_d.types.git_remote* owner, const (char)* url);
163 
164 /**
165  * Create an ssh transport with custom git command paths
166  *
167  * This is a factory function suitable for setting as the transport
168  * callback in a remote (or for a clone in the options).
169  *
170  * The payload argument must be a strarray pointer with the paths for
171  * the `git-upload-pack` and `git-receive-pack` at index 0 and 1.
172  *
173  * @param out_ the resulting transport
174  * @param owner the owning remote
175  * @param payload a strarray with the paths
176  * @return 0 or an error code
177  */
178 //GIT_EXTERN
179 int git_transport_ssh_with_paths(.git_transport** out_, libgit2_d.types.git_remote* owner, void* payload);
180 
181 /**
182  * Add a custom transport definition, to be used in addition to the built-in
183  * set of transports that come with libgit2.
184  *
185  * The caller is responsible for synchronizing calls to git_transport_register
186  * and git_transport_unregister with other calls to the library that
187  * instantiate transports.
188  *
189  * @param prefix The scheme (ending in "://") to match, i.e. "git://"
190  * @param cb The callback used to create an instance of the transport
191  * @param param A fixed parameter to pass to cb at creation time
192  * @return 0 or an error code
193  */
194 //GIT_EXTERN
195 int git_transport_register(const (char)* prefix, libgit2_d.transport.git_transport_cb cb, void* param);
196 
197 /**
198  * Unregister a custom transport definition which was previously registered
199  * with git_transport_register.
200  *
201  * The caller is responsible for synchronizing calls to git_transport_register
202  * and git_transport_unregister with other calls to the library that
203  * instantiate transports.
204  *
205  * @param prefix From the previous call to git_transport_register
206  * @return 0 or an error code
207  */
208 //GIT_EXTERN
209 int git_transport_unregister(const (char)* prefix);
210 
211 /*
212  * Transports which come with libgit2 (match git_transport_cb). The expected
213  * value for "param" is listed in-line below.
214  */
215 
216 /**
217  * Create an instance of the dummy transport.
218  *
219  * @param out_ The newly created transport (out)
220  * @param owner The git_remote which will own this transport
221  * @param payload You must pass null for this parameter.
222  * @return 0 or an error code
223  */
224 //GIT_EXTERN
225 int git_transport_dummy(.git_transport** out_, libgit2_d.types.git_remote* owner, /* null */ void* payload);
226 
227 /**
228  * Create an instance of the local transport.
229  *
230  * @param out_ The newly created transport (out)
231  * @param owner The git_remote which will own this transport
232  * @param payload You must pass null for this parameter.
233  * @return 0 or an error code
234  */
235 //GIT_EXTERN
236 int git_transport_local(.git_transport** out_, libgit2_d.types.git_remote* owner, /* null */ void* payload);
237 
238 /**
239  * Create an instance of the smart transport.
240  *
241  * @param out_ The newly created transport (out)
242  * @param owner The git_remote which will own this transport
243  * @param payload A pointer to a git_smart_subtransport_definition
244  * @return 0 or an error code
245  */
246 //GIT_EXTERN
247 int git_transport_smart(.git_transport** out_, libgit2_d.types.git_remote* owner, /* (git_smart_subtransport_definition *) */ void* payload);
248 
249 /**
250  * Call the certificate check for this transport.
251  *
252  * @param transport a smart transport
253  * @param cert the certificate to pass to the caller
254  * @param valid whether we believe the certificate is valid
255  * @param hostname the hostname we connected to
256  * @return the return value of the callback: 0 for no error, git_error_code.GIT_PASSTHROUGH
257  *         to indicate that there is no callback registered (or the callback
258  *         refused to validate the certificate and callers should behave as
259  *         if no callback was set), or < 0 for an error
260  */
261 //GIT_EXTERN
262 int git_transport_smart_certificate_check(.git_transport* transport, libgit2_d.types.git_cert* cert, int valid, const (char)* hostname);
263 
264 /**
265  * Call the credentials callback for this transport
266  *
267  * @param out_ the pointer where the creds are to be stored
268  * @param transport a smart transport
269  * @param user the user we saw on the url (if any)
270  * @param methods available methods for authentication
271  * @return the return value of the callback: 0 for no error, git_error_code.GIT_PASSTHROUGH
272  *         to indicate that there is no callback registered (or the callback
273  *         refused to provide credentials and callers should behave as if no
274  *         callback was set), or < 0 for an error
275  */
276 //GIT_EXTERN
277 int git_transport_smart_credentials(libgit2_d.sys.credential.git_credential** out_, .git_transport* transport, const (char)* user, int methods);
278 
279 /**
280  * Get a copy of the proxy options
281  *
282  * The url is copied and must be freed by the caller.
283  *
284  * @param out_ options struct to fill
285  * @param transport the transport to extract the data from.
286  */
287 //GIT_EXTERN
288 int git_transport_smart_proxy_options(libgit2_d.proxy.git_proxy_options* out_, .git_transport* transport);
289 
290 /*
291  *** End of base transport interface ***
292  *** Begin interface for subtransports for the smart transport ***
293  */
294 
295 /**
296  * Actions that the smart transport can ask a subtransport to perform
297  */
298 enum git_smart_service_t
299 {
300 	GIT_SERVICE_UPLOADPACK_LS = 1,
301 	GIT_SERVICE_UPLOADPACK = 2,
302 	GIT_SERVICE_RECEIVEPACK_LS = 3,
303 	GIT_SERVICE_RECEIVEPACK = 4,
304 }
305 
306 /**
307  * A stream used by the smart transport to read and write data
308  * from a subtransport.
309  *
310  * This provides a customization point in case you need to
311  * support some other communication method.
312  */
313 struct git_smart_subtransport_stream
314 {
315 	/**
316 	 * The owning subtransport
317 	 */
318 	.git_smart_subtransport* subtransport;
319 
320 	/**
321 	 * Read available data from the stream.
322 	 *
323 	 * The implementation may read less than requested.
324 	 */
325 	int function(.git_smart_subtransport_stream* stream, char* buffer, size_t buf_size, size_t* bytes_read) read;
326 
327 	/**
328 	 * Write data to the stream
329 	 *
330 	 * The implementation must write all data or return an error.
331 	 */
332 	int function(.git_smart_subtransport_stream* stream, const (char)* buffer, size_t len) write;
333 
334 	/**
335 	 * Free the stream
336 	 */
337 	void function(.git_smart_subtransport_stream* stream) free;
338 }
339 
340 /**
341  * An implementation of a subtransport which carries data for the
342  * smart transport
343  */
344 struct git_smart_subtransport
345 {
346 	/**
347 	 * Setup a subtransport stream for the requested action.
348 	 */
349 	int function(.git_smart_subtransport_stream** out_, .git_smart_subtransport* transport, const (char)* url, .git_smart_service_t action) action;
350 
351 	/**
352 	 * Close the subtransport.
353 	 *
354 	 * Subtransports are guaranteed a call to close() between
355 	 * calls to action(), except for the following two "natural" progressions
356 	 * of actions against a constant URL:
357 	 *
358 	 * - UPLOADPACK_LS -> UPLOADPACK
359 	 * - RECEIVEPACK_LS -> RECEIVEPACK
360 	 */
361 	int function(.git_smart_subtransport* transport) close;
362 
363 	/**
364 	 * Free the subtransport
365 	 */
366 	void function(.git_smart_subtransport* transport) free;
367 }
368 
369 /**
370  * A function which creates a new subtransport for the smart transport
371  */
372 alias git_smart_subtransport_cb = int function(.git_smart_subtransport** out_, .git_transport* owner, void* param);
373 
374 /**
375  * Definition for a "subtransport"
376  *
377  * The smart transport knows how to speak the git protocol, but it has no
378  * knowledge of how to establish a connection between it and another endpoint,
379  * or how to move data back and forth. For this, a subtransport interface is
380  * declared, and the smart transport delegates this work to the subtransports.
381  *
382  * Three subtransports are provided by libgit2: ssh, git, http(s).
383  *
384  * Subtransports can either be RPC = 0 (persistent connection) or RPC = 1
385  * (request/response). The smart transport handles the differences in its own
386  * logic. The git subtransport is RPC = 0, while http is RPC = 1.
387  */
388 struct git_smart_subtransport_definition
389 {
390 	/**
391 	 * The function to use to create the git_smart_subtransport
392 	 */
393 	.git_smart_subtransport_cb callback;
394 
395 	/**
396 	 * True if the protocol is stateless; false otherwise. For example,
397 	 * http:// is stateless, but git:// is not.
398 	 */
399 	uint rpc;
400 
401 	/**
402 	 * User-specified parameter passed to the callback
403 	 */
404 	void* param;
405 }
406 
407 /* Smart transport subtransports that come with libgit2 */
408 
409 /**
410  * Create an instance of the http subtransport.
411  *
412  * This subtransport also supports https.
413  *
414  * @param out_ The newly created subtransport
415  * @param owner The smart transport to own this subtransport
416  * @return 0 or an error code
417  */
418 //GIT_EXTERN
419 int git_smart_subtransport_http(.git_smart_subtransport** out_, .git_transport* owner, void* param);
420 
421 /**
422  * Create an instance of the git subtransport.
423  *
424  * @param out_ The newly created subtransport
425  * @param owner The smart transport to own this subtransport
426  * @return 0 or an error code
427  */
428 //GIT_EXTERN
429 int git_smart_subtransport_git(.git_smart_subtransport** out_, .git_transport* owner, void* param);
430 
431 /**
432  * Create an instance of the ssh subtransport.
433  *
434  * @param out_ The newly created subtransport
435  * @param owner The smart transport to own this subtransport
436  * @return 0 or an error code
437  */
438 //GIT_EXTERN
439 int git_smart_subtransport_ssh(.git_smart_subtransport** out_, .git_transport* owner, void* param);
440 
441 /** @} */