proxygen
StaticService::StaticHandler Class Reference

#include <StaticHandler.h>

Inheritance diagram for StaticService::StaticHandler:
proxygen::RequestHandler

Public Member Functions

void onRequest (std::unique_ptr< proxygen::HTTPMessage > headers) noexceptoverride
 
void onBody (std::unique_ptr< folly::IOBuf > body) noexceptoverride
 
void onEOM () noexceptoverride
 
void onUpgrade (proxygen::UpgradeProtocol proto) noexceptoverride
 
void requestComplete () noexceptoverride
 
void onError (proxygen::ProxygenError err) noexceptoverride
 
void onEgressPaused () noexceptoverride
 
void onEgressResumed () noexceptoverride
 
- Public Member Functions inherited from proxygen::RequestHandler
virtual void setResponseHandler (ResponseHandler *handler) noexcept
 
virtual bool canHandleExpect () noexcept
 
virtual ExMessageHandlergetExHandler () noexcept
 
virtual ResponseHandlergetDownstream () noexcept
 
virtual ~RequestHandler ()
 

Private Member Functions

void readFile (folly::EventBase *evb)
 
bool checkForCompletion ()
 

Private Attributes

std::unique_ptr< folly::Filefile_
 
bool readFileScheduled_ {false}
 
std::atomic< bool > paused_ {false}
 
bool finished_ {false}
 

Additional Inherited Members

- Protected Attributes inherited from proxygen::RequestHandler
ResponseHandlerdownstream_ {nullptr}
 

Detailed Description

Definition at line 22 of file StaticHandler.h.

Member Function Documentation

bool StaticService::StaticHandler::checkForCompletion ( )
private

Definition at line 147 of file StaticHandler.cpp.

147  {
148  if (finished_ && !readFileScheduled_) {
149  VLOG(4) << "deleting StaticHandler";
150  delete this;
151  return true;
152  }
153  return false;
154 }
void StaticService::StaticHandler::onBody ( std::unique_ptr< folly::IOBuf body)
overridevirtualnoexcept

Invoked when we get part of body for the request.

Implements proxygen::RequestHandler.

Definition at line 124 of file StaticHandler.cpp.

124  {
125  // ignore, only support GET
126 }
void StaticService::StaticHandler::onEgressPaused ( )
overridevirtualnoexcept

Signals from HTTP layer when client queue is full or empty. If you are sending a streaming response, consider implementing these and acting accordingly. Saves your server from running out of memory.

Reimplemented from proxygen::RequestHandler.

Definition at line 103 of file StaticHandler.cpp.

103  {
104  // This will terminate readFile soon
105  VLOG(4) << "StaticHandler paused";
106  paused_ = true;
107 }
std::atomic< bool > paused_
Definition: StaticHandler.h:47
void StaticService::StaticHandler::onEgressResumed ( )
overridevirtualnoexcept

Reimplemented from proxygen::RequestHandler.

Definition at line 109 of file StaticHandler.cpp.

References folly::netops::bind(), folly::EventBaseManager::get(), folly::getCPUExecutor(), folly::getEventBase(), and folly::readFile().

109  {
110  VLOG(4) << "StaticHandler resumed";
111  paused_ = false;
112  // If readFileScheduled_, it will reschedule itself
113  if (!readFileScheduled_ && file_) {
114  readFileScheduled_ = true;
115  folly::getCPUExecutor()->add(
118  } else {
119  VLOG(4) << "Deferred scheduling readFile";
120  }
121 }
EventBase * getEventBase()
static EventBaseManager * get()
std::shared_ptr< Executor > getCPUExecutor()
int bind(NetworkSocket s, const sockaddr *name, socklen_t namelen)
Definition: NetOps.cpp:76
std::atomic< bool > paused_
Definition: StaticHandler.h:47
std::unique_ptr< folly::File > file_
Definition: StaticHandler.h:45
void readFile(folly::EventBase *evb)
void StaticService::StaticHandler::onEOM ( )
overridevirtualnoexcept

Invoked when we finish receiving the body.

Implements proxygen::RequestHandler.

Definition at line 128 of file StaticHandler.cpp.

128  {
129 }
void StaticService::StaticHandler::onError ( proxygen::ProxygenError  err)
overridevirtualnoexcept

Request failed. Maybe because of read/write error on socket or client not being able to send request in time.

NOTE: Can be invoked at any time (except for before onRequest).

No more callbacks will be invoked after this. You should clean up after yourself.

Implements proxygen::RequestHandler.

Definition at line 141 of file StaticHandler.cpp.

141  {
142  finished_ = true;
143  paused_ = true;
145 }
std::atomic< bool > paused_
Definition: StaticHandler.h:47
void StaticService::StaticHandler::onRequest ( std::unique_ptr< proxygen::HTTPMessage headers)
overridevirtualnoexcept

Handles requests by serving the file named in path. Only supports GET. reads happen in a CPU thread pool since read(2) is blocking. If egress pauses, file reading is also paused.

Implements proxygen::RequestHandler.

Definition at line 28 of file StaticHandler.cpp.

References folly::netops::bind(), proxygen::ResponseBuilder::body(), folly::exceptionStr(), proxygen::GET, folly::EventBaseManager::get(), folly::getCPUExecutor(), folly::getEventBase(), folly::readFile(), proxygen::ResponseBuilder::send(), proxygen::ResponseBuilder::sendWithEOM(), and proxygen::ResponseBuilder::status().

28  {
29  if (headers->getMethod() != HTTPMethod::GET) {
31  .status(400, "Bad method")
32  .body("Only GET is supported")
33  .sendWithEOM();
34  return;
35  }
36  // a real webserver would validate this path didn't contain malicious
37  // characters like '//' or '..'
38  try {
39  // + 1 to kill leading /
40  file_ = std::make_unique<folly::File>(headers->getPath().c_str() + 1);
41  } catch (const std::system_error& ex) {
43  .status(404, "Not Found")
44  .body(folly::to<std::string>("Could not find ", headers->getPath(),
45  " ex=", folly::exceptionStr(ex)))
46  .sendWithEOM();
47  return;
48  }
50  .status(200, "Ok")
51  .send();
52  // use a CPU executor since read(2) of a file can block
53  readFileScheduled_ = true;
54  folly::getCPUExecutor()->add(
57 }
ResponseBuilder & status(uint16_t code, const std::string &message)
const std::string & getPath() const
Definition: HTTPMessage.h:215
fbstring exceptionStr(const std::exception &e)
EventBase * getEventBase()
ResponseBuilder & body(std::unique_ptr< folly::IOBuf > bodyIn)
static EventBaseManager * get()
std::shared_ptr< Executor > getCPUExecutor()
int bind(NetworkSocket s, const sockaddr *name, socklen_t namelen)
Definition: NetOps.cpp:76
folly::Optional< HTTPMethod > getMethod() const
std::unique_ptr< folly::File > file_
Definition: StaticHandler.h:45
ResponseHandler * downstream_
void readFile(folly::EventBase *evb)
void StaticService::StaticHandler::onUpgrade ( proxygen::UpgradeProtocol  prot)
overridevirtualnoexcept

Invoked when the session has been upgraded to a different protocol

Implements proxygen::RequestHandler.

Definition at line 131 of file StaticHandler.cpp.

131  {
132  // handler doesn't support upgrades
133 }
void StaticService::StaticHandler::readFile ( folly::EventBase evb)
private

Definition at line 59 of file StaticHandler.cpp.

References proxygen::ResponseBuilder::body(), data, proxygen::ERROR, folly::IOBufQueue::move(), folly::gen::move, folly::IOBufQueue::postallocate(), folly::IOBufQueue::preallocate(), folly::readNoInt(), folly::EventBase::runInEventBaseThread(), proxygen::ResponseBuilder::send(), and proxygen::ResponseBuilder::sendWithEOM().

59  {
61  while (file_ && !paused_) {
62  // read 4k-ish chunks and foward each one to the client
63  auto data = buf.preallocate(4000, 4000);
64  auto rc = folly::readNoInt(file_->fd(), data.first, data.second);
65  if (rc < 0) {
66  // error
67  VLOG(4) << "Read error=" << rc;
68  file_.reset();
69  evb->runInEventBaseThread([this] {
70  LOG(ERROR) << "Error reading file";
72  });
73  break;
74  } else if (rc == 0) {
75  // done
76  file_.reset();
77  VLOG(4) << "Read EOF";
78  evb->runInEventBaseThread([this] {
80  .sendWithEOM();
81  });
82  break;
83  } else {
84  buf.postallocate(rc);
85  evb->runInEventBaseThread([this, body=buf.move()] () mutable {
87  .body(std::move(body))
88  .send();
89  });
90  }
91  }
92 
93  // Notify the request thread that we terminated the readFile loop
94  evb->runInEventBaseThread([this] {
95  readFileScheduled_ = false;
96  if (!checkForCompletion() && !paused_) {
97  VLOG(4) << "Resuming deferred readFile";
99  }
100  });
101 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
ssize_t readNoInt(int fd, void *buf, size_t count)
Definition: FileUtil.cpp:102
std::unique_ptr< folly::IOBuf > move()
Definition: IOBufQueue.h:459
ResponseBuilder & body(std::unique_ptr< folly::IOBuf > bodyIn)
std::pair< void *, std::size_t > preallocate(std::size_t min, std::size_t newAllocationSize, std::size_t max=std::numeric_limits< std::size_t >::max())
Definition: IOBufQueue.h:356
virtual void sendAbort() noexcept=0
void onEgressResumed() noexceptoverride
bool runInEventBaseThread(void(*fn)(T *), T *arg)
Definition: EventBase.h:794
std::atomic< bool > paused_
Definition: StaticHandler.h:47
std::unique_ptr< folly::File > file_
Definition: StaticHandler.h:45
void postallocate(std::size_t n)
Definition: IOBufQueue.h:380
ResponseHandler * downstream_
static constexpr uint64_t data[1]
Definition: Fingerprint.cpp:43
void StaticService::StaticHandler::requestComplete ( )
overridevirtualnoexcept

Invoked when request processing has been completed and nothing more needs to be done. This may be a good place to log some stats and clean up resources. This is distinct from onEOM() because it is invoked after the response is fully sent. Once this callback has been received, downstream_ should be considered invalid.

Implements proxygen::RequestHandler.

Definition at line 135 of file StaticHandler.cpp.

135  {
136  finished_ = true;
137  paused_ = true;
139 }
std::atomic< bool > paused_
Definition: StaticHandler.h:47

Member Data Documentation

std::unique_ptr<folly::File> StaticService::StaticHandler::file_
private

Definition at line 45 of file StaticHandler.h.

bool StaticService::StaticHandler::finished_ {false}
private

Definition at line 48 of file StaticHandler.h.

std::atomic<bool> StaticService::StaticHandler::paused_ {false}
private

Definition at line 47 of file StaticHandler.h.

bool StaticService::StaticHandler::readFileScheduled_ {false}
private

Definition at line 46 of file StaticHandler.h.


The documentation for this class was generated from the following files: