1 /* 2 * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 6726695 27 * @summary HttpURLConnection shoul support 'Expect: 100-contimue' headers for PUT 28 */ 29 30 import java.net.*; 31 import java.io.*; 32 33 public class B6726695 extends Thread { 34 private ServerSocket server = null; 35 private int port = 0; 36 private byte[] data = new byte[512]; 37 private String boundary = "----------------7774563516523621"; 38 39 public static void main(String[] args) throws Exception { 40 B6726695 test = new B6726695(); 41 // Exit even if server is still running 42 test.setDaemon(true); 43 // start server 44 test.start(); 45 // run test 46 test.test(); 47 } 48 49 public B6726695() { 50 try { 51 server = new ServerSocket(0); 52 port = server.getLocalPort(); 53 } catch (IOException e) { 54 e.printStackTrace(); 55 } 56 } 57 58 public void test() throws Exception { 59 /** 60 * This is a hardcoded test. The server side expects 3 requests with a 61 * Expect: 100-continue header. It will reject the 1st one and accept 62 * the second one. Thus allowing us to test both scenarios. 63 * The 3rd case is the simulation of a server that just plains ignore 64 * the Expect: 100-Continue header. So the POST should proceed after 65 * a timeout. 66 */ 67 URL url = new URL("http://localhost:" + port + "/foo"); 68 69 // 1st Connection. Should be rejected. I.E. get a ProtocolException 70 URLConnection con = url.openConnection(); 71 HttpURLConnection http = (HttpURLConnection) con; 72 http.setRequestMethod("POST"); 73 http.setRequestProperty("Expect", "100-Continue"); 74 http.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); 75 http.setDoOutput(true); 76 http.setFixedLengthStreamingMode(512); 77 OutputStream out = null; 78 int errorCode = -1; 79 try { 80 out = http.getOutputStream(); 81 } catch (ProtocolException e) { 82 errorCode = http.getResponseCode(); 83 } 84 if (errorCode != 417) { 85 throw new RuntimeException("Didn't get the ProtocolException"); 86 } 87 88 // 2nd connection. Should be accepted by server. 89 http = (HttpURLConnection) url.openConnection(); 90 http.setRequestMethod("POST"); 91 http.setRequestProperty("Expect", "100-Continue"); 92 http.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); 93 http.setDoOutput(true); 94 http.setFixedLengthStreamingMode(data.length); 95 out = null; 96 try { 97 out = http.getOutputStream(); 98 } catch (ProtocolException e) { 99 } 100 if (out == null) { 101 throw new RuntimeException("Didn't get an OutputStream"); 102 } 103 out.write(data); 104 out.flush(); 105 errorCode = http.getResponseCode(); 106 if (errorCode != 200) { 107 throw new RuntimeException("Response code is " + errorCode); 108 } 109 out.close(); 110 111 // 3rd connection. Simulate a server that doesn't implement 100-continue 112 http = (HttpURLConnection) url.openConnection(); 113 http.setRequestMethod("POST"); 114 http.setRequestProperty("Expect", "100-Continue"); 115 http.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); 116 http.setDoOutput(true); 117 http.setFixedLengthStreamingMode(data.length); 118 out = null; 119 try { 120 out = http.getOutputStream(); 121 } catch (ProtocolException e) { 122 } 123 if (out == null) { 124 throw new RuntimeException("Didn't get an OutputStream"); 125 } 126 out.write(data); 127 out.flush(); 128 out.close(); 129 errorCode = http.getResponseCode(); 130 if (errorCode != 200) { 131 throw new RuntimeException("Response code is " + errorCode); 132 } 133 } 134 135 136 @Override 137 public void run() { 138 try { 139 // Fist connection: don't accetpt the request 140 Socket s = server.accept(); 141 serverReject(s); 142 // Second connection: accept the request (send 100-continue) 143 s = server.accept(); 144 serverAccept(s); 145 // 3rd connection: just ignore the 'Expect:' header 146 s = server.accept(); 147 serverIgnore(s); 148 } catch (IOException e) { 149 e.printStackTrace(); 150 } finally { 151 try { server.close(); } catch (IOException unused) {} 152 } 153 } 154 155 public void serverReject(Socket s) throws IOException { 156 BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); 157 PrintStream out = new PrintStream(new BufferedOutputStream(s.getOutputStream())); 158 String line = null; 159 do { 160 line = in.readLine(); 161 } while (line != null && line.length() != 0); 162 163 out.print("HTTP/1.1 417 Expectation Failed\r\n"); 164 out.print("Server: Sun-Java-System-Web-Server/7.0\r\n"); 165 out.print("Connection: close\r\n"); 166 out.print("Content-Length: 0\r\n"); 167 out.print("\r\n"); 168 out.flush(); 169 out.close(); 170 in.close(); 171 } 172 173 public void serverAccept(Socket s) throws IOException { 174 BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); 175 PrintStream out = new PrintStream(new BufferedOutputStream(s.getOutputStream())); 176 String line = null; 177 do { 178 line = in.readLine(); 179 } while (line != null && line.length() != 0); 180 181 // Send 100-Continue 182 out.print("HTTP/1.1 100 Continue\r\n"); 183 out.print("\r\n"); 184 out.flush(); 185 // Then read the body 186 char[] cbuf = new char[512]; 187 int l = in.read(cbuf); 188 // finally send the 200 OK 189 out.print("HTTP/1.1 200 OK"); 190 out.print("Server: Sun-Java-System-Web-Server/7.0\r\n"); 191 out.print("Connection: close\r\n"); 192 out.print("Content-Length: 0\r\n"); 193 out.print("\r\n"); 194 out.flush(); 195 out.close(); 196 in.close(); 197 } 198 199 public void serverIgnore(Socket s) throws IOException { 200 BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); 201 PrintStream out = new PrintStream(new BufferedOutputStream(s.getOutputStream())); 202 String line = null; 203 do { 204 line = in.readLine(); 205 } while (line != null && line.length() != 0); 206 207 // Then read the body 208 char[] cbuf = new char[512]; 209 int l = in.read(cbuf); 210 // finally send the 200 OK 211 out.print("HTTP/1.1 200 OK"); 212 out.print("Server: Sun-Java-System-Web-Server/7.0\r\n"); 213 out.print("Content-Length: 0\r\n"); 214 out.print("Connection: close\r\n"); 215 out.print("\r\n"); 216 out.flush(); 217 out.close(); 218 in.close(); 219 } 220 }