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 }