void XmlFetch::Read() { iDechunker.ReadFlush(); ReaderHttpResponse readerResponse(iCpStack.Env(), iReaderUntil); HttpHeaderContentLength headerContentLength; HttpHeaderTransferEncoding headerTransferEncoding; readerResponse.AddHeader(headerContentLength); readerResponse.AddHeader(headerTransferEncoding); readerResponse.Read(kResponseTimeoutMs); const HttpStatus& status = readerResponse.Status(); if (status != HttpStatus::kOk) { LOG2(kXmlFetch, kError, "XmlFetch::Read, http error %u ", status.Code()); LOG2(kXmlFetch, kError, status.Reason()); LOG2(kXmlFetch, kError, "\n"); SetError(Error::eHttp, status.Code(), status.Reason()); THROW(HttpError); } if (iCheckContactable) { iContactable = true; return; } WriterBwh writer(1024); static const TUint kMaxReadBytes = 4 * 1024; if (headerTransferEncoding.IsChunked()) { iDechunker.SetChunked(true); for (;;) { Brn buf = iDechunker.Read(kMaxReadBytes); writer.Write(buf); if (buf.Bytes() == 0) { // end of stream break; } } } else { TUint remaining = headerContentLength.ContentLength(); if (remaining == 0) { // no content length - read until connection closed by server try { for (;;) { writer.Write(iReaderUntil.Read(kMaxReadBytes)); } } catch (ReaderError&) { } } else { do { Brn buf = iReaderUntil.Read(kMaxReadBytes); remaining -= buf.Bytes(); writer.Write(buf); } while (remaining > 0); } } writer.TransferTo(iXml); }
void XmlFetch::Read(SocketTcpClient& aSocket) { Srd readBuffer(kRwBufferLength, aSocket); ReaderHttpResponse readerResponse(iCpStack.Env(), readBuffer); HttpHeaderContentLength headerContentLength; HttpHeaderTransferEncoding headerTransferEncoding; readerResponse.AddHeader(headerContentLength); readerResponse.AddHeader(headerTransferEncoding); readerResponse.Read(kResponseTimeoutMs); const HttpStatus& status = readerResponse.Status(); if (status != HttpStatus::kOk) { LOG2(kXmlFetch, kError, "XmlFetch::Read, http error %u ", status.Code()); LOG2(kXmlFetch, kError, status.Reason()); LOG2(kXmlFetch, kError, "\n"); SetError(Error::eHttp, status.Code(), status.Reason()); THROW(HttpError); } if (headerTransferEncoding.IsChunked()) { ReaderHttpChunked dechunker(readBuffer); dechunker.Read(); dechunker.TransferTo(iXml); } else { TUint remaining = headerContentLength.ContentLength(); if (remaining == 0) { // no content length - read until connection closed by server try { for (;;) { Brn buf = readBuffer.Read(kRwBufferLength); iXml.Grow(iXml.Bytes() + kRwBufferLength); iXml.Append(buf); } } catch (ReaderError&) { Brn snaffle = readBuffer.Snaffle(); iXml.Grow(iXml.Bytes() + snaffle.Bytes()); iXml.Append(snaffle); } } else { while (remaining > 0) { TInt readBytes = (remaining > kRwBufferLength ? kRwBufferLength : remaining); Brn buf = readBuffer.Read(readBytes); iXml.Grow(iXml.Bytes() + readBytes); iXml.Append(buf); remaining -= readBytes; } } } }
void InvocationUpnp::ReadResponse() { OutputProcessorUpnp outputProcessor; HttpHeaderContentLength headerContentLength; HttpHeaderTransferEncoding headerTransferEncoding; Bwh entity; iReaderResponse.AddHeader(headerContentLength); iReaderResponse.AddHeader(headerTransferEncoding); iReaderResponse.Read(kResponseTimeoutMs); const HttpStatus& status = iReaderResponse.Status(); if (status != HttpStatus::kOk) { LOG2(kService, kError, "InvocationUpnp::ReadResponse, http error %u ", status.Code()); LOG2(kService, kError, status.Reason()); LOG2(kService, kError, "\n"); if (status != HttpStatus::kInternalServerError) { iInvocation.SetError(Error::eHttp, status.Code(), status.Reason()); THROW(HttpError); } } if (headerTransferEncoding.IsChunked()) { ReaderHttpChunked dechunker(iReadBuffer); dechunker.Read(); dechunker.TransferTo(entity); } else { TUint length = headerContentLength.ContentLength(); if (length != 0) { Bwh buf(length); while (length > 0) { TUint readBytes = (length<kMaxReadBytes? length : kMaxReadBytes); buf.Append(iReadBuffer.Read(readBytes)); length -= readBytes; } buf.TransferTo(entity); } else { // no content length - read until connection closed by server try { for (;;) { Brn buf = iReadBuffer.Read(kMaxReadBytes); entity.Grow(entity.Bytes() + kMaxReadBytes); entity.Append(buf); } } catch (ReaderError&) { Brn snaffle = iReadBuffer.Snaffle(); entity.Grow(entity.Bytes() + snaffle.Bytes()); entity.Append(snaffle); } } } if (status == HttpStatus::kInternalServerError) { Brn envelope = XmlParserBasic::Find("Envelope", entity); Brn body = XmlParserBasic::Find("Body", envelope); Brn fault = XmlParserBasic::Find("Fault", body); Brn detail = XmlParserBasic::Find("detail", fault); Brn code = XmlParserBasic::Find("errorCode", detail); Brn description = XmlParserBasic::Find("errorDescription", detail); iInvocation.SetError(Error::eUpnp, Ascii::Uint(code), description); THROW(HttpError); } const Invocation::VectorArguments& outArgs = iInvocation.OutputArguments(); const TUint count = (TUint)outArgs.size(); Brn envelope = XmlParserBasic::Find("Envelope", entity); Brn body = XmlParserBasic::Find("Body", envelope); const Brn responseTagTrailer("Response"); const Brx& actionName = iInvocation.Action().Name(); TUint len = actionName.Bytes() + responseTagTrailer.Bytes(); Bwh responseTag(len); responseTag.Append(actionName); responseTag.Append(responseTagTrailer); Brn response = XmlParserBasic::Find(responseTag, body); for (TUint i=0; i<count; i++) { const Brx& name = outArgs[i]->Parameter().Name(); Brn value = XmlParserBasic::Find(name, response); outArgs[i]->ProcessOutput(outputProcessor, value); } }