source: josm/trunk/src/org/openstreetmap/josm/io/OsmServerReader.java@ 5344

Last change on this file since 5344 was 5324, checked in by simon04, 12 years ago

fix #7640 - History query will not cancel or timeout

  • Property svn:eol-style set to native
File size: 7.0 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.BufferedReader;
7import java.io.IOException;
8import java.io.InputStream;
9import java.io.InputStreamReader;
10import java.net.HttpURLConnection;
11import java.net.MalformedURLException;
12import java.net.URL;
13import java.util.zip.GZIPInputStream;
14import java.util.zip.Inflater;
15import java.util.zip.InflaterInputStream;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.data.gpx.GpxData;
19import org.openstreetmap.josm.data.osm.DataSet;
20import org.openstreetmap.josm.gui.progress.ProgressMonitor;
21
22/**
23 * This DataReader reads directly from the REST API of the osm server.
24 *
25 * It supports plain text transfer as well as gzip or deflate encoded transfers;
26 * if compressed transfers are unwanted, set property osm-server.use-compression
27 * to false.
28 *
29 * @author imi
30 */
31public abstract class OsmServerReader extends OsmConnection {
32 private OsmApi api = OsmApi.getOsmApi();
33 private boolean doAuthenticate = false;
34
35 /**
36 * Open a connection to the given url and return a reader on the input stream
37 * from that connection. In case of user cancel, return <code>null</code>.
38 * @param urlStr The exact url to connect to.
39 * @param pleaseWaitDlg
40 * @return An reader reading the input stream (servers answer) or <code>null</code>.
41 */
42 protected InputStream getInputStream(String urlStr, ProgressMonitor progressMonitor) throws OsmTransferException {
43 try {
44 api.initialize(progressMonitor);
45 urlStr = urlStr.startsWith("http") ? urlStr : (getBaseUrl() + urlStr);
46 return getInputStreamRaw(urlStr, progressMonitor);
47 } finally {
48 progressMonitor.invalidate();
49 }
50 }
51
52 protected String getBaseUrl() {
53 return api.getBaseUrl();
54 }
55
56 protected InputStream getInputStreamRaw(String urlStr, ProgressMonitor progressMonitor) throws OsmTransferException {
57 try {
58 URL url = null;
59 try {
60 url = new URL(urlStr.replace(" ", "%20"));
61 } catch(MalformedURLException e) {
62 throw new OsmTransferException(e);
63 }
64 try {
65 activeConnection = (HttpURLConnection)url.openConnection();
66 // fix #7640, see http://www.tikalk.com/java/forums/httpurlconnection-disable-keep-alive
67 activeConnection.setRequestProperty("Connection", "close");
68 } catch(Exception e) {
69 throw new OsmTransferException(tr("Failed to open connection to API {0}.", url.toExternalForm()), e);
70 }
71 if (cancel) {
72 activeConnection.disconnect();
73 return null;
74 }
75
76 if (doAuthenticate) {
77 addAuth(activeConnection);
78 }
79 if (cancel)
80 throw new OsmTransferCanceledException();
81 if (Main.pref.getBoolean("osm-server.use-compression", true)) {
82 activeConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");
83 }
84
85 activeConnection.setConnectTimeout(Main.pref.getInteger("socket.timeout.connect",15)*1000);
86
87 try {
88 System.out.println("GET " + url);
89 activeConnection.connect();
90 } catch (Exception e) {
91 e.printStackTrace();
92 throw new OsmTransferException(tr("Could not connect to the OSM server. Please check your internet connection."), e);
93 }
94 try {
95 if (activeConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED)
96 throw new OsmApiException(HttpURLConnection.HTTP_UNAUTHORIZED,null,null);
97
98 if (activeConnection.getResponseCode() == HttpURLConnection.HTTP_PROXY_AUTH)
99 throw new OsmTransferCanceledException();
100
101 String encoding = activeConnection.getContentEncoding();
102 if (activeConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
103 String errorHeader = activeConnection.getHeaderField("Error");
104 StringBuilder errorBody = new StringBuilder();
105 try
106 {
107 InputStream i = FixEncoding(activeConnection.getErrorStream(), encoding);
108 if (i != null) {
109 BufferedReader in = new BufferedReader(new InputStreamReader(i));
110 String s;
111 while((s = in.readLine()) != null) {
112 errorBody.append(s);
113 errorBody.append("\n");
114 }
115 }
116 }
117 catch(Exception e) {
118 errorBody.append(tr("Reading error text failed."));
119 }
120
121 throw new OsmApiException(activeConnection.getResponseCode(), errorHeader, errorBody.toString());
122 }
123
124 return FixEncoding(new ProgressInputStream(activeConnection, progressMonitor), encoding);
125 } catch(Exception e) {
126 if (e instanceof OsmTransferException)
127 throw (OsmTransferException)e;
128 else
129 throw new OsmTransferException(e);
130
131 }
132 } finally {
133 progressMonitor.invalidate();
134 }
135 }
136
137 private InputStream FixEncoding(InputStream stream, String encoding) throws IOException
138 {
139 if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
140 stream = new GZIPInputStream(stream);
141 }
142 else if (encoding != null && encoding.equalsIgnoreCase("deflate")) {
143 stream = new InflaterInputStream(stream, new Inflater(true));
144 }
145 return stream;
146 }
147
148 public abstract DataSet parseOsm(final ProgressMonitor progressMonitor) throws OsmTransferException;
149
150 public DataSet parseOsmChange(final ProgressMonitor progressMonitor) throws OsmTransferException {
151 return null;
152 }
153
154 public GpxData parseRawGps(final ProgressMonitor progressMonitor) throws OsmTransferException {
155 return null;
156 }
157
158 public DataSet parseOsmBzip2(final ProgressMonitor progressMonitor) throws OsmTransferException {
159 return null;
160 }
161
162 /**
163 * Returns true if this reader is adding authentication credentials to the read
164 * request sent to the server.
165 *
166 * @return true if this reader is adding authentication credentials to the read
167 * request sent to the server
168 */
169 public boolean isDoAuthenticate() {
170 return doAuthenticate;
171 }
172
173 /**
174 * Sets whether this reader adds authentication credentials to the read
175 * request sent to the server.
176 *
177 * @param doAuthenticate true if this reader adds authentication credentials to the read
178 * request sent to the server
179 */
180 public void setDoAuthenticate(boolean doAuthenticate) {
181 this.doAuthenticate = doAuthenticate;
182 }
183}
Note: See TracBrowser for help on using the repository browser.