コード例 #1
0
ファイル: server.c プロジェクト: JustSid/extip
static void FetchIPAddress()
{
	if(publicIPState == IPStateFetching)
		return;

	publicIPState = IPStateFetching;

	const UInt8 bodyBytes[] = {0};
	CFDataRef body = CFDataCreate(kCFAllocatorDefault, bodyBytes, 0);

	CFURLRef url = CFURLCreateWithString(kCFAllocatorDefault, CFSTR("http://icanhazip.com"), NULL);
	CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), url, kCFHTTPVersion1_1);
	CFHTTPMessageSetBody(request, body);

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

	// Apple suggests the NSURLSession API instead of CFReadStreamCreateForHTTPRequest,
	// But obviously that doesn't really work here

	CFReadStreamRef stream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request);

#pragma clang diagnostic pop

	CFRelease(body);
	CFRelease(url);
	CFRelease(request);

	CFMutableDataRef responseData = CFDataCreateMutable(kCFAllocatorDefault, 17);
	CFStreamClientContext context = { 0, responseData, NULL, NULL, NULL };

	if(!CFReadStreamSetClient(stream, kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable | kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred, &IPStreamCallback, &context))
	{
		CFRelease(stream);

		publicIPState = IPStateInvalid;
		return;
	}

	// Add to the run loop and open the stream
	CFReadStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);

	if(!CFReadStreamOpen(stream))
	{
		CFReadStreamSetClient(stream, 0, NULL, NULL);
		CFReadStreamUnscheduleFromRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
		CFRelease(stream);

		publicIPState = IPStateInvalid;
		return;
	}


	// Run the run loop
	do {
		CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, TRUE);
	} while(publicIPState == IPStateFetching);
}
コード例 #2
0
CFReadStreamRef HTTP_Stream::createReadStream(CFURLRef url)
{
    CFReadStreamRef readStream = 0;
    CFHTTPMessageRef request = 0;
    CFDictionaryRef proxySettings = 0;
    
    Stream_Configuration *config = Stream_Configuration::configuration();
    
    if (!(request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, httpRequestMethod, url, kCFHTTPVersion1_1))) {
        goto out;
    }
    
    if (config->userAgent) {
        CFHTTPMessageSetHeaderFieldValue(request, httpUserAgentHeader, config->userAgent);
    }
    
    CFHTTPMessageSetHeaderFieldValue(request, icyMetaDataHeader, icyMetaDataValue);
    
    if (m_position.start > 0 && m_position.end > m_position.start) {
        CFStringRef rangeHeaderValue = CFStringCreateWithFormat(NULL,
                                                                NULL,
                                                                CFSTR("bytes=%llu-%llu"),
                                                                m_position.start,
                                                                m_position.end);
        
        CFHTTPMessageSetHeaderFieldValue(request, httpRangeHeader, rangeHeaderValue);
        CFRelease(rangeHeaderValue);
    }
    
    if (!(readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request))) {
        goto out;
    }
    
    CFReadStreamSetProperty(readStream,
                            kCFStreamPropertyHTTPShouldAutoredirect,
                            kCFBooleanTrue);
    
    proxySettings = CFNetworkCopySystemProxySettings();
    if (proxySettings) {
        CFReadStreamSetProperty(readStream, kCFStreamPropertyHTTPProxy, proxySettings);
        CFRelease(proxySettings);
    }
    
out:
    if (request) {
        CFRelease(request);
    }
    
    return readStream;
}
コード例 #3
0
/* Return true, iff we didn't schedule any work, return false if we did. */
bool asynchttp_request(CFHTTPMessageRef request, asynchttp_t *http) {
    secdebug("http", "request %@", request);
    if (request) {
        http->request = request;
        CFRetain(request);
    }

    /* Create the stream for the request. */
    require_quiet(http->stream = CFReadStreamCreateForHTTPRequest(
        kCFAllocatorDefault, http->request), errOut);

	/* Set a reasonable timeout */
    require_quiet(http->timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, http->queue), errOut);
    dispatch_source_set_event_handler(http->timer, ^{
        asynchttp_timer_proc(http);
    });
