rugged 0.19.0 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (668) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +1 -1
  3. data/README.md +184 -33
  4. data/ext/rugged/extconf.rb +111 -28
  5. data/ext/rugged/rugged.c +327 -89
  6. data/ext/rugged/rugged.h +64 -28
  7. data/ext/rugged/rugged_allocator.c +89 -0
  8. data/ext/rugged/rugged_backend.c +17 -0
  9. data/ext/rugged/rugged_blame.c +278 -0
  10. data/ext/rugged/rugged_blob.c +301 -75
  11. data/ext/rugged/rugged_branch.c +92 -242
  12. data/ext/rugged/rugged_branch_collection.c +388 -0
  13. data/ext/rugged/rugged_commit.c +575 -79
  14. data/ext/rugged/rugged_config.c +129 -36
  15. data/ext/rugged/rugged_cred.c +131 -0
  16. data/ext/rugged/rugged_diff.c +291 -122
  17. data/ext/rugged/rugged_diff_delta.c +16 -22
  18. data/ext/rugged/rugged_diff_hunk.c +35 -51
  19. data/ext/rugged/rugged_diff_line.c +23 -36
  20. data/ext/rugged/rugged_index.c +289 -152
  21. data/ext/rugged/rugged_note.c +50 -60
  22. data/ext/rugged/rugged_object.c +13 -30
  23. data/ext/rugged/rugged_patch.c +400 -0
  24. data/ext/rugged/rugged_rebase.c +397 -0
  25. data/ext/rugged/rugged_reference.c +76 -346
  26. data/ext/rugged/rugged_reference_collection.c +423 -0
  27. data/ext/rugged/rugged_remote.c +438 -461
  28. data/ext/rugged/rugged_remote_collection.c +435 -0
  29. data/ext/rugged/rugged_repo.c +1548 -365
  30. data/ext/rugged/rugged_revwalk.c +378 -99
  31. data/ext/rugged/rugged_settings.c +86 -23
  32. data/ext/rugged/rugged_signature.c +47 -37
  33. data/ext/rugged/rugged_submodule.c +835 -0
  34. data/ext/rugged/rugged_submodule_collection.c +366 -0
  35. data/ext/rugged/rugged_tag.c +88 -210
  36. data/ext/rugged/rugged_tag_collection.c +326 -0
  37. data/ext/rugged/rugged_tree.c +460 -217
  38. data/lib/rugged/attributes.rb +46 -0
  39. data/lib/rugged/blob.rb +33 -0
  40. data/lib/rugged/branch.rb +12 -16
  41. data/lib/rugged/commit.rb +9 -0
  42. data/lib/rugged/console.rb +5 -0
  43. data/lib/rugged/credentials.rb +48 -0
  44. data/lib/rugged/diff/delta.rb +6 -2
  45. data/lib/rugged/diff/hunk.rb +9 -9
  46. data/lib/rugged/diff/line.rb +28 -5
  47. data/lib/rugged/diff.rb +7 -1
  48. data/lib/rugged/index.rb +120 -0
  49. data/lib/rugged/object.rb +5 -0
  50. data/lib/rugged/patch.rb +41 -0
  51. data/lib/rugged/reference.rb +6 -3
  52. data/lib/rugged/remote.rb +5 -9
  53. data/lib/rugged/repository.rb +126 -14
  54. data/lib/rugged/submodule_collection.rb +53 -0
  55. data/lib/rugged/tag.rb +45 -16
  56. data/lib/rugged/tree.rb +163 -1
  57. data/lib/rugged/version.rb +6 -1
  58. data/lib/rugged/walker.rb +5 -0
  59. data/lib/rugged.rb +16 -1
  60. data/vendor/libgit2/AUTHORS +77 -0
  61. data/vendor/libgit2/CMakeLists.txt +317 -0
  62. data/vendor/libgit2/COPYING +993 -0
  63. data/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake +30 -0
  64. data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.c.in +29 -0
  65. data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.cmake +96 -0
  66. data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +11 -0
  67. data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +26 -0
  68. data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +324 -0
  69. data/vendor/libgit2/cmake/Modules/FindHTTP_Parser.cmake +39 -0
  70. data/vendor/libgit2/cmake/Modules/FindIconv.cmake +45 -0
  71. data/vendor/libgit2/cmake/Modules/FindPkgLibraries.cmake +28 -0
  72. data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +28 -0
  73. data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +20 -0
  74. data/vendor/libgit2/cmake/Modules/FindmbedTLS.cmake +93 -0
  75. data/vendor/libgit2/cmake/Modules/IdeSplitSources.cmake +22 -0
  76. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +5 -0
  77. data/vendor/libgit2/deps/http-parser/COPYING +23 -0
  78. data/vendor/libgit2/deps/http-parser/http_parser.c +5 -2
  79. data/vendor/libgit2/deps/http-parser/http_parser.h +2 -0
  80. data/vendor/libgit2/deps/regex/CMakeLists.txt +2 -0
  81. data/vendor/libgit2/deps/regex/COPYING +502 -0
  82. data/vendor/libgit2/deps/regex/regex.c +10 -3
  83. data/vendor/libgit2/deps/winhttp/CMakeLists.txt +26 -0
  84. data/vendor/libgit2/deps/winhttp/COPYING.GPL +993 -0
  85. data/vendor/libgit2/deps/winhttp/COPYING.LGPL +502 -0
  86. data/vendor/libgit2/deps/winhttp/urlmon.h +45 -0
  87. data/vendor/libgit2/deps/winhttp/winhttp.def +29 -0
  88. data/vendor/libgit2/deps/winhttp/winhttp.h +594 -0
  89. data/vendor/libgit2/deps/winhttp/winhttp64.def +29 -0
  90. data/vendor/libgit2/deps/zlib/CMakeLists.txt +5 -0
  91. data/vendor/libgit2/deps/zlib/COPYING +27 -0
  92. data/vendor/libgit2/deps/zlib/adler32.c +51 -34
  93. data/vendor/libgit2/deps/zlib/crc32.c +61 -61
  94. data/vendor/libgit2/deps/zlib/crc32.h +1 -1
  95. data/vendor/libgit2/deps/zlib/deflate.c +681 -352
  96. data/vendor/libgit2/deps/zlib/deflate.h +25 -18
  97. data/vendor/libgit2/deps/zlib/gzguts.h +218 -0
  98. data/vendor/libgit2/deps/zlib/infback.c +640 -0
  99. data/vendor/libgit2/deps/zlib/inffast.c +36 -53
  100. data/vendor/libgit2/deps/zlib/inffixed.h +3 -3
  101. data/vendor/libgit2/deps/zlib/inflate.c +167 -86
  102. data/vendor/libgit2/deps/zlib/inflate.h +7 -4
  103. data/vendor/libgit2/deps/zlib/inftrees.c +24 -50
  104. data/vendor/libgit2/deps/zlib/trees.c +55 -96
  105. data/vendor/libgit2/deps/zlib/zconf.h +499 -19
  106. data/vendor/libgit2/deps/zlib/zlib.h +526 -227
  107. data/vendor/libgit2/deps/zlib/zutil.c +39 -32
  108. data/vendor/libgit2/deps/zlib/zutil.h +75 -78
  109. data/vendor/libgit2/include/git2/annotated_commit.h +125 -0
  110. data/vendor/libgit2/include/git2/apply.h +129 -0
  111. data/vendor/libgit2/include/git2/attr.h +36 -21
  112. data/vendor/libgit2/include/git2/blame.h +229 -0
  113. data/vendor/libgit2/include/git2/blob.h +81 -44
  114. data/vendor/libgit2/include/git2/branch.h +81 -42
  115. data/vendor/libgit2/include/git2/buffer.h +128 -0
  116. data/vendor/libgit2/include/git2/checkout.h +141 -67
  117. data/vendor/libgit2/include/git2/cherrypick.h +92 -0
  118. data/vendor/libgit2/include/git2/clone.h +157 -58
  119. data/vendor/libgit2/include/git2/commit.h +231 -12
  120. data/vendor/libgit2/include/git2/common.h +216 -30
  121. data/vendor/libgit2/include/git2/config.h +274 -48
  122. data/vendor/libgit2/include/git2/cred_helpers.h +4 -4
  123. data/vendor/libgit2/include/git2/deprecated.h +253 -0
  124. data/vendor/libgit2/include/git2/describe.h +189 -0
  125. data/vendor/libgit2/include/git2/diff.h +985 -575
  126. data/vendor/libgit2/include/git2/errors.h +93 -52
  127. data/vendor/libgit2/include/git2/filter.h +217 -0
  128. data/vendor/libgit2/include/git2/global.h +44 -0
  129. data/vendor/libgit2/include/git2/graph.h +17 -0
  130. data/vendor/libgit2/include/git2/ignore.h +2 -2
  131. data/vendor/libgit2/include/git2/index.h +269 -94
  132. data/vendor/libgit2/include/git2/indexer.h +44 -12
  133. data/vendor/libgit2/include/git2/mailmap.h +115 -0
  134. data/vendor/libgit2/include/git2/merge.h +501 -64
  135. data/vendor/libgit2/include/git2/message.h +52 -17
  136. data/vendor/libgit2/include/git2/net.h +11 -5
  137. data/vendor/libgit2/include/git2/notes.h +120 -16
  138. data/vendor/libgit2/include/git2/object.h +62 -23
  139. data/vendor/libgit2/include/git2/odb.h +140 -24
  140. data/vendor/libgit2/include/git2/odb_backend.h +56 -12
  141. data/vendor/libgit2/include/git2/oid.h +17 -18
  142. data/vendor/libgit2/include/git2/oidarray.h +40 -0
  143. data/vendor/libgit2/include/git2/pack.h +86 -7
  144. data/vendor/libgit2/include/git2/patch.h +274 -0
  145. data/vendor/libgit2/include/git2/pathspec.h +280 -0
  146. data/vendor/libgit2/include/git2/proxy.h +96 -0
  147. data/vendor/libgit2/include/git2/rebase.h +323 -0
  148. data/vendor/libgit2/include/git2/reflog.h +12 -9
  149. data/vendor/libgit2/include/git2/refs.h +241 -46
  150. data/vendor/libgit2/include/git2/refspec.h +20 -4
  151. data/vendor/libgit2/include/git2/remote.h +636 -209
  152. data/vendor/libgit2/include/git2/repository.h +267 -57
  153. data/vendor/libgit2/include/git2/reset.h +36 -6
  154. data/vendor/libgit2/include/git2/revert.h +91 -0
  155. data/vendor/libgit2/include/git2/revparse.h +27 -16
  156. data/vendor/libgit2/include/git2/revwalk.h +78 -35
  157. data/vendor/libgit2/include/git2/signature.h +32 -5
  158. data/vendor/libgit2/include/git2/stash.h +160 -21
  159. data/vendor/libgit2/include/git2/status.h +92 -30
  160. data/vendor/libgit2/include/git2/submodule.h +226 -133
  161. data/vendor/libgit2/include/git2/sys/alloc.h +101 -0
  162. data/vendor/libgit2/include/git2/sys/commit.h +38 -4
  163. data/vendor/libgit2/include/git2/sys/config.h +68 -9
  164. data/vendor/libgit2/include/git2/sys/diff.h +94 -0
  165. data/vendor/libgit2/include/git2/sys/filter.h +332 -0
  166. data/vendor/libgit2/include/git2/sys/hashsig.h +106 -0
  167. data/vendor/libgit2/include/git2/sys/index.h +6 -5
  168. data/vendor/libgit2/include/git2/sys/mempack.h +86 -0
  169. data/vendor/libgit2/include/git2/sys/merge.h +182 -0
  170. data/vendor/libgit2/include/git2/sys/odb_backend.h +66 -28
  171. data/vendor/libgit2/include/git2/sys/openssl.h +38 -0
  172. data/vendor/libgit2/include/git2/sys/path.h +64 -0
  173. data/vendor/libgit2/include/git2/sys/refdb_backend.h +79 -19
  174. data/vendor/libgit2/include/git2/sys/reflog.h +21 -0
  175. data/vendor/libgit2/include/git2/sys/refs.h +13 -2
  176. data/vendor/libgit2/include/git2/sys/repository.h +64 -1
  177. data/vendor/libgit2/include/git2/sys/stream.h +138 -0
  178. data/vendor/libgit2/include/git2/sys/time.h +31 -0
  179. data/vendor/libgit2/include/git2/sys/transport.h +439 -0
  180. data/vendor/libgit2/include/git2/tag.h +11 -2
  181. data/vendor/libgit2/include/git2/trace.h +1 -1
  182. data/vendor/libgit2/include/git2/transaction.h +121 -0
  183. data/vendor/libgit2/include/git2/transport.h +261 -292
  184. data/vendor/libgit2/include/git2/tree.h +111 -21
  185. data/vendor/libgit2/include/git2/types.h +244 -32
  186. data/vendor/libgit2/include/git2/version.h +5 -2
  187. data/vendor/libgit2/include/git2/worktree.h +255 -0
  188. data/vendor/libgit2/include/git2.h +50 -40
  189. data/vendor/libgit2/libgit2.pc.in +13 -0
  190. data/vendor/libgit2/src/CMakeLists.txt +525 -0
  191. data/vendor/libgit2/src/alloc.c +55 -0
  192. data/vendor/libgit2/src/alloc.h +40 -0
  193. data/vendor/libgit2/src/annotated_commit.c +228 -0
  194. data/vendor/libgit2/src/annotated_commit.h +52 -0
  195. data/vendor/libgit2/src/apply.c +855 -0
  196. data/vendor/libgit2/src/apply.h +25 -0
  197. data/vendor/libgit2/src/array.h +74 -16
  198. data/vendor/libgit2/src/attr.c +239 -408
  199. data/vendor/libgit2/src/attr.h +3 -33
  200. data/vendor/libgit2/src/attr_file.c +424 -156
  201. data/vendor/libgit2/src/attr_file.h +95 -23
  202. data/vendor/libgit2/src/attrcache.c +469 -0
  203. data/vendor/libgit2/src/attrcache.h +37 -5
  204. data/vendor/libgit2/src/bitvec.h +75 -0
  205. data/vendor/libgit2/src/blame.c +532 -0
  206. data/vendor/libgit2/src/blame.h +95 -0
  207. data/vendor/libgit2/src/blame_git.c +668 -0
  208. data/vendor/libgit2/src/blame_git.h +22 -0
  209. data/vendor/libgit2/src/blob.c +233 -129
  210. data/vendor/libgit2/src/blob.h +29 -1
  211. data/vendor/libgit2/src/branch.c +295 -197
  212. data/vendor/libgit2/src/branch.h +2 -0
  213. data/vendor/libgit2/src/buf_text.c +52 -27
  214. data/vendor/libgit2/src/buf_text.h +7 -7
  215. data/vendor/libgit2/src/buffer.c +609 -52
  216. data/vendor/libgit2/src/buffer.h +68 -23
  217. data/vendor/libgit2/src/cache.c +48 -51
  218. data/vendor/libgit2/src/cache.h +6 -4
  219. data/vendor/libgit2/src/cc-compat.h +35 -7
  220. data/vendor/libgit2/src/checkout.c +1827 -483
  221. data/vendor/libgit2/src/checkout.h +4 -1
  222. data/vendor/libgit2/src/cherrypick.c +230 -0
  223. data/vendor/libgit2/src/clone.c +338 -258
  224. data/vendor/libgit2/src/{compress.h → clone.h} +5 -5
  225. data/vendor/libgit2/src/commit.c +711 -124
  226. data/vendor/libgit2/src/commit.h +10 -3
  227. data/vendor/libgit2/src/commit_list.c +21 -14
  228. data/vendor/libgit2/src/commit_list.h +9 -3
  229. data/vendor/libgit2/src/common.h +153 -13
  230. data/vendor/libgit2/src/config.c +871 -242
  231. data/vendor/libgit2/src/config.h +58 -14
  232. data/vendor/libgit2/src/config_backend.h +84 -0
  233. data/vendor/libgit2/src/config_cache.c +44 -18
  234. data/vendor/libgit2/src/config_entries.c +259 -0
  235. data/vendor/libgit2/src/config_entries.h +23 -0
  236. data/vendor/libgit2/src/config_file.c +837 -1113
  237. data/vendor/libgit2/src/config_mem.c +224 -0
  238. data/vendor/libgit2/src/config_parse.c +558 -0
  239. data/vendor/libgit2/src/config_parse.h +64 -0
  240. data/vendor/libgit2/src/crlf.c +290 -195
  241. data/vendor/libgit2/src/date.c +35 -7
  242. data/vendor/libgit2/src/delta.c +275 -71
  243. data/vendor/libgit2/src/delta.h +80 -58
  244. data/vendor/libgit2/src/describe.c +893 -0
  245. data/vendor/libgit2/src/diff.c +330 -1128
  246. data/vendor/libgit2/src/diff.h +25 -67
  247. data/vendor/libgit2/src/diff_driver.c +225 -109
  248. data/vendor/libgit2/src/diff_driver.h +5 -2
  249. data/vendor/libgit2/src/diff_file.c +128 -103
  250. data/vendor/libgit2/src/diff_file.h +17 -12
  251. data/vendor/libgit2/src/diff_generate.c +1622 -0
  252. data/vendor/libgit2/src/diff_generate.h +128 -0
  253. data/vendor/libgit2/src/diff_parse.c +108 -0
  254. data/vendor/libgit2/src/diff_parse.h +20 -0
  255. data/vendor/libgit2/src/diff_print.c +578 -218
  256. data/vendor/libgit2/src/diff_stats.c +362 -0
  257. data/vendor/libgit2/src/diff_tform.c +429 -257
  258. data/vendor/libgit2/src/diff_tform.h +25 -0
  259. data/vendor/libgit2/src/diff_xdiff.c +143 -46
  260. data/vendor/libgit2/src/diff_xdiff.h +12 -5
  261. data/vendor/libgit2/src/errors.c +150 -34
  262. data/vendor/libgit2/src/features.h.in +37 -0
  263. data/vendor/libgit2/src/fetch.c +69 -46
  264. data/vendor/libgit2/src/fetch.h +6 -12
  265. data/vendor/libgit2/src/fetchhead.c +40 -33
  266. data/vendor/libgit2/src/fetchhead.h +5 -4
  267. data/vendor/libgit2/src/filebuf.c +163 -61
  268. data/vendor/libgit2/src/filebuf.h +13 -7
  269. data/vendor/libgit2/src/fileops.c +549 -407
  270. data/vendor/libgit2/src/fileops.h +97 -106
  271. data/vendor/libgit2/src/filter.c +989 -46
  272. data/vendor/libgit2/src/filter.h +21 -70
  273. data/vendor/libgit2/src/fnmatch.c +67 -11
  274. data/vendor/libgit2/src/fnmatch.h +27 -7
  275. data/vendor/libgit2/src/global.c +257 -63
  276. data/vendor/libgit2/src/global.h +19 -0
  277. data/vendor/libgit2/src/graph.c +39 -23
  278. data/vendor/libgit2/src/hash/hash_collisiondetect.h +51 -0
  279. data/vendor/libgit2/src/hash/hash_common_crypto.h +61 -0
  280. data/vendor/libgit2/src/hash/hash_generic.c +3 -3
  281. data/vendor/libgit2/src/hash/hash_generic.h +10 -5
  282. data/vendor/libgit2/src/hash/hash_mbedtls.c +38 -0
  283. data/vendor/libgit2/src/hash/hash_mbedtls.h +24 -0
  284. data/vendor/libgit2/src/hash/hash_openssl.h +26 -8
  285. data/vendor/libgit2/src/hash/hash_win32.c +71 -43
  286. data/vendor/libgit2/src/hash/hash_win32.h +4 -3
  287. data/vendor/libgit2/src/hash/sha1dc/sha1.c +1900 -0
  288. data/vendor/libgit2/src/hash/sha1dc/sha1.h +110 -0
  289. data/vendor/libgit2/src/hash/sha1dc/ubc_check.c +372 -0
  290. data/vendor/libgit2/src/hash/sha1dc/ubc_check.h +52 -0
  291. data/vendor/libgit2/src/hash.c +0 -1
  292. data/vendor/libgit2/src/hash.h +13 -6
  293. data/vendor/libgit2/src/hashsig.c +121 -126
  294. data/vendor/libgit2/src/ident.c +129 -0
  295. data/vendor/libgit2/src/idxmap.c +153 -0
  296. data/vendor/libgit2/src/idxmap.h +41 -0
  297. data/vendor/libgit2/src/ignore.c +362 -123
  298. data/vendor/libgit2/src/ignore.h +16 -4
  299. data/vendor/libgit2/src/index.c +2131 -692
  300. data/vendor/libgit2/src/index.h +138 -6
  301. data/vendor/libgit2/src/indexer.c +866 -266
  302. data/vendor/libgit2/src/indexer.h +16 -0
  303. data/vendor/libgit2/src/integer.h +106 -0
  304. data/vendor/libgit2/src/iterator.c +1888 -967
  305. data/vendor/libgit2/src/iterator.h +130 -67
  306. data/vendor/libgit2/src/khash.h +43 -29
  307. data/vendor/libgit2/src/mailmap.c +485 -0
  308. data/vendor/libgit2/src/mailmap.h +35 -0
  309. data/vendor/libgit2/src/map.h +1 -1
  310. data/vendor/libgit2/src/merge.c +1679 -479
  311. data/vendor/libgit2/src/merge.h +89 -22
  312. data/vendor/libgit2/src/merge_driver.c +426 -0
  313. data/vendor/libgit2/src/merge_driver.h +62 -0
  314. data/vendor/libgit2/src/merge_file.c +238 -101
  315. data/vendor/libgit2/src/message.c +4 -28
  316. data/vendor/libgit2/src/message.h +3 -1
  317. data/vendor/libgit2/src/mwindow.c +123 -15
  318. data/vendor/libgit2/src/mwindow.h +10 -1
  319. data/vendor/libgit2/src/netops.c +178 -499
  320. data/vendor/libgit2/src/netops.h +51 -27
  321. data/vendor/libgit2/src/notes.c +251 -94
  322. data/vendor/libgit2/src/notes.h +5 -2
  323. data/vendor/libgit2/src/object.c +253 -67
  324. data/vendor/libgit2/src/object.h +40 -2
  325. data/vendor/libgit2/src/object_api.c +30 -11
  326. data/vendor/libgit2/src/odb.c +765 -201
  327. data/vendor/libgit2/src/odb.h +40 -8
  328. data/vendor/libgit2/src/odb_loose.c +560 -346
  329. data/vendor/libgit2/src/odb_mempack.c +185 -0
  330. data/vendor/libgit2/src/odb_pack.c +117 -73
  331. data/vendor/libgit2/src/offmap.c +113 -0
  332. data/vendor/libgit2/src/offmap.h +32 -42
  333. data/vendor/libgit2/src/oid.c +45 -25
  334. data/vendor/libgit2/src/oid.h +26 -8
  335. data/vendor/libgit2/src/oidarray.c +34 -0
  336. data/vendor/libgit2/src/oidarray.h +20 -0
  337. data/vendor/libgit2/src/oidmap.c +125 -0
  338. data/vendor/libgit2/src/oidmap.h +30 -17
  339. data/vendor/libgit2/src/pack-objects.c +688 -265
  340. data/vendor/libgit2/src/pack-objects.h +27 -13
  341. data/vendor/libgit2/src/pack.c +418 -202
  342. data/vendor/libgit2/src/pack.h +25 -16
  343. data/vendor/libgit2/src/parse.c +124 -0
  344. data/vendor/libgit2/src/parse.h +61 -0
  345. data/vendor/libgit2/src/patch.c +223 -0
  346. data/vendor/libgit2/src/patch.h +68 -0
  347. data/vendor/libgit2/src/patch_generate.c +901 -0
  348. data/vendor/libgit2/src/patch_generate.h +69 -0
  349. data/vendor/libgit2/src/patch_parse.c +1136 -0
  350. data/vendor/libgit2/src/patch_parse.h +51 -0
  351. data/vendor/libgit2/src/path.c +1247 -241
  352. data/vendor/libgit2/src/path.h +353 -57
  353. data/vendor/libgit2/src/pathspec.c +586 -58
  354. data/vendor/libgit2/src/pathspec.h +37 -15
  355. data/vendor/libgit2/src/pool.c +134 -221
  356. data/vendor/libgit2/src/pool.h +38 -50
  357. data/vendor/libgit2/src/posix.c +76 -10
  358. data/vendor/libgit2/src/posix.h +74 -32
  359. data/vendor/libgit2/src/pqueue.c +79 -117
  360. data/vendor/libgit2/src/pqueue.h +38 -82
  361. data/vendor/libgit2/src/proxy.c +39 -0
  362. data/vendor/libgit2/src/proxy.h +17 -0
  363. data/vendor/libgit2/src/push.c +178 -279
  364. data/vendor/libgit2/src/push.h +93 -4
  365. data/vendor/libgit2/src/reader.c +265 -0
  366. data/vendor/libgit2/src/reader.h +107 -0
  367. data/vendor/libgit2/src/rebase.c +1364 -0
  368. data/vendor/libgit2/src/refdb.c +74 -19
  369. data/vendor/libgit2/src/refdb.h +16 -3
  370. data/vendor/libgit2/src/refdb_fs.c +1472 -603
  371. data/vendor/libgit2/src/refdb_fs.h +4 -0
  372. data/vendor/libgit2/src/reflog.c +40 -330
  373. data/vendor/libgit2/src/reflog.h +8 -2
  374. data/vendor/libgit2/src/refs.c +641 -225
  375. data/vendor/libgit2/src/refs.h +53 -6
  376. data/vendor/libgit2/src/refspec.c +175 -62
  377. data/vendor/libgit2/src/refspec.h +10 -25
  378. data/vendor/libgit2/src/remote.c +1741 -723
  379. data/vendor/libgit2/src/remote.h +17 -5
  380. data/vendor/libgit2/src/repository.c +1505 -421
  381. data/vendor/libgit2/src/repository.h +95 -15
  382. data/vendor/libgit2/src/reset.c +63 -26
  383. data/vendor/libgit2/src/revert.c +232 -0
  384. data/vendor/libgit2/src/revparse.c +94 -80
  385. data/vendor/libgit2/src/revwalk.c +427 -194
  386. data/vendor/libgit2/src/revwalk.h +14 -5
  387. data/vendor/libgit2/src/settings.c +290 -0
  388. data/vendor/libgit2/src/sha1_lookup.c +16 -159
  389. data/vendor/libgit2/src/sha1_lookup.h +5 -4
  390. data/vendor/libgit2/src/signature.c +138 -26
  391. data/vendor/libgit2/src/signature.h +5 -0
  392. data/vendor/libgit2/src/sortedcache.c +395 -0
  393. data/vendor/libgit2/src/sortedcache.h +180 -0
  394. data/vendor/libgit2/src/stash.c +629 -168
  395. data/vendor/libgit2/src/status.c +125 -75
  396. data/vendor/libgit2/src/status.h +4 -2
  397. data/vendor/libgit2/src/stdalloc.c +120 -0
  398. data/vendor/libgit2/src/stdalloc.h +17 -0
  399. data/vendor/libgit2/src/stream.h +86 -0
  400. data/vendor/libgit2/src/streams/mbedtls.c +483 -0
  401. data/vendor/libgit2/src/streams/mbedtls.h +23 -0
  402. data/vendor/libgit2/src/streams/openssl.c +789 -0
  403. data/vendor/libgit2/src/streams/openssl.h +23 -0
  404. data/vendor/libgit2/src/streams/registry.c +118 -0
  405. data/vendor/libgit2/src/streams/registry.h +19 -0
  406. data/vendor/libgit2/src/streams/socket.c +235 -0
  407. data/vendor/libgit2/src/streams/socket.h +23 -0
  408. data/vendor/libgit2/src/streams/stransport.c +323 -0
  409. data/vendor/libgit2/src/streams/stransport.h +21 -0
  410. data/vendor/libgit2/src/streams/tls.c +73 -0
  411. data/vendor/libgit2/src/streams/tls.h +31 -0
  412. data/vendor/libgit2/src/strmap.c +147 -0
  413. data/vendor/libgit2/src/strmap.h +46 -51
  414. data/vendor/libgit2/src/strnlen.h +24 -0
  415. data/vendor/libgit2/src/submodule.c +1633 -877
  416. data/vendor/libgit2/src/submodule.h +83 -21
  417. data/vendor/libgit2/src/sysdir.c +355 -0
  418. data/vendor/libgit2/src/sysdir.h +119 -0
  419. data/vendor/libgit2/src/tag.c +87 -62
  420. data/vendor/libgit2/src/tag.h +4 -1
  421. data/vendor/libgit2/src/thread-utils.c +3 -0
  422. data/vendor/libgit2/src/thread-utils.h +71 -35
  423. data/vendor/libgit2/src/trace.c +4 -4
  424. data/vendor/libgit2/src/trace.h +11 -3
  425. data/vendor/libgit2/src/trailer.c +416 -0
  426. data/vendor/libgit2/src/transaction.c +382 -0
  427. data/vendor/libgit2/src/transaction.h +14 -0
  428. data/vendor/libgit2/src/transport.c +133 -67
  429. data/vendor/libgit2/src/transports/auth.c +75 -0
  430. data/vendor/libgit2/src/transports/auth.h +64 -0
  431. data/vendor/libgit2/src/transports/auth_negotiate.c +277 -0
  432. data/vendor/libgit2/src/transports/auth_negotiate.h +27 -0
  433. data/vendor/libgit2/src/transports/cred.c +296 -68
  434. data/vendor/libgit2/src/transports/cred.h +16 -0
  435. data/vendor/libgit2/src/transports/cred_helpers.c +4 -0
  436. data/vendor/libgit2/src/transports/git.c +108 -90
  437. data/vendor/libgit2/src/transports/http.c +803 -258
  438. data/vendor/libgit2/src/transports/http.h +25 -0
  439. data/vendor/libgit2/src/transports/local.c +265 -169
  440. data/vendor/libgit2/src/transports/smart.c +255 -45
  441. data/vendor/libgit2/src/transports/smart.h +42 -22
  442. data/vendor/libgit2/src/transports/smart_pkt.c +250 -159
  443. data/vendor/libgit2/src/transports/smart_protocol.c +414 -196
  444. data/vendor/libgit2/src/transports/ssh.c +645 -236
  445. data/vendor/libgit2/src/transports/ssh.h +14 -0
  446. data/vendor/libgit2/src/transports/winhttp.c +809 -353
  447. data/vendor/libgit2/src/tree-cache.c +138 -52
  448. data/vendor/libgit2/src/tree-cache.h +14 -7
  449. data/vendor/libgit2/src/tree.c +620 -259
  450. data/vendor/libgit2/src/tree.h +12 -19
  451. data/vendor/libgit2/src/tsort.c +3 -2
  452. data/vendor/libgit2/src/unix/map.c +25 -7
  453. data/vendor/libgit2/src/unix/posix.h +77 -12
  454. data/vendor/libgit2/src/unix/pthread.h +56 -0
  455. data/vendor/libgit2/src/unix/realpath.c +12 -8
  456. data/vendor/libgit2/src/userdiff.h +208 -0
  457. data/vendor/libgit2/src/util.c +349 -165
  458. data/vendor/libgit2/src/util.h +167 -85
  459. data/vendor/libgit2/src/varint.c +43 -0
  460. data/vendor/libgit2/src/varint.h +17 -0
  461. data/vendor/libgit2/src/vector.c +156 -33
  462. data/vendor/libgit2/src/vector.h +41 -5
  463. data/vendor/libgit2/src/win32/dir.c +22 -42
  464. data/vendor/libgit2/src/win32/dir.h +7 -5
  465. data/vendor/libgit2/src/win32/error.c +6 -32
  466. data/vendor/libgit2/src/win32/error.h +4 -2
  467. data/vendor/libgit2/src/win32/findfile.c +62 -69
  468. data/vendor/libgit2/src/win32/findfile.h +5 -13
  469. data/vendor/libgit2/src/win32/git2.rc +44 -0
  470. data/vendor/libgit2/src/win32/map.c +39 -11
  471. data/vendor/libgit2/src/win32/mingw-compat.h +10 -11
  472. data/vendor/libgit2/src/win32/msvc-compat.h +10 -33
  473. data/vendor/libgit2/src/win32/path_w32.c +476 -0
  474. data/vendor/libgit2/src/win32/path_w32.h +104 -0
  475. data/vendor/libgit2/src/win32/posix.h +35 -30
  476. data/vendor/libgit2/src/win32/posix_w32.c +659 -327
  477. data/vendor/libgit2/src/win32/precompiled.h +7 -2
  478. data/vendor/libgit2/src/win32/reparse.h +57 -0
  479. data/vendor/libgit2/src/win32/thread.c +258 -0
  480. data/vendor/libgit2/src/win32/thread.h +64 -0
  481. data/vendor/libgit2/src/win32/utf-conv.c +127 -62
  482. data/vendor/libgit2/src/win32/utf-conv.h +47 -6
  483. data/vendor/libgit2/src/win32/version.h +21 -4
  484. data/vendor/libgit2/src/win32/w32_buffer.c +54 -0
  485. data/vendor/libgit2/src/win32/w32_buffer.h +20 -0
  486. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +438 -0
  487. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +129 -0
  488. data/vendor/libgit2/src/win32/w32_stack.c +193 -0
  489. data/vendor/libgit2/src/win32/w32_stack.h +140 -0
  490. data/vendor/libgit2/src/win32/w32_util.c +95 -0
  491. data/vendor/libgit2/src/win32/w32_util.h +170 -0
  492. data/vendor/libgit2/src/win32/win32-compat.h +52 -0
  493. data/vendor/libgit2/src/worktree.c +578 -0
  494. data/vendor/libgit2/src/worktree.h +39 -0
  495. data/vendor/libgit2/src/xdiff/xdiff.h +33 -18
  496. data/vendor/libgit2/src/xdiff/xdiffi.c +578 -88
  497. data/vendor/libgit2/src/xdiff/xdiffi.h +3 -2
  498. data/vendor/libgit2/src/xdiff/xemit.c +106 -45
  499. data/vendor/libgit2/src/xdiff/xemit.h +3 -3
  500. data/vendor/libgit2/src/xdiff/xhistogram.c +5 -4
  501. data/vendor/libgit2/src/xdiff/xinclude.h +3 -2
  502. data/vendor/libgit2/src/xdiff/xmacros.h +2 -2
  503. data/vendor/libgit2/src/xdiff/xmerge.c +167 -48
  504. data/vendor/libgit2/src/xdiff/xpatience.c +42 -10
  505. data/vendor/libgit2/src/xdiff/xprepare.c +14 -14
  506. data/vendor/libgit2/src/xdiff/xprepare.h +2 -2
  507. data/vendor/libgit2/src/xdiff/xtypes.h +2 -2
  508. data/vendor/libgit2/src/xdiff/xutils.c +60 -56
  509. data/vendor/libgit2/src/xdiff/xutils.h +3 -5
  510. data/vendor/libgit2/src/zstream.c +205 -0
  511. data/vendor/libgit2/src/zstream.h +53 -0
  512. metadata +281 -233
  513. data/Rakefile +0 -61
  514. data/ext/rugged/rugged_diff_patch.c +0 -169
  515. data/lib/rugged/diff/patch.rb +0 -28
  516. data/test/blob_test.rb +0 -341
  517. data/test/branch_test.rb +0 -199
  518. data/test/commit_test.rb +0 -104
  519. data/test/config_test.rb +0 -45
  520. data/test/coverage/cover.rb +0 -133
  521. data/test/diff_test.rb +0 -777
  522. data/test/errors_test.rb +0 -34
  523. data/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 +0 -0
  524. data/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 +0 -0
  525. data/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f +0 -0
  526. data/test/fixtures/archive.tar.gz +0 -0
  527. data/test/fixtures/attr/attr0 +0 -1
  528. data/test/fixtures/attr/attr1 +0 -29
  529. data/test/fixtures/attr/attr2 +0 -21
  530. data/test/fixtures/attr/attr3 +0 -4
  531. data/test/fixtures/attr/binfile +0 -1
  532. data/test/fixtures/attr/dir/file +0 -0
  533. data/test/fixtures/attr/file +0 -1
  534. data/test/fixtures/attr/gitattributes +0 -29
  535. data/test/fixtures/attr/gitignore +0 -2
  536. data/test/fixtures/attr/ign +0 -1
  537. data/test/fixtures/attr/macro_bad +0 -1
  538. data/test/fixtures/attr/macro_test +0 -1
  539. data/test/fixtures/attr/root_test1 +0 -1
  540. data/test/fixtures/attr/root_test2 +0 -6
  541. data/test/fixtures/attr/root_test3 +0 -19
  542. data/test/fixtures/attr/root_test4.txt +0 -14
  543. data/test/fixtures/attr/sub/abc +0 -37
  544. data/test/fixtures/attr/sub/dir/file +0 -0
  545. data/test/fixtures/attr/sub/file +0 -1
  546. data/test/fixtures/attr/sub/ign/file +0 -1
  547. data/test/fixtures/attr/sub/ign/sub/file +0 -1
  548. data/test/fixtures/attr/sub/sub/dir +0 -0
  549. data/test/fixtures/attr/sub/sub/file +0 -1
  550. data/test/fixtures/attr/sub/sub/subsub.txt +0 -1
  551. data/test/fixtures/attr/sub/subdir_test1 +0 -2
  552. data/test/fixtures/attr/sub/subdir_test2.txt +0 -1
  553. data/test/fixtures/diff/another.txt +0 -38
  554. data/test/fixtures/diff/readme.txt +0 -36
  555. data/test/fixtures/mergedrepo/conflicts-one.txt +0 -5
  556. data/test/fixtures/mergedrepo/conflicts-two.txt +0 -5
  557. data/test/fixtures/mergedrepo/one.txt +0 -10
  558. data/test/fixtures/mergedrepo/two.txt +0 -12
  559. data/test/fixtures/status/current_file +0 -1
  560. data/test/fixtures/status/ignored_file +0 -1
  561. data/test/fixtures/status/modified_file +0 -2
  562. data/test/fixtures/status/new_file +0 -1
  563. data/test/fixtures/status/staged_changes +0 -2
  564. data/test/fixtures/status/staged_changes_modified_file +0 -3
  565. data/test/fixtures/status/staged_delete_modified_file +0 -1
  566. data/test/fixtures/status/staged_new_file +0 -1
  567. data/test/fixtures/status/staged_new_file_modified_file +0 -2
  568. data/test/fixtures/status/subdir/current_file +0 -1
  569. data/test/fixtures/status/subdir/modified_file +0 -2
  570. data/test/fixtures/status/subdir/new_file +0 -1
  571. data/test/fixtures/status/subdir.txt +0 -2
  572. data/test/fixtures/status//350/277/231 +0 -1
  573. data/test/fixtures/testrepo.git/HEAD +0 -1
  574. data/test/fixtures/testrepo.git/config +0 -13
  575. data/test/fixtures/testrepo.git/description +0 -1
  576. data/test/fixtures/testrepo.git/index +0 -0
  577. data/test/fixtures/testrepo.git/info/exclude +0 -6
  578. data/test/fixtures/testrepo.git/logs/HEAD +0 -3
  579. data/test/fixtures/testrepo.git/logs/refs/heads/master +0 -3
  580. data/test/fixtures/testrepo.git/logs/refs/notes/commits +0 -1
  581. data/test/fixtures/testrepo.git/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d +0 -0
  582. data/test/fixtures/testrepo.git/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 +0 -0
  583. data/test/fixtures/testrepo.git/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 +0 -0
  584. data/test/fixtures/testrepo.git/objects/18/10dff58d8a660512d4832e740f692884338ccd +0 -0
  585. data/test/fixtures/testrepo.git/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2 +0 -0
  586. data/test/fixtures/testrepo.git/objects/36/060c58702ed4c2a40832c51758d5344201d89a +0 -2
  587. data/test/fixtures/testrepo.git/objects/44/1034f860c1d5d90e4188d11ae0d325176869a8 +0 -1
  588. data/test/fixtures/testrepo.git/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 +0 -0
  589. data/test/fixtures/testrepo.git/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 +0 -2
  590. data/test/fixtures/testrepo.git/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 +0 -2
  591. data/test/fixtures/testrepo.git/objects/60/d415052a33de2150bf68757f6461df4f563ae4 +0 -0
  592. data/test/fixtures/testrepo.git/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96 +0 -0
  593. data/test/fixtures/testrepo.git/objects/68/8a8f4ef7496901d15322972f96e212a9e466cc +0 -1
  594. data/test/fixtures/testrepo.git/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a +0 -0
  595. data/test/fixtures/testrepo.git/objects/77/71329dfa3002caf8c61a0ceb62a31d09023f37 +0 -0
  596. data/test/fixtures/testrepo.git/objects/81/4889a078c031f61ed08ab5fa863aea9314344d +0 -0
  597. data/test/fixtures/testrepo.git/objects/84/96071c1b46c854b31185ea97743be6a8774479 +0 -0
  598. data/test/fixtures/testrepo.git/objects/94/eca2de348d5f672faf56b0decafa5937e3235e +0 -0
  599. data/test/fixtures/testrepo.git/objects/9b/7384fe1676186192842f5d3e129457b62db9e3 +0 -0
  600. data/test/fixtures/testrepo.git/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a +0 -3
  601. data/test/fixtures/testrepo.git/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f +0 -2
  602. data/test/fixtures/testrepo.git/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd +0 -0
  603. data/test/fixtures/testrepo.git/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 +0 -0
  604. data/test/fixtures/testrepo.git/objects/b7/4713326bc972cc15751ed504dca6f6f3b91f7a +0 -3
  605. data/test/fixtures/testrepo.git/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 +0 -3
  606. data/test/fixtures/testrepo.git/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd +0 -3
  607. data/test/fixtures/testrepo.git/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b +0 -0
  608. data/test/fixtures/testrepo.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 +0 -0
  609. data/test/fixtures/testrepo.git/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 +0 -0
  610. data/test/fixtures/testrepo.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 +0 -0
  611. data/test/fixtures/testrepo.git/objects/fd/093bff70906175335656e6ce6ae05783708765 +0 -0
  612. data/test/fixtures/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx +0 -0
  613. data/test/fixtures/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack +0 -0
  614. data/test/fixtures/testrepo.git/packed-refs +0 -2
  615. data/test/fixtures/testrepo.git/refs/heads/master +0 -1
  616. data/test/fixtures/testrepo.git/refs/notes/commits +0 -1
  617. data/test/fixtures/testrepo.git/refs/tags/v0.9 +0 -1
  618. data/test/fixtures/testrepo.git/refs/tags/v1.0 +0 -1
  619. data/test/fixtures/text_file.md +0 -464
  620. data/test/fixtures/unsymlinked.git/HEAD +0 -1
  621. data/test/fixtures/unsymlinked.git/config +0 -6
  622. data/test/fixtures/unsymlinked.git/description +0 -1
  623. data/test/fixtures/unsymlinked.git/info/exclude +0 -2
  624. data/test/fixtures/unsymlinked.git/objects/08/8b64704e0d6b8bd061dea879418cb5442a3fbf +0 -0
  625. data/test/fixtures/unsymlinked.git/objects/13/a5e939bca25940c069fd2169d993dba328e30b +0 -0
  626. data/test/fixtures/unsymlinked.git/objects/19/bf568e59e3a0b363cafb4106226e62d4a4c41c +0 -0
  627. data/test/fixtures/unsymlinked.git/objects/58/1fadd35b4cf320d102a152f918729011604773 +0 -0
  628. data/test/fixtures/unsymlinked.git/objects/5c/87b6791e8b13da658a14d1ef7e09b5dc3bac8c +0 -0
  629. data/test/fixtures/unsymlinked.git/objects/6f/e5f5398af85fb3de8a6aba0339b6d3bfa26a27 +0 -0
  630. data/test/fixtures/unsymlinked.git/objects/7f/ccd75616ec188b8f1b23d67506a334cc34a49d +0 -0
  631. data/test/fixtures/unsymlinked.git/objects/80/6999882bf91d24241e4077906b9017605eb1f3 +0 -0
  632. data/test/fixtures/unsymlinked.git/objects/83/7d176303c5005505ec1e4a30231c40930c0230 +0 -0
  633. data/test/fixtures/unsymlinked.git/objects/a8/595ccca04f40818ae0155c8f9c77a230e597b6 +0 -2
  634. data/test/fixtures/unsymlinked.git/objects/cf/8f1cf5cce859c438d6cc067284cb5e161206e7 +0 -0
  635. data/test/fixtures/unsymlinked.git/objects/d5/278d05c8607ec420bfee4cf219fbc0eeebfd6a +0 -0
  636. data/test/fixtures/unsymlinked.git/objects/f4/e16fb76536591a41454194058d048d8e4dd2e9 +0 -0
  637. data/test/fixtures/unsymlinked.git/objects/f9/e65619d93fdf2673882e0a261c5e93b1a84006 +0 -0
  638. data/test/fixtures/unsymlinked.git/refs/heads/exe-file +0 -1
  639. data/test/fixtures/unsymlinked.git/refs/heads/master +0 -1
  640. data/test/fixtures/unsymlinked.git/refs/heads/reg-file +0 -1
  641. data/test/index_test.rb +0 -333
  642. data/test/lib_test.rb +0 -127
  643. data/test/note_test.rb +0 -158
  644. data/test/object_test.rb +0 -43
  645. data/test/reference_test.rb +0 -207
  646. data/test/remote_test.rb +0 -324
  647. data/test/repo_pack_test.rb +0 -24
  648. data/test/repo_reset_test.rb +0 -82
  649. data/test/repo_test.rb +0 -402
  650. data/test/tag_test.rb +0 -68
  651. data/test/test_helper.rb +0 -92
  652. data/test/tree_test.rb +0 -91
  653. data/test/walker_test.rb +0 -88
  654. data/vendor/libgit2/Makefile.embed +0 -42
  655. data/vendor/libgit2/include/git2/push.h +0 -131
  656. data/vendor/libgit2/include/git2/threads.h +0 -50
  657. data/vendor/libgit2/src/amiga/map.c +0 -48
  658. data/vendor/libgit2/src/bswap.h +0 -97
  659. data/vendor/libgit2/src/compress.c +0 -53
  660. data/vendor/libgit2/src/config_file.h +0 -60
  661. data/vendor/libgit2/src/delta-apply.c +0 -134
  662. data/vendor/libgit2/src/delta-apply.h +0 -50
  663. data/vendor/libgit2/src/diff_patch.c +0 -995
  664. data/vendor/libgit2/src/diff_patch.h +0 -46
  665. data/vendor/libgit2/src/hashsig.h +0 -72
  666. data/vendor/libgit2/src/merge_file.h +0 -71
  667. data/vendor/libgit2/src/win32/pthread.c +0 -144
  668. data/vendor/libgit2/src/win32/pthread.h +0 -50
