1 /* Cycript - Inlining/Optimizing JavaScript Compiler
2 * Copyright (C) 2009 Jay Freeman (saurik)
5 /* Modified BSD License {{{ */
7 * Redistribution and use in source and binary
8 * forms, with or without modification, are permitted
9 * provided that the following conditions are met:
11 * 1. Redistributions of source code must retain the
12 * above copyright notice, this list of conditions
13 * and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the
15 * above copyright notice, this list of conditions
16 * and the following disclaimer in the documentation
17 * and/or other materials provided with the
19 * 3. The name of the author may not be used to endorse
20 * or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
25 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #include <Pooling.hpp>
42 #include <apr_thread_proc.h>
44 #include <CoreFoundation/CFLogUtilities.h>
45 #include <CFNetwork/CFNetwork.h>
47 #include <sys/types.h>
48 #include <sys/socket.h>
49 #include <netinet/in.h>
53 CFHTTPMessageRef message_
;
57 static void OnData(CFSocketRef socket
, CFSocketCallBackType type
, CFDataRef address
, const void *value
, void *info
) {
59 case kCFSocketDataCallBack
:
60 CFDataRef
data(reinterpret_cast<CFDataRef
>(value
));
61 Client
*client(reinterpret_cast<Client
*>(info
));
63 if (client
->message_
== NULL
)
64 client
->message_
= CFHTTPMessageCreateEmpty(kCFAllocatorDefault
, TRUE
);
66 if (!CFHTTPMessageAppendBytes(client
->message_
, CFDataGetBytePtr(data
), CFDataGetLength(data
)))
67 CFLog(kCFLogLevelError
, CFSTR("CFHTTPMessageAppendBytes()"));
68 else if (CFHTTPMessageIsHeaderComplete(client
->message_
)) {
69 CFURLRef
url(CFHTTPMessageCopyRequestURL(client
->message_
));
71 CFStringRef
path(CFURLCopyStrictPath(url
, &absolute
));
72 CFRelease(client
->message_
);
74 CFStringRef
code(CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault
, path
, CFSTR("")));
77 JSStringRef
script(JSStringCreateWithCFString(code
));
80 JSValueRef
result(JSEvaluateScript(CYGetJSContext(), script
, NULL
, NULL
, 0, NULL
));
81 JSStringRelease(script
);
83 CFHTTPMessageRef
response(CFHTTPMessageCreateResponse(kCFAllocatorDefault
, 200, NULL
, kCFHTTPVersion1_1
));
84 CFHTTPMessageSetHeaderFieldValue(response
, CFSTR("Content-Type"), CFSTR("application/json; charset=utf-8"));
86 CFStringRef
json(CYCopyJSONString(CYGetJSContext(), result
, NULL
));
87 CFDataRef
body(CFStringCreateExternalRepresentation(kCFAllocatorDefault
, json
, kCFStringEncodingUTF8
, NULL
));
90 CFStringRef
length(CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%u"), CFDataGetLength(body
)));
91 CFHTTPMessageSetHeaderFieldValue(response
, CFSTR("Content-Length"), length
);
94 CFHTTPMessageSetBody(response
, body
);
97 CFDataRef
serialized(CFHTTPMessageCopySerializedMessage(response
));
100 CFSocketSendData(socket
, NULL
, serialized
, 0);
101 CFRelease(serialized
);
109 static void OnAccept(CFSocketRef socket
, CFSocketCallBackType type
, CFDataRef address
, const void *value
, void *info
) {
111 case kCFSocketAcceptCallBack
:
112 Client
*client(new Client());
114 client
->message_
= NULL
;
116 CFSocketContext context
;
118 context
.info
= client
;
119 context
.retain
= NULL
;
120 context
.release
= NULL
;
121 context
.copyDescription
= NULL
;
123 client
->socket_
= CFSocketCreateWithNative(kCFAllocatorDefault
, *reinterpret_cast<const CFSocketNativeHandle
*>(value
), kCFSocketDataCallBack
, &OnData
, &context
);
125 CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault
, client
->socket_
, 0), kCFRunLoopDefaultMode
);
130 int main(int argc
, char *argv
[]) {
132 struct sockaddr_in address
;
133 address
.sin_len
= sizeof(address
);
134 address
.sin_family
= AF_INET
;
135 address
.sin_addr
.s_addr
= INADDR_ANY
;
136 address
.sin_port
= htons(787);
138 CFDataRef
data(CFDataCreate(kCFAllocatorDefault
, reinterpret_cast<UInt8
*>(&address
), sizeof(address
)));
140 CFSocketSignature signature
;
141 signature
.protocolFamily
= AF_INET
;
142 signature
.socketType
= SOCK_STREAM
;
143 signature
.protocol
= IPPROTO_TCP
;
144 signature
.address
= data
;
146 CFSocketRef
socket(CFSocketCreateWithSocketSignature(kCFAllocatorDefault
, &signature
, kCFSocketAcceptCallBack
, &OnAccept
, NULL
));
147 CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault
, socket
, 0), kCFRunLoopDefaultMode
);
151 CYServer
*server(new CYServer());
152 server
->socket_
= _syscall(socket(PF_UNIX
, SOCK_STREAM
, 0));
154 struct sockaddr_un address
;
155 memset(&address
, 0, sizeof(address
));
156 address
.sun_family
= AF_UNIX
;
158 sprintf(address
.sun_path
, "/tmp/.s.cy");