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  {
24      @Test
25      public void testSimpleGetWithOrigin() throws IOException
26      {
27          Map<String,String> headers = makeRequest("GET", ImmutableMap.<String, String>of(ORIGIN.value(), CREDENTIALS));
28          assertEquals(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()), CREDENTIALS);
29          assertEquals(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()), "true");
30          assertEquals(headers.get(ACCESS_CONTROL_EXPOSE_HEADERS.value()), "X-Response-Header");
31      }
32  
33      @Test
34      public void testSimpleGetWithNoCredentialsOrigin() throws IOException
35      {
36          Map<String,String> headers = makeRequest("GET", ImmutableMap.<String, String>of(ORIGIN.value(), NO_CREDENTIALS));
37          assertEquals(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()), NO_CREDENTIALS);
38          assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
39          assertEquals(headers.get(ACCESS_CONTROL_EXPOSE_HEADERS.value()), "X-Response-Header");
40      }
41  
42      @Test
43      public void testPreflight() throws IOException
44      {
45          Map<String,String> headers = makeRequest("OPTIONS", ImmutableMap.<String, String>of(
46                  ORIGIN.value(), CREDENTIALS,
47                  ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT"
48          ));
49          assertEquals(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()), CREDENTIALS);
50          assertEquals(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()), "true");
51          assertEquals(headers.get(ACCESS_CONTROL_MAX_AGE.value()), String.valueOf(60*60));
52          assertEquals(headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()), "PUT");
53          assertEquals(headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()), "X-Custom-Header");
54      }
55  
56      @Test
57      public void testPreflightWithWrongHeaders() throws Exception
58      {
59          Map<String,String> headers = makeRequest("OPTIONS", ImmutableMap.<String, String>of(
60                  ORIGIN.value(), NO_CREDENTIALS,
61                  ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT",
62                  ACCESS_CONTROL_REQUEST_HEADERS.value(), "X-Unexpected-Header"
63          ));
64          assertNull(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
65          assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
66          assertNull(headers.get(ACCESS_CONTROL_MAX_AGE.value()));
67          assertNull(headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()));
68          assertNull(headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()));
69      }
70  
71      @Test
72      public void testPreflightWithWrongOrigin() throws IOException
73      {
74          Map<String,String> headers = makeRequest("OPTIONS", ImmutableMap.<String, String>of(
75                  ORIGIN.value(), "http://www.invalid.com",
76                  ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT"
77          ));
78          assertNull(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
79          assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
80          assertNull(headers.get(ACCESS_CONTROL_MAX_AGE.value()));
81          assertNull(headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()));
82          assertNull(headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()));
83      }
84  
85      @Test
86      public void testPreflightWithWrongMethod() throws IOException
87      {
88          Map<String,String> headers = makeRequest(
89                  WebResourceFactory.anonymous().path("cors").path("none").getURI().toString(),
90                  "OPTIONS", ImmutableMap.<String, String>of(
91                      ORIGIN.value(), CREDENTIALS,
92                      ACCESS_CONTROL_REQUEST_METHOD.value(), "PUT"
93          ));
94          assertNull(headers.get(ACCESS_CONTROL_ALLOW_ORIGIN.value()));
95          assertNull(headers.get(ACCESS_CONTROL_ALLOW_CREDENTIALS.value()));
96          assertNull(headers.get(ACCESS_CONTROL_MAX_AGE.value()));
97          assertNull(headers.get(ACCESS_CONTROL_ALLOW_METHODS.value()));
98          assertNull(headers.get(ACCESS_CONTROL_ALLOW_HEADERS.value()));
99      }
100 
101     private Map<String,String> makeRequest(String method, Map<String,String> headers) throws IOException
102     {
103         return makeRequest(WebResourceFactory.anonymous().path("cors").getURI().toString(), method, headers);
104     }
105 
106     private Map<String,String> makeRequest(String uri, String method, Map<String,String> headers) throws IOException
107     {
108         URL url = new URL(uri);
109         Socket socket = new Socket(url.getHost(), url.getPort());
110 
111         PrintWriter writer = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()));
112         writer.write(method + " " + url.getPath() + " HTTP/1.1\r\n");
113         for (String key : headers.keySet())
114         {
115             writer.write(key + ": " + headers.get(key) + "\r\n");
116         }
117         writer.write("Accept: text/html\r\n");
118         writer.write("User-Agent: Me\r\n");
119         writer.write("Connection: keep-alive\r\n");
120         writer.write("Host: 127.0.0.1:" + url.getPort() + " \r\n");
121         writer.write("\n\n");
122         writer.flush();
123 
124         Map<String,String> responseHeaders = newHashMap();
125         BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
126         String line;
127         while ((line = reader.readLine()) != null)
128         {
129             if ("".equals(line))
130             {
131                 socket.close();
132                 break;
133             }
134             int pos = line.indexOf(':');
135             if (pos > -1)
136             {
137                 String key = line.substring(0, pos).trim();
138                 String value = line.substring(pos+1).trim();
139                 responseHeaders.put(key, value);
140             }
141         }
142 
143         return responseHeaders;
144     }
145 }