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