[ https://issues.apache.org/jira/browse/CAMEL-12395?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Claus Ibsen resolved CAMEL-12395. --------------------------------- Resolution: Fixed Assignee: Claus Ibsen Thanks for reporting and the suggested patch > HttpProducer cookie handling broken > ----------------------------------- > > Key: CAMEL-12395 > URL: https://issues.apache.org/jira/browse/CAMEL-12395 > Project: Camel > Issue Type: Bug > Components: camel-http > Affects Versions: 2.20.2 > Reporter: Kevin Brooks > Assignee: Claus Ibsen > Priority: Minor > Fix For: 2.20.4, 2.21.1, 2.22.0 > > Original Estimate: 24h > Remaining Estimate: 24h > > Assumptions from https://tools.ietf.org/html/rfc6265 > When a host response contains multiple headers with the same key, each with > different values, the HttpProducer overwrites the value, effectively > last-in-wins, extracted problem code below > {code:java} > protected void populateResponse(Exchange exchange, HttpRequestBase > httpRequest, HttpResponse httpResponse, > Message in, HeaderFilterStrategy strategy, int responseCode) throws > IOException, ClassNotFoundException { > ... > // propagate HTTP response headers > Header[] headers = httpResponse.getAllHeaders(); > Map<String, List<String>> m = new HashMap<String, List<String>>(); > for (Header header : headers) { > String name = header.getName(); > String value = header.getValue(); > m.put(name, Collections.singletonList(value)); //<--- This is the problem > if (name.toLowerCase().equals("content-type")) { > name = Exchange.CONTENT_TYPE; > exchange.setProperty(Exchange.CHARSET_NAME, > IOHelper.getCharsetNameFromContentType(value)); > } > // use http helper to extract parameter value as it may contain multiple > values > Object extracted = HttpHelper.extractHttpParameterValue(value); > if (strategy != null && !strategy.applyFilterToExternalHeaders(name, > extracted, exchange)) { > HttpHelper.appendHeader(answer.getHeaders(), name, extracted); > } > } > // handle cookies > if (getEndpoint().getCookieHandler() != null) { > //if host responded with multiple Set-Cookie headers, only last cookie is > presented > getEndpoint().getCookieHandler().storeCookies(exchange, > httpRequest.getURI(), m); > } > ... > {code} > A simple fix -> > {code:java} > ... > for (Header header : headers) { > String name = header.getName(); > String value = header.getValue(); > List<String> values = m.computeIfAbsent(name, k -> new > ArrayList<>()).add(value); > ... > {code} > On the flip side, when the client responds, the cookies pulled from the > handler are not formatted correctly, broken code snippet from > HttpProducer.process() > {code:java} > if (getEndpoint().getCookieHandler() != null) { > Map<String, List<String>> cookieHeaders = > getEndpoint().getCookieHandler().loadCookies(exchange, httpRequest.getURI()); > for (Map.Entry<String, List<String>> entry : > cookieHeaders.entrySet()) { > String key = entry.getKey(); > if (entry.getValue().size() > 0) { > // use the default toString of a ArrayList to create in > the form [xxx, yyy] > // if multi valued, for a single value, then just output > the value as is > String s = entry.getValue().size() > 1 ? > entry.getValue().toString() : entry.getValue().get(0);//<--- This is a problem > httpRequest.addHeader(key, s); > } > } > } > {code} > This can be fixed simply > {code:java} > if (getEndpoint().getCookieHandler() != null) { > Map<String, List<String>> cookieHeaders = > getEndpoint().getCookieHandler().loadCookies(exchange, httpRequest.getURI()); > for (Map.Entry<String, List<String>> entry : > cookieHeaders.entrySet()) { > String key = entry.getKey(); > if (entry.getValue().size() > 0) { > httpRequest.addHeader(key, > entry.getValue().stream().collect(Collectors.joining(";"))); //semi-colon, > not comma... > } > } > } > {code} > Additionally, the CookieHandler.loadCookies method is not properly > constructing the Cookie values, as it calls HttpCookie.toString - which > represents the host's _Set-Cookie_ value, not the client's _Cookie_ value -- This message was sent by Atlassian JIRA (v7.6.3#76005)