Skip to content

Commit 8731609

Browse files
Jake ChampionJakeChampion
authored andcommitted
extract fastly namespace into its own files
1 parent 93e2668 commit 8731609

File tree

4 files changed

+254
-194
lines changed

4 files changed

+254
-194
lines changed
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
// TODO: remove these once the warnings are fixed
2+
#pragma clang diagnostic push
3+
#pragma clang diagnostic ignored "-Winvalid-offsetof"
4+
#include "js/experimental/TypedData.h" // used in "js/Conversions.h"
5+
#pragma clang diagnostic pop
6+
7+
#include "js/Conversions.h"
8+
#include "js/JSON.h"
9+
10+
#include "builtin.h"
11+
#include "builtins/env.h"
12+
#include "builtins/fastly.h"
13+
#include "builtins/logger.h"
14+
#include "geo_ip.h"
15+
16+
namespace builtins {
17+
18+
bool Fastly::debug_logging_enabled = false;
19+
20+
JS::PersistentRooted<JSObject *> Fastly::env;
21+
22+
JS::PersistentRooted<JSObject *> Fastly::baseURL;
23+
JS::PersistentRooted<JSString *> Fastly::defaultBackend;
24+
25+
bool Fastly::dump(JSContext *cx, unsigned argc, JS::Value *vp) {
26+
JS::CallArgs args = CallArgsFromVp(argc, vp);
27+
if (!args.requireAtLeast(cx, __func__, 1))
28+
return false;
29+
30+
dump_value(cx, args[0], stdout);
31+
32+
args.rval().setUndefined();
33+
return true;
34+
}
35+
36+
bool Fastly::enableDebugLogging(JSContext *cx, unsigned argc, JS::Value *vp) {
37+
JS::CallArgs args = CallArgsFromVp(argc, vp);
38+
if (!args.requireAtLeast(cx, __func__, 1))
39+
return false;
40+
41+
debug_logging_enabled = JS::ToBoolean(args[0]);
42+
43+
args.rval().setUndefined();
44+
return true;
45+
}
46+
47+
bool Fastly::getGeolocationForIpAddress(JSContext *cx, unsigned argc, JS::Value *vp) {
48+
JS::CallArgs args = CallArgsFromVp(argc, vp);
49+
REQUEST_HANDLER_ONLY("fastly.getGeolocationForIpAddress");
50+
if (!args.requireAtLeast(cx, "fastly.getGeolocationForIpAddress", 1))
51+
return false;
52+
53+
JS::RootedString address_str(cx, JS::ToString(cx, args[0]));
54+
if (!address_str)
55+
return false;
56+
57+
JS::RootedString geo_info_str(cx, get_geo_info(cx, address_str));
58+
if (!geo_info_str)
59+
return false;
60+
61+
return JS_ParseJSON(cx, geo_info_str, args.rval());
62+
}
63+
64+
// TODO: consider allowing logger creation during initialization, but then throw
65+
// when trying to log.
66+
bool Fastly::getLogger(JSContext *cx, unsigned argc, JS::Value *vp) {
67+
JS::CallArgs args = CallArgsFromVp(argc, vp);
68+
REQUEST_HANDLER_ONLY("fastly.getLogger");
69+
JS::RootedObject self(cx, &args.thisv().toObject());
70+
if (!args.requireAtLeast(cx, "fastly.getLogger", 1))
71+
return false;
72+
73+
size_t name_len;
74+
JS::UniqueChars name = encode(cx, args[0], &name_len);
75+
if (!name)
76+
return false;
77+
78+
JS::RootedObject logger(cx, builtins::Logger::create(cx, name.get()));
79+
if (!logger)
80+
return false;
81+
82+
args.rval().setObject(*logger);
83+
return true;
84+
}
85+
86+
bool Fastly::includeBytes(JSContext *cx, unsigned argc, JS::Value *vp) {
87+
JS::CallArgs args = CallArgsFromVp(argc, vp);
88+
INIT_ONLY("fastly.includeBytes");
89+
JS::RootedObject self(cx, &args.thisv().toObject());
90+
if (!args.requireAtLeast(cx, "fastly.includeBytes", 1))
91+
return false;
92+
93+
size_t path_len;
94+
JS::UniqueChars path = encode(cx, args[0], &path_len);
95+
if (!path)
96+
return false;
97+
98+
FILE *fp = fopen(path.get(), "r");
99+
if (!fp) {
100+
JS_ReportErrorUTF8(cx, "Error opening file %s", path.get());
101+
return false;
102+
}
103+
104+
fseek(fp, 0L, SEEK_END);
105+
size_t size = ftell(fp);
106+
rewind(fp);
107+
JS::RootedObject typed_array(cx, JS_NewUint8Array(cx, size));
108+
if (!typed_array)
109+
return false;
110+
111+
size_t read_bytes;
112+
{
113+
JS::AutoCheckCannotGC noGC(cx);
114+
bool is_shared;
115+
void *buffer = JS_GetArrayBufferViewData(typed_array, &is_shared, noGC);
116+
read_bytes = fread(buffer, 1, size, fp);
117+
}
118+
119+
if (read_bytes != size) {
120+
JS_ReportErrorUTF8(cx, "Failed to read contents of file %s", path.get());
121+
return false;
122+
}
123+
124+
args.rval().setObject(*typed_array);
125+
return true;
126+
}
127+
128+
const JSFunctionSpec Fastly::methods[] = {
129+
JS_FN("dump", dump, 1, 0),
130+
JS_FN("enableDebugLogging", enableDebugLogging, 1, JSPROP_ENUMERATE),
131+
JS_FN("getGeolocationForIpAddress", getGeolocationForIpAddress, 1, JSPROP_ENUMERATE),
132+
JS_FN("getLogger", getLogger, 1, JSPROP_ENUMERATE),
133+
JS_FN("includeBytes", includeBytes, 1, JSPROP_ENUMERATE),
134+
JS_FS_END};
135+
136+
bool Fastly::env_get(JSContext *cx, unsigned argc, JS::Value *vp) {
137+
JS::CallArgs args = CallArgsFromVp(argc, vp);
138+
args.rval().setObject(*env);
139+
return true;
140+
}
141+
142+
bool Fastly::baseURL_get(JSContext *cx, unsigned argc, JS::Value *vp) {
143+
JS::CallArgs args = CallArgsFromVp(argc, vp);
144+
args.rval().setObjectOrNull(baseURL);
145+
return true;
146+
}
147+
148+
bool Fastly::baseURL_set(JSContext *cx, unsigned argc, JS::Value *vp) {
149+
JS::CallArgs args = CallArgsFromVp(argc, vp);
150+
if (args.get(0).isNullOrUndefined()) {
151+
baseURL.set(nullptr);
152+
} else if (!URL::is_instance(args.get(0))) {
153+
JS_ReportErrorUTF8(cx, "Invalid value assigned to fastly.baseURL, must be an instance of "
154+
"URL, null, or undefined");
155+
return false;
156+
}
157+
158+
baseURL.set(&args.get(0).toObject());
159+
160+
args.rval().setObjectOrNull(baseURL);
161+
return true;
162+
}
163+
164+
bool Fastly::defaultBackend_get(JSContext *cx, unsigned argc, JS::Value *vp) {
165+
JS::CallArgs args = CallArgsFromVp(argc, vp);
166+
args.rval().setString(defaultBackend);
167+
return true;
168+
}
169+
170+
bool Fastly::defaultBackend_set(JSContext *cx, unsigned argc, JS::Value *vp) {
171+
JS::CallArgs args = CallArgsFromVp(argc, vp);
172+
JS::RootedString backend(cx, JS::ToString(cx, args.get(0)));
173+
if (!backend)
174+
return false;
175+
176+
defaultBackend = backend;
177+
args.rval().setUndefined();
178+
return true;
179+
}
180+
181+
const JSPropertySpec Fastly::properties[] = {
182+
JS_PSG("env", env_get, JSPROP_ENUMERATE),
183+
JS_PSGS("baseURL", baseURL_get, baseURL_set, JSPROP_ENUMERATE),
184+
JS_PSGS("defaultBackend", defaultBackend_get, defaultBackend_set, JSPROP_ENUMERATE), JS_PS_END};
185+
186+
bool Fastly::create(JSContext *cx, JS::HandleObject global) {
187+
JS::RootedObject fastly(cx, JS_NewPlainObject(cx));
188+
if (!fastly)
189+
return false;
190+
191+
env.init(cx, Env::create(cx));
192+
if (!env)
193+
return false;
194+
baseURL.init(cx);
195+
defaultBackend.init(cx);
196+
197+
if (!JS_DefineProperty(cx, global, "fastly", fastly, 0))
198+
return false;
199+
return JS_DefineFunctions(cx, fastly, methods) && JS_DefineProperties(cx, fastly, properties);
200+
}
201+
202+
} // namespace builtins
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#ifndef JS_COMPUTE_RUNTIME_BUILTIN_FASTLY_H
2+
#define JS_COMPUTE_RUNTIME_BUILTIN_FASTLY_H
3+
4+
#include "builtin.h"
5+
6+
namespace builtins {
7+
8+
class Fastly : public BuiltinNoConstructor<Fastly> {
9+
private:
10+
static bool log(JSContext *cx, unsigned argc, JS::Value *vp);
11+
12+
public:
13+
static constexpr const char *class_name = "Fastly";
14+
15+
static bool debug_logging_enabled;
16+
17+
static JS::PersistentRooted<JSObject *> env;
18+
19+
static JS::PersistentRooted<JSObject *> baseURL;
20+
static JS::PersistentRooted<JSString *> defaultBackend;
21+
22+
static const JSFunctionSpec methods[];
23+
static const JSPropertySpec properties[];
24+
25+
static bool dump(JSContext *cx, unsigned argc, JS::Value *vp);
26+
static bool enableDebugLogging(JSContext *cx, unsigned argc, JS::Value *vp);
27+
static bool getGeolocationForIpAddress(JSContext *cx, unsigned argc, JS::Value *vp);
28+
static bool getLogger(JSContext *cx, unsigned argc, JS::Value *vp);
29+
static bool includeBytes(JSContext *cx, unsigned argc, JS::Value *vp);
30+
static bool env_get(JSContext *cx, unsigned argc, JS::Value *vp);
31+
static bool baseURL_get(JSContext *cx, unsigned argc, JS::Value *vp);
32+
static bool baseURL_set(JSContext *cx, unsigned argc, JS::Value *vp);
33+
static bool defaultBackend_get(JSContext *cx, unsigned argc, JS::Value *vp);
34+
static bool defaultBackend_set(JSContext *cx, unsigned argc, JS::Value *vp);
35+
static bool create(JSContext *cx, JS::HandleObject global);
36+
};
37+
38+
} // namespace builtins
39+
40+
#endif

0 commit comments

Comments
 (0)