1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2012 Jay Freeman (saurik)
5 /* GNU Lesser General Public License, Version 3 {{{ */
7 * Cycript is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
12 * Cycript is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with Cycript. If not, see <http://www.gnu.org/licenses/>.
22 #include <Pooling.hpp>
24 #include <apr_thread_proc.h>
26 #include <CoreFoundation/CFLogUtilities.h>
27 #include <CFNetwork/CFNetwork.h>
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
35 CFHTTPMessageRef message_
;
39 static void OnData(CFSocketRef socket
, CFSocketCallBackType type
, CFDataRef address
, const void *value
, void *info
) {
41 case kCFSocketDataCallBack
:
42 CFDataRef
data(reinterpret_cast<CFDataRef
>(value
));
43 Client
*client(reinterpret_cast<Client
*>(info
));
45 if (client
->message_
== NULL
)
46 client
->message_
= CFHTTPMessageCreateEmpty(kCFAllocatorDefault
, TRUE
);
48 if (!CFHTTPMessageAppendBytes(client
->message_
, CFDataGetBytePtr(data
), CFDataGetLength(data
)))
49 CFLog(kCFLogLevelError
, CFSTR("CFHTTPMessageAppendBytes()"));
50 else if (CFHTTPMessageIsHeaderComplete(client
->message_
)) {
51 CFURLRef
url(CFHTTPMessageCopyRequestURL(client
->message_
));
53 CFStringRef
path(CFURLCopyStrictPath(url
, &absolute
));
54 CFRelease(client
->message_
);
56 CFStringRef
code(CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault
, path
, CFSTR("")));
59 JSStringRef
script(JSStringCreateWithCFString(code
));
62 JSValueRef
result(JSEvaluateScript(CYGetJSContext(), script
, NULL
, NULL
, 0, NULL
));
63 JSStringRelease(script
);
65 CFHTTPMessageRef
response(CFHTTPMessageCreateResponse(kCFAllocatorDefault
, 200, NULL
, kCFHTTPVersion1_1
));
66 CFHTTPMessageSetHeaderFieldValue(response
, CFSTR("Content-Type"), CFSTR("application/json; charset=utf-8"));
68 CFStringRef
json(CYCopyJSONString(CYGetJSContext(), result
, NULL
));
69 CFDataRef
body(CFStringCreateExternalRepresentation(kCFAllocatorDefault
, json
, kCFStringEncodingUTF8
, NULL
));
72 CFStringRef
length(CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%u"), CFDataGetLength(body
)));
73 CFHTTPMessageSetHeaderFieldValue(response
, CFSTR("Content-Length"), length
);
76 CFHTTPMessageSetBody(response
, body
);
79 CFDataRef
serialized(CFHTTPMessageCopySerializedMessage(response
));
82 CFSocketSendData(socket
, NULL
, serialized
, 0);
83 CFRelease(serialized
);
91 static void OnAccept(CFSocketRef socket
, CFSocketCallBackType type
, CFDataRef address
, const void *value
, void *info
) {
93 case kCFSocketAcceptCallBack
:
94 Client
*client(new Client());
96 client
->message_
= NULL
;
98 CFSocketContext context
;
100 context
.info
= client
;
101 context
.retain
= NULL
;
102 context
.release
= NULL
;
103 context
.copyDescription
= NULL
;
105 client
->socket_
= CFSocketCreateWithNative(kCFAllocatorDefault
, *reinterpret_cast<const CFSocketNativeHandle
*>(value
), kCFSocketDataCallBack
, &OnData
, &context
);
107 CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault
, client
->socket_
, 0), kCFRunLoopDefaultMode
);
112 int main(int argc
, char *argv
[]) {
114 struct sockaddr_in address
;
115 address
.sin_len
= sizeof(address
);
116 address
.sin_family
= AF_INET
;
117 address
.sin_addr
.s_addr
= INADDR_ANY
;
118 address
.sin_port
= htons(787);
120 CFDataRef
data(CFDataCreate(kCFAllocatorDefault
, reinterpret_cast<UInt8
*>(&address
), sizeof(address
)));
122 CFSocketSignature signature
;
123 signature
.protocolFamily
= AF_INET
;
124 signature
.socketType
= SOCK_STREAM
;
125 signature
.protocol
= IPPROTO_TCP
;
126 signature
.address
= data
;
128 CFSocketRef
socket(CFSocketCreateWithSocketSignature(kCFAllocatorDefault
, &signature
, kCFSocketAcceptCallBack
, &OnAccept
, NULL
));
129 CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault
, socket
, 0), kCFRunLoopDefaultMode
);
133 CYServer
*server(new CYServer());
134 server
->socket_
= _syscall(socket(PF_UNIX
, SOCK_STREAM
, 0));
136 struct sockaddr_un address
;
137 memset(&address
, 0, sizeof(address
));
138 address
.sun_family
= AF_UNIX
;
140 sprintf(address
.sun_path
, "/tmp/.s.cy");