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 /** @} */