75
76
const size_t BUFSIZE = 16*1024;
78
DownloadCommand::DownloadCommand(cuid_t cuid,
79
const SharedHandle<Request>& req,
80
const SharedHandle<FileEntry>& fileEntry,
81
RequestGroup* requestGroup,
83
const SocketHandle& s):
84
AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
86
lowestDownloadSpeedLimit_(0),
87
pieceHashValidationEnabled_(false)
79
DownloadCommand::DownloadCommand
81
const SharedHandle<Request>& req,
82
const SharedHandle<FileEntry>& fileEntry,
83
RequestGroup* requestGroup,
85
const SocketHandle& s,
86
const SharedHandle<SocketRecvBuffer>& socketRecvBuffer)
87
: AbstractCommand(cuid, req, fileEntry, requestGroup, e, s, socketRecvBuffer),
89
lowestDownloadSpeedLimit_(0),
90
pieceHashValidationEnabled_(false)
89
92
#ifdef ENABLE_MESSAGE_DIGEST
124
128
const SharedHandle<DiskAdaptor>& diskAdaptor =
125
129
getPieceStorage()->getDiskAdaptor();
126
130
SharedHandle<Segment> segment = getSegments().front();
128
unsigned char buf[BUFSIZE];
129
if(sinkFilterOnly_) {
130
if(segment->getLength() > 0 ) {
131
if(static_cast<uint64_t>(segment->getPosition()+segment->getLength()) <=
132
static_cast<uint64_t>(getFileEntry()->getLastOffset())) {
133
bufSize = std::min(segment->getLength()-segment->getWrittenLength(),
132
if(getSocketRecvBuffer()->bufferEmpty()) {
133
// Only read from socket when buffer is empty. Imagine that When
134
// segment length is *short* and we are using HTTP pilelining. We
135
// issued 2 requests in pipeline. When reading first response
136
// header, we may read its response body and 2nd response header
137
// and 2nd response body in buffer if they are small enough to fit
138
// in buffer. And then server may sends EOF. In this case, we
139
// read data from socket here, we will get EOF and leaves 2nd
140
// response unprocessed. To prevent this, we don't read from
141
// socket when buffer is not empty.
142
eof = getSocketRecvBuffer()->recv() == 0 &&
143
!getSocket()->wantRead() && !getSocket()->wantWrite();
147
if(sinkFilterOnly_) {
148
if(segment->getLength() > 0) {
149
if(static_cast<uint64_t>(segment->getPosition()+segment->getLength()) <=
150
static_cast<uint64_t>(getFileEntry()->getLastOffset())) {
151
bufSize = std::min(segment->getLength()-segment->getWrittenLength(),
152
getSocketRecvBuffer()->getBufferLength());
157
(getFileEntry()->getLastOffset()-segment->getPositionToWrite()),
158
getSocketRecvBuffer()->getBufferLength());
139
(getFileEntry()->getLastOffset()-segment->getPositionToWrite()),
161
bufSize = getSocketRecvBuffer()->getBufferLength();
163
streamFilter_->transform(diskAdaptor, segment,
164
getSocketRecvBuffer()->getBuffer(), bufSize);
166
// It is possible that segment is completed but we have some bytes
167
// of stream to read. For example, chunked encoding has "0"+CRLF
168
// after data. After we read data(at this moment segment is
169
// completed), we need another 3bytes(or more if it has trailers).
170
streamFilter_->transform(diskAdaptor, segment,
171
getSocketRecvBuffer()->getBuffer(),
172
getSocketRecvBuffer()->getBufferLength());
173
bufSize = streamFilter_->getBytesProcessed();
145
getSocket()->readData(buf, bufSize);
146
streamFilter_->transform(diskAdaptor, segment, buf, bufSize);
148
// It is possible that segment is completed but we have some bytes
149
// of stream to read. For example, chunked encoding has "0"+CRLF
150
// after data. After we read data(at this moment segment is
151
// completed), we need another 3bytes(or more if it has trailers).
153
getSocket()->peekData(buf, bufSize);
154
streamFilter_->transform(diskAdaptor, segment, buf, bufSize);
155
bufSize = streamFilter_->getBytesProcessed();
156
getSocket()->readData(buf, bufSize);
175
getSocketRecvBuffer()->shiftBuffer(bufSize);
176
peerStat_->updateDownloadLength(bufSize);
158
peerStat_->updateDownloadLength(bufSize);
159
178
getSegmentMan()->updateDownloadSpeedFor(peerStat_);
160
179
bool segmentPartComplete = false;
161
180
// Note that GrowSegment::complete() always returns false.