Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Browsermob proxy не загружает страницу


(Vad Cheh) #1

Доброго времени суток,

проблема такая: на днях у меня появилась задача тестировать страницы на ошибки javascript, решил использовать для этого browsermob proxy, так как программистов даже под пытками не заставишь добавить в хедер пару строк лишнего (в их понимании) кода.
Но тут столкнулся с проблемой, при загрузке страницы получаю ошибку, в Mozilla :

“Ошибка в типе содержимого”,

часть стактрейс:

driver info: driver.version: “unknown at .anonymous(about:neterror?e=contentEncodingError&u=http%3A…”,

немного покопавшись, оказалось что проблема была в том, что нужно было поставить в Мозиле значение “true” для “network.http.accept-encoding”,

суть вопроса в том, что в других браузера нет возможности (по крайней мере мне их не удалось найти) поменять accept-encoding, можно ли как-то программно найти решение этой проблемы?

Пишу на java, в Еклипсе, ОС : 7;

Вот код:

public void CaptureJavaScript() throws Exception {
	JavascriptExecutor js = (JavascriptExecutor) driver;
    ProxyServer bmp = new ProxyServer(8071);
    bmp.start();

    HttpResponseInterceptor injector = new JQueryInjector();
    bmp.addResponseInterceptor(injector);

    DesiredCapabilities caps = new DesiredCapabilities();
    caps.setCapability(CapabilityType.PROXY, bmp.seleniumProxy());
   // System.setProperty("webdriver.firefox.profile", "test");

    FirefoxDriver driver = new FirefoxDriver(caps);

    driver.get("http://music.day.az/new");
    
    String [] error=(String []) ((JavascriptExecutor) driver).executeScript("return window.jsErrors.toString()").toString().split(",");
    for(int i=0; i<=error.length-2; i++) {
    Reporter.log("Windows js errors: "+error[i].toString(),true);
    
    }
    driver.quit();

    bmp.stop();
  }

  public static class JQueryInjector implements HttpResponseInterceptor {

    @Override
    public void process(HttpResponse response, HttpContext context) throws HttpException, IOException {
      String contentType = response.getFirstHeader("Content-Type").getValue();
      System.out.println(contentType);
      if (contentType.startsWith("text/html")) {
        String text = EntityUtils.toString(response.getEntity(),"utf-8");
       
        
        String newText = text.replace("</head>",
            "<script type=\"text/javascript\">window.jsErrors = []; window.onerror = function(errorMessage) { window.jsErrors[window.jsErrors.length] = errorMessage;} </script></head>");
        
        response.removeHeaders("Content-Length");
        response.addHeader("Content-Length", "" + newText.length());
        response.setEntity(new StringEntity(newText,"utf-8"));
      }

    }
  }
}

@dzhariy: поправил форматирование поста


(Ruslan Semerenko) #2

Проблема немного в другом.
В общем, если кратко, то http://music.day.az/new возвращает сжатую gzip-ом страницу.

EntityUtils.toString(response.getEntity(),"utf-8")

пытается gzip байт-поток превратить в строку. Естественно, в text теперь лежит просто строка из странных юникод символов. Конечно же найти там строку

</head>

вряд ли повезет. Соответственно и скрипт никакой не заинжектится. Как следствие

executeScript("return window.jsErrors.toString()")

свалится. А ошибка в браузере, так как тело ответа подменяется отконвертированным gzip потоком в строку

response.setEntity(new StringEntity(newText,"utf-8"))

(Vad Cheh) #3

Спасибо за ответ. А есть ли какой -то способ убрать или обойти это сжатие программными средствами? То есть можно ли в заголовок запроса передать параметр для того что б браузер не сжимал контент?


(Ruslan Semerenko) #4

Чтобы вытащить текст из gzip-ованой entity нужно сделать так

EntityUtils.toString(new GzipDecompressingEntity(response.getEntity()), "utf-8");

А засунуть подмененную вот так

ByteArrayOutputStream out = new ByteArrayOutputStream();
new GzipCompressingEntity(new StringEntity(newText, "utf-8")).writeTo(out);
response.setEntity(new ByteArrayEntity(out.toByteArray()));

Строки выкинуть

response.removeHeaders("Content-Length");
response.addHeader("Content-Length", "" + newText.length());

(Vad Cheh) #5

Большое Вам спасибо, все работает!!!