@@ -5,6 +5,8 @@
5
5
  * a Linking Exception. For full terms see the included COPYING file.
6
6
  */
7
7
 
8
+ #include "common.h"
9
+
8
10
  #ifdef GIT_WINHTTP
9
11
 
10
12
  #include "git2.h"
@@ -15,14 +17,15 @@
15
17
  #include "smart.h"
16
18
  #include "remote.h"
17
19
  #include "repository.h"
20
+ #include "global.h"
21
+ #include "http.h"
18
22
 
23
+ #include <wincrypt.h>
19
24
  #include <winhttp.h>
20
- #pragma comment(lib, "winhttp")
21
-
22
- #include <strsafe.h>
23
25
 
24
- /* For UuidCreate */
25
- #pragma comment(lib, "rpcrt4")
26
+ /* For IInternetSecurityManager zone check */
27
+ #include <objbase.h>
28
+ #include <urlmon.h>
26
29
 
27
30
  #define WIDEN2(s) L ## s
28
31
  #define WIDEN(s) WIDEN2(s)
@@ -31,8 +34,20 @@
31
34
  #define WINHTTP_OPTION_PEERDIST_EXTENSION_STATE 109
32
35
  #define CACHED_POST_BODY_BUF_SIZE 4096
33
36
  #define UUID_LENGTH_CCH 32
