Я работал над сценарием golang, который использует протокол chrome devtools для:
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) Измените тело ответа
Здесь я делаю небольшие изменения в разметке HTML в procesHtml()
(но код этой функции не имеет отношения к этой проблеме, поэтому не буду публиковать ее здесь). Я также извлекаю заголовки из запроса и при необходимостиобновите content-length
и date
, прежде чем продолжить ответ. Затем я gzip сжимаю тело при вызове r := gZipCompress([]byte(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 для всех ответов. Вышеприведенное является временным, пока я выясняю, как решить эту проблему.функция выглядит следующим образом:
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> строка> base64)?Должно ли это быть сделано в другом порядке для работы?Любая помощь будет очень полезна.
Ответ выглядит следующим образом, который Chrome помещает в тег <body></body>
����r ܸ� ��_A��Q% GH��Kʔ��vU�˷c�v�}
или в ответе:

Я также могу сказать, что этосжатие корректно, так как при удалении заголовков запрос приводит к загрузке файла .gz
со всеми правильными .html
в несжатом виде.Кроме того, первые несколько байтов в объекте, возвращенном в gZipCompress
, говорят мне, что он правильно распакован:
31 139 8
или
0x1f 0x8B 0x08