1515using bazel::tools::cpp::runfiles::Runfiles;
1616using ::nlohmann::json;
1717
18+ using Path = std::string;
19+ using FileContents = std::string;
20+
1821bool DEBUG = false ;
1922
2023#define DEBUG_LOG (msg ) \
@@ -24,6 +27,70 @@ constexpr char kWorkspaceName[] = "rules_devserver";
2427constexpr int kDefaultPort = 8080 ;
2528constexpr char kHost [] = " localhost" ;
2629
30+ /*
31+ * Base64 encoding/decoding (RFC1341)
32+ * Copyright (c) 2005-2011, Jouni Malinen <[email protected] > 33+ *
34+ * This software may be distributed under the terms of the BSD license.
35+ * See README for more details.
36+ */
37+
38+ // 2016-12-12 - Gaspard Petit : Slightly modified to return a std::string
39+ // instead of a buffer allocated with malloc.
40+
41+ #include < string>
42+
43+ static const unsigned char base64_table[65 ] =
44+ " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ;
45+
46+ /* *
47+ * base64_encode - Base64 encode
48+ * @src: Data to be encoded
49+ * @len: Length of the data to be encoded
50+ * @out_len: Pointer to output length variable, or %NULL if not used
51+ * Returns: Allocated buffer of out_len bytes of encoded data,
52+ * or empty string on failure
53+ */
54+ std::string base64_encode (const unsigned char *src, size_t len) {
55+ unsigned char *out, *pos;
56+ const unsigned char *end, *in;
57+
58+ size_t olen;
59+
60+ olen = 4 * ((len + 2 ) / 3 ); /* 3-byte blocks to 4-byte */
61+
62+ if (olen < len) return std::string (); /* integer overflow */
63+
64+ std::string outStr;
65+ outStr.resize (olen);
66+ out = (unsigned char *)&outStr[0 ];
67+
68+ end = src + len;
69+ in = src;
70+ pos = out;
71+ while (end - in >= 3 ) {
72+ *pos++ = base64_table[in[0 ] >> 2 ];
73+ *pos++ = base64_table[((in[0 ] & 0x03 ) << 4 ) | (in[1 ] >> 4 )];
74+ *pos++ = base64_table[((in[1 ] & 0x0f ) << 2 ) | (in[2 ] >> 6 )];
75+ *pos++ = base64_table[in[2 ] & 0x3f ];
76+ in += 3 ;
77+ }
78+
79+ if (end - in) {
80+ *pos++ = base64_table[in[0 ] >> 2 ];
81+ if (end - in == 1 ) {
82+ *pos++ = base64_table[(in[0 ] & 0x03 ) << 4 ];
83+ *pos++ = ' =' ;
84+ } else {
85+ *pos++ = base64_table[((in[0 ] & 0x03 ) << 4 ) | (in[1 ] >> 4 )];
86+ *pos++ = base64_table[(in[1 ] & 0x0f ) << 2 ];
87+ }
88+ *pos++ = ' =' ;
89+ }
90+
91+ return outStr;
92+ }
93+
2794struct Arguments {
2895 int32_t port;
2996 std::string static_file;
@@ -38,10 +105,22 @@ std::string GetFileContents(const std::string &path) {
38105 return content;
39106}
40107
41- json ComputeManifest () {
108+ json ComputeManifest (const std::map<Path, FileContents> &path_to_contents ) {
42109 json manifest;
43110
44- manifest[" manifest" ] = {{" /" , " 123" }};
111+ for (const auto &path_and_contents : path_to_contents) {
112+ Path path = path_and_contents.first ;
113+ FileContents contents = path_and_contents.second ;
114+
115+ picohash_ctx_t ctx;
116+ char digest[PICOHASH_MD5_DIGEST_LENGTH];
117+
118+ picohash_init_md5 (&ctx);
119+ picohash_update (&ctx, &contents, contents.size ());
120+ picohash_final (&ctx, digest);
121+ std::string digest_str (base64_encode (digest, PICOHASH_MD5_DIGEST_LENGTH));
122+ manifest[path] = digest_str;
123+ }
45124
46125 return manifest;
47126}
@@ -93,7 +172,7 @@ Arguments ParseArguments(int argc, char **argv) {
93172 parser, " static_file" , " Index file to serve from top-level / route" ,
94173 {" static_file" });
95174 args::ValueFlag<std::string> workspace_name_arg (
96- parser, " workspace_name" , " Calling Bazel workspace name" ,
175+ parser, " workspace_name" , " Cgalling Bazel workspace name" ,
97176 {" workspace_name" });
98177 args::ValueFlag<std::string> package_name (parser, " package_name" ,
99178 " Package name" , {" package_name" });
@@ -148,8 +227,10 @@ int main(int argc, char **argv) {
148227 static_file_contents =
149228 AddDevserverLoaderToStaticFileContents (static_file_contents);
150229
151- const std::map<std::string, std::string> path_to_contents = {{" /" , " 123" }};
152- const json manifest = ComputeManifest ();
230+ const std::map<std::string, std::string> path_to_contents = {
231+ {" /" , static_file_contents}};
232+ json manifest = ComputeManifest (path_to_contents);
233+ std::cout << " manifest: " << manifest.dump () << std::endl;
153234
154235 svr.Get (" /" , [&static_file_contents](const httplib::Request &req,
155236 httplib::Response &res) {
@@ -164,8 +245,8 @@ int main(int argc, char **argv) {
164245 });
165246
166247 svr.Get (" /devserver/manifest" ,
167- [](const httplib::Request &req, httplib::Response &res) {
168- res.set_content (ComputeManifest () .dump (), " application/json" );
248+ [&manifest ](const httplib::Request &req, httplib::Response &res) {
249+ res.set_content (manifest .dump (), " application/json" );
169250 });
170251
171252 svr.listen (kHost , port);
0 commit comments