View Javadoc

1   package it.com.atlassian.rest.cors;
2   
3   import com.atlassian.rest.jersey.client.WebResourceFactory;
4   import com.google.common.collect.ImmutableMap;
5   import org.junit.Test;
6   
7   import java.io.BufferedOutputStream;
8   import java.io.BufferedReader;
9   import java.io.IOException;
10  import java.io.InputStreamReader;
11  import java.io.PrintWriter;
12  import java.net.Socket;
13  import java.net.URL;
14  import java.util.Map;
15  
16  import static com.atlassian.plugins.rest.common.security.CorsHeaders.*;
17  import static com.atlassian.plugins.rest.cors.SimpleCorsDefaults.*;
18  import static com.google.common.collect.Maps.newHashMap;
19  import static org.junit.Assert.assertEquals;
20  import static org.junit.Assert.assertNull;
21  
22  public class CorsCheckTest {
23      @Test
24      public void testSimpleGetWithOrigin() throws IOException {
25          Map<String, String> headers = makeRequest("GET", ImmutableMap.<String, String>of(ORIGIN.value(), CREDENTIALS));
26          assertEquals(CREDENTIALS, headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
27          assertEquals("true", headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
28          assertEquals("X-Response-Header", headers.get(ACCESS_CONTROL_EXPOSE_HEADERS.value()));
29      }
30  
31      @Test
32      public void testSimpleGetWithNoCredentialsOrigin() throws IOException {
33          Map<String, String> headers = makeRequest("GET", ImmutableMap.<String, String>of(ORIGIN.value(), NO_CREDENTIALS));
34          assertEquals(NO_CREDENTIALS, headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
35          assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
36          assertEquals("X-Response-Header", headers.get(ACCESS_CONTROL_EXPOSE_HEADERS.value()));
37      }
38  
39      @Test
40      public void testPreflight() throws IOException {
41          Map<String, String> headers = makeRequest("OPTIONS", ImmutableMap.<String, String>of(
42                  ORIGIN.value(), CREDENTIALS,
43                  ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT"
44          ));
45          assertEquals(CREDENTIALS, headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
46          assertEquals("true", headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
47          assertEquals(String.valueOf(60 * 60), headers.get(ACCESS_CONTROL_MAX_AGE.value()));
48          assertEquals("PUT", headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()));
49          assertEquals("X-Custom-Header", headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()));
50      }
51  
52      @Test
53      public void testPreflightWithWrongHeaders() throws Exception {
54          Map<String, String> headers = makeRequest("OPTIONS", ImmutableMap.<String, String>of(
55                  ORIGIN.value(), NO_CREDENTIALS,
56                  ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT",
57                  ACCESS_CONTROL_REQUEST_HEADERS.value(), "X-Unexpected-Header"
58          ));
59          assertNull(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
60          assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
61          assertNull(headers.get(ACCESS_CONTROL_MAX_AGE.value()));
62          assertNull(headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()));
63          assertNull(headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()));
64      }
65  
66      @Test
67      public void testPreflightWithWrongOrigin() throws IOException {
68          Map<String, String> headers = makeRequest("OPTIONS", ImmutableMap.<String, String>of(
69                  ORIGIN.value(), "http://www.invalid.com",
70                  ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT"
71          ));
72          assertNull(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
73          assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
74          assertNull(headers.get(ACCESS_CONTROL_MAX_AGE.value()));
75          assertNull(headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()));
76          assertNull(headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()));
77      }
78  
79      @Test
80      public void testPreflightWithWrongMethod() throws IOException {
81          Map<String, String> headers = makeRequest(
82                  WebResourceFactory.anonymous().path("cors").path("none").getURI().toString(),
83                  "OPTIONS", ImmutableMap.<String, String>of(
84                          ORIGIN.value(), CREDENTIALS,
85                          ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT"
86                  ));
87          assertNull(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
88          assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
89          assertNull(headers.get(ACCESS_CONTROL_MAX_AGE.value()));
90          assertNull(headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()));
91          assertNull(headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()));
92      }
93  
94      private Map<String, String> makeRequest(String method, Map<String, String> headers) throws IOException {
95          return makeRequest(WebResourceFactory.anonymous().path("cors").getURI().toString(), method, headers);
96      }
97  
98      private Map<String, String> makeRequest(String uri, String method, Map<String, String> headers) throws IOException {
99          URL url = new URL(uri);
100         Socket socket = new Socket(url.getHost(), url.getPort());
101 
102         PrintWriter writer = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()));
103         writer.write(method + " " + url.getPath() + " HTTP/1.1\r\n");
104         for (String key : headers.keySet()) {
105             writer.write(key + ": " + headers.get(key) + "\r\n");
106         }
107         writer.write("Accept: text/html\r\n");
108         writer.write("User-Agent: Me\r\n");
109         writer.write("Connection: keep-alive\r\n");
110         writer.write("Host: 127.0.0.1:" + url.getPort() + " \r\n");
111         writer.write("\n\n");
112         writer.flush();
113 
114         Map<String, String> responseHeaders = newHashMap();
115         BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
116         String line;
117         while ((line = reader.readLine()) != null) {
118             if ("".equals(line)) {
119                 socket.close();
120                 break;
121             }
122             int pos = line.indexOf(':');
123             if (pos > -1) {
124                 String key = line.substring(0, pos).trim();
125                 String value = line.substring(pos + 1).trim();
126                 responseHeaders.put(key, value);
127             }
128         }
129 
130         return responseHeaders;
131     }
132 }