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
@@ -4,16 +4,29 @@
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
6
6
  */
7
+
8
+ #include "common.h"
9
+
7
10
  #ifndef GIT_WINHTTP
8
11
 
9
12
  #include "git2.h"
10
13
  #include "http_parser.h"
11
14
  #include "buffer.h"
12
15
  #include "netops.h"
16
+ #include "global.h"
17
+ #include "remote.h"
13
18
  #include "smart.h"
19
+ #include "auth.h"
20
+ #include "http.h"
21
+ #include "auth_negotiate.h"
22
+ #include "streams/tls.h"
23
+ #include "streams/socket.h"
24
+
25
+ git_http_auth_scheme auth_schemes[] = {
26
+ { GIT_AUTHTYPE_NEGOTIATE, "Negotiate", GIT_CREDTYPE_DEFAULT, git_http_auth_negotiate },
27
+ { GIT_AUTHTYPE_BASIC, "Basic", GIT_CREDTYPE_USERPASS_PLAINTEXT, git_http_auth_basic },
28
+ };
14
29
 
15
- static const char *prefix_http = "http://";
16
- static const char *prefix_https = "https://";
17
30
  static const char *upload_pack_service = "upload-pack";
18
31
  static const char *upload_pack_ls_service_url = "/info/refs?service=git-upload-pack";
19
32
  static const char *upload_pack_service_url = "/git-upload-pack";
@@ -22,12 +35,19 @@ static const char *receive_pack_ls_service_url = "/info/refs?service=git-receive
22
35
  static const char *receive_pack_service_url = "/git-receive-pack";
23
36
  static const char *get_verb = "GET";
24
37
  static const char *post_verb = "POST";
25
- static const char *basic_authtype = "Basic";
38
+
39
+ #define AUTH_HEADER_SERVER "Authorization"
40
+ #define AUTH_HEADER_PROXY "Proxy-Authorization"
41
+
42
+ #define SERVER_TYPE_REMOTE "remote"
43
+ #define SERVER_TYPE_PROXY "proxy"
26
44
 
27
45
  #define OWNING_SUBTRANSPORT(s) ((http_subtransport *)(s)->parent.subtransport)
28
46
 
29
47
  #define PARSE_ERROR_GENERIC -1
30
48
  #define PARSE_ERROR_REPLAY -2
49
+ /** Look at the user field */
50
+ #define PARSE_ERROR_EXT -3
31
51
 
32
52
  #define CHUNK_SIZE 4096
33
53
 
@@ -37,10 +57,6 @@ enum last_cb {
37
57
  VALUE
38
58
  };
39
59
 
40
- typedef enum {
41
- GIT_HTTP_AUTH_BASIC = 1,
42
- } http_authmechanism_t;
43
-
44
60
  typedef struct {
45
61
  git_smart_subtransport_stream parent;
46
62
  const char *service;
@@ -51,24 +67,31 @@ typedef struct {
51
67
  unsigned chunk_buffer_len;
52
68
  unsigned sent_request : 1,
53
69
  received_response : 1,
54
- chunked : 1,
55
- redirect_count : 3;
70
+ chunked : 1;
56
71
  } http_stream;
57
72
 
58
73
  typedef struct {
59
- git_smart_subtransport parent;
60
- transport_smart *owner;
61
- gitno_socket socket;
62
- const char *path;
63
- char *host;
64
- char *port;
65
- char *user_from_url;
66
- char *pass_from_url;
74
+ gitno_connection_data url;
75
+ git_stream *stream;
76
+
67
77
  git_cred *cred;
68
78
  git_cred *url_cred;
69
- http_authmechanism_t auth_mechanism;
70
- unsigned connected : 1,
71
- use_ssl : 1;
79
+
80
+ git_vector auth_challenges;
81
+ git_vector auth_contexts;
82
+ } http_server;
83
+
84
+ typedef struct {
85
+ git_smart_subtransport parent;
86
+ transport_smart *owner;
87
+ git_stream *gitserver_stream;
88
+ bool connected;
89
+
90
+ http_server server;
91
+
92
+ http_server proxy;
93
+ char *proxy_url;
94
+ git_proxy_options proxy_opts;
72
95
 
73
96
  /* Parser structures */
74
97
  http_parser parser;
@@ -76,13 +99,15 @@ typedef struct {
76
99
  gitno_buffer parse_buffer;
77
100
  git_buf parse_header_name;
78
101
  git_buf parse_header_value;
79
- char parse_buffer_data[2048];
102
+ char parse_buffer_data[NETIO_BUFSIZE];
80
103
  char *content_type;
104
+ char *content_length;
81
105
  char *location;
82
- git_vector www_authenticate;
83
106
  enum last_cb last_cb;
84
107
  int parse_error;
85
- unsigned parse_finished : 1;
108
+ int error;
109
+ unsigned parse_finished : 1,
110
+ replay_count : 3;
86
111
  } http_subtransport;
87
112
 
88
113
  typedef struct {
@@ -95,28 +120,98 @@ typedef struct {
95
120
  size_t *bytes_read;
96
121
  } parser_context;
97
122
 
98
- static int apply_basic_credential(git_buf *buf, git_cred *cred)
123
+ static bool credtype_match(git_http_auth_scheme *scheme, void *data)
99
124
  {
100
- git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
101
- git_buf raw = GIT_BUF_INIT;
102
- int error = -1;
125
+ unsigned int credtype = *(unsigned int *)data;
103
126
 
104
- git_buf_printf(&raw, "%s:%s", c->username, c->password);
127
+ return !!(scheme->credtypes & credtype);
128
+ }
105
129
 
106
- if (git_buf_oom(&raw) ||
107
- git_buf_puts(buf, "Authorization: Basic ") < 0 ||
108
- git_buf_put_base64(buf, git_buf_cstr(&raw), raw.size) < 0 ||
109
- git_buf_puts(buf, "\r\n") < 0)
110
- goto on_error;
130
+ static bool challenge_match(git_http_auth_scheme *scheme, void *data)
131
+ {
132
+ const char *scheme_name = scheme->name;
133
+ const char *challenge = (const char *)data;
134
+ size_t scheme_len;
111
135
 
112
- error = 0;
136
+ scheme_len = strlen(scheme_name);
137
+ return (strncasecmp(challenge, scheme_name, scheme_len) == 0 &&
138
+ (challenge[scheme_len] == '\0' || challenge[scheme_len] == ' '));
139
+ }
113
140
 
114
- on_error:
115
- if (raw.size)
116
- memset(raw.ptr, 0x0, raw.size);
141
+ static int auth_context_match(
142
+ git_http_auth_context **out,
143
+ http_server *server,
144
+ bool (*scheme_match)(git_http_auth_scheme *scheme, void *data),
145
+ void *data)
146
+ {
147
+ git_http_auth_scheme *scheme = NULL;
148
+ git_http_auth_context *context = NULL, *c;
149
+ size_t i;
117
150
 
118
- git_buf_free(&raw);
119
- return error;
151
+ *out = NULL;
152
+
153
+ for (i = 0; i < ARRAY_SIZE(auth_schemes); i++) {
154
+ if (scheme_match(&auth_schemes[i], data)) {
155
+ scheme = &auth_schemes[i];
156
+ break;
157
+ }
158
+ }
159
+
160
+ if (!scheme)
161
+ return 0;
162
+
163
+ /* See if authentication has already started for this scheme */
164
+ git_vector_foreach(&server->auth_contexts, i, c) {
165
+ if (c->type == scheme->type) {
166
+ context = c;
167
+ break;
168
+ }
169
+ }
170
+
171
+ if (!context) {
172
+ if (scheme->init_context(&context, &server->url) < 0)
173
+ return -1;
174
+ else if (!context)
175
+ return 0;
176
+ else if (git_vector_insert(&server->auth_contexts, context) < 0)
177
+ return -1;
178
+ }
179
+
180
+ *out = context;
181
+
182
+ return 0;
183
+ }
184
+
185
+ static int apply_credentials(
186
+ git_buf *buf,
187
+ http_server *server,
188
+ const char *header_name)
189
+ {
190
+ git_cred *cred = server->cred;
191
+ git_http_auth_context *context;
192
+
193
+ /* Apply the credentials given to us in the URL */
194
+ if (!cred && server->url.user && server->url.pass) {
195
+ if (!server->url_cred &&
196
+ git_cred_userpass_plaintext_new(&server->url_cred,
197
+ server->url.user, server->url.pass) < 0)
198
+ return -1;
199
+
200
+ cred = server->url_cred;
201
+ }
202
+
203
+ if (!cred)
204
+ return 0;
205
+
206
+ /* Get or create a context for the best scheme for this cred type */
207
+ if (auth_context_match(&context, server,
208
+ credtype_match, &cred->credtype) < 0)
209
+ return -1;
210
+
211
+ if (!context)
212
+ return 0;
213
+
214
+ return context->next_token(buf, context, header_name, cred);
120
215
  }
121
216
 
122
217
  static int gen_request(
@@ -125,18 +220,28 @@ static int gen_request(
125
220
  size_t content_length)
126
221
  {
127
222
  http_subtransport *t = OWNING_SUBTRANSPORT(s);
128
-
129
- if (!t->path)
130
- t->path = "/";
131
-
132
- /* If we were redirected, make sure to respect that here */
133
- if (s->redirect_url)
134
- git_buf_printf(buf, "%s %s HTTP/1.1\r\n", s->verb, s->redirect_url);
223
+ const char *path = t->server.url.path ? t->server.url.path : "/";
224
+ size_t i;
225
+
226
+ if (t->proxy_opts.type == GIT_PROXY_SPECIFIED)
227
+ git_buf_printf(buf, "%s %s://%s:%s%s%s HTTP/1.1\r\n",
228
+ s->verb,
229
+ t->server.url.use_ssl ? "https" : "http",
230
+ t->server.url.host,
231
+ t->server.url.port,
232
+ path, s->service_url);
135
233
  else
136
- git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n", s->verb, t->path, s->service_url);
234
+ git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n",
235
+ s->verb, path, s->service_url);
137
236
 
138
- git_buf_puts(buf, "User-Agent: git/1.0 (libgit2 " LIBGIT2_VERSION ")\r\n");
139
- git_buf_printf(buf, "Host: %s\r\n", t->host);
237
+ git_buf_puts(buf, "User-Agent: ");
238
+ git_http__user_agent(buf);
239
+ git_buf_puts(buf, "\r\n");
240
+ git_buf_printf(buf, "Host: %s", t->server.url.host);
241
+ if (strcmp(t->server.url.port, gitno__default_port(&t->server.url)) != 0) {
242
+ git_buf_printf(buf, ":%s", t->server.url.port);
243
+ }
244
+ git_buf_puts(buf, "\r\n");
140
245
 
141
246
  if (s->chunked || content_length > 0) {
142
247
  git_buf_printf(buf, "Accept: application/x-git-%s-result\r\n", s->service);
@@ -149,19 +254,18 @@ static int gen_request(
149
254
  } else
150
255
  git_buf_puts(buf, "Accept: */*\r\n");
151
256
 
152
- /* Apply credentials to the request */
153
- if (t->cred && t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT &&
154
- t->auth_mechanism == GIT_HTTP_AUTH_BASIC &&
155
- apply_basic_credential(buf, t->cred) < 0)
257
+ for (i = 0; i < t->owner->custom_headers.count; i++) {
258
+ if (t->owner->custom_headers.strings[i])
259
+ git_buf_printf(buf, "%s\r\n", t->owner->custom_headers.strings[i]);
260
+ }
261
+
262
+ /* Apply proxy and server credentials to the request */
263
+ if (t->proxy_opts.type != GIT_PROXY_NONE &&
264
+ apply_credentials(buf, &t->proxy, AUTH_HEADER_PROXY) < 0)
156
265
  return -1;
157
266
 
158
- /* Use url-parsed basic auth if username and password are both provided */
159
- if (!t->cred && t->user_from_url && t->pass_from_url) {
160
- if (!t->url_cred &&
161
- git_cred_userpass_plaintext_new(&t->url_cred, t->user_from_url, t->pass_from_url) < 0)
162
- return -1;
163
- if (apply_basic_credential(buf, t->url_cred) < 0) return -1;
164
- }
267
+ if (apply_credentials(buf, &t->server, AUTH_HEADER_SERVER) < 0)
268
+ return -1;
165
269
 
166
270
  git_buf_puts(buf, "\r\n");
167
271
 
@@ -171,20 +275,26 @@ static int gen_request(
171
275
  return 0;
172
276
  }
173
277
 
174
- static int parse_unauthorized_response(
175
- git_vector *www_authenticate,
176
- int *allowed_types,
177
- http_authmechanism_t *auth_mechanism)
278
+ static int parse_authenticate_response(
279
+ http_server *server,
280
+ int *allowed_types)
178
281
  {
179
- unsigned i;
180
- char *entry;
282
+ git_http_auth_context *context;
283
+ char *challenge;
284
+ size_t i;
181
285
 
182
- git_vector_foreach(www_authenticate, i, entry) {
183
- if (!strncmp(entry, basic_authtype, 5) &&
184
- (entry[5] == '\0' || entry[5] == ' ')) {
185
- *allowed_types |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
186
- *auth_mechanism = GIT_HTTP_AUTH_BASIC;
187
- }
286
+ git_vector_foreach(&server->auth_challenges, i, challenge) {
287
+ if (auth_context_match(&context, server,
288
+ challenge_match, challenge) < 0)
289
+ return -1;
290
+ else if (!context)
291
+ continue;
292
+
293
+ if (context->set_challenge &&
294
+ context->set_challenge(context, challenge) < 0)
295
+ return -1;
296
+
297
+ *allowed_types |= context->credtypes;
188
298
  }
189
299
 
190
300
  return 0;
@@ -196,22 +306,45 @@ static int on_header_ready(http_subtransport *t)
196
306
  git_buf *value = &t->parse_header_value;
197
307
 
198
308
  if (!strcasecmp("Content-Type", git_buf_cstr(name))) {
199
- if (!t->content_type) {
200
- t->content_type = git__strdup(git_buf_cstr(value));
201
- GITERR_CHECK_ALLOC(t->content_type);
309
+ if (t->content_type) {
310
+ git_error_set(GIT_ERROR_NET, "multiple Content-Type headers");
311
+ return -1;
202
312
  }
313
+
314
+ t->content_type = git__strdup(git_buf_cstr(value));
315
+ GIT_ERROR_CHECK_ALLOC(t->content_type);
316
+ }
317
+ else if (!strcasecmp("Content-Length", git_buf_cstr(name))) {
318
+ if (t->content_length) {
319
+ git_error_set(GIT_ERROR_NET, "multiple Content-Length headers");
320
+ return -1;
321
+ }
322
+
323
+ t->content_length = git__strdup(git_buf_cstr(value));
324
+ GIT_ERROR_CHECK_ALLOC(t->content_length);
203
325
  }
204
- else if (!strcmp("WWW-Authenticate", git_buf_cstr(name))) {
326
+ else if (!strcasecmp("Proxy-Authenticate", git_buf_cstr(name))) {
205
327
  char *dup = git__strdup(git_buf_cstr(value));
206
- GITERR_CHECK_ALLOC(dup);
328
+ GIT_ERROR_CHECK_ALLOC(dup);
207
329
 
208
- git_vector_insert(&t->www_authenticate, dup);
330
+ if (git_vector_insert(&t->proxy.auth_challenges, dup) < 0)
331
+ return -1;
332
+ }
333
+ else if (!strcasecmp("WWW-Authenticate", git_buf_cstr(name))) {
334
+ char *dup = git__strdup(git_buf_cstr(value));
335
+ GIT_ERROR_CHECK_ALLOC(dup);
336
+
337
+ if (git_vector_insert(&t->server.auth_challenges, dup) < 0)
338
+ return -1;
209
339
  }
210
340
  else if (!strcasecmp("Location", git_buf_cstr(name))) {
211
- if (!t->location) {
212
- t->location= git__strdup(git_buf_cstr(value));
213
- GITERR_CHECK_ALLOC(t->location);
341
+ if (t->location) {
342
+ git_error_set(GIT_ERROR_NET, "multiple Location headers");
343
+ return -1;
214
344
  }
345
+
346
+ t->location = git__strdup(git_buf_cstr(value));
347
+ GIT_ERROR_CHECK_ALLOC(t->location);
215
348
  }
216
349
 
217
350
  return 0;
@@ -255,12 +388,78 @@ static int on_header_value(http_parser *parser, const char *str, size_t len)
255
388
  return 0;
256
389
  }
257
390
 
391
+ GIT_INLINE(void) free_cred(git_cred **cred)
392
+ {
393
+ if (*cred) {
394
+ git_cred_free(*cred);
395
+ (*cred) = NULL;
396
+ }
397
+ }
398
+
399
+ static int on_auth_required(
400
+ git_cred **creds,
401
+ http_parser *parser,
402
+ const char *url,
403
+ const char *type,
404
+ git_cred_acquire_cb callback,
405
+ void *callback_payload,
406
+ const char *username,
407
+ int allowed_types)
408
+ {
409
+ parser_context *ctx = (parser_context *) parser->data;
410
+ http_subtransport *t = ctx->t;
411
+ int ret;
412
+
413
+ if (!allowed_types) {
414
+ git_error_set(GIT_ERROR_NET, "%s requested authentication but did not negotiate mechanisms", type);
415
+ t->parse_error = PARSE_ERROR_GENERIC;
416
+ return t->parse_error;
417
+ }
418
+
419
+ if (callback) {
420
+ free_cred(creds);
421
+ ret = callback(creds, url, username, allowed_types, callback_payload);
422
+
423
+ if (ret == GIT_PASSTHROUGH) {
424
+ /* treat GIT_PASSTHROUGH as if callback isn't set */
425
+ } else if (ret < 0) {
426
+ t->error = ret;
427
+ t->parse_error = PARSE_ERROR_EXT;
428
+ return t->parse_error;
429
+ } else {
430
+ assert(*creds);
431
+
432
+ if (!((*creds)->credtype & allowed_types)) {
433
+ git_error_set(GIT_ERROR_NET, "%s credential provider returned an invalid cred type", type);
434
+ t->parse_error = PARSE_ERROR_GENERIC;
435
+ return t->parse_error;
436
+ }
437
+
438
+ /* Successfully acquired a credential. */
439
+ t->parse_error = PARSE_ERROR_REPLAY;
440
+ return 0;
441
+ }
442
+ }
443
+
444
+ git_error_set(GIT_ERROR_NET, "%s authentication required but no callback set",
445
+ type);
446
+ t->parse_error = PARSE_ERROR_GENERIC;
447
+ return t->parse_error;
448
+ }
449
+
258
450
  static int on_headers_complete(http_parser *parser)
259
451
  {
260
452
  parser_context *ctx = (parser_context *) parser->data;
261
453
  http_subtransport *t = ctx->t;
262
454
  http_stream *s = ctx->s;
263
455
  git_buf buf = GIT_BUF_INIT;
456
+ int proxy_auth_types = 0, server_auth_types = 0;
457
+
458
+ /* Enforce a reasonable cap on the number of replays */
459
+ if (t->replay_count++ >= GIT_HTTP_REPLAY_MAX) {
460
+ git_error_set(GIT_ERROR_NET, "too many redirects or authentication replays");
461
+ return t->parse_error = PARSE_ERROR_GENERIC;
462
+ }
264
463
 
265
464
  /* Both parse_header_name and parse_header_value are populated
266
465
  * and ready for consumption. */
@@ -268,50 +467,48 @@ static int on_headers_complete(http_parser *parser)
268
467
  if (on_header_ready(t) < 0)
269
468
  return t->parse_error = PARSE_ERROR_GENERIC;
270
469
 
271
- /* Check for an authentication failure. */
272
- if (parser->status_code == 401 &&
273
- get_verb == s->verb &&
274
- t->owner->cred_acquire_cb) {
275
- int allowed_types = 0;
276
-
277
- if (parse_unauthorized_response(&t->www_authenticate,
278
- &allowed_types, &t->auth_mechanism) < 0)
279
- return t->parse_error = PARSE_ERROR_GENERIC;
280
-
281
- if (allowed_types &&
282
- (!t->cred || 0 == (t->cred->credtype & allowed_types))) {
283
-
284
- if (t->owner->cred_acquire_cb(&t->cred,
285
- t->owner->url,
286
- t->user_from_url,
287
- allowed_types,
288
- t->owner->cred_acquire_payload) < 0)
289
- return PARSE_ERROR_GENERIC;
470
+ /*
471
+ * Capture authentication headers for the proxy or final endpoint,
472
+ * these may be 407/401 (authentication is not complete) or a 200
473
+ * (informing us that auth has completed).
474
+ */
475
+ if (parse_authenticate_response(&t->proxy, &proxy_auth_types) < 0 ||
476
+ parse_authenticate_response(&t->server, &server_auth_types) < 0)
477
+ return t->parse_error = PARSE_ERROR_GENERIC;
290
478
 
291
- assert(t->cred);
479
+ /* Check for a proxy authentication failure. */
480
+ if (parser->status_code == 407 && get_verb == s->verb)
481
+ return on_auth_required(&t->proxy.cred,
482
+ parser,
483
+ t->proxy_opts.url,
484
+ SERVER_TYPE_PROXY,
485
+ t->proxy_opts.credentials,
486
+ t->proxy_opts.payload,
487
+ t->proxy.url.user,
488
+ proxy_auth_types);
292
489
 
293
- /* Successfully acquired a credential. */
294
- return t->parse_error = PARSE_ERROR_REPLAY;
295
- }
296
- }
490
+ /* Check for an authentication failure. */
491
+ if (parser->status_code == 401 && get_verb == s->verb)
492
+ return on_auth_required(&t->server.cred,
493
+ parser,
494
+ t->owner->url,
495
+ SERVER_TYPE_REMOTE,
496
+ t->owner->cred_acquire_cb,
497
+ t->owner->cred_acquire_payload,
498
+ t->server.url.user,
499
+ server_auth_types);
297
500
 
298
501
  /* Check for a redirect.
299
502
  * Right now we only permit a redirect to the same hostname. */
300
503
  if ((parser->status_code == 301 ||
301
- parser->status_code == 302 ||
302
- (parser->status_code == 303 && get_verb == s->verb) ||
303
- parser->status_code == 307) &&
304
- t->location) {
305
-
306
- if (s->redirect_count >= 7) {
307
- giterr_set(GITERR_NET, "Too many redirects");
308
- return t->parse_error = PARSE_ERROR_GENERIC;
309
- }
504
+ parser->status_code == 302 ||
505
+ (parser->status_code == 303 && get_verb == s->verb) ||
506
+ parser->status_code == 307 ||
507
+ parser->status_code == 308) &&
508
+ t->location) {
310
509
 
311
- if (t->location[0] != '/') {
312
- giterr_set(GITERR_NET, "Only relative redirects are supported");
510
+ if (gitno_connection_data_from_url(&t->server.url, t->location, s->service_url) < 0)
313
511
  return t->parse_error = PARSE_ERROR_GENERIC;
314
- }
315
512
 
316
513
  /* Set the redirect URL on the stream. This is a transfer of
317
514
  * ownership of the memory. */
@@ -322,22 +519,21 @@ static int on_headers_complete(http_parser *parser)
322
519
  t->location = NULL;
323
520
 
324
521
  t->connected = 0;
325
- s->redirect_count++;
326
-
327
- return t->parse_error = PARSE_ERROR_REPLAY;
522
+ t->parse_error = PARSE_ERROR_REPLAY;
523
+ return 0;
328
524
  }
329
525
 
330
526
  /* Check for a 200 HTTP status code. */
331
527
  if (parser->status_code != 200) {
332
- giterr_set(GITERR_NET,
333
- "Unexpected HTTP status code: %d",
528
+ git_error_set(GIT_ERROR_NET,
529
+ "unexpected HTTP status code: %d",
334
530
  parser->status_code);
335
531
  return t->parse_error = PARSE_ERROR_GENERIC;
336
532
  }
337
533
 
338
534
  /* The response must contain a Content-Type header. */
339
535
  if (!t->content_type) {
340
- giterr_set(GITERR_NET, "No Content-Type header in response");
536
+ git_error_set(GIT_ERROR_NET, "no Content-Type header in response");
341
537
  return t->parse_error = PARSE_ERROR_GENERIC;
342
538
  }
343
539
 
@@ -355,14 +551,14 @@ static int on_headers_complete(http_parser *parser)
355
551
  return t->parse_error = PARSE_ERROR_GENERIC;
356
552
 
357
553
  if (strcmp(t->content_type, git_buf_cstr(&buf))) {
358
- git_buf_free(&buf);
359
- giterr_set(GITERR_NET,
360
- "Invalid Content-Type: %s",
554
+ git_buf_dispose(&buf);
555
+ git_error_set(GIT_ERROR_NET,
556
+ "invalid Content-Type: %s",
361
557
  t->content_type);
362
558
  return t->parse_error = PARSE_ERROR_GENERIC;
363
559
  }
364
560
 
365
- git_buf_free(&buf);
561
+ git_buf_dispose(&buf);
366
562
 
367
563
  return 0;
368
564
  }
@@ -382,26 +578,34 @@ static int on_body_fill_buffer(http_parser *parser, const char *str, size_t len)
382
578
  parser_context *ctx = (parser_context *) parser->data;
383
579
  http_subtransport *t = ctx->t;
384
580
 
385
- if (ctx->buf_size < len) {
386
- giterr_set(GITERR_NET, "Can't fit data in the buffer");
387
- return t->parse_error = PARSE_ERROR_GENERIC;
581
+ /* If our goal is to replay the request (either an auth failure or
582
+ * a redirect) then don't bother buffering since we're ignoring the
583
+ * content anyway.
584
+ */
585
+ if (t->parse_error == PARSE_ERROR_REPLAY)
586
+ return 0;
587
+
588
+ /* If there's no buffer set, we're explicitly ignoring the body. */
589
+ if (ctx->buffer) {
590
+ if (ctx->buf_size < len) {
591
+ git_error_set(GIT_ERROR_NET, "can't fit data in the buffer");
592
+ return t->parse_error = PARSE_ERROR_GENERIC;
593
+ }
594
+
595
+ memcpy(ctx->buffer, str, len);
596
+ ctx->buffer += len;
597
+ ctx->buf_size -= len;
388
598
  }
389
599
 
390
- memcpy(ctx->buffer, str, len);
391
600
  *(ctx->bytes_read) += len;
392
- ctx->buffer += len;
393
- ctx->buf_size -= len;
394
601
 
395
602
  return 0;
396
603
  }
397
604
 
398
605
  static void clear_parser_state(http_subtransport *t)
399
606
  {
400
- unsigned i;
401
- char *entry;
402
-
403
607
  http_parser_init(&t->parser, HTTP_RESPONSE);
404
- gitno_buffer_setup(&t->socket,
608
+ gitno_buffer_setup_fromstream(t->server.stream,
405
609
  &t->parse_buffer,
406
610
  t->parse_buffer_data,
407
611
  sizeof(t->parse_buffer_data));
@@ -410,81 +614,400 @@ static void clear_parser_state(http_subtransport *t)
410
614
  t->parse_error = 0;
411
615
  t->parse_finished = 0;
412
616
 
413
- git_buf_free(&t->parse_header_name);
617
+ git_buf_dispose(&t->parse_header_name);
414
618
  git_buf_init(&t->parse_header_name, 0);
415
619
 
416
- git_buf_free(&t->parse_header_value);
620
+ git_buf_dispose(&t->parse_header_value);
417
621
  git_buf_init(&t->parse_header_value, 0);
418
622
 
419
623
  git__free(t->content_type);
420
624
  t->content_type = NULL;
421
625
 
626
+ git__free(t->content_length);
627
+ t->content_length = NULL;
628
+
422
629
  git__free(t->location);
423
630
  t->location = NULL;
424
631
 
425
- git_vector_foreach(&t->www_authenticate, i, entry)
426
- git__free(entry);
427
-
428
- git_vector_free(&t->www_authenticate);
632
+ git_vector_free_deep(&t->proxy.auth_challenges);
633
+ git_vector_free_deep(&t->server.auth_challenges);
429
634
  }
430
635
 
431
- static int write_chunk(gitno_socket *socket, const char *buffer, size_t len)
636
+ static int write_chunk(git_stream *io, const char *buffer, size_t len)
432
637
  {
433
638
  git_buf buf = GIT_BUF_INIT;
434
639
 
435
640
  /* Chunk header */
436
- git_buf_printf(&buf, "%X\r\n", (unsigned)len);
641
+ git_buf_printf(&buf, "%" PRIxZ "\r\n", len);
437
642
 
438
643
  if (git_buf_oom(&buf))
439
644
  return -1;
440
645
 
441
- if (gitno_send(socket, buf.ptr, buf.size, 0) < 0) {
442
- git_buf_free(&buf);
646
+ if (git_stream__write_full(io, buf.ptr, buf.size, 0) < 0) {
647
+ git_buf_dispose(&buf);
443
648
  return -1;
444
649
  }
445
650
 
446
- git_buf_free(&buf);
651
+ git_buf_dispose(&buf);
447
652
 
448
653
  /* Chunk body */
449
- if (len > 0 && gitno_send(socket, buffer, len, 0) < 0)
654
+ if (len > 0 && git_stream__write_full(io, buffer, len, 0) < 0)
450
655
  return -1;
451
656
 
452
657
  /* Chunk footer */
453
- if (gitno_send(socket, "\r\n", 2, 0) < 0)
658
+ if (git_stream__write_full(io, "\r\n", 2, 0) < 0)
659
+ return -1;
660
+
661
+ return 0;
662
+ }
663
+
664
+ static int load_proxy_config(http_subtransport *t)
665
+ {
666
+ int error;
667
+
668
+ switch (t->owner->proxy.type) {
669
+ case GIT_PROXY_NONE:
670
+ return 0;
671
+
672
+ case GIT_PROXY_AUTO:
673
+ git__free(t->proxy_url);
674
+ t->proxy_url = NULL;
675
+
676
+ git_proxy_init_options(&t->proxy_opts, GIT_PROXY_OPTIONS_VERSION);
677
+
678
+ if ((error = git_remote__get_http_proxy(t->owner->owner,
679
+ !!t->server.url.use_ssl, &t->proxy_url)) < 0)
680
+ return error;
681
+
682
+ if (!t->proxy_url)
683
+ return 0;
684
+
685
+ t->proxy_opts.type = GIT_PROXY_SPECIFIED;
686
+ t->proxy_opts.url = t->proxy_url;
687
+ t->proxy_opts.credentials = t->owner->proxy.credentials;
688
+ t->proxy_opts.certificate_check = t->owner->proxy.certificate_check;
689
+ t->proxy_opts.payload = t->owner->proxy.payload;
690
+ break;
691
+
692
+ case GIT_PROXY_SPECIFIED:
693
+ memcpy(&t->proxy_opts, &t->owner->proxy, sizeof(git_proxy_options));
694
+ break;
695
+
696
+ default:
697
+ assert(0);
698
+ return -1;
699
+ }
700
+
701
+ if ((error = gitno_connection_data_from_url(&t->proxy.url, t->proxy_opts.url, NULL)) < 0)
702
+ return error;
703
+
704
+ if (t->proxy.url.use_ssl) {
705
+ git_error_set(GIT_ERROR_NET, "SSL connections to proxy are not supported");
454
706
  return -1;
707
+ }
708
+
709
+ return error;
710
+ }
711
+
712
+ static int check_certificate(
713
+ git_stream *stream,
714
+ gitno_connection_data *url,
715
+ int is_valid,
716
+ git_transport_certificate_check_cb cert_cb,
717
+ void *cert_cb_payload)
718
+ {
719
+ git_cert *cert;
720
+ git_error_state last_error = {0};
721
+ int error;
722
+
723
+ if ((error = git_stream_certificate(&cert, stream)) < 0)
724
+ return error;
725
+
726
+ git_error_state_capture(&last_error, GIT_ECERTIFICATE);
727
+
728
+ error = cert_cb(cert, is_valid, url->host, cert_cb_payload);
729
+
730
+ if (error == GIT_PASSTHROUGH && !is_valid)
731
+ return git_error_state_restore(&last_error);
732
+ else if (error == GIT_PASSTHROUGH)
733
+ error = 0;
734
+ else if (error && !git_error_last())
735
+ git_error_set(GIT_ERROR_NET, "user rejected certificate for %s", url->host);
736
+
737
+ git_error_state_free(&last_error);
738
+ return error;
739
+ }
740
+
741
+ static int stream_connect(
742
+ git_stream *stream,
743
+ gitno_connection_data *url,
744
+ git_transport_certificate_check_cb cert_cb,
745
+ void *cb_payload)
746
+ {
747
+ int error;
748
+
749
+ GIT_ERROR_CHECK_VERSION(stream, GIT_STREAM_VERSION, "git_stream");
750
+
751
+ error = git_stream_connect(stream);
752
+
753
+ if (error && error != GIT_ECERTIFICATE)
754
+ return error;
755
+
756
+ if (git_stream_is_encrypted(stream) && cert_cb != NULL)
757
+ error = check_certificate(stream, url, !error, cert_cb, cb_payload);
758
+
759
+ return error;
760
+ }
761
+
762
+ static int gen_connect_req(git_buf *buf, http_subtransport *t)
763
+ {
764
+ git_buf_printf(buf, "CONNECT %s:%s HTTP/1.1\r\n",
765
+ t->server.url.host, t->server.url.port);
766
+
767
+ git_buf_puts(buf, "User-Agent: ");
768
+ git_http__user_agent(buf);
769
+ git_buf_puts(buf, "\r\n");
770
+
771
+ git_buf_printf(buf, "Host: %s\r\n", t->proxy.url.host);
772
+
773
+ if (apply_credentials(buf, &t->proxy, AUTH_HEADER_PROXY) < 0)
774
+ return -1;
775
+
776
+ git_buf_puts(buf, "\r\n");
777
+
778
+ return git_buf_oom(buf) ? -1 : 0;
779
+ }
780
+
781
+ static int proxy_headers_complete(http_parser *parser)
782
+ {
783
+ parser_context *ctx = (parser_context *) parser->data;
784
+ http_subtransport *t = ctx->t;
785
+ int proxy_auth_types = 0;
786
+
787
+ /* Enforce a reasonable cap on the number of replays */
788
+ if (t->replay_count++ >= GIT_HTTP_REPLAY_MAX) {
789
+ git_error_set(GIT_ERROR_NET, "too many redirects or authentication replays");
790
+ return t->parse_error = PARSE_ERROR_GENERIC;
791
+ }
792
+
793
+ /* Both parse_header_name and parse_header_value are populated
794
+ * and ready for consumption. */
795
+ if (VALUE == t->last_cb)
796
+ if (on_header_ready(t) < 0)
797
+ return t->parse_error = PARSE_ERROR_GENERIC;
798
+
799
+ /*
800
+ * Capture authentication headers for the proxy or final endpoint,
801
+ * these may be 407/401 (authentication is not complete) or a 200
802
+ * (informing us that auth has completed).
803
+ */
804
+ if (parse_authenticate_response(&t->proxy, &proxy_auth_types) < 0)
805
+ return t->parse_error = PARSE_ERROR_GENERIC;
806
+
807
+ /* Check for a proxy authentication failure. */
808
+ if (parser->status_code == 407)
809
+ return on_auth_required(&t->proxy.cred,
810
+ parser,
811
+ t->proxy_opts.url,
812
+ SERVER_TYPE_PROXY,
813
+ t->proxy_opts.credentials,
814
+ t->proxy_opts.payload,
815
+ t->proxy.url.user,
816
+ proxy_auth_types);
817
+
818
+ if (parser->status_code != 200) {
819
+ git_error_set(GIT_ERROR_NET, "unexpected status code from proxy: %d",
820
+ parser->status_code);
821
+ return t->parse_error = PARSE_ERROR_GENERIC;
822
+ }
823
+
824
+ if (!t->content_length || strcmp(t->content_length, "0") == 0)
825
+ t->parse_finished = 1;
455
826
 
456
827
  return 0;
457
828
  }
458
829
 
830
+ static int proxy_connect(
831
+ git_stream **out, git_stream *proxy_stream, http_subtransport *t)
832
+ {
833
+ git_buf request = GIT_BUF_INIT;
834
+ static http_parser_settings proxy_parser_settings = {0};
835
+ size_t bytes_read = 0, bytes_parsed;
836
+ parser_context ctx;
837
+ int error;
838
+
839
+ /* Use the parser settings only to parser headers. */
840
+ proxy_parser_settings.on_header_field = on_header_field;
841
+ proxy_parser_settings.on_header_value = on_header_value;
842
+ proxy_parser_settings.on_headers_complete = proxy_headers_complete;
843
+ proxy_parser_settings.on_message_complete = on_message_complete;
844
+
845
+ replay:
846
+ clear_parser_state(t);
847
+
848
+ gitno_buffer_setup_fromstream(proxy_stream,
849
+ &t->parse_buffer,
850
+ t->parse_buffer_data,
851
+ sizeof(t->parse_buffer_data));
852
+
853
+ if ((error = gen_connect_req(&request, t)) < 0)
854
+ goto done;
855
+
856
+ if ((error = git_stream__write_full(proxy_stream, request.ptr,
857
+ request.size, 0)) < 0)
858
+ goto done;
859
+
860
+ git_buf_dispose(&request);
861
+
862
+ while (!bytes_read && !t->parse_finished) {
863
+ t->parse_buffer.offset = 0;
864
+
865
+ if ((error = gitno_recv(&t->parse_buffer)) < 0)
866
+ goto done;
867
+
868
+ /*
869
+ * This call to http_parser_execute will invoke the on_*
870
+ * callbacks. Since we don't care about the body of the response,
871
+ * we can set our buffer to NULL.
872
+ */
873
+ ctx.t = t;
874
+ ctx.s = NULL;
875
+ ctx.buffer = NULL;
876
+ ctx.buf_size = 0;
877
+ ctx.bytes_read = &bytes_read;
878
+
879
+ /* Set the context, call the parser, then unset the context. */
880
+ t->parser.data = &ctx;
881
+
882
+ bytes_parsed = http_parser_execute(&t->parser,
883
+ &proxy_parser_settings, t->parse_buffer.data, t->parse_buffer.offset);
884
+
885
+ t->parser.data = NULL;
886
+
887
+ /* Ensure that we didn't get a redirect; unsupported. */
888
+ if (t->location) {
889
+ git_error_set(GIT_ERROR_NET, "proxy server sent unsupported redirect during CONNECT");
890
+ error = -1;
891
+ goto done;
892
+ }
893
+
894
+ /* Replay the request with authentication headers. */
895
+ if (PARSE_ERROR_REPLAY == t->parse_error)
896
+ goto replay;
897
+
898
+ if (t->parse_error < 0) {
899
+ error = t->parse_error == PARSE_ERROR_EXT ? PARSE_ERROR_EXT : -1;
900
+ goto done;
901
+ }
902
+
903
+ if (bytes_parsed != t->parse_buffer.offset) {
904
+ git_error_set(GIT_ERROR_NET,
905
+ "HTTP parser error: %s",
906
+ http_errno_description((enum http_errno)t->parser.http_errno));
907
+ error = -1;
908
+ goto done;
909
+ }
910
+ }
911
+
912
+ if ((error = git_tls_stream_wrap(out, proxy_stream, t->server.url.host)) == 0)
913
+ error = stream_connect(*out, &t->server.url,
914
+ t->owner->certificate_check_cb,
915
+ t->owner->message_cb_payload);
916
+
917
+ /*
918
+ * Since we've connected via a HTTPS proxy tunnel, we don't behave
919
+ * as if we have an HTTP proxy.
920
+ */
921
+ t->proxy_opts.type = GIT_PROXY_NONE;
922
+ t->replay_count = 0;
923
+
924
+ done:
925
+ return error;
926
+ }
927
+
459
928
  static int http_connect(http_subtransport *t)
460
929
  {
461
- int flags = 0;
930
+ gitno_connection_data *url;
931
+ git_stream *proxy_stream = NULL, *stream = NULL;
932
+ git_transport_certificate_check_cb cert_cb;
933
+ void *cb_payload;
934
+ int error;
462
935
 
463
936
  if (t->connected &&
464
937
  http_should_keep_alive(&t->parser) &&
465
- http_body_is_final(&t->parser))
938
+ t->parse_finished)
466
939
  return 0;
467
940
 
468
- if (t->socket.socket)
469
- gitno_close(&t->socket);
941
+ if ((error = load_proxy_config(t)) < 0)
942
+ return error;
470
943
 
471
- if (t->use_ssl) {
472
- int tflags;
944
+ if (t->server.stream) {
945
+ git_stream_close(t->server.stream);
946
+ git_stream_free(t->server.stream);
947
+ t->server.stream = NULL;
948
+ }
473
949
 
474
- if (t->owner->parent.read_flags(&t->owner->parent, &tflags) < 0)
475
- return -1;
950
+ if (t->proxy.stream) {
951
+ git_stream_close(t->proxy.stream);
952
+ git_stream_free(t->proxy.stream);
953
+ t->proxy.stream = NULL;
954
+ }
476
955
 
477
- flags |= GITNO_CONNECT_SSL;
956
+ t->connected = 0;
478
957
 
479
- if (GIT_TRANSPORTFLAGS_NO_CHECK_CERT & tflags)
480
- flags |= GITNO_CONNECT_SSL_NO_CHECK_CERT;
958
+ if (t->proxy_opts.type == GIT_PROXY_SPECIFIED) {
959
+ url = &t->proxy.url;
960
+ cert_cb = t->proxy_opts.certificate_check;
961
+ cb_payload = t->proxy_opts.payload;
962
+ } else {
963
+ url = &t->server.url;
964
+ cert_cb = t->owner->certificate_check_cb;
965
+ cb_payload = t->owner->message_cb_payload;
481
966
  }
482
967
 
483
- if (gitno_connect(&t->socket, t->host, t->port, flags) < 0)
484
- return -1;
968
+ if (url->use_ssl)
969
+ error = git_tls_stream_new(&stream, url->host, url->port);
970
+ else
971
+ error = git_socket_stream_new(&stream, url->host, url->port);
485
972
 
973
+ if (error < 0)
974
+ goto on_error;
975
+
976
+ if ((error = stream_connect(stream, url, cert_cb, cb_payload)) < 0)
977
+ goto on_error;
978
+
979
+ /*
980
+ * At this point we have a connection to the remote server or to
981
+ * a proxy. If it's a proxy and the remote server is actually
982
+ * an HTTPS connection, then we need to build a CONNECT tunnel.
983
+ */
984
+ if (t->proxy_opts.type == GIT_PROXY_SPECIFIED &&
985
+ t->server.url.use_ssl) {
986
+ proxy_stream = stream;
987
+ stream = NULL;
988
+
989
+ if ((error = proxy_connect(&stream, proxy_stream, t)) < 0)
990
+ goto on_error;
991
+ }
992
+
993
+ t->proxy.stream = proxy_stream;
994
+ t->server.stream = stream;
486
995
  t->connected = 1;
996
+ t->replay_count = 0;
487
997
  return 0;
998
+
999
+ on_error:
1000
+ if (stream) {
1001
+ git_stream_close(stream);
1002
+ git_stream_free(stream);
1003
+ }
1004
+
1005
+ if (proxy_stream) {
1006
+ git_stream_close(proxy_stream);
1007
+ git_stream_free(proxy_stream);
1008
+ }
1009
+
1010
+ return error;
488
1011
  }
489
1012
 
490
1013
  static int http_stream_read(
@@ -508,17 +1031,16 @@ replay:
508
1031
 
509
1032
  clear_parser_state(t);
510
1033
 
511
- if (gen_request(&request, s, 0) < 0) {
512
- giterr_set(GITERR_NET, "Failed to generate request");
1034
+ if (gen_request(&request, s, 0) < 0)
513
1035
  return -1;
514
- }
515
1036
 
516
- if (gitno_send(&t->socket, request.ptr, request.size, 0) < 0) {
517
- git_buf_free(&request);
1037
+ if (git_stream__write_full(t->server.stream, request.ptr,
1038
+ request.size, 0) < 0) {
1039
+ git_buf_dispose(&request);
518
1040
  return -1;
519
1041
  }
520
1042
 
521
- git_buf_free(&request);
1043
+ git_buf_dispose(&request);
522
1044
 
523
1045
  s->sent_request = 1;
524
1046
  }
@@ -529,13 +1051,15 @@ replay:
529
1051
 
530
1052
  /* Flush, if necessary */
531
1053
  if (s->chunk_buffer_len > 0 &&
532
- write_chunk(&t->socket, s->chunk_buffer, s->chunk_buffer_len) < 0)
1054
+ write_chunk(t->server.stream,
1055
+ s->chunk_buffer, s->chunk_buffer_len) < 0)
533
1056
  return -1;
534
1057
 
535
1058
  s->chunk_buffer_len = 0;
536
1059
 
537
1060
  /* Write the final chunk. */
538
- if (gitno_send(&t->socket, "0\r\n\r\n", 5, 0) < 0)
1061
+ if (git_stream__write_full(t->server.stream,
1062
+ "0\r\n\r\n", 5, 0) < 0)
539
1063
  return -1;
540
1064
  }
541
1065
 
@@ -543,7 +1067,24 @@ replay:
543
1067
  }
544
1068
 
545
1069
  while (!*bytes_read && !t->parse_finished) {
546
- t->parse_buffer.offset = 0;
1070
+ size_t data_offset;
1071
+ int error;
1072
+
1073
+ /*
1074
+ * Make the parse_buffer think it's as full of data as
1075
+ * the buffer, so it won't try to recv more data than
1076
+ * we can put into it.
1077
+ *
1078
+ * data_offset is the actual data offset from which we
1079
+ * should tell the parser to start reading.
1080
+ */
1081
+ if (buf_size >= t->parse_buffer.len) {
1082
+ t->parse_buffer.offset = 0;
1083
+ } else {
1084
+ t->parse_buffer.offset = t->parse_buffer.len - buf_size;
1085
+ }
1086
+
1087
+ data_offset = t->parse_buffer.offset;
547
1088
 
548
1089
  if (gitno_recv(&t->parse_buffer) < 0)
549
1090
  return -1;
@@ -564,8 +1105,8 @@ replay:
564
1105
 
565
1106
  bytes_parsed = http_parser_execute(&t->parser,
566
1107
  &t->settings,
567
- t->parse_buffer.data,
568
- t->parse_buffer.offset);
1108
+ t->parse_buffer.data + data_offset,
1109
+ t->parse_buffer.offset - data_offset);
569
1110
 
570
1111
  t->parser.data = NULL;
571
1112
 
@@ -574,17 +1115,21 @@ replay:
574
1115
  if (PARSE_ERROR_REPLAY == t->parse_error) {
575
1116
  s->sent_request = 0;
576
1117
 
577
- if (http_connect(t) < 0)
578
- return -1;
1118
+ if ((error = http_connect(t)) < 0)
1119
+ return error;
579
1120
 
580
1121
  goto replay;
581
1122
  }
582
1123
 
1124
+ if (t->parse_error == PARSE_ERROR_EXT) {
1125
+ return t->error;
1126
+ }
1127
+
583
1128
  if (t->parse_error < 0)
584
1129
  return -1;
585
1130
 
586
- if (bytes_parsed != t->parse_buffer.offset) {
587
- giterr_set(GITERR_NET,
1131
+ if (bytes_parsed != t->parse_buffer.offset - data_offset) {
1132
+ git_error_set(GIT_ERROR_NET,
588
1133
  "HTTP parser error: %s",
589
1134
  http_errno_description((enum http_errno)t->parser.http_errno));
590
1135
  return -1;
@@ -610,17 +1155,16 @@ static int http_stream_write_chunked(
610
1155
 
611
1156
  clear_parser_state(t);
612
1157
 
613
- if (gen_request(&request, s, 0) < 0) {
614
- giterr_set(GITERR_NET, "Failed to generate request");
1158
+ if (gen_request(&request, s, 0) < 0)
615
1159
  return -1;
616
- }
617
1160
 
618
- if (gitno_send(&t->socket, request.ptr, request.size, 0) < 0) {
619
- git_buf_free(&request);
1161
+ if (git_stream__write_full(t->server.stream, request.ptr,
1162
+ request.size, 0) < 0) {
1163
+ git_buf_dispose(&request);
620
1164
  return -1;
621
1165
  }
622
1166
 
623
- git_buf_free(&request);
1167
+ git_buf_dispose(&request);
624
1168
 
625
1169
  s->sent_request = 1;
626
1170
  }
@@ -628,14 +1172,15 @@ static int http_stream_write_chunked(
628
1172
  if (len > CHUNK_SIZE) {
629
1173
  /* Flush, if necessary */
630
1174
  if (s->chunk_buffer_len > 0) {
631
- if (write_chunk(&t->socket, s->chunk_buffer, s->chunk_buffer_len) < 0)
1175
+ if (write_chunk(t->server.stream,
1176
+ s->chunk_buffer, s->chunk_buffer_len) < 0)
632
1177
  return -1;
633
1178
 
634
1179
  s->chunk_buffer_len = 0;
635
1180
  }
636
1181
 
637
1182
  /* Write chunk directly */
638
- if (write_chunk(&t->socket, buffer, len) < 0)
1183
+ if (write_chunk(t->server.stream, buffer, len) < 0)
639
1184
  return -1;
640
1185
  }
641
1186
  else {
@@ -652,7 +1197,8 @@ static int http_stream_write_chunked(
652
1197
 
653
1198
  /* Is the buffer full? If so, then flush */
654
1199
  if (CHUNK_SIZE == s->chunk_buffer_len) {
655
- if (write_chunk(&t->socket, s->chunk_buffer, s->chunk_buffer_len) < 0)
1200
+ if (write_chunk(t->server.stream,
1201
+ s->chunk_buffer, s->chunk_buffer_len) < 0)
656
1202
  return -1;
657
1203
 
658
1204
  s->chunk_buffer_len = 0;
@@ -679,30 +1225,28 @@ static int http_stream_write_single(
679
1225
  assert(t->connected);
680
1226
 
681
1227
  if (s->sent_request) {
682
- giterr_set(GITERR_NET, "Subtransport configured for only one write");
1228
+ git_error_set(GIT_ERROR_NET, "subtransport configured for only one write");
683
1229
  return -1;
684
1230
  }
685
1231
 
686
1232
  clear_parser_state(t);
687
1233
 
688
- if (gen_request(&request, s, len) < 0) {
689
- giterr_set(GITERR_NET, "Failed to generate request");
1234
+ if (gen_request(&request, s, len) < 0)
690
1235
  return -1;
691
- }
692
1236
 
693
- if (gitno_send(&t->socket, request.ptr, request.size, 0) < 0)
1237
+ if (git_stream__write_full(t->server.stream, request.ptr, request.size, 0) < 0)
694
1238
  goto on_error;
695
1239
 
696
- if (len && gitno_send(&t->socket, buffer, len, 0) < 0)
1240
+ if (len && git_stream__write_full(t->server.stream, buffer, len, 0) < 0)
697
1241
  goto on_error;
698
1242
 
699
- git_buf_free(&request);
1243
+ git_buf_dispose(&request);
700
1244
  s->sent_request = 1;
701
1245
 
702
1246
  return 0;
703
1247
 
704
1248
  on_error:
705
- git_buf_free(&request);
1249
+ git_buf_dispose(&request);
706
1250
  return -1;
707
1251
  }
708
1252
 
@@ -728,7 +1272,7 @@ static int http_stream_alloc(http_subtransport *t,
728
1272
  return -1;
729
1273
 
730
1274
  s = git__calloc(sizeof(http_stream), 1);
731
- GITERR_CHECK_ALLOC(s);
1275
+ GIT_ERROR_CHECK_ALLOC(s);
732
1276
 
733
1277
  s->parent.subtransport = &t->parent;
734
1278
  s->parent.read = http_stream_read;
@@ -822,54 +1366,55 @@ static int http_action(
822
1366
  git_smart_service_t action)
823
1367
  {
824
1368
  http_subtransport *t = (http_subtransport *)subtransport;
825
- const char *default_port = NULL;
826
1369
  int ret;
827
1370
 
828
- if (!stream)
829
- return -1;
1371
+ assert(stream);
830
1372
 
831
- if (!t->host || !t->port || !t->path) {
832
- if (!git__prefixcmp(url, prefix_http)) {
833
- url = url + strlen(prefix_http);
834
- default_port = "80";
835
- }
1373
+ /*
1374
+ * If we've seen a redirect then preserve the location that we've
1375
+ * been given. This is important to continue authorization against
1376
+ * the redirect target, not the user-given source; the endpoint may
1377
+ * have redirected us from HTTP->HTTPS and is using an auth mechanism
1378
+ * that would be insecure in plaintext (eg, HTTP Basic).
1379
+ */
1380
+ if ((!t->server.url.host || !t->server.url.port || !t->server.url.path) &&
1381
+ (ret = gitno_connection_data_from_url(&t->server.url, url, NULL)) < 0)
1382
+ return ret;
836
1383
 
837
- if (!git__prefixcmp(url, prefix_https)) {
838
- url += strlen(prefix_https);
839
- default_port = "443";
840
- t->use_ssl = 1;
841
- }
1384
+ assert(t->server.url.host && t->server.url.port && t->server.url.path);
842
1385
 
843
- if (!default_port)
844
- return -1;
1386
+ if ((ret = http_connect(t)) < 0)
1387
+ return ret;
845
1388
 
846
- if ((ret = gitno_extract_url_parts(&t->host, &t->port,
847
- &t->user_from_url, &t->pass_from_url, url, default_port)) < 0)
848
- return ret;
1389
+ switch (action) {
1390
+ case GIT_SERVICE_UPLOADPACK_LS:
1391
+ return http_uploadpack_ls(t, stream);
849
1392
 
850
- t->path = strchr(url, '/');
851
- }
1393
+ case GIT_SERVICE_UPLOADPACK:
1394
+ return http_uploadpack(t, stream);
852
1395
 
853
- if (http_connect(t) < 0)
854
- return -1;
1396
+ case GIT_SERVICE_RECEIVEPACK_LS:
1397
+ return http_receivepack_ls(t, stream);
855
1398
 
856
- switch (action)
857
- {
858
- case GIT_SERVICE_UPLOADPACK_LS:
859
- return http_uploadpack_ls(t, stream);
1399
+ case GIT_SERVICE_RECEIVEPACK:
1400
+ return http_receivepack(t, stream);
1401
+ }
860
1402
 
861
- case GIT_SERVICE_UPLOADPACK:
862
- return http_uploadpack(t, stream);
1403
+ *stream = NULL;
1404
+ return -1;
1405
+ }
863
1406
 
864
- case GIT_SERVICE_RECEIVEPACK_LS:
865
- return http_receivepack_ls(t, stream);
1407
+ static void free_auth_contexts(git_vector *contexts)
1408
+ {
1409
+ git_http_auth_context *context;
1410
+ size_t i;
866
1411
 
867
- case GIT_SERVICE_RECEIVEPACK:
868
- return http_receivepack(t, stream);
1412
+ git_vector_foreach(contexts, i, context) {
1413
+ if (context->free)
1414
+ context->free(context);
869
1415
  }
870
1416
 
871
- *stream = NULL;
872
- return -1;
1417
+ git_vector_clear(contexts);
873
1418
  }
874
1419
 
875
1420
  static int http_close(git_smart_subtransport *subtransport)
@@ -878,40 +1423,36 @@ static int http_close(git_smart_subtransport *subtransport)
878
1423
 
879
1424
  clear_parser_state(t);
880
1425
 
881
- if (t->socket.socket) {
882
- gitno_close(&t->socket);
883
- memset(&t->socket, 0x0, sizeof(gitno_socket));
884
- }
1426
+ t->connected = 0;
885
1427
 
886
- if (t->cred) {
887
- t->cred->free(t->cred);
888
- t->cred = NULL;
1428
+ if (t->server.stream) {
1429
+ git_stream_close(t->server.stream);
1430
+ git_stream_free(t->server.stream);
1431
+ t->server.stream = NULL;
889
1432
  }
890
1433
 
891
- if (t->url_cred) {
892
- t->url_cred->free(t->url_cred);
893
- t->url_cred = NULL;
1434
+ if (t->proxy.stream) {
1435
+ git_stream_close(t->proxy.stream);
1436
+ git_stream_free(t->proxy.stream);
1437
+ t->proxy.stream = NULL;
894
1438
  }
895
1439
 
896
- if (t->host) {
897
- git__free(t->host);
898
- t->host = NULL;
899
- }
1440
+ free_cred(&t->server.cred);
1441
+ free_cred(&t->server.url_cred);
1442
+ free_cred(&t->proxy.cred);
1443
+ free_cred(&t->proxy.url_cred);
900
1444
 
901
- if (t->port) {
902
- git__free(t->port);
903
- t->port = NULL;
904
- }
1445
+ free_auth_contexts(&t->server.auth_contexts);
1446
+ free_auth_contexts(&t->proxy.auth_contexts);
905
1447
 
906
- if (t->user_from_url) {
907
- git__free(t->user_from_url);
908
- t->user_from_url = NULL;
909
- }
1448
+ gitno_connection_data_free_ptrs(&t->server.url);
1449
+ memset(&t->server.url, 0x0, sizeof(gitno_connection_data));
910
1450
 
911
- if (t->pass_from_url) {
912
- git__free(t->pass_from_url);
913
- t->pass_from_url = NULL;
914
- }
1451
+ gitno_connection_data_free_ptrs(&t->proxy.url);
1452
+ memset(&t->proxy.url, 0x0, sizeof(gitno_connection_data));
1453
+
1454
+ git__free(t->proxy_url);
1455
+ t->proxy_url = NULL;
915
1456
 
916
1457
  return 0;
917
1458
  }
@@ -922,18 +1463,22 @@ static void http_free(git_smart_subtransport *subtransport)
922
1463
 
923
1464
  http_close(subtransport);
924
1465
 
1466
+ git_vector_free(&t->server.auth_contexts);
1467
+ git_vector_free(&t->proxy.auth_contexts);
925
1468
  git__free(t);
926
1469
  }
927
1470
 
928
- int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *owner)
1471
+ int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *owner, void *param)
929
1472
  {
930
1473
  http_subtransport *t;
931
1474
 
1475
+ GIT_UNUSED(param);
1476
+
932
1477
  if (!out)
933
1478
  return -1;
934
1479
 
935
1480
  t = git__calloc(sizeof(http_subtransport), 1);
936
- GITERR_CHECK_ALLOC(t);
1481
+ GIT_ERROR_CHECK_ALLOC(t);
937
1482
 
938
1483
  t->owner = (transport_smart *)owner;
939
1484
  t->parent.action = http_action;