00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #include "OW_config.h"
00037 #include "OW_HTTPChunkedIStream.hpp"
00038 #include "OW_HTTPUtils.hpp"
00039 #include "OW_HTTPException.hpp"
00040 #include "OW_CIMException.hpp"
00041 #include "OW_CIMErrorException.hpp"
00042
00043 namespace OW_NAMESPACE
00044 {
00045
00046 using std::istream;
00048 HTTPChunkedIStreamBuffer::HTTPChunkedIStreamBuffer(istream& istr,
00049 HTTPChunkedIStream* chunker)
00050 : BaseStreamBuffer(HTTP_BUF_SIZE, "in"), m_istr(istr),
00051 m_inLen(0), m_inPos(0), m_isEOF(false), m_pChunker(chunker)
00052 {
00053 }
00055 HTTPChunkedIStreamBuffer::~HTTPChunkedIStreamBuffer()
00056 {
00057 }
00059 int
00060 HTTPChunkedIStreamBuffer::buffer_from_device(char* c, int n)
00061 {
00062 if (m_isEOF || n < 0)
00063 {
00064 return -1;
00065 }
00066 unsigned int un = n;
00067 unsigned int tmpInLen = 0;
00068 unsigned int offset = 0;
00069 unsigned int lastRead = 0;
00070 while (offset < un && m_istr.good())
00071 {
00072 if (m_inLen == 0)
00073 {
00074 m_istr >> std::hex >> m_inLen >> std::dec;
00075 if (m_istr.fail() || m_istr.bad())
00076 {
00077 return -1;
00078 }
00079
00080
00081 while (m_istr.get() != '\n' && m_istr.good())
00082 {
00083
00084 }
00085
00086 m_inPos = 0;
00087 if (m_inLen == 0)
00088 {
00089
00090 m_isEOF = true;
00091 m_pChunker->buildTrailerMap();
00092 return offset;
00093 }
00094 }
00095
00096 tmpInLen = ((un - offset) < (m_inLen - m_inPos)) ? (un - offset)
00097 : (m_inLen - m_inPos);
00098 m_istr.read(c + offset, tmpInLen);
00099 lastRead = m_istr.gcount();
00100 offset += lastRead;
00101 m_inPos += lastRead;
00102 if (m_inPos == m_inLen)
00103 {
00104 m_inLen = 0;
00105 m_inPos = 0;
00106
00107
00108 }
00109 if (lastRead < tmpInLen)
00110 {
00111 break;
00112 }
00113 }
00114 return offset;
00115 }
00117 void
00118 HTTPChunkedIStreamBuffer::resetInput()
00119 {
00120 initGetBuffer();
00121 m_inLen = 0;
00122 m_inPos = 0;
00123 m_isEOF = false;
00124 }
00127 HTTPChunkedIStream::HTTPChunkedIStream(istream& istr)
00128 : HTTPChunkedIStreamBase(istr, this)
00129 , CIMProtocolIStreamIFC(&m_strbuf)
00130 , m_istr(istr)
00131 , m_trailerMap()
00132 {
00133 }
00135 HTTPChunkedIStream::~HTTPChunkedIStream()
00136 {
00137 }
00139 void
00140 HTTPChunkedIStream::resetInput()
00141 {
00142 clear();
00143 m_strbuf.resetInput();
00144 }
00146 void
00147 HTTPChunkedIStream::buildTrailerMap()
00148 {
00149 if (!HTTPUtils::parseHeader(m_trailerMap, m_istr))
00150 {
00151 m_trailerMap.clear();
00152 OW_THROW(HTTPException, "Error parsing trailers");
00153 }
00154 }
00156 String
00157 HTTPChunkedIStream::getTrailer(const String& key) const
00158 {
00159 for (Map<String, String>::const_iterator iter = m_trailerMap.begin();
00160 iter != m_trailerMap.end(); ++iter)
00161 {
00162 if (iter->first.substring(3).equalsIgnoreCase(key))
00163 {
00164 return iter->second;
00165 }
00166 }
00167 return String();
00168 }
00170
00171 void HTTPChunkedIStream::checkForError() const
00172 {
00173 String errorStr;
00174 errorStr = getTrailer("CIMError");
00175 if (!errorStr.empty())
00176 {
00177 OW_THROW(CIMErrorException, errorStr.c_str());
00178 }
00179 errorStr = getTrailer("CIMStatusCode");
00180 if (errorStr.empty())
00181 {
00182
00183 errorStr = getTrailer("CIMErrorCode");
00184 }
00185 if (!errorStr.empty())
00186 {
00187 String descr;
00188 descr = getTrailer("CIMStatusDescription");
00189 if (descr.empty())
00190 {
00191
00192 descr = getTrailer("CIMErrorDescription");
00193 }
00194 if (!descr.empty())
00195 {
00196 OW_THROWCIMMSG(CIMException::ErrNoType(errorStr.toInt32()),
00197 descr.c_str());
00198 }
00199 else
00200 {
00201 OW_THROWCIM(CIMException::ErrNoType(errorStr.toInt32()));
00202 }
00203 }
00204 }
00206
00207 }
00208