37
+ #define TIMEOUT_INFINITE -1
38
+ #define DEFAULT_CONNECT_TIMEOUT 60000
39
+ #ifndef WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH
40
+ #define WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH 0
41
+ #endif
42
+
43
+ #ifndef WINHTTP_FLAG_SECURE_PROTOCOL_TLS_1_1
44
+ # define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 0x00000200
45
+ #endif
46
+
47
+ #ifndef WINHTTP_FLAG_SECURE_PROTOCOL_TLS_1_2
48
+ # define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 0x00000800
49
+ #endif
34
50
 
35
- static const char *prefix_http = "http://";
36
51
  static const char *prefix_https = "https://";
37
52
  static const char *upload_pack_service = "upload-pack";
38
53
  static const char *upload_pack_ls_service_url = "/info/refs?service=git-upload-pack";
@@ -48,10 +63,25 @@ static const int no_check_cert_flags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
48
63
  SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
49
64
  SECURITY_FLAG_IGNORE_UNKNOWN_CA;
50
65
 
66
+ #if defined(__MINGW32__)
67
+ static const CLSID CLSID_InternetSecurityManager_mingw =
68
+ { 0x7B8A2D94, 0x0AC9, 0x11D1,
69
+ { 0x89, 0x6C, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4 } };
70
+ static const IID IID_IInternetSecurityManager_mingw =
71
+ { 0x79EAC9EE, 0xBAF9, 0x11CE,
72
+ { 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B } };
73
+
74
+ # define CLSID_InternetSecurityManager CLSID_InternetSecurityManager_mingw
75
+ # define IID_IInternetSecurityManager IID_IInternetSecurityManager_mingw
76
+ #endif
77
+
51
78
  #define OWNING_SUBTRANSPORT(s) ((winhttp_subtransport *)(s)->parent.subtransport)
