1 16 17 18 package org.apache.xmlrpc; 19 20 import java.io.BufferedInputStream ; 21 import java.io.BufferedOutputStream ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.net.ConnectException ; 25 import java.net.Socket ; 26 import java.net.URL ; 27 import java.util.StringTokenizer ; 28 29 import org.apache.xmlrpc.util.HttpUtil; 30 31 40 class LiteXmlRpcTransport implements XmlRpcTransport 41 { 42 String hostname; 43 String host; 44 protected String auth = null; 45 int port; 46 String uri; 47 Socket socket = null; 48 BufferedOutputStream output; 49 BufferedInputStream input; 50 boolean keepalive; 51 byte[] buffer; 52 53 58 public LiteXmlRpcTransport(URL url) 59 { 60 hostname = url.getHost(); 61 port = url.getPort(); 62 if (port < 1) 63 { 64 port = 80; 65 } 66 uri = url.getFile(); 67 if (uri == null || "".equals(uri)) 68 { 69 uri = "/"; 70 } 71 host = port == 80 ? hostname : hostname + ":" + port; 72 } 73 74 public InputStream sendXmlRpc(byte [] request) 75 throws IOException 76 { 77 try 78 { 79 if (socket == null) 80 { 81 initConnection(); 82 } 83 84 InputStream in = null; 85 86 try 89 { 90 in = sendRequest(request); 91 } 92 catch (IOException iox) 93 { 94 if (keepalive) 98 { 99 closeConnection(); 100 initConnection(); 101 in = sendRequest(request); 102 } 103 else 104 { 105 throw iox; 106 } 107 } 108 109 return in; 110 } 111 catch (IOException iox) 112 { 113 throw iox; 116 } 117 catch (Exception x) 118 { 119 if (XmlRpc.debug) 122 { 123 x.printStackTrace (); 124 } 125 126 String msg = x.getMessage (); 127 if (msg == null || msg.length () == 0) 128 { 129 msg = x.toString (); 130 } 131 throw new IOException (msg); 132 } 133 } 134 135 139 protected void initConnection() throws IOException 140 { 141 final int retries = 3; 142 final int delayMillis = 100; 143 144 int tries = 0; 145 146 socket = null; 147 while (socket == null) { 148 try { 149 socket = new Socket (hostname, port); 150 } 151 catch (ConnectException e) { 152 if (tries >= retries) { 153 throw e; 154 } else { 155 try { 157 Thread.sleep(delayMillis); 158 } 159 catch (InterruptedException ignore) { 160 } 161 } 162 } 163 } 164 165 output = new BufferedOutputStream (socket.getOutputStream()); 166 input = new BufferedInputStream (socket.getInputStream()); 167 } 168 169 172 protected void closeConnection () 173 { 174 try 175 { 176 socket.close(); 177 } 178 catch (Exception ignore) 179 { 180 } 181 finally 182 { 183 socket = null; 184 } 185 } 186 187 193 public InputStream sendRequest(byte[] request) throws IOException 194 { 195 output.write(("POST " + uri + " HTTP/1.0\r\n").getBytes()); 196 output.write(("User-Agent: " + XmlRpc.version + "\r\n").getBytes()); 197 output.write(("Host: " + host + "\r\n").getBytes()); 198 if (XmlRpc.getKeepAlive()) 199 { 200 output.write("Connection: Keep-Alive\r\n".getBytes()); 201 } 202 output.write("Content-Type: text/xml\r\n".getBytes()); 203 if (auth != null) 204 { 205 output.write(("Authorization: Basic " + auth + "\r\n") 206 .getBytes()); 207 } 208 output.write(("Content-Length: " + request.length) 209 .getBytes()); 210 output.write("\r\n\r\n".getBytes()); 211 output.write(request); 212 output.flush(); 213 214 String line = readLine(); 216 if (XmlRpc.debug) 217 { 218 System.out.println(line); 219 } 220 int contentLength = -1; 221 try 222 { 223 StringTokenizer tokens = new StringTokenizer (line); 224 String httpversion = tokens.nextToken(); 225 String statusCode = tokens.nextToken(); 226 String statusMsg = tokens.nextToken("\n\r"); 227 keepalive = XmlRpc.getKeepAlive() 228 && "HTTP/1.1".equals(httpversion); 229 if (! "200".equals(statusCode)) 230 { 231 throw new IOException ("Unexpected Response from Server: " 232 + statusMsg); 233 } 234 } 235 catch (IOException iox) 236 { 237 throw iox; 238 } 239 catch (Exception x) 240 { 241 throw new IOException ("Server returned invalid Response."); 243 } 244 do 245 { 246 line = readLine (); 247 if (line != null) 248 { 249 if (XmlRpc.debug) 250 { 251 System.out.println(line); 252 } 253 line = line.toLowerCase(); 254 if (line.startsWith("content-length:")) 255 { 256 contentLength = Integer.parseInt( 257 line.substring(15).trim()); 258 } 259 if (line.startsWith("connection:")) 260 { 261 keepalive = XmlRpc.getKeepAlive() 262 && line.indexOf("keep-alive") > -1; 263 } 264 } 265 } 266 while (line != null && ! line.equals("")) 267 ; 268 return new ServerInputStream(input, contentLength); 269 } 270 271 277 public void setBasicAuthentication(String user, String password) 278 { 279 auth = HttpUtil.encodeBasicAuthentication(user, password); 280 } 281 282 public void endClientRequest() 283 { 284 if (!keepalive) 286 { 287 closeConnection (); 288 } 289 } 290 291 296 private String readLine() throws IOException 297 { 298 if (buffer == null) 299 { 300 buffer = new byte[2048]; 301 } 302 int next; 303 int count = 0; 304 while (true) 305 { 306 next = input.read(); 307 if (next < 0 || next == '\n') 308 { 309 break; 310 } 311 if (next != '\r') 312 { 313 buffer[count++] = (byte) next; 314 } 315 if (count >= buffer.length) 316 { 317 throw new IOException ("HTTP Header too long"); 318 } 319 } 320 return new String (buffer, 0, count); 321 } 322 323 327 protected void finalize() throws Throwable 328 { 329 closeConnection (); 330 } 331 } 332 | Popular Tags |