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 }