1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.http.functional;
12
13 import org.mule.DefaultMuleMessage;
14 import org.mule.api.MessagingException;
15 import org.mule.api.MuleMessage;
16 import org.mule.api.config.MuleProperties;
17 import org.mule.api.construct.FlowConstruct;
18 import org.mule.api.endpoint.InboundEndpoint;
19 import org.mule.api.lifecycle.CreateException;
20 import org.mule.api.service.Service;
21 import org.mule.api.transport.Connector;
22 import org.mule.config.DefaultMuleConfiguration;
23 import org.mule.service.ServiceCompositeMessageSource;
24 import org.mule.tck.junit4.AbstractMuleContextTestCase;
25 import org.mule.transport.http.HttpsConnector;
26 import org.mule.transport.http.HttpsMessageReceiver;
27 import org.mule.transport.ssl.MockHandshakeCompletedEvent;
28 import org.mule.transport.ssl.MockSslSocket;
29
30 import com.mockobjects.dynamic.Mock;
31
32 import java.io.IOException;
33 import java.lang.reflect.InvocationTargetException;
34 import java.lang.reflect.Method;
35 import java.net.Socket;
36 import java.util.Collections;
37 import java.util.Map;
38
39 import javax.net.ssl.HandshakeCompletedEvent;
40 import javax.resource.spi.work.Work;
41
42 import org.junit.Test;
43
44 import static org.junit.Assert.assertNotNull;
45 import static org.junit.Assert.assertTrue;
46 import static org.junit.Assert.fail;
47
48
49
50
51
52
53
54
55
56
57 public class HttpsHandshakeTimingTestCase extends AbstractMuleContextTestCase
58 {
59
60 @Test
61 public void testHttpsHandshakeExceedsTimeout() throws Exception
62 {
63 MockHttpsMessageReceiver messageReceiver = setupMockHttpsMessageReceiver();
64
65 MockSslSocket socket = new MockSslSocket();
66 Work work = messageReceiver.createWork(socket);
67 assertNotNull(work);
68
69 MuleMessage message = new DefaultMuleMessage(TEST_MESSAGE, muleContext);
70 try
71 {
72
73
74 invokePreRouteMessage(work, message);
75 fail();
76 }
77 catch (InvocationTargetException ite)
78 {
79 assertTrue(ite.getCause() instanceof MessagingException);
80 assertTrue(ite.getCause().getMessage().contains("handshake"));
81 }
82 }
83
84 @Test
85 public void testHttpsHandshakeCompletesBeforeProcessingMessage() throws Exception
86 {
87 MockHttpsMessageReceiver messageReceiver = setupMockHttpsMessageReceiver();
88
89 MockSslSocket socket = new MockSslSocket();
90 Work work = messageReceiver.createWork(socket);
91 assertNotNull(work);
92
93 invokeHandshakeCompleted(work, socket);
94
95 MuleMessage message = new DefaultMuleMessage(TEST_MESSAGE, muleContext);
96 invokePreRouteMessage(work, message);
97 assertNotNull(message.<Object>getInboundProperty(MuleProperties.MULE_REMOTE_CLIENT_ADDRESS));
98 }
99
100 private void invokeHandshakeCompleted(Work work, MockSslSocket socket) throws Exception
101 {
102 Method handshakeCompleted = work.getClass().getDeclaredMethod("handshakeCompleted", HandshakeCompletedEvent.class);
103 assertNotNull(handshakeCompleted);
104 handshakeCompleted.setAccessible(true);
105 HandshakeCompletedEvent event = new MockHandshakeCompletedEvent(socket);
106 handshakeCompleted.invoke(work, new Object[] { event });
107 }
108
109 private void invokePreRouteMessage(Work work, MuleMessage message) throws Exception
110 {
111 Method preRouteMessage = work.getClass().getDeclaredMethod("preRouteMessage", MuleMessage.class);
112 assertNotNull(preRouteMessage);
113 preRouteMessage.setAccessible(true);
114 preRouteMessage.invoke(work, new Object[] { message });
115 }
116
117 private MockHttpsMessageReceiver setupMockHttpsMessageReceiver() throws CreateException
118 {
119 HttpsConnector httpsConnector = new HttpsConnector(muleContext);
120 httpsConnector.setSslHandshakeTimeout(1000);
121
122 Map<?, ?> properties = Collections.emptyMap();
123
124 Mock mockEndpoint = new Mock(InboundEndpoint.class);
125 mockEndpoint.expectAndReturn("getConnector", httpsConnector);
126 mockEndpoint.expectAndReturn("getEncoding", new DefaultMuleConfiguration().getDefaultEncoding());
127 mockEndpoint.expectAndReturn("getProperties", properties);
128 mockEndpoint.expectAndReturn("getProperties", properties);
129 InboundEndpoint inboundEndpoint = (InboundEndpoint) mockEndpoint.proxy();
130
131 Mock mockService = new Mock(Service.class);
132 mockService.expectAndReturn("getResponseRouter", null);
133 mockService.expectAndReturn("getInboundRouter", new ServiceCompositeMessageSource());
134 Service service = (Service) mockService.proxy();
135
136 MockHttpsMessageReceiver messageReceiver = new MockHttpsMessageReceiver(httpsConnector, service, inboundEndpoint);
137 return messageReceiver;
138 }
139
140 private static class MockHttpsMessageReceiver extends HttpsMessageReceiver
141 {
142 public MockHttpsMessageReceiver(Connector connector, FlowConstruct flowConstruct,
143 InboundEndpoint endpoint) throws CreateException
144 {
145 super(connector, flowConstruct, endpoint);
146 }
147
148
149
150
151 @Override
152 public Work createWork(Socket socket) throws IOException
153 {
154 return super.createWork(socket);
155 }
156 }
157 }