Skip to content

Commit

Permalink
Merge pull request #33 from kentonv/master
Browse files Browse the repository at this point in the history
Sandstorm: Properly support gzipped assets.
  • Loading branch information
davidjgraph committed Nov 27, 2016
2 parents bb89ca0 + 6d934db commit c4b2403
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 35 deletions.
73 changes: 38 additions & 35 deletions etc/sandstorm/server.c++
Expand Up @@ -291,59 +291,62 @@ private:
}
}

struct ContentType {
kj::StringPtr type;
kj::StringPtr encoding;

ContentType(kj::StringPtr type): type(type), encoding(nullptr) {}
ContentType(const char* type): type(type), encoding(nullptr) {}
ContentType() = default;
};

ContentType inferContentType(kj::StringPtr filename) {
ContentType result;
kj::String scratch;

if (filename.endsWith(".gz")) {
result.encoding = "gzip";
scratch = kj::str(filename.slice(0, filename.size() - 3));
filename = scratch;
}

kj::StringPtr inferContentType(kj::StringPtr filename) {
if (filename.endsWith(".html")) {
result.type = "text/html; charset=UTF-8";
return "text/html; charset=UTF-8";
} else if (filename.endsWith(".js")) {
result.type = "text/javascript; charset=UTF-8";
return "text/javascript; charset=UTF-8";
} else if (filename.endsWith(".css")) {
result.type = "text/css; charset=UTF-8";
return "text/css; charset=UTF-8";
} else if (filename.endsWith(".png")) {
result.type = "image/png";
return "image/png";
} else if (filename.endsWith(".gif")) {
result.type = "image/gif";
return "image/gif";
} else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) {
result.type = "image/jpeg";
return "image/jpeg";
} else if (filename.endsWith(".svg")) {
result.type = "image/svg+xml; charset=UTF-8";
return "image/svg+xml; charset=UTF-8";
} else if (filename.endsWith(".txt")) {
result.type = "text/plain; charset=UTF-8";
return "text/plain; charset=UTF-8";
} else {
result.type = "application/octet-stream";
return "application/octet-stream";
}

return result;
}

kj::Promise<void> readFile(
kj::StringPtr filename, GetContext context, ContentType contentType) {
KJ_IF_MAYBE(fd, tryOpen(filename, O_RDONLY)) {
kj::StringPtr filename, GetContext context, kj::StringPtr contentType) {
// Do we support compression?
bool canGzip = false;
for (auto accept: context.getParams().getContext().getAcceptEncoding()) {
if (accept.getContentCoding() == "gzip") {
canGzip = true;
break;
}
}

// If compression is supported, look for file with .gz extension.
kj::Maybe<kj::AutoCloseFd> maybeFd;
bool isGzipped = false;
if (canGzip) {
maybeFd = tryOpen(kj::str(filename, ".gz"), O_RDONLY);
isGzipped = maybeFd != nullptr;
}

// If we haven't found a suitable file yet, look for the uncompressed version.
if (maybeFd == nullptr) {
maybeFd = tryOpen(filename, O_RDONLY);
}

// Serve it.
KJ_IF_MAYBE(fd, kj::mv(maybeFd)) {
auto size = getFileSize(*fd, filename);
kj::FdInputStream stream(kj::mv(*fd));
auto response = context.getResults(capnp::MessageSize { size / sizeof(capnp::word) + 32, 0 });
auto content = response.initContent();
content.setStatusCode(sandstorm::WebSession::Response::SuccessCode::OK);
content.setMimeType(contentType.type);
if (contentType.encoding != nullptr) {
content.setEncoding(contentType.encoding);
content.setMimeType(contentType);
if (isGzipped) {
content.setEncoding("gzip");
}
stream.read(content.getBody().initBytes(size).begin(), size);
return kj::READY_NOW;
Expand Down
4 changes: 4 additions & 0 deletions etc/sandstorm/stage.sh
Expand Up @@ -40,6 +40,10 @@ mkdir -p build/.sandstorm/client/styles
cp -rf ../../war/styles/* build/.sandstorm/client/styles/
mkdir -p build/.sandstorm/client/templates
cp -rf ../../war/templates/* build/.sandstorm/client/templates/

echo "Compressing assets"
gfind build/.sandstorm/client -name '*.html' -o -name '*.css' -o -name '*.js' -o -name '*.txt' -o -name '*.xml' | xargs gzip -k

echo "Creating file list"
cd build/.sandstorm
gfind ./client -type f -printf "%p\n" | cut -c 3- > sandstorm-files.list
Expand Down

0 comments on commit c4b2403

Please sign in to comment.