mcxiaoke / android-volley

DEPRECATED
4.29k stars 1.56k forks source link

ETag not working if responseHeaders are loaded from DiskCache #116

Open ghost opened 8 years ago

ghost commented 8 years ago

When the BasicNetwork parses the headers it uses a TreeMap to stores the key/value pair, with case-insensitive ordering. Because of this it also possible to access the keys case insensitive ("ETag" == "etag" in this case).

     /**
     * Converts Headers[] to Map<String, String>.
     */
    protected static Map<String, String> convertHeaders(Header[] headers) {
        Map<String, String> result = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
        for (int i = 0; i < headers.length; i++) {
            result.put(headers[i].getName(), headers[i].getValue());
        }
        return result;
    }

But when the response cache is filled with data that was stored on disk the header map is build using a HashMap which is not case-insensitive and therefore it will not work anymore if the server sends "etag" instead of "ETag"

    static Map<String, String> readStringStringMap(InputStream is) throws IOException {
        int size = readInt(is);
        Map<String, String> result = (size == 0)
                ? Collections.<String, String>emptyMap()
                : new HashMap<String, String>(size);
        for (int i = 0; i < size; i++) {
            String key = readString(is).intern();
            String value = readString(is).intern();
            result.put(key, value);
        }
        return result;
    }

As stated in http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 should the header be case insensitive

ghost commented 8 years ago

@mcxiaoke Would it be possible to merge the PR with the fix?