Apache 反向代理将 POST 请求转换为 GET 请求
Apache reverse-proxy transforms POST requests into GET requests
我正在尝试使用 SonarQube 分析来自 Jenkins 作业的代码,但当请求出现 405 错误时,我的作业失败了。 Apache 基本上是将 POST 请求更改为 GET 请求,从而导致作业失败。
这是我的 apache 虚拟主机配置:
<VirtualHost *:80>
ServerName public.dev
Redirect permanent / https://public.dev/
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/wildcard_cnp_dev.pem
SSLCertificateKeyFile /etc/httpd/ssl/wildcard_cnp_dev.key
ServerName public.dev
ProxyPass / http://localhost:9000/
ProxyPassReverse / http://localhost:9000/
ProxyRequests Off
ProxyPreserveHost on
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ErrorLog /var/log/httpd/sonar-https-error.log
LogLevel warn
CustomLog /var/log/httpd/sonar-https-access.log combined
</VirtualHost>
当作业失败时,我得到这个控制台输出:
INFO: ------------------------------------------------------------------------
INFO: EXECUTION FAILURE
INFO: ------------------------------------------------------------------------
INFO: Total time: 18.627s
INFO: Final Memory: 46M/112M
INFO: ------------------------------------------------------------------------
ERROR: Error during SonarQube Scanner execution
org.sonarqube.ws.client.HttpException: Error 405 on https://public.dev/api/ce/submit?projectKey=java-sonar-runner-simple&projectName=Simple%20Java%20project%20analyzed%20with%20the%20SonarQube%20Runner
at org.sonarqube.ws.client.BaseResponse.failIfNotSuccessful(BaseResponse.java:32)
at org.sonar.batch.bootstrap.BatchWsClient.failIfUnauthorized(BatchWsClient.java:96)
at org.sonar.batch.bootstrap.BatchWsClient.call(BatchWsClient.java:67)
at org.sonar.batch.report.ReportPublisher.upload(ReportPublisher.java:157)
at org.sonar.batch.report.ReportPublisher.execute(ReportPublisher.java:116)
at org.sonar.batch.phases.PhaseExecutor.publishReportJob(PhaseExecutor.java:116)
at org.sonar.batch.phases.PhaseExecutor.execute(PhaseExecutor.java:106)
at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:185)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:132)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:117)
at org.sonar.batch.scan.ProjectScanContainer.scan(ProjectScanContainer.java:243)
at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:238)
at org.sonar.batch.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:228)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:132)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:117)
at org.sonar.batch.task.ScanTask.execute(ScanTask.java:55)
at org.sonar.batch.task.TaskContainer.doAfterStart(TaskContainer.java:86)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:132)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:117)
at org.sonar.batch.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:122)
at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:119)
at org.sonar.runner.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.sonar.runner.impl.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:61)
at com.sun.proxy.$Proxy0.execute(Unknown Source)
at org.sonar.runner.api.EmbeddedRunner.doExecute(EmbeddedRunner.java:274)
at org.sonar.runner.api.EmbeddedRunner.runAnalysis(EmbeddedRunner.java:165)
at org.sonar.runner.api.EmbeddedRunner.runAnalysis(EmbeddedRunner.java:152)
at org.sonarsource.scanner.cli.Main.runAnalysis(Main.java:118)
at org.sonarsource.scanner.cli.Main.execute(Main.java:80)
at org.sonarsource.scanner.cli.Main.main(Main.java:66)
ERROR:
ERROR: Re-run SonarQube Scanner using the -X switch to enable full debug logging.
Build step 'Invoke Standalone SonarQube Analysis' marked build as failure
Finished: FAILURE
405 错误是因为 SonarQube 正在接收 GET 请求而不是 POST 请求(正常行为)。我可以在 Apache 和 Sonar 访问日志中看到它:
APACHE
192.168.100.7 - - [01/Feb/2016:09:03:06 -0500] "GET /api/ce/submit?projectKey=java-sonar-runner-simple&projectName=Simple%20Java%20project%20analyzed%20with%20the%20SonarQube%20Runner HTTP/1.1" 405 51 "-" "SonarQubeRunner/2.5.1"
SONAR
127.0.0.1 - - [01/Feb/2016:09:14:08 -0500] "GET /api/ce/submit?projectKey=java-sonar-runner-simple&projectName=Simple%20Java%20project%20analyzed%20with%20the%20SonarQube%20Runner HTTP/1.1" 405 51 "-" "SonarQubeRunner/2.5.1"
这在我不使用 Apache 作为反向代理时有效。 Jenkins 在一台机器上,Apache 和 SonarQube 在另一台机器上。
知道为什么会发生这种情况,或者如何解决它?
如果你想在 Sonar 前面放置一个 Apache 反向代理,然后从 Jenkins 访问它,那么你应该在 URL 中添加一个上下文。在声纳服务器上,编辑您的 sonar.properties 文件并编辑以下 属性 以添加上下文。上下文可以是任何东西...这是我的:
sonar.web.context=/quality
然后在 Apache 中编辑您的代理设置。这是我的:
ProxyPass /quality http://another-machine:9000/quality keepalive=on
<Location /quality>
ProxyPassReverse http://another-machine:9000/quality
</Location>
希望对您有所帮助。
我正在尝试使用 SonarQube 分析来自 Jenkins 作业的代码,但当请求出现 405 错误时,我的作业失败了。 Apache 基本上是将 POST 请求更改为 GET 请求,从而导致作业失败。
这是我的 apache 虚拟主机配置:
<VirtualHost *:80>
ServerName public.dev
Redirect permanent / https://public.dev/
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/wildcard_cnp_dev.pem
SSLCertificateKeyFile /etc/httpd/ssl/wildcard_cnp_dev.key
ServerName public.dev
ProxyPass / http://localhost:9000/
ProxyPassReverse / http://localhost:9000/
ProxyRequests Off
ProxyPreserveHost on
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ErrorLog /var/log/httpd/sonar-https-error.log
LogLevel warn
CustomLog /var/log/httpd/sonar-https-access.log combined
</VirtualHost>
当作业失败时,我得到这个控制台输出:
INFO: ------------------------------------------------------------------------
INFO: EXECUTION FAILURE
INFO: ------------------------------------------------------------------------
INFO: Total time: 18.627s
INFO: Final Memory: 46M/112M
INFO: ------------------------------------------------------------------------
ERROR: Error during SonarQube Scanner execution
org.sonarqube.ws.client.HttpException: Error 405 on https://public.dev/api/ce/submit?projectKey=java-sonar-runner-simple&projectName=Simple%20Java%20project%20analyzed%20with%20the%20SonarQube%20Runner
at org.sonarqube.ws.client.BaseResponse.failIfNotSuccessful(BaseResponse.java:32)
at org.sonar.batch.bootstrap.BatchWsClient.failIfUnauthorized(BatchWsClient.java:96)
at org.sonar.batch.bootstrap.BatchWsClient.call(BatchWsClient.java:67)
at org.sonar.batch.report.ReportPublisher.upload(ReportPublisher.java:157)
at org.sonar.batch.report.ReportPublisher.execute(ReportPublisher.java:116)
at org.sonar.batch.phases.PhaseExecutor.publishReportJob(PhaseExecutor.java:116)
at org.sonar.batch.phases.PhaseExecutor.execute(PhaseExecutor.java:106)
at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:185)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:132)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:117)
at org.sonar.batch.scan.ProjectScanContainer.scan(ProjectScanContainer.java:243)
at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:238)
at org.sonar.batch.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:228)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:132)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:117)
at org.sonar.batch.task.ScanTask.execute(ScanTask.java:55)
at org.sonar.batch.task.TaskContainer.doAfterStart(TaskContainer.java:86)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:132)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:117)
at org.sonar.batch.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:122)
at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:119)
at org.sonar.runner.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.sonar.runner.impl.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:61)
at com.sun.proxy.$Proxy0.execute(Unknown Source)
at org.sonar.runner.api.EmbeddedRunner.doExecute(EmbeddedRunner.java:274)
at org.sonar.runner.api.EmbeddedRunner.runAnalysis(EmbeddedRunner.java:165)
at org.sonar.runner.api.EmbeddedRunner.runAnalysis(EmbeddedRunner.java:152)
at org.sonarsource.scanner.cli.Main.runAnalysis(Main.java:118)
at org.sonarsource.scanner.cli.Main.execute(Main.java:80)
at org.sonarsource.scanner.cli.Main.main(Main.java:66)
ERROR:
ERROR: Re-run SonarQube Scanner using the -X switch to enable full debug logging.
Build step 'Invoke Standalone SonarQube Analysis' marked build as failure
Finished: FAILURE
405 错误是因为 SonarQube 正在接收 GET 请求而不是 POST 请求(正常行为)。我可以在 Apache 和 Sonar 访问日志中看到它:
APACHE
192.168.100.7 - - [01/Feb/2016:09:03:06 -0500] "GET /api/ce/submit?projectKey=java-sonar-runner-simple&projectName=Simple%20Java%20project%20analyzed%20with%20the%20SonarQube%20Runner HTTP/1.1" 405 51 "-" "SonarQubeRunner/2.5.1"
SONAR
127.0.0.1 - - [01/Feb/2016:09:14:08 -0500] "GET /api/ce/submit?projectKey=java-sonar-runner-simple&projectName=Simple%20Java%20project%20analyzed%20with%20the%20SonarQube%20Runner HTTP/1.1" 405 51 "-" "SonarQubeRunner/2.5.1"
这在我不使用 Apache 作为反向代理时有效。 Jenkins 在一台机器上,Apache 和 SonarQube 在另一台机器上。
知道为什么会发生这种情况,或者如何解决它?
如果你想在 Sonar 前面放置一个 Apache 反向代理,然后从 Jenkins 访问它,那么你应该在 URL 中添加一个上下文。在声纳服务器上,编辑您的 sonar.properties 文件并编辑以下 属性 以添加上下文。上下文可以是任何东西...这是我的:
sonar.web.context=/quality
然后在 Apache 中编辑您的代理设置。这是我的:
ProxyPass /quality http://another-machine:9000/quality keepalive=on
<Location /quality>
ProxyPassReverse http://another-machine:9000/quality
</Location>
希望对您有所帮助。