void HTTPInputSource::HandleNetworkEvent(CFReadStreamRef stream, CFStreamEventType type) { switch(type) { case kCFStreamEventOpenCompleted: mOffset = mDesiredOffset; break; case kCFStreamEventHasBytesAvailable: if(nullptr == mResponseHeaders) { CFTypeRef responseHeader = CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader); if(responseHeader) { mResponseHeaders = CFHTTPMessageCopyAllHeaderFields(static_cast<CFHTTPMessageRef>(const_cast<void *>(responseHeader))); CFRelease(responseHeader), responseHeader = nullptr; } } break; case kCFStreamEventErrorOccurred: { CFErrorRef error = CFReadStreamCopyError(stream); if(error) { LOGGER_ERR("org.sbooth.AudioEngine.InputSource.HTTP", "Error: " << error); CFRelease(error), error = nullptr; } break; } case kCFStreamEventEndEncountered: mEOSReached = true; break; } }
CFDictionaryRef download_file(int socket, CFDictionaryRef dict) { UInt8 buffer[8192]; CFIndex bytesRead; CFStringRef path = CFDictionaryGetValue(dict, CFSTR("Path")); if(path == NULL || CFGetTypeID(path) != CFStringGetTypeID()) return NULL; CFMutableDictionaryRef out = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFURLRef fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, kCFURLPOSIXPathStyle, FALSE); CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, fileURL); CFRelease(fileURL); if(!CFReadStreamOpen(stream)) { CFErrorRef error = CFReadStreamCopyError(stream); if (error != NULL) { CFStringRef errorDesc = CFErrorCopyDescription(error); CFDictionaryAddValue(out, CFSTR("Error"), errorDesc); CFRelease(errorDesc); CFRelease(error); } CFRelease(stream); return out; } CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0); while(CFReadStreamHasBytesAvailable(stream)) { if((bytesRead = CFReadStreamRead(stream, buffer, 8192)) <= 0) break; CFDataAppendBytes(data, buffer, bytesRead); } CFReadStreamClose(stream); CFRelease(stream); CFDictionaryAddValue(out, CFSTR("Data"), data); CFRelease(data); return out; }
void HTTPInputSource::HandleNetworkEvent(CFReadStreamRef stream, CFStreamEventType type) { switch(type) { case kCFStreamEventOpenCompleted: mOffset = mDesiredOffset; break; case kCFStreamEventHasBytesAvailable: if(NULL == mResponseHeaders) { CFTypeRef responseHeader = CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader); if(responseHeader) mResponseHeaders = CFHTTPMessageCopyAllHeaderFields(static_cast<CFHTTPMessageRef>(const_cast<void *>(responseHeader))); } break; case kCFStreamEventErrorOccurred: CFShow(CFReadStreamCopyError(stream)); break; case kCFStreamEventEndEncountered: mEOSReached = true; break; } }
void SocketStreamHandle::readStreamCallback(CFStreamEventType type) { switch(type) { case kCFStreamEventNone: break; case kCFStreamEventOpenCompleted: break; case kCFStreamEventHasBytesAvailable: { if (m_connectingSubstate == WaitingForConnect) { if (m_connectionType == CONNECTProxy) { RetainPtr<CFHTTPMessageRef> proxyResponse(AdoptCF, wkCopyCONNECTProxyResponse(m_readStream.get(), m_httpsURL.get())); if (proxyResponse && (407 == CFHTTPMessageGetResponseStatusCode(proxyResponse.get()))) { addCONNECTCredentials(proxyResponse.get()); return; } } } else if (m_connectingSubstate == WaitingForCredentials) break; if (m_connectingSubstate == WaitingForConnect) { m_connectingSubstate = Connected; m_state = Open; RefPtr<SocketStreamHandle> protect(this); // The client can close the handle, potentially removing the last reference. m_client->didOpen(this); if (m_state == Closed) break; // Fall through. } else if (m_state == Closed) break; ASSERT(m_state == Open); ASSERT(m_connectingSubstate == Connected); CFIndex length; UInt8 localBuffer[1024]; // Used if CFReadStreamGetBuffer couldn't return anything. const UInt8* ptr = CFReadStreamGetBuffer(m_readStream.get(), 0, &length); if (!ptr) { length = CFReadStreamRead(m_readStream.get(), localBuffer, sizeof(localBuffer)); ptr = localBuffer; } m_client->didReceiveData(this, reinterpret_cast<const char*>(ptr), length); break; } case kCFStreamEventCanAcceptBytes: ASSERT_NOT_REACHED(); break; case kCFStreamEventErrorOccurred: { #ifndef BUILDING_ON_TIGER RetainPtr<CFErrorRef> error(AdoptCF, CFReadStreamCopyError(m_readStream.get())); reportErrorToClient(error.get()); #else CFStreamError error = CFReadStreamGetError(m_readStream.get()); m_client->didFail(this, SocketStreamError(error.error)); // FIXME: Provide a sensible error. #endif break; } case kCFStreamEventEndEncountered: platformClose(); break; } }
void __CFReadStreamClientCallBack(CFReadStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo) { // Extract the context tnet_transport_t *transport = (tnet_transport_t *) clientCallBackInfo; transport_context_t *context = transport->context; /* lock context */ tsk_safeobj_lock(context); // Extract the native socket CFDataRef data = CFReadStreamCopyProperty(stream, kCFStreamPropertySocketNativeHandle); CFSocketNativeHandle fd; CFDataGetBytes(data, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8*) &fd); CFRelease(data); transport_socket_t *sock = (transport_socket_t *) getSocket(context, fd); switch(eventType) { case kCFStreamEventOpenCompleted: { TSK_DEBUG_INFO("__CFReadStreamClientCallBack --> kCFStreamEventOpenCompleted"); break; } case kCFStreamEventHasBytesAvailable: { tsk_size_t len = 0; void *buffer = 0; tnet_transport_event_t* e; // Allocate a standard buffer len = TNET_BUFFER_SIZE; if (!(buffer = tsk_calloc(len, sizeof(uint8_t)))) { TSK_DEBUG_ERROR("TSK_CALLOC FAILED."); break; } // Process to read data CFIndex index = CFReadStreamRead(stream, buffer, TNET_BUFFER_SIZE); len = index; TSK_DEBUG_INFO("__CFReadStreamClientCallBack --> %u bytes read", len); e = tnet_transport_event_create(event_data, transport->callback_data, sock->fd); e->data = buffer; e->size = len; TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(transport), e); break; } case kCFStreamEventEndEncountered: case kCFStreamEventErrorOccurred: { // Get the error code CFErrorRef error = CFReadStreamCopyError(stream); CFIndex index = CFErrorGetCode(error); CFRelease(error); TSK_DEBUG_INFO("__CFReadStreamClientCallBack --> Error %lu", index); TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, sock->fd); removeSocket(sock, context); break; } default: { // Not Implemented assert(42 == 0); break; } } /* unlock context */ tsk_safeobj_unlock(context); }
void SocketStreamHandle::readStreamCallback(CFStreamEventType type) { switch(type) { case kCFStreamEventNone: break; case kCFStreamEventOpenCompleted: break; case kCFStreamEventHasBytesAvailable: { if (m_connectingSubstate == WaitingForConnect) { if (m_connectionType == CONNECTProxy) { RetainPtr<CFHTTPMessageRef> proxyResponse(AdoptCF, wkCopyCONNECTProxyResponse(m_readStream.get(), m_httpsURL.get())); if (proxyResponse) { CFIndex proxyResponseCode = CFHTTPMessageGetResponseStatusCode(proxyResponse.get()); switch (proxyResponseCode) { case 200: // Successful connection. break; case 407: addCONNECTCredentials(proxyResponse.get()); return; default: m_client->didFailSocketStream(this, SocketStreamError(static_cast<int>(proxyResponseCode), m_url.string(), "Proxy connection could not be established")); platformClose(); return; } } } } else if (m_connectingSubstate == WaitingForCredentials) break; if (m_connectingSubstate == WaitingForConnect) { m_connectingSubstate = Connected; m_state = Open; m_client->didOpenSocketStream(this); if (m_state == Closed) break; // Fall through. } else if (m_state == Closed) break; ASSERT(m_state == Open); ASSERT(m_connectingSubstate == Connected); CFIndex length; UInt8 localBuffer[1024]; // Used if CFReadStreamGetBuffer couldn't return anything. const UInt8* ptr = CFReadStreamGetBuffer(m_readStream.get(), 0, &length); if (!ptr) { length = CFReadStreamRead(m_readStream.get(), localBuffer, sizeof(localBuffer)); ptr = localBuffer; } m_client->didReceiveSocketStreamData(this, reinterpret_cast<const char*>(ptr), length); break; } case kCFStreamEventCanAcceptBytes: ASSERT_NOT_REACHED(); break; case kCFStreamEventErrorOccurred: { RetainPtr<CFErrorRef> error(AdoptCF, CFReadStreamCopyError(m_readStream.get())); reportErrorToClient(error.get()); break; } case kCFStreamEventEndEncountered: platformClose(); break; } }
void HTTP_Stream::readCallBack(CFReadStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo) { HTTP_Stream *THIS = static_cast<HTTP_Stream*>(clientCallBackInfo); Stream_Configuration *config = Stream_Configuration::configuration(); switch (eventType) { case kCFStreamEventHasBytesAvailable: { if (!THIS->m_httpReadBuffer) { THIS->m_httpReadBuffer = new UInt8[config->httpConnectionBufferSize]; } while (CFReadStreamHasBytesAvailable(stream)) { if (!THIS->m_scheduledInRunLoop) { /* * This is critical - though the stream has data available, * do not try to feed the audio queue with data, if it has * indicated that it doesn't want more data due to buffers * full. */ THIS->m_readPending = true; break; } CFIndex bytesRead = CFReadStreamRead(stream, THIS->m_httpReadBuffer, config->httpConnectionBufferSize); if (CFReadStreamGetStatus(stream) == kCFStreamStatusError || bytesRead < 0) { #if defined (HS_DEBUG) CFErrorRef streamError = CFReadStreamCopyError(stream); if (streamError) { CFStringRef errorDesc = CFErrorCopyDescription(streamError); if (errorDesc) { HS_TRACE_CFSTRING(errorDesc); CFRelease(errorDesc); } CFRelease(streamError); } #endif /* HS_DEBUG */ if (THIS->m_delegate) { THIS->m_delegate->streamErrorOccurred(); } break; } if (bytesRead > 0) { HS_TRACE("Read %li bytes\n", bytesRead); THIS->parseHttpHeadersIfNeeded(THIS->m_httpReadBuffer, bytesRead); #ifdef INCLUDE_ID3TAG_SUPPORT if (!THIS->m_icyStream && THIS->m_id3Parser->wantData()) { THIS->m_id3Parser->feedData(THIS->m_httpReadBuffer, (UInt32)bytesRead); } #endif if (THIS->m_icyStream) { HS_TRACE("Parsing ICY stream\n"); THIS->parseICYStream(THIS->m_httpReadBuffer, bytesRead); } else { if (THIS->m_delegate) { HS_TRACE("Not an ICY stream; calling the delegate back\n"); THIS->m_delegate->streamHasBytesAvailable(THIS->m_httpReadBuffer, (UInt32)bytesRead); } } } } break; } case kCFStreamEventEndEncountered: { if (THIS->m_delegate) { THIS->m_delegate->streamEndEncountered(); } break; } case kCFStreamEventErrorOccurred: { if (THIS->m_delegate) { THIS->m_delegate->streamErrorOccurred(); } break; } } }