2016-12-13 6 views
0

Выполнение запроса с одинаковым URL-адресом и другим заголовком Accept возвращает предыдущий ответ из кэша okhttp.Клиент OkHttp не принимает заголовок Accept

Это означает, что первый запрос выполнен для данных приложения/json, второй запрашивает application/xml. Поэтому клиент возвращает данные json из кеша вместо того, чтобы делать xml вверх.

Например, запрос GET: http://example.com с заголовком/json возвращает заголовок Cache-Control и полезную нагрузку json. Отклик кэшируется во внутреннем кэше HTTP. Второй запрос выполнен в окне управления кешем до http://example.com с заголовком application/xml. В этом случае Okhttp возвращает ту же полезную нагрузку json из кеша, а не в полезную нагрузку xml.

Builder builder = new Builder().url("https://httpbin.org/headers").header("accept", header); 

Неужели кто-нибудь испытал эту проблему уже?

+1

Возможно, покажите нам короткую часть кода и ее выход, демонстрируя проблему? – slim

+0

https://gist.github.com/gpor89/c69c795b334af5ff63cef6468222a01e, но проходит тест для этого ресурса, потому что сайт не возвращает заголовки кэша. – Gregor

+0

Не на Gist. Вопросы должны быть самодостаточными. Вам не нужен весь код, достаточно, чтобы люди могли видеть, что вы делаете, и показываете свой результат. – slim

ответ

2

Соответствующий RFC, описывающий, как кэш должен работать здесь: https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6:

Если поля заголовка запроса выбора для кэшированной записи не соответствуют полям заголовка запроса выбора нового запроса, то cache НЕ ДОЛЖЕН использовать кэшированную запись для удовлетворения запроса, если он сначала не перенаправляет новый запрос на исходный сервер в условном запросе, а сервер отвечает 304 (Not Modified), включая тег объекта или Content-Location, который указывает, что объект использоваться.

Исходный код OkHttp-х Cache здесь: https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/Cache.java

Ключ кэша просто, URL ресурса. Но запись кэша сравнивается с «меняются» заголовков запроса тоже:

Response response = entry.response(snapshot); 

if (!entry.matches(request, response)) { 
    Util.closeQuietly(response.body()); 
    return null; 
} 

...

public boolean matches(Request request, Response response) { 
    return url.equals(request.url().toString()) 
     && requestMethod.equals(request.method()) 
     && HttpHeaders.varyMatches(response, varyHeaders, request); 
} 

Это, возможно, вы нашли ошибку, конечно. Я предлагаю подключить источник JAR OkHttp, отлаживая с помощью точки останова в методе Cache.get() и перешагнув, чтобы увидеть, если/когда он пойдет не так. Если это так, поднимите с сопровождающими или отправьте патч.

+2

_key_ - это только URL-адрес, но он рассматривает заголовки из сохраненного ответа и входящего запроса при принятии решения о возврате кэшированного ответа. –

+0

@JesseWilson Ах, глядя ближе, так оно и есть. – slim

+1

@JesseWilson изменил ответ соответственно. – slim

 Смежные вопросы

  • Нет связанных вопросов^_^