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