aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md14
-rw-r--r--include/AnnotationTypes.hpp1
-rw-r--r--include/Response.hpp5
-rw-r--r--src/Response.cpp105
-rw-r--r--src/SimpleHandlers.cpp95
5 files changed, 97 insertions, 123 deletions
diff --git a/README.md b/README.md
index ea08283..fd3aa1c 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,8 @@ No extra content.
##### `attachment`
The text is the caption of an attached file.
-Extra content: an `attachment`-object. (TODO: extend to array of attachments)
+Extra content: String of content: "`file_name`;`file_type`;`file_content`", where `file_content` is base64 encoded.
+E.g.: "image.png;png;iVBORw0KGgoAAAANSUhEUgAAABwAAAAMBAMAAACD9cA8AAAALVBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAOrOgAAAADnRSTlMAELt2Mu9Eic1mIqtU3XZzvlQAAAAJcEhZcwAADsQAAA7EAZUrDhsAAACJSURBVAgdY2BgFGCAARCTyQDGAzP5HOBcENMVzgMx0zsqGXjmGDBwzpwFYjJoMjBsZkhjOMlQCWIyvGLgvMBQxVDhIABkMrAFMPDqTE5gWPv0AJDJwL6BQW4ByLTlD4BMBo4JMnJADscBhgAgk4HXwYDXgeEINwMbkDZg4LFZwFVzUoAt5ySICQDlYB5evEnwqgAAAABJRU5ErkJggg=="
##### `command`
The text should be formatted in a way to underlying platform of the bridge would recognize it (e.g. prefix with '/').
@@ -74,13 +75,4 @@ Extra content: the description of the command.
##### `link`
The text should be formatted as a link.
-Extra content: the alt text for the uri - the uri should be the text itself, so that clients ignoring this annotation still show the real uri.
-
-#### `attachment`
-The `attachment` object:
-
-| Field | Type | Description |
-|-------|------|-------------|
-| `type` | string | MIME type of the attachment (e.g. "png", "gif", etc) |
-| `name` | string | The name of the file (including the file ending) |
-| `content` | string | Base64 encoded file contents | \ No newline at end of file
+Extra content: the alt text for the uri - the uri should be the text itself, so that clients ignoring this annotation still show the real uri. \ No newline at end of file
diff --git a/include/AnnotationTypes.hpp b/include/AnnotationTypes.hpp
index 66d0b9d..8fba983 100644
--- a/include/AnnotationTypes.hpp
+++ b/include/AnnotationTypes.hpp
@@ -14,6 +14,7 @@ namespace Reply {
DECL_ENUM_ELEMENT(none),
DECL_ENUM_ELEMENT(bold),
DECL_ENUM_ELEMENT(italics),
+ DECL_ENUM_ELEMENT(attachment),
DECL_ENUM_ELEMENT(strikethrough),
DECL_ENUM_ELEMENT(underline),
DECL_ENUM_ELEMENT(command),
diff --git a/include/Response.hpp b/include/Response.hpp
index 3e42d0d..82edb53 100644
--- a/include/Response.hpp
+++ b/include/Response.hpp
@@ -11,11 +11,6 @@ namespace Response {
// create a full response of just plain text
json simple_response(std::string const &text, std::string const &session = "null", bool success = true);
- // create file attachment (is an annotation)
- json create_attachment(std::string const &file_path);
- json create_attachment(std::string const &file_path, std::string const &file_name);
- json create_attachment(std::string const &file_path, std::string const &file_name, std::string const &file_type);
-
// "nested" annotations: the extra field is again an array of text-annotation pairs
json create_annotation(AnnotationType annotation, std::vector<json> &&extra);
// construct an extra field with no special annotations in the extra
diff --git a/src/Response.cpp b/src/Response.cpp
index d97ab40..53b0d8c 100644
--- a/src/Response.cpp
+++ b/src/Response.cpp
@@ -45,108 +45,3 @@ Response::json Response::create_response(std::vector<json> &&reply, std::string
response["reply"] = std::move(reply);
return response;
}
-
-static std::string const base64_chars =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789+/";
-
-std::string base64_encode(unsigned char const *input, unsigned int const len) {
- std::string ret;
- size_t i = 0;
- unsigned char bytes[3];
- unsigned char sextets[4];
-
- while (i <= (len - 3)) {
- bytes[0] = *(input++);
- bytes[1] = *(input++);
- bytes[2] = *(input++);
-
- sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte
- sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0)
- >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte
- sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0)
- >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte
- sextets[3] = bytes[2] & 0x3f; // takes last 6 bits of third byte
-
- for (size_t j = 0; j < 4; ++j) {
- ret += base64_chars[sextets[j]];
- }
-
- i += 3; // increases to go to third byte
- }
-
- if (i != len) {
- size_t k = 0;
- size_t j = len - i; // Find index of last byte
- while (k < j) { // Sets first bytes
- bytes[k] = *(input++);
- ++k;
- }
-
- while (j < 3) { // Set last bytes to 0x00
- bytes[j] = '\0';
- ++j;
- }
-
- sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte
- sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0)
- >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte
- sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0)
- >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte
- // No last one is needed, because if there were 4, then (i == len) == true
-
- for (j = 0; j < (len - i) + 1; ++j) { // Gets sextets that include data
- ret += base64_chars[sextets[j]]; // Appends them to string
- }
-
- while ((j++) < 4) // Appends remaining ='s
- ret += '=';
-
- }
-
- return ret;
-}
-
-std::string base64_encode_file(std::string const &path) {
- std::vector<char> temp;
-
- std::ifstream infile;
- infile.open(path, std::ios::binary); // Open file in binary mode
- if (infile.is_open()) {
- while (!infile.eof()) {
- char c = (char) infile.get();
- temp.push_back(c);
- }
- infile.close();
- } else return "File could not be opened";
- std::string ret(temp.begin(), temp.end() - 1);
- ret = base64_encode((unsigned const char *) ret.c_str(), ret.size());
-
- return ret;
-}
-
-Response::json Response::create_attachment(std::string const &file_path) {
- std::string name = file_path;
- if (auto pos = file_path.find_last_of('/'); pos != std::string::npos) {
- name = file_path.substr(pos + 1);
- }
- return create_attachment(file_path, name);
-}
-
-Response::json Response::create_attachment(std::string const &file_path, std::string const &file_name) {
- std::string type = "unknown";
- if (auto pos = file_name.find_last_of('.'); pos != std::string::npos) {
- type = file_name.substr(pos + 1);
- }
- return create_attachment(file_path, file_name, type);
-}
-
-Response::json
-Response::create_attachment(std::string const &file_path, std::string const &file_name, std::string const &file_type) {
- json attachment(crow::json::type::Object);
- attachment["type"] = file_type;
- attachment["name"] = file_name;
- attachment["content"] = base64_encode_file(file_path);
- return attachment;
-}
diff --git a/src/SimpleHandlers.cpp b/src/SimpleHandlers.cpp
index d9c6448..70b3a8c 100644
--- a/src/SimpleHandlers.cpp
+++ b/src/SimpleHandlers.cpp
@@ -116,7 +116,6 @@ std::string url_encode(std::string const &value) {
return escaped.str();
}
-
std::string exec(const char* cmd) {
std::array<char, 128> buffer{};
std::string result;
@@ -130,6 +129,86 @@ std::string exec(const char* cmd) {
return result;
}
+static std::string const base64_chars =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+
+std::string base64_encode(unsigned char const *input, unsigned int const len) {
+ std::string ret;
+ size_t i = 0;
+ unsigned char bytes[3];
+ unsigned char sextets[4];
+
+ while (i <= (len - 3)) {
+ bytes[0] = *(input++);
+ bytes[1] = *(input++);
+ bytes[2] = *(input++);
+
+ sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte
+ sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0)
+ >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte
+ sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0)
+ >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte
+ sextets[3] = bytes[2] & 0x3f; // takes last 6 bits of third byte
+
+ for (unsigned char sextet : sextets) {
+ ret += base64_chars[sextet];
+ }
+
+ i += 3; // increases to go to third byte
+ }
+
+ if (i != len) {
+ size_t k = 0;
+ size_t j = len - i; // Find index of last byte
+ while (k < j) { // Sets first bytes
+ bytes[k] = *(input++);
+ ++k;
+ }
+
+ while (j < 3) { // Set last bytes to 0x00
+ bytes[j] = '\0';
+ ++j;
+ }
+
+ sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte
+ sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0)
+ >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte
+ sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0)
+ >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte
+ // No last one is needed, because if there were 4, then (i == len) == true
+
+ for (j = 0; j < (len - i) + 1; ++j) { // Gets sextets that include data
+ ret += base64_chars[sextets[j]]; // Appends them to string
+ }
+
+ while ((j++) < 4) // Appends remaining ='s
+ ret += '=';
+
+ }
+
+ return ret;
+}
+
+std::string base64_encode_file(std::string const &path) {
+ std::vector<char> temp;
+
+ std::ifstream infile;
+ infile.open(path, std::ios::binary); // Open file in binary mode
+ if (infile.is_open()) {
+ while (!infile.eof()) {
+ char c = (char) infile.get();
+ temp.push_back(c);
+ }
+ infile.close();
+ } else return "File could not be opened";
+ std::string ret(temp.begin(), temp.end() - 1);
+ ret = base64_encode((unsigned const char *) ret.c_str(), ret.size());
+
+ return ret;
+}
+
json Handler::latexRenderHandler(std::string const &arguments, std::string const &session, void *payload) {
(void) payload;
@@ -141,5 +220,17 @@ json Handler::latexRenderHandler(std::string const &arguments, std::string const
"-H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'DNT: 1' -H 'Connection: keep-alive' "
"-H 'Upgrade-Insecure-Requests: 1' --output " + file).c_str());
- return simple_response(result, session, true);
+ if (!result.empty())
+ return simple_response("Error: " + result + "\n"
+ "Please report to an admin", session, false);
+
+ std::vector<json> reply_vec;
+ std::vector<json> annotations;
+
+ annotations.emplace_back(
+ create_annotation(Reply::AnnotationType::attachment, "latex.png;png;" + base64_encode_file(file)));
+
+ reply_vec.emplace_back(create_text("", std::move(annotations)));
+
+ return create_response(std::move(reply_vec), session, true);
}