rugged 0.27.9 → 0.27.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (420) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/AUTHORS +1 -0
  4. data/vendor/libgit2/CMakeLists.txt +98 -54
  5. data/vendor/libgit2/COPYING +28 -0
  6. data/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake +15 -1
  7. data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +9 -8
  8. data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +2 -2
  9. data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +1 -1
  10. data/vendor/libgit2/cmake/Modules/FindGSSFramework.cmake +28 -0
  11. data/vendor/libgit2/cmake/Modules/FindPCRE.cmake +38 -0
  12. data/vendor/libgit2/cmake/Modules/FindPCRE2.cmake +37 -0
  13. data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +2 -2
  14. data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +6 -0
  15. data/vendor/libgit2/cmake/Modules/FindmbedTLS.cmake +93 -0
  16. data/vendor/libgit2/cmake/Modules/PkgBuildConfig.cmake +110 -0
  17. data/vendor/libgit2/cmake/Modules/SelectGSSAPI.cmake +53 -0
  18. data/vendor/libgit2/cmake/Modules/SelectHTTPSBackend.cmake +124 -0
  19. data/vendor/libgit2/cmake/Modules/SelectHashes.cmake +66 -0
  20. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +2 -0
  21. data/vendor/libgit2/deps/http-parser/{LICENSE-MIT → COPYING} +0 -0
  22. data/vendor/libgit2/deps/http-parser/http_parser.c +11 -6
  23. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +21 -0
  24. data/vendor/libgit2/deps/ntlmclient/compat.h +33 -0
  25. data/vendor/libgit2/deps/ntlmclient/crypt.h +64 -0
  26. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +120 -0
  27. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +18 -0
  28. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +145 -0
  29. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +18 -0
  30. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +130 -0
  31. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +21 -0
  32. data/vendor/libgit2/deps/ntlmclient/ntlm.c +1420 -0
  33. data/vendor/libgit2/deps/ntlmclient/ntlm.h +174 -0
  34. data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +320 -0
  35. data/vendor/libgit2/deps/ntlmclient/unicode.h +36 -0
  36. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +445 -0
  37. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +201 -0
  38. data/vendor/libgit2/deps/ntlmclient/utf8.h +1257 -0
  39. data/vendor/libgit2/deps/ntlmclient/util.c +21 -0
  40. data/vendor/libgit2/deps/ntlmclient/util.h +14 -0
  41. data/vendor/libgit2/deps/pcre/CMakeLists.txt +140 -0
  42. data/vendor/libgit2/deps/pcre/COPYING +5 -0
  43. data/vendor/libgit2/deps/pcre/cmake/COPYING-CMAKE-SCRIPTS +22 -0
  44. data/vendor/libgit2/deps/pcre/cmake/FindEditline.cmake +17 -0
  45. data/vendor/libgit2/deps/pcre/cmake/FindPackageHandleStandardArgs.cmake +58 -0
  46. data/vendor/libgit2/deps/pcre/cmake/FindReadline.cmake +29 -0
  47. data/vendor/libgit2/deps/pcre/config.h.in +57 -0
  48. data/vendor/libgit2/deps/pcre/pcre.h +641 -0
  49. data/vendor/libgit2/deps/pcre/pcre_byte_order.c +319 -0
  50. data/vendor/libgit2/deps/pcre/pcre_chartables.c +198 -0
  51. data/vendor/libgit2/deps/pcre/pcre_compile.c +9800 -0
  52. data/vendor/libgit2/deps/pcre/pcre_config.c +190 -0
  53. data/vendor/libgit2/deps/pcre/pcre_dfa_exec.c +3676 -0
  54. data/vendor/libgit2/deps/pcre/pcre_exec.c +7173 -0
  55. data/vendor/libgit2/deps/pcre/pcre_fullinfo.c +245 -0
  56. data/vendor/libgit2/deps/pcre/pcre_get.c +669 -0
  57. data/vendor/libgit2/deps/pcre/pcre_globals.c +86 -0
  58. data/vendor/libgit2/deps/pcre/pcre_internal.h +2787 -0
  59. data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +11913 -0
  60. data/vendor/libgit2/deps/pcre/pcre_maketables.c +156 -0
  61. data/vendor/libgit2/deps/pcre/pcre_newline.c +210 -0
  62. data/vendor/libgit2/deps/pcre/pcre_ord2utf8.c +94 -0
  63. data/vendor/libgit2/deps/pcre/pcre_printint.c +834 -0
  64. data/vendor/libgit2/deps/pcre/pcre_refcount.c +92 -0
  65. data/vendor/libgit2/deps/pcre/pcre_string_utils.c +211 -0
  66. data/vendor/libgit2/deps/pcre/pcre_study.c +1686 -0
  67. data/vendor/libgit2/deps/pcre/pcre_tables.c +727 -0
  68. data/vendor/libgit2/deps/pcre/pcre_ucd.c +3644 -0
  69. data/vendor/libgit2/deps/pcre/pcre_valid_utf8.c +301 -0
  70. data/vendor/libgit2/deps/pcre/pcre_version.c +98 -0
  71. data/vendor/libgit2/deps/pcre/pcre_xclass.c +268 -0
  72. data/vendor/libgit2/deps/pcre/pcreposix.c +421 -0
  73. data/vendor/libgit2/deps/pcre/pcreposix.h +117 -0
  74. data/vendor/libgit2/deps/pcre/ucp.h +224 -0
  75. data/vendor/libgit2/deps/winhttp/COPYING.GPL +993 -0
  76. data/vendor/libgit2/deps/winhttp/COPYING.LGPL +502 -0
  77. data/vendor/libgit2/deps/zlib/CMakeLists.txt +1 -0
  78. data/vendor/libgit2/deps/zlib/COPYING +27 -0
  79. data/vendor/libgit2/deps/zlib/adler32.c +0 -7
  80. data/vendor/libgit2/deps/zlib/crc32.c +0 -7
  81. data/vendor/libgit2/include/git2.h +5 -0
  82. data/vendor/libgit2/include/git2/annotated_commit.h +9 -0
  83. data/vendor/libgit2/include/git2/apply.h +149 -0
  84. data/vendor/libgit2/include/git2/attr.h +38 -20
  85. data/vendor/libgit2/include/git2/blame.h +42 -25
  86. data/vendor/libgit2/include/git2/blob.h +45 -13
  87. data/vendor/libgit2/include/git2/branch.h +1 -1
  88. data/vendor/libgit2/include/git2/buffer.h +22 -16
  89. data/vendor/libgit2/include/git2/cert.h +135 -0
  90. data/vendor/libgit2/include/git2/checkout.h +65 -32
  91. data/vendor/libgit2/include/git2/cherrypick.h +9 -7
  92. data/vendor/libgit2/include/git2/clone.h +12 -10
  93. data/vendor/libgit2/include/git2/commit.h +53 -3
  94. data/vendor/libgit2/include/git2/common.h +60 -8
  95. data/vendor/libgit2/include/git2/config.h +30 -19
  96. data/vendor/libgit2/include/git2/cred.h +308 -0
  97. data/vendor/libgit2/include/git2/deprecated.h +493 -0
  98. data/vendor/libgit2/include/git2/describe.h +32 -9
  99. data/vendor/libgit2/include/git2/diff.h +208 -156
  100. data/vendor/libgit2/include/git2/errors.h +54 -46
  101. data/vendor/libgit2/include/git2/filter.h +8 -0
  102. data/vendor/libgit2/include/git2/ignore.h +2 -2
  103. data/vendor/libgit2/include/git2/index.h +74 -52
  104. data/vendor/libgit2/include/git2/indexer.h +76 -6
  105. data/vendor/libgit2/include/git2/mailmap.h +115 -0
  106. data/vendor/libgit2/include/git2/merge.h +35 -18
  107. data/vendor/libgit2/include/git2/net.h +0 -5
  108. data/vendor/libgit2/include/git2/notes.h +1 -1
  109. data/vendor/libgit2/include/git2/object.h +17 -29
  110. data/vendor/libgit2/include/git2/odb.h +12 -11
  111. data/vendor/libgit2/include/git2/odb_backend.h +10 -9
  112. data/vendor/libgit2/include/git2/oid.h +2 -2
  113. data/vendor/libgit2/include/git2/pack.h +14 -3
  114. data/vendor/libgit2/include/git2/proxy.h +14 -8
  115. data/vendor/libgit2/include/git2/rebase.h +53 -6
  116. data/vendor/libgit2/include/git2/refs.h +33 -15
  117. data/vendor/libgit2/include/git2/refspec.h +17 -0
  118. data/vendor/libgit2/include/git2/remote.h +123 -24
  119. data/vendor/libgit2/include/git2/repository.h +76 -39
  120. data/vendor/libgit2/include/git2/revert.h +6 -4
  121. data/vendor/libgit2/include/git2/revwalk.h +7 -7
  122. data/vendor/libgit2/include/git2/signature.h +2 -2
  123. data/vendor/libgit2/include/git2/stash.h +15 -12
  124. data/vendor/libgit2/include/git2/status.h +33 -20
  125. data/vendor/libgit2/include/git2/submodule.h +30 -12
  126. data/vendor/libgit2/include/git2/sys/alloc.h +101 -0
  127. data/vendor/libgit2/include/git2/sys/commit.h +1 -1
  128. data/vendor/libgit2/include/git2/sys/config.h +13 -13
  129. data/vendor/libgit2/include/git2/sys/cred.h +90 -0
  130. data/vendor/libgit2/include/git2/sys/filter.h +6 -6
  131. data/vendor/libgit2/include/git2/sys/index.h +3 -0
  132. data/vendor/libgit2/include/git2/sys/mempack.h +35 -35
  133. data/vendor/libgit2/include/git2/sys/merge.h +9 -4
  134. data/vendor/libgit2/include/git2/sys/odb_backend.h +66 -22
  135. data/vendor/libgit2/include/git2/sys/path.h +64 -0
  136. data/vendor/libgit2/include/git2/sys/refdb_backend.h +76 -40
  137. data/vendor/libgit2/include/git2/sys/repository.h +5 -1
  138. data/vendor/libgit2/include/git2/sys/stream.h +92 -12
  139. data/vendor/libgit2/include/git2/sys/transport.h +129 -83
  140. data/vendor/libgit2/include/git2/tag.h +13 -4
  141. data/vendor/libgit2/include/git2/trace.h +2 -2
  142. data/vendor/libgit2/include/git2/transaction.h +1 -0
  143. data/vendor/libgit2/include/git2/transport.h +11 -311
  144. data/vendor/libgit2/include/git2/tree.h +4 -4
  145. data/vendor/libgit2/include/git2/types.h +33 -111
  146. data/vendor/libgit2/include/git2/version.h +4 -4
  147. data/vendor/libgit2/include/git2/worktree.h +48 -13
  148. data/vendor/libgit2/src/CMakeLists.txt +96 -164
  149. data/vendor/libgit2/src/alloc.c +43 -0
  150. data/vendor/libgit2/src/alloc.h +40 -0
  151. data/vendor/libgit2/src/allocators/stdalloc.c +119 -0
  152. data/vendor/libgit2/src/{streams/curl.h → allocators/stdalloc.h} +5 -5
  153. data/vendor/libgit2/src/allocators/win32_crtdbg.c +118 -0
  154. data/vendor/libgit2/src/{transports/cred.h → allocators/win32_crtdbg.h} +5 -4
  155. data/vendor/libgit2/src/annotated_commit.c +15 -8
  156. data/vendor/libgit2/src/apply.c +537 -31
  157. data/vendor/libgit2/src/apply.h +3 -1
  158. data/vendor/libgit2/src/array.h +2 -2
  159. data/vendor/libgit2/src/attr.c +81 -75
  160. data/vendor/libgit2/src/attr_file.c +207 -121
  161. data/vendor/libgit2/src/attr_file.h +9 -9
  162. data/vendor/libgit2/src/attrcache.c +51 -53
  163. data/vendor/libgit2/src/attrcache.h +2 -1
  164. data/vendor/libgit2/src/blame.c +47 -20
  165. data/vendor/libgit2/src/blame.h +2 -1
  166. data/vendor/libgit2/src/blame_git.c +37 -20
  167. data/vendor/libgit2/src/blob.c +128 -42
  168. data/vendor/libgit2/src/blob.h +19 -2
  169. data/vendor/libgit2/src/branch.c +67 -43
  170. data/vendor/libgit2/src/buf_text.c +7 -6
  171. data/vendor/libgit2/src/buffer.c +69 -57
  172. data/vendor/libgit2/src/buffer.h +1 -1
  173. data/vendor/libgit2/src/cache.c +38 -45
  174. data/vendor/libgit2/src/cache.h +3 -3
  175. data/vendor/libgit2/src/cc-compat.h +20 -3
  176. data/vendor/libgit2/src/checkout.c +109 -90
  177. data/vendor/libgit2/src/cherrypick.c +15 -9
  178. data/vendor/libgit2/src/clone.c +49 -27
  179. data/vendor/libgit2/src/clone.h +4 -0
  180. data/vendor/libgit2/src/commit.c +117 -49
  181. data/vendor/libgit2/src/commit.h +7 -0
  182. data/vendor/libgit2/src/commit_list.c +30 -78
  183. data/vendor/libgit2/src/commit_list.h +2 -2
  184. data/vendor/libgit2/src/common.h +27 -91
  185. data/vendor/libgit2/src/config.c +194 -176
  186. data/vendor/libgit2/src/config.h +8 -20
  187. data/vendor/libgit2/src/config_backend.h +96 -0
  188. data/vendor/libgit2/src/config_cache.c +41 -35
  189. data/vendor/libgit2/src/config_entries.c +229 -0
  190. data/vendor/libgit2/src/config_entries.h +24 -0
  191. data/vendor/libgit2/src/config_file.c +439 -753
  192. data/vendor/libgit2/src/config_mem.c +220 -0
  193. data/vendor/libgit2/src/config_parse.c +114 -63
  194. data/vendor/libgit2/src/config_parse.h +17 -16
  195. data/vendor/libgit2/src/config_snapshot.c +206 -0
  196. data/vendor/libgit2/src/crlf.c +219 -190
  197. data/vendor/libgit2/src/delta.c +25 -18
  198. data/vendor/libgit2/src/describe.c +42 -41
  199. data/vendor/libgit2/src/diff.c +53 -68
  200. data/vendor/libgit2/src/diff.h +2 -1
  201. data/vendor/libgit2/src/diff_driver.c +47 -49
  202. data/vendor/libgit2/src/diff_file.c +19 -17
  203. data/vendor/libgit2/src/diff_file.h +1 -1
  204. data/vendor/libgit2/src/diff_generate.c +162 -106
  205. data/vendor/libgit2/src/diff_generate.h +3 -3
  206. data/vendor/libgit2/src/diff_parse.c +4 -4
  207. data/vendor/libgit2/src/diff_print.c +42 -30
  208. data/vendor/libgit2/src/diff_stats.c +22 -7
  209. data/vendor/libgit2/src/diff_tform.c +16 -16
  210. data/vendor/libgit2/src/diff_xdiff.c +15 -3
  211. data/vendor/libgit2/src/errors.c +51 -39
  212. data/vendor/libgit2/src/errors.h +81 -0
  213. data/vendor/libgit2/src/features.h.in +11 -3
  214. data/vendor/libgit2/src/fetch.c +10 -5
  215. data/vendor/libgit2/src/fetchhead.c +17 -17
  216. data/vendor/libgit2/src/filebuf.c +32 -36
  217. data/vendor/libgit2/src/filebuf.h +2 -2
  218. data/vendor/libgit2/src/filter.c +46 -38
  219. data/vendor/libgit2/src/filter.h +0 -10
  220. data/vendor/libgit2/src/{fileops.c → futils.c} +80 -73
  221. data/vendor/libgit2/src/{fileops.h → futils.h} +6 -6
  222. data/vendor/libgit2/src/global.c +48 -63
  223. data/vendor/libgit2/src/global.h +0 -2
  224. data/vendor/libgit2/src/hash.c +61 -0
  225. data/vendor/libgit2/src/hash.h +20 -19
  226. data/vendor/libgit2/src/hash/sha1.h +38 -0
  227. data/vendor/libgit2/src/hash/sha1/collisiondetect.c +48 -0
  228. data/vendor/libgit2/src/hash/sha1/collisiondetect.h +19 -0
  229. data/vendor/libgit2/src/hash/{hash_common_crypto.h → sha1/common_crypto.c} +17 -17
  230. data/vendor/libgit2/src/hash/sha1/common_crypto.h +19 -0
  231. data/vendor/libgit2/src/hash/{hash_generic.c → sha1/generic.c} +22 -10
  232. data/vendor/libgit2/src/hash/{hash_generic.h → sha1/generic.h} +4 -10
  233. data/vendor/libgit2/src/hash/sha1/mbedtls.c +46 -0
  234. data/vendor/libgit2/src/hash/sha1/mbedtls.h +19 -0
  235. data/vendor/libgit2/src/hash/sha1/openssl.c +59 -0
  236. data/vendor/libgit2/src/hash/sha1/openssl.h +19 -0
  237. data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/sha1.c +14 -3
  238. data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/sha1.h +0 -0
  239. data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/ubc_check.c +0 -0
  240. data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/ubc_check.h +0 -0
  241. data/vendor/libgit2/src/hash/{hash_win32.c → sha1/win32.c} +47 -37
  242. data/vendor/libgit2/src/hash/{hash_win32.h → sha1/win32.h} +6 -19
  243. data/vendor/libgit2/src/hashsig.c +5 -5
  244. data/vendor/libgit2/src/idxmap.c +107 -61
  245. data/vendor/libgit2/src/idxmap.h +153 -31
  246. data/vendor/libgit2/src/ignore.c +43 -47
  247. data/vendor/libgit2/src/index.c +337 -232
  248. data/vendor/libgit2/src/index.h +17 -1
  249. data/vendor/libgit2/src/indexer.c +346 -175
  250. data/vendor/libgit2/src/integer.h +71 -26
  251. data/vendor/libgit2/src/iterator.c +142 -70
  252. data/vendor/libgit2/src/iterator.h +15 -0
  253. data/vendor/libgit2/src/khash.h +3 -1
  254. data/vendor/libgit2/src/mailmap.c +485 -0
  255. data/vendor/libgit2/src/mailmap.h +35 -0
  256. data/vendor/libgit2/src/map.h +1 -1
  257. data/vendor/libgit2/src/merge.c +144 -100
  258. data/vendor/libgit2/src/merge_driver.c +11 -11
  259. data/vendor/libgit2/src/merge_file.c +2 -2
  260. data/vendor/libgit2/src/mwindow.c +24 -29
  261. data/vendor/libgit2/src/mwindow.h +4 -4
  262. data/vendor/libgit2/src/net.c +184 -0
  263. data/vendor/libgit2/src/net.h +36 -0
  264. data/vendor/libgit2/src/netops.c +55 -156
  265. data/vendor/libgit2/src/netops.h +3 -23
  266. data/vendor/libgit2/src/notes.c +16 -11
  267. data/vendor/libgit2/src/object.c +120 -69
  268. data/vendor/libgit2/src/object.h +22 -9
  269. data/vendor/libgit2/src/object_api.c +8 -8
  270. data/vendor/libgit2/src/odb.c +116 -93
  271. data/vendor/libgit2/src/odb.h +8 -7
  272. data/vendor/libgit2/src/odb_loose.c +62 -55
  273. data/vendor/libgit2/src/odb_mempack.c +21 -34
  274. data/vendor/libgit2/src/odb_pack.c +18 -14
  275. data/vendor/libgit2/src/offmap.c +53 -35
  276. data/vendor/libgit2/src/offmap.h +108 -21
  277. data/vendor/libgit2/src/oid.c +12 -7
  278. data/vendor/libgit2/src/oidmap.c +49 -47
  279. data/vendor/libgit2/src/oidmap.h +101 -24
  280. data/vendor/libgit2/src/pack-objects.c +88 -87
  281. data/vendor/libgit2/src/pack-objects.h +2 -8
  282. data/vendor/libgit2/src/pack.c +99 -101
  283. data/vendor/libgit2/src/pack.h +17 -19
  284. data/vendor/libgit2/src/parse.c +10 -0
  285. data/vendor/libgit2/src/parse.h +3 -3
  286. data/vendor/libgit2/src/patch.c +4 -4
  287. data/vendor/libgit2/src/patch_generate.c +20 -20
  288. data/vendor/libgit2/src/patch_parse.c +151 -63
  289. data/vendor/libgit2/src/path.c +169 -125
  290. data/vendor/libgit2/src/path.h +3 -71
  291. data/vendor/libgit2/src/pathspec.c +19 -19
  292. data/vendor/libgit2/src/pool.c +26 -22
  293. data/vendor/libgit2/src/pool.h +7 -7
  294. data/vendor/libgit2/src/posix.c +10 -10
  295. data/vendor/libgit2/src/posix.h +12 -1
  296. data/vendor/libgit2/src/proxy.c +8 -3
  297. data/vendor/libgit2/src/push.c +37 -31
  298. data/vendor/libgit2/src/push.h +2 -1
  299. data/vendor/libgit2/src/reader.c +265 -0
  300. data/vendor/libgit2/src/reader.h +107 -0
  301. data/vendor/libgit2/src/rebase.c +115 -59
  302. data/vendor/libgit2/src/refdb.c +15 -3
  303. data/vendor/libgit2/src/refdb_fs.c +381 -254
  304. data/vendor/libgit2/src/reflog.c +13 -15
  305. data/vendor/libgit2/src/refs.c +118 -88
  306. data/vendor/libgit2/src/refs.h +5 -3
  307. data/vendor/libgit2/src/refspec.c +56 -37
  308. data/vendor/libgit2/src/refspec.h +1 -1
  309. data/vendor/libgit2/src/regexp.c +221 -0
  310. data/vendor/libgit2/src/regexp.h +97 -0
  311. data/vendor/libgit2/src/remote.c +266 -215
  312. data/vendor/libgit2/src/remote.h +11 -2
  313. data/vendor/libgit2/src/repository.c +280 -225
  314. data/vendor/libgit2/src/repository.h +52 -40
  315. data/vendor/libgit2/src/reset.c +8 -8
  316. data/vendor/libgit2/src/revert.c +14 -9
  317. data/vendor/libgit2/src/revparse.c +47 -48
  318. data/vendor/libgit2/src/revwalk.c +120 -57
  319. data/vendor/libgit2/src/revwalk.h +22 -1
  320. data/vendor/libgit2/src/settings.c +47 -10
  321. data/vendor/libgit2/src/signature.c +11 -11
  322. data/vendor/libgit2/src/sortedcache.c +22 -36
  323. data/vendor/libgit2/src/sortedcache.h +1 -1
  324. data/vendor/libgit2/src/stash.c +125 -99
  325. data/vendor/libgit2/src/status.c +28 -22
  326. data/vendor/libgit2/src/stream.h +17 -2
  327. data/vendor/libgit2/src/streams/mbedtls.c +483 -0
  328. data/vendor/libgit2/src/streams/mbedtls.h +23 -0
  329. data/vendor/libgit2/src/streams/openssl.c +224 -114
  330. data/vendor/libgit2/src/streams/openssl.h +4 -108
  331. data/vendor/libgit2/src/streams/registry.c +118 -0
  332. data/vendor/libgit2/src/streams/registry.h +19 -0
  333. data/vendor/libgit2/src/streams/socket.c +55 -30
  334. data/vendor/libgit2/src/streams/stransport.c +57 -32
  335. data/vendor/libgit2/src/streams/stransport.h +5 -0
  336. data/vendor/libgit2/src/streams/tls.c +50 -19
  337. data/vendor/libgit2/src/streams/tls.h +12 -4
  338. data/vendor/libgit2/src/strmap.c +47 -74
  339. data/vendor/libgit2/src/strmap.h +108 -33
  340. data/vendor/libgit2/src/submodule.c +272 -216
  341. data/vendor/libgit2/src/submodule.h +1 -1
  342. data/vendor/libgit2/src/sysdir.c +29 -19
  343. data/vendor/libgit2/src/tag.c +41 -28
  344. data/vendor/libgit2/src/tag.h +2 -1
  345. data/vendor/libgit2/src/trace.c +2 -2
  346. data/vendor/libgit2/src/trace.h +3 -3
  347. data/vendor/libgit2/src/trailer.c +52 -38
  348. data/vendor/libgit2/src/transaction.c +30 -29
  349. data/vendor/libgit2/src/transport.c +5 -5
  350. data/vendor/libgit2/src/transports/auth.c +15 -11
  351. data/vendor/libgit2/src/transports/auth.h +10 -3
  352. data/vendor/libgit2/src/transports/auth_negotiate.c +33 -18
  353. data/vendor/libgit2/src/transports/auth_negotiate.h +2 -2
  354. data/vendor/libgit2/src/transports/auth_ntlm.c +223 -0
  355. data/vendor/libgit2/src/transports/auth_ntlm.h +35 -0
  356. data/vendor/libgit2/src/transports/cred.c +24 -24
  357. data/vendor/libgit2/src/transports/git.c +26 -31
  358. data/vendor/libgit2/src/transports/http.c +881 -348
  359. data/vendor/libgit2/src/transports/http.h +2 -0
  360. data/vendor/libgit2/src/transports/local.c +35 -35
  361. data/vendor/libgit2/src/transports/smart.c +70 -47
  362. data/vendor/libgit2/src/transports/smart.h +3 -4
  363. data/vendor/libgit2/src/transports/smart_pkt.c +43 -40
  364. data/vendor/libgit2/src/transports/smart_protocol.c +96 -116
  365. data/vendor/libgit2/src/transports/ssh.c +77 -66
  366. data/vendor/libgit2/src/transports/winhttp.c +318 -314
  367. data/vendor/libgit2/src/tree-cache.c +19 -12
  368. data/vendor/libgit2/src/tree.c +103 -142
  369. data/vendor/libgit2/src/tree.h +1 -12
  370. data/vendor/libgit2/src/unix/map.c +3 -3
  371. data/vendor/libgit2/src/unix/posix.h +1 -11
  372. data/vendor/libgit2/src/userdiff.h +3 -1
  373. data/vendor/libgit2/src/util.c +70 -56
  374. data/vendor/libgit2/src/util.h +28 -156
  375. data/vendor/libgit2/src/vector.c +4 -4
  376. data/vendor/libgit2/src/wildmatch.c +320 -0
  377. data/vendor/libgit2/src/wildmatch.h +23 -0
  378. data/vendor/libgit2/src/win32/dir.c +3 -3
  379. data/vendor/libgit2/src/win32/findfile.c +3 -3
  380. data/vendor/libgit2/src/win32/map.c +9 -11
  381. data/vendor/libgit2/src/win32/msvc-compat.h +6 -0
  382. data/vendor/libgit2/src/win32/path_w32.c +113 -9
  383. data/vendor/libgit2/src/win32/path_w32.h +18 -29
  384. data/vendor/libgit2/src/win32/posix.h +1 -4
  385. data/vendor/libgit2/src/win32/posix_w32.c +70 -45
  386. data/vendor/libgit2/src/win32/precompiled.h +0 -2
  387. data/vendor/libgit2/src/win32/thread.c +5 -10
  388. data/vendor/libgit2/src/win32/w32_buffer.c +9 -5
  389. data/vendor/libgit2/src/win32/w32_common.h +39 -0
  390. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +3 -2
  391. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +26 -75
  392. data/vendor/libgit2/src/win32/w32_stack.c +6 -11
  393. data/vendor/libgit2/src/win32/w32_stack.h +3 -3
  394. data/vendor/libgit2/src/win32/w32_util.c +27 -64
  395. data/vendor/libgit2/src/win32/w32_util.h +5 -49
  396. data/vendor/libgit2/src/worktree.c +95 -60
  397. data/vendor/libgit2/src/worktree.h +2 -0
  398. data/vendor/libgit2/src/xdiff/xdiffi.c +7 -5
  399. data/vendor/libgit2/src/xdiff/xhistogram.c +1 -1
  400. data/vendor/libgit2/src/xdiff/xmerge.c +27 -15
  401. data/vendor/libgit2/src/xdiff/xpatience.c +3 -0
  402. data/vendor/libgit2/src/zstream.c +4 -4
  403. metadata +122 -33
  404. data/vendor/libgit2/deps/regex/CMakeLists.txt +0 -2
  405. data/vendor/libgit2/deps/regex/config.h +0 -7
  406. data/vendor/libgit2/deps/regex/regcomp.c +0 -3857
  407. data/vendor/libgit2/deps/regex/regex.c +0 -92
  408. data/vendor/libgit2/deps/regex/regex.h +0 -582
  409. data/vendor/libgit2/deps/regex/regex_internal.c +0 -1744
  410. data/vendor/libgit2/deps/regex/regex_internal.h +0 -819
  411. data/vendor/libgit2/deps/regex/regexec.c +0 -4369
  412. data/vendor/libgit2/include/git2/inttypes.h +0 -309
  413. data/vendor/libgit2/include/git2/sys/time.h +0 -31
  414. data/vendor/libgit2/libgit2.pc.in +0 -13
  415. data/vendor/libgit2/src/config_file.h +0 -73
  416. data/vendor/libgit2/src/fnmatch.c +0 -248
  417. data/vendor/libgit2/src/fnmatch.h +0 -48
  418. data/vendor/libgit2/src/hash/hash_collisiondetect.h +0 -47
  419. data/vendor/libgit2/src/hash/hash_openssl.h +0 -59
  420. data/vendor/libgit2/src/streams/curl.c +0 -385
