how to transfers files from client to servers
liwenhui-soul opened this issue · comments
my code is like this:
class SendFileClient : public proxygen::HTTPConnector::Callback,
public proxygen::HTTPTransactionHandler{
void connectSuccess(proxygen::HTTPUpstreamSession* session) override{
proxygen::HTTPTransaction* txn = session->newTransaction(this);
proxygen::HTTPMessage request;
request_.setMethod(proxygen::HTTPMethod::PUT);
request_.setURL(url_.makeRelativeURL());
request_.setSecure(false);
if (!request_.getHeaders().getNumberOfValues(proxygen::HTTP_HEADER_USER_AGENT)) {
request_.getHeaders().add(proxygen::HTTP_HEADER_USER_AGENT, "proxygen_curl");
}
if (!request_.getHeaders().getNumberOfValues(proxygen::HTTP_HEADER_HOST)) {
request_.getHeaders().add(proxygen::HTTP_HEADER_HOST, url_.getHostAndPort());
}
if (!request_.getHeaders().getNumberOfValues(proxygen::HTTP_HEADER_ACCEPT)) {
request_.getHeaders().add("Accept", "*/*");
}
txn_->sendHeaders(request_);
const uint16_t kReadSize = 4096;
int32_t fd = ::open("/tmp/sendFile", O_RDWR);
while (true) {
std::unique_ptr<folly::IOBuf> buf = folly::IOBuf::createCombined(kReadSize);
int32_t len = ::read(fd, reinterpret_cast<char*>(buf->writableData()), kReadSize);
if (len) {
buf->append(len);
txn_->sendBody(std::move(buf));
} else {
txn_->sendEOM();
break;
}
}
::close(fd);
}
}
class RecvFilesHandler : public proxygen::RequestHandler{
void onRequest(std::unique_ptr<proxygen::HTTPMessage> headers) noexcept override{
fd_ = ::open("/tmp/recvFile", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
}
void onBody(std::unique_ptr<folly::IOBuf> body) noexcept override{
ssize_t bytesWritten = ::write(fd_, body->data(), body->length());
}
void onEOM() noexcept override{
::close(fd_);
}
int fd_;
}
In my test, the RecvFilesHandler could receive headers, but can't receive the body. Did I miss something?
I don't think you want to read from the disk in the same thread where you are sending. The network IO thread should not block.
There's an example of what you are trying to do here:
https://github.com/facebook/proxygen/blob/main/proxygen/httpclient/samples/curl/CurlClient.cpp#L203
Though it has the same "calling read in the io thread problem, as noted by the comment".
The Static example HTTP server is correctly using a CPU thread to do the disk read here: https://github.com/facebook/proxygen/blob/main/proxygen/httpserver/samples/static/StaticHandler.cpp#L54
Note that server is an example and is not safe to run as an actual file server because (at a minimum) it doesn't validate the path properly.