You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SmartClientSmartServerTest.java 48KB

Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Do authentication re-tries on HTTP POST There is at least one git server out there (GOGS) that does not require authentication on the initial GET for info/refs?service=git-receive-pack but that _does_ require authentication for the subsequent POST to actually do the push. This occurs on GOGS with public repositories; for private repositories it wants authentication up front. Handle this behavior by adding 401 handling to our POST request. Note that this is suboptimal; we'll re-send the push data at least twice if an authentication failure on POST occurs. It would be much better if the server required authentication up-front in the GET request. Added authentication unit tests (using BASIC auth) to the SmartClientSmartServerTest: - clone with authentication - clone with authentication but lacking CredentialsProvider - clone with authentication and wrong password - clone with authentication after redirect - clone with authentication only on POST, but not on GET Also tested manually in the wild using repositories at try.gogs.io. That server offers only BASIC auth, so the other paths (DIGEST, NEGOTIATE, fall back from DIGEST to BASIC) are untested and I have no way to test them. * public repository: GET unauthenticated, POST authenticated Also tested after clearing the credentials and then entering a wrong password: correctly asks three times during the HTTP POST for user name and password, then gives up. * private repository: authentication already on GET; then gets applied correctly initially to the POST request, which succeeds. Also fix the authentication to use the credentials for the redirected URI if redirects had occurred. We must not present the credentials for the original URI in that case. Consider a malicious redirect A->B: this would allow server B to harvest the user credentials for server A. The unit test for authentication after a redirect also tests for this. Bug: 513043 Change-Id: I97ee5058569efa1545a6c6f6edfd2b357c40592a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
7 years ago
Add support to follow HTTP redirects git-core follows HTTP redirects so JGit should also provide this. Implement config setting http.followRedirects with possible values "false" (= never), "true" (= always), and "initial" (only on GET, but not on POST).[1] We must do our own redirect handling and cannot rely on the support that the underlying real connection may offer. At least the JDK's HttpURLConnection has two features that get in the way: * it does not allow cross-protocol redirects and thus fails on http->https redirects (for instance, on Github). * it translates a redirect after a POST to a GET unless the system property "http.strictPostRedirect" is set to true. We don't want to manipulate that system setting nor require it. Additionally, git has its own rules about what redirects it accepts;[2] for instance, it does not allow a redirect that adds query arguments. We handle response codes 301, 302, 303, and 307 as per RFC 2616.[3] On POST we do not handle 303, and we follow redirects only if http.followRedirects == true. Redirects are followed only a certain number of times. There are two ways to control that limit: * by default, the limit is given by the http.maxRedirects system property that is also used by the JDK. If the system property is not set, the default is 5. (This is much lower than the JDK default of 20, but I don't see the value of following so many redirects.) * this can be overwritten by a http.maxRedirects git config setting. The JGit http.* git config settings are currently all global; JGit has no support yet for URI-specific settings "http.<pattern>.name". Adding support for that is well beyond the scope of this change. Like git-core, we log every redirect attempt (LOG.info) so that users may know about the redirection having occurred. Extends the test framework to configure an AppServer with HTTPS support so that we can test cloning via HTTPS and redirections involving HTTPS. [1] https://git-scm.com/docs/git-config [2] https://kernel.googlesource.com/pub/scm/git/git/+/6628eb41db5189c0cdfdced6d8697e7c813c5f0f [3] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html CQ: 13987 Bug: 465167 Change-Id: I86518cb76842f7d326b51f8715e3bbf8ada89859 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
9 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357
  1. /*
  2. * Copyright (C) 2010, 2017 Google Inc. and others
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.http.test;
  11. import static java.nio.charset.StandardCharsets.UTF_8;
  12. import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING;
  13. import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_LENGTH;
  14. import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_TYPE;
  15. import static org.junit.Assert.assertEquals;
  16. import static org.junit.Assert.assertFalse;
  17. import static org.junit.Assert.assertNotNull;
  18. import static org.junit.Assert.assertNull;
  19. import static org.junit.Assert.assertThrows;
  20. import static org.junit.Assert.assertTrue;
  21. import static org.junit.Assert.fail;
  22. import java.io.IOException;
  23. import java.io.PrintWriter;
  24. import java.net.URI;
  25. import java.net.URISyntaxException;
  26. import java.text.MessageFormat;
  27. import java.util.Collections;
  28. import java.util.EnumSet;
  29. import java.util.List;
  30. import java.util.Map;
  31. import java.util.regex.Matcher;
  32. import java.util.regex.Pattern;
  33. import javax.servlet.DispatcherType;
  34. import javax.servlet.Filter;
  35. import javax.servlet.FilterChain;
  36. import javax.servlet.FilterConfig;
  37. import javax.servlet.RequestDispatcher;
  38. import javax.servlet.ServletException;
  39. import javax.servlet.ServletRequest;
  40. import javax.servlet.ServletResponse;
  41. import javax.servlet.http.HttpServletRequest;
  42. import javax.servlet.http.HttpServletResponse;
  43. import org.eclipse.jetty.servlet.FilterHolder;
  44. import org.eclipse.jetty.servlet.ServletContextHandler;
  45. import org.eclipse.jetty.servlet.ServletHolder;
  46. import org.eclipse.jgit.errors.RemoteRepositoryException;
  47. import org.eclipse.jgit.errors.TransportException;
  48. import org.eclipse.jgit.errors.UnsupportedCredentialItem;
  49. import org.eclipse.jgit.http.server.GitServlet;
  50. import org.eclipse.jgit.http.server.resolver.DefaultUploadPackFactory;
  51. import org.eclipse.jgit.internal.JGitText;
  52. import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
  53. import org.eclipse.jgit.junit.TestRepository;
  54. import org.eclipse.jgit.junit.TestRng;
  55. import org.eclipse.jgit.junit.http.AccessEvent;
  56. import org.eclipse.jgit.junit.http.AppServer;
  57. import org.eclipse.jgit.lib.ConfigConstants;
  58. import org.eclipse.jgit.lib.Constants;
  59. import org.eclipse.jgit.lib.NullProgressMonitor;
  60. import org.eclipse.jgit.lib.ObjectId;
  61. import org.eclipse.jgit.lib.ObjectIdRef;
  62. import org.eclipse.jgit.lib.ObjectInserter;
  63. import org.eclipse.jgit.lib.Ref;
  64. import org.eclipse.jgit.lib.ReflogEntry;
  65. import org.eclipse.jgit.lib.ReflogReader;
  66. import org.eclipse.jgit.lib.Repository;
  67. import org.eclipse.jgit.lib.StoredConfig;
  68. import org.eclipse.jgit.revwalk.RevBlob;
  69. import org.eclipse.jgit.revwalk.RevCommit;
  70. import org.eclipse.jgit.revwalk.RevWalk;
  71. import org.eclipse.jgit.transport.AbstractAdvertiseRefsHook;
  72. import org.eclipse.jgit.transport.AdvertiseRefsHook;
  73. import org.eclipse.jgit.transport.CredentialItem;
  74. import org.eclipse.jgit.transport.CredentialsProvider;
  75. import org.eclipse.jgit.transport.FetchConnection;
  76. import org.eclipse.jgit.transport.HttpTransport;
  77. import org.eclipse.jgit.transport.RefSpec;
  78. import org.eclipse.jgit.transport.RemoteRefUpdate;
  79. import org.eclipse.jgit.transport.Transport;
  80. import org.eclipse.jgit.transport.TransportHttp;
  81. import org.eclipse.jgit.transport.URIish;
  82. import org.eclipse.jgit.transport.UploadPack;
  83. import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
  84. import org.eclipse.jgit.transport.http.HttpConnectionFactory;
  85. import org.eclipse.jgit.util.HttpSupport;
  86. import org.eclipse.jgit.util.SystemReader;
  87. import org.junit.Before;
  88. import org.junit.Test;
  89. public class SmartClientSmartServerTest extends AllFactoriesHttpTestCase {
  90. private static final String HDR_TRANSFER_ENCODING = "Transfer-Encoding";
  91. private AdvertiseRefsHook advertiseRefsHook;
  92. private Repository remoteRepository;
  93. private CredentialsProvider testCredentials = new UsernamePasswordCredentialsProvider(
  94. AppServer.username, AppServer.password);
  95. private URIish remoteURI;
  96. private URIish brokenURI;
  97. private URIish redirectURI;
  98. private URIish authURI;
  99. private URIish authOnPostURI;
  100. private RevBlob A_txt;
  101. private RevCommit A, B, unreachableCommit;
  102. public SmartClientSmartServerTest(HttpConnectionFactory cf) {
  103. super(cf);
  104. }
  105. @Override
  106. @Before
  107. public void setUp() throws Exception {
  108. super.setUp();
  109. final TestRepository<Repository> src = createTestRepository();
  110. final String srcName = src.getRepository().getDirectory().getName();
  111. src.getRepository()
  112. .getConfig()
  113. .setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
  114. ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, true);
  115. GitServlet gs = new GitServlet();
  116. gs.setUploadPackFactory((HttpServletRequest req, Repository db) -> {
  117. DefaultUploadPackFactory f = new DefaultUploadPackFactory();
  118. UploadPack up = f.create(req, db);
  119. if (advertiseRefsHook != null) {
  120. up.setAdvertiseRefsHook(advertiseRefsHook);
  121. }
  122. return up;
  123. });
  124. ServletContextHandler app = addNormalContext(gs, src, srcName);
  125. ServletContextHandler broken = addBrokenContext(gs, srcName);
  126. ServletContextHandler redirect = addRedirectContext(gs);
  127. ServletContextHandler auth = addAuthContext(gs, "auth");
  128. ServletContextHandler authOnPost = addAuthContext(gs, "pauth", "POST");
  129. server.setUp();
  130. remoteRepository = src.getRepository();
  131. remoteURI = toURIish(app, srcName);
  132. brokenURI = toURIish(broken, srcName);
  133. redirectURI = toURIish(redirect, srcName);
  134. authURI = toURIish(auth, srcName);
  135. authOnPostURI = toURIish(authOnPost, srcName);
  136. A_txt = src.blob("A");
  137. A = src.commit().add("A_txt", A_txt).create();
  138. B = src.commit().parent(A).add("A_txt", "C").add("B", "B").create();
  139. src.update(master, B);
  140. unreachableCommit = src.commit().add("A_txt", A_txt).create();
  141. src.update("refs/garbage/a/very/long/ref/name/to/compress", B);
  142. }
  143. private ServletContextHandler addNormalContext(GitServlet gs, TestRepository<Repository> src, String srcName) {
  144. ServletContextHandler app = server.addContext("/git");
  145. app.addFilter(new FilterHolder(new Filter() {
  146. @Override
  147. public void init(FilterConfig filterConfig)
  148. throws ServletException {
  149. // empty
  150. }
  151. // Does an internal forward for GET requests containing "/post/",
  152. // and issues a 301 redirect on POST requests for such URLs. Used
  153. // in the POST redirect tests.
  154. @Override
  155. public void doFilter(ServletRequest request,
  156. ServletResponse response, FilterChain chain)
  157. throws IOException, ServletException {
  158. final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
  159. final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
  160. final StringBuffer fullUrl = httpServletRequest.getRequestURL();
  161. if (httpServletRequest.getQueryString() != null) {
  162. fullUrl.append("?")
  163. .append(httpServletRequest.getQueryString());
  164. }
  165. String urlString = fullUrl.toString();
  166. if ("POST".equalsIgnoreCase(httpServletRequest.getMethod())) {
  167. httpServletResponse.setStatus(
  168. HttpServletResponse.SC_MOVED_PERMANENTLY);
  169. httpServletResponse.setHeader(HttpSupport.HDR_LOCATION,
  170. urlString.replace("/post/", "/"));
  171. } else {
  172. String path = httpServletRequest.getPathInfo();
  173. path = path.replace("/post/", "/");
  174. if (httpServletRequest.getQueryString() != null) {
  175. path += '?' + httpServletRequest.getQueryString();
  176. }
  177. RequestDispatcher dispatcher = httpServletRequest
  178. .getRequestDispatcher(path);
  179. dispatcher.forward(httpServletRequest, httpServletResponse);
  180. }
  181. }
  182. @Override
  183. public void destroy() {
  184. // empty
  185. }
  186. }), "/post/*", EnumSet.of(DispatcherType.REQUEST));
  187. gs.setRepositoryResolver(new TestRepositoryResolver(src, srcName));
  188. app.addServlet(new ServletHolder(gs), "/*");
  189. return app;
  190. }
  191. private ServletContextHandler addBrokenContext(GitServlet gs,
  192. String srcName) {
  193. ServletContextHandler broken = server.addContext("/bad");
  194. broken.addFilter(new FilterHolder(new Filter() {
  195. @Override
  196. public void doFilter(ServletRequest request,
  197. ServletResponse response, FilterChain chain)
  198. throws IOException, ServletException {
  199. final HttpServletResponse r = (HttpServletResponse) response;
  200. r.setContentType("text/plain");
  201. r.setCharacterEncoding(UTF_8.name());
  202. try (PrintWriter w = r.getWriter()) {
  203. w.print("OK");
  204. }
  205. }
  206. @Override
  207. public void init(FilterConfig filterConfig)
  208. throws ServletException {
  209. // empty
  210. }
  211. @Override
  212. public void destroy() {
  213. // empty
  214. }
  215. }), "/" + srcName + "/git-upload-pack",
  216. EnumSet.of(DispatcherType.REQUEST));
  217. broken.addServlet(new ServletHolder(gs), "/*");
  218. return broken;
  219. }
  220. private ServletContextHandler addAuthContext(GitServlet gs,
  221. String contextPath, String... methods) {
  222. ServletContextHandler auth = server.addContext('/' + contextPath);
  223. auth.addServlet(new ServletHolder(gs), "/*");
  224. return server.authBasic(auth, methods);
  225. }
  226. private ServletContextHandler addRedirectContext(GitServlet gs) {
  227. ServletContextHandler redirect = server.addContext("/redirect");
  228. redirect.addFilter(new FilterHolder(new Filter() {
  229. // Enables tests for different codes, and for multiple redirects.
  230. // First parameter is the number of redirects, second one is the
  231. // redirect status code that should be used
  232. private Pattern responsePattern = Pattern
  233. .compile("/response/(\\d+)/(30[1237])/");
  234. // Enables tests to specify the context that the request should be
  235. // redirected to in the end. If not present, redirects got to the
  236. // normal /git context.
  237. private Pattern targetPattern = Pattern.compile("/target(/\\w+)/");
  238. @Override
  239. public void init(FilterConfig filterConfig)
  240. throws ServletException {
  241. // empty
  242. }
  243. private String local(String url, boolean toLocal) {
  244. if (!toLocal) {
  245. return url;
  246. }
  247. try {
  248. URI u = new URI(url);
  249. String fragment = u.getRawFragment();
  250. if (fragment != null) {
  251. return u.getRawPath() + '#' + fragment;
  252. }
  253. return u.getRawPath();
  254. } catch (URISyntaxException e) {
  255. return url;
  256. }
  257. }
  258. @Override
  259. public void doFilter(ServletRequest request,
  260. ServletResponse response, FilterChain chain)
  261. throws IOException, ServletException {
  262. final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
  263. final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
  264. final StringBuffer fullUrl = httpServletRequest.getRequestURL();
  265. if (httpServletRequest.getQueryString() != null) {
  266. fullUrl.append("?")
  267. .append(httpServletRequest.getQueryString());
  268. }
  269. String urlString = fullUrl.toString();
  270. boolean localRedirect = false;
  271. if (urlString.contains("/local")) {
  272. urlString = urlString.replace("/local", "");
  273. localRedirect = true;
  274. }
  275. if (urlString.contains("/loop/")) {
  276. urlString = urlString.replace("/loop/", "/loop/x/");
  277. if (urlString.contains("/loop/x/x/x/x/x/x/x/x/")) {
  278. // Go back to initial.
  279. urlString = urlString.replace("/loop/x/x/x/x/x/x/x/x/",
  280. "/loop/");
  281. }
  282. httpServletResponse.setStatus(
  283. HttpServletResponse.SC_MOVED_TEMPORARILY);
  284. httpServletResponse.setHeader(HttpSupport.HDR_LOCATION,
  285. local(urlString, localRedirect));
  286. return;
  287. }
  288. int responseCode = HttpServletResponse.SC_MOVED_PERMANENTLY;
  289. int nofRedirects = 0;
  290. Matcher matcher = responsePattern.matcher(urlString);
  291. if (matcher.find()) {
  292. nofRedirects = Integer
  293. .parseUnsignedInt(matcher.group(1));
  294. responseCode = Integer.parseUnsignedInt(matcher.group(2));
  295. if (--nofRedirects <= 0) {
  296. urlString = urlString.substring(0, matcher.start())
  297. + '/' + urlString.substring(matcher.end());
  298. } else {
  299. urlString = urlString.substring(0, matcher.start())
  300. + "/response/" + nofRedirects + "/"
  301. + responseCode + '/'
  302. + urlString.substring(matcher.end());
  303. }
  304. }
  305. httpServletResponse.setStatus(responseCode);
  306. if (nofRedirects <= 0) {
  307. String targetContext = "/git";
  308. matcher = targetPattern.matcher(urlString);
  309. if (matcher.find()) {
  310. urlString = urlString.substring(0, matcher.start())
  311. + '/' + urlString.substring(matcher.end());
  312. targetContext = matcher.group(1);
  313. }
  314. urlString = urlString.replace("/redirect", targetContext);
  315. }
  316. httpServletResponse.setHeader(HttpSupport.HDR_LOCATION,
  317. local(urlString, localRedirect));
  318. }
  319. @Override
  320. public void destroy() {
  321. // empty
  322. }
  323. }), "/*", EnumSet.of(DispatcherType.REQUEST));
  324. redirect.addServlet(new ServletHolder(gs), "/*");
  325. return redirect;
  326. }
  327. @Test
  328. public void testListRemote() throws IOException {
  329. assertEquals("http", remoteURI.getScheme());
  330. Map<String, Ref> map;
  331. try (Repository dst = createBareRepository();
  332. Transport t = Transport.open(dst, remoteURI)) {
  333. // I didn't make up these public interface names, I just
  334. // approved them for inclusion into the code base. Sorry.
  335. // --spearce
  336. //
  337. assertTrue("isa TransportHttp", t instanceof TransportHttp);
  338. assertTrue("isa HttpTransport", t instanceof HttpTransport);
  339. try (FetchConnection c = t.openFetch()) {
  340. map = c.getRefsMap();
  341. }
  342. }
  343. assertNotNull("have map of refs", map);
  344. assertEquals(3, map.size());
  345. assertNotNull("has " + master, map.get(master));
  346. assertEquals(B, map.get(master).getObjectId());
  347. assertNotNull("has " + Constants.HEAD, map.get(Constants.HEAD));
  348. assertEquals(B, map.get(Constants.HEAD).getObjectId());
  349. List<AccessEvent> requests = getRequests();
  350. assertEquals(1, requests.size());
  351. AccessEvent info = requests.get(0);
  352. assertEquals("GET", info.getMethod());
  353. assertEquals(join(remoteURI, "info/refs"), info.getPath());
  354. assertEquals(1, info.getParameters().size());
  355. assertEquals("git-upload-pack", info.getParameter("service"));
  356. assertEquals(200, info.getStatus());
  357. assertEquals("application/x-git-upload-pack-advertisement", info
  358. .getResponseHeader(HDR_CONTENT_TYPE));
  359. assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));
  360. }
  361. @Test
  362. public void testListRemote_BadName() throws IOException, URISyntaxException {
  363. URIish uri = new URIish(this.remoteURI.toString() + ".invalid");
  364. try (Repository dst = createBareRepository();
  365. Transport t = Transport.open(dst, uri)) {
  366. try {
  367. t.openFetch();
  368. fail("fetch connection opened");
  369. } catch (RemoteRepositoryException notFound) {
  370. assertEquals(uri + ": Git repository not found",
  371. notFound.getMessage());
  372. }
  373. }
  374. List<AccessEvent> requests = getRequests();
  375. assertEquals(1, requests.size());
  376. AccessEvent info = requests.get(0);
  377. assertEquals("GET", info.getMethod());
  378. assertEquals(join(uri, "info/refs"), info.getPath());
  379. assertEquals(1, info.getParameters().size());
  380. assertEquals("git-upload-pack", info.getParameter("service"));
  381. assertEquals(200, info.getStatus());
  382. assertEquals("application/x-git-upload-pack-advertisement",
  383. info.getResponseHeader(HDR_CONTENT_TYPE));
  384. }
  385. @Test
  386. public void testFetchBySHA1() throws Exception {
  387. try (Repository dst = createBareRepository();
  388. Transport t = Transport.open(dst, remoteURI)) {
  389. assertFalse(dst.getObjectDatabase().has(A_txt));
  390. t.fetch(NullProgressMonitor.INSTANCE,
  391. Collections.singletonList(new RefSpec(B.name())));
  392. assertTrue(dst.getObjectDatabase().has(A_txt));
  393. }
  394. }
  395. @Test
  396. public void testFetchBySHA1Unreachable() throws Exception {
  397. try (Repository dst = createBareRepository();
  398. Transport t = Transport.open(dst, remoteURI)) {
  399. assertFalse(dst.getObjectDatabase().has(A_txt));
  400. Exception e = assertThrows(TransportException.class,
  401. () -> t.fetch(NullProgressMonitor.INSTANCE,
  402. Collections.singletonList(
  403. new RefSpec(unreachableCommit.name()))));
  404. assertTrue(e.getMessage().contains(
  405. "want " + unreachableCommit.name() + " not valid"));
  406. }
  407. }
  408. @Test
  409. public void testFetchBySHA1UnreachableByAdvertiseRefsHook()
  410. throws Exception {
  411. advertiseRefsHook = new AbstractAdvertiseRefsHook() {
  412. @Override
  413. protected Map<String, Ref> getAdvertisedRefs(Repository repository,
  414. RevWalk revWalk) {
  415. return Collections.emptyMap();
  416. }
  417. };
  418. try (Repository dst = createBareRepository();
  419. Transport t = Transport.open(dst, remoteURI)) {
  420. assertFalse(dst.getObjectDatabase().has(A_txt));
  421. Exception e = assertThrows(TransportException.class,
  422. () -> t.fetch(NullProgressMonitor.INSTANCE,
  423. Collections.singletonList(new RefSpec(A.name()))));
  424. assertTrue(
  425. e.getMessage().contains("want " + A.name() + " not valid"));
  426. }
  427. }
  428. @Test
  429. public void testInitialClone_Small() throws Exception {
  430. try (Repository dst = createBareRepository();
  431. Transport t = Transport.open(dst, remoteURI)) {
  432. assertFalse(dst.getObjectDatabase().has(A_txt));
  433. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  434. assertTrue(dst.getObjectDatabase().has(A_txt));
  435. assertEquals(B, dst.exactRef(master).getObjectId());
  436. fsck(dst, B);
  437. }
  438. List<AccessEvent> requests = getRequests();
  439. assertEquals(2, requests.size());
  440. AccessEvent info = requests.get(0);
  441. assertEquals("GET", info.getMethod());
  442. assertEquals(join(remoteURI, "info/refs"), info.getPath());
  443. assertEquals(1, info.getParameters().size());
  444. assertEquals("git-upload-pack", info.getParameter("service"));
  445. assertEquals(200, info.getStatus());
  446. assertEquals("application/x-git-upload-pack-advertisement", info
  447. .getResponseHeader(HDR_CONTENT_TYPE));
  448. assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));
  449. AccessEvent service = requests.get(1);
  450. assertEquals("POST", service.getMethod());
  451. assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
  452. assertEquals(0, service.getParameters().size());
  453. assertNotNull("has content-length", service
  454. .getRequestHeader(HDR_CONTENT_LENGTH));
  455. assertNull("not chunked", service
  456. .getRequestHeader(HDR_TRANSFER_ENCODING));
  457. assertEquals(200, service.getStatus());
  458. assertEquals("application/x-git-upload-pack-result", service
  459. .getResponseHeader(HDR_CONTENT_TYPE));
  460. }
  461. private void initialClone_Redirect(int nofRedirects, int code)
  462. throws Exception {
  463. initialClone_Redirect(nofRedirects, code, false);
  464. }
  465. private void initialClone_Redirect(int nofRedirects, int code,
  466. boolean localRedirect) throws Exception {
  467. URIish cloneFrom = redirectURI;
  468. if (localRedirect) {
  469. cloneFrom = extendPath(cloneFrom, "/local");
  470. }
  471. if (code != 301 || nofRedirects > 1) {
  472. cloneFrom = extendPath(cloneFrom,
  473. "/response/" + nofRedirects + "/" + code);
  474. }
  475. try (Repository dst = createBareRepository();
  476. Transport t = Transport.open(dst, cloneFrom)) {
  477. assertFalse(dst.getObjectDatabase().has(A_txt));
  478. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  479. assertTrue(dst.getObjectDatabase().has(A_txt));
  480. assertEquals(B, dst.exactRef(master).getObjectId());
  481. fsck(dst, B);
  482. }
  483. List<AccessEvent> requests = getRequests();
  484. assertEquals(2 + nofRedirects, requests.size());
  485. int n = 0;
  486. while (n < nofRedirects) {
  487. AccessEvent redirect = requests.get(n++);
  488. assertEquals(code, redirect.getStatus());
  489. }
  490. AccessEvent info = requests.get(n++);
  491. assertEquals("GET", info.getMethod());
  492. assertEquals(join(remoteURI, "info/refs"), info.getPath());
  493. assertEquals(1, info.getParameters().size());
  494. assertEquals("git-upload-pack", info.getParameter("service"));
  495. assertEquals(200, info.getStatus());
  496. assertEquals("application/x-git-upload-pack-advertisement",
  497. info.getResponseHeader(HDR_CONTENT_TYPE));
  498. assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));
  499. AccessEvent service = requests.get(n++);
  500. assertEquals("POST", service.getMethod());
  501. assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
  502. assertEquals(0, service.getParameters().size());
  503. assertNotNull("has content-length",
  504. service.getRequestHeader(HDR_CONTENT_LENGTH));
  505. assertNull("not chunked",
  506. service.getRequestHeader(HDR_TRANSFER_ENCODING));
  507. assertEquals(200, service.getStatus());
  508. assertEquals("application/x-git-upload-pack-result",
  509. service.getResponseHeader(HDR_CONTENT_TYPE));
  510. }
  511. @Test
  512. public void testInitialClone_Redirect301Small() throws Exception {
  513. initialClone_Redirect(1, 301);
  514. }
  515. @Test
  516. public void testInitialClone_Redirect301Local() throws Exception {
  517. initialClone_Redirect(1, 301, true);
  518. }
  519. @Test
  520. public void testInitialClone_Redirect302Small() throws Exception {
  521. initialClone_Redirect(1, 302);
  522. }
  523. @Test
  524. public void testInitialClone_Redirect303Small() throws Exception {
  525. initialClone_Redirect(1, 303);
  526. }
  527. @Test
  528. public void testInitialClone_Redirect307Small() throws Exception {
  529. initialClone_Redirect(1, 307);
  530. }
  531. @Test
  532. public void testInitialClone_RedirectMultiple() throws Exception {
  533. initialClone_Redirect(4, 302);
  534. }
  535. @Test
  536. public void testInitialClone_RedirectMax() throws Exception {
  537. StoredConfig userConfig = SystemReader.getInstance()
  538. .getUserConfig();
  539. userConfig.setInt("http", null, "maxRedirects", 4);
  540. userConfig.save();
  541. initialClone_Redirect(4, 302);
  542. }
  543. @Test
  544. public void testInitialClone_RedirectTooOften() throws Exception {
  545. StoredConfig userConfig = SystemReader.getInstance()
  546. .getUserConfig();
  547. userConfig.setInt("http", null, "maxRedirects", 3);
  548. userConfig.save();
  549. URIish cloneFrom = extendPath(redirectURI, "/response/4/302");
  550. String remoteUri = cloneFrom.toString();
  551. try (Repository dst = createBareRepository();
  552. Transport t = Transport.open(dst, cloneFrom)) {
  553. assertFalse(dst.getObjectDatabase().has(A_txt));
  554. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  555. fail("Should have failed (too many redirects)");
  556. } catch (TransportException e) {
  557. String expectedMessageBegin = remoteUri.toString() + ": "
  558. + MessageFormat.format(JGitText.get().redirectLimitExceeded,
  559. "3", remoteUri.replace("/4/", "/1/") + '/', "");
  560. String message = e.getMessage();
  561. if (message.length() > expectedMessageBegin.length()) {
  562. message = message.substring(0, expectedMessageBegin.length());
  563. }
  564. assertEquals(expectedMessageBegin, message);
  565. }
  566. }
  567. @Test
  568. public void testInitialClone_RedirectLoop() throws Exception {
  569. URIish cloneFrom = extendPath(redirectURI, "/loop");
  570. try (Repository dst = createBareRepository();
  571. Transport t = Transport.open(dst, cloneFrom)) {
  572. assertFalse(dst.getObjectDatabase().has(A_txt));
  573. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  574. fail("Should have failed (redirect loop)");
  575. } catch (TransportException e) {
  576. assertTrue(e.getMessage().contains("Redirected more than"));
  577. }
  578. }
  579. @Test
  580. public void testInitialClone_RedirectOnPostAllowed() throws Exception {
  581. StoredConfig userConfig = SystemReader.getInstance()
  582. .getUserConfig();
  583. userConfig.setString("http", null, "followRedirects", "true");
  584. userConfig.save();
  585. URIish cloneFrom = extendPath(remoteURI, "/post");
  586. try (Repository dst = createBareRepository();
  587. Transport t = Transport.open(dst, cloneFrom)) {
  588. assertFalse(dst.getObjectDatabase().has(A_txt));
  589. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  590. assertTrue(dst.getObjectDatabase().has(A_txt));
  591. assertEquals(B, dst.exactRef(master).getObjectId());
  592. fsck(dst, B);
  593. }
  594. List<AccessEvent> requests = getRequests();
  595. assertEquals(3, requests.size());
  596. AccessEvent info = requests.get(0);
  597. assertEquals("GET", info.getMethod());
  598. assertEquals(join(cloneFrom, "info/refs"), info.getPath());
  599. assertEquals(1, info.getParameters().size());
  600. assertEquals("git-upload-pack", info.getParameter("service"));
  601. assertEquals(200, info.getStatus());
  602. assertEquals("application/x-git-upload-pack-advertisement",
  603. info.getResponseHeader(HDR_CONTENT_TYPE));
  604. assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));
  605. AccessEvent redirect = requests.get(1);
  606. assertEquals("POST", redirect.getMethod());
  607. assertEquals(301, redirect.getStatus());
  608. AccessEvent service = requests.get(2);
  609. assertEquals("POST", service.getMethod());
  610. assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
  611. assertEquals(0, service.getParameters().size());
  612. assertNotNull("has content-length",
  613. service.getRequestHeader(HDR_CONTENT_LENGTH));
  614. assertNull("not chunked",
  615. service.getRequestHeader(HDR_TRANSFER_ENCODING));
  616. assertEquals(200, service.getStatus());
  617. assertEquals("application/x-git-upload-pack-result",
  618. service.getResponseHeader(HDR_CONTENT_TYPE));
  619. }
  620. @Test
  621. public void testInitialClone_RedirectOnPostForbidden() throws Exception {
  622. URIish cloneFrom = extendPath(remoteURI, "/post");
  623. try (Repository dst = createBareRepository();
  624. Transport t = Transport.open(dst, cloneFrom)) {
  625. assertFalse(dst.getObjectDatabase().has(A_txt));
  626. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  627. fail("Should have failed (redirect on POST)");
  628. } catch (TransportException e) {
  629. assertTrue(e.getMessage().contains("301"));
  630. }
  631. }
  632. @Test
  633. public void testInitialClone_RedirectForbidden() throws Exception {
  634. StoredConfig userConfig = SystemReader.getInstance()
  635. .getUserConfig();
  636. userConfig.setString("http", null, "followRedirects", "false");
  637. userConfig.save();
  638. try (Repository dst = createBareRepository();
  639. Transport t = Transport.open(dst, redirectURI)) {
  640. assertFalse(dst.getObjectDatabase().has(A_txt));
  641. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  642. fail("Should have failed (redirects forbidden)");
  643. } catch (TransportException e) {
  644. assertTrue(
  645. e.getMessage().contains("http.followRedirects is false"));
  646. }
  647. }
  648. @Test
  649. public void testInitialClone_WithAuthentication() throws Exception {
  650. try (Repository dst = createBareRepository();
  651. Transport t = Transport.open(dst, authURI)) {
  652. assertFalse(dst.getObjectDatabase().has(A_txt));
  653. t.setCredentialsProvider(testCredentials);
  654. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  655. assertTrue(dst.getObjectDatabase().has(A_txt));
  656. assertEquals(B, dst.exactRef(master).getObjectId());
  657. fsck(dst, B);
  658. }
  659. List<AccessEvent> requests = getRequests();
  660. assertEquals(3, requests.size());
  661. AccessEvent info = requests.get(0);
  662. assertEquals("GET", info.getMethod());
  663. assertEquals(401, info.getStatus());
  664. info = requests.get(1);
  665. assertEquals("GET", info.getMethod());
  666. assertEquals(join(authURI, "info/refs"), info.getPath());
  667. assertEquals(1, info.getParameters().size());
  668. assertEquals("git-upload-pack", info.getParameter("service"));
  669. assertEquals(200, info.getStatus());
  670. assertEquals("application/x-git-upload-pack-advertisement",
  671. info.getResponseHeader(HDR_CONTENT_TYPE));
  672. assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));
  673. AccessEvent service = requests.get(2);
  674. assertEquals("POST", service.getMethod());
  675. assertEquals(join(authURI, "git-upload-pack"), service.getPath());
  676. assertEquals(0, service.getParameters().size());
  677. assertNotNull("has content-length",
  678. service.getRequestHeader(HDR_CONTENT_LENGTH));
  679. assertNull("not chunked",
  680. service.getRequestHeader(HDR_TRANSFER_ENCODING));
  681. assertEquals(200, service.getStatus());
  682. assertEquals("application/x-git-upload-pack-result",
  683. service.getResponseHeader(HDR_CONTENT_TYPE));
  684. }
  685. @Test
  686. public void testInitialClone_WithAuthenticationNoCredentials()
  687. throws Exception {
  688. try (Repository dst = createBareRepository();
  689. Transport t = Transport.open(dst, authURI)) {
  690. assertFalse(dst.getObjectDatabase().has(A_txt));
  691. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  692. fail("Should not have succeeded -- no authentication");
  693. } catch (TransportException e) {
  694. String msg = e.getMessage();
  695. assertTrue("Unexpected exception message: " + msg,
  696. msg.contains("no CredentialsProvider"));
  697. }
  698. List<AccessEvent> requests = getRequests();
  699. assertEquals(1, requests.size());
  700. AccessEvent info = requests.get(0);
  701. assertEquals("GET", info.getMethod());
  702. assertEquals(401, info.getStatus());
  703. }
  704. @Test
  705. public void testInitialClone_WithAuthenticationWrongCredentials()
  706. throws Exception {
  707. try (Repository dst = createBareRepository();
  708. Transport t = Transport.open(dst, authURI)) {
  709. assertFalse(dst.getObjectDatabase().has(A_txt));
  710. t.setCredentialsProvider(new UsernamePasswordCredentialsProvider(
  711. AppServer.username, "wrongpassword"));
  712. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  713. fail("Should not have succeeded -- wrong password");
  714. } catch (TransportException e) {
  715. String msg = e.getMessage();
  716. assertTrue("Unexpected exception message: " + msg,
  717. msg.contains("auth"));
  718. }
  719. List<AccessEvent> requests = getRequests();
  720. // Once without authentication plus three re-tries with authentication
  721. assertEquals(4, requests.size());
  722. for (AccessEvent event : requests) {
  723. assertEquals("GET", event.getMethod());
  724. assertEquals(401, event.getStatus());
  725. }
  726. }
  727. @Test
  728. public void testInitialClone_WithAuthenticationAfterRedirect()
  729. throws Exception {
  730. URIish cloneFrom = extendPath(redirectURI, "/target/auth");
  731. CredentialsProvider uriSpecificCredentialsProvider = new UsernamePasswordCredentialsProvider(
  732. "unknown", "none") {
  733. @Override
  734. public boolean get(URIish uri, CredentialItem... items)
  735. throws UnsupportedCredentialItem {
  736. // Only return the true credentials if the uri path starts with
  737. // /auth. This ensures that we do provide the correct
  738. // credentials only for the URi after the redirect, making the
  739. // test fail if we should be asked for the credentials for the
  740. // original URI.
  741. if (uri.getPath().startsWith("/auth")) {
  742. return testCredentials.get(uri, items);
  743. }
  744. return super.get(uri, items);
  745. }
  746. };
  747. try (Repository dst = createBareRepository();
  748. Transport t = Transport.open(dst, cloneFrom)) {
  749. assertFalse(dst.getObjectDatabase().has(A_txt));
  750. t.setCredentialsProvider(uriSpecificCredentialsProvider);
  751. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  752. assertTrue(dst.getObjectDatabase().has(A_txt));
  753. assertEquals(B, dst.exactRef(master).getObjectId());
  754. fsck(dst, B);
  755. }
  756. List<AccessEvent> requests = getRequests();
  757. assertEquals(4, requests.size());
  758. AccessEvent redirect = requests.get(0);
  759. assertEquals("GET", redirect.getMethod());
  760. assertEquals(join(cloneFrom, "info/refs"), redirect.getPath());
  761. assertEquals(301, redirect.getStatus());
  762. AccessEvent info = requests.get(1);
  763. assertEquals("GET", info.getMethod());
  764. assertEquals(join(authURI, "info/refs"), info.getPath());
  765. assertEquals(401, info.getStatus());
  766. info = requests.get(2);
  767. assertEquals("GET", info.getMethod());
  768. assertEquals(join(authURI, "info/refs"), info.getPath());
  769. assertEquals(1, info.getParameters().size());
  770. assertEquals("git-upload-pack", info.getParameter("service"));
  771. assertEquals(200, info.getStatus());
  772. assertEquals("application/x-git-upload-pack-advertisement",
  773. info.getResponseHeader(HDR_CONTENT_TYPE));
  774. assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));
  775. AccessEvent service = requests.get(3);
  776. assertEquals("POST", service.getMethod());
  777. assertEquals(join(authURI, "git-upload-pack"), service.getPath());
  778. assertEquals(0, service.getParameters().size());
  779. assertNotNull("has content-length",
  780. service.getRequestHeader(HDR_CONTENT_LENGTH));
  781. assertNull("not chunked",
  782. service.getRequestHeader(HDR_TRANSFER_ENCODING));
  783. assertEquals(200, service.getStatus());
  784. assertEquals("application/x-git-upload-pack-result",
  785. service.getResponseHeader(HDR_CONTENT_TYPE));
  786. }
  787. @Test
  788. public void testInitialClone_WithAuthenticationOnPostOnly()
  789. throws Exception {
  790. try (Repository dst = createBareRepository();
  791. Transport t = Transport.open(dst, authOnPostURI)) {
  792. assertFalse(dst.getObjectDatabase().has(A_txt));
  793. t.setCredentialsProvider(testCredentials);
  794. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  795. assertTrue(dst.getObjectDatabase().has(A_txt));
  796. assertEquals(B, dst.exactRef(master).getObjectId());
  797. fsck(dst, B);
  798. }
  799. List<AccessEvent> requests = getRequests();
  800. assertEquals(3, requests.size());
  801. AccessEvent info = requests.get(0);
  802. assertEquals("GET", info.getMethod());
  803. assertEquals(join(authOnPostURI, "info/refs"), info.getPath());
  804. assertEquals(1, info.getParameters().size());
  805. assertEquals("git-upload-pack", info.getParameter("service"));
  806. assertEquals(200, info.getStatus());
  807. assertEquals("application/x-git-upload-pack-advertisement",
  808. info.getResponseHeader(HDR_CONTENT_TYPE));
  809. assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING));
  810. AccessEvent service = requests.get(1);
  811. assertEquals("POST", service.getMethod());
  812. assertEquals(join(authOnPostURI, "git-upload-pack"), service.getPath());
  813. assertEquals(401, service.getStatus());
  814. service = requests.get(2);
  815. assertEquals("POST", service.getMethod());
  816. assertEquals(join(authOnPostURI, "git-upload-pack"), service.getPath());
  817. assertEquals(0, service.getParameters().size());
  818. assertNotNull("has content-length",
  819. service.getRequestHeader(HDR_CONTENT_LENGTH));
  820. assertNull("not chunked",
  821. service.getRequestHeader(HDR_TRANSFER_ENCODING));
  822. assertEquals(200, service.getStatus());
  823. assertEquals("application/x-git-upload-pack-result",
  824. service.getResponseHeader(HDR_CONTENT_TYPE));
  825. }
  826. @Test
  827. public void testFetch_FewLocalCommits() throws Exception {
  828. // Bootstrap by doing the clone.
  829. //
  830. TestRepository dst = createTestRepository();
  831. try (Transport t = Transport.open(dst.getRepository(), remoteURI)) {
  832. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  833. }
  834. assertEquals(B, dst.getRepository().exactRef(master).getObjectId());
  835. List<AccessEvent> cloneRequests = getRequests();
  836. // Only create a few new commits.
  837. TestRepository.BranchBuilder b = dst.branch(master);
  838. for (int i = 0; i < 4; i++)
  839. b.commit().tick(3600 /* 1 hour */).message("c" + i).create();
  840. // Create a new commit on the remote.
  841. //
  842. RevCommit Z;
  843. try (TestRepository<Repository> tr = new TestRepository<>(
  844. remoteRepository)) {
  845. b = tr.branch(master);
  846. Z = b.commit().message("Z").create();
  847. }
  848. // Now incrementally update.
  849. //
  850. try (Transport t = Transport.open(dst.getRepository(), remoteURI)) {
  851. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  852. }
  853. assertEquals(Z, dst.getRepository().exactRef(master).getObjectId());
  854. List<AccessEvent> requests = getRequests();
  855. requests.removeAll(cloneRequests);
  856. assertEquals(2, requests.size());
  857. AccessEvent info = requests.get(0);
  858. assertEquals("GET", info.getMethod());
  859. assertEquals(join(remoteURI, "info/refs"), info.getPath());
  860. assertEquals(1, info.getParameters().size());
  861. assertEquals("git-upload-pack", info.getParameter("service"));
  862. assertEquals(200, info.getStatus());
  863. assertEquals("application/x-git-upload-pack-advertisement",
  864. info.getResponseHeader(HDR_CONTENT_TYPE));
  865. // We should have needed one request to perform the fetch.
  866. //
  867. AccessEvent service = requests.get(1);
  868. assertEquals("POST", service.getMethod());
  869. assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
  870. assertEquals(0, service.getParameters().size());
  871. assertNotNull("has content-length",
  872. service.getRequestHeader(HDR_CONTENT_LENGTH));
  873. assertNull("not chunked",
  874. service.getRequestHeader(HDR_TRANSFER_ENCODING));
  875. assertEquals(200, service.getStatus());
  876. assertEquals("application/x-git-upload-pack-result",
  877. service.getResponseHeader(HDR_CONTENT_TYPE));
  878. }
  879. @Test
  880. public void testFetch_TooManyLocalCommits() throws Exception {
  881. // Bootstrap by doing the clone.
  882. //
  883. TestRepository dst = createTestRepository();
  884. try (Transport t = Transport.open(dst.getRepository(), remoteURI)) {
  885. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  886. }
  887. assertEquals(B, dst.getRepository().exactRef(master).getObjectId());
  888. List<AccessEvent> cloneRequests = getRequests();
  889. // Force enough into the local client that enumeration will
  890. // need multiple packets, but not too many to overflow and
  891. // not pick up the ACK_COMMON message.
  892. //
  893. TestRepository.BranchBuilder b = dst.branch(master);
  894. for (int i = 0; i < 32 - 1; i++)
  895. b.commit().tick(3600 /* 1 hour */).message("c" + i).create();
  896. // Create a new commit on the remote.
  897. //
  898. RevCommit Z;
  899. try (TestRepository<Repository> tr = new TestRepository<>(
  900. remoteRepository)) {
  901. b = tr.branch(master);
  902. Z = b.commit().message("Z").create();
  903. }
  904. // Now incrementally update.
  905. //
  906. try (Transport t = Transport.open(dst.getRepository(), remoteURI)) {
  907. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  908. }
  909. assertEquals(Z, dst.getRepository().exactRef(master).getObjectId());
  910. List<AccessEvent> requests = getRequests();
  911. requests.removeAll(cloneRequests);
  912. assertEquals(3, requests.size());
  913. AccessEvent info = requests.get(0);
  914. assertEquals("GET", info.getMethod());
  915. assertEquals(join(remoteURI, "info/refs"), info.getPath());
  916. assertEquals(1, info.getParameters().size());
  917. assertEquals("git-upload-pack", info.getParameter("service"));
  918. assertEquals(200, info.getStatus());
  919. assertEquals("application/x-git-upload-pack-advertisement", info
  920. .getResponseHeader(HDR_CONTENT_TYPE));
  921. // We should have needed two requests to perform the fetch
  922. // due to the high number of local unknown commits.
  923. //
  924. AccessEvent service = requests.get(1);
  925. assertEquals("POST", service.getMethod());
  926. assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
  927. assertEquals(0, service.getParameters().size());
  928. assertNotNull("has content-length", service
  929. .getRequestHeader(HDR_CONTENT_LENGTH));
  930. assertNull("not chunked", service
  931. .getRequestHeader(HDR_TRANSFER_ENCODING));
  932. assertEquals(200, service.getStatus());
  933. assertEquals("application/x-git-upload-pack-result", service
  934. .getResponseHeader(HDR_CONTENT_TYPE));
  935. service = requests.get(2);
  936. assertEquals("POST", service.getMethod());
  937. assertEquals(join(remoteURI, "git-upload-pack"), service.getPath());
  938. assertEquals(0, service.getParameters().size());
  939. assertNotNull("has content-length", service
  940. .getRequestHeader(HDR_CONTENT_LENGTH));
  941. assertNull("not chunked", service
  942. .getRequestHeader(HDR_TRANSFER_ENCODING));
  943. assertEquals(200, service.getStatus());
  944. assertEquals("application/x-git-upload-pack-result", service
  945. .getResponseHeader(HDR_CONTENT_TYPE));
  946. }
  947. @Test
  948. public void testInitialClone_BrokenServer() throws Exception {
  949. try (Repository dst = createBareRepository();
  950. Transport t = Transport.open(dst, brokenURI)) {
  951. assertFalse(dst.getObjectDatabase().has(A_txt));
  952. try {
  953. t.fetch(NullProgressMonitor.INSTANCE, mirror(master));
  954. fail("fetch completed despite upload-pack being broken");
  955. } catch (TransportException err) {
  956. String exp = brokenURI + ": expected"
  957. + " Content-Type application/x-git-upload-pack-result;"
  958. + " received Content-Type text/plain;charset=utf-8";
  959. assertEquals(exp, err.getMessage());
  960. }
  961. }
  962. List<AccessEvent> requests = getRequests();
  963. assertEquals(2, requests.size());
  964. AccessEvent info = requests.get(0);
  965. assertEquals("GET", info.getMethod());
  966. assertEquals(join(brokenURI, "info/refs"), info.getPath());
  967. assertEquals(1, info.getParameters().size());
  968. assertEquals("git-upload-pack", info.getParameter("service"));
  969. assertEquals(200, info.getStatus());
  970. assertEquals("application/x-git-upload-pack-advertisement", info
  971. .getResponseHeader(HDR_CONTENT_TYPE));
  972. AccessEvent service = requests.get(1);
  973. assertEquals("POST", service.getMethod());
  974. assertEquals(join(brokenURI, "git-upload-pack"), service.getPath());
  975. assertEquals(0, service.getParameters().size());
  976. assertEquals(200, service.getStatus());
  977. assertEquals("text/plain;charset=utf-8",
  978. service.getResponseHeader(HDR_CONTENT_TYPE));
  979. }
  980. @Test
  981. public void testInvalidWant() throws Exception {
  982. ObjectId id;
  983. try (ObjectInserter.Formatter formatter = new ObjectInserter.Formatter()) {
  984. id = formatter.idFor(Constants.OBJ_BLOB,
  985. "testInvalidWant".getBytes(UTF_8));
  986. }
  987. try (Repository dst = createBareRepository();
  988. Transport t = Transport.open(dst, remoteURI);
  989. FetchConnection c = t.openFetch()) {
  990. Ref want = new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, id.name(),
  991. id);
  992. c.fetch(NullProgressMonitor.INSTANCE, Collections.singleton(want),
  993. Collections.<ObjectId> emptySet());
  994. fail("Server accepted want " + id.name());
  995. } catch (TransportException err) {
  996. assertEquals("want " + id.name() + " not valid", err.getMessage());
  997. }
  998. }
  999. @Test
  1000. public void testFetch_RefsUnreadableOnUpload() throws Exception {
  1001. AppServer noRefServer = new AppServer();
  1002. try {
  1003. final String repoName = "refs-unreadable";
  1004. RefsUnreadableInMemoryRepository badRefsRepo = new RefsUnreadableInMemoryRepository(
  1005. new DfsRepositoryDescription(repoName));
  1006. final TestRepository<Repository> repo = new TestRepository<>(
  1007. badRefsRepo);
  1008. ServletContextHandler app = noRefServer.addContext("/git");
  1009. GitServlet gs = new GitServlet();
  1010. gs.setRepositoryResolver(new TestRepositoryResolver(repo, repoName));
  1011. app.addServlet(new ServletHolder(gs), "/*");
  1012. noRefServer.setUp();
  1013. RevBlob A2_txt = repo.blob("A2");
  1014. RevCommit A2 = repo.commit().add("A2_txt", A2_txt).create();
  1015. RevCommit B2 = repo.commit().parent(A2).add("A2_txt", "C2")
  1016. .add("B2", "B2").create();
  1017. repo.update(master, B2);
  1018. URIish badRefsURI = new URIish(noRefServer.getURI()
  1019. .resolve(app.getContextPath() + "/" + repoName).toString());
  1020. try (Repository dst = createBareRepository();
  1021. Transport t = Transport.open(dst, badRefsURI);
  1022. FetchConnection c = t.openFetch()) {
  1023. // We start failing here to exercise the post-advertisement
  1024. // upload pack handler.
  1025. badRefsRepo.startFailing();
  1026. // Need to flush caches because ref advertisement populated them.
  1027. badRefsRepo.getRefDatabase().refresh();
  1028. c.fetch(NullProgressMonitor.INSTANCE,
  1029. Collections.singleton(c.getRef(master)),
  1030. Collections.<ObjectId> emptySet());
  1031. fail("Successfully served ref with value " + c.getRef(master));
  1032. } catch (TransportException err) {
  1033. assertEquals("Internal server error", err.getMessage());
  1034. }
  1035. } finally {
  1036. noRefServer.tearDown();
  1037. }
  1038. }
  1039. @Test
  1040. public void testPush_NotAuthorized() throws Exception {
  1041. final TestRepository src = createTestRepository();
  1042. final RevBlob Q_txt = src.blob("new text");
  1043. final RevCommit Q = src.commit().add("Q", Q_txt).create();
  1044. final Repository db = src.getRepository();
  1045. final String dstName = Constants.R_HEADS + "new.branch";
  1046. // push anonymous shouldn't be allowed.
  1047. //
  1048. try (Transport t = Transport.open(db, remoteURI)) {
  1049. final String srcExpr = Q.name();
  1050. final boolean forceUpdate = false;
  1051. final String localName = null;
  1052. final ObjectId oldId = null;
  1053. RemoteRefUpdate u = new RemoteRefUpdate(src.getRepository(),
  1054. srcExpr, dstName, forceUpdate, localName, oldId);
  1055. try {
  1056. t.push(NullProgressMonitor.INSTANCE, Collections.singleton(u));
  1057. fail("anonymous push incorrectly accepted without error");
  1058. } catch (TransportException e) {
  1059. final String exp = remoteURI + ": "
  1060. + JGitText.get().authenticationNotSupported;
  1061. assertEquals(exp, e.getMessage());
  1062. }
  1063. }
  1064. List<AccessEvent> requests = getRequests();
  1065. assertEquals(1, requests.size());
  1066. AccessEvent info = requests.get(0);
  1067. assertEquals("GET", info.getMethod());
  1068. assertEquals(join(remoteURI, "info/refs"), info.getPath());
  1069. assertEquals(1, info.getParameters().size());
  1070. assertEquals("git-receive-pack", info.getParameter("service"));
  1071. assertEquals(401, info.getStatus());
  1072. }
  1073. @Test
  1074. public void testPush_CreateBranch() throws Exception {
  1075. final TestRepository src = createTestRepository();
  1076. final RevBlob Q_txt = src.blob("new text");
  1077. final RevCommit Q = src.commit().add("Q", Q_txt).create();
  1078. final Repository db = src.getRepository();
  1079. final String dstName = Constants.R_HEADS + "new.branch";
  1080. enableReceivePack();
  1081. try (Transport t = Transport.open(db, remoteURI)) {
  1082. final String srcExpr = Q.name();
  1083. final boolean forceUpdate = false;
  1084. final String localName = null;
  1085. final ObjectId oldId = null;
  1086. RemoteRefUpdate u = new RemoteRefUpdate(src.getRepository(),
  1087. srcExpr, dstName, forceUpdate, localName, oldId);
  1088. t.push(NullProgressMonitor.INSTANCE, Collections.singleton(u));
  1089. }
  1090. assertTrue(remoteRepository.getObjectDatabase().has(Q_txt));
  1091. assertNotNull("has " + dstName, remoteRepository.exactRef(dstName));
  1092. assertEquals(Q, remoteRepository.exactRef(dstName).getObjectId());
  1093. fsck(remoteRepository, Q);
  1094. final ReflogReader log = remoteRepository.getReflogReader(dstName);
  1095. assertNotNull("has log for " + dstName, log);
  1096. final ReflogEntry last = log.getLastEntry();
  1097. assertNotNull("has last entry", last);
  1098. assertEquals(ObjectId.zeroId(), last.getOldId());
  1099. assertEquals(Q, last.getNewId());
  1100. assertEquals("anonymous", last.getWho().getName());
  1101. // Assumption: The host name we use to contact the server should
  1102. // be the server's own host name, because it should be the loopback
  1103. // network interface.
  1104. //
  1105. final String clientHost = remoteURI.getHost();
  1106. assertEquals("anonymous@" + clientHost, last.getWho().getEmailAddress());
  1107. assertEquals("push: created", last.getComment());
  1108. List<AccessEvent> requests = getRequests();
  1109. assertEquals(2, requests.size());
  1110. AccessEvent info = requests.get(0);
  1111. assertEquals("GET", info.getMethod());
  1112. assertEquals(join(remoteURI, "info/refs"), info.getPath());
  1113. assertEquals(1, info.getParameters().size());
  1114. assertEquals("git-receive-pack", info.getParameter("service"));
  1115. assertEquals(200, info.getStatus());
  1116. assertEquals("application/x-git-receive-pack-advertisement", info
  1117. .getResponseHeader(HDR_CONTENT_TYPE));
  1118. AccessEvent service = requests.get(1);
  1119. assertEquals("POST", service.getMethod());
  1120. assertEquals(join(remoteURI, "git-receive-pack"), service.getPath());
  1121. assertEquals(0, service.getParameters().size());
  1122. assertNotNull("has content-length", service
  1123. .getRequestHeader(HDR_CONTENT_LENGTH));
  1124. assertNull("not chunked", service
  1125. .getRequestHeader(HDR_TRANSFER_ENCODING));
  1126. assertEquals(200, service.getStatus());
  1127. assertEquals("application/x-git-receive-pack-result", service
  1128. .getResponseHeader(HDR_CONTENT_TYPE));
  1129. }
  1130. @Test
  1131. public void testPush_ChunkedEncoding() throws Exception {
  1132. final TestRepository<Repository> src = createTestRepository();
  1133. final RevBlob Q_bin = src.blob(new TestRng("Q").nextBytes(128 * 1024));
  1134. final RevCommit Q = src.commit().add("Q", Q_bin).create();
  1135. final Repository db = src.getRepository();
  1136. final String dstName = Constants.R_HEADS + "new.branch";
  1137. enableReceivePack();
  1138. final StoredConfig cfg = db.getConfig();
  1139. cfg.setInt("core", null, "compression", 0);
  1140. cfg.setInt("http", null, "postbuffer", 8 * 1024);
  1141. cfg.save();
  1142. try (Transport t = Transport.open(db, remoteURI)) {
  1143. final String srcExpr = Q.name();
  1144. final boolean forceUpdate = false;
  1145. final String localName = null;
  1146. final ObjectId oldId = null;
  1147. RemoteRefUpdate u = new RemoteRefUpdate(src.getRepository(),
  1148. srcExpr, dstName, forceUpdate, localName, oldId);
  1149. t.push(NullProgressMonitor.INSTANCE, Collections.singleton(u));
  1150. }
  1151. assertTrue(remoteRepository.getObjectDatabase().has(Q_bin));
  1152. assertNotNull("has " + dstName, remoteRepository.exactRef(dstName));
  1153. assertEquals(Q, remoteRepository.exactRef(dstName).getObjectId());
  1154. fsck(remoteRepository, Q);
  1155. List<AccessEvent> requests = getRequests();
  1156. assertEquals(2, requests.size());
  1157. AccessEvent info = requests.get(0);
  1158. assertEquals("GET", info.getMethod());
  1159. assertEquals(join(remoteURI, "info/refs"), info.getPath());
  1160. assertEquals(1, info.getParameters().size());
  1161. assertEquals("git-receive-pack", info.getParameter("service"));
  1162. assertEquals(200, info.getStatus());
  1163. assertEquals("application/x-git-receive-pack-advertisement", info
  1164. .getResponseHeader(HDR_CONTENT_TYPE));
  1165. AccessEvent service = requests.get(1);
  1166. assertEquals("POST", service.getMethod());
  1167. assertEquals(join(remoteURI, "git-receive-pack"), service.getPath());
  1168. assertEquals(0, service.getParameters().size());
  1169. assertNull("no content-length", service
  1170. .getRequestHeader(HDR_CONTENT_LENGTH));
  1171. assertEquals("chunked", service.getRequestHeader(HDR_TRANSFER_ENCODING));
  1172. assertEquals(200, service.getStatus());
  1173. assertEquals("application/x-git-receive-pack-result", service
  1174. .getResponseHeader(HDR_CONTENT_TYPE));
  1175. }
  1176. private void enableReceivePack() throws IOException {
  1177. final StoredConfig cfg = remoteRepository.getConfig();
  1178. cfg.setBoolean("http", null, "receivepack", true);
  1179. cfg.save();
  1180. }
  1181. }