MCPcopy Create free account
hub / github.com/3rdparty/libprocess / sendfile

Function sendfile

src/http.cpp:1589–1653  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1587
1588
1589Future<Nothing> sendfile(
1590 network::Socket socket,
1591 Response response,
1592 Request* request)
1593{
1594 CHECK(response.type == Response::PATH);
1595
1596 // Make sure no body is sent (this is really an error and
1597 // should be reported and no response sent.
1598 response.body.clear();
1599
1600 Try<int_fd> fd = os::open(response.path, O_CLOEXEC | O_NONBLOCK | O_RDONLY);
1601
1602 if (fd.isError()) {
1603 const string body = "Failed to open '" + response.path + "': " + fd.error();
1604 // TODO(benh): VLOG(1)?
1605 // TODO(benh): Don't send error back as part of InternalServiceError?
1606 // TODO(benh): Copy headers from `response`?
1607 return send(socket, InternalServerError(body), request);
1608 }
1609
1610 const Try<Bytes> size = os::stat::size(fd.get());
1611 if (size.isError()) {
1612 const string body =
1613 "Failed to fstat '" + response.path + "': " + size.error();
1614 // TODO(benh): VLOG(1)?
1615 // TODO(benh): Don't send error back as part of InternalServiceError?
1616 // TODO(benh): Copy headers from `response`?
1617 os::close(fd.get());
1618 return send(socket, InternalServerError(body), request);
1619 } else if (os::stat::isdir(fd.get())) {
1620 const string body = "'" + response.path + "' is a directory";
1621 // TODO(benh): VLOG(1)?
1622 // TODO(benh): Don't send error back as part of InternalServiceError?
1623 // TODO(benh): Copy headers from `response`?
1624 os::close(fd.get());
1625 return send(socket, InternalServerError(body), request);
1626 }
1627
1628 // While the user is expected to properly set a 'Content-Type'
1629 // header, we'll fill in (or overwrite) 'Content-Length' header.
1630 response.headers["Content-Length"] = stringify(size->bytes());
1631
1632 // TODO(benh): If this is a TCP socket consider turning on TCP_CORK
1633 // for both sends and then turning it off.
1634 Encoder* encoder = new HttpResponseEncoder(response, *request);
1635
1636 return send(socket, encoder)
1637 .onAny([=](const Future<Nothing>& future) {
1638 delete encoder;
1639
1640 // Close file descriptor if we aren't doing any more sending.
1641 if (future.isDiscarded() || future.isFailed()) {
1642 os::close(fd.get());
1643 }
1644 })
1645 .then([=]() mutable -> Future<Nothing> {
1646 // NOTE: the file descriptor gets closed by FileEncoder.

Callers 1

sendFunction · 0.70

Calls 7

InternalServerErrorClass · 0.85
closeFunction · 0.85
isDiscardedMethod · 0.80
isFailedMethod · 0.80
sendFunction · 0.70
getMethod · 0.45
thenMethod · 0.45

Tested by

no test coverage detected