コード例 #4
0
void HTTPLoader::load(CFURLRef url)
{
  CFHTTPMessageRef request = CFHTTPMessageCreateRequest(NULL, CFSTR("GET"), url, kCFHTTPVersion1_1);
  mStream = CFReadStreamCreateForHTTPRequest(NULL, request);
  CFRelease(request);
  
  if (!CFReadStreamOpen(mStream)) {
    CFRelease(mStream);
    mStream = 0;
  } else {
    CFStreamClientContext context = {0, this, NULL, NULL, NULL};
    CFReadStreamSetClient(mStream, 
                          kCFStreamEventHasBytesAvailable |
                          kCFStreamEventErrorOccurred |
                          kCFStreamEventEndEncountered, 
                          readStreamCallback, 
                          &context);
    CFReadStreamScheduleWithRunLoop(mStream, 
                                    CFRunLoopGetCurrent(), 
                                    kCFRunLoopCommonModes);
  }
}
static void send_request(
    SG_context* pCtx,
    CFHTTPMessageRef myRequest,
    CFReadStreamRef* pp
)
{
    CFReadStreamRef myReadStream = NULL;

    myReadStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest);

    if (!CFReadStreamOpen(myReadStream))
    {
        CFStreamError myErr = CFReadStreamGetError(myReadStream);

        if (myErr.domain == kCFStreamErrorDomainPOSIX)
        {
            // Interpret myErr.error as a UNIX errno.
            SG_ERR_THROW(  SG_ERR_ERRNO(myErr.error)  );
        }
        else if (myErr.domain == kCFStreamErrorDomainMacOSStatus)
        {
            // Interpret myErr.error as a MacOS error code.
            // TODO SG_ERR_THROW(  SG_ERR_MAC((OSStatus) myErr.error)  );
            SG_ERR_THROW(  SG_ERR_UNSPECIFIED  );
        }
    }

    *pp = myReadStream;
    myReadStream = NULL;

fail:
    if (myReadStream)
    {
        CFReadStreamClose(myReadStream);
        CFRelease(myReadStream);
        myReadStream = NULL;
    }
}
コード例 #6
0
nuiHTTPResponse* nuiHTTPRequest::SendRequest()
{
  char* pUrl = mUrl.Export();
	
  CFStringRef originalURLString = CFStringCreateWithCString(kCFAllocatorDefault, pUrl, kCFStringEncodingUTF8);
	
  CFStringRef preprocessedString =
  CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, originalURLString, CFSTR(""), kCFStringEncodingUTF8);
  CFStringRef urlString =
  CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, preprocessedString, NULL, NULL, kCFStringEncodingUTF8);
	
  free(pUrl);
  CFURLRef url = CFURLCreateWithString(kCFAllocatorDefault, urlString, NULL);
  CFRelease(urlString);
  
  char* pMeth = mMethod.Export(); 
  CFStringRef method = CFStringCreateWithCString(kCFAllocatorDefault, pMeth, kCFStringEncodingUTF8);
  free(pMeth);
  
  CFHTTPMessageRef req = CFHTTPMessageCreateRequest(kCFAllocatorDefault, method, url, kCFHTTPVersion1_1);
  
  CFStringRef userAgentField = CFSTR("User-Agent");
  CFStringRef userAgentName = CFSTR("nuiHTTP/2.0");
  CFHTTPMessageSetHeaderFieldValue(req, userAgentField, userAgentName);
  CFRelease(userAgentField);
  CFRelease(userAgentName);
  
  nuiHTTPHeaderMap::const_iterator end = mHeaders.end();
  for (nuiHTTPHeaderMap::const_iterator it = mHeaders.begin(); it != end; ++it)
  {
    char* pName = it->first.Export();
    char* pVal = it->second.Export();
    CFStringRef fieldName = CFStringCreateWithCString(kCFAllocatorDefault, pName, kCFStringEncodingUTF8);
    CFStringRef fieldValue = CFStringCreateWithCString(kCFAllocatorDefault, pVal, kCFStringEncodingUTF8);
    
    CFHTTPMessageSetHeaderFieldValue(req, fieldName, fieldValue);
    
    CFRelease(fieldName);
    CFRelease(fieldValue);
    delete pName;
    delete pVal;
  }
  
  CFDataRef body = NULL;
  if (mBody.size())
  {
    body = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8*)&mBody[0], mBody.size(), kCFAllocatorNull);
    CFHTTPMessageSetBody(req, body);
  }
  
  CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, req);
  CFReadStreamOpen(readStream);
  
  std::vector<char> buf;
  CFIndex pos = 0;
  CFIndex size = 0;
  bool cont = true;
  do
  {
    buf.resize(pos + 1024);
    size = CFReadStreamRead(readStream, (UInt8*)&buf[pos], 1024);
    if (size == -1)
    {
      return NULL;
    }
    else if (size == 0)
    {
      if (CFReadStreamGetStatus(readStream) == kCFStreamStatusAtEnd)
        cont = false;
      else
        nglThread::MsSleep(10);
    }
    
    pos += size;
  }
  while (cont);
  
  CFHTTPMessageRef responseHeader = (CFHTTPMessageRef)CFReadStreamCopyProperty(readStream, kCFStreamPropertyHTTPResponseHeader);
  
  CFStringRef statusLine = CFHTTPMessageCopyResponseStatusLine(responseHeader);
  CFIndex strSize = CFStringGetLength(statusLine)+1;
  char* pStatus = new char[strSize];
  CFStringGetCString(statusLine, pStatus, strSize, kCFStringEncodingUTF8);
  nglString status(pStatus);
  
  UInt32 statusCode = CFHTTPMessageGetResponseStatusCode(responseHeader);
  
  nuiHTTPResponse* pResponse = new nuiHTTPResponse(statusCode, status);
  pResponse->SetBody(&buf[0], pos);
  
  delete[] pStatus;
  
  CFDictionaryRef dict = CFHTTPMessageCopyAllHeaderFields(responseHeader);
  CFIndex valueCount = CFDictionaryGetCount(dict);
  const CFStringRef* pNames = new CFStringRef[valueCount];
  const CFStringRef* pValues = new CFStringRef[valueCount];
  CFDictionaryGetKeysAndValues(dict, (const void**)pNames, (const void**)pValues);
  for (CFIndex i = 0; i< valueCount; i++)
  {
    strSize = CFStringGetLength(pNames[i])+1;
    char* pName = new char[strSize];
    CFStringGetCString(pNames[i], pName, strSize, kCFStringEncodingUTF8);
    
    strSize = CFStringGetLength(pValues[i])+1;
    char* pVal = new char[strSize];
    CFStringGetCString(pValues[i], pVal, strSize, kCFStringEncodingUTF8);
    
    nglString name(pName);
    nglString val(pVal);
    pResponse->AddHeader(name, val);
    
    delete[] pName;
    delete[] pVal;
  }
  delete[] pNames;
  delete[] pValues;
  
  CFRelease(responseHeader);
  CFRelease(url);
  CFRelease(method);
  CFRelease(req);
  CFRelease(readStream);
  CFRelease(dict);
  CFRelease(statusLine);
  if (body)
    CFRelease(body);
  
  return pResponse;
}
コード例 #7
0
char* DotMacQuery::ReadStream (CFURLRef url, size_t &responseLength)
{
	SInt32 ito;
	CFNumberRef cfnTo = NULL;
	CFDictionaryRef proxyDict = NULL;
	
	// make a connection to the provided URL
	CFHTTPMessageRef httpRequestRef = CFHTTPMessageCreateRequest (kCFAllocatorDefault, CFSTR("GET"), url, kCFHTTPVersion1_1);
	if (httpRequestRef == NULL)
	{
		CSSMError::ThrowCSSMError (CSSMERR_DL_RECORD_NOT_FOUND);
	}
	
	// open the stream
	CFReadStreamRef httpStreamRef = CFReadStreamCreateForHTTPRequest (kCFAllocatorDefault, httpRequestRef);
	if (httpStreamRef == NULL)
	{
		CSSMError::ThrowCSSMError (CSSMERR_DL_RECORD_NOT_FOUND);
	}

	// set a reasonable timeout
	ito = READ_STREAM_TIMEOUT;
	cfnTo = CFNumberCreate(NULL, kCFNumberSInt32Type, &ito);
    if(!CFReadStreamSetProperty(httpStreamRef, _kCFStreamPropertyReadTimeout, cfnTo)) {
		// oh well - keep going 
	}
	
	/* set up possible proxy info */
	proxyDict = SCDynamicStoreCopyProxies(NULL);
	if(proxyDict) {
		CFReadStreamSetProperty(httpStreamRef, kCFStreamPropertyHTTPProxy, proxyDict);
	}

	if (CFReadStreamOpen (httpStreamRef) == false)
	{
		CFRelease(httpRequestRef);
		CFRelease(httpStreamRef);
		CFRelease(cfnTo);
		if(proxyDict) {
			CFRelease(proxyDict);
		}
		CSSMError::ThrowCSSMError (CSSMERR_DL_RECORD_NOT_FOUND);
	}
	
	char* response = (char*) malloc (kResponseIncrement);
	size_t responseBufferLength = kResponseIncrement;
	responseLength = 0;

	// read data from the stream
	CFIndex bytesRead = CFReadStreamRead (httpStreamRef, (UInt8*) response + responseLength, kResponseIncrement);
	while (bytesRead > 0)
	{
		responseLength += bytesRead;
		responseBufferLength = responseLength + kResponseIncrement;
		response = (char*) realloc (response, responseBufferLength);
		
		bytesRead = CFReadStreamRead (httpStreamRef, (UInt8*) response + responseLength, kResponseIncrement);
	}
	
	CFRelease (httpRequestRef);
	CFRelease (httpStreamRef);
	CFRelease(cfnTo);
	if(proxyDict) {
		CFRelease(proxyDict);
	}

	// check for error
	if (bytesRead < 0)
	{
		CSSMError::ThrowCSSMError (CSSMERR_DL_RECORD_NOT_FOUND);
	}
	
	return response;
}