52
79
 
53
80
  typedef enum {
54
81
  GIT_WINHTTP_AUTH_BASIC = 1,
82
+ GIT_WINHTTP_AUTH_NTLM = 2,
83
+ GIT_WINHTTP_AUTH_NEGOTIATE = 4,
84
+ GIT_WINHTTP_AUTH_DIGEST = 8,
55
85
  } winhttp_authmechanism_t;
56
86
 
57
87
  typedef struct {
@@ -73,109 +103,259 @@ typedef struct {
73
103
  typedef struct {
74
104
  git_smart_subtransport parent;
75
105
  transport_smart *owner;
76
- const char *path;
77
- char *host;
78
- char *port;
79
- char *user_from_url;
80
- char *pass_from_url;
106
+ gitno_connection_data connection_data;
107
+ gitno_connection_data proxy_connection_data;
81
108
  git_cred *cred;
82
109
  git_cred *url_cred;
83
- int auth_mechanism;
110
+ git_cred *proxy_cred;
111
+ int auth_mechanisms;
84
112
  HINTERNET session;
85
113
  HINTERNET connection;
86
- unsigned use_ssl : 1;
87
114
  } winhttp_subtransport;
88
115
 
89
- static int apply_basic_credential(HINTERNET request, git_cred *cred)
116
+ static int _apply_userpass_credential(HINTERNET request, DWORD target, DWORD scheme, git_cred *cred)
90
117
  {
91
118
  git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
92
- git_buf buf = GIT_BUF_INIT, raw = GIT_BUF_INIT;
93
- wchar_t *wide = NULL;
94
- int error = -1, wide_len = 0;
119
+ wchar_t *user, *pass;
120
+ int user_len = 0, pass_len = 0, error = 0;
95
121
 
96
- git_buf_printf(&raw, "%s:%s", c->username, c->password);
122
+ if ((error = user_len = git__utf8_to_16_alloc(&user, c->username)) < 0)
123
+ goto done;
97
124
 
98
- if (git_buf_oom(&raw) ||
99
- git_buf_puts(&buf, "Authorization: Basic ") < 0 ||
100
- git_buf_put_base64(&buf, git_buf_cstr(&raw), raw.size) < 0)
101
- goto on_error;
125
+ if ((error = pass_len = git__utf8_to_16_alloc(&pass, c->password)) < 0)
126
+ goto done;
102
127
 
103
- wide_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
104
- git_buf_cstr(&buf), -1, NULL, 0);
128
+ if (!WinHttpSetCredentials(request, target, scheme, user, pass, NULL)) {
129
+ git_error_set(GIT_ERROR_OS, "failed to set credentials");
130
+ error = -1;
131
+ }
105
132
 
106
- if (!wide_len) {
107
- giterr_set(GITERR_OS, "Failed to measure string for wide conversion");
108
- goto on_error;
133
+ done:
134
+ if (user_len > 0)
135
+ git__memzero(user, user_len * sizeof(wchar_t));
136
+
137
+ if (pass_len > 0)
138
+ git__memzero(pass, pass_len * sizeof(wchar_t));
139
+
140
+ git__free(user);
141
+ git__free(pass);
142
+
143
+ return error;
144
+ }
145
+
146
+ static int apply_userpass_credential_proxy(HINTERNET request, git_cred *cred, int mechanisms)
147
+ {
148
+ if (GIT_WINHTTP_AUTH_DIGEST & mechanisms) {
149
+ return _apply_userpass_credential(request, WINHTTP_AUTH_TARGET_PROXY,
150
+ WINHTTP_AUTH_SCHEME_DIGEST, cred);
109
151
  }
110
152
 
111
- wide = git__malloc(wide_len * sizeof(wchar_t));
153
+ return _apply_userpass_credential(request, WINHTTP_AUTH_TARGET_PROXY,
154
+ WINHTTP_AUTH_SCHEME_BASIC, cred);
155
+ }
112
156
 
113
- if (!wide)
114
- goto on_error;
157
+ static int apply_userpass_credential(HINTERNET request, int mechanisms, git_cred *cred)
158
+ {
159
+ DWORD native_scheme;
160
+
161
+ if ((mechanisms & GIT_WINHTTP_AUTH_NTLM) ||
162
+ (mechanisms & GIT_WINHTTP_AUTH_NEGOTIATE)) {
163
+ native_scheme = WINHTTP_AUTH_SCHEME_NTLM;
164
+ } else if (mechanisms & GIT_WINHTTP_AUTH_BASIC) {
165
+ native_scheme = WINHTTP_AUTH_SCHEME_BASIC;
166
+ } else {
167
+ git_error_set(GIT_ERROR_NET, "invalid authentication scheme");
168
+ return -1;
169
+ }
115
170
 
116
- if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
117
- git_buf_cstr(&buf), -1, wide, wide_len)) {
118
- giterr_set(GITERR_OS, "Failed to convert string to wide form");
119
- goto on_error;
171
+ return _apply_userpass_credential(request, WINHTTP_AUTH_TARGET_SERVER,
172
+ native_scheme, cred);
173
+ }
174
+
175
+ static int apply_default_credentials(HINTERNET request, int mechanisms)
176
+ {
177
+ /* Either the caller explicitly requested that default credentials be passed,
178
+ * or our fallback credential callback was invoked and checked that the target
179
+ * URI was in the appropriate Internet Explorer security zone. By setting this
180
+ * flag, we guarantee that the credentials are delivered by WinHTTP. The default
181
+ * is "medium" which applies to the intranet and sounds like it would correspond
182
+ * to Internet Explorer security zones, but in fact does not. */
183
+ DWORD data = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW;
184
+ DWORD native_scheme = 0;
185
+
186
+ if ((mechanisms & GIT_WINHTTP_AUTH_NTLM) != 0)
187
+ native_scheme = WINHTTP_AUTH_SCHEME_NTLM;
188
+
189
+ if ((mechanisms & GIT_WINHTTP_AUTH_NEGOTIATE) != 0)
190
+ native_scheme = WINHTTP_AUTH_SCHEME_NEGOTIATE;
191
+
192
+ if (!native_scheme) {
193
+ git_error_set(GIT_ERROR_NET, "invalid authentication scheme");
194
+ return -1;
120
195
  }
121
196
 
122
- if (!WinHttpAddRequestHeaders(request, wide, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) {
123
- giterr_set(GITERR_OS, "Failed to add a header to the request");
124
- goto on_error;
197
+ if (!WinHttpSetOption(request, WINHTTP_OPTION_AUTOLOGON_POLICY, &data, sizeof(DWORD)))
198
+ return -1;
199
+
200
+ if (!WinHttpSetCredentials(request, WINHTTP_AUTH_TARGET_SERVER, native_scheme, NULL, NULL, NULL))
201
+ return -1;
202
+
203
+ return 0;
204
+ }
205
+
206
+ static int fallback_cred_acquire_cb(
207
+ git_cred **cred,
208
+ const char *url,
209
+ const char *username_from_url,
210
+ unsigned int allowed_types,
211
+ void *payload)
212
+ {
213
+ int error = 1;
214
+
215
+ GIT_UNUSED(username_from_url);
216
+ GIT_UNUSED(payload);
217
+
218
+ /* If the target URI supports integrated Windows authentication
219
+ * as an authentication mechanism */
220
+ if (GIT_CREDTYPE_DEFAULT & allowed_types) {
221
+ wchar_t *wide_url;
222
+ HRESULT hCoInitResult;
223
+
224
+ /* Convert URL to wide characters */
225
+ if (git__utf8_to_16_alloc(&wide_url, url) < 0) {
226
+ git_error_set(GIT_ERROR_OS, "failed to convert string to wide form");
227
+ return -1;
228
+ }
229
+
230
+ hCoInitResult = CoInitializeEx(NULL, COINIT_MULTITHREADED);
231
+
232
+ if (SUCCEEDED(hCoInitResult) || hCoInitResult == RPC_E_CHANGED_MODE) {
233
+ IInternetSecurityManager* pISM;
234
+
235
+ /* And if the target URI is in the My Computer, Intranet, or Trusted zones */
236
+ if (SUCCEEDED(CoCreateInstance(&CLSID_InternetSecurityManager, NULL,
237
+ CLSCTX_ALL, &IID_IInternetSecurityManager, (void **)&pISM))) {
238
+ DWORD dwZone;
239
+
240
+ if (SUCCEEDED(pISM->lpVtbl->MapUrlToZone(pISM, wide_url, &dwZone, 0)) &&
241
+ (URLZONE_LOCAL_MACHINE == dwZone ||
242
+ URLZONE_INTRANET == dwZone ||
243
+ URLZONE_TRUSTED == dwZone)) {
244
+ git_cred *existing = *cred;
245
+
246
+ if (existing)
247
+ existing->free(existing);
248
+
249
+ /* Then use default Windows credentials to authenticate this request */
250
+ error = git_cred_default_new(cred);
251
+ }
252
+
253
+ pISM->lpVtbl->Release(pISM);
254
+ }
255
+
256
+ if (SUCCEEDED(hCoInitResult))
257
+ /* Only unitialize if the call to CoInitializeEx was successful. */
258
+ CoUninitialize();
259
+ }
260
+
261
+ git__free(wide_url);
125
262
  }
126
263
 
127
- error = 0;
264
+ return error;
265
+ }
128
266
 
129
- on_error:
130
- /* We were dealing with plaintext passwords, so clean up after ourselves a bit. */
131
- if (wide)
132
- memset(wide, 0x0, wide_len * sizeof(wchar_t));
267
+ static int certificate_check(winhttp_stream *s, int valid)
268
+ {
269
+ int error;
270
+ winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
271
+ PCERT_CONTEXT cert_ctx;
272
+ DWORD cert_ctx_size = sizeof(cert_ctx);
273
+ git_cert_x509 cert;
133
274
 
134
- if (buf.size)
135
- memset(buf.ptr, 0x0, buf.size);
275
+ /* If there is no override, we should fail if WinHTTP doesn't think it's fine */
276
+ if (t->owner->certificate_check_cb == NULL && !valid) {
277
+ if (!git_error_last())
278
+ git_error_set(GIT_ERROR_NET, "unknown certificate check failure");
136
279
 
137
- if (raw.size)
138
- memset(raw.ptr, 0x0, raw.size);
280
+ return GIT_ECERTIFICATE;
281
+ }
282
+
283
+ if (t->owner->certificate_check_cb == NULL || !t->connection_data.use_ssl)
284
+ return 0;
285
+
286
+ if (!WinHttpQueryOption(s->request, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert_ctx, &cert_ctx_size)) {
287
+ git_error_set(GIT_ERROR_OS, "failed to get server certificate");
288
+ return -1;
289
+ }
290
+
291
+ git_error_clear();
292
+ cert.parent.cert_type = GIT_CERT_X509;
293
+ cert.data = cert_ctx->pbCertEncoded;
294
+ cert.len = cert_ctx->cbCertEncoded;
295
+ error = t->owner->certificate_check_cb((git_cert *) &cert, valid, t->connection_data.host, t->owner->message_cb_payload);
296
+ CertFreeCertificateContext(cert_ctx);
297
+
298
+ if (error == GIT_PASSTHROUGH)
299
+ error = valid ? 0 : GIT_ECERTIFICATE;
300
+
301
+ if (error < 0 && !git_error_last())
302
+ git_error_set(GIT_ERROR_NET, "user cancelled certificate check");
139
303
 
140
- git__free(wide);
141
- git_buf_free(&buf);
142
- git_buf_free(&raw);
143
304
  return error;
144
305
  }
145
306
 
307
+ static void winhttp_stream_close(winhttp_stream *s)
308
+ {
309
+ if (s->chunk_buffer) {
310
+ git__free(s->chunk_buffer);
311
+ s->chunk_buffer = NULL;
312
+ }
313
+
314
+ if (s->post_body) {
315
+ CloseHandle(s->post_body);
316
+ s->post_body = NULL;
317
+ }
318
+
319
+ if (s->request_uri) {
320
+ git__free(s->request_uri);
321
+ s->request_uri = NULL;
322
+ }
323
+
324
+ if (s->request) {
325
+ WinHttpCloseHandle(s->request);
326
+ s->request = NULL;
327
+ }
328
+
329
+ s->sent_request = 0;
330
+ }
331
+
332
+ #define SCHEME_HTTP "http://"
333
+ #define SCHEME_HTTPS "https://"
334
+
146
335
  static int winhttp_stream_connect(winhttp_stream *s)
147
336
  {
148
337
  winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
149
338
  git_buf buf = GIT_BUF_INIT;
150
339
  char *proxy_url = NULL;
151
340
  wchar_t ct[MAX_CONTENT_TYPE_LEN];
152
- wchar_t *types[] = { L"*/*", NULL };
341
+ LPCWSTR types[] = { L"*/*", NULL };
153
342
  BOOL peerdist = FALSE;
154
- int error = -1, wide_len;
343
+ int error = -1;
344
+ unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS;
345
+ int default_timeout = TIMEOUT_INFINITE;
346
+ int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
347
+ size_t i;
348
+ const git_proxy_options *proxy_opts;
155
349
 
156
350
  /* Prepare URL */
157
- git_buf_printf(&buf, "%s%s", t->path, s->service_url);
351
+ git_buf_printf(&buf, "%s%s", t->connection_data.path, s->service_url);
158
352
 
159
353
  if (git_buf_oom(&buf))
160
354
  return -1;
161
355
 
162
356
  /* Convert URL to wide characters */
163
- wide_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
164
- git_buf_cstr(&buf), -1, NULL, 0);
165
-
166
- if (!wide_len) {
167
- giterr_set(GITERR_OS, "Failed to measure string for wide conversion");
168
- goto on_error;
169
- }
170
-
171
- s->request_uri = git__malloc(wide_len * sizeof(wchar_t));
172
-
173
- if (!s->request_uri)
174
- goto on_error;
175
-
176
- if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
177
- git_buf_cstr(&buf), -1, s->request_uri, wide_len)) {
178
- giterr_set(GITERR_OS, "Failed to convert string to wide form");
357
+ if (git__utf8_to_16_alloc(&s->request_uri, git_buf_cstr(&buf)) < 0) {
358
+ git_error_set(GIT_ERROR_OS, "failed to convert string to wide form");
179
359
  goto on_error;
180
360
  }
181
361
 
@@ -187,46 +367,77 @@ static int winhttp_stream_connect(winhttp_stream *s)
187
367
  NULL,
188
368
  WINHTTP_NO_REFERER,
189
369
  types,
190
- t->use_ssl ? WINHTTP_FLAG_SECURE : 0);
370
+ t->connection_data.use_ssl ? WINHTTP_FLAG_SECURE : 0);
191
371
 
