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: { CFStreamError error = CFReadStreamGetError(m_readStream.get()); m_client->didFail(this, SocketStreamError(error.error)); // FIXME: Provide a sensible error. break; } case kCFStreamEventEndEncountered: platformClose(); 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) { 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; } }