Commit ff759a48 authored by Jeff VanDyke's avatar Jeff VanDyke Committed by Jeff VanDyke

Fixed inability to serve static files greater than 140 KB

Added offset_ to BufferHolder so that retries would remember where they left off,
Fixed range of copying in struct Buffer so that large dynamic responses still work.
parent 00d065c3
...@@ -143,10 +143,11 @@ struct Buffer { ...@@ -143,10 +143,11 @@ struct Buffer {
if (fromIndex > len) if (fromIndex > len)
throw std::invalid_argument("Invalid index (> len)"); throw std::invalid_argument("Invalid index (> len)");
char *newData = new char[len - fromIndex]; size_t retainedLen = len - fromIndex;
std::copy(data + fromIndex, data + len - fromIndex, newData); char *newData = new char[retainedLen];
std::copy(data + fromIndex, data + len, newData);
return Buffer(newData, len, true); return Buffer(newData, retainedLen, true);
} }
const char* const data; const char* const data;
......
...@@ -87,23 +87,26 @@ private: ...@@ -87,23 +87,26 @@ private:
struct BufferHolder { struct BufferHolder {
enum Type { Raw, File }; enum Type { Raw, File };
explicit BufferHolder(const Buffer& buffer) explicit BufferHolder(const Buffer& buffer, off_t offset = 0)
: type(Raw) : type(Raw)
, u(buffer) , u(buffer)
{ {
offset_ = offset;
size_ = buffer.len; size_ = buffer.len;
} }
explicit BufferHolder(const FileBuffer& buffer) explicit BufferHolder(const FileBuffer& buffer, off_t offset = 0)
: type(File) : type(File)
, u(buffer.fd()) , u(buffer.fd())
{ {
offset_ = offset;
size_ = buffer.size(); size_ = buffer.size();
} }
bool isFile() const { return type == File; } bool isFile() const { return type == File; }
bool isRaw() const { return type == Raw; } bool isRaw() const { return type == Raw; }
size_t size() const { return size_; } size_t size() const { return size_; }
size_t offset() const { return offset_; }
Fd fd() const { Fd fd() const {
if (!isFile()) if (!isFile())
...@@ -122,19 +125,20 @@ private: ...@@ -122,19 +125,20 @@ private:
BufferHolder detach(size_t offset = 0) const { BufferHolder detach(size_t offset = 0) const {
if (!isRaw()) if (!isRaw())
return BufferHolder(u.fd, size_); return BufferHolder(u.fd, size_, offset);
if (u.raw.isOwned) if (u.raw.isOwned)
return BufferHolder(u.raw); return BufferHolder(u.raw, offset);
auto detached = u.raw.detach(offset); auto detached = u.raw.detach(offset);
return BufferHolder(detached); return BufferHolder(detached);
} }
private: private:
BufferHolder(Fd fd, size_t size) BufferHolder(Fd fd, size_t size, off_t offset = 0)
: u(fd) : u(fd)
, size_(size) , size_(size)
, offset_(offset)
, type(File) , type(File)
{ } { }
...@@ -145,7 +149,8 @@ private: ...@@ -145,7 +149,8 @@ private:
U(Buffer buffer) : raw(buffer) { } U(Buffer buffer) : raw(buffer) { }
U(Fd fd) : fd(fd) { } U(Fd fd) : fd(fd) { }
} u; } u;
size_t size_; size_t size_= 0;
off_t offset_ = 0;
Type type; Type type;
}; };
......
...@@ -193,7 +193,7 @@ Transport::asyncWriteImpl( ...@@ -193,7 +193,7 @@ Transport::asyncWriteImpl(
toWrite.erase(fd); toWrite.erase(fd);
}; };
ssize_t totalWritten = 0; ssize_t totalWritten = buffer.offset();
for (;;) { for (;;) {
ssize_t bytesWritten = 0; ssize_t bytesWritten = 0;
auto len = buffer.size() - totalWritten; auto len = buffer.size() - totalWritten;
...@@ -209,6 +209,7 @@ Transport::asyncWriteImpl( ...@@ -209,6 +209,7 @@ Transport::asyncWriteImpl(
if (bytesWritten < 0) { if (bytesWritten < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) { if (errno == EAGAIN || errno == EWOULDBLOCK) {
if (status == FirstTry) { if (status == FirstTry) {
toWrite.erase(fd);
toWrite.insert( toWrite.insert(
std::make_pair(fd, std::make_pair(fd,
WriteEntry(std::move(deferred), buffer.detach(totalWritten), flags))); WriteEntry(std::move(deferred), buffer.detach(totalWritten), flags)));
...@@ -224,11 +225,15 @@ Transport::asyncWriteImpl( ...@@ -224,11 +225,15 @@ Transport::asyncWriteImpl(
} }
else { else {
totalWritten += bytesWritten; totalWritten += bytesWritten;
if (totalWritten == len) { if (totalWritten >= buffer.size()) {
cleanUp(); cleanUp();
deferred.resolve(totalWritten); deferred.resolve(totalWritten);
break; break;
} }
else if (bytesWritten > 0)
{
status = FirstTry;
}
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment