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; 12765208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 12865208317ba9d16486b47ebcaa868c596d424c87fLixin Yue /* 12965208317ba9d16486b47ebcaa868c596d424c87fLixin Yue * Determine if the final bit is set 13065208317ba9d16486b47ebcaa868c596d424c87fLixin Yue */ 13165208317ba9d16486b47ebcaa868c596d424c87fLixin Yue if ((request & 0x80) == 0) { 13265208317ba9d16486b47ebcaa868c596d424c87fLixin Yue finalBitSet = false; 13365208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } else { 13465208317ba9d16486b47ebcaa868c596d424c87fLixin Yue finalBitSet = true; 13565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue mRequestFinished = true; 13665208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } 13765208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } else if ((request == 0x03) || (request == 0x83)) { 1389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * It is a GET request. 1409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1413998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mGetOperation = true; 1429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 14365208317ba9d16486b47ebcaa868c596d424c87fLixin Yue // For Get request, final bit set is decided by server side logic 1449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly finalBitSet = false; 14565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 14665208317ba9d16486b47ebcaa868c596d424c87fLixin Yue if (request == 0x83) { 14765208317ba9d16486b47ebcaa868c596d424c87fLixin Yue mRequestFinished = true; 14865208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } 1499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 15065208317ba9d16486b47ebcaa868c596d424c87fLixin Yue throw new IOException("ServerOperation can not handle such request"); 1519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int length = in.read(); 1549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly length = (length << 8) + in.read(); 1559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if the packet length is larger than this device can receive 1589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1592e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly if (length > ObexHelper.MAX_PACKET_SIZE_INT) { 1603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null); 1619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Packet received was too large"); 1629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if any headers were sent in the initial request 1669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 3) { 1689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] data = new byte[length - 3]; 1699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly bytesReceived = in.read(data); 1709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != data.length) { 1729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly bytesReceived += in.read(data, bytesReceived, data.length - bytesReceived); 1739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1753998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] body = ObexHelper.updateHeaderSet(requestHeader, data); 1769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 1783998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mHasBody = true; 1799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 181e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun if (mListener.getConnectionId() != -1 && requestHeader.mConnectionID != null) { 1823998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(ObexHelper.convertToLong(requestHeader.mConnectionID)); 1839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 184e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun mListener.setConnectionId(1); 1859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1873998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthResp != null) { 1883998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mParent.handleAuthResp(requestHeader.mAuthResp)) { 1893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Authentication Failed"; 1903998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null); 1913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 1923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 1939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return; 1949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1973998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthChall != null) { 1983998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.handleAuthChall(requestHeader); 1999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // send the authResp to the client 2003998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp = new byte[requestHeader.mAuthResp.length]; 2013998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(requestHeader.mAuthResp, 0, replyHeader.mAuthResp, 0, 2023998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp.length); 2033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 2043998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthChall = null; 2059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 2093998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput.writeBytes(body, 1); 2109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while ((!mGetOperation) && (!finalBitSet)) { 2123998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2133998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput.available() > 0) { 2149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 2159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2173998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 2183998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 2199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2203998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while ((!mGetOperation) && (!finalBitSet) && (mPrivateInput.available() == 0)) { 2213998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput.available() > 0) { 2239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 2249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // wait for get request finished !!!! 22865208317ba9d16486b47ebcaa868c596d424c87fLixin Yue while (mGetOperation && !mRequestFinished) { 2293998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2333998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public boolean isValidBody() { 2343998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mHasBody; 2359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 23805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Determines if the operation should continue or should wait. If it should 23905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * continue, this method will continue the operation. 2409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param sendEmpty if <code>true</code> then this will continue the 24105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * operation even if no headers will be sent; if <code>false</code> 24205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * then this method will only continue the operation if there are 24305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * headers to send 24405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param inStream if<code>true</code> the stream is input stream, otherwise 24505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * output stream 2469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return <code>true</code> if the operation was completed; 24705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if no operation took place 2489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream) 2509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throws IOException { 2513998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mGetOperation) { 2529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (!finalBitSet) { 2539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (sendEmpty) { 2543998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 2569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2573998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((mResponseSize > 3) || (mPrivateOutput.size() > 0)) { 2583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 2609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 2629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 2669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2683998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 2709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 27405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Sends a reply to the client. If the reply is a OBEX_HTTP_CONTINUE, it 2759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * will wait for a response from the client before ending. 2769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param type the response code to send back to the client 2779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return <code>true</code> if the final bit was not set on the reply; 27805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if no reply was received because the operation 27905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * ended, an abort was received, or the final bit was set in the 28005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * reply 2812e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 2829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2833998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public synchronized boolean sendReply(int type) throws IOException { 2849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ByteArrayOutputStream out = new ByteArrayOutputStream(); 2859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bytesReceived; 2869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2873998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun long id = mListener.getConnectionId(); 2889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (id == -1) { 2893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mConnectionID = null; 2909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mConnectionID = ObexHelper.convertToByteArray(id); 2929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2943998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] headerArray = ObexHelper.createHeader(replyHeader, true); 2959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bodyLength = -1; 2969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int orginalBodyLength = -1; 2979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2983998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput != null) { 2993998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bodyLength = mPrivateOutput.size(); 3009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly orginalBodyLength = bodyLength; 3019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((ObexHelper.BASE_PACKET_LENGTH + headerArray.length) > mMaxPacketLength) { 3049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int end = 0; 3069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int start = 0; 3079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (end != headerArray.length) { 3093998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun end = ObexHelper.findHeaderEnd(headerArray, start, mMaxPacketLength 3103998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun - ObexHelper.BASE_PACKET_LENGTH); 3119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (end == -1) { 3129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3133998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 3149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3153998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput != null) { 3163998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput.close(); 3179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3193998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput != null) { 3203998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutput.close(); 3219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); 3239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("OBEX Packet exceeds max packet size"); 3249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] sendHeader = new byte[end - start]; 3269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length); 3279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3283998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(type, sendHeader); 3299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly start = end; 3309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (bodyLength > 0) { 3339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 3349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 3359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 3369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 3399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(headerArray); 3409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 34265208317ba9d16486b47ebcaa868c596d424c87fLixin Yue // For Get operation: if response code is OBEX_HTTP_OK, then this is the 34365208317ba9d16486b47ebcaa868c596d424c87fLixin Yue // last packet; so set finalBitSet to true. 34465208317ba9d16486b47ebcaa868c596d424c87fLixin Yue if (mGetOperation && type == ResponseCodes.OBEX_HTTP_OK) { 34565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue finalBitSet = true; 34665208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } 34765208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 3483998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((finalBitSet) || (headerArray.length < (mMaxPacketLength - 20))) { 3499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (bodyLength > 0) { 3509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 3519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if I can send the whole body or just part of 3529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * the body. Remember that there is the 3 bytes for the 3539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * response message and 3 bytes for the header ID and length 3549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3553998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (bodyLength > (mMaxPacketLength - headerArray.length - 6)) { 3563998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bodyLength = mMaxPacketLength - headerArray.length - 6; 3579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3593998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] body = mPrivateOutput.readBytes(bodyLength); 3609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 3629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Since this is a put request if the final bit is set or 3639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * the output stream is closed we need to send the 0x49 3649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * (End of Body) otherwise, we need to send 0x48 (Body) 3659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3663998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((finalBitSet) || (mPrivateOutput.isClosed())) { 3679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x49); 3689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 3699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x48); 3709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly bodyLength += 3; 3739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)(bodyLength >> 8)); 3749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)bodyLength); 3759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(body); 3769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((finalBitSet) && (type == ResponseCodes.OBEX_HTTP_OK) && (orginalBodyLength <= 0)) { 3809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x49); 3819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly orginalBodyLength = 3; 3829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)(orginalBodyLength >> 8)); 3839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)orginalBodyLength); 3849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3873998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mResponseSize = 3; 3883998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(type, out.toByteArray()); 3899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3903998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (type == ResponseCodes.OBEX_HTTP_CONTINUE) { 3913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun int headerID = mInput.read(); 3923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun int length = mInput.read(); 3933998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun length = (length << 8) + mInput.read(); 3943998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((headerID != ObexHelper.OBEX_OPCODE_PUT) 3953998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun && (headerID != ObexHelper.OBEX_OPCODE_PUT_FINAL) 3963998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun && (headerID != ObexHelper.OBEX_OPCODE_GET) 3973998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun && (headerID != ObexHelper.OBEX_OPCODE_GET_FINAL)) { 3989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 3) { 4004507b177c35cfd918dba1cdc325fae3688fb7bd2Anders Petersson byte[] temp = new byte[length - 3]; 4014507b177c35cfd918dba1cdc325fae3688fb7bd2Anders Petersson // First three bytes already read, compensating for this 4023998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived = mInput.read(temp); 4039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4044507b177c35cfd918dba1cdc325fae3688fb7bd2Anders Petersson while (bytesReceived != temp.length) { 4054507b177c35cfd918dba1cdc325fae3688fb7bd2Anders Petersson bytesReceived += mInput.read(temp, bytesReceived, 4064507b177c35cfd918dba1cdc325fae3688fb7bd2Anders Petersson temp.length - bytesReceived); 4079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if an ABORT was sent as the reply 4129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4133998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (headerID == ObexHelper.OBEX_OPCODE_ABORT) { 4143998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_OK, null); 4153998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 4169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly isAborted = true; 4173998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Abort Received"; 4189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Abort Received"); 4199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4203998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_BAD_REQUEST, null); 4213998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 4223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Bad Request Received"; 4239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Bad Request Received"); 4249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 42765208317ba9d16486b47ebcaa868c596d424c87fLixin Yue if ((headerID == ObexHelper.OBEX_OPCODE_PUT_FINAL)) { 4289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly finalBitSet = true; 42965208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } else if (headerID == ObexHelper.OBEX_OPCODE_GET_FINAL) { 43065208317ba9d16486b47ebcaa868c596d424c87fLixin Yue mRequestFinished = true; 4319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if the packet length is larger then this device can receive 4359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4362e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly if (length > ObexHelper.MAX_PACKET_SIZE_INT) { 4373998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null); 4389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Packet received was too large"); 4399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if any headers were sent in the initial request 4439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 3) { 4459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] data = new byte[length - 3]; 4463998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived = mInput.read(data); 4479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != data.length) { 4493998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived += mInput.read(data, bytesReceived, data.length 4509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly - bytesReceived); 4519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4523998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] body = ObexHelper.updateHeaderSet(requestHeader, data); 4539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 4543998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mHasBody = true; 4559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 456e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun if (mListener.getConnectionId() != -1 && requestHeader.mConnectionID != null) { 4573998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(ObexHelper 4583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun .convertToLong(requestHeader.mConnectionID)); 4599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(1); 4619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4633998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthResp != null) { 4643998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mParent.handleAuthResp(requestHeader.mAuthResp)) { 4653998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Authentication Failed"; 4663998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null); 4673998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 4683998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 4699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 4709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4713998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 4729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4743998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthChall != null) { 4753998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.handleAuthChall(requestHeader); 4769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // send the auhtResp to the client 4773998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp = new byte[requestHeader.mAuthResp.length]; 4783998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(requestHeader.mAuthResp, 0, replyHeader.mAuthResp, 0, 4793998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp.length); 4803998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 4813998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthChall = null; 4829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 4853998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput.writeBytes(body, 1); 4869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 4909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 4929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 49605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Sends an ABORT message to the server. By calling this method, the 4979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * corresponding input and output streams will be closed along with this 4989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * object. 49905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if the transaction has already ended or if an OBEX 50005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * server called this method 5019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void abort() throws IOException { 5039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Called from a server"); 5049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the headers that have been received during the operation. 50805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Modifying the object returned has no effect on the headers that are sent 50905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * or retrieved. 5109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the headers received during this <code>Operation</code> 5112e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if this <code>Operation</code> has been closed 5129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5133998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public HeaderSet getReceivedHeader() throws IOException { 5149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 5153998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return requestHeader; 5169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Specifies the headers that should be sent in the next OBEX message that 5209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * is sent. 5219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param headers the headers to send in the next message 52205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if this <code>Operation</code> has been closed or the 52305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * transaction has ended and no further messages will be exchanged 5242e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IllegalArgumentException if <code>headers</code> was not created 52505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * by a call to <code>ServerRequestHandler.createHeaderSet()</code> 5269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void sendHeaders(HeaderSet headers) throws IOException { 5289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 5299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (headers == null) { 5313998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun throw new IOException("Headers may not be null"); 5329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int[] headerList = headers.getHeaderList(); 5359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (headerList != null) { 5369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly for (int i = 0; i < headerList.length; i++) { 5373998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.setHeader(headerList[i], headers.getHeader(headerList[i])); 5389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 54405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Retrieves the response code retrieved from the server. Response codes are 54505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * defined in the <code>ResponseCodes</code> interface. 5469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the response code retrieved from the server 5472e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an error occurred in the transport layer during 54805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * the transaction; if this method is called on a 54905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>HeaderSet</code> object created by calling 55005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>createHeaderSet</code> in a <code>ClientSession</code> 55105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * object; if this is called from a server 5529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public int getResponseCode() throws IOException { 5549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Called from a server"); 5559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Always returns <code>null</code> 5599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return <code>null</code> 5609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public String getEncoding() { 5629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return null; 5639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the type of content that the resource connected to is providing. 5679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * E.g. if the connection is via HTTP, then the value of the content-type 5689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * header field is returned. 5699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the content type of the resource that the URL references, or 57005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>null</code> if not known 5719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public String getType() { 5739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 5743998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return (String)requestHeader.getHeader(HeaderSet.TYPE); 5759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (IOException e) { 5769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return null; 5779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the length of the content which is being provided. E.g. if the 58205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * connection is via HTTP, then the value of the content-length header field 58305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * is returned. 5849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the content length of the resource that this connection's URL 58505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * references, or -1 if the content length is not known 5869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public long getLength() { 5889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 5893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun Long temp = (Long)requestHeader.getHeader(HeaderSet.LENGTH); 5909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (temp == null) { 5929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return -1; 5939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 5949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return temp.longValue(); 5959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (IOException e) { 5979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return -1; 5989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public int getMaxPacketSize() { 60265208317ba9d16486b47ebcaa868c596d424c87fLixin Yue return mMaxPacketLength - 6 - getHeaderLength(); 60365208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } 60465208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 60565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue public int getHeaderLength() { 60665208317ba9d16486b47ebcaa868c596d424c87fLixin Yue long id = mListener.getConnectionId(); 60765208317ba9d16486b47ebcaa868c596d424c87fLixin Yue if (id == -1) { 60865208317ba9d16486b47ebcaa868c596d424c87fLixin Yue replyHeader.mConnectionID = null; 60965208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } else { 61065208317ba9d16486b47ebcaa868c596d424c87fLixin Yue replyHeader.mConnectionID = ObexHelper.convertToByteArray(id); 61165208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } 61265208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 61365208317ba9d16486b47ebcaa868c596d424c87fLixin Yue byte[] headerArray = ObexHelper.createHeader(replyHeader, false); 61465208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 61565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue return headerArray.length; 6169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return an input stream for a connection. 6209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an input stream 6212e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 6229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public InputStream openInputStream() throws IOException { 6249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 6253998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mPrivateInput; 6269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return a data input stream for a connection. 6309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an input stream 6312e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 6329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public DataInputStream openDataInputStream() throws IOException { 6349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return new DataInputStream(openInputStream()); 6359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return an output stream for a connection. 6399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an output stream 6402e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 6419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public OutputStream openOutputStream() throws IOException { 6439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 6449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6453998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutputOpen) { 6469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("no more input streams available, stream already opened"); 6473998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 6489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6493998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mRequestFinished) { 6509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("no output streams available ,request not finished"); 6513998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 6529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6533998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput == null) { 65465208317ba9d16486b47ebcaa868c596d424c87fLixin Yue mPrivateOutput = new PrivateOutputStream(this, getMaxPacketSize()); 6559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6563998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutputOpen = true; 6573998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mPrivateOutput; 6589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return a data output stream for a connection. 6629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an output stream 6632e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 6649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public DataOutputStream openDataOutputStream() throws IOException { 6669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return new DataOutputStream(openOutputStream()); 6679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Closes the connection and ends the transaction 6712e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if the operation has already ended or is closed 6729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void close() throws IOException { 6749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 6753998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 6769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Verifies that the connection is open and no exceptions should be thrown. 6802e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an exception needs to be thrown 6819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void ensureOpen() throws IOException { 6833998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mExceptionString != null) { 6843998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun throw new IOException(mExceptionString); 6859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6863998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mClosed) { 6879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Operation has already ended"); 6889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 69205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Verifies that additional information may be sent. In other words, the 6939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * operation is not done. 6949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <P> 69505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Included to implement the BaseStream interface only. It does not do 6969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * anything on the server side since the operation of the Operation object 6979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * is not done until after the handler returns from its method. 6982e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if the operation is completed 6999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 7009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void ensureNotDone() throws IOException { 7019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 70405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Called when the output or input stream is closed. It does not do anything 70505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * on the server side since the operation of the Operation object is not 70605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * done until after the handler returns from its method. 7079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param inStream <code>true</code> if the input stream is closed; 70805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if the output stream is closed 7092e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 7109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 7119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void streamClosed(boolean inStream) throws IOException { 7129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly} 715