@@ -12,19 +12,22 @@
12
12
  #include "git2.h"
13
13
  #include "http_parser.h"
14
14
  #include "buffer.h"
15
+ #include "net.h"
15
16
  #include "netops.h"
16
17
  #include "global.h"
17
18
  #include "remote.h"
19
+ #include "git2/sys/cred.h"
18
20
  #include "smart.h"
19
21
  #include "auth.h"
20
22
  #include "http.h"
21
23
  #include "auth_negotiate.h"
24
+ #include "auth_ntlm.h"
22
25
  #include "streams/tls.h"
23
26
  #include "streams/socket.h"
24
- #include "streams/curl.h"
25
27
 
26
28
  git_http_auth_scheme auth_schemes[] = {
27
29
  { GIT_AUTHTYPE_NEGOTIATE, "Negotiate", GIT_CREDTYPE_DEFAULT, git_http_auth_negotiate },
30
+ { GIT_AUTHTYPE_NTLM, "NTLM", GIT_CREDTYPE_USERPASS_PLAINTEXT, git_http_auth_ntlm },
28
31
  { GIT_AUTHTYPE_BASIC, "Basic", GIT_CREDTYPE_USERPASS_PLAINTEXT, git_http_auth_basic },
29
32
  };
30
33
 
@@ -37,6 +40,12 @@ static const char *receive_pack_service_url = "/git-receive-pack";
37
40
  static const char *get_verb = "GET";
