qint64 QHttpNetworkReplyPrivate::readBody(QAbstractSocket *socket, QByteDataBuffer *out) { qint64 bytes = 0; if (isChunked()) { bytes += readReplyBodyChunked(socket, out); // chunked transfer encoding (rfc 2616, sec 3.6) } else if (bodyLength > 0) { // we have a Content-Length bytes += readReplyBodyRaw(socket, out, bodyLength - contentRead); if (contentRead + bytes == bodyLength) state = AllDoneState; } else { bytes += readReplyBodyRaw(socket, out, socket->bytesAvailable()); } contentRead += bytes; return bytes; }
qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QIODevice *in, QByteDataBuffer *out) { qint64 bytes = 0; while (in->bytesAvailable()) { // while we can read from input // if we are done with the current chunk, get the size of the new chunk if (currentChunkRead >= currentChunkSize) { currentChunkSize = 0; currentChunkRead = 0; if (bytes) { char crlf[2]; bytes += in->read(crlf, 2); // read the "\r\n" after the chunk } bytes += getChunkSize(in, ¤tChunkSize); if (currentChunkSize == -1) break; } // if the chunk size is 0, end of the stream if (currentChunkSize == 0) { state = AllDoneState; break; } // otherwise, try to read what is missing for this chunk qint64 haveRead = readReplyBodyRaw (in, out, currentChunkSize - currentChunkRead); currentChunkRead += haveRead; bytes += haveRead; // ### error checking here } return bytes; }
qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QAbstractSocket *socket, QByteDataBuffer *out) { qint64 bytes = 0; while (socket->bytesAvailable()) { if (currentChunkRead >= currentChunkSize) { // For the first chunk and when we're done with a chunk currentChunkSize = 0; currentChunkRead = 0; if (bytes) { // After a chunk char crlf[2]; // read the "\r\n" after the chunk qint64 haveRead = socket->read(crlf, 2); // FIXME: This code is slightly broken and not optimal. What if the 2 bytes are not available yet?! // For nice reasons (the toLong in getChunkSize accepting \n at the beginning // it right now still works, but we should definitely fix this. if (haveRead != 2) return bytes; // FIXME bytes += haveRead; } // Note that chunk size gets stored in currentChunkSize, what is returned is the bytes read bytes += getChunkSize(socket, ¤tChunkSize); if (currentChunkSize == -1) break; } // if the chunk size is 0, end of the stream if (currentChunkSize == 0) { state = AllDoneState; break; } // otherwise, try to begin reading this chunk / to read what is missing for this chunk qint64 haveRead = readReplyBodyRaw (socket, out, currentChunkSize - currentChunkRead); currentChunkRead += haveRead; bytes += haveRead; // ### error checking here } return bytes; }
qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QAbstractSocket *socket, QByteDataBuffer *out) { qint64 bytes = 0; while (socket->bytesAvailable()) { if (readBufferMaxSize && (bytes > readBufferMaxSize)) break; if (!lastChunkRead && currentChunkRead >= currentChunkSize) { // For the first chunk and when we're done with a chunk currentChunkSize = 0; currentChunkRead = 0; if (bytes) { // After a chunk char crlf[2]; // read the "\r\n" after the chunk qint64 haveRead = socket->read(crlf, 2); // FIXME: This code is slightly broken and not optimal. What if the 2 bytes are not available yet?! // For nice reasons (the toLong in getChunkSize accepting \n at the beginning // it right now still works, but we should definitely fix this. if (haveRead != 2) return bytes; // FIXME bytes += haveRead; } // Note that chunk size gets stored in currentChunkSize, what is returned is the bytes read bytes += getChunkSize(socket, ¤tChunkSize); if (currentChunkSize == -1) break; } // if the chunk size is 0, end of the stream if (currentChunkSize == 0 || lastChunkRead) { lastChunkRead = true; // try to read the "\r\n" after the chunk char crlf[2]; qint64 haveRead = socket->read(crlf, 2); if (haveRead > 0) bytes += haveRead; if ((haveRead == 2 && crlf[0] == '\r' && crlf[1] == '\n') || (haveRead == 1 && crlf[0] == '\n')) state = AllDoneState; else if (haveRead == 1 && crlf[0] == '\r') break; // Still waiting for the last \n else if (haveRead > 0) { // If we read something else then CRLF, we need to close the channel. forceConnectionCloseEnabled = true; state = AllDoneState; } break; } // otherwise, try to begin reading this chunk / to read what is missing for this chunk qint64 haveRead = readReplyBodyRaw (socket, out, currentChunkSize - currentChunkRead); currentChunkRead += haveRead; bytes += haveRead; // ### error checking here } return bytes; }