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 91fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie private boolean mSendBodyHeader = true; 92fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie 939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 943998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun * Creates new ServerOperation 959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param p the parent that created this object 969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param in the input stream to read from 979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param out the output stream to write to 989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param request the initial request that was received from the client 999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param maxSize the max packet size that the client will accept 1009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param listen the listener that is responding to the request 1012e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 1029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public ServerOperation(ServerSession p, InputStream in, int request, int maxSize, 1049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ServerRequestHandler listen) throws IOException { 1059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly isAborted = false; 1073998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent = p; 1083998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mInput = in; 1093998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mMaxPacketLength = maxSize; 1103998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = false; 1113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader = new HeaderSet(); 1123998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader = new HeaderSet(); 1133998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput = new PrivateInputStream(this); 1143998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mResponseSize = 3; 1153998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener = listen; 1163998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mRequestFinished = false; 1173998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutputOpen = false; 1183998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mHasBody = false; 1199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bytesReceived; 1209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if this is a PUT request 1239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((request == 0x02) || (request == 0x82)) { 1259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * It is a PUT request. 1279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1283998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mGetOperation = false; 12965208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 13065208317ba9d16486b47ebcaa868c596d424c87fLixin Yue /* 13165208317ba9d16486b47ebcaa868c596d424c87fLixin Yue * Determine if the final bit is set 13265208317ba9d16486b47ebcaa868c596d424c87fLixin Yue */ 13365208317ba9d16486b47ebcaa868c596d424c87fLixin Yue if ((request & 0x80) == 0) { 13465208317ba9d16486b47ebcaa868c596d424c87fLixin Yue finalBitSet = false; 13565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } else { 13665208317ba9d16486b47ebcaa868c596d424c87fLixin Yue finalBitSet = true; 13765208317ba9d16486b47ebcaa868c596d424c87fLixin Yue mRequestFinished = true; 13865208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } 13965208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } else if ((request == 0x03) || (request == 0x83)) { 1409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * It is a GET request. 1429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1433998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mGetOperation = true; 1449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 14565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue // For Get request, final bit set is decided by server side logic 1469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly finalBitSet = false; 14765208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 14865208317ba9d16486b47ebcaa868c596d424c87fLixin Yue if (request == 0x83) { 14965208317ba9d16486b47ebcaa868c596d424c87fLixin Yue mRequestFinished = true; 15065208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } 1519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 15265208317ba9d16486b47ebcaa868c596d424c87fLixin Yue throw new IOException("ServerOperation can not handle such request"); 1539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int length = in.read(); 1569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly length = (length << 8) + in.read(); 1579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if the packet length is larger than this device can receive 1609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1612e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly if (length > ObexHelper.MAX_PACKET_SIZE_INT) { 1623998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null); 1639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Packet received was too large"); 1649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if any headers were sent in the initial request 1689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 3) { 1709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] data = new byte[length - 3]; 1719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly bytesReceived = in.read(data); 1729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != data.length) { 1749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly bytesReceived += in.read(data, bytesReceived, data.length - bytesReceived); 1759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1773998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] body = ObexHelper.updateHeaderSet(requestHeader, data); 1789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 1803998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mHasBody = true; 1819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 183e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun if (mListener.getConnectionId() != -1 && requestHeader.mConnectionID != null) { 1843998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(ObexHelper.convertToLong(requestHeader.mConnectionID)); 1859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 186e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun mListener.setConnectionId(1); 1879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthResp != null) { 1903998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mParent.handleAuthResp(requestHeader.mAuthResp)) { 1913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Authentication Failed"; 1923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null); 1933998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 1943998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 1959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return; 1969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1993998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthChall != null) { 2003998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.handleAuthChall(requestHeader); 2019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // send the authResp to the client 2023998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp = new byte[requestHeader.mAuthResp.length]; 2033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(requestHeader.mAuthResp, 0, replyHeader.mAuthResp, 0, 2043998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp.length); 2053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 2063998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthChall = null; 2079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 2113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput.writeBytes(body, 1); 2129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2133998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while ((!mGetOperation) && (!finalBitSet)) { 2143998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2153998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput.available() > 0) { 2169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 2179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2193998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 2203998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 2219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while ((!mGetOperation) && (!finalBitSet) && (mPrivateInput.available() == 0)) { 2233998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2243998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput.available() > 0) { 2259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 2269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // wait for get request finished !!!! 23065208317ba9d16486b47ebcaa868c596d424c87fLixin Yue while (mGetOperation && !mRequestFinished) { 2313998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2353998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public boolean isValidBody() { 2363998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mHasBody; 2379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 24005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Determines if the operation should continue or should wait. If it should 24105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * continue, this method will continue the operation. 2429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param sendEmpty if <code>true</code> then this will continue the 24305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * operation even if no headers will be sent; if <code>false</code> 24405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * then this method will only continue the operation if there are 24505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * headers to send 24605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param inStream if<code>true</code> the stream is input stream, otherwise 24705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * output stream 2489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return <code>true</code> if the operation was completed; 24905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if no operation took place 2509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream) 2529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throws IOException { 2533998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mGetOperation) { 2549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (!finalBitSet) { 2559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (sendEmpty) { 2563998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 2589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2593998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((mResponseSize > 3) || (mPrivateOutput.size() > 0)) { 2603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 2629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 2649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 2689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2703998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 2729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 27605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Sends a reply to the client. If the reply is a OBEX_HTTP_CONTINUE, it 2779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * will wait for a response from the client before ending. 2789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param type the response code to send back to the client 2799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return <code>true</code> if the final bit was not set on the reply; 28005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if no reply was received because the operation 28105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * ended, an abort was received, or the final bit was set in the 28205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * reply 2832e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 2849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2853998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public synchronized boolean sendReply(int type) throws IOException { 2869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ByteArrayOutputStream out = new ByteArrayOutputStream(); 2879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bytesReceived; 2889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun long id = mListener.getConnectionId(); 2909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (id == -1) { 2913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mConnectionID = null; 2929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2933998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mConnectionID = ObexHelper.convertToByteArray(id); 2949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2963998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] headerArray = ObexHelper.createHeader(replyHeader, true); 2979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bodyLength = -1; 2989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int orginalBodyLength = -1; 2999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3003998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput != null) { 3013998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bodyLength = mPrivateOutput.size(); 3029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly orginalBodyLength = bodyLength; 3039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((ObexHelper.BASE_PACKET_LENGTH + headerArray.length) > mMaxPacketLength) { 3069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int end = 0; 3089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int start = 0; 3099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (end != headerArray.length) { 3113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun end = ObexHelper.findHeaderEnd(headerArray, start, mMaxPacketLength 3123998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun - ObexHelper.BASE_PACKET_LENGTH); 3139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (end == -1) { 3149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3153998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 3169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3173998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput != null) { 3183998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput.close(); 3199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3213998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput != null) { 3223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutput.close(); 3239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3243998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); 3259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("OBEX Packet exceeds max packet size"); 3269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] sendHeader = new byte[end - start]; 3289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length); 3299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3303998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(type, sendHeader); 3319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly start = end; 3329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (bodyLength > 0) { 3359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 3369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 3379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 3389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 3419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(headerArray); 3429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 34465208317ba9d16486b47ebcaa868c596d424c87fLixin Yue // For Get operation: if response code is OBEX_HTTP_OK, then this is the 34565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue // last packet; so set finalBitSet to true. 34665208317ba9d16486b47ebcaa868c596d424c87fLixin Yue if (mGetOperation && type == ResponseCodes.OBEX_HTTP_OK) { 34765208317ba9d16486b47ebcaa868c596d424c87fLixin Yue finalBitSet = true; 34865208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } 34965208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 3503998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((finalBitSet) || (headerArray.length < (mMaxPacketLength - 20))) { 3519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (bodyLength > 0) { 3529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 3539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if I can send the whole body or just part of 3549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * the body. Remember that there is the 3 bytes for the 3559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * response message and 3 bytes for the header ID and length 3569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3573998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (bodyLength > (mMaxPacketLength - headerArray.length - 6)) { 3583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bodyLength = mMaxPacketLength - headerArray.length - 6; 3599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3613998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] body = mPrivateOutput.readBytes(bodyLength); 3629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 3649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Since this is a put request if the final bit is set or 3659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * the output stream is closed we need to send the 0x49 3669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * (End of Body) otherwise, we need to send 0x48 (Body) 3679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3683998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((finalBitSet) || (mPrivateOutput.isClosed())) { 369fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie if(mSendBodyHeader == true) { 370fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie out.write(0x49); 371fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie bodyLength += 3; 372fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie out.write((byte)(bodyLength >> 8)); 373fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie out.write((byte)bodyLength); 374fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie out.write(body); 375fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie } 3769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 377fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie if(mSendBodyHeader == true) { 3789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x48); 379fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie bodyLength += 3; 380fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie out.write((byte)(bodyLength >> 8)); 381fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie out.write((byte)bodyLength); 382fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie out.write(body); 383fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie } 3849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((finalBitSet) && (type == ResponseCodes.OBEX_HTTP_OK) && (orginalBodyLength <= 0)) { 390fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie if(mSendBodyHeader == true) { 391fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie out.write(0x49); 392fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie orginalBodyLength = 3; 393fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie out.write((byte)(orginalBodyLength >> 8)); 394fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie out.write((byte)orginalBodyLength); 395fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie } 3969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3983998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mResponseSize = 3; 3993998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(type, out.toByteArray()); 4009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4013998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (type == ResponseCodes.OBEX_HTTP_CONTINUE) { 4023998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun int headerID = mInput.read(); 4033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun int length = mInput.read(); 4043998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun length = (length << 8) + mInput.read(); 4053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((headerID != ObexHelper.OBEX_OPCODE_PUT) 4063998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun && (headerID != ObexHelper.OBEX_OPCODE_PUT_FINAL) 4073998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun && (headerID != ObexHelper.OBEX_OPCODE_GET) 4083998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun && (headerID != ObexHelper.OBEX_OPCODE_GET_FINAL)) { 4099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 3) { 4114507b177c35cfd918dba1cdc325fae3688fb7bd2Anders Petersson byte[] temp = new byte[length - 3]; 4124507b177c35cfd918dba1cdc325fae3688fb7bd2Anders Petersson // First three bytes already read, compensating for this 4133998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived = mInput.read(temp); 4149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4154507b177c35cfd918dba1cdc325fae3688fb7bd2Anders Petersson while (bytesReceived != temp.length) { 4164507b177c35cfd918dba1cdc325fae3688fb7bd2Anders Petersson bytesReceived += mInput.read(temp, bytesReceived, 4174507b177c35cfd918dba1cdc325fae3688fb7bd2Anders Petersson temp.length - bytesReceived); 4189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if an ABORT was sent as the reply 4239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4243998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (headerID == ObexHelper.OBEX_OPCODE_ABORT) { 4253998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_OK, null); 4263998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 4279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly isAborted = true; 4283998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Abort Received"; 4299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Abort Received"); 4309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4313998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_BAD_REQUEST, null); 4323998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 4333998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Bad Request Received"; 4349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Bad Request Received"); 4359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 43865208317ba9d16486b47ebcaa868c596d424c87fLixin Yue if ((headerID == ObexHelper.OBEX_OPCODE_PUT_FINAL)) { 4399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly finalBitSet = true; 44065208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } else if (headerID == ObexHelper.OBEX_OPCODE_GET_FINAL) { 44165208317ba9d16486b47ebcaa868c596d424c87fLixin Yue mRequestFinished = true; 4429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if the packet length is larger then this device can receive 4469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4472e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly if (length > ObexHelper.MAX_PACKET_SIZE_INT) { 4483998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null); 4499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Packet received was too large"); 4509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if any headers were sent in the initial request 4549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 3) { 4569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] data = new byte[length - 3]; 4573998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived = mInput.read(data); 4589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != data.length) { 4603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived += mInput.read(data, bytesReceived, data.length 4619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly - bytesReceived); 4629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4633998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] body = ObexHelper.updateHeaderSet(requestHeader, data); 4649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 4653998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mHasBody = true; 4669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 467e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun if (mListener.getConnectionId() != -1 && requestHeader.mConnectionID != null) { 4683998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(ObexHelper 4693998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun .convertToLong(requestHeader.mConnectionID)); 4709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4713998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(1); 4729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4743998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthResp != null) { 4753998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mParent.handleAuthResp(requestHeader.mAuthResp)) { 4763998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionString = "Authentication Failed"; 4773998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null); 4783998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 4793998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 4809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 4819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4823998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 4839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4853998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (requestHeader.mAuthChall != null) { 4863998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.handleAuthChall(requestHeader); 4879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // send the auhtResp to the client 4883998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp = new byte[requestHeader.mAuthResp.length]; 4893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(requestHeader.mAuthResp, 0, replyHeader.mAuthResp, 0, 4903998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.mAuthResp.length); 4913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthResp = null; 4923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun requestHeader.mAuthChall = null; 4939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 4963998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput.writeBytes(body, 1); 4979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 5019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 5029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 5039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 50705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Sends an ABORT message to the server. By calling this method, the 5089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * corresponding input and output streams will be closed along with this 5099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * object. 51005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if the transaction has already ended or if an OBEX 51105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * server called this method 5129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void abort() throws IOException { 5149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Called from a server"); 5159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the headers that have been received during the operation. 51905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Modifying the object returned has no effect on the headers that are sent 52005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * or retrieved. 5219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the headers received during this <code>Operation</code> 5222e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if this <code>Operation</code> has been closed 5239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5243998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public HeaderSet getReceivedHeader() throws IOException { 5259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 5263998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return requestHeader; 5279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Specifies the headers that should be sent in the next OBEX message that 5319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * is sent. 5329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param headers the headers to send in the next message 53305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if this <code>Operation</code> has been closed or the 53405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * transaction has ended and no further messages will be exchanged 5352e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IllegalArgumentException if <code>headers</code> was not created 53605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * by a call to <code>ServerRequestHandler.createHeaderSet()</code> 5379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void sendHeaders(HeaderSet headers) throws IOException { 5399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 5409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (headers == null) { 5423998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun throw new IOException("Headers may not be null"); 5439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int[] headerList = headers.getHeaderList(); 5469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (headerList != null) { 5479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly for (int i = 0; i < headerList.length; i++) { 5483998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun replyHeader.setHeader(headerList[i], headers.getHeader(headerList[i])); 5499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 55505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Retrieves the response code retrieved from the server. Response codes are 55605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * defined in the <code>ResponseCodes</code> interface. 5579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the response code retrieved from the server 5582e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an error occurred in the transport layer during 55905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * the transaction; if this method is called on a 56005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>HeaderSet</code> object created by calling 56105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>createHeaderSet</code> in a <code>ClientSession</code> 56205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * object; if this is called from a server 5639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public int getResponseCode() throws IOException { 5659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Called from a server"); 5669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Always returns <code>null</code> 5709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return <code>null</code> 5719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public String getEncoding() { 5739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return null; 5749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the type of content that the resource connected to is providing. 5789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * E.g. if the connection is via HTTP, then the value of the content-type 5799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * header field is returned. 5809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the content type of the resource that the URL references, or 58105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>null</code> if not known 5829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public String getType() { 5849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 5853998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return (String)requestHeader.getHeader(HeaderSet.TYPE); 5869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (IOException e) { 5879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return null; 5889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the length of the content which is being provided. E.g. if the 59305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * connection is via HTTP, then the value of the content-length header field 59405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * is returned. 5959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the content length of the resource that this connection's URL 59605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * references, or -1 if the content length is not known 5979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public long getLength() { 5999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 6003998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun Long temp = (Long)requestHeader.getHeader(HeaderSet.LENGTH); 6019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (temp == null) { 6039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return -1; 6049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 6059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return temp.longValue(); 6069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (IOException e) { 6089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return -1; 6099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public int getMaxPacketSize() { 61365208317ba9d16486b47ebcaa868c596d424c87fLixin Yue return mMaxPacketLength - 6 - getHeaderLength(); 61465208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } 61565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 61665208317ba9d16486b47ebcaa868c596d424c87fLixin Yue public int getHeaderLength() { 61765208317ba9d16486b47ebcaa868c596d424c87fLixin Yue long id = mListener.getConnectionId(); 61865208317ba9d16486b47ebcaa868c596d424c87fLixin Yue if (id == -1) { 61965208317ba9d16486b47ebcaa868c596d424c87fLixin Yue replyHeader.mConnectionID = null; 62065208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } else { 62165208317ba9d16486b47ebcaa868c596d424c87fLixin Yue replyHeader.mConnectionID = ObexHelper.convertToByteArray(id); 62265208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } 62365208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 62465208317ba9d16486b47ebcaa868c596d424c87fLixin Yue byte[] headerArray = ObexHelper.createHeader(replyHeader, false); 62565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 62665208317ba9d16486b47ebcaa868c596d424c87fLixin Yue return headerArray.length; 6279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return an input stream for a connection. 6319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an input stream 6322e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 6339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public InputStream openInputStream() throws IOException { 6359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 6363998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mPrivateInput; 6379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return a data input stream for a connection. 6419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an input stream 6422e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 6439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public DataInputStream openDataInputStream() throws IOException { 6459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return new DataInputStream(openInputStream()); 6469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return an output stream for a connection. 6509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an output stream 6512e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 6529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public OutputStream openOutputStream() throws IOException { 6549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 6559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6563998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutputOpen) { 6579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("no more input streams available, stream already opened"); 6583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 6599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mRequestFinished) { 6619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("no output streams available ,request not finished"); 6623998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } 6639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6643998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput == null) { 66565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue mPrivateOutput = new PrivateOutputStream(this, getMaxPacketSize()); 6669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6673998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutputOpen = true; 6683998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mPrivateOutput; 6699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return a data output stream for a connection. 6739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an output stream 6742e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 6759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public DataOutputStream openDataOutputStream() throws IOException { 6779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return new DataOutputStream(openOutputStream()); 6789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Closes the connection and ends the transaction 6822e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if the operation has already ended or is closed 6839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void close() throws IOException { 6859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 6863998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 6879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Verifies that the connection is open and no exceptions should be thrown. 6912e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an exception needs to be thrown 6929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void ensureOpen() throws IOException { 6943998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mExceptionString != null) { 6953998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun throw new IOException(mExceptionString); 6969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6973998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mClosed) { 6989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Operation has already ended"); 6999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 70305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Verifies that additional information may be sent. In other words, the 7049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * operation is not done. 7059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <P> 70605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Included to implement the BaseStream interface only. It does not do 7079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * anything on the server side since the operation of the Operation object 7089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * is not done until after the handler returns from its method. 7092e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if the operation is completed 7109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 7119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void ensureNotDone() throws IOException { 7129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 71505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Called when the output or input stream is closed. It does not do anything 71605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * on the server side since the operation of the Operation object is not 71705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * done until after the handler returns from its method. 7189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param inStream <code>true</code> if the input stream is closed; 71905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if the output stream is closed 7202e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 7219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 7229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void streamClosed(boolean inStream) throws IOException { 7239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 725fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie 726fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie public void noBodyHeader(){ 727fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie mSendBodyHeader = false; 728fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie } 7299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly} 730