android http-headers adt android-volley setcookie

Volley de Android, se ha anulado el set-Cookie duplicado



http-headers adt (4)

Intenté eliminar las clases para solucionar esto, pero cuando tuve que editar NetworkResponse , estaba descendiendo demasiado lejos por el rabbithole. Así que decidí editar Volley directamente para capturar todos los encabezados de respuesta en una matriz y no en un Mapa.

Mi fork está en GitHub y he incluido un ejemplo de actividad de uso .

Hice cambios en NetworkResponse.java, BasicNetwork.java y HurlStack.java como se detalla en este compromiso .

Luego, para usar en tus aplicaciones reales, haces algo como esto.

protected Response<String> parseNetworkResponse(NetworkResponse response) { // we must override this to get headers. and with the fix, we should get all headers including duplicate names // in an array of apache headers called apacheHeaders. everything else about volley is the same for (int i = 0; i < response.apacheHeaders.length; i++) { String key = response.apacheHeaders[i].getName(); String value = response.apacheHeaders[i].getValue(); Log.d("VOLLEY_HEADERFIX",key + " - " +value); } return super.parseNetworkResponse(response); }

Es un pequeño truco sucio pero parece funcionar bien para mí en este momento.

Trato de usar Volley lib como un contenedor de red para mi aplicación de Android. Tengo una conexión en funcionamiento, pero el problema es que cada vez que hay múltiples encabezados "Set-Cookie" en la respuesta, Volley usa Map que no puede tener claves duplicadas, y solo almacenará el último encabezado Set-cookie y sobrescribirá el resto .

¿Hay una solución para este problema?

¿Hay otra lib para usar?


Lo primero que necesita es modificar el método BasicNetwork.convertHeaders para que sea compatible con varios valores de mapa. Aquí hay un ejemplo de método modificado:

protected static Map<String, List<String>> convertHeaders(Header[] headers) { Map<String, List<String>> result = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER); for (int i = 0; i < headers.length; i++) { Header header = headers[i]; List<String> list = result.get(header.getName()); if (list == null) { list = new ArrayList<String>(1); list.add(header.getValue()); result.put(header.getName(), list); } else list.add(header.getValue()); } return result; }

Lo siguiente que necesita es modificar los métodos DiskBasedCache.writeStringStringStringMap y DiskBasedCache.readStringStringMap . Deben soportar múltiples valores. Aquí están los métodos modificados junto con los métodos de ayuda:

static void writeStringStringMap(Map<String, List<String>> map, OutputStream os) throws IOException { if (map != null) { writeInt(os, map.size()); for (Map.Entry<String, List<String>> entry : map.entrySet()) { writeString(os, entry.getKey()); writeString(os, joinStringsList(entry.getValue())); } } else { writeInt(os, 0); } } static Map<String, List<String>> readStringStringMap(InputStream is) throws IOException { int size = readInt(is); Map<String, List<String>> result = (size == 0) ? Collections.<String, List<String>>emptyMap() : new HashMap<String, List<String>>(size); for (int i = 0; i < size; i++) { String key = readString(is).intern(); String value = readString(is).intern(); result.put(key, parseNullStringsList(value)); } return result; } static List<String> parseNullStringsList(String str) { String[] strs = str.split("/0"); return Arrays.asList(strs); } static String joinStringsList(List<String> list) { StringBuilder ret = new StringBuilder(); boolean first = true; for (String str : list) { if (first) first = false; else ret.append("/0"); ret.append(str); } return ret.toString(); }

Y lo último es la clase HttpHeaderParser . Debería hacer que su método parseCacheHeaders soporte múltiples valores. Utilice el siguiente método de ayuda para esto:

public static String getHeaderValue(List<String> list) { if ((list == null) || list.isEmpty()) return null; return list.get(0); }

Y lo último para modificar es un montón de lugares para reemplazar

Map<String, String>

a

Map<String, List<String>>

Usa tu IDE para hacer esto.


Pregunta bastante vieja, pero si ayuda a alguien. En la volea más nueva tienes:

protected Response<String> parseNetworkResponse(NetworkResponse response) { List<Header> headers = response.allHeaders; String sessionId = null; for (Header header : headers) { // header.getName(); // header.getValue(); } return super.parseNetworkResponse(response); }


Puede anular la clase de Network de volea. Ver los métodos performRequest y convertHeaders de BasicNetwork puede ayudar. Luego, pasando su implementación de red al contralor de RequestQueue como:

nuevo RequestQueue (nuevo NoCache (), nuevo YourOwnNetwork ());