38
41
  static const char *post_verb = "POST";
39
42
 
43
+ #define AUTH_HEADER_SERVER "Authorization"
44
+ #define AUTH_HEADER_PROXY "Proxy-Authorization"
45
+
46
+ #define SERVER_TYPE_REMOTE "remote"
47
+ #define SERVER_TYPE_PROXY "proxy"
48
+
40
49
  #define OWNING_SUBTRANSPORT(s) ((http_subtransport *)(s)->parent.subtransport)
41
50
 
42
51
  #define PARSE_ERROR_GENERIC -1
@@ -62,17 +71,36 @@ typedef struct {
62
71
  unsigned chunk_buffer_len;
63
72
  unsigned sent_request : 1,
64
73
  received_response : 1,
65
- chunked : 1,
66
- redirect_count : 3;
74
+ chunked : 1;
67
75
  } http_stream;
68
76
 
77
+ typedef struct {
78
+ git_net_url url;
79
+ git_stream *stream;
80
+
81
+ git_http_authtype_t authtypes;
82
+ git_credtype_t credtypes;
83
+
84
+ git_cred *cred;
85
+ unsigned url_cred_presented : 1,
86
+ authenticated : 1;
87
+
88
+ git_vector auth_challenges;
89
+ git_http_auth_context *auth_context;
90
+ } http_server;
91
+
69
92
  typedef struct {
70
93
  git_smart_subtransport parent;
71
94
  transport_smart *owner;
72
- git_stream *io;
73
- gitno_connection_data connection_data;
95
+ git_stream *gitserver_stream;
74
96
  bool connected;
75
97
 
98
+ http_server server;
99
+
100
+ http_server proxy;
101
+ char *proxy_url;
102
+ git_proxy_options proxy_opts;
103
+
76
104
  /* Parser structures */
77
105
  http_parser parser;
78
106
  http_parser_settings settings;
@@ -81,17 +109,15 @@ typedef struct {
81
109
  git_buf parse_header_value;
82
110
  char parse_buffer_data[NETIO_BUFSIZE];
83
111
  char *content_type;
112
+ char *content_length;
84
113
  char *location;
85
- git_vector www_authenticate;
86
114
  enum last_cb last_cb;
87
115
  int parse_error;
88
116
  int error;
89
- unsigned parse_finished : 1;
90
-
91
- /* Authentication */
92
- git_cred *cred;
93
- git_cred *url_cred;
94
- git_vector auth_contexts;
117
+ unsigned request_count;
118
+ unsigned parse_finished : 1,
119
+ keepalive : 1,
120
+ replay_count : 4;
95
121
  } http_subtransport;
96
122
 
97
123
  typedef struct {
@@ -104,94 +130,50 @@ typedef struct {
104
130
  size_t *bytes_read;
105
131
  } parser_context;
106
132
 
107
- static bool credtype_match(git_http_auth_scheme *scheme, void *data)
108
- {
109
- unsigned int credtype = *(unsigned int *)data;
110
-
111
- return !!(scheme->credtypes & credtype);
112
- }
113
-
114
- static bool challenge_match(git_http_auth_scheme *scheme, void *data)
115
- {
116
- const char *scheme_name = scheme->name;
117
- const char *challenge = (const char *)data;
118
- size_t scheme_len;
119
-
120
- scheme_len = strlen(scheme_name);
121
- return (strncasecmp(challenge, scheme_name, scheme_len) == 0 &&
122
- (challenge[scheme_len] == '\0' || challenge[scheme_len] == ' '));
123
- }
124
-
125
- static int auth_context_match(
126
- git_http_auth_context **out,
127
- http_subtransport *t,
128
- bool (*scheme_match)(git_http_auth_scheme *scheme, void *data),
129
- void *data)
133
+ static git_http_auth_scheme *scheme_for_challenge(
134
+ const char *challenge,
135
+ git_cred *cred)
130
136
  {
131
137
  git_http_auth_scheme *scheme = NULL;
132
- git_http_auth_context *context = NULL, *c;
133
138
  size_t i;
134
139
 
135
- *out = NULL;
136
-
137
140
  for (i = 0; i < ARRAY_SIZE(auth_schemes); i++) {
138
- if (scheme_match(&auth_schemes[i], data)) {
139
- scheme = &auth_schemes[i];
140
- break;
141
- }
142
- }
141
+ const char *scheme_name = auth_schemes[i].name;
142
+ const git_credtype_t scheme_types = auth_schemes[i].credtypes;
143
+ size_t scheme_len;
143
144
 
144
- if (!scheme)
145
- return 0;
145
+ scheme_len = strlen(scheme_name);
146
146
 
147
- /* See if authentication has already started for this scheme */
148
- git_vector_foreach(&t->auth_contexts, i, c) {
149
- if (c->type == scheme->type) {
150
- context = c;
147
+ if ((!cred || (cred->credtype & scheme_types)) &&
148
+ strncasecmp(challenge, scheme_name, scheme_len) == 0 &&
149
+ (challenge[scheme_len] == '\0' || challenge[scheme_len] == ' ')) {
150
+ scheme = &auth_schemes[i];
151
151
  break;
152
152
  }
153
153
  }
154
154
 
155
- if (!context) {
156
- if (scheme->init_context(&context, &t->connection_data) < 0)
157
- return -1;
158
- else if (!context)
159
- return 0;
160
- else if (git_vector_insert(&t->auth_contexts, context) < 0)
161
- return -1;
162
- }
163
-
164
- *out = context;
165
-
166
- return 0;
155
+ return scheme;
167
156
  }
168
157
 
169
- static int apply_credentials(git_buf *buf, http_subtransport *t)
158
+ static int apply_credentials(
159
+ git_buf *buf,
160
+ http_server *server,
161
+ const char *header_name)
170
162
  {
171
- git_cred *cred = t->cred;
172
- git_http_auth_context *context;
173
-
174
- /* Apply the credentials given to us in the URL */
175
- if (!cred && t->connection_data.user && t->connection_data.pass) {
176
- if (!t->url_cred &&
177
- git_cred_userpass_plaintext_new(&t->url_cred,
178
- t->connection_data.user, t->connection_data.pass) < 0)
179
- return -1;
180
-
181
- cred = t->url_cred;
182
- }
163
+ git_buf token = GIT_BUF_INIT;
164
+ int error = 0;
183
165
 
184
- if (!cred)
185
- return 0;
166
+ if (!server->auth_context)
167
+ goto done;
186
168
 
187
- /* Get or create a context for the best scheme for this cred type */
188
- if (auth_context_match(&context, t, credtype_match, &cred->credtype) < 0)
189
- return -1;
169
+ if ((error = server->auth_context->next_token(&token, server->auth_context, server->cred)) < 0)
170
+ goto done;
190
171
 
191
- if (!context)
192
- return 0;
172
+ error = git_buf_printf(buf, "%s: %s\r\n", header_name, token.ptr);
193
173
 
194
- return context->next_token(buf, context, cred);
174
+ done:
175
+ git_buf_dispose(&token);
176
+ return error;
195
177
  }
196
178
 
197
179
  static int gen_request(
@@ -200,15 +182,29 @@ static int gen_request(
200
182
  size_t content_length)
201
183
  {
202
184
  http_subtransport *t = OWNING_SUBTRANSPORT(s);
203
- const char *path = t->connection_data.path ? t->connection_data.path : "/";
185
+ const char *path = t->server.url.path ? t->server.url.path : "/";
204
186
  size_t i;
205
187
 
206
- git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n", s->verb, path, s->service_url);
188
+ if (t->proxy_opts.type == GIT_PROXY_SPECIFIED)
189
+ git_buf_printf(buf, "%s %s://%s:%s%s%s HTTP/1.1\r\n",
190
+ s->verb,
191
+ t->server.url.scheme,
192
+ t->server.url.host,
193
+ t->server.url.port,
194
+ path, s->service_url);
195
+ else
196
+ git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n",
197
+ s->verb, path, s->service_url);
207
198
 
208
199
  git_buf_puts(buf, "User-Agent: ");
209
200
  git_http__user_agent(buf);
210
201
  git_buf_puts(buf, "\r\n");
211
- git_buf_printf(buf, "Host: %s\r\n", t->connection_data.host);
202
+ git_buf_printf(buf, "Host: %s", t->server.url.host);
203
+
204
+ if (!git_net_url_is_default_port(&t->server.url))
205
+ git_buf_printf(buf, ":%s", t->server.url.port);
206
+
207
+ git_buf_puts(buf, "\r\n");
212
208
 
213
209
  if (s->chunked || content_length > 0) {
214
210
  git_buf_printf(buf, "Accept: application/x-git-%s-result\r\n", s->service);
@@ -226,8 +222,12 @@ static int gen_request(
226
222
  git_buf_printf(buf, "%s\r\n", t->owner->custom_headers.strings[i]);
227
223
  }
228
224
 
229
- /* Apply credentials to the request */
230
- if (apply_credentials(buf, t) < 0)
225
+ /* Apply proxy and server credentials to the request */
226
+ if (t->proxy_opts.type != GIT_PROXY_NONE &&
227
+ apply_credentials(buf, &t->proxy, AUTH_HEADER_PROXY) < 0)
228
+ return -1;
229
+
230
+ if (apply_credentials(buf, &t->server, AUTH_HEADER_SERVER) < 0)
231
231
  return -1;
232
232
 
233
233
  git_buf_puts(buf, "\r\n");
@@ -238,29 +238,86 @@ static int gen_request(
238
238
  return 0;
239
239
  }
240
240
 
241
- static int parse_authenticate_response(
242
- git_vector *www_authenticate,
243
- http_subtransport *t,
244
- int *allowed_types)
241
+ static int set_authentication_challenge(http_server *server)
242
+ {
243
+ const char *challenge;
244
+
245
+ if (git_vector_length(&server->auth_challenges) > 1) {
246
+ git_error_set(GIT_ERROR_NET, "received multiple authentication challenges");
247
+ return -1;
248
+ }
249
+
250
+ challenge = git_vector_get(&server->auth_challenges, 0);
251
+
252
+ if (server->auth_context->set_challenge)
253
+ return server->auth_context->set_challenge(server->auth_context, challenge);
254
+ else
255
+ return 0;
256
+ }
257
+
258
+ static int set_authentication_types(http_server *server)
245
259
  {
246
- git_http_auth_context *context;
260
+ git_http_auth_scheme *scheme;
247
261
  char *challenge;
248
262
  size_t i;
249
263
 
250
- git_vector_foreach(www_authenticate, i, challenge) {
251
- if (auth_context_match(&context, t, challenge_match, challenge) < 0)
252
- return -1;
253
- else if (!context)
254
- continue;
264
+ git_vector_foreach(&server->auth_challenges, i, challenge) {
265
+ if ((scheme = scheme_for_challenge(challenge, NULL)) != NULL) {
266
+ server->authtypes |= scheme->type;
267
+ server->credtypes |= scheme->credtypes;
268
+ }
269
+ }
255
270
 
256
- if (context->set_challenge &&
257
- context->set_challenge(context, challenge) < 0)
258
- return -1;
271
+ return 0;
272
+ }
273
+
274
+ static bool auth_context_complete(http_server *server)
275
+ {
276
+ /* If there's no is_complete function, we're always complete */
277
+ if (!server->auth_context->is_complete)
278
+ return true;
279
+
280
+ if (server->auth_context->is_complete(server->auth_context))
281
+ return true;
282
+
283
+ return false;
284
+ }
285
+
286
+ static void free_auth_context(http_server *server)
287
+ {
288
+ if (!server->auth_context)
289
+ return;
259
290
 
260
- *allowed_types |= context->credtypes;
291
+ if (server->auth_context->free)
292
+ server->auth_context->free(server->auth_context);
293
+
294
+ server->auth_context = NULL;
295
+ }
296
+
297
+ static int parse_authenticate_response(http_server *server)
298
+ {
299
+ /*
300
+ * If we think that we've completed authentication (ie, we've either
301
+ * sent a basic credential or we've sent the NTLM/Negotiate response)
302
+ * but we've got an authentication request from the server then our
303
+ * last authentication did not succeed. Start over.
304
+ */
305
+ if (server->auth_context && auth_context_complete(server)) {
306
+ free_auth_context(server);
307
+
308
+ server->authenticated = 0;
261
309
  }
262
310
 
263
- return 0;
311
+ /*
312
+ * If we've begun authentication, give the challenge to the context.
313
+ * Otherwise, set up the types to prepare credentials.
314
+ */
315
+ if (git_vector_length(&server->auth_challenges) == 0)
316
+ return 0;
317
+ else if (server->auth_context)
318
+ return set_authentication_challenge(server);
319
+ else
320
+ return set_authentication_types(server);
264
321
  }
265
322
 
266
323
  static int on_header_ready(http_subtransport *t)
@@ -269,22 +326,45 @@ static int on_header_ready(http_subtransport *t)
269
326
  git_buf *value = &t->parse_header_value;
270
327
 
271
328
  if (!strcasecmp("Content-Type", git_buf_cstr(name))) {
272
- if (!t->content_type) {
273
- t->content_type = git__strdup(git_buf_cstr(value));
274
- GITERR_CHECK_ALLOC(t->content_type);
329
+ if (t->content_type) {
330
+ git_error_set(GIT_ERROR_NET, "multiple Content-Type headers");
331
+ return -1;
332
+ }
333
+
334
+ t->content_type = git__strdup(git_buf_cstr(value));
335
+ GIT_ERROR_CHECK_ALLOC(t->content_type);
336
+ }
337
+ else if (!strcasecmp("Content-Length", git_buf_cstr(name))) {
338
+ if (t->content_length) {
339
+ git_error_set(GIT_ERROR_NET, "multiple Content-Length headers");
340
+ return -1;
275
341
  }
342
+
343
+ t->content_length = git__strdup(git_buf_cstr(value));
344
+ GIT_ERROR_CHECK_ALLOC(t->content_length);
345
+ }
346
+ else if (!strcasecmp("Proxy-Authenticate", git_buf_cstr(name))) {
347
+ char *dup = git__strdup(git_buf_cstr(value));
348
+ GIT_ERROR_CHECK_ALLOC(dup);
349
+
350
+ if (git_vector_insert(&t->proxy.auth_challenges, dup) < 0)
351
+ return -1;
276
352
  }
277
353
  else if (!strcasecmp("WWW-Authenticate", git_buf_cstr(name))) {
278
354
  char *dup = git__strdup(git_buf_cstr(value));
279
- GITERR_CHECK_ALLOC(dup);
355
+ GIT_ERROR_CHECK_ALLOC(dup);
280
356
 
281
- git_vector_insert(&t->www_authenticate, dup);
357
+ if (git_vector_insert(&t->server.auth_challenges, dup) < 0)
358
+ return -1;
282
359
  }
283
360
  else if (!strcasecmp("Location", git_buf_cstr(name))) {
284
- if (!t->location) {
285
- t->location = git__strdup(git_buf_cstr(value));
286
- GITERR_CHECK_ALLOC(t->location);
361
+ if (t->location) {
362
+ git_error_set(GIT_ERROR_NET, "multiple Location headers");
363
+ return -1;
287
364
  }
365
+
366
+ t->location = git__strdup(git_buf_cstr(value));
367
+ GIT_ERROR_CHECK_ALLOC(t->location);
288
368
  }
289
369
 
290
370
  return 0;
@@ -328,85 +408,204 @@ static int on_header_value(http_parser *parser, const char *str, size_t len)
328
408
  return 0;
329
409
  }
330
410
 
411
+ GIT_INLINE(void) free_cred(git_cred **cred)
412
+ {
413
+ if (*cred) {
414
+ git_cred_free(*cred);
415
+ (*cred) = NULL;
416
+ }
417
+ }
418
+
419
+ static int apply_url_credentials(
420
+ git_cred **cred,
421
+ unsigned int allowed_types,
422
+ const char *username,
423
+ const char *password)
424
+ {
425
+ if (allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT)
426
+ return git_cred_userpass_plaintext_new(cred, username, password);
427
+
428
+ if ((allowed_types & GIT_CREDTYPE_DEFAULT) && *username == '\0' && *password == '\0')
429
+ return git_cred_default_new(cred);
430
+
431
+ return GIT_PASSTHROUGH;
432
+ }
433
+
434
+ static int init_auth(http_server *server)
435
+ {
436
+ git_http_auth_scheme *s, *scheme = NULL;
437
+ char *c, *challenge = NULL;
438
+ size_t i;
439
+ int error;
440
+
441
+ git_vector_foreach(&server->auth_challenges, i, c) {
442
+ s = scheme_for_challenge(c, server->cred);
443
+
444
+ if (s && !!(s->credtypes & server->credtypes)) {
445
+ scheme = s;
446
+ challenge = c;
447
+ break;
448
+ }
449
+ }
450
+
451
+ if (!scheme) {
452
+ git_error_set(GIT_ERROR_NET, "no authentication mechanism could be negotiated");
453
+ return -1;
454
+ }
455
+
456
+ if ((error = scheme->init_context(&server->auth_context, &server->url)) == GIT_PASSTHROUGH)
457
+ return 0;
458
+ else if (error < 0)
459
+ return error;
460
+
461
+ if (server->auth_context->set_challenge &&
462
+ (error = server->auth_context->set_challenge(server->auth_context, challenge)) < 0)
463
+ return error;
464
+
465
+ return 0;
466
+ }
467
+
468
+ static int on_auth_required(
469
+ http_parser *parser,
470
+ http_server *server,
471
+ const char *url,
472
+ const char *type,
473
+ git_cred_acquire_cb callback,
474
+ void *callback_payload)
475
+ {
476
+ parser_context *ctx = (parser_context *) parser->data;
477
+ http_subtransport *t = ctx->t;
478
+ int error = 1;
479
+
480
+ if (parse_authenticate_response(server) < 0) {
481
+ t->parse_error = PARSE_ERROR_GENERIC;
482
+ return t->parse_error;
483
+ }
484
+
485
+ /* If we're in the middle of challenge/response auth, continue */
486
+ if (parser->status_code == 407 || parser->status_code == 401) {
487
+ if (server->auth_context && !auth_context_complete(server)) {
488
+ t->parse_error = PARSE_ERROR_REPLAY;
489
+ return 0;
490
+ }
491
+ }
492
+
493
+ /* Enforce a reasonable cap on the number of replays */
494
+ if (t->replay_count++ >= GIT_HTTP_REPLAY_MAX) {
495
+ git_error_set(GIT_ERROR_NET, "too many redirects or authentication replays");
496
+ return t->parse_error = PARSE_ERROR_GENERIC;
497
+ }
498
+
499
+ if (!server->credtypes) {
500
+ git_error_set(GIT_ERROR_NET, "%s requested authentication but did not negotiate mechanisms", type);
501
+ t->parse_error = PARSE_ERROR_GENERIC;
502
+ return t->parse_error;
503
+ }
504
+
505
+ free_auth_context(server);
506
+ free_cred(&server->cred);
507
+
508
+ /* Start with URL-specified credentials, if there were any. */
509
+ if (!server->url_cred_presented && server->url.username && server->url.password) {
510
+ error = apply_url_credentials(&server->cred, server->credtypes, server->url.username, server->url.password);
511
+ server->url_cred_presented = 1;
512
+
513
+ if (error == GIT_PASSTHROUGH) {
514
+ /* treat GIT_PASSTHROUGH as if callback isn't set */
515
+ error = 1;
516
+ }
517
+ }
518
+
519
+ if (error > 0 && callback) {
520
+ error = callback(&server->cred, url, server->url.username, server->credtypes, callback_payload);
521
+
522
+ if (error == GIT_PASSTHROUGH) {
523
+ /* treat GIT_PASSTHROUGH as if callback isn't set */
524
+ error = 1;
525
+ }
526
+ }
527
+
528
+ if (error > 0) {
529
+ git_error_set(GIT_ERROR_NET, "%s authentication required but no callback set",
530
+ type);
531
+ t->parse_error = PARSE_ERROR_GENERIC;
532
+ return t->parse_error;
533
+ } else if (error < 0) {
534
+ t->error = error;
535
+ t->parse_error = PARSE_ERROR_EXT;
536
+ return t->parse_error;
537
+ }
538
+
539
+ assert(server->cred);
540
+
541
+ if (!(server->cred->credtype & server->credtypes)) {
542
+ git_error_set(GIT_ERROR_NET, "%s credential provider returned an invalid cred type", type);
543
+ t->parse_error = PARSE_ERROR_GENERIC;
544
+ return t->parse_error;
545
+ }
546
+
547
+ /* Successfully acquired a credential. Start an auth context. */
548
+ if (init_auth(server) < 0) {
549
+ t->parse_error = PARSE_ERROR_GENERIC;
550
+ return t->parse_error;
551
+ }
552
+
553
+ t->parse_error = PARSE_ERROR_REPLAY;
554
+ return 0;
555
+ }
556
+
557
+ static void on_auth_success(http_server *server)
558
+ {
559
+ server->url_cred_presented = 0;
560
+ server->authenticated = 1;
561
+ }
562
+
331
563
  static int on_headers_complete(http_parser *parser)
332
564
  {
333
565
  parser_context *ctx = (parser_context *) parser->data;
334
566
  http_subtransport *t = ctx->t;
335
567
  http_stream *s = ctx->s;
336
568
  git_buf buf = GIT_BUF_INIT;
337
- int error = 0, no_callback = 0, allowed_auth_types = 0;
338
569
 
339
570
  /* Both parse_header_name and parse_header_value are populated
340
571
  * and ready for consumption. */
341
- if (VALUE == t->last_cb)
342
- if (on_header_ready(t) < 0)
343
- return t->parse_error = PARSE_ERROR_GENERIC;
344
-
345
- /* Capture authentication headers which may be a 401 (authentication
346
- * is not complete) or a 200 (simply informing us that auth *is*
347
- * complete.)
348
- */
349
- if (parse_authenticate_response(&t->www_authenticate, t,
350
- &allowed_auth_types) < 0)
572
+ if (t->last_cb == VALUE && on_header_ready(t) < 0)
351
573
  return t->parse_error = PARSE_ERROR_GENERIC;
352
574
 
353
- /* Check for an authentication failure. */
354
- if (parser->status_code == 401 && get_verb == s->verb) {
355
- if (!t->owner->cred_acquire_cb) {
356
- no_callback = 1;
357
- } else {
358
- if (allowed_auth_types) {
359
- if (t->cred) {
360
- t->cred->free(t->cred);
361
- t->cred = NULL;
362
- }
363
-
364
- error = t->owner->cred_acquire_cb(&t->cred,
365
- t->owner->url,
366
- t->connection_data.user,
367
- allowed_auth_types,
368
- t->owner->cred_acquire_payload);
369
-
370
- if (error == GIT_PASSTHROUGH) {
371
- no_callback = 1;
372
- } else if (error < 0) {
373
- t->error = error;
374
- return t->parse_error = PARSE_ERROR_EXT;
375
- } else {
376
- assert(t->cred);
377
-
378
- if (!(t->cred->credtype & allowed_auth_types)) {
379
- giterr_set(GITERR_NET, "credentials callback returned an invalid cred type");
380
- return t->parse_error = PARSE_ERROR_GENERIC;
381
- }
382
-
383
- /* Successfully acquired a credential. */
384
- t->parse_error = PARSE_ERROR_REPLAY;
385
- return 0;
386
- }
387
- }
388
- }
575
+ /* Check for a proxy authentication failure. */
576
+ if (parser->status_code == 407 && get_verb == s->verb)
577
+ return on_auth_required(
578
+ parser,
579
+ &t->proxy,
580
+ t->proxy_opts.url,
581
+ SERVER_TYPE_PROXY,
582
+ t->proxy_opts.credentials,
583
+ t->proxy_opts.payload);
584
+ else
585
+ on_auth_success(&t->proxy);
389
586
 
390
- if (no_callback) {
391
- giterr_set(GITERR_NET, "authentication required but no callback set");
392
- return t->parse_error = PARSE_ERROR_GENERIC;
393
- }
394
- }
587
+ /* Check for an authentication failure. */
588
+ if (parser->status_code == 401 && get_verb == s->verb)
589
+ return on_auth_required(
590
+ parser,
591
+ &t->server,
592
+ t->owner->url,
593
+ SERVER_TYPE_REMOTE,
594
+ t->owner->cred_acquire_cb,
595
+ t->owner->cred_acquire_payload);
596
+ else
597
+ on_auth_success(&t->server);
395
598
 
396
599
  /* Check for a redirect.
397
600
  * Right now we only permit a redirect to the same hostname. */
398
601
  if ((parser->status_code == 301 ||
399
602
  parser->status_code == 302 ||
400
603
  (parser->status_code == 303 && get_verb == s->verb) ||
401
- parser->status_code == 307) &&
604
+ parser->status_code == 307 ||
605
+ parser->status_code == 308) &&
402
606
  t->location) {
403
607
 
404
- if (s->redirect_count >= 7) {
405
- giterr_set(GITERR_NET, "too many redirects");
406
- return t->parse_error = PARSE_ERROR_GENERIC;
407
- }
408
-
409
- if (gitno_connection_data_from_url(&t->connection_data, t->location, s->service_url) < 0)
608
+ if (gitno_connection_data_handle_redirect(&t->server.url, t->location, s->service_url) < 0)
410
609
  return t->parse_error = PARSE_ERROR_GENERIC;
411
610
 
412
611
  /* Set the redirect URL on the stream. This is a transfer of
@@ -418,15 +617,13 @@ static int on_headers_complete(http_parser *parser)
418
617
  t->location = NULL;
419
618
 
420
619
  t->connected = 0;
421
- s->redirect_count++;
422
-
423
620
  t->parse_error = PARSE_ERROR_REPLAY;
424
621
  return 0;
425
622
  }
426
623
 
427
624
  /* Check for a 200 HTTP status code. */
428
625
  if (parser->status_code != 200) {
429
- giterr_set(GITERR_NET,
626
+ git_error_set(GIT_ERROR_NET,
430
627
  "unexpected HTTP status code: %d",
431
628
  parser->status_code);
432
629
  return t->parse_error = PARSE_ERROR_GENERIC;
@@ -434,7 +631,7 @@ static int on_headers_complete(http_parser *parser)
434
631
 
435
632
  /* The response must contain a Content-Type header. */
436
633
  if (!t->content_type) {
437
- giterr_set(GITERR_NET, "no Content-Type header in response");
634
+ git_error_set(GIT_ERROR_NET, "no Content-Type header in response");
438
635
  return t->parse_error = PARSE_ERROR_GENERIC;
439
636
  }
440
637
 
@@ -452,14 +649,14 @@ static int on_headers_complete(http_parser *parser)
452
649
  return t->parse_error = PARSE_ERROR_GENERIC;
453
650
 
454
651
  if (strcmp(t->content_type, git_buf_cstr(&buf))) {
455
- git_buf_free(&buf);
456
- giterr_set(GITERR_NET,
652
+ git_buf_dispose(&buf);
653
+ git_error_set(GIT_ERROR_NET,
457
654
  "invalid Content-Type: %s",
458
655
  t->content_type);
459
656
  return t->parse_error = PARSE_ERROR_GENERIC;
460
657
  }
461
658
 
462
- git_buf_free(&buf);
659
+ git_buf_dispose(&buf);
463
660
 
464
661
  return 0;
465
662
  }
@@ -470,6 +667,7 @@ static int on_message_complete(http_parser *parser)
470
667
  http_subtransport *t = ctx->t;
471
668
 
472
669
  t->parse_finished = 1;
670
+ t->keepalive = http_should_keep_alive(parser);
473
671
 
474
672
  return 0;
475
673
  }
@@ -479,22 +677,19 @@ static int on_body_fill_buffer(http_parser *parser, const char *str, size_t len)
479
677
  parser_context *ctx = (parser_context *) parser->data;
480
678
  http_subtransport *t = ctx->t;
481
679
 
482
- /* If our goal is to replay the request (either an auth failure or
483
- * a redirect) then don't bother buffering since we're ignoring the
484
- * content anyway.
485
- */
486
- if (t->parse_error == PARSE_ERROR_REPLAY)
487
- return 0;
680
+ /* If there's no buffer set, we're explicitly ignoring the body. */
681
+ if (ctx->buffer) {
682
+ if (ctx->buf_size < len) {
683
+ git_error_set(GIT_ERROR_NET, "can't fit data in the buffer");
684
+ return t->parse_error = PARSE_ERROR_GENERIC;
685
+ }
488
686
 
489
- if (ctx->buf_size < len) {
490
- giterr_set(GITERR_NET, "can't fit data in the buffer");
491
- return t->parse_error = PARSE_ERROR_GENERIC;
687
+ memcpy(ctx->buffer, str, len);
688
+ ctx->buffer += len;
689
+ ctx->buf_size -= len;
492
690
  }
493
691
 
494
- memcpy(ctx->buffer, str, len);
495
692
  *(ctx->bytes_read) += len;
496
- ctx->buffer += len;
497
- ctx->buf_size -= len;
498
693
 
499
694
  return 0;
500
695
  }
@@ -502,7 +697,7 @@ static int on_body_fill_buffer(http_parser *parser, const char *str, size_t len)
502
697
  static void clear_parser_state(http_subtransport *t)
503
698
  {
504
699
  http_parser_init(&t->parser, HTTP_RESPONSE);
505
- gitno_buffer_setup_fromstream(t->io,
700
+ gitno_buffer_setup_fromstream(t->server.stream,
506
701
  &t->parse_buffer,
507
702
  t->parse_buffer_data,
508
703
  sizeof(t->parse_buffer_data));
@@ -510,20 +705,25 @@ static void clear_parser_state(http_subtransport *t)
510
705
  t->last_cb = NONE;
511
706
  t->parse_error = 0;
512
707
  t->parse_finished = 0;
708
+ t->keepalive = 0;
513
709
 
514
- git_buf_free(&t->parse_header_name);
710
+ git_buf_dispose(&t->parse_header_name);
515
711
  git_buf_init(&t->parse_header_name, 0);
516
712
 
517
- git_buf_free(&t->parse_header_value);
713
+ git_buf_dispose(&t->parse_header_value);
518
714
  git_buf_init(&t->parse_header_value, 0);
519
715
 
520
716
  git__free(t->content_type);
521
717
  t->content_type = NULL;
522
718
 
719
+ git__free(t->content_length);
720
+ t->content_length = NULL;
721
+
523
722
  git__free(t->location);
524
723
  t->location = NULL;
525
724
 
526
- git_vector_free_deep(&t->www_authenticate);
725
+ git_vector_free_deep(&t->proxy.auth_challenges);
726
+ git_vector_free_deep(&t->server.auth_challenges);
527
727
  }
528
728
 
529
729
  static int write_chunk(git_stream *io, const char *buffer, size_t len)
@@ -536,117 +736,424 @@ static int write_chunk(git_stream *io, const char *buffer, size_t len)
536
736
  if (git_buf_oom(&buf))
537
737
  return -1;
538
738
 
539
- if (git_stream_write(io, buf.ptr, buf.size, 0) < 0) {
540
- git_buf_free(&buf);
739
+ if (git_stream__write_full(io, buf.ptr, buf.size, 0) < 0) {
740
+ git_buf_dispose(&buf);
541
741
  return -1;
542
742
  }
543
743
 
544
- git_buf_free(&buf);
744
+ git_buf_dispose(&buf);
545
745
 
546
746
  /* Chunk body */
547
- if (len > 0 && git_stream_write(io, buffer, len, 0) < 0)
747
+ if (len > 0 && git_stream__write_full(io, buffer, len, 0) < 0)
548
748
  return -1;
549
749
 
550
750
  /* Chunk footer */
551
- if (git_stream_write(io, "\r\n", 2, 0) < 0)
751
+ if (git_stream__write_full(io, "\r\n", 2, 0) < 0)
552
752
  return -1;
553
753
 
554
754
  return 0;
555
755
  }
556
756
 
557
- static int apply_proxy_config(http_subtransport *t)
757
+ static int load_proxy_config(http_subtransport *t)
558
758
  {
559
759
  int error;
560
- git_proxy_t proxy_type;
561
760
 
562
- if (!git_stream_supports_proxy(t->io))
761
+ switch (t->owner->proxy.type) {
762
+ case GIT_PROXY_NONE:
563
763
  return 0;
564
764
 
565
- proxy_type = t->owner->proxy.type;
765
+ case GIT_PROXY_AUTO:
766
+ git__free(t->proxy_url);
767
+ t->proxy_url = NULL;
566
768
 
567
- if (proxy_type == GIT_PROXY_NONE)
568
- return 0;
569
-
570
- if (proxy_type == GIT_PROXY_AUTO) {
571
- char *url;
572
- git_proxy_options opts = GIT_PROXY_OPTIONS_INIT;
769
+ git_proxy_options_init(&t->proxy_opts, GIT_PROXY_OPTIONS_VERSION);
573
770
 
574
- if ((error = git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &url)) < 0)
771
+ if ((error = git_remote__get_http_proxy(t->owner->owner,
772
+ !strcmp(t->server.url.scheme, "https"), &t->proxy_url)) < 0)
575
773
  return error;
576
774
 
577
- opts.credentials = t->owner->proxy.credentials;
578
- opts.certificate_check = t->owner->proxy.certificate_check;
579
- opts.payload = t->owner->proxy.payload;
580
- opts.type = GIT_PROXY_SPECIFIED;
581
- opts.url = url;
582
- error = git_stream_set_proxy(t->io, &opts);
583
- git__free(url);
775
+ if (!t->proxy_url)
776
+ return 0;
777
+
778
+ t->proxy_opts.type = GIT_PROXY_SPECIFIED;
779
+ t->proxy_opts.url = t->proxy_url;
780
+ t->proxy_opts.credentials = t->owner->proxy.credentials;
781
+ t->proxy_opts.certificate_check = t->owner->proxy.certificate_check;
782
+ t->proxy_opts.payload = t->owner->proxy.payload;
783
+ break;
584
784
 
585
- return error;
785
+ case GIT_PROXY_SPECIFIED:
786
+ memcpy(&t->proxy_opts, &t->owner->proxy, sizeof(git_proxy_options));
787
+ break;
788
+
789
+ default:
790
+ assert(0);
791
+ return -1;
586
792
  }
587
793
 
588
- return git_stream_set_proxy(t->io, &t->owner->proxy);
794
+ git_net_url_dispose(&t->proxy.url);
795
+
796
+ return git_net_url_parse(&t->proxy.url, t->proxy_opts.url);
589
797
  }
590
798
 
591
- static int http_connect(http_subtransport *t)
799
+ static int check_certificate(
800
+ git_stream *stream,
801
+ git_net_url *url,
802
+ int is_valid,
803
+ git_transport_certificate_check_cb cert_cb,
804
+ void *cert_cb_payload)
592
805
  {
806
+ git_cert *cert;
807
+ git_error_state last_error = {0};
593
808
  int error;
594
809
 
595
- if (t->connected &&
596
- http_should_keep_alive(&t->parser) &&
597
- t->parse_finished)
598
- return 0;
810
+ if ((error = git_stream_certificate(&cert, stream)) < 0)
811
+ return error;
599
812
 
600
- if (t->io) {
601
- git_stream_close(t->io);
602
- git_stream_free(t->io);
603
- t->io = NULL;
604
- t->connected = 0;
813
+ git_error_state_capture(&last_error, GIT_ECERTIFICATE);
814
+
815
+ error = cert_cb(cert, is_valid, url->host, cert_cb_payload);
816
+
817
+ if (error == GIT_PASSTHROUGH && !is_valid)
818
+ return git_error_state_restore(&last_error);
819
+ else if (error == GIT_PASSTHROUGH)
820
+ error = 0;
821
+ else if (error && !git_error_last())
822
+ git_error_set(GIT_ERROR_NET, "user rejected certificate for %s", url->host);
823
+
824
+ git_error_state_free(&last_error);
825
+ return error;
826
+ }
827
+
828
+ static int stream_connect(
829
+ git_stream *stream,
830
+ git_net_url *url,
831
+ git_transport_certificate_check_cb cert_cb,
832
+ void *cb_payload)
833
+ {
834
+ int error;
835
+
836
+ GIT_ERROR_CHECK_VERSION(stream, GIT_STREAM_VERSION, "git_stream");
837
+
838
+ error = git_stream_connect(stream);
839
+
840
+ if (error && error != GIT_ECERTIFICATE)
841
+ return error;
842
+
843
+ if (git_stream_is_encrypted(stream) && cert_cb != NULL)
844
+ error = check_certificate(stream, url, !error, cert_cb, cb_payload);
845
+
846
+ return error;
847
+ }
848
+
849
+ static int gen_connect_req(git_buf *buf, http_subtransport *t)
850
+ {
851
+ git_buf_printf(buf, "CONNECT %s:%s HTTP/1.1\r\n",
852
+ t->server.url.host, t->server.url.port);
853
+
854
+ git_buf_puts(buf, "User-Agent: ");
855
+ git_http__user_agent(buf);
856
+ git_buf_puts(buf, "\r\n");
857
+
858
+ git_buf_printf(buf, "Host: %s\r\n", t->proxy.url.host);
859
+
860
+ if (apply_credentials(buf, &t->proxy, AUTH_HEADER_PROXY) < 0)
861
+ return -1;
862
+
863
+ git_buf_puts(buf, "\r\n");
864
+
865
+ return git_buf_oom(buf) ? -1 : 0;
866
+ }
867
+
868
+ static int proxy_headers_complete(http_parser *parser)
869
+ {
870
+ parser_context *ctx = (parser_context *) parser->data;
871
+ http_subtransport *t = ctx->t;
872
+
873
+ /* Both parse_header_name and parse_header_value are populated
874
+ * and ready for consumption. */
875
+ if (t->last_cb == VALUE && on_header_ready(t) < 0)
876
+ return t->parse_error = PARSE_ERROR_GENERIC;
877
+
878
+ /*
879
+ * Capture authentication headers for the proxy or final endpoint,
880
+ * these may be 407/401 (authentication is not complete) or a 200
881
+ * (informing us that auth has completed).
882
+ */
883
+ if (parse_authenticate_response(&t->proxy) < 0)
884
+ return t->parse_error = PARSE_ERROR_GENERIC;
885
+
886
+ /* If we're in the middle of challenge/response auth, continue */
887
+ if (parser->status_code == 407) {
888
+ if (t->proxy.auth_context && !auth_context_complete(&t->proxy)) {
889
+ t->parse_error = PARSE_ERROR_REPLAY;
890
+ return 0;
891
+ }
605
892
  }
606
893
 
607
- if (t->connection_data.use_ssl) {
608
- error = git_tls_stream_new(&t->io, t->connection_data.host, t->connection_data.port);
609
- } else {
610
- #ifdef GIT_CURL
611
- error = git_curl_stream_new(&t->io, t->connection_data.host, t->connection_data.port);
612
- #else
613
- error = git_socket_stream_new(&t->io, t->connection_data.host, t->connection_data.port);
614
- #endif
894
+ /* Enforce a reasonable cap on the number of replays */
895
+ if (t->replay_count++ >= GIT_HTTP_REPLAY_MAX) {
896
+ git_error_set(GIT_ERROR_NET, "too many redirects or authentication replays");
897
+ return t->parse_error = PARSE_ERROR_GENERIC;
615
898
  }
616
899
 
617
- if (error < 0)
618
- return error;
900
+ /* Check for a proxy authentication failure. */
901
+ if (parser->status_code == 407)
902
+ return on_auth_required(
903
+ parser,
904
+ &t->proxy,
905
+ t->proxy_opts.url,
906
+ SERVER_TYPE_PROXY,
907
+ t->proxy_opts.credentials,
908
+ t->proxy_opts.payload);
909
+
910
+ if (parser->status_code != 200) {
911
+ git_error_set(GIT_ERROR_NET, "unexpected status code from proxy: %d",
912
+ parser->status_code);
913
+ return t->parse_error = PARSE_ERROR_GENERIC;
914
+ }
915
+
916
+ if (!t->content_length || strcmp(t->content_length, "0") == 0)
917
+ t->parse_finished = 1;
918
+
919
+ return 0;
920
+ }
619
921
 
620
- GITERR_CHECK_VERSION(t->io, GIT_STREAM_VERSION, "git_stream");
922
+ static int proxy_connect(
923
+ git_stream **out, git_stream *proxy_stream, http_subtransport *t)
924
+ {
925
+ git_buf request = GIT_BUF_INIT;
926
+ static http_parser_settings proxy_parser_settings = {0};
927
+ size_t bytes_read = 0, bytes_parsed;
928
+ parser_context ctx;
929
+ bool auth_replay;
930
+ int error;
931
+
932
+ /* Use the parser settings only to parser headers. */
933
+ proxy_parser_settings.on_header_field = on_header_field;
934
+ proxy_parser_settings.on_header_value = on_header_value;
935
+ proxy_parser_settings.on_headers_complete = proxy_headers_complete;
936
+ proxy_parser_settings.on_message_complete = on_message_complete;
621
937
 
622
- apply_proxy_config(t);
938
+ replay:
939
+ clear_parser_state(t);
623
940
 
624
- error = git_stream_connect(t->io);
941
+ auth_replay = false;
625
942
 
626
- if ((!error || error == GIT_ECERTIFICATE) && t->owner->certificate_check_cb != NULL &&
627
- git_stream_is_encrypted(t->io)) {
628
- git_cert *cert;
629
- int is_valid = (error == GIT_OK);
943
+ gitno_buffer_setup_fromstream(proxy_stream,
944
+ &t->parse_buffer,
945
+ t->parse_buffer_data,
946
+ sizeof(t->parse_buffer_data));
630
947
 
631
- if ((error = git_stream_certificate(&cert, t->io)) < 0)
632
- return error;
948
+ if ((error = gen_connect_req(&request, t)) < 0)
949
+ goto done;
633
950
 
634
- giterr_clear();
635
- error = t->owner->certificate_check_cb(cert, is_valid, t->connection_data.host, t->owner->message_cb_payload);
951
+ if ((error = git_stream__write_full(proxy_stream, request.ptr,
952
+ request.size, 0)) < 0)
953
+ goto done;
636
954
 
637
- if (error < 0) {
638
- if (!giterr_last())
639
- giterr_set(GITERR_NET, "user cancelled certificate check");
955
+ git_buf_dispose(&request);
640
956
 
641
- return error;
957
+ while (!bytes_read && !t->parse_finished) {
958
+ t->parse_buffer.offset = 0;
959
+
960
+ if ((error = gitno_recv(&t->parse_buffer)) < 0) {
961
+ goto done;
962
+ } else if (error == 0 && t->request_count > 0) {
963
+ /* Server closed a keep-alive socket; reconnect. */
964
+ auth_replay = true;
965
+ goto done;
966
+ } else if (error == 0) {
967
+ git_error_set(GIT_ERROR_NET, "unexpected disconnection from server");
968
+ error = -1;
969
+ goto done;
970
+ }
971
+
972
+ /*
973
+ * This call to http_parser_execute will invoke the on_*
974
+ * callbacks. Since we don't care about the body of the response,
975
+ * we can set our buffer to NULL.
976
+ */
977
+ ctx.t = t;
978
+ ctx.s = NULL;
979
+ ctx.buffer = NULL;
980
+ ctx.buf_size = 0;
981
+ ctx.bytes_read = &bytes_read;
982
+
983
+ /* Set the context, call the parser, then unset the context. */
984
+ t->parser.data = &ctx;
985
+
986
+ bytes_parsed = http_parser_execute(&t->parser,
987
+ &proxy_parser_settings, t->parse_buffer.data, t->parse_buffer.offset);
988
+
989
+ t->parser.data = NULL;
990
+
991
+ /* Ensure that we didn't get a redirect; unsupported. */
992
+ if (t->location) {
993
+ git_error_set(GIT_ERROR_NET, "proxy server sent unsupported redirect during CONNECT");
994
+ error = -1;
995
+ goto done;
996
+ }
997
+
998
+ /* Replay the request with authentication headers. */
999
+ if (PARSE_ERROR_REPLAY == t->parse_error) {
1000
+ auth_replay = true;
1001
+ } else if (t->parse_error < 0) {
1002
+ error = t->parse_error == PARSE_ERROR_EXT ? PARSE_ERROR_EXT : -1;
1003
+ goto done;
1004
+ }
1005
+
1006
+ if (bytes_parsed != t->parse_buffer.offset) {
1007
+ git_error_set(GIT_ERROR_NET,
1008
+ "HTTP parser error: %s",
1009
+ http_errno_description((enum http_errno)t->parser.http_errno));
1010
+ error = -1;
1011
+ goto done;
642
1012
  }
643
1013
  }
644
1014
 
645
- if (error < 0)
1015
+ t->request_count++;
1016
+
1017
+ if (auth_replay) {
1018
+ if (t->keepalive && t->parse_finished)
1019
+ goto replay;
1020
+
1021
+ return PARSE_ERROR_REPLAY;
1022
+ }
1023
+
1024
+ if ((error = git_tls_stream_wrap(out, proxy_stream, t->server.url.host)) == 0)
1025
+ error = stream_connect(*out, &t->server.url,
1026
+ t->owner->certificate_check_cb,
1027
+ t->owner->message_cb_payload);
1028
+
1029
+ /*
1030
+ * Since we've connected via a HTTPS proxy tunnel, we don't behave
1031
+ * as if we have an HTTP proxy.
1032
+ */
1033
+ t->proxy_opts.type = GIT_PROXY_NONE;
1034
+ t->replay_count = 0;
1035
+ t->request_count = 0;
1036
+
1037
+ done:
1038
+ return error;
1039
+ }
1040
+
1041
+ static void reset_auth_connection(http_server *server)
1042
+ {
1043
+ /*
1044
+ * If we've authenticated and we're doing "normal"
1045
+ * authentication with a request affinity (Basic, Digest)
1046
+ * then we want to _keep_ our context, since authentication
1047
+ * survives even through non-keep-alive connections. If
1048
+ * we've authenticated and we're doing connection-based
1049
+ * authentication (NTLM, Negotiate) - indicated by the presence
1050
+ * of an `is_complete` callback - then we need to restart
1051
+ * authentication on a new connection.
1052
+ */
1053
+
1054
+ if (server->authenticated &&
1055
+ server->auth_context &&
1056
+ server->auth_context->connection_affinity) {
1057
+ free_auth_context(server);
1058
+
1059
+ server->url_cred_presented = 0;
1060
+ server->authenticated = 0;
1061
+ }
1062
+ }
1063
+
1064
+ static int http_connect(http_subtransport *t)
1065
+ {
1066
+ git_net_url *url;
1067
+ git_stream *proxy_stream = NULL, *stream = NULL;
1068
+ git_transport_certificate_check_cb cert_cb;
1069
+ void *cb_payload;
1070
+ int error;
1071
+
1072
+ auth_replay:
1073
+ if (t->connected && t->keepalive && t->parse_finished)
1074
+ return 0;
1075
+
1076
+ if ((error = load_proxy_config(t)) < 0)
646
1077
  return error;
647
1078
 
1079
+ if (t->server.stream) {
1080
+ git_stream_close(t->server.stream);
1081
+ git_stream_free(t->server.stream);
1082
+ t->server.stream = NULL;
1083
+ }
1084
+
1085
+ if (t->proxy.stream) {
1086
+ git_stream_close(t->proxy.stream);
1087
+ git_stream_free(t->proxy.stream);
1088
+ t->proxy.stream = NULL;
1089
+ }
1090
+
1091
+ reset_auth_connection(&t->server);
1092
+ reset_auth_connection(&t->proxy);
1093
+
1094
+ t->connected = 0;
1095
+ t->keepalive = 0;
1096
+ t->request_count = 0;
1097
+
1098
+ if (t->proxy_opts.type == GIT_PROXY_SPECIFIED) {
1099
+ url = &t->proxy.url;
1100
+ cert_cb = t->proxy_opts.certificate_check;
1101
+ cb_payload = t->proxy_opts.payload;
1102
+ } else {
1103
+ url = &t->server.url;
1104
+ cert_cb = t->owner->certificate_check_cb;
1105
+ cb_payload = t->owner->message_cb_payload;
1106
+ }
1107
+
1108
+ if (strcmp(url->scheme, "https") == 0)
1109
+ error = git_tls_stream_new(&stream, url->host, url->port);
1110
+ else
1111
+ error = git_socket_stream_new(&stream, url->host, url->port);
1112
+
1113
+ if (error < 0)
1114
+ goto on_error;
1115
+
1116
+ if ((error = stream_connect(stream, url, cert_cb, cb_payload)) < 0)
1117
+ goto on_error;
1118
+
1119
+ /*
1120
+ * At this point we have a connection to the remote server or to
1121
+ * a proxy. If it's a proxy and the remote server is actually
1122
+ * an HTTPS connection, then we need to build a CONNECT tunnel.
1123
+ */
1124
+ if (t->proxy_opts.type == GIT_PROXY_SPECIFIED &&
1125
+ strcmp(t->server.url.scheme, "https") == 0) {
1126
+ proxy_stream = stream;
1127
+ stream = NULL;
1128
+
1129
+ error = proxy_connect(&stream, proxy_stream, t);
1130
+
1131
+ if (error == PARSE_ERROR_REPLAY) {
1132
+ git_stream_close(proxy_stream);
1133
+ git_stream_free(proxy_stream);
1134
+ goto auth_replay;
1135
+ } else if (error < 0) {
1136
+ goto on_error;
1137
+ }
1138
+ }
1139
+
1140
+ t->proxy.stream = proxy_stream;
1141
+ t->server.stream = stream;
648
1142
  t->connected = 1;
649
1143
  return 0;
1144
+
1145
+ on_error:
1146
+ if (stream) {
1147
+ git_stream_close(stream);
1148
+ git_stream_free(stream);
1149
+ }
1150
+
1151
+ if (proxy_stream) {
1152
+ git_stream_close(proxy_stream);
1153
+ git_stream_free(proxy_stream);
1154
+ }
1155
+
1156
+ return error;
650
1157
  }
651
1158
 
652
1159
  static int http_stream_read(
@@ -659,26 +1166,23 @@ static int http_stream_read(
659
1166
  http_subtransport *t = OWNING_SUBTRANSPORT(s);
660
1167
  parser_context ctx;
661
1168
  size_t bytes_parsed;
1169
+ git_buf request = GIT_BUF_INIT;
1170
+ bool auth_replay;
1171
+ int error = 0;
662
1172
 
663
1173
  replay:
664
1174
  *bytes_read = 0;
1175
+ auth_replay = false;
665
1176
 
666
1177
  assert(t->connected);
667
1178
 
668
1179
  if (!s->sent_request) {
669
- git_buf request = GIT_BUF_INIT;
670
-
1180
+ git_buf_clear(&request);
671
1181
  clear_parser_state(t);
672
1182
 
673
- if (gen_request(&request, s, 0) < 0)
674
- return -1;
675
-
676
- if (git_stream_write(t->io, request.ptr, request.size, 0) < 0) {
677
- git_buf_free(&request);
678
- return -1;
679
- }
680
-
681
- git_buf_free(&request);
1183
+ if ((error = gen_request(&request, s, 0)) < 0 ||
1184
+ (error = git_stream__write_full(t->server.stream, request.ptr, request.size, 0)) < 0)
1185
+ goto done;
682
1186
 
683
1187
  s->sent_request = 1;
684
1188
  }
@@ -688,15 +1192,17 @@ replay:
688
1192
  assert(s->verb == post_verb);
689
1193
 
690
1194
  /* Flush, if necessary */
691
- if (s->chunk_buffer_len > 0 &&
692
- write_chunk(t->io, s->chunk_buffer, s->chunk_buffer_len) < 0)
693
- return -1;
1195
+ if (s->chunk_buffer_len > 0) {
1196
+ if ((error = write_chunk(t->server.stream, s->chunk_buffer, s->chunk_buffer_len)) < 0)
1197
+ goto done;
694
1198
 
695
- s->chunk_buffer_len = 0;
1199
+ s->chunk_buffer_len = 0;
1200
+ }
696
1201
 
697
1202
  /* Write the final chunk. */
698
- if (git_stream_write(t->io, "0\r\n\r\n", 5, 0) < 0)
699
- return -1;
1203
+ if ((error = git_stream__write_full(t->server.stream,
1204
+ "0\r\n\r\n", 5, 0)) < 0)
1205
+ goto done;
700
1206
  }
701
1207
 
702
1208
  s->received_response = 1;
@@ -704,7 +1210,6 @@ replay:
704
1210
 
705
1211
  while (!*bytes_read && !t->parse_finished) {
706
1212
  size_t data_offset;
707
- int error;
708
1213
 
709
1214
  /*
710
1215
  * Make the parse_buffer think it's as full of data as
@@ -714,26 +1219,37 @@ replay:
714
1219
  * data_offset is the actual data offset from which we
715
1220
  * should tell the parser to start reading.
716
1221
  */
717
- if (buf_size >= t->parse_buffer.len) {
1222
+ if (buf_size >= t->parse_buffer.len)
718
1223
  t->parse_buffer.offset = 0;
719
- } else {
1224
+ else
720
1225
  t->parse_buffer.offset = t->parse_buffer.len - buf_size;
721
- }
722
1226
 
723
1227
  data_offset = t->parse_buffer.offset;
724
1228
 
725
- if (gitno_recv(&t->parse_buffer) < 0)
726
- return -1;
1229
+ if ((error = gitno_recv(&t->parse_buffer)) < 0) {
1230
+ goto done;
1231
+ } else if (error == 0 && t->request_count > 0) {
1232
+ /* Server closed a keep-alive socket; reconnect. */
1233
+ auth_replay = true;
1234
+ goto done;
1235
+ } else if (error == 0) {
1236
+ git_error_set(GIT_ERROR_NET, "unexpected disconnection from server");
1237
+ error = -1;
1238
+ goto done;
1239
+ }
727
1240
 
728
- /* This call to http_parser_execute will result in invocations of the
729
- * on_* family of callbacks. The most interesting of these is
730
- * on_body_fill_buffer, which is called when data is ready to be copied
731
- * into the target buffer. We need to marshal the buffer, buf_size, and
732
- * bytes_read parameters to this callback. */
1241
+ /*
1242
+ * This call to http_parser_execute will result in invocations
1243
+ * of the on_* family of callbacks, including on_body_fill_buffer
1244
+ * which will write into the target buffer. Set up the buffer
1245
+ * for it to write into _unless_ we got an auth failure; in
1246
+ * that case we only care about the headers and don't need to
1247
+ * bother copying the body.
1248
+ */
733
1249
  ctx.t = t;
734
1250
  ctx.s = s;
735
- ctx.buffer = buffer;
736
- ctx.buf_size = buf_size;
1251
+ ctx.buffer = auth_replay ? NULL : buffer;
1252
+ ctx.buf_size = auth_replay ? 0 : buf_size;
737
1253
  ctx.bytes_read = bytes_read;
738
1254
 
739
1255
  /* Set the context, call the parser, then unset the context. */
@@ -746,33 +1262,40 @@ replay:
746
1262
 
747
1263
  t->parser.data = NULL;
748
1264
 
749
- /* If there was a handled authentication failure, then parse_error
750
- * will have signaled us that we should replay the request. */
751
- if (PARSE_ERROR_REPLAY == t->parse_error) {
752
- s->sent_request = 0;
753
-
754
- if ((error = http_connect(t)) < 0)
755
- return error;
756
-
757
- goto replay;
758
- }
759
-
760
- if (t->parse_error == PARSE_ERROR_EXT) {
761
- return t->error;
1265
+ /* On a 401, read the rest of the response then retry. */
1266
+ if (t->parse_error == PARSE_ERROR_REPLAY) {
1267
+ auth_replay = true;
1268
+ } else if (t->parse_error == PARSE_ERROR_EXT) {
1269
+ error = t->error;
1270
+ goto done;
1271
+ } else if (t->parse_error < 0) {
1272
+ error = -1;
1273
+ goto done;
762
1274
  }
763
1275
 
764
- if (t->parse_error < 0)
765
- return -1;
766
-
767
1276
  if (bytes_parsed != t->parse_buffer.offset - data_offset) {
768
- giterr_set(GITERR_NET,
1277
+ git_error_set(GIT_ERROR_NET,
769
1278
  "HTTP parser error: %s",
770
1279
  http_errno_description((enum http_errno)t->parser.http_errno));
771
- return -1;
1280
+ error = -1;
1281
+ goto done;
772
1282
  }
773
1283
  }
774
1284
 
775
- return 0;
1285
+ t->request_count++;
1286
+
1287
+ if (auth_replay) {
1288
+ s->sent_request = 0;
1289
+
1290
+ if ((error = http_connect(t)) < 0)
1291
+ return error;
1292
+
1293
+ goto replay;
1294
+ }
1295
+
1296
+ done:
1297
+ git_buf_dispose(&request);
1298
+ return error;
776
1299
  }
777
1300
 
778
1301
  static int http_stream_write_chunked(
@@ -780,7 +1303,7 @@ static int http_stream_write_chunked(
780
1303
  const char *buffer,
781
1304
  size_t len)
782
1305
  {
783
- http_stream *s = (http_stream *)stream;
1306
+ http_stream *s = GIT_CONTAINER_OF(stream, http_stream, parent);
784
1307
  http_subtransport *t = OWNING_SUBTRANSPORT(s);
785
1308
 
786
1309
  assert(t->connected);
@@ -794,12 +1317,13 @@ static int http_stream_write_chunked(
794
1317
  if (gen_request(&request, s, 0) < 0)
795
1318
  return -1;
796
1319
 
797
- if (git_stream_write(t->io, request.ptr, request.size, 0) < 0) {
798
- git_buf_free(&request);
1320
+ if (git_stream__write_full(t->server.stream, request.ptr,
1321
+ request.size, 0) < 0) {
1322
+ git_buf_dispose(&request);
799
1323
  return -1;
800
1324
  }
801
1325
 
802
- git_buf_free(&request);
1326
+ git_buf_dispose(&request);
803
1327
 
804
1328
  s->sent_request = 1;
805
1329
  }
@@ -807,22 +1331,25 @@ static int http_stream_write_chunked(
807
1331
  if (len > CHUNK_SIZE) {
808
1332
  /* Flush, if necessary */
809
1333
  if (s->chunk_buffer_len > 0) {
810
- if (write_chunk(t->io, s->chunk_buffer, s->chunk_buffer_len) < 0)
1334
+ if (write_chunk(t->server.stream,
1335
+ s->chunk_buffer, s->chunk_buffer_len) < 0)
811
1336
  return -1;
812
1337
 
813
1338
  s->chunk_buffer_len = 0;
814
1339
  }
815
1340
 
816
1341
  /* Write chunk directly */
817
- if (write_chunk(t->io, buffer, len) < 0)
1342
+ if (write_chunk(t->server.stream, buffer, len) < 0)
818
1343
  return -1;
819
1344
  }
820
1345
  else {
821
1346
  /* Append as much to the buffer as we can */
822
1347
  int count = min(CHUNK_SIZE - s->chunk_buffer_len, len);
823
1348
 
824
- if (!s->chunk_buffer)
1349
+ if (!s->chunk_buffer) {
825
1350
  s->chunk_buffer = git__malloc(CHUNK_SIZE);
1351
+ GIT_ERROR_CHECK_ALLOC(s->chunk_buffer);
1352
+ }
826
1353
 
827
1354
  memcpy(s->chunk_buffer + s->chunk_buffer_len, buffer, count);
828
1355
  s->chunk_buffer_len += count;
@@ -831,7 +1358,8 @@ static int http_stream_write_chunked(
831
1358
 
832
1359
  /* Is the buffer full? If so, then flush */
833
1360
  if (CHUNK_SIZE == s->chunk_buffer_len) {
834
- if (write_chunk(t->io, s->chunk_buffer, s->chunk_buffer_len) < 0)
1361
+ if (write_chunk(t->server.stream,
1362
+ s->chunk_buffer, s->chunk_buffer_len) < 0)
835
1363
  return -1;
836
1364
 
837
1365
  s->chunk_buffer_len = 0;
@@ -851,14 +1379,14 @@ static int http_stream_write_single(
851
1379
  const char *buffer,
852
1380
  size_t len)
853
1381
  {
854
- http_stream *s = (http_stream *)stream;
1382
+ http_stream *s = GIT_CONTAINER_OF(stream, http_stream, parent);
855
1383
  http_subtransport *t = OWNING_SUBTRANSPORT(s);
856
1384
  git_buf request = GIT_BUF_INIT;
857
1385
 
858
1386
  assert(t->connected);
859
1387
 
860
1388
  if (s->sent_request) {
861
- giterr_set(GITERR_NET, "subtransport configured for only one write");
1389
+ git_error_set(GIT_ERROR_NET, "subtransport configured for only one write");
862
1390
  return -1;
863
1391
  }
864
1392
 
@@ -867,25 +1395,25 @@ static int http_stream_write_single(
867
1395
  if (gen_request(&request, s, len) < 0)
868
1396
  return -1;
869
1397
 
870
- if (git_stream_write(t->io, request.ptr, request.size, 0) < 0)
1398
+ if (git_stream__write_full(t->server.stream, request.ptr, request.size, 0) < 0)
871
1399
  goto on_error;
872
1400
 
873
- if (len && git_stream_write(t->io, buffer, len, 0) < 0)
1401
+ if (len && git_stream__write_full(t->server.stream, buffer, len, 0) < 0)
874
1402
  goto on_error;
875
1403
 
876
- git_buf_free(&request);
1404
+ git_buf_dispose(&request);
877
1405
  s->sent_request = 1;
878
1406
 
879
1407
  return 0;
880
1408
 
881
1409
  on_error:
882
- git_buf_free(&request);
1410
+ git_buf_dispose(&request);
883
1411
  return -1;
884
1412
  }
885
1413
 
886
1414
  static void http_stream_free(git_smart_subtransport_stream *stream)
887
1415
  {
888
- http_stream *s = (http_stream *)stream;
1416
+ http_stream *s = GIT_CONTAINER_OF(stream, http_stream, parent);
889
1417
 
890
1418
  if (s->chunk_buffer)
891
1419
  git__free(s->chunk_buffer);
@@ -905,7 +1433,7 @@ static int http_stream_alloc(http_subtransport *t,
905
1433
  return -1;
906
1434
 
907
1435
  s = git__calloc(sizeof(http_stream), 1);
908
- GITERR_CHECK_ALLOC(s);
1436
+ GIT_ERROR_CHECK_ALLOC(s);
909
1437
 
910
1438
  s->parent.subtransport = &t->parent;
911
1439
  s->parent.read = http_stream_read;
@@ -998,16 +1526,24 @@ static int http_action(
998
1526
  const char *url,
999
1527
  git_smart_service_t action)
1000
1528
  {
1001
- http_subtransport *t = (http_subtransport *)subtransport;
1529
+ http_subtransport *t = GIT_CONTAINER_OF(subtransport, http_subtransport, parent);
1002
1530
  int ret;
1003
1531
 
1004
- if (!stream)
1005
- return -1;
1532
+ assert(stream);
1006
1533
 
1007
- if ((!t->connection_data.host || !t->connection_data.port || !t->connection_data.path) &&
1008
- (ret = gitno_connection_data_from_url(&t->connection_data, url, NULL)) < 0)
1534
+ /*
1535
+ * If we've seen a redirect then preserve the location that we've
1536
+ * been given. This is important to continue authorization against
1537
+ * the redirect target, not the user-given source; the endpoint may
1538
+ * have redirected us from HTTP->HTTPS and is using an auth mechanism
1539
+ * that would be insecure in plaintext (eg, HTTP Basic).
1540
+ */
1541
+ if ((!t->server.url.host || !t->server.url.port || !t->server.url.path) &&
1542
+ (ret = git_net_url_parse(&t->server.url, url)) < 0)
1009
1543
  return ret;
1010
1544
 
1545
+ assert(t->server.url.host && t->server.url.port && t->server.url.path);
1546
+
1011
1547
  if ((ret = http_connect(t)) < 0)
1012
1548
  return ret;
1013
1549
 
@@ -1031,50 +1567,47 @@ static int http_action(
1031
1567
 
1032
1568
  static int http_close(git_smart_subtransport *subtransport)
1033
1569
  {
1034
- http_subtransport *t = (http_subtransport *) subtransport;
1035
- git_http_auth_context *context;
1036
- size_t i;
1570
+ http_subtransport *t = GIT_CONTAINER_OF(subtransport, http_subtransport, parent);
1037
1571
 
1038
1572
  clear_parser_state(t);
1039
1573
 
1040
1574
  t->connected = 0;
1041
1575
 
1042
- if (t->io) {
1043
- git_stream_close(t->io);
1044
- git_stream_free(t->io);
1045
- t->io = NULL;
1576
+ if (t->server.stream) {
1577
+ git_stream_close(t->server.stream);
1578
+ git_stream_free(t->server.stream);
1579
+ t->server.stream = NULL;
1046
1580
  }
1047
1581
 
1048
- if (t->cred) {
1049
- t->cred->free(t->cred);
1050
- t->cred = NULL;
1582
+ if (t->proxy.stream) {
1583
+ git_stream_close(t->proxy.stream);
1584
+ git_stream_free(t->proxy.stream);
1585
+ t->proxy.stream = NULL;
1051
1586
  }
1052
1587
 
1053
- if (t->url_cred) {
1054
- t->url_cred->free(t->url_cred);
1055
- t->url_cred = NULL;
1056
- }
1588
+ free_cred(&t->server.cred);
1589
+ free_cred(&t->proxy.cred);
1057
1590
 
1058
- git_vector_foreach(&t->auth_contexts, i, context) {
1059
- if (context->free)
1060
- context->free(context);
1061
- }
1591
+ free_auth_context(&t->server);
1592
+ free_auth_context(&t->proxy);
1593
+
1594
+ t->server.url_cred_presented = false;
1595
+ t->proxy.url_cred_presented = false;
1062
1596
 
1063
- git_vector_clear(&t->auth_contexts);
1597
+ git_net_url_dispose(&t->server.url);
1598
+ git_net_url_dispose(&t->proxy.url);
1064
1599
 
1065
- gitno_connection_data_free_ptrs(&t->connection_data);
1066
- memset(&t->connection_data, 0x0, sizeof(gitno_connection_data));
1600
+ git__free(t->proxy_url);
1601
+ t->proxy_url = NULL;
1067
1602
 
1068
1603
  return 0;
1069
1604
  }
1070
1605
 
1071
1606
  static void http_free(git_smart_subtransport *subtransport)
1072
1607
  {
1073
- http_subtransport *t = (http_subtransport *) subtransport;
1608
+ http_subtransport *t = GIT_CONTAINER_OF(subtransport, http_subtransport, parent);
1074
1609
 
1075
1610
  http_close(subtransport);
1076
-
1077
- git_vector_free(&t->auth_contexts);
1078
1611
  git__free(t);
1079
1612
  }
1080
1613
 
@@ -1088,7 +1621,7 @@ int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *own
1088
1621
  return -1;
1089
1622
 
1090
1623
  t = git__calloc(sizeof(http_subtransport), 1);
1091
- GITERR_CHECK_ALLOC(t);
1624
+ GIT_ERROR_CHECK_ALLOC(t);
1092
1625
 
1093
1626
  t->owner = (transport_smart *)owner;
1094
1627
  t->parent.action = http_action;