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  * Params:
145  *      opts = the `git_transport` struct to initialize
146  *      version = Version of struct; pass `GIT_TRANSPORT_VERSION`
147  *
148  * Returns: Zero on success; -1 on failure.
149  */
150 //GIT_EXTERN
151 int git_transport_init(.git_transport* opts, uint version_);
152 
153 /**
154  * Function to use to create a transport from a URL. The transport database
155  * is scanned to find a transport that implements the scheme of the URI (i.e.
156  * git:// or http://) and a transport object is returned to the caller.
157  *
158  * Params:
159  *      out_ = The newly created transport (out)
160  *      owner = The git_remote which will own this transport
161  *      url = The URL to connect to
162  *
163  * Returns: 0 or an error code
164  */
165 //GIT_EXTERN
166 int git_transport_new(.git_transport** out_, libgit2_d.types.git_remote* owner, const (char)* url);
167 
168 /**
169  * Create an ssh transport with custom git command paths
170  *
171  * This is a factory function suitable for setting as the transport
172  * callback in a remote (or for a clone in the options).
173  *
174  * The payload argument must be a strarray pointer with the paths for
175  * the `git-upload-pack` and `git-receive-pack` at index 0 and 1.
176  *
177  * Params:
178  *      out_ = the resulting transport
179  *      owner = the owning remote
180  *      payload = a strarray with the paths
181  *
182  * Returns: 0 or an error code
183  */
184 //GIT_EXTERN
185 int git_transport_ssh_with_paths(.git_transport** out_, libgit2_d.types.git_remote* owner, void* payload);
186 
187 /**
188  * Add a custom transport definition, to be used in addition to the built-in
189  * set of transports that come with libgit2.
190  *
191  * The caller is responsible for synchronizing calls to git_transport_register
192  * and git_transport_unregister with other calls to the library that
193  * instantiate transports.
194  *
195  * Params:
196  *      prefix = The scheme (ending in "://") to match, i.e. "git://"
197  *      cb = The callback used to create an instance of the transport
198  *      param = A fixed parameter to pass to cb at creation time
199  *
200  * Returns: 0 or an error code
201  */
202 //GIT_EXTERN
203 int git_transport_register(const (char)* prefix, libgit2_d.transport.git_transport_cb cb, void* param);
204 
205 /**
206  * Unregister a custom transport definition which was previously registered
207  * with git_transport_register.
208  *
209  * The caller is responsible for synchronizing calls to git_transport_register
210  * and git_transport_unregister with other calls to the library that
211  * instantiate transports.
212  *
213  * Params:
214  *      prefix = From the previous call to git_transport_register
215  *
216  * Returns: 0 or an error code
217  */
218 //GIT_EXTERN
219 int git_transport_unregister(const (char)* prefix);
220 
221 /*
222  * Transports which come with libgit2 (match git_transport_cb). The expected
223  * value for "param" is listed in-line below.
224  */
225 
226 /**
227  * Create an instance of the dummy transport.
228  *
229  * Params:
230  *      out_ = The newly created transport (out)
231  *      owner = The git_remote which will own this transport
232  *      payload = You must pass null for this parameter.
233  *
234  * Returns: 0 or an error code
235  */
236 //GIT_EXTERN
237 int git_transport_dummy(.git_transport** out_, libgit2_d.types.git_remote* owner, /* null */ void* payload);
238 
239 /**
240  * Create an instance of the local transport.
241  *
242  * Params:
243  *      out_ = The newly created transport (out)
244  *      owner = The git_remote which will own this transport
245  *      payload = You must pass null for this parameter.
246  *
247  * Returns: 0 or an error code
248  */
249 //GIT_EXTERN
250 int git_transport_local(.git_transport** out_, libgit2_d.types.git_remote* owner, /* null */ void* payload);
251 
252 /**
253  * Create an instance of the smart transport.
254  *
255  * Params:
256  *      out_ = The newly created transport (out)
257  *      owner = The git_remote which will own this transport
258  *      payload = A pointer to a git_smart_subtransport_definition
259  *
260  * Returns: 0 or an error code
261  */
262 //GIT_EXTERN
263 int git_transport_smart(.git_transport** out_, libgit2_d.types.git_remote* owner, /* (git_smart_subtransport_definition *) */ void* payload);
264 
265 /**
266  * Call the certificate check for this transport.
267  *
268  * Params:
269  *      transport = a smart transport
270  *      cert = the certificate to pass to the caller
271  *      valid = whether we believe the certificate is valid
272  *      hostname = the hostname we connected to
273  *
274  * 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
275  */
276 //GIT_EXTERN
277 int git_transport_smart_certificate_check(.git_transport* transport, libgit2_d.types.git_cert* cert, int valid, const (char)* hostname);
278 
279 /**
280  * Call the credentials callback for this transport
281  *
282  * Params:
283  *      out_ = the pointer where the creds are to be stored
284  *      transport = a smart transport
285  *      user = the user we saw on the url (if any)
286  *      methods = available methods for authentication
287  *
288  * 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
289  */
290 //GIT_EXTERN
291 int git_transport_smart_credentials(libgit2_d.sys.credential.git_credential** out_, .git_transport* transport, const (char)* user, int methods);
292 
293 /**
294  * Get a copy of the proxy options
295  *
296  * The url is copied and must be freed by the caller.
297  *
298  * Params:
299  *      out_ = options struct to fill
300  *      transport = the transport to extract the data from.
301  */
302 //GIT_EXTERN
303 int git_transport_smart_proxy_options(libgit2_d.proxy.git_proxy_options* out_, .git_transport* transport);
304 
305 /*
306  *** End of base transport interface ***
307  *** Begin interface for subtransports for the smart transport ***
308  */
309 
310 /**
311  * Actions that the smart transport can ask a subtransport to perform
312  */
313 enum git_smart_service_t
314 {
315 	GIT_SERVICE_UPLOADPACK_LS = 1,
316 	GIT_SERVICE_UPLOADPACK = 2,
317 	GIT_SERVICE_RECEIVEPACK_LS = 3,
318 	GIT_SERVICE_RECEIVEPACK = 4,
319 }
320 
321 /**
322  * A stream used by the smart transport to read and write data
323  * from a subtransport.
324  *
325  * This provides a customization point in case you need to
326  * support some other communication method.
327  */
328 struct git_smart_subtransport_stream
329 {
330 	/**
331 	 * The owning subtransport
332 	 */
333 	.git_smart_subtransport* subtransport;
334 
335 	/**
336 	 * Read available data from the stream.
337 	 *
338 	 * The implementation may read less than requested.
339 	 */
340 	int function(.git_smart_subtransport_stream* stream, char* buffer, size_t buf_size, size_t* bytes_read) read;
341 
342 	/**
343 	 * Write data to the stream
344 	 *
345 	 * The implementation must write all data or return an error.
346 	 */
347 	int function(.git_smart_subtransport_stream* stream, const (char)* buffer, size_t len) write;
348 
349 	/**
350 	 * Free the stream
351 	 */
352 	void function(.git_smart_subtransport_stream* stream) free;
353 }
354 
355 /**
356  * An implementation of a subtransport which carries data for the
357  * smart transport
358  */
359 struct git_smart_subtransport
360 {
361 	/**
362 	 * Setup a subtransport stream for the requested action.
363 	 */
364 	int function(.git_smart_subtransport_stream** out_, .git_smart_subtransport* transport, const (char)* url, .git_smart_service_t action) action;
365 
366 	/**
367 	 * Close the subtransport.
368 	 *
369 	 * Subtransports are guaranteed a call to close() between
370 	 * calls to action(), except for the following two "natural" progressions
371 	 * of actions against a constant URL:
372 	 *
373 	 * - UPLOADPACK_LS -> UPLOADPACK
374 	 * - RECEIVEPACK_LS -> RECEIVEPACK
375 	 */
376 	int function(.git_smart_subtransport* transport) close;
377 
378 	/**
379 	 * Free the subtransport
380 	 */
381 	void function(.git_smart_subtransport* transport) free;
382 }
383 
384 /**
385  * A function which creates a new subtransport for the smart transport
386  */
387 alias git_smart_subtransport_cb = int function(.git_smart_subtransport** out_, .git_transport* owner, void* param);
388 
389 /**
390  * Definition for a "subtransport"
391  *
392  * The smart transport knows how to speak the git protocol, but it has no
393  * knowledge of how to establish a connection between it and another endpoint,
394  * or how to move data back and forth. For this, a subtransport interface is
395  * declared, and the smart transport delegates this work to the subtransports.
396  *
397  * Three subtransports are provided by libgit2: ssh, git, http(s).
398  *
399  * Subtransports can either be RPC = 0 (persistent connection) or RPC = 1
400  * (request/response). The smart transport handles the differences in its own
401  * logic. The git subtransport is RPC = 0, while http is RPC = 1.
402  */
403 struct git_smart_subtransport_definition
404 {
405 	/**
406 	 * The function to use to create the git_smart_subtransport
407 	 */
408 	.git_smart_subtransport_cb callback;
409 
410 	/**
411 	 * True if the protocol is stateless; false otherwise. For example,
412 	 * http:// is stateless, but git:// is not.
413 	 */
414 	uint rpc;
415 
416 	/**
417 	 * User-specified parameter passed to the callback
418 	 */
419 	void* param;
420 }
421 
422 /* Smart transport subtransports that come with libgit2 */
423 
424 /**
425  * Create an instance of the http subtransport.
426  *
427  * This subtransport also supports https.
428  *
429  * Params:
430  *      out_ = The newly created subtransport
431  *      owner = The smart transport to own this subtransport
432  *
433  * Returns: 0 or an error code
434  */
435 //GIT_EXTERN
436 int git_smart_subtransport_http(.git_smart_subtransport** out_, .git_transport* owner, void* param);
437 
438 /**
439  * Create an instance of the git subtransport.
440  *
441  * Params:
442  *      out_ = The newly created subtransport
443  *      owner = The smart transport to own this subtransport
444  *
445  * Returns: 0 or an error code
446  */
447 //GIT_EXTERN
448 int git_smart_subtransport_git(.git_smart_subtransport** out_, .git_transport* owner, void* param);
449 
450 /**
451  * Create an instance of the ssh subtransport.
452  *
453  * Params:
454  *      out_ = The newly created subtransport
455  *      owner = The smart transport to own this subtransport
456  *
457  * Returns: 0 or an error code
458  */
459 //GIT_EXTERN
460 int git_smart_subtransport_ssh(.git_smart_subtransport** out_, .git_transport* owner, void* param);
461 
462 /** @} */