【问题标题】:Apache reverse-proxy transforms POST requests into GET requestsApache 反向代理将 POST 请求转换为 GET 请求
【发布时间】:2016-02-01 14:39:13
【问题描述】:

我正在尝试使用 SonarQube 分析来自 Jenkins 作业的代码,但当请求收到 405 错误时,我的作业失败。 Apache 基本上是把 POST 请求变成 GET 请求,导致作业失败。

这是我的 apache vhost 配置:

 <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 在另一台机器上。

任何想法为什么会发生这种情况,或者如何解决它?

【问题讨论】:

    标签: apache jenkins sonarqube reverse-proxy


    【解决方案1】:

    如果您想在 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>
    

    希望这会有所帮助。

    【讨论】:

    • 我遇到了同样的问题,除了我有一个 NGINX 规则而不是 apache。知道如何在 NGINX 上做到这一点吗?我的代码如下:server { listen 80; server_name sonar.company.com; return 301 https://$server_name$request_uri; if ($scheme = http) { return 301 https://$server_name$request_uri; } }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    • 2012-01-01
    • 1970-01-01
    • 2017-02-27
    相关资源
    最近更新 更多