1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.jumpmind.symmetric.transport.http;
22
23 import java.io.BufferedReader;
24 import java.io.BufferedWriter;
25 import java.io.IOException;
26 import java.io.OutputStream;
27 import java.io.OutputStreamWriter;
28 import java.net.HttpURLConnection;
29 import java.net.URL;
30 import java.util.zip.GZIPOutputStream;
31
32 import javax.servlet.http.HttpServletResponse;
33
34 import org.apache.commons.io.IOUtils;
35 import org.jumpmind.symmetric.common.Constants;
36 import org.jumpmind.symmetric.transport.AuthenticationException;
37 import org.jumpmind.symmetric.transport.ConnectionRejectedException;
38 import org.jumpmind.symmetric.transport.IOutgoingWithResponseTransport;
39
40 public class HttpOutgoingTransport implements IOutgoingWithResponseTransport {
41
42 private URL url;
43
44 private BufferedWriter writer;
45
46 private BufferedReader reader;
47
48 private HttpURLConnection connection;
49
50 private int httpTimeout;
51
52 private boolean useCompression;
53
54 public HttpOutgoingTransport(URL url, int httpTimeout, boolean useCompression) {
55 this.url = url;
56 this.httpTimeout = httpTimeout;
57 this.useCompression = useCompression;
58 }
59
60 public void close() throws IOException {
61 closeWriter();
62 closeReader();
63 if (connection != null) {
64 connection.disconnect();
65 connection = null;
66 }
67 }
68
69 private void closeReader() throws IOException {
70 if (reader != null) {
71 IOUtils.closeQuietly(reader);
72 reader = null;
73 }
74 }
75
76 private void closeWriter() throws IOException {
77 if (writer != null) {
78 writer.flush();
79 IOUtils.closeQuietly(writer);
80 writer = null;
81 }
82 }
83
84 /***
85 * Before streaming data to the remote node, make sure it is ok to. We have
86 * found that we can be more efficient on a push by relying on HTTP
87 * keep-alive.
88 *
89 * @throws IOException
90 * @throws {@link ConnectionRejectedException}
91 * @throws {@link AuthenticationException}
92 */
93 private void requestReservation() throws IOException {
94 HttpURLConnection c = (HttpURLConnection) url.openConnection();
95 c.setUseCaches(false);
96 c.setConnectTimeout(httpTimeout);
97 c.setReadTimeout(httpTimeout);
98 c.setRequestMethod("HEAD");
99 analyzeResponseCode(c.getResponseCode());
100 }
101
102 public BufferedWriter open() throws IOException {
103 requestReservation();
104 connection = (HttpURLConnection) url.openConnection();
105 connection.setDoInput(true);
106 connection.setDoOutput(true);
107 connection.setUseCaches(false);
108 connection.setConnectTimeout(httpTimeout);
109 connection.setReadTimeout(httpTimeout);
110 connection.setRequestMethod("PUT");
111 connection.setRequestProperty("accept-encoding", "gzip");
112 if (useCompression) {
113 connection.addRequestProperty("Content-Type", "gzip");
114 }
115 OutputStream out = connection.getOutputStream();
116 if (useCompression) {
117 out = new GZIPOutputStream(out);
118 }
119 OutputStreamWriter wout = new OutputStreamWriter(out, Constants.ENCODING);
120 writer = new BufferedWriter(wout);
121 return writer;
122 }
123
124 /***
125 * @throws {@link ConnectionRejectedException}
126 * @throws {@link AuthenticationException}
127 */
128 private void analyzeResponseCode(int code) throws IOException {
129 if (HttpServletResponse.SC_SERVICE_UNAVAILABLE == code) {
130 throw new ConnectionRejectedException();
131 } else if (HttpServletResponse.SC_FORBIDDEN == code) {
132 throw new AuthenticationException();
133 }
134 }
135
136 public BufferedReader readResponse() throws IOException {
137 closeWriter();
138 analyzeResponseCode(connection.getResponseCode());
139 this.reader = HttpTransportManager.getReaderFrom(connection);
140 return this.reader;
141 }
142
143 public boolean isOpen() {
144 return connection != null;
145 }
146
147 }