如何使用 Groovy 代码在响应正文中删除 Gerrit 的 REST API 魔法前缀?

How do you remove Gerrit's REST API's magic prefix in the response body with Groovy code?

我的代码:

@Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7')
@Grab('oauth.signpost:signpost-core:1.2.1.2')
@Grab('oauth.signpost:signpost-commonshttp4:1.2.1.2')
import groovyx.net.http.RESTClient
import static groovyx.net.http.ContentType.*

def gerrit = new RESTClient('http://localhost:8080/gerrit')
gerrit.auth.basic "gerrit", "password123"
gerrit.get( path: 'changes/1234/reviewers' ) 

根据https://gerrit-review.googlesource.com/Documentation/rest-api.html#authentication

"To prevent against Cross Site Script Inclusion (XSSI) attacks, the JSON response body starts with a magic prefix line that must be stripped before feeding the rest of the response body to a JSON parser:"

  )]}'
  [ ... valid JSON ... ]

我的错误:

WARNING: Error parsing 'application/json; charset=UTF-8' response
groovy.json.JsonException: Unable to determine the current character, it is not a string, number, array, or object

The current character read is ')' with an int value of 41
Unable to determine the current character, it is not a string, number, array, or object
line number 1
index number 0
)]}'

抱歉,我对 Groovy 不是很熟悉,但是除非您想修改源代码并推出自己的版本,否则无法从 Gerrit 中删除此前缀。

解决方案是使用不同的Groovy API获取原始数据,去掉前5个字符,然后将其输入Groovy JSON 解析器。再次抱歉,但我无法帮助解决 Groovy API 可能是一个选项的问题。

如文档所述,这些字符有时很烦人,但这是 Gerrit 的一项重要安全功能,可防止任何 XSS 黑客攻击。

我找到了答案。

@Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7')
@Grab('oauth.signpost:signpost-core:1.2.1.2')
@Grab('oauth.signpost:signpost-commonshttp4:1.2.1.2')
import groovyx.net.http.RESTClient
import static groovyx.net.http.Method.*
import static groovyx.net.http.ContentType.*
import groovy.json.JsonSlurper

public class GerritRestClient {
    def gerrit

    GerritRestClient(config) {
        def username = config.username
        def password = config.password
        this.gerrit = new RESTClient(config.endpoint)
        this.gerrit.auth.basic config.username, config.password
    }

  def sendRequest(path) {
    this.gerrit.request(GET,TEXT) { req ->
      uri.path = path // overrides any path in the default URL
      response.success = { resp, json ->
        assert resp.status == 200
        def fixedJson = json.text.replaceAll('\)]}\'', '').trim() // remove magic prefix
        def jsonSlurper = new JsonSlurper()
        return jsonSlurper.parseText(fixedJson) // parse the fixed json body and return
      }
      // called only for a 404 (not found) status code:
      response.failure = { resp ->
        println "My response handler got response: ${resp.statusLine}"
        return null
      }
    }
  }

  def getChangeReviewers(changeNumber) {
    def requestPath = "changes/${changeNumber}/reviewers"
    return sendRequest(requestPath)
  }

}