mirror of
https://github.com/drogonframework/drogon.git
synced 2025-09-22 00:00:33 -04:00
Modify the newFileResponse method
This commit is contained in:
parent
77c8e8a296
commit
075e3cc6b3
@ -49,6 +49,6 @@ void Attachment::upload(const HttpRequestPtr &req,
|
||||
void Attachment::download(const HttpRequestPtr &req,
|
||||
const std::function<void(const HttpResponsePtr &)> &callback)
|
||||
{
|
||||
auto resp = HttpResponse::newFileResponse("./drogon.jpg");
|
||||
auto resp = HttpResponse::newFileResponse("./drogon.jpg", "", CT_IMAGE_JPG);
|
||||
callback(resp);
|
||||
}
|
||||
|
@ -111,8 +111,8 @@ int main()
|
||||
app().registerHttpMethod("/api/v1/handle11/{1}/{2}/?p3={3}&p4={4}", &A::staticHandle);
|
||||
//lambda example
|
||||
app().registerHttpMethod("/api/v1/handle2/{1}/{2}", [](const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback, int a, float b) {
|
||||
LOG_DEBUG << "int a=" << a;
|
||||
LOG_DEBUG << "float b=" << b;
|
||||
// LOG_DEBUG << "int a=" << a;
|
||||
// LOG_DEBUG << "float b=" << b;
|
||||
HttpViewData data;
|
||||
data.insert("title", std::string("ApiTest::get"));
|
||||
std::map<std::string, std::string> para;
|
||||
|
@ -449,12 +449,40 @@ void doTest(const HttpClientPtr &client, std::promise<int> &pro)
|
||||
req = HttpRequest::newHttpRequest();
|
||||
req->setMethod(drogon::Get);
|
||||
req->setPath("/drogon.jpg");
|
||||
client->sendRequest(req, [=](ReqResult result, const HttpResponsePtr &resp) {
|
||||
client->sendRequest(req, [=, &pro](ReqResult result, const HttpResponsePtr &resp) {
|
||||
if (result == ReqResult::Ok)
|
||||
{
|
||||
if (resp->getBody().length() == 51822)
|
||||
{
|
||||
outputGood(req);
|
||||
auto lastModified = resp->getHeader("last-modified");
|
||||
//LOG_DEBUG << lastModified;
|
||||
// Test 'Not Modified'
|
||||
auto req = HttpRequest::newHttpRequest();
|
||||
req->setMethod(drogon::Get);
|
||||
req->setPath("/drogon.jpg");
|
||||
req->addHeader("If-Modified-Since", lastModified);
|
||||
client->sendRequest(req, [=, &pro](ReqResult result, const HttpResponsePtr &resp) {
|
||||
if (result == ReqResult::Ok)
|
||||
{
|
||||
if (resp->statusCode() == k304NotModified)
|
||||
{
|
||||
outputGood(req);
|
||||
pro.set_value(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG << resp->getBody().length();
|
||||
LOG_ERROR << "Error!";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR << "Error!";
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -526,13 +554,12 @@ void doTest(const HttpClientPtr &client, std::promise<int> &pro)
|
||||
req = HttpRequest::newHttpRequest();
|
||||
req->setMethod(drogon::Get);
|
||||
req->setPath("/api/attachment/download");
|
||||
client->sendRequest(req, [=, &pro](ReqResult result, const HttpResponsePtr &resp) {
|
||||
client->sendRequest(req, [=](ReqResult result, const HttpResponsePtr &resp) {
|
||||
if (result == ReqResult::Ok)
|
||||
{
|
||||
if (resp->getBody().length() == 51822)
|
||||
{
|
||||
outputGood(req);
|
||||
pro.set_value(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -73,6 +73,9 @@ class HttpClient : public trantor::NonCopyable
|
||||
uint16_t port,
|
||||
bool useSSL = false,
|
||||
trantor::EventLoop *loop = nullptr);
|
||||
|
||||
/// Get the event loop of the client;
|
||||
virtual trantor::EventLoop *loop() = 0;
|
||||
|
||||
/// Use hostString to connect to server
|
||||
/**
|
||||
|
@ -92,7 +92,7 @@ class HttpResponse
|
||||
static HttpResponsePtr newHttpJsonResponse(const Json::Value &data);
|
||||
static HttpResponsePtr newHttpViewResponse(const std::string &viewName, const HttpViewData &data = HttpViewData());
|
||||
static HttpResponsePtr newLocationRedirectResponse(const std::string &path);
|
||||
static HttpResponsePtr newFileResponse(const std::string &fullPath, const std::string &attachmentFileName = "", bool asAttachment = true);
|
||||
static HttpResponsePtr newFileResponse(const std::string &fullPath, const std::string &attachmentFileName = "", ContentType type = CT_NONE);
|
||||
|
||||
virtual ~HttpResponse() {}
|
||||
};
|
||||
|
@ -70,7 +70,8 @@ enum Version
|
||||
|
||||
enum ContentType
|
||||
{
|
||||
CT_APPLICATION_JSON = 0,
|
||||
CT_NONE = 0,
|
||||
CT_APPLICATION_JSON,
|
||||
CT_TEXT_PLAIN,
|
||||
CT_TEXT_HTML,
|
||||
CT_APPLICATION_X_FORM,
|
||||
|
@ -692,7 +692,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu
|
||||
callback(cachedResp);
|
||||
return;
|
||||
}
|
||||
auto resp = HttpResponse::newFileResponse(filePath, "", false);
|
||||
auto resp = HttpResponse::newFileResponse(filePath);
|
||||
if (!timeStr.empty())
|
||||
{
|
||||
resp->addHeader("Last-Modified", timeStr);
|
||||
|
@ -28,6 +28,7 @@ class HttpClientImpl : public HttpClient, public std::enable_shared_from_this<Ht
|
||||
HttpClientImpl(trantor::EventLoop *loop, const std::string &hostString);
|
||||
virtual void sendRequest(const HttpRequestPtr &req, const HttpReqCallback &callback) override;
|
||||
virtual void sendRequest(const HttpRequestPtr &req, HttpReqCallback &&callback) override;
|
||||
virtual trantor::EventLoop *loop() override { return _loop; }
|
||||
~HttpClientImpl();
|
||||
|
||||
private:
|
||||
|
@ -68,7 +68,7 @@ HttpResponsePtr HttpResponse::newHttpViewResponse(const std::string &viewName, c
|
||||
return HttpViewBase::genHttpResponse(viewName, data);
|
||||
}
|
||||
|
||||
HttpResponsePtr HttpResponse::newFileResponse(const std::string &fullPath, const std::string &fileNameForUser, bool asAttachment)
|
||||
HttpResponsePtr HttpResponse::newFileResponse(const std::string &fullPath, const std::string &attachmentFileName, ContentType type)
|
||||
{
|
||||
auto resp = std::make_shared<HttpResponseImpl>();
|
||||
std::ifstream infile(fullPath, std::ifstream::binary);
|
||||
@ -79,11 +79,9 @@ HttpResponsePtr HttpResponse::newFileResponse(const std::string &fullPath, const
|
||||
resp->setCloseConnection(true);
|
||||
return resp;
|
||||
}
|
||||
|
||||
std::streambuf *pbuf = infile.rdbuf();
|
||||
std::streamsize filesize = pbuf->pubseekoff(0, infile.end);
|
||||
pbuf->pubseekoff(0, infile.beg); // rewind
|
||||
|
||||
if (HttpAppFrameworkImpl::instance().useSendfile() &&
|
||||
filesize > 1024 * 200)
|
||||
//TODO : Is 200k an appropriate value? Or set it to be configurable
|
||||
@ -98,81 +96,87 @@ HttpResponsePtr HttpResponse::newFileResponse(const std::string &fullPath, const
|
||||
pbuf->sgetn(&str[0], filesize);
|
||||
resp->setBody(std::move(str));
|
||||
}
|
||||
|
||||
resp->setStatusCode(k200OK);
|
||||
std::string filename;
|
||||
std::string filetype;
|
||||
if (!fileNameForUser.empty())
|
||||
|
||||
if (type == CT_NONE)
|
||||
{
|
||||
filename = fileNameForUser;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto pos = fullPath.rfind("/");
|
||||
if (pos != std::string::npos)
|
||||
std::string filename;
|
||||
if (!attachmentFileName.empty())
|
||||
{
|
||||
filename = fullPath.substr(pos + 1);
|
||||
filename = attachmentFileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = fullPath;
|
||||
auto pos = fullPath.rfind("/");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
filename = fullPath.substr(pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = fullPath;
|
||||
}
|
||||
}
|
||||
std::string filetype;
|
||||
auto pos = filename.rfind(".");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
filetype = filename.substr(pos + 1);
|
||||
transform(filetype.begin(), filetype.end(), filetype.begin(), tolower);
|
||||
}
|
||||
if (filetype == "html")
|
||||
resp->setContentTypeCode(CT_TEXT_HTML);
|
||||
else if (filetype == "js")
|
||||
resp->setContentTypeCode(CT_APPLICATION_X_JAVASCRIPT);
|
||||
else if (filetype == "css")
|
||||
resp->setContentTypeCode(CT_TEXT_CSS);
|
||||
else if (filetype == "xml")
|
||||
resp->setContentTypeCode(CT_TEXT_XML);
|
||||
else if (filetype == "xsl")
|
||||
resp->setContentTypeCode(CT_TEXT_XSL);
|
||||
else if (filetype == "txt")
|
||||
resp->setContentTypeCode(CT_TEXT_PLAIN);
|
||||
else if (filetype == "svg")
|
||||
resp->setContentTypeCode(CT_IMAGE_SVG_XML);
|
||||
else if (filetype == "ttf")
|
||||
resp->setContentTypeCode(CT_APPLICATION_X_FONT_TRUETYPE);
|
||||
else if (filetype == "otf")
|
||||
resp->setContentTypeCode(CT_APPLICATION_X_FONT_OPENTYPE);
|
||||
else if (filetype == "woff2")
|
||||
resp->setContentTypeCode(CT_APPLICATION_FONT_WOFF2);
|
||||
else if (filetype == "woff")
|
||||
resp->setContentTypeCode(CT_APPLICATION_FONT_WOFF);
|
||||
else if (filetype == "eot")
|
||||
resp->setContentTypeCode(CT_APPLICATION_VND_MS_FONTOBJ);
|
||||
else if (filetype == "png")
|
||||
resp->setContentTypeCode(CT_IMAGE_PNG);
|
||||
else if (filetype == "jpg")
|
||||
resp->setContentTypeCode(CT_IMAGE_JPG);
|
||||
else if (filetype == "jpeg")
|
||||
resp->setContentTypeCode(CT_IMAGE_JPG);
|
||||
else if (filetype == "gif")
|
||||
resp->setContentTypeCode(CT_IMAGE_GIF);
|
||||
else if (filetype == "bmp")
|
||||
resp->setContentTypeCode(CT_IMAGE_BMP);
|
||||
else if (filetype == "ico")
|
||||
resp->setContentTypeCode(CT_IMAGE_XICON);
|
||||
else if (filetype == "icns")
|
||||
resp->setContentTypeCode(CT_IMAGE_ICNS);
|
||||
else
|
||||
{
|
||||
resp->setContentTypeCode(CT_APPLICATION_OCTET_STREAM);
|
||||
}
|
||||
}
|
||||
auto pos = filename.rfind(".");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
filetype = filename.substr(pos + 1);
|
||||
transform(filetype.begin(), filetype.end(), filetype.begin(), tolower);
|
||||
}
|
||||
bool attachment = (asAttachment || (!fileNameForUser.empty()));
|
||||
// pick a Content-Type for the file
|
||||
if (filetype == "html")
|
||||
resp->setContentTypeCode(CT_TEXT_HTML);
|
||||
else if (filetype == "js")
|
||||
resp->setContentTypeCode(CT_APPLICATION_X_JAVASCRIPT);
|
||||
else if (filetype == "css")
|
||||
resp->setContentTypeCode(CT_TEXT_CSS);
|
||||
else if (filetype == "xml")
|
||||
resp->setContentTypeCode(CT_TEXT_XML);
|
||||
else if (filetype == "xsl")
|
||||
resp->setContentTypeCode(CT_TEXT_XSL);
|
||||
else if (filetype == "txt")
|
||||
resp->setContentTypeCode(CT_TEXT_PLAIN);
|
||||
else if (filetype == "svg")
|
||||
resp->setContentTypeCode(CT_IMAGE_SVG_XML);
|
||||
else if (filetype == "ttf")
|
||||
resp->setContentTypeCode(CT_APPLICATION_X_FONT_TRUETYPE);
|
||||
else if (filetype == "otf")
|
||||
resp->setContentTypeCode(CT_APPLICATION_X_FONT_OPENTYPE);
|
||||
else if (filetype == "woff2")
|
||||
resp->setContentTypeCode(CT_APPLICATION_FONT_WOFF2);
|
||||
else if (filetype == "woff")
|
||||
resp->setContentTypeCode(CT_APPLICATION_FONT_WOFF);
|
||||
else if (filetype == "eot")
|
||||
resp->setContentTypeCode(CT_APPLICATION_VND_MS_FONTOBJ);
|
||||
else if (filetype == "png")
|
||||
resp->setContentTypeCode(CT_IMAGE_PNG);
|
||||
else if (filetype == "jpg")
|
||||
resp->setContentTypeCode(CT_IMAGE_JPG);
|
||||
else if (filetype == "jpeg")
|
||||
resp->setContentTypeCode(CT_IMAGE_JPG);
|
||||
else if (filetype == "gif")
|
||||
resp->setContentTypeCode(CT_IMAGE_GIF);
|
||||
else if (filetype == "bmp")
|
||||
resp->setContentTypeCode(CT_IMAGE_BMP);
|
||||
else if (filetype == "ico")
|
||||
resp->setContentTypeCode(CT_IMAGE_XICON);
|
||||
else if (filetype == "icns")
|
||||
resp->setContentTypeCode(CT_IMAGE_ICNS);
|
||||
else
|
||||
{
|
||||
resp->setContentTypeCode(CT_APPLICATION_OCTET_STREAM);
|
||||
attachment = true;
|
||||
resp->setContentTypeCode(type);
|
||||
}
|
||||
if (attachment)
|
||||
|
||||
if (!attachmentFileName.empty())
|
||||
{
|
||||
resp->addHeader("Content-Disposition", "attachment; filename=" + filename);
|
||||
resp->addHeader("Content-Disposition", "attachment; filename=" + attachmentFileName);
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user