192
372
  if (!s->request) {
193
- giterr_set(GITERR_OS, "Failed to open request");
373
+ git_error_set(GIT_ERROR_OS, "failed to open request");
194
374
  goto on_error;
195
375
  }
196
376
 
197
- /* Set proxy if necessary */
198
- if (git_remote__get_http_proxy(t->owner->owner, t->use_ssl, &proxy_url) < 0)
377
+ if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) {
378
+ git_error_set(GIT_ERROR_OS, "failed to set timeouts for WinHTTP");
199
379
  goto on_error;
380
+ }
381
+
382
+ proxy_opts = &t->owner->proxy;
383
+ if (proxy_opts->type == GIT_PROXY_AUTO) {
384
+ /* Set proxy if necessary */
385
+ if (git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url) < 0)
386
+ goto on_error;
387
+ }
388
+ else if (proxy_opts->type == GIT_PROXY_SPECIFIED) {
389
+ proxy_url = git__strdup(proxy_opts->url);
390
+ GIT_ERROR_CHECK_ALLOC(proxy_url);
391
+ }
200
392
 
201
393
  if (proxy_url) {
394
+ git_buf processed_url = GIT_BUF_INIT;
202
395
  WINHTTP_PROXY_INFO proxy_info;
203
396
  wchar_t *proxy_wide;
204
397
 
205
- /* Convert URL to wide characters */
206
- wide_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
207
- proxy_url, -1, NULL, 0);
398
+ if (!git__prefixcmp(proxy_url, SCHEME_HTTP)) {
399
+ t->proxy_connection_data.use_ssl = false;
400
+ } else if (!git__prefixcmp(proxy_url, SCHEME_HTTPS)) {
401
+ t->proxy_connection_data.use_ssl = true;
402
+ } else {
403
+ git_error_set(GIT_ERROR_NET, "invalid URL: '%s'", proxy_url);
404
+ return -1;
405
+ }
406
+
407
+ gitno_connection_data_free_ptrs(&t->proxy_connection_data);
208
408
 
209
- if (!wide_len) {
210
- giterr_set(GITERR_OS, "Failed to measure string for wide conversion");
409
+ if ((error = gitno_extract_url_parts(&t->proxy_connection_data.host, &t->proxy_connection_data.port, NULL,
410
+ &t->proxy_connection_data.user, &t->proxy_connection_data.pass, proxy_url, NULL)) < 0)
211
411
  goto on_error;
412
+
413
+ if (t->proxy_connection_data.user && t->proxy_connection_data.pass) {
414
+ if (t->proxy_cred) {
415
+ t->proxy_cred->free(t->proxy_cred);
416
+ }
417
+
418
+ if ((error = git_cred_userpass_plaintext_new(&t->proxy_cred, t->proxy_connection_data.user, t->proxy_connection_data.pass)) < 0)
419
+ goto on_error;
212
420
  }
213
421
 
214
- proxy_wide = git__malloc(wide_len * sizeof(wchar_t));
422
+ if (t->proxy_connection_data.use_ssl)
423
+ git_buf_PUTS(&processed_url, SCHEME_HTTPS);
424
+ else
425
+ git_buf_PUTS(&processed_url, SCHEME_HTTP);
215
426
 
216
- if (!proxy_wide)
217
- goto on_error;
427
+ git_buf_puts(&processed_url, t->proxy_connection_data.host);
428
+ if (t->proxy_connection_data.port)
429
+ git_buf_printf(&processed_url, ":%s", t->proxy_connection_data.port);
218
430
 
219
- if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
220
- proxy_url, -1, proxy_wide, wide_len)) {
221
- giterr_set(GITERR_OS, "Failed to convert string to wide form");
222
- git__free(proxy_wide);
431
+ if (git_buf_oom(&processed_url)) {
432
+ error = -1;
223
433
  goto on_error;
224
434
  }
225
435
 
226
- /* Strip any trailing forward slash on the proxy URL;
227
- * WinHTTP doesn't like it if one is present */
228
- if (wide_len > 1 && L'/' == proxy_wide[wide_len - 2])
229
- proxy_wide[wide_len - 2] = L'\0';
436
+ /* Convert URL to wide characters */
437
+ error = git__utf8_to_16_alloc(&proxy_wide, processed_url.ptr);
438
+ git_buf_dispose(&processed_url);
439
+ if (error < 0)
440
+ goto on_error;
230
441
 
231
442
  proxy_info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
232
443
  proxy_info.lpszProxy = proxy_wide;
@@ -236,12 +447,31 @@ static int winhttp_stream_connect(winhttp_stream *s)
236
447
  WINHTTP_OPTION_PROXY,
237
448
  &proxy_info,
238
449
  sizeof(WINHTTP_PROXY_INFO))) {
239
- giterr_set(GITERR_OS, "Failed to set proxy");
450
+ git_error_set(GIT_ERROR_OS, "failed to set proxy");
240
451
  git__free(proxy_wide);
241
452
  goto on_error;
242
453
  }
243
454
 
244
455
  git__free(proxy_wide);
456
+
457
+ if (t->proxy_cred) {
458
+ if (t->proxy_cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT) {
459
+ if ((error = apply_userpass_credential_proxy(s->request, t->proxy_cred, t->auth_mechanisms)) < 0)
460
+ goto on_error;
461
+ }
462
+ }
463
+
464
+ }
465
+
466
+ /* Disable WinHTTP redirects so we can handle them manually. Why, you ask?
467
+ * http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/b2ff8879-ab9f-4218-8f09-16d25dff87ae
468
+ */
469
+ if (!WinHttpSetOption(s->request,
470
+ WINHTTP_OPTION_DISABLE_FEATURE,
471
+ &disable_redirects,
472
+ sizeof(disable_redirects))) {
473
+ git_error_set(GIT_ERROR_OS, "failed to disable redirects");
474
+ goto on_error;
245
475
  }
246
476
 
247
477
  /* Strip unwanted headers (X-P2P-PeerDist, X-P2P-PeerDistEx) that WinHTTP
@@ -254,53 +484,89 @@ static int winhttp_stream_connect(winhttp_stream *s)
254
484
 
255
485
  /* Send Pragma: no-cache header */
256
486
  if (!WinHttpAddRequestHeaders(s->request, pragma_nocache, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) {
257
- giterr_set(GITERR_OS, "Failed to add a header to the request");
487
+ git_error_set(GIT_ERROR_OS, "failed to add a header to the request");
258
488
  goto on_error;
259
489
  }
260
490
 
261
- /* Send Content-Type header -- only necessary on a POST */
262
491
  if (post_verb == s->verb) {
492
+ /* Send Content-Type and Accept headers -- only necessary on a POST */
263
493
  git_buf_clear(&buf);
264
- if (git_buf_printf(&buf, "Content-Type: application/x-git-%s-request", s->service) < 0)
494
+ if (git_buf_printf(&buf,
495
+ "Content-Type: application/x-git-%s-request",
496
+ s->service) < 0)
265
497
  goto on_error;
266
498
 
267
- git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf));
499
+ if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) {
500
+ git_error_set(GIT_ERROR_OS, "failed to convert content-type to wide characters");
501
+ goto on_error;
502
+ }
503
+
504
+ if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
505
+ WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
506
+ git_error_set(GIT_ERROR_OS, "failed to add a header to the request");
507
+ goto on_error;
508
+ }
509
+
510
+ git_buf_clear(&buf);
511
+ if (git_buf_printf(&buf,
512
+ "Accept: application/x-git-%s-result",
513
+ s->service) < 0)
514
+ goto on_error;
515
+
516
+ if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) {
517
+ git_error_set(GIT_ERROR_OS, "failed to convert accept header to wide characters");
518
+ goto on_error;
519
+ }
268
520
 
269
- if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) {
270
- giterr_set(GITERR_OS, "Failed to add a header to the request");
521
+ if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
522
+ WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
523
+ git_error_set(GIT_ERROR_OS, "failed to add a header to the request");
271
524
  goto on_error;
272
525
  }
273
526
  }
274
527
 
528
+ for (i = 0; i < t->owner->custom_headers.count; i++) {
529
+ if (t->owner->custom_headers.strings[i]) {
530
+ git_buf_clear(&buf);
531
+ git_buf_puts(&buf, t->owner->custom_headers.strings[i]);
532
+ if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) {
533
+ git_error_set(GIT_ERROR_OS, "failed to convert custom header to wide characters");
534
+ goto on_error;
535
+ }
536
+
537
+ if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
538
+ WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
539
+ git_error_set(GIT_ERROR_OS, "failed to add a header to the request");
540
+ goto on_error;
541
+ }
542
+ }
543
+ }
544
+
275
545
  /* If requested, disable certificate validation */
276
- if (t->use_ssl) {
546
+ if (t->connection_data.use_ssl) {
277
547
  int flags;
278
548
 
279
549
  if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0)
280
550
  goto on_error;
281
-
282
- if ((GIT_TRANSPORTFLAGS_NO_CHECK_CERT & flags) &&
283
- !WinHttpSetOption(s->request, WINHTTP_OPTION_SECURITY_FLAGS,
284
- (LPVOID)&no_check_cert_flags, sizeof(no_check_cert_flags))) {
285
- giterr_set(GITERR_OS, "Failed to set options to ignore cert errors");
286
- goto on_error;
287
- }
288
551
  }
289
552
 
290
553
  /* If we have a credential on the subtransport, apply it to the request */
291
554
  if (t->cred &&
292
555
  t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT &&
293
- t->auth_mechanism == GIT_WINHTTP_AUTH_BASIC &&
294
- apply_basic_credential(s->request, t->cred) < 0)
556
+ apply_userpass_credential(s->request, t->auth_mechanisms, t->cred) < 0)
557
+ goto on_error;
558
+ else if (t->cred &&
559
+ t->cred->credtype == GIT_CREDTYPE_DEFAULT &&
560
+ apply_default_credentials(s->request, t->auth_mechanisms) < 0)
295
561
  goto on_error;
296
562
 
297
563
  /* If no other credentials have been applied and the URL has username and
298
564
  * password, use those */
299
- if (!t->cred && t->user_from_url && t->pass_from_url) {
565
+ if (!t->cred && t->connection_data.user && t->connection_data.pass) {
300
566
  if (!t->url_cred &&
301
- git_cred_userpass_plaintext_new(&t->url_cred, t->user_from_url, t->pass_from_url) < 0)
567
+ git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0)
302
568
  goto on_error;
303
- if (apply_basic_credential(s->request, t->url_cred) < 0)
569
+ if (apply_userpass_credential(s->request, GIT_WINHTTP_AUTH_BASIC, t->url_cred) < 0)
304
570
  goto on_error;
305
571
  }
306
572
 
@@ -309,32 +575,51 @@ static int winhttp_stream_connect(winhttp_stream *s)
309
575
  error = 0;
310
576
 
311
577
  on_error:
578
+ if (error < 0)
579
+ winhttp_stream_close(s);
580
+
312
581
  git__free(proxy_url);
313
- git_buf_free(&buf);
582
+ git_buf_dispose(&buf);
314
583
  return error;
315
584
  }
316
585
 
317
586
  static int parse_unauthorized_response(
318
587
  HINTERNET request,
319
588
  int *allowed_types,
320
- int *auth_mechanism)
589
+ int *allowed_mechanisms)
321
590
  {
322
591
  DWORD supported, first, target;
323
592
 
324
593
  *allowed_types = 0;
325
- *auth_mechanism = 0;
594
+ *allowed_mechanisms = 0;
326
595
 
327
- /* WinHttpQueryHeaders() must be called before WinHttpQueryAuthSchemes().
328
- * We can assume this was already done, since we know we are unauthorized.
596
+ /* WinHttpQueryHeaders() must be called before WinHttpQueryAuthSchemes().
597
+ * We can assume this was already done, since we know we are unauthorized.
329
598
  */
330
599
  if (!WinHttpQueryAuthSchemes(request, &supported, &first, &target)) {
331
- giterr_set(GITERR_OS, "Failed to parse supported auth schemes");
600
+ git_error_set(GIT_ERROR_OS, "failed to parse supported auth schemes");
332
601
  return -1;
333
602
  }
334
603
 
604
+ if (WINHTTP_AUTH_SCHEME_NTLM & supported) {
605
+ *allowed_types |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
606
+ *allowed_types |= GIT_CREDTYPE_DEFAULT;
607
+ *allowed_mechanisms |= GIT_WINHTTP_AUTH_NTLM;
608
+ }
609
+
610
+ if (WINHTTP_AUTH_SCHEME_NEGOTIATE & supported) {
611
+ *allowed_types |= GIT_CREDTYPE_DEFAULT;
612
+ *allowed_mechanisms |= GIT_WINHTTP_AUTH_NEGOTIATE;
613
+ }
614
+
335
615
  if (WINHTTP_AUTH_SCHEME_BASIC & supported) {
336
616
  *allowed_types |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
337
- *auth_mechanism = GIT_WINHTTP_AUTH_BASIC;
617
+ *allowed_mechanisms |= GIT_WINHTTP_AUTH_BASIC;
618
+ }
619
+
620
+ if (WINHTTP_AUTH_SCHEME_DIGEST & supported) {
621
+ *allowed_types |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
622
+ *allowed_mechanisms |= GIT_WINHTTP_AUTH_DIGEST;
338
623
  }
339
624
 
340
625
  return 0;
@@ -346,7 +631,7 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
346
631
  git_buf buf = GIT_BUF_INIT;
347
632
 
348
633
  /* Chunk header */
349
- git_buf_printf(&buf, "%X\r\n", len);
634
+ git_buf_printf(&buf, "%"PRIXZ"\r\n", len);
350
635
 
351
636
  if (git_buf_oom(&buf))
352
637
  return -1;
@@ -354,18 +639,18 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
354
639
  if (!WinHttpWriteData(request,
355
640
  git_buf_cstr(&buf), (DWORD)git_buf_len(&buf),
356
641
  &bytes_written)) {
357
- git_buf_free(&buf);
358
- giterr_set(GITERR_OS, "Failed to write chunk header");
642
+ git_buf_dispose(&buf);
643
+ git_error_set(GIT_ERROR_OS, "failed to write chunk header");
359
644
  return -1;
360
645
  }
361
646
 
362
- git_buf_free(&buf);
647
+ git_buf_dispose(&buf);
363
648
 
364
649
  /* Chunk body */
365
650
  if (!WinHttpWriteData(request,
366
651
  buffer, (DWORD)len,
367
652
  &bytes_written)) {
368
- giterr_set(GITERR_OS, "Failed to write chunk");
653
+ git_error_set(GIT_ERROR_OS, "failed to write chunk");
369
654
  return -1;
370
655
  }
371
656
 
@@ -373,13 +658,238 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
373
658
  if (!WinHttpWriteData(request,
374
659
  "\r\n", 2,
375
660
  &bytes_written)) {
376
- giterr_set(GITERR_OS, "Failed to write chunk footer");
661
+ git_error_set(GIT_ERROR_OS, "failed to write chunk footer");
377
662
  return -1;
378
663
  }
379
664
 
380
665
  return 0;
381
666
  }
382
667
 
668
+ static int winhttp_close_connection(winhttp_subtransport *t)
669
+ {
670
+ int ret = 0;
671
+
672
+ if (t->connection) {
673
+ if (!WinHttpCloseHandle(t->connection)) {
674
+ git_error_set(GIT_ERROR_OS, "unable to close connection");
675
+ ret = -1;
676
+ }
677
+
678
+ t->connection = NULL;
679
+ }
680
+
681
+ if (t->session) {
682
+ if (!WinHttpCloseHandle(t->session)) {
683
+ git_error_set(GIT_ERROR_OS, "unable to close session");
684
+ ret = -1;
685
+ }
686
+
687
+ t->session = NULL;
688
+ }
689
+
690
+ return ret;
691
+ }
692
+
693
+ static void CALLBACK winhttp_status(
694
+ HINTERNET connection,
695
+ DWORD_PTR ctx,
696
+ DWORD code,
697
+ LPVOID info,
698
+ DWORD info_len)
699
+ {
700
+ DWORD status;
701
+
702
+ if (code != WINHTTP_CALLBACK_STATUS_SECURE_FAILURE)
703
+ return;
704
+
705
+ status = *((DWORD *)info);
706
+
707
+ if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID))
708
+ git_error_set(GIT_ERROR_NET, "SSL certificate issued for different common name");
709
+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID))
710
+ git_error_set(GIT_ERROR_NET, "SSL certificate has expired");
711
+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA))
712
+ git_error_set(GIT_ERROR_NET, "SSL certificate signed by unknown CA");
713
+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT))
714
+ git_error_set(GIT_ERROR_NET, "SSL certificate is invalid");
715
+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED))
716
+ git_error_set(GIT_ERROR_NET, "certificate revocation check failed");
717
+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED))
718
+ git_error_set(GIT_ERROR_NET, "SSL certificate was revoked");
719
+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR))
720
+ git_error_set(GIT_ERROR_NET, "security libraries could not be loaded");
721
+ else
722
+ git_error_set(GIT_ERROR_NET, "unknown security error %lu", status);
723
+ }
724
+
725
+ static int winhttp_connect(
726
+ winhttp_subtransport *t)
727
+ {
728
+ wchar_t *wide_host;
729
+ int32_t port;
730
+ wchar_t *wide_ua;
731
+ git_buf ua = GIT_BUF_INIT;
732
+ int error = -1;
733
+ int default_timeout = TIMEOUT_INFINITE;
734
+ int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
735
+ DWORD protocols =
736
+ WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 |
737
+ WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 |
738
+ WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
739
+
740
+ t->session = NULL;
741
+ t->connection = NULL;
742
+
743
+ /* Prepare port */
744
+ if (git__strntol32(&port, t->connection_data.port,
745
+ strlen(t->connection_data.port), NULL, 10) < 0)
746
+ return -1;
747
+
748
+ /* Prepare host */
749
+ if (git__utf8_to_16_alloc(&wide_host, t->connection_data.host) < 0) {
750
+ git_error_set(GIT_ERROR_OS, "unable to convert host to wide characters");
751
+ return -1;
752
+ }
753
+
754
+
755
+ if ((error = git_http__user_agent(&ua)) < 0) {
756
+ git__free(wide_host);
757
+ return error;
758
+ }
759
+
760
+ if (git__utf8_to_16_alloc(&wide_ua, git_buf_cstr(&ua)) < 0) {
761
+ git_error_set(GIT_ERROR_OS, "unable to convert host to wide characters");
762
+ git__free(wide_host);
763
+ git_buf_dispose(&ua);
764
+ return -1;
765
+ }
766
+
767
+ git_buf_dispose(&ua);
768
+
769
+ /* Establish session */
770
+ t->session = WinHttpOpen(
771
+ wide_ua,
772
+ WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
773
+ WINHTTP_NO_PROXY_NAME,
774
+ WINHTTP_NO_PROXY_BYPASS,
775
+ 0);
776
+
777
+ if (!t->session) {
778
+ git_error_set(GIT_ERROR_OS, "failed to init WinHTTP");
779
+ goto on_error;
780
+ }
781
+
782
+ /*
783
+ * Do a best-effort attempt to enable TLS 1.2 but allow this to
784
+ * fail; if TLS 1.2 support is not available for some reason,
785
+ * ignore the failure (it will keep the default protocols).
786
+ */
787
+ WinHttpSetOption(t->session,
788
+ WINHTTP_OPTION_SECURE_PROTOCOLS,
789
+ &protocols,
790
+ sizeof(protocols));
791
+
792
+ if (!WinHttpSetTimeouts(t->session, default_timeout, default_connect_timeout, default_timeout, default_timeout)) {
793
+ git_error_set(GIT_ERROR_OS, "failed to set timeouts for WinHTTP");
794
+ goto on_error;
795
+ }
796
+
797
+
798
+ /* Establish connection */
799
+ t->connection = WinHttpConnect(
800
+ t->session,
801
+ wide_host,
802
+ (INTERNET_PORT) port,
803
+ 0);
804
+
805
+ if (!t->connection) {
806
+ git_error_set(GIT_ERROR_OS, "failed to connect to host");
807
+ goto on_error;
808
+ }
809
+
810
+ if (WinHttpSetStatusCallback(t->connection, winhttp_status, WINHTTP_CALLBACK_FLAG_SECURE_FAILURE, 0) == WINHTTP_INVALID_STATUS_CALLBACK) {
811
+ git_error_set(GIT_ERROR_OS, "failed to set status callback");
812
+ goto on_error;
813
+ }
814
+
815
+ error = 0;
816
+
817
+ on_error:
818
+ if (error < 0)
819
+ winhttp_close_connection(t);
820
+
821
+ git__free(wide_host);
822
+ git__free(wide_ua);
823
+
824
+ return error;
825
+ }
826
+
827
+ static int do_send_request(winhttp_stream *s, size_t len, int ignore_length)
828
+ {
829
+ int attempts;
830
+ bool success;
831
+
832
+ for (attempts = 0; attempts < 5; attempts++) {
833
+ if (ignore_length) {
834
+ success = WinHttpSendRequest(s->request,
835
+ WINHTTP_NO_ADDITIONAL_HEADERS, 0,
836
+ WINHTTP_NO_REQUEST_DATA, 0,
837
+ WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0);
838
+ } else {
839
+ success = WinHttpSendRequest(s->request,
840
+ WINHTTP_NO_ADDITIONAL_HEADERS, 0,
841
+ WINHTTP_NO_REQUEST_DATA, 0,
842
+ len, 0);
843
+ }
844
+
845
+ if (success || GetLastError() != (DWORD)SEC_E_BUFFER_TOO_SMALL)
846
+ break;
847
+ }
848
+
849
+ return success ? 0 : -1;
850
+ }
851
+
852
+ static int send_request(winhttp_stream *s, size_t len, int ignore_length)
853
+ {
854
+ int request_failed = 0, cert_valid = 1, error = 0;
855
+ DWORD ignore_flags;
856
+
857
+ git_error_clear();
858
+ if ((error = do_send_request(s, len, ignore_length)) < 0) {
859
+ if (GetLastError() != ERROR_WINHTTP_SECURE_FAILURE) {
860
+ git_error_set(GIT_ERROR_OS, "failed to send request");
861
+ return -1;
862
+ }
863
+
864
+ request_failed = 1;
865
+ cert_valid = 0;
866
+ }
867
+
868
+ git_error_clear();
869
+ if ((error = certificate_check(s, cert_valid)) < 0) {
870
+ if (!git_error_last())
871
+ git_error_set(GIT_ERROR_OS, "user cancelled certificate check");
872
+
873
+ return error;
874
+ }
875
+
876
+ /* if neither the request nor the certificate check returned errors, we're done */
877
+ if (!request_failed)
878
+ return 0;
879
+
880
+ ignore_flags = no_check_cert_flags;
881
+
882
+ if (!WinHttpSetOption(s->request, WINHTTP_OPTION_SECURITY_FLAGS, &ignore_flags, sizeof(ignore_flags))) {
883
+ git_error_set(GIT_ERROR_OS, "failed to set security options");
884
+ return -1;
885
+ }
886
+
887
+ if ((error = do_send_request(s, len, ignore_length)) < 0)
888
+ git_error_set(GIT_ERROR_OS, "failed to send request with unchecked certificate");
889
+
890
+ return error;
891
+ }
892
+
383
893
  static int winhttp_stream_read(
384
894
  git_smart_subtransport_stream *stream,
385
895
  char *buffer,
@@ -390,11 +900,12 @@ static int winhttp_stream_read(
390
900
  winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
391
901
  DWORD dw_bytes_read;
392
902
  char replay_count = 0;
903
+ int error;
393
904
 
394
905
  replay:
395
906
  /* Enforce a reasonable cap on the number of replays */
396
- if (++replay_count >= 7) {
397
- giterr_set(GITERR_NET, "Too many redirects or authentication replays");
907
+ if (replay_count++ >= GIT_HTTP_REPLAY_MAX) {
908
+ git_error_set(GIT_ERROR_NET, "too many redirects or authentication replays");
398
909
  return -1;
399
910
  }
400
911
 
@@ -408,13 +919,9 @@ replay:
408
919
  wchar_t expected_content_type[MAX_CONTENT_TYPE_LEN], content_type[MAX_CONTENT_TYPE_LEN];
409
920
 
410
921
  if (!s->sent_request) {
411
- if (!WinHttpSendRequest(s->request,
412
- WINHTTP_NO_ADDITIONAL_HEADERS, 0,
413
- WINHTTP_NO_REQUEST_DATA, 0,
414
- s->post_body_len, 0)) {
415
- giterr_set(GITERR_OS, "Failed to send request");
416
- return -1;
417
- }
922
+
923
+ if ((error = send_request(s, s->post_body_len, 0)) < 0)
924
+ return error;
418
925
 
419
926
  s->sent_request = 1;
420
927
  }
@@ -433,7 +940,7 @@ replay:
433
940
  if (!WinHttpWriteData(s->request,
434
941
  "0\r\n\r\n", 5,
435
942
  &bytes_written)) {
436
- giterr_set(GITERR_OS, "Failed to write final chunk");
943
+ git_error_set(GIT_ERROR_OS, "failed to write final chunk");
437
944
  return -1;
438
945
  }
439
946
  }
@@ -444,7 +951,7 @@ replay:
444
951
  if (INVALID_SET_FILE_POINTER == SetFilePointer(s->post_body,
445
952
  0, 0, FILE_BEGIN) &&
446
953
  NO_ERROR != GetLastError()) {
447
- giterr_set(GITERR_OS, "Failed to reset file pointer");
954
+ git_error_set(GIT_ERROR_OS, "failed to reset file pointer");
448
955
  return -1;
449
956
  }
450
957
 
@@ -458,14 +965,14 @@ replay:
458
965
  &bytes_read, NULL) ||
459
966
  !bytes_read) {
460
967
  git__free(buffer);
461
- giterr_set(GITERR_OS, "Failed to read from temp file");
968
+ git_error_set(GIT_ERROR_OS, "failed to read from temp file");
462
969
  return -1;
463
970
  }
464
971
 
465
972
  if (!WinHttpWriteData(s->request, buffer,
466
973
  bytes_read, &bytes_written)) {
467
974
  git__free(buffer);
468
- giterr_set(GITERR_OS, "Failed to write data");
975
+ git_error_set(GIT_ERROR_OS, "failed to write data");
469
976
  return -1;
470
977
  }
471
978
 
@@ -481,7 +988,7 @@ replay:
481
988
  }
482
989
 
483
990
  if (!WinHttpReceiveResponse(s->request, 0)) {
484
- giterr_set(GITERR_OS, "Failed to receive response");
991
+ git_error_set(GIT_ERROR_OS, "failed to receive response");
485
992
  return -1;
486
993
  }
487
994
 
@@ -493,7 +1000,7 @@ replay:
493
1000
  WINHTTP_HEADER_NAME_BY_INDEX,
494
1001
  &status_code, &status_code_length,
495
1002
  WINHTTP_NO_HEADER_INDEX)) {
496
- giterr_set(GITERR_OS, "Failed to retrieve status code");
1003
+ git_error_set(GIT_ERROR_OS, "failed to retrieve status code");
497
1004
  return -1;
498
1005
  }
499
1006
 
@@ -511,89 +1018,145 @@ replay:
511
1018
 
512
1019
  /* Check for Windows 7. This workaround is only necessary on
513
1020
  * Windows Vista and earlier. Windows 7 is version 6.1. */
514
- if (!git_has_win32_version(6, 1)) {
515
- wchar_t *location;
516
- DWORD location_length;
517
- int redirect_cmp;
518
-
519
- /* OK, fetch the Location header from the redirect. */
520
- if (WinHttpQueryHeaders(s->request,
521
- WINHTTP_QUERY_LOCATION,
522
- WINHTTP_HEADER_NAME_BY_INDEX,
523
- WINHTTP_NO_OUTPUT_BUFFER,
524
- &location_length,
525
- WINHTTP_NO_HEADER_INDEX) ||
526
- GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
527
- giterr_set(GITERR_OS, "Failed to read Location header");
1021
+ wchar_t *location;
1022
+ DWORD location_length;
1023
+ char *location8;
1024
+
1025
+ /* OK, fetch the Location header from the redirect. */
1026
+ if (WinHttpQueryHeaders(s->request,
1027
+ WINHTTP_QUERY_LOCATION,
1028
+ WINHTTP_HEADER_NAME_BY_INDEX,
1029
+ WINHTTP_NO_OUTPUT_BUFFER,
1030
+ &location_length,
1031
+ WINHTTP_NO_HEADER_INDEX) ||
1032
+ GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
1033
+ git_error_set(GIT_ERROR_OS, "failed to read Location header");
1034
+ return -1;
1035
+ }
1036
+
1037
+ location = git__malloc(location_length);
1038
+ GIT_ERROR_CHECK_ALLOC(location);
1039
+
1040
+ if (!WinHttpQueryHeaders(s->request,
1041
+ WINHTTP_QUERY_LOCATION,
1042
+ WINHTTP_HEADER_NAME_BY_INDEX,
1043
+ location,
1044
+ &location_length,
1045
+ WINHTTP_NO_HEADER_INDEX)) {
1046
+ git_error_set(GIT_ERROR_OS, "failed to read Location header");
1047
+ git__free(location);
1048
+ return -1;
1049
+ }
1050
+
1051
+ /* Convert the Location header to UTF-8 */
1052
+ if (git__utf16_to_8_alloc(&location8, location) < 0) {
1053
+ git_error_set(GIT_ERROR_OS, "failed to convert Location header to UTF-8");
1054
+ git__free(location);
1055
+ return -1;
1056
+ }
1057
+
1058
+ git__free(location);
1059
+
1060
+ /* Replay the request */
1061
+ winhttp_stream_close(s);
1062
+
1063
+ if (!git__prefixcmp_icase(location8, prefix_https)) {
1064
+ /* Upgrade to secure connection; disconnect and start over */
1065
+ if (gitno_connection_data_from_url(&t->connection_data, location8, s->service_url) < 0) {
1066
+ git__free(location8);
528
1067
  return -1;
529
1068
  }
530
1069
 
531
- location = git__malloc(location_length);
532
- GITERR_CHECK_ALLOC(location);
533
-
534
- if (!WinHttpQueryHeaders(s->request,
535
- WINHTTP_QUERY_LOCATION,
536
- WINHTTP_HEADER_NAME_BY_INDEX,
537
- location,
538
- &location_length,
539
- WINHTTP_NO_HEADER_INDEX)) {
540
- giterr_set(GITERR_OS, "Failed to read Location header");
541
- git__free(location);
1070
+ winhttp_close_connection(t);
1071
+
1072
+ if (winhttp_connect(t) < 0)
542
1073
  return -1;
543
- }
1074
+ }
544
1075
 
545
- /* Compare the Location header with the request URI */
546
- redirect_cmp = wcscmp(location, s->request_uri);
547
- git__free(location);
1076
+ git__free(location8);
1077
+ goto replay;
1078
+ }
548
1079
 
549
- if (!redirect_cmp) {
550
- /* Replay the request */
551
- WinHttpCloseHandle(s->request);
552
- s->request = NULL;
553
- s->sent_request = 0;
1080
+ /* Handle proxy authentication failures */
1081
+ if (status_code == HTTP_STATUS_PROXY_AUTH_REQ) {
1082
+ int allowed_types;
554
1083
 
555
- goto replay;
556
- }
1084
+ if (parse_unauthorized_response(s->request, &allowed_types, &t->auth_mechanisms) < 0)
1085
+ return -1;
1086
+
1087
+ /* TODO: extract the username from the url, no payload? */
1088
+ if (t->owner->proxy.credentials) {
1089
+ int cred_error = 1;
1090
+ cred_error = t->owner->proxy.credentials(&t->proxy_cred, t->owner->proxy.url, NULL, allowed_types, t->owner->proxy.payload);
1091
+
1092
+ if (cred_error < 0)
1093
+ return cred_error;
557
1094
  }
1095
+
1096
+ winhttp_stream_close(s);
1097
+ goto replay;
558
1098
  }
559
1099
 
560
1100
  /* Handle authentication failures */
561
- if (HTTP_STATUS_DENIED == status_code &&
562
- get_verb == s->verb && t->owner->cred_acquire_cb) {
1101
+ if (HTTP_STATUS_DENIED == status_code && get_verb == s->verb) {
563
1102
  int allowed_types;
564
1103
 
565
- if (parse_unauthorized_response(s->request, &allowed_types, &t->auth_mechanism) < 0)
1104
+ if (parse_unauthorized_response(s->request, &allowed_types, &t->auth_mechanisms) < 0)
566
1105
  return -1;
567
1106
 
568
- if (allowed_types &&
569
- (!t->cred || 0 == (t->cred->credtype & allowed_types))) {
1107
+ if (allowed_types) {
1108
+ int cred_error = 1;
1109
+
1110
+ git_cred_free(t->cred);
1111
+ t->cred = NULL;
1112
+ /* Start with the user-supplied credential callback, if present */
1113
+ if (t->owner->cred_acquire_cb) {
1114
+ cred_error = t->owner->cred_acquire_cb(&t->cred, t->owner->url,
1115
+ t->connection_data.user, allowed_types, t->owner->cred_acquire_payload);
1116
+
1117
+ /* Treat GIT_PASSTHROUGH as though git_cred_acquire_cb isn't set */
1118
+ if (cred_error == GIT_PASSTHROUGH)
1119
+ cred_error = 1;
1120
+ else if (cred_error < 0)
1121
+ return cred_error;
1122
+ }
570
1123
 
571
- if (t->owner->cred_acquire_cb(&t->cred, t->owner->url, t->user_from_url, allowed_types, t->owner->cred_acquire_payload) < 0)
572
- return -1;
1124
+ /* Invoke the fallback credentials acquisition callback if necessary */
1125
+ if (cred_error > 0) {
1126
+ cred_error = fallback_cred_acquire_cb(&t->cred, t->owner->url,
1127
+ t->connection_data.user, allowed_types, NULL);
1128
+
1129
+ if (cred_error < 0)
1130
+ return cred_error;
1131
+ }
573
1132
 
574
- assert(t->cred);
1133
+ if (!cred_error) {
1134
+ assert(t->cred);
575
1135
 
576
- WinHttpCloseHandle(s->request);
577
- s->request = NULL;
578
- s->sent_request = 0;
1136
+ winhttp_stream_close(s);
579
1137
 
580
- /* Successfully acquired a credential */
581
- goto replay;
1138
+ /* Successfully acquired a credential */
1139
+ goto replay;
1140
+ }
582
1141
  }
583
1142
  }
584
1143
 
585
1144
  if (HTTP_STATUS_OK != status_code) {
586
- giterr_set(GITERR_NET, "Request failed with status code: %d", status_code);
1145
+ git_error_set(GIT_ERROR_NET, "request failed with status code: %lu", status_code);
587
1146
  return -1;
588
1147
  }
589
1148
 
590
1149
  /* Verify that we got the correct content-type back */
591
1150
  if (post_verb == s->verb)
592
- snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-result", s->service);
1151
+ p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-result", s->service);
593
1152
  else
594
- snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-advertisement", s->service);
1153
+ p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-advertisement", s->service);
1154
+
1155
+ if (git__utf8_to_16(expected_content_type, MAX_CONTENT_TYPE_LEN, expected_content_type_8) < 0) {
1156
+ git_error_set(GIT_ERROR_OS, "failed to convert expected content-type to wide characters");
1157
+ return -1;
1158
+ }
595
1159
 
596
- git__utf8_to_16(expected_content_type, MAX_CONTENT_TYPE_LEN, expected_content_type_8);
597
1160
  content_type_length = sizeof(content_type);
598
1161
 
599
1162
  if (!WinHttpQueryHeaders(s->request,
@@ -601,12 +1164,12 @@ replay:
601
1164
  WINHTTP_HEADER_NAME_BY_INDEX,
602
1165
  &content_type, &content_type_length,
603
1166
  WINHTTP_NO_HEADER_INDEX)) {
604
- giterr_set(GITERR_OS, "Failed to retrieve response content-type");
1167
+ git_error_set(GIT_ERROR_OS, "failed to retrieve response content-type");
605
1168
  return -1;
606
1169
  }
607
1170
 
608
1171
  if (wcscmp(expected_content_type, content_type)) {
609
- giterr_set(GITERR_NET, "Received unexpected content-type");
1172
+ git_error_set(GIT_ERROR_NET, "received unexpected content-type");
610
1173
  return -1;
611
1174
  }
612
1175
 
@@ -618,7 +1181,7 @@ replay:
618
1181
  (DWORD)buf_size,
619
1182
  &dw_bytes_read))
620
1183
  {
621
- giterr_set(GITERR_OS, "Failed to read data");
1184
+ git_error_set(GIT_ERROR_OS, "failed to read data");
622
1185
  return -1;
623
1186
  }
624
1187
 
@@ -633,25 +1196,20 @@ static int winhttp_stream_write_single(
633
1196
  size_t len)
634
1197
  {
635
1198
  winhttp_stream *s = (winhttp_stream *)stream;
636
- winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
637
1199
  DWORD bytes_written;
1200
+ int error;
638
1201
 
639
1202
  if (!s->request && winhttp_stream_connect(s) < 0)
640
1203
  return -1;
641
1204
 
642
1205
  /* This implementation of write permits only a single call. */
643
1206
  if (s->sent_request) {
644
- giterr_set(GITERR_NET, "Subtransport configured for only one write");
1207
+ git_error_set(GIT_ERROR_NET, "subtransport configured for only one write");
645
1208
  return -1;
646
1209
  }
647
1210
 
648
- if (!WinHttpSendRequest(s->request,
649
- WINHTTP_NO_ADDITIONAL_HEADERS, 0,
650
- WINHTTP_NO_REQUEST_DATA, 0,
651
- (DWORD)len, 0)) {
652
- giterr_set(GITERR_OS, "Failed to send request");
653
- return -1;
654
- }
1211
+ if ((error = send_request(s, len, 0)) < 0)
1212
+ return error;
655
1213
 
656
1214
  s->sent_request = 1;
657
1215
 
@@ -659,7 +1217,7 @@ static int winhttp_stream_write_single(
659
1217
  (LPCVOID)buffer,
660
1218
  (DWORD)len,
661
1219
  &bytes_written)) {
662
- giterr_set(GITERR_OS, "Failed to write data");
1220
+ git_error_set(GIT_ERROR_OS, "failed to write data");
663
1221
  return -1;
664
1222
  }
665
1223
 
@@ -672,29 +1230,32 @@ static int put_uuid_string(LPWSTR buffer, size_t buffer_len_cch)
672
1230
  {
673
1231
  UUID uuid;
674
1232
  RPC_STATUS status = UuidCreate(&uuid);
675
- HRESULT result;
1233
+ int result;
676
1234
 
677
1235
  if (RPC_S_OK != status &&
678
1236
  RPC_S_UUID_LOCAL_ONLY != status &&
679
1237
  RPC_S_UUID_NO_ADDRESS != status) {
680
- giterr_set(GITERR_NET, "Unable to generate name for temp file");
1238
+ git_error_set(GIT_ERROR_NET, "unable to generate name for temp file");
681
1239
  return -1;
682
1240
  }
683
1241
 
684
1242
  if (buffer_len_cch < UUID_LENGTH_CCH + 1) {
685
- giterr_set(GITERR_NET, "Buffer too small for name of temp file");
1243
+ git_error_set(GIT_ERROR_NET, "buffer too small for name of temp file");
686
1244
  return -1;
687
1245
  }
688
1246
 
689
- result = StringCbPrintfW(
690
- buffer, buffer_len_cch,
1247
+ #if !defined(__MINGW32__) || defined(MINGW_HAS_SECURE_API)
1248
+ result = swprintf_s(buffer, buffer_len_cch,
1249
+ #else
1250
+ result = wsprintfW(buffer,
1251
+ #endif
691
1252
  L"%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x",
692
1253
  uuid.Data1, uuid.Data2, uuid.Data3,
693
1254
  uuid.Data4[0], uuid.Data4[1], uuid.Data4[2], uuid.Data4[3],
694
1255
  uuid.Data4[4], uuid.Data4[5], uuid.Data4[6], uuid.Data4[7]);
695
1256
 
696
- if (FAILED(result)) {
697
- giterr_set(GITERR_OS, "Unable to generate name for temp file");
1257
+ if (result < UUID_LENGTH_CCH) {
1258
+ git_error_set(GIT_ERROR_OS, "unable to generate name for temp file");
698
1259
  return -1;
699
1260
  }
700
1261
 
@@ -706,7 +1267,7 @@ static int get_temp_file(LPWSTR buffer, DWORD buffer_len_cch)
706
1267
  size_t len;
707
1268
 
708
1269
  if (!GetTempPathW(buffer_len_cch, buffer)) {
709
- giterr_set(GITERR_OS, "Failed to get temp path");
1270
+ git_error_set(GIT_ERROR_OS, "failed to get temp path");
710
1271
  return -1;
711
1272
  }
712
1273
 
@@ -727,7 +1288,6 @@ static int winhttp_stream_write_buffered(
727
1288
  size_t len)
728
1289
  {
729
1290
  winhttp_stream *s = (winhttp_stream *)stream;
730
- winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
731
1291
  DWORD bytes_written;
732
1292
 
733
1293
  if (!s->request && winhttp_stream_connect(s) < 0)
@@ -750,13 +1310,13 @@ static int winhttp_stream_write_buffered(
750
1310
 
751
1311
  if (INVALID_HANDLE_VALUE == s->post_body) {
752
1312
  s->post_body = NULL;
753
- giterr_set(GITERR_OS, "Failed to create temporary file");
1313
+ git_error_set(GIT_ERROR_OS, "failed to create temporary file");
754
1314
  return -1;
755
1315
  }
756
1316
  }
757
1317
 
758
1318
  if (!WriteFile(s->post_body, buffer, (DWORD)len, &bytes_written, NULL)) {
759
- giterr_set(GITERR_OS, "Failed to write to temporary file");
1319
+ git_error_set(GIT_ERROR_OS, "failed to write to temporary file");
760
1320
  return -1;
761
1321
  }
762
1322
 
@@ -773,7 +1333,7 @@ static int winhttp_stream_write_chunked(
773
1333
  size_t len)
774
1334
  {
775
1335
  winhttp_stream *s = (winhttp_stream *)stream;
776
- winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
1336
+ int error;
777
1337
 
778
1338
  if (!s->request && winhttp_stream_connect(s) < 0)
779
1339
  return -1;
@@ -783,17 +1343,12 @@ static int winhttp_stream_write_chunked(
783
1343
  if (!WinHttpAddRequestHeaders(s->request,
784
1344
  transfer_encoding, (ULONG) -1L,
785
1345
  WINHTTP_ADDREQ_FLAG_ADD)) {
786
- giterr_set(GITERR_OS, "Failed to add a header to the request");
1346
+ git_error_set(GIT_ERROR_OS, "failed to add a header to the request");
787
1347
  return -1;
788
1348
  }
789
1349
 
790
- if (!WinHttpSendRequest(s->request,
791
- WINHTTP_NO_ADDITIONAL_HEADERS, 0,
792
- WINHTTP_NO_REQUEST_DATA, 0,
793
- WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0)) {
794
- giterr_set(GITERR_OS, "Failed to send request");
795
- return -1;
796
- }
1350
+ if ((error = send_request(s, 0, 1)) < 0)
1351
+ return error;
797
1352
 
798
1353
  s->sent_request = 1;
799
1354
  }
@@ -813,7 +1368,7 @@ static int winhttp_stream_write_chunked(
813
1368
  }
814
1369
  else {
815
1370
  /* Append as much to the buffer as we can */
816
- int count = min(CACHED_POST_BODY_BUF_SIZE - s->chunk_buffer_len, (int)len);
1371
+ int count = (int)min(CACHED_POST_BODY_BUF_SIZE - s->chunk_buffer_len, len);
817
1372
 
818
1373
  if (!s->chunk_buffer)
819
1374
  s->chunk_buffer = git__malloc(CACHED_POST_BODY_BUF_SIZE);
@@ -845,26 +1400,7 @@ static void winhttp_stream_free(git_smart_subtransport_stream *stream)
845
1400
  {
846
1401
  winhttp_stream *s = (winhttp_stream *)stream;
847
1402
 
848
- if (s->chunk_buffer) {
849
- git__free(s->chunk_buffer);
850
- s->chunk_buffer = NULL;
851
- }
852
-
853
- if (s->post_body) {
854
- CloseHandle(s->post_body);
855
- s->post_body = NULL;
856
- }
857
-
858
- if (s->request_uri) {
859
- git__free(s->request_uri);
860
- s->request_uri = NULL;
861
- }
862
-
863
- if (s->request) {
864
- WinHttpCloseHandle(s->request);
865
- s->request = NULL;
866
- }
867
-
1403
+ winhttp_stream_close(s);
868
1404
  git__free(s);
869
1405
  }
870
1406
 
@@ -875,8 +1411,8 @@ static int winhttp_stream_alloc(winhttp_subtransport *t, winhttp_stream **stream
875
1411
  if (!stream)
876
1412
  return -1;
877
1413
 
878
- s = git__calloc(sizeof(winhttp_stream), 1);
879
- GITERR_CHECK_ALLOC(s);
1414
+ s = git__calloc(1, sizeof(winhttp_stream));
1415
+ GIT_ERROR_CHECK_ALLOC(s);
880
1416
 
881
1417
  s->parent.subtransport = &t->parent;
882
1418
  s->parent.read = winhttp_stream_read;
@@ -888,72 +1424,12 @@ static int winhttp_stream_alloc(winhttp_subtransport *t, winhttp_stream **stream
888
1424
  return 0;
889
1425
  }
890
1426
 
891
- static int winhttp_connect(
892
- winhttp_subtransport *t,
893
- const char *url)
894
- {
895
- wchar_t *ua = L"git/1.0 (libgit2 " WIDEN(LIBGIT2_VERSION) L")";
896
- wchar_t host[GIT_WIN_PATH];
897
- int32_t port;
898
- const char *default_port = "80";
899
- int ret;
900
-
901
- if (!git__prefixcmp(url, prefix_http)) {
902
- url = url + strlen(prefix_http);
903
- default_port = "80";
904
- }
905
-
906
- if (!git__prefixcmp(url, prefix_https)) {
907
- url += strlen(prefix_https);
908
- default_port = "443";
909
- t->use_ssl = 1;
910
- }
911
-
912
- if ((ret = gitno_extract_url_parts(&t->host, &t->port, &t->user_from_url,
913
- &t->pass_from_url, url, default_port)) < 0)
914
- return ret;
915
-
916
- t->path = strchr(url, '/');
917
-
918
- /* Prepare port */
919
- if (git__strtol32(&port, t->port, NULL, 10) < 0)
920
- return -1;
921
-
922
- /* Prepare host */
923
- git__utf8_to_16(host, GIT_WIN_PATH, t->host);
924
-
925
- /* Establish session */
926
- t->session = WinHttpOpen(
927
- ua,
928
- WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
929
- WINHTTP_NO_PROXY_NAME,
930
- WINHTTP_NO_PROXY_BYPASS,
931
- 0);
932
-
933
- if (!t->session) {
934
- giterr_set(GITERR_OS, "Failed to init WinHTTP");
935
- return -1;
936
- }
937
-
938
- /* Establish connection */
939
- t->connection = WinHttpConnect(
940
- t->session,
941
- host,
942
- port,
943
- 0);
944
-
945
- if (!t->connection) {
946
- giterr_set(GITERR_OS, "Failed to connect to host");
947
- return -1;
948
- }
949
-
950
- return 0;
951
- }
952
-
953
1427
  static int winhttp_uploadpack_ls(
954
1428
  winhttp_subtransport *t,
955
1429
  winhttp_stream *s)
956
1430
  {
1431
+ GIT_UNUSED(t);
1432
+
957
1433
  s->service = upload_pack_service;
958
1434
  s->service_url = upload_pack_ls_service_url;
959
1435
  s->verb = get_verb;
@@ -965,6 +1441,8 @@ static int winhttp_uploadpack(
965
1441
  winhttp_subtransport *t,
966
1442
  winhttp_stream *s)
967
1443
  {
1444
+ GIT_UNUSED(t);
1445
+
968
1446
  s->service = upload_pack_service;
969
1447
  s->service_url = upload_pack_service_url;
970
1448
  s->verb = post_verb;
@@ -976,6 +1454,8 @@ static int winhttp_receivepack_ls(
976
1454
  winhttp_subtransport *t,
977
1455
  winhttp_stream *s)
978
1456
  {
1457
+ GIT_UNUSED(t);
1458
+
979
1459
  s->service = receive_pack_service;
980
1460
  s->service_url = receive_pack_ls_service_url;
981
1461
  s->verb = get_verb;
@@ -987,9 +1467,11 @@ static int winhttp_receivepack(
987
1467
  winhttp_subtransport *t,
988
1468
  winhttp_stream *s)
989
1469
  {
1470
+ GIT_UNUSED(t);
1471
+
990
1472
  /* WinHTTP only supports Transfer-Encoding: chunked
991
1473
  * on Windows Vista (NT 6.0) and higher. */
992
- s->chunked = git_has_win32_version(6, 0);
1474
+ s->chunked = git_has_win32_version(6, 0, 0);
993
1475
 
994
1476
  if (s->chunked)
995
1477
  s->parent.write = winhttp_stream_write_chunked;
@@ -1013,9 +1495,10 @@ static int winhttp_action(
1013
1495
  winhttp_stream *s;
1014
1496
  int ret = -1;
1015
1497
 
1016
- if (!t->connection &&
1017
- winhttp_connect(t, url) < 0)
1018
- return -1;
1498
+ if (!t->connection)
1499
+ if ((ret = gitno_connection_data_from_url(&t->connection_data, url, NULL)) < 0 ||
1500
+ (ret = winhttp_connect(t)) < 0)
1501
+ return ret;
1019
1502
 
1020
1503
  if (winhttp_stream_alloc(t, &s) < 0)
1021
1504
  return -1;
@@ -1054,57 +1537,28 @@ static int winhttp_action(
1054
1537
  static int winhttp_close(git_smart_subtransport *subtransport)
1055
1538
  {
1056
1539
  winhttp_subtransport *t = (winhttp_subtransport *)subtransport;
1057
- int ret = 0;
1058
1540
 
1059
- if (t->host) {
1060
- git__free(t->host);
1061
- t->host = NULL;
1062
- }
1063
-
1064
- if (t->port) {
1065
- git__free(t->port);
1066
- t->port = NULL;
1067
- }
1068
-
1069
- if (t->user_from_url) {
1070
- git__free(t->user_from_url);
1071
- t->user_from_url = NULL;
1072
- }
1073
-
1074
- if (t->pass_from_url) {
1075
- git__free(t->pass_from_url);
1076
- t->pass_from_url = NULL;
1077
- }
1541
+ gitno_connection_data_free_ptrs(&t->connection_data);
1542
+ memset(&t->connection_data, 0x0, sizeof(gitno_connection_data));
1543
+ gitno_connection_data_free_ptrs(&t->proxy_connection_data);
1544
+ memset(&t->proxy_connection_data, 0x0, sizeof(gitno_connection_data));
1078
1545
 
1079
1546
  if (t->cred) {
1080
1547
  t->cred->free(t->cred);
1081
1548
  t->cred = NULL;
1082
1549
  }
1083
1550
 
1551
+ if (t->proxy_cred) {
1552
+ t->proxy_cred->free(t->proxy_cred);
1553
+ t->proxy_cred = NULL;
1554
+ }
1555
+
1084
1556
  if (t->url_cred) {
1085
1557
  t->url_cred->free(t->url_cred);
1086
1558
  t->url_cred = NULL;
1087
1559
  }
1088
1560
 
1089
- if (t->connection) {
1090
- if (!WinHttpCloseHandle(t->connection)) {
1091
- giterr_set(GITERR_OS, "Unable to close connection");
1092
- ret = -1;
1093
- }
1094
-
1095
- t->connection = NULL;
1096
- }
1097
-
1098
- if (t->session) {
1099
- if (!WinHttpCloseHandle(t->session)) {
1100
- giterr_set(GITERR_OS, "Unable to close session");
1101
- ret = -1;
1102
- }
1103
-
1104
- t->session = NULL;
1105
- }
1106
-
1107
- return ret;
1561
+ return winhttp_close_connection(t);
1108
1562
  }
1109
1563
 
1110
1564
  static void winhttp_free(git_smart_subtransport *subtransport)
@@ -1116,15 +1570,17 @@ static void winhttp_free(git_smart_subtransport *subtransport)
1116
1570
  git__free(t);
1117
1571
  }
1118
1572
 
1119
- int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *owner)
1573
+ int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *owner, void *param)
1120
1574
  {
1121
1575
  winhttp_subtransport *t;
1122
1576
 
1577
+ GIT_UNUSED(param);
1578
+
1123
1579
  if (!out)
1124
1580
  return -1;
1125
1581
 
1126
- t = git__calloc(sizeof(winhttp_subtransport), 1);
1127
- GITERR_CHECK_ALLOC(t);
1582
+ t = git__calloc(1, sizeof(winhttp_subtransport));
1583
+ GIT_ERROR_CHECK_ALLOC(t);
1128
1584
 
1129
1585
  t->owner = (transport_smart *)owner;
1130
1586
  t->parent.action = winhttp_action;