Changeset 1392


Ignore:
Timestamp:
02/21/14 19:27:26 (10 years ago)
Author:
pharms
Message:
  • correct 2 bugs: one an implementation bug in encoding queries in the Jetty HTML client and another one when proxying CXF SOAP exchanges where the server is deployed in a tomcat.
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-httpmonitor-test/src/test/java/de/ugoe/cs/autoquest/httpmonitor/AbstractTC.java

    r1390 r1392  
    1515package de.ugoe.cs.autoquest.httpmonitor; 
    1616 
     17import static org.junit.Assert.assertEquals; 
     18import static org.junit.Assert.assertNotNull; 
     19import static org.junit.Assert.assertTrue; 
     20 
    1721import java.io.BufferedReader; 
    1822import java.io.File; 
     
    3539import org.junit.Before; 
    3640 
     41import de.ugoe.cs.autoquest.eventcore.Event; 
     42import de.ugoe.cs.autoquest.httpmonitor.exchange.HttpExchange; 
     43import de.ugoe.cs.autoquest.httpmonitor.exchange.Method; 
     44import de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType; 
     45import de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPTarget; 
    3746import de.ugoe.cs.util.console.TextConsole; 
    3847 
     
    208217        return message.toString(); 
    209218    } 
     219     
     220    /** 
     221     * 
     222     */ 
     223    protected void assertEvent(Event event, String method, String message, String response) { 
     224        assertNotNull(event); 
     225        assertNotNull(event.getType()); 
     226        assertNotNull(event.getTarget()); 
     227         
     228        assertTrue(event.getType() instanceof HTTPEventType); 
     229        assertTrue(event.getTarget() instanceof HTTPTarget); 
     230         
     231        HttpExchange exchange = ((HTTPEventType) event.getType()).getExchange(); 
     232         
     233        assertEquals(Method.fromValue(method), exchange.getRequest().getMethod()); 
     234         
     235        if (message != null) { 
     236            assertEquals(message, exchange.getRequest().getContent().getData()); 
     237        } 
     238        else if (exchange.getRequest().getContent() != null) { 
     239            System.err.println(exchange.getRequest().getContent().getData()); 
     240        } 
     241         
     242        if (response != null) { 
     243            assertEquals(response, exchange.getResponse().getContent().getData()); 
     244        } 
     245        else if (exchange.getResponse().getContent() != null) { 
     246            System.err.println(exchange.getResponse().getContent().getData()); 
     247        } 
     248    } 
    210249 
    211250    /** 
  • trunk/autoquest-httpmonitor-test/src/test/java/de/ugoe/cs/autoquest/httpmonitor/HttpMonitorTest.java

    r1390 r1392  
    2222import java.io.File; 
    2323import java.io.StringWriter; 
     24import java.net.URL; 
    2425import java.util.Collection; 
    2526import java.util.Iterator; 
     
    2829import javax.xml.bind.JAXBContext; 
    2930import javax.xml.bind.Marshaller; 
     31import javax.xml.namespace.QName; 
    3032 
    3133import org.apache.http.HttpEntity; 
     
    4648import de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType; 
    4749import de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPTarget; 
     50import dummyservice.DummyService; 
     51import dummyservice.DummyServicePortType; 
     52import dummyservice.VerifyUserInMsgType; 
     53import dummyservice.VerifyUserOutMsgType; 
    4854 
    4955/** 
     
    201207        assertEquals(1, sequence.size()); 
    202208 
    203         assertNotNull(sequence.get(0)); 
    204         assertNotNull(sequence.get(0).getType()); 
    205         assertTrue(sequence.get(0).getType() instanceof HTTPEventType); 
    206  
    207         assertNotNull(sequence.get(0).getTarget()); 
    208         assertTrue(sequence.get(0).getTarget() instanceof HTTPTarget); 
    209  
    210         HttpExchange exchange = ((HTTPEventType) sequence.get(0).getType()).getExchange(); 
    211          
    212         assertEquals(message, exchange.getRequest().getContent().getData()); 
    213         assertEquals(response, exchange.getResponse().getContent().getData()); 
     209        assertEvent(sequence.get(0), "POST", message, response); 
    214210    } 
    215211 
     
    295291        assertEquals(1, sequence.size()); 
    296292 
    297         assertNotNull(sequence.get(0)); 
    298         assertNotNull(sequence.get(0).getType()); 
    299         assertTrue(sequence.get(0).getType() instanceof HTTPEventType); 
    300  
    301         assertNotNull(sequence.get(0).getTarget()); 
    302         assertTrue(sequence.get(0).getTarget() instanceof HTTPTarget); 
    303  
    304         HttpExchange exchange = ((HTTPEventType) sequence.get(0).getType()).getExchange(); 
    305          
    306         assertEquals(message, exchange.getRequest().getContent().getData()); 
    307         assertEquals(response, exchange.getResponse().getContent().getData()); 
     293        assertEvent(sequence.get(0), "POST", message, response); 
     294    } 
     295 
     296    @Test 
     297    public void test_SOAP_ProxyAndMonitor() throws Exception { 
     298        monitor = new HttpMonitor(new String[] { LOG_FILE_DIR, MONITOR_PORT + "" }); 
     299 
     300        monitor.init(); 
     301        monitor.start(); 
     302 
     303        proxy = new HttpMonitoringProxy 
     304            (new String[] { LOG_FILE_DIR, PROXY_PORT + "", 
     305                            "localhost:" + DUMMY_SERVER_PORT, "localhost:" + MONITOR_PORT }); 
     306 
     307        proxy.init(); 
     308        proxy.start(); 
     309 
     310        DummyService service = new DummyService 
     311            (new URL("http://localhost:" + PROXY_PORT + "/dummyWebapp/DummyServiceSOAPPort?wsdl"), 
     312             new QName("DummyService", "DummyService")); 
     313 
     314        DummyServicePortType dummyService = service.getDummyServiceSOAPPort(); 
     315         
     316        dummyservice.ObjectFactory factory = new dummyservice.ObjectFactory(); 
     317        VerifyUserInMsgType request = factory.createVerifyUserInMsgType(); 
     318        VerifyUserOutMsgType response = dummyService.verifyUser(request); 
     319 
     320        assertNotNull(response); 
     321         
     322        // the monitor needs some time to receive the exchange --> give it 
     323        Thread.sleep(1000); 
     324         
     325        monitor.stop(); 
     326        monitor = null; 
     327 
     328        File logFile = new File(LOG_FILE_DIR + File.separator + "httpmonitor_000.log"); 
     329         
     330        assertTrue(logFile.exists()); 
     331         
     332        HTTPLogParser parser = new HTTPLogParser(); 
     333 
     334        parser.parseFile(logFile); 
     335 
     336        // check the sequences 
     337        Collection<List<Event>> sequences = parser.getSequences(); 
     338 
     339        assertNotNull(sequences); 
     340 
     341        Iterator<List<Event>> iterator = sequences.iterator(); 
     342        assertTrue(iterator.hasNext()); 
     343 
     344        List<Event> sequence = iterator.next(); 
     345        assertFalse(iterator.hasNext()); 
     346 
     347        assertNotNull(sequence); 
     348        assertEquals(2, sequence.size()); 
     349 
     350        assertEvent(sequence.get(0), "GET", null, null); // get WSDL 
     351        assertEvent(sequence.get(1), "POST", null, null); // send request 
    308352    } 
    309353     
  • trunk/autoquest-httpmonitor-test/src/test/java/de/ugoe/cs/autoquest/httpmonitor/HttpMonitoringProxyTest.java

    r1390 r1392  
    4949import de.ugoe.cs.autoquest.httpmonitor.proxy.HttpMonitoringProxy; 
    5050import de.ugoe.cs.autoquest.plugin.http.HTTPLogParser; 
    51 import de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType; 
    52 import de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPTarget; 
    5351import dummyservice.DummyService; 
    5452import dummyservice.DummyServicePortType; 
     
    445443        assertNotNull(exchange.getResponse().getContent().getData()); 
    446444    } 
    447      
    448     /** 
    449      * 
    450      */ 
    451     private void assertEvent(Event event, String method, String message, String response) { 
    452         assertNotNull(event); 
    453         assertNotNull(event.getType()); 
    454         assertNotNull(event.getTarget()); 
    455          
    456         assertTrue(event.getType() instanceof HTTPEventType); 
    457         assertTrue(event.getTarget() instanceof HTTPTarget); 
    458          
    459         HttpExchange exchange = ((HTTPEventType) event.getType()).getExchange(); 
    460          
    461         assertEquals(Method.fromValue(method), exchange.getRequest().getMethod()); 
    462          
    463         if (message != null) { 
    464             assertEquals(message, exchange.getRequest().getContent().getData()); 
    465         } 
    466         else if (exchange.getRequest().getContent() != null) { 
    467             System.err.println(exchange.getRequest().getContent().getData()); 
    468         } 
    469          
    470         if (response != null) { 
    471             assertEquals(response, exchange.getResponse().getContent().getData()); 
    472         } 
    473         else if (exchange.getResponse().getContent() != null) { 
    474             System.err.println(exchange.getResponse().getContent().getData()); 
    475         } 
    476     } 
    477445 
    478446    /** 
  • trunk/autoquest-httpmonitor/src/main/java/de/ugoe/cs/autoquest/httpmonitor/proxy/HttpMonitoringProxyServlet.java

    r1389 r1392  
    1616 
    1717import java.io.IOException; 
     18import java.io.UnsupportedEncodingException; 
    1819import java.net.URI; 
    1920import java.net.URISyntaxException; 
     21import java.net.URLEncoder; 
    2022import java.nio.ByteBuffer; 
     23import java.nio.charset.UnsupportedCharsetException; 
    2124import java.util.Iterator; 
     25import java.util.LinkedList; 
     26import java.util.List; 
    2227 
    2328import javax.servlet.http.HttpServletRequest; 
    2429import javax.servlet.http.HttpServletResponse; 
    2530 
     31import org.eclipse.jetty.client.HttpClient; 
     32import org.eclipse.jetty.client.HttpRequest; 
    2633import org.eclipse.jetty.client.api.ContentProvider; 
    2734import org.eclipse.jetty.client.api.Request; 
    2835import org.eclipse.jetty.client.api.Response; 
    2936import org.eclipse.jetty.proxy.ProxyServlet; 
     37import org.eclipse.jetty.util.Fields; 
    3038 
    3139import de.ugoe.cs.autoquest.httpmonitor.exchange.Status; 
     
    4149 * recorded exchange. 
    4250 * </p> 
     51 * <p> 
     52 * The implementation also overrides the default implementation of the jetty HTTP client 
     53 * and the jetty HTTP request to fix a bug in forwarding queries. 
     54 * </p> 
    4355 *  
    4456 * @author Patrick Harms 
     
    97109            return null; 
    98110        } 
     111    } 
     112 
     113    /* (non-Javadoc) 
     114     * @see org.eclipse.jetty.proxy.ProxyServlet#newHttpClient() 
     115     */ 
     116    @Override 
     117    protected HttpClient newHttpClient() { 
     118        return new BugfixedHttpClient(); 
    99119    } 
    100120 
     
    200220 
    201221    /** 
    202      * This iterator is used to implement the {@link DubbingContentProvider}. It works in the  
    203      * same manner and uses delegation for wrapping the original iterator and forwards all copied 
    204      * data to the exchange listener manager. 
     222     * This iterator is used to implement the {@link DubbingContentProvider}. It uses delegation 
     223     * for wrapping the original iterator and forwards all copied data to the exchange listener 
     224     * manager. Furthermore, it combines several buffers into one. This seems to be required if 
     225     * SOAP messages are proxied. 
    205226     */ 
    206227    public class DubbingByteBufferIterator implements Iterator<ByteBuffer> { 
     
    237258        @Override 
    238259        public ByteBuffer next() { 
    239             ByteBuffer next = delegate.next(); 
    240             exchangeListenerManager.onRequestContent(request, next.duplicate()); 
    241             return next; 
     260            List<ByteBuffer> buffers = new LinkedList<ByteBuffer>(); 
     261             
     262            int size = 0; 
     263            while (delegate.hasNext()) { 
     264                ByteBuffer next = delegate.next(); 
     265                exchangeListenerManager.onRequestContent(request, next.duplicate()); 
     266 
     267                ByteBuffer copy = ByteBuffer.allocate(next.limit()); 
     268                copy.put(next); 
     269                copy.position(0); 
     270                buffers.add(copy); 
     271                 
     272                size += next.limit(); 
     273            } 
     274             
     275            ByteBuffer buffer = ByteBuffer.allocate(size); 
     276             
     277            for (ByteBuffer orig : buffers) { 
     278                buffer.put(orig); 
     279            } 
     280             
     281            buffer.position(0); 
     282             
     283            return buffer; 
    242284        } 
    243285 
     
    247289        @Override 
    248290        public void remove() { 
    249             delegate.remove(); 
    250         } 
    251  
    252     } 
    253  
     291            while (delegate.hasNext()) { 
     292                delegate.remove(); 
     293            } 
     294        } 
     295 
     296    } 
     297 
     298    /** 
     299     * <p> 
     300     * bugfix implementation of the jetty HTTP client to be able to use only bugfixed HTTP requests 
     301     * </p> 
     302     *  
     303     * @author Patrick Harms 
     304     */ 
     305    private class BugfixedHttpClient extends HttpClient { 
     306 
     307        /* (non-Javadoc) 
     308         * @see org.eclipse.jetty.client.HttpClient#newRequest(java.net.URI) 
     309         */ 
     310        @Override 
     311        public Request newRequest(URI uri) { 
     312            return new BugfixedHttpRequest(this, uri); 
     313        } 
     314 
     315    } 
     316 
     317    /** 
     318     * <p> 
     319     * bugfix implementation of the jetty HTTP request. This ensures that query string 
     320     * representations are correctly forwarded in the case that a query parameter does not have 
     321     * a value.  
     322     * </p> 
     323     *  
     324     * @author Patrick Harms 
     325     */ 
     326    private class BugfixedHttpRequest extends HttpRequest { 
     327 
     328        /** 
     329         * <p> 
     330         * Constructor to override parent constructor 
     331         * </p>  
     332         */ 
     333        BugfixedHttpRequest(HttpClient client, URI uri) { 
     334            super(client, uri); 
     335        } 
     336 
     337        /* 
     338         * (non-Javadoc) 
     339         *  
     340         * @see org.eclipse.jetty.client.HttpRequest#getQuery() 
     341         */ 
     342        @Override 
     343        public String getQuery() { 
     344            return buildQuery(); 
     345        } 
     346 
     347        /** 
     348         * <p> 
     349         * this corrects the bug implemented in the parent class on creating the query string 
     350         * </p> 
     351         *  
     352         * @return the correct query string 
     353         */ 
     354        private String buildQuery() { 
     355            StringBuilder result = new StringBuilder(); 
     356            for (Iterator<Fields.Field> iterator = super.getParams().iterator(); iterator.hasNext();) 
     357            { 
     358                Fields.Field field = iterator.next(); 
     359                String[] values = field.values(); 
     360                for (int i = 0; i < values.length; ++i) { 
     361                    if (i > 0) { 
     362                        result.append("&"); 
     363                    } 
     364 
     365                    result.append(field.name()); 
     366 
     367                    if ((values[i] != null) && (!"".equals(values[i].trim()))) { 
     368                        result.append("="); 
     369                        result.append(urlEncode(values[i])); 
     370                    } 
     371                } 
     372                if (iterator.hasNext()) { 
     373                    result.append("&"); 
     374                } 
     375            } 
     376            return result.toString(); 
     377        } 
     378 
     379        /** 
     380         * <p> 
     381         * convenience method copied from parent class, as it is private there. 
     382         * </p> 
     383         *  
     384         * @see HttpRequest#urlEncode(String) 
     385         */ 
     386        private String urlEncode(String value) { 
     387            String encoding = "UTF-8"; 
     388            try { 
     389                return URLEncoder.encode(value, encoding); 
     390            } 
     391            catch (UnsupportedEncodingException e) { 
     392                throw new UnsupportedCharsetException(encoding); 
     393            } 
     394        } 
     395    } 
    254396} 
Note: See TracChangeset for help on using the changeset viewer.