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