ServerOperation.java revision e80534ff59b2e62a0ddf4359147b81f5ba10de86
19439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly/* 29439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Copyright (c) 2008-2009, Motorola, Inc. 39439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 49439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * All rights reserved. 59439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 69439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Redistribution and use in source and binary forms, with or without 79439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * modification, are permitted provided that the following conditions are met: 89439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 99439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Redistributions of source code must retain the above copyright notice, 109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * this list of conditions and the following disclaimer. 119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Redistributions in binary form must reproduce the above copyright notice, 139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * this list of conditions and the following disclaimer in the documentation 149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * and/or other materials provided with the distribution. 159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Neither the name of the Motorola, Inc. nor the names of its contributors 179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * may be used to endorse or promote products derived from this software 189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * without specific prior written permission. 199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * POSSIBILITY OF SUCH DAMAGE. 319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellypackage javax.obex; 349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.IOException; 369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.InputStream; 379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.DataInputStream; 389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.OutputStream; 399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.DataOutputStream; 409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.ByteArrayOutputStream; 419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly/** 439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * This class implements the Operation interface for server side connections. 449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <P> 4505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <STRONG>Request Codes</STRONG> There are four different request codes that 4605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * are in this class. 0x02 is a PUT request that signals that the request is not 4705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * complete and requires an additional OBEX packet. 0x82 is a PUT request that 4805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * says that request is complete. In this case, the server can begin sending the 4905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * response. The 0x03 is a GET request that signals that the request is not 5005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * finished. When the server receives a 0x83, the client is signaling the server 5105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * that it is done with its request. TODO: Extend the ClientOperation and reuse 5205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * the methods defined TODO: in that class. 532e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @hide 549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 553998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejunpublic final class ServerOperation implements Operation, BaseStream { 569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 573998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public boolean isAborted; 589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 593998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public HeaderSet requestHeader; 609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 613998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public HeaderSet replyHeader; 629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 633998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public boolean finalBitSet; 649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 653998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private InputStream mInput; 669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 673998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private ServerSession mParent; 689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 693998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private int mMaxPacketLength; 702e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly 713998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private int mResponseSize; 729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 733998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mClosed; 749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 753998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mGetOperation; 769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 773998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private PrivateInputStream mPrivateInput; 789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 793998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private PrivateOutputStream mPrivateOutput; 809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 813998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mPrivateOutputOpen; 829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 833998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private String mExceptionString; 849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 853998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private ServerRequestHandler mListener; 869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 873998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mRequestFinished; 889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mHasBody; 909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun * Creates new ServerOperation 939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param p the parent that created this object 949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param in the input stream to read from 959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param out the output stream to write to 969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param request the initial request that was received from the client 979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param maxSize the max packet size that the client will accept 989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param listen the listener that is responding to the request 992e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 1009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public ServerOperation(ServerSession p, InputStream in, int request, int maxSize, 1029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ServerRequestHandler listen) throws IOException { 1039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly isAborted = false; 1053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent = p; 1063998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mInput = in; 1073998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mMaxPacketLength = maxSize; 1083998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = false; 1093998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader = new HeaderSet(); 1103998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader = new HeaderSet(); 1113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput = new PrivateInputStream(this); 1123998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mResponseSize = 3; 1133998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener = listen; 1143998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mRequestFinished = false; 1153998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutputOpen = false; 1163998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mHasBody = false; 1179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bytesReceived; 1189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if this is a PUT request 1219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((request == 0x02) || (request == 0x82)) { 1239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * It is a PUT request. 1259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1263998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mGetOperation = false; 1279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 1289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * It is a GET request. 1309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1313998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mGetOperation = true; 1329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if the final bit is set 1369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((request & 0x80) == 0) { 1389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly finalBitSet = false; 1399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 1409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly finalBitSet = true; 1413998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mRequestFinished = true; 1429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int length = in.read(); 1459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly length = (length << 8) + in.read(); 1469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if the packet length is larger than this device can receive 1499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1502e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly if (length > ObexHelper.MAX_PACKET_SIZE_INT) { 1513998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null); 1529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Packet received was too large"); 1539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if any headers were sent in the initial request 1579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 3) { 1599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] data = new byte[length - 3]; 1609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly bytesReceived = in.read(data); 1619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != data.length) { 1639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly bytesReceived += in.read(data, bytesReceived, data.length - bytesReceived); 1649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1663998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] body = ObexHelper.updateHeaderSet(requestHeader, data); 1679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 1693998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mHasBody = true; 1709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 172e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun if (mListener.getConnectionId() != -1 && requestHeader.mConnectionID != null) { 1733998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(ObexHelper.convertToLong(requestHeader.mConnectionID)); 1749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 175e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun mListener.setConnectionId(1); 1769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1783998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthResp != null) { 1793998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mParent.handleAuthResp(requestHeader.mAuthResp)) { 1803998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Authentication Failed"; 1813998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null); 1823998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 1833998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 1849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return; 1859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1883998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthChall != null) { 1893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.handleAuthChall(requestHeader); 1909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // send the authResp to the client 1913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp = new byte[requestHeader.mAuthResp.length]; 1923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(requestHeader.mAuthResp, 0, replyHeader.mAuthResp, 0, 1933998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp.length); 1943998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 1953998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthChall = null; 1969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 2003998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput.writeBytes(body, 1); 2019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2023998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while ((!mGetOperation) && (!finalBitSet)) { 2033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2043998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput.available() > 0) { 2059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 2069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2083998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 2093998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 2109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while ((!mGetOperation) && (!finalBitSet) && (mPrivateInput.available() == 0)) { 2123998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2133998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput.available() > 0) { 2149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 2159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // wait for get request finished !!!! 2193998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while (mGetOperation && !finalBitSet) { 2203998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (finalBitSet && mGetOperation) { 2233998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mRequestFinished = true; 2249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2273998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public boolean isValidBody() { 2283998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mHasBody; 2299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 23205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Determines if the operation should continue or should wait. If it should 23305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * continue, this method will continue the operation. 2349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param sendEmpty if <code>true</code> then this will continue the 23505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * operation even if no headers will be sent; if <code>false</code> 23605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * then this method will only continue the operation if there are 23705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * headers to send 23805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param inStream if<code>true</code> the stream is input stream, otherwise 23905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * output stream 2409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return <code>true</code> if the operation was completed; 24105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if no operation took place 2429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream) 2449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throws IOException { 2453998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mGetOperation) { 2469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (!finalBitSet) { 2479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (sendEmpty) { 2483998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 2509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2513998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((mResponseSize > 3) || (mPrivateOutput.size() > 0)) { 2523998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 2549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 2569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 2609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2623998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 2649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 26805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Sends a reply to the client. If the reply is a OBEX_HTTP_CONTINUE, it 2699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * will wait for a response from the client before ending. 2709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param type the response code to send back to the client 2719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return <code>true</code> if the final bit was not set on the reply; 27205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if no reply was received because the operation 27305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * ended, an abort was received, or the final bit was set in the 27405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * reply 2752e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 2769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2773998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public synchronized boolean sendReply(int type) throws IOException { 2789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ByteArrayOutputStream out = new ByteArrayOutputStream(); 2799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bytesReceived; 2809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2813998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun long id = mListener.getConnectionId(); 2829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (id == -1) { 2833998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mConnectionID = null; 2849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2853998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mConnectionID = ObexHelper.convertToByteArray(id); 2869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2883998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] headerArray = ObexHelper.createHeader(replyHeader, true); 2899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bodyLength = -1; 2909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int orginalBodyLength = -1; 2919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput != null) { 2933998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bodyLength = mPrivateOutput.size(); 2949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly orginalBodyLength = bodyLength; 2959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2973998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((ObexHelper.BASE_PACKET_LENGTH + headerArray.length) > mMaxPacketLength) { 2989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int end = 0; 3009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int start = 0; 3019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (end != headerArray.length) { 3033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun end = ObexHelper.findHeaderEnd(headerArray, start, mMaxPacketLength 3043998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun - ObexHelper.BASE_PACKET_LENGTH); 3059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (end == -1) { 3069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3073998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 3089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3093998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput != null) { 3103998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput.close(); 3119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3133998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput != null) { 3143998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutput.close(); 3159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3163998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); 3179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("OBEX Packet exceeds max packet size"); 3189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] sendHeader = new byte[end - start]; 3209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length); 3219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(type, sendHeader); 3239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly start = end; 3249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (bodyLength > 0) { 3279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 3289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 3299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 3309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 3339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(headerArray); 3349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3363998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((finalBitSet) || (headerArray.length < (mMaxPacketLength - 20))) { 3379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (bodyLength > 0) { 3389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 3399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if I can send the whole body or just part of 3409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * the body. Remember that there is the 3 bytes for the 3419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * response message and 3 bytes for the header ID and length 3429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3433998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (bodyLength > (mMaxPacketLength - headerArray.length - 6)) { 3443998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bodyLength = mMaxPacketLength - headerArray.length - 6; 3459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3473998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] body = mPrivateOutput.readBytes(bodyLength); 3489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 3509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Since this is a put request if the final bit is set or 3519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * the output stream is closed we need to send the 0x49 3529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * (End of Body) otherwise, we need to send 0x48 (Body) 3539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3543998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((finalBitSet) || (mPrivateOutput.isClosed())) { 3559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x49); 3569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 3579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x48); 3589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly bodyLength += 3; 3619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)(bodyLength >> 8)); 3629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)bodyLength); 3639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(body); 3649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((finalBitSet) && (type == ResponseCodes.OBEX_HTTP_OK) && (orginalBodyLength <= 0)) { 3689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x49); 3699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly orginalBodyLength = 3; 3709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)(orginalBodyLength >> 8)); 3719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)orginalBodyLength); 3729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3753998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mResponseSize = 3; 3763998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(type, out.toByteArray()); 3779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3783998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (type == ResponseCodes.OBEX_HTTP_CONTINUE) { 3793998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun int headerID = mInput.read(); 3803998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun int length = mInput.read(); 3813998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun length = (length << 8) + mInput.read(); 3823998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((headerID != ObexHelper.OBEX_OPCODE_PUT) 3833998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun && (headerID != ObexHelper.OBEX_OPCODE_PUT_FINAL) 3843998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun && (headerID != ObexHelper.OBEX_OPCODE_GET) 3853998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun && (headerID != ObexHelper.OBEX_OPCODE_GET_FINAL)) { 3869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 3) { 3889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] temp = new byte[length]; 3893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived = mInput.read(temp); 3909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != length) { 3923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived += mInput.read(temp, bytesReceived, length - bytesReceived); 3939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 3979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if an ABORT was sent as the reply 3989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3993998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (headerID == ObexHelper.OBEX_OPCODE_ABORT) { 4003998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_OK, null); 4013998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 4029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly isAborted = true; 4033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Abort Received"; 4049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Abort Received"); 4059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4063998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_BAD_REQUEST, null); 4073998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 4083998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Bad Request Received"; 4099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Bad Request Received"); 4109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4133998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((headerID == ObexHelper.OBEX_OPCODE_PUT_FINAL) 4143998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun || (headerID == ObexHelper.OBEX_OPCODE_GET_FINAL)) { 4159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly finalBitSet = true; 4169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if the packet length is larger then this device can receive 4209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4212e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly if (length > ObexHelper.MAX_PACKET_SIZE_INT) { 4223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null); 4239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Packet received was too large"); 4249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if any headers were sent in the initial request 4289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 3) { 4309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] data = new byte[length - 3]; 4313998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived = mInput.read(data); 4329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != data.length) { 4343998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived += mInput.read(data, bytesReceived, data.length 4359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly - bytesReceived); 4369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4373998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] body = ObexHelper.updateHeaderSet(requestHeader, data); 4389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 4393998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mHasBody = true; 4409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 441e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun if (mListener.getConnectionId() != -1 && requestHeader.mConnectionID != null) { 4423998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(ObexHelper 4433998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun .convertToLong(requestHeader.mConnectionID)); 4449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4453998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(1); 4469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4483998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthResp != null) { 4493998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mParent.handleAuthResp(requestHeader.mAuthResp)) { 4503998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Authentication Failed"; 4513998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null); 4523998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 4533998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 4549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 4559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4563998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 4579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4593998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthChall != null) { 4603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.handleAuthChall(requestHeader); 4619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // send the auhtResp to the client 4623998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp = new byte[requestHeader.mAuthResp.length]; 4633998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(requestHeader.mAuthResp, 0, replyHeader.mAuthResp, 0, 4643998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp.length); 4653998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 4663998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthChall = null; 4679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 4703998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput.writeBytes(body, 1); 4719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 4759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 4779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 48105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Sends an ABORT message to the server. By calling this method, the 4829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * corresponding input and output streams will be closed along with this 4839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * object. 48405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if the transaction has already ended or if an OBEX 48505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * server called this method 4869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void abort() throws IOException { 4889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Called from a server"); 4899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 4929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the headers that have been received during the operation. 49305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Modifying the object returned has no effect on the headers that are sent 49405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * or retrieved. 4959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the headers received during this <code>Operation</code> 4962e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if this <code>Operation</code> has been closed 4979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4983998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public HeaderSet getReceivedHeader() throws IOException { 4999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 5003998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return requestHeader; 5019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Specifies the headers that should be sent in the next OBEX message that 5059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * is sent. 5069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param headers the headers to send in the next message 50705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if this <code>Operation</code> has been closed or the 50805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * transaction has ended and no further messages will be exchanged 5092e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IllegalArgumentException if <code>headers</code> was not created 51005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * by a call to <code>ServerRequestHandler.createHeaderSet()</code> 5119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void sendHeaders(HeaderSet headers) throws IOException { 5139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 5149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (headers == null) { 5163998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun throw new IOException("Headers may not be null"); 5179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int[] headerList = headers.getHeaderList(); 5209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (headerList != null) { 5219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly for (int i = 0; i < headerList.length; i++) { 5223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.setHeader(headerList[i], headers.getHeader(headerList[i])); 5239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 52905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Retrieves the response code retrieved from the server. Response codes are 53005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * defined in the <code>ResponseCodes</code> interface. 5319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the response code retrieved from the server 5322e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an error occurred in the transport layer during 53305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * the transaction; if this method is called on a 53405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>HeaderSet</code> object created by calling 53505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>createHeaderSet</code> in a <code>ClientSession</code> 53605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * object; if this is called from a server 5379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public int getResponseCode() throws IOException { 5399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Called from a server"); 5409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Always returns <code>null</code> 5449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return <code>null</code> 5459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public String getEncoding() { 5479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return null; 5489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the type of content that the resource connected to is providing. 5529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * E.g. if the connection is via HTTP, then the value of the content-type 5539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * header field is returned. 5549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the content type of the resource that the URL references, or 55505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>null</code> if not known 5569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public String getType() { 5589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 5593998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return (String)requestHeader.getHeader(HeaderSet.TYPE); 5609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (IOException e) { 5619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return null; 5629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the length of the content which is being provided. E.g. if the 56705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * connection is via HTTP, then the value of the content-length header field 56805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * is returned. 5699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the content length of the resource that this connection's URL 57005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * references, or -1 if the content length is not known 5719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public long getLength() { 5739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 5743998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun Long temp = (Long)requestHeader.getHeader(HeaderSet.LENGTH); 5759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (temp == null) { 5779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return -1; 5789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 5799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return temp.longValue(); 5809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (IOException e) { 5829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return -1; 5839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public int getMaxPacketSize() { 5873998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mMaxPacketLength - 6; 5889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return an input stream for a connection. 5929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an input stream 5932e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 5949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public InputStream openInputStream() throws IOException { 5969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 5973998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mPrivateInput; 5989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return a data input stream for a connection. 6029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an input stream 6032e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 6049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public DataInputStream openDataInputStream() throws IOException { 6069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return new DataInputStream(openInputStream()); 6079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return an output stream for a connection. 6119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an output stream 6122e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 6139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public OutputStream openOutputStream() throws IOException { 6159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 6169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6173998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutputOpen) { 6189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("no more input streams available, stream already opened"); 6193998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 6209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6213998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mRequestFinished) { 6229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("no output streams available ,request not finished"); 6233998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 6249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6253998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput == null) { 6263998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutput = new PrivateOutputStream(this, mMaxPacketLength - 6); 6279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6283998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutputOpen = true; 6293998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mPrivateOutput; 6309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return a data output stream for a connection. 6349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an output stream 6352e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 6369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public DataOutputStream openDataOutputStream() throws IOException { 6389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return new DataOutputStream(openOutputStream()); 6399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Closes the connection and ends the transaction 6432e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if the operation has already ended or is closed 6449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void close() throws IOException { 6469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 6473998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 6489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Verifies that the connection is open and no exceptions should be thrown. 6522e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an exception needs to be thrown 6539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void ensureOpen() throws IOException { 6553998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mExceptionString != null) { 6563998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun throw new IOException(mExceptionString); 6579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mClosed) { 6599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Operation has already ended"); 6609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 66405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Verifies that additional information may be sent. In other words, the 6659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * operation is not done. 6669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <P> 66705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Included to implement the BaseStream interface only. It does not do 6689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * anything on the server side since the operation of the Operation object 6699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * is not done until after the handler returns from its method. 6702e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if the operation is completed 6719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void ensureNotDone() throws IOException { 6739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 67605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Called when the output or input stream is closed. It does not do anything 67705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * on the server side since the operation of the Operation object is not 67805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * done until after the handler returns from its method. 6799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param inStream <code>true</code> if the input stream is closed; 68005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if the output stream is closed 6812e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 6829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void streamClosed(boolean inStream) throws IOException { 6849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly} 687