-static void OnData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) {
- switch (type) {
- case kCFSocketDataCallBack:
- CFDataRef data(reinterpret_cast<CFDataRef>(value));
- Client *client(reinterpret_cast<Client *>(info));
-
- if (client->message_ == NULL)
- client->message_ = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE);
-
- if (!CFHTTPMessageAppendBytes(client->message_, CFDataGetBytePtr(data), CFDataGetLength(data)))
- CFLog(kCFLogLevelError, CFSTR("CFHTTPMessageAppendBytes()"));
- else if (CFHTTPMessageIsHeaderComplete(client->message_)) {
- CFURLRef url(CFHTTPMessageCopyRequestURL(client->message_));
- Boolean absolute;
- CFStringRef path(CFURLCopyStrictPath(url, &absolute));
- CFRelease(client->message_);
-
- CFStringRef code(CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault, path, CFSTR("")));
- CFRelease(path);
-
- JSStringRef script(JSStringCreateWithCFString(code));
- CFRelease(code);
-
- JSValueRef result(JSEvaluateScript(CYGetJSContext(), script, NULL, NULL, 0, NULL));
- JSStringRelease(script);
-
- CFHTTPMessageRef response(CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1));
- CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Type"), CFSTR("application/json; charset=utf-8"));
-
- CFStringRef json(CYCopyJSONString(CYGetJSContext(), result, NULL));
- CFDataRef body(CFStringCreateExternalRepresentation(kCFAllocatorDefault, json, kCFStringEncodingUTF8, NULL));
- CFRelease(json);
-
- CFStringRef length(CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"), CFDataGetLength(body)));
- CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Length"), length);
- CFRelease(length);
-
- CFHTTPMessageSetBody(response, body);
- CFRelease(body);
-
- CFDataRef serialized(CFHTTPMessageCopySerializedMessage(response));
- CFRelease(response);
-
- CFSocketSendData(socket, NULL, serialized, 0);
- CFRelease(serialized);
-
- CFRelease(url);
- }
- break;
- }
-}
-
-static void OnAccept(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) {
- switch (type) {
- case kCFSocketAcceptCallBack:
- Client *client(new Client());
-
- client->message_ = NULL;
-
- CFSocketContext context;
- context.version = 0;
- context.info = client;
- context.retain = NULL;
- context.release = NULL;
- context.copyDescription = NULL;
-
- client->socket_ = CFSocketCreateWithNative(kCFAllocatorDefault, *reinterpret_cast<const CFSocketNativeHandle *>(value), kCFSocketDataCallBack, &OnData, &context);
-
- CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, client->socket_, 0), kCFRunLoopDefaultMode);
- break;
- }
-}
-