| 107 | } |
| 108 | |
| 109 | void |
| 110 | done() |
| 111 | { |
| 112 | if (GIF::verifySignature(content_)) { |
| 113 | contentType_ = "image/gif"; |
| 114 | } else if (JPEG::verifySignature(content_)) { |
| 115 | contentType_ = "image/jpeg"; |
| 116 | } else if (PNG::verifySignature(content_)) { |
| 117 | contentType_ = "image/png"; |
| 118 | } else { |
| 119 | // TODO(dmorilha): check png signature code. |
| 120 | Dbg(dbg_ctl, "Invalid signature for: %s", url_.c_str()); |
| 121 | } |
| 122 | |
| 123 | if (contentType_ != "image/gif" && contentType_ != "image/jpeg" && contentType_ != "image/jpg" && |
| 124 | contentType_ != "image/png") { |
| 125 | return; |
| 126 | } |
| 127 | |
| 128 | if (!contentType_.empty() && !content_.empty()) { |
| 129 | std::string output; |
| 130 | output.reserve(content_.size() * 5); |
| 131 | output += "data:"; |
| 132 | output += contentType_; |
| 133 | output += ";base64,"; |
| 134 | |
| 135 | { |
| 136 | const int64_t s = output.size(); |
| 137 | size_t size = 0; |
| 138 | output.resize(content_.size() * 5); |
| 139 | CHECK(TSBase64Encode(content_.data(), content_.size(), const_cast<char *>(output.data()) + s, output.size() - s, &size)); |
| 140 | output.resize(size + s); |
| 141 | } |
| 142 | |
| 143 | Dbg(dbg_ctl, "%s (%s) %lu %lu", url_.c_str(), contentType_.c_str(), content_.size(), output.size()); |
| 144 | |
| 145 | cache::write(url_ + VERSION, std::move(output)); |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | void |
| 150 | header(TSMBuffer b, TSMLoc l) |