Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google chrome Chrome DevTools协议-与Golang中的gzip主体继续接收请求_Google Chrome_Go_Google Chrome Devtools_Gzip - Fatal编程技术网

Google chrome Chrome DevTools协议-与Golang中的gzip主体继续接收请求

Google chrome Chrome DevTools协议-与Golang中的gzip主体继续接收请求,google-chrome,go,google-chrome-devtools,gzip,Google Chrome,Go,Google Chrome Devtools,Gzip,我一直在编写一个golang脚本,该脚本使用 1) 拦截请求 2) 获取截获请求的响应正文 3) 对html文档进行一些修改 4) 继续拦截请求 该脚本适用于HTML文档,除非Content Encoding设置为gzip。循序渐进的过程如下所示“ 1)拦截请求 s.Debugger.CallbackEvent("Network.requestIntercepted", func(params godet.Params) { iid := params.String("intercep

我一直在编写一个golang脚本,该脚本使用

1) 拦截请求

2) 获取截获请求的响应正文

3) 对
html
文档进行一些修改

4) 继续拦截请求

该脚本适用于HTML文档,除非
Content Encoding
设置为
gzip
。循序渐进的过程如下所示“

1)拦截请求

 s.Debugger.CallbackEvent("Network.requestIntercepted", func(params godet.Params) {
    iid := params.String("interceptionId")
    rtype := params.String("resourceType")
    reason := responses[rtype]
    headers := getHeadersString(params["responseHeaders"])

    log.Println("[+] Request intercepted for", iid, rtype, params.Map("request")["url"])
    if reason != "" {
        log.Println("  abort with reason", reason)
    }

    // Alter HTML in request response
    if s.Options.AlterDocument && rtype == "Document" && iid != "" {
        res, err := s.Debugger.GetResponseBodyForInterception(iid)

        if err != nil {
            log.Println("[-] Unable to get intercepted response body!")
        }

        rawAlteredResponse, err := AlterDocument(res, headers)
        if err != nil{
            log.Println("[-] Unable to alter HTML")
        }

        if rawAlteredResponse != "" {
            log.Println("[+] Sending modified body")

            err := s.Debugger.ContinueInterceptedRequest(iid, godet.ErrorReason(reason), rawAlteredResponse, "", "", "", nil)
            if err != nil {
                fmt.Println("OH NOES AN ERROR!")
                log.Println(err)
            }
        }
    } else {
        s.Debugger.ContinueInterceptedRequest(iid, godet.ErrorReason(reason), "", "", "", "", nil)
    }
})
2)更改响应主体

在这里,我对
procesHtml()
中的HTML标记做了一些小改动(但该函数的代码与此问题无关,因此不会在这里发布)。我还从请求中获取头,并在必要时更新
内容长度
日期
,然后在继续响应之前。然后,我在调用
r:=gzip压缩正文([]字节(alteredBody)
,它返回一个字符串。然后将该字符串连接到标题,这样我就可以创建
rawResponse

func AlterDocument(debuggerResponse []byte, headers map[string]string) (string, error) {
    alteredBody, err := processHtml(debuggerResponse)
    if err != nil {
        return "", err
    }


    alteredHeader := ""
    for k, v := range headers{
        switch strings.ToLower(k) {
            case "content-length":
                v = strconv.Itoa(len(alteredBody))
                fmt.Println("Updating content-length to: " + strconv.Itoa(len(alteredBody)))
                break
            case "date":
                v = fmt.Sprintf("%s", time.Now().Format(time.RFC3339))
                break
        }
        alteredHeader += k + ": " + v + "\r\n"
    }

    r := gZipCompress([]byte(alteredBody))

    rawAlteredResponse := 
    base64.StdEncoding.EncodeToString([]byte("HTTP/1.1 200 OK" + "\r\n" + alteredHeader + "\r\n\r\n\r\n" + r))

    return rawAlteredResponse, nil
}
注意:我现在正在压缩所有响应的正文。在我找出如何解决此问题时,上述内容是暂时的

gzip compress函数如下所示:

func gZipCompress(dataToWorkWith []byte) string{
    var b bytes.Buffer

    gz, err := gzip.NewWriterLevel(&b, 5)
    if err != nil{
        panic(err)
    }
    if _, err := gz.Write(dataToWorkWith); err != nil {
        panic(err)
    }
    if err := gz.Flush(); err != nil {
        panic(err)
    }
    if err := gz.Close(); err != nil {
        panic(err)
    }
    return b.String()
}
如第一段代码所示,响应正文和标题设置如下:

err := s.Debugger.ContinueInterceptedRequest(iid, godet.ErrorReason(reason), rawAlteredResponse, "", "", "", nil)
结果是浏览器中出现一堆乱码。对于非gzip请求,这在没有gzip函数的情况下有效。我也更改了压缩级别(未成功)。我是否以错误的顺序处理正文(字符串>[]字节>gzip>字符串>base64)?是否应以不同的顺序进行此操作?如有任何帮助,将不胜感激

响应如下所示,Chrome将其放入
标记中

����rܸ� ��_A.��Q%GH��Kʔ��似曾相识�˷c�v�}

或在答复中:

我还可以看出它正在正确压缩,因为当我删除标题时,请求会导致下载一个
.gz
文件,在解压缩时会下载所有正确的
.html
。此外,在
gzip压缩中返回的对象的前几个字节告诉我它已正确压缩:

31 139 8


0x1f 0x8B 0x08

我最终使用了另一个库,它可以更好、更高效地处理更大的响应

现在,DevTools协议似乎在解压后返回响应体,但在调用
Network.GetResponseBodyForInterception
时在浏览器中呈现响应体之前返回响应体。当然,这只是一个假设,因为我在中没有看到该方法的代码。该假设基于这样一个事实:调用
Network.Get时ResponseBodyForInterception
获取的响应正文未压缩(尽管它可能是base64编码的)此外,该方法被标记为实验性的,文档中没有提及任何与压缩响应有关的内容。基于该假设,我将进一步假设,在我们从
网络获得响应时。GetResponseBodyForInterception
我们自己压缩身体已经太晚了。我确认我使用的e库不需要压缩或解压gzip响应

我可以继续使用我的代码,而无需担心gzip压缩响应,因为我可以毫无问题地修改主体


作为参考,我现在使用它,因为它在截取较大的响应时更加健壮和稳定。

在处理Gzip请求时,您不应该首先解压缩
debuggerResponse
吗?您的垃圾看起来像什么?前几个字符应该足够了。从我在您的代码中看到的情况来看,您可能已经压缩了浏览器只解压一次的未压缩内容,因此垃圾。
debuggerResponse
已解压。我应该注意到,
processHtml
只需执行
bodyString:=string(body[:]),即可将字节数组转换为字符串
,在这一点上,我创建了一个
goquery
文档,并基本上查找/替换了几个字符串。
processHtml
返回一个带有更新html的字符串。我将用响应的示例更新帖子。另外,谢谢,请注意
s.Debugger.GetResponseBodyForInterception
base64解码响应体w在该函数返回之前,它是必需的。在这里只是扮演魔鬼代言人,但鉴于Chrome限制的最新变化,生成的软件是否可用?我不100%确定这是否相关,但在Chrome的最新版本中,防病毒/恶意软件等应用程序不再能够与Chrome的内部连接,如浏览器不再允许这样做。虽然这似乎是一个实际公开的API,所以乍一看似乎还可以,但我刚刚注意到,该协议的稳定版本1.3标记为Chrome 64。只是为了确保您不会浪费时间。很抱歉,缺少资源。