cxf-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Romain Manni-Bucau (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CXF-7042) review some jaxrs client defaults: thread safe and split headers
Date Wed, 07 Sep 2016 14:10:21 GMT

    [ https://issues.apache.org/jira/browse/CXF-7042?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15470741#comment-15470741
] 

Romain Manni-Bucau commented on CXF-7042:
-----------------------------------------

{code}
package com.cxf;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.Tomcat;
import org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet;
import org.apache.cxf.transport.http.Headers;
import org.junit.Test;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class HeaderSenderTest {
    @Test
    public void run() throws Exception {
        //hackCxf();

        final Tomcat tomcat = new Tomcat();
        tomcat.getHost(); // create the host
        tomcat.start();
        try {
            final File root = new File("target/root");
            root.mkdirs();
            final Context context = tomcat.addContext("", root.getAbsolutePath());
            final Wrapper cxf = Tomcat.addServlet(context, "cxf", CXFNonSpringJaxrsServlet.class.getName());
            cxf.addInitParameter("jaxrs.serviceClasses", HeaderSender.class.getName());
            context.addServletMappingDecoded("/*", "cxf");

            final Response response = ClientBuilder.newClient()
                    .target("http://localhost:8080").path("demo")
                    .request(MediaType.WILDCARD_TYPE).get();

            System.out.println();
            System.out.println();
            System.out.println();
            System.out.println("headers =");
            for (final Map.Entry<String, List<Object>> entry : response.getHeaders().entrySet())
{
                System.out.println("  " + entry.getKey() + " = " + entry.getValue() + " ("
+ entry.getValue().size() + ")");
            }
            System.out.println("links   = " + response.getLinks() + " (" + response.getLinks().size()
+ ")");
            System.out.println();
            System.out.println();
            System.out.println();
        } finally {
            tomcat.stop();
            tomcat.destroy();
        }
    }

    private void hackCxf() throws Exception {
        final Field f = Headers.class.getDeclaredField("HTTP_HEADERS_SINGLE_VALUE_ONLY");
        f.setAccessible(true);
        Collection.class.cast(f.get(null)).add("a");
    }

    @Path("demo")
    public static class HeaderSender {
        @GET
        public Response send() {
            return Response.ok()
                    .header("a", "1")
                    .header("a", "2")
                    .link("http://link1", "rel")
                    .link("http://link2", "self")
                    .build();
        }
    }
}


/* pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="
            http://maven.apache.org/POM/4.0.0
            http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.cxf</groupId>
  <artifactId>cxf-headers</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>org.apache.geronimo.specs</groupId>
      <artifactId>geronimo-jaxrs_2.0_spec</artifactId>
      <version>1.0-alpha-1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
      <version>3.1.7</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-rs-client</artifactId>
      <version>3.1.7</version>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-core</artifactId>
      <version>8.5.5</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
 */
{code}

allows to see the issue:

- the output will have a concatenated string value (1 item) for a header on the client side
but server explicitely sent 1 values so on a JAXRS roundtrip (client-server) it is inconsistent
- if you activate hackCxf() it works but it should be the default

proposal would be to let the transport handle the concatenation or not of headers (using addHeader
instead of setHeader on the response) and just add a flag in CXF to enforce CXF to concatenate
the value but not the opposite to ensure client reads by default what the server writes

> review some jaxrs client defaults: thread safe and split headers
> ----------------------------------------------------------------
>
>                 Key: CXF-7042
>                 URL: https://issues.apache.org/jira/browse/CXF-7042
>             Project: CXF
>          Issue Type: Bug
>            Reporter: Romain Manni-Bucau
>
> Hi
> putting it as "bug" but can be "improvement" depending how you see it
> I'd like we take a moment to review 2 properties of the client:
> - thread.safe.client: i think the default should be true since the spec is thread safe
> - org.apache.cxf.http.header.split (AbstractClient): issue not being true by default
is it breaks some natural JAXRS round trips like Link: your server sends Link header with
2 values, client (response.getLinks()) is not able to read it. If it is about performances,
known headers (the ones wrapped by some higher level API in JAXRS) should at least be handled
properly by default.
> Side note for headers: org.apache.cxf.transport.http.Headers#copyToResponse concatenate
headers properly for multiple values but not for Link header cause of org.apache.cxf.transport.http.Headers#HTTP_HEADERS_SINGLE_VALUE_ONLY,
not sure it is intended
> wdyt?



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message