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; } }
CF::String URL::GetStrictPath( void ) { CF::String str; CFStringRef cfStr; if( this->_cfObject == NULL ) { return str; } cfStr = CFURLCopyStrictPath( this->_cfObject, NULL ); if( cfStr != NULL ) { str = cfStr; CFRelease( cfStr ); } return str; }
/* * We need to separate the share name and any path component from the URL. * URL "smb://*****:*****@server" no share name or path. * URL "smb://*****:*****@server/"no share name or path. * URL "smb://*****:*****@server/share" just a share name. * URL "smb://*****:*****@server/share/path" share name and path. * * The Share name and Path name will not begin with a slash. * smb://server/ntfs share = ntfs path = NULL * smb://ntfs/dir1/dir2 share = ntfs path = dir1/dir2 * smb://server/OPEN%2fSPACE/dir1 share = OPEN%2fSPACE path = dir1 */ static int GetShareAndPathFromURL(CFURLRef url, CFStringRef *out_share, CFStringRef *out_path) { Boolean isAbsolute; CFArrayRef userArray = NULL; CFMutableArrayRef userArrayM = NULL; CFStringRef share = CFURLCopyStrictPath(url, &isAbsolute); CFStringRef path = NULL; *out_share = NULL; *out_path = NULL; /* We have an empty share treat it like no share */ if (share && (CFStringGetLength(share) == 0)) { CFRelease(share); share = NULL; } /* Since there is no share name we have nothing left to do. */ if (!share) return 0; userArray = CFStringCreateArrayBySeparatingStrings(NULL, share, CFSTR("/")); if (userArray && (CFArrayGetCount(userArray) > 1)) userArrayM = CFArrayCreateMutableCopy(NULL, CFArrayGetCount(userArray), userArray); if (userArray) CFRelease(userArray); if (userArrayM) { CFMutableStringRef newshare; /* Just in case something goes wrong */ newshare = CFStringCreateMutableCopy(NULL, 0, (CFStringRef)CFArrayGetValueAtIndex(userArrayM, 0)); if (newshare) { CFStringTrim(newshare, CFSTR("/")); /* Remove any trailing slashes */ CreateStringByReplacingPercentEscapesUTF8((CFStringRef *) &newshare, CFSTR("/")); } CFArrayRemoveValueAtIndex(userArrayM, 0); /* Now remove any trailing slashes */ path = CFStringCreateByCombiningStrings(NULL, userArrayM, CFSTR("/")); if (path && (CFStringGetLength(path) == 0)) { CFRelease(path); /* Empty path remove it */ path = NULL; } if (path) { CFMutableStringRef newpath = CFStringCreateMutableCopy(NULL, 0, path); if (newpath) { CFStringTrim(newpath, CFSTR("/")); /* Remove any trailing slashes */ CFRelease(path); path = newpath; } } if (path) { CreateStringByReplacingPercentEscapesUTF8(&path, CFSTR("/")); LogCFString(path, "Path", __FUNCTION__, __LINE__); } CFRelease(userArrayM); /* Something went wrong use the original value */ if (newshare) { CFRelease(share); share = newshare; } } else CreateStringByReplacingPercentEscapesUTF8(&share, CFSTR("/")); /* * The above routines will not un-precent escape out slashes. We only allow for the cases * where the share name is a single slash. Slashes are treated as delemiters in the path name. * So if the share name has a single 0x2f then make it a slash. This means you can't have * a share name whos name is 0x2f, not likley to happen. */ if (share && ( kCFCompareEqualTo == CFStringCompare (share, CFSTR("0x2f"), kCFCompareCaseInsensitive) )) { CFRelease(share); share = CFStringCreateCopy(NULL, CFSTR("/")); } if (share && (CFStringGetLength(share) >= SMB_MAXSHARENAMELEN)) { CFRelease(share); if (path) CFRelease(path); return ENAMETOOLONG; } *out_share = share; *out_path = path; return 0; }
string URL::path() const { Boolean isAbsolute; return "/" + mkstr(CFURLCopyStrictPath(ref, &isAbsolute)); }