void HttpClientApp::onConnect( TcpSessionRef session ) { mHttpResponse = HttpResponse(); mSession = session; mText.push_back( "Connected" ); mSession->connectCloseEventHandler( &HttpClientApp::onClose, this ); mSession->connectErrorEventHandler( &HttpClientApp::onError, this ); mSession->connectReadEventHandler( &HttpClientApp::onRead, this ); mSession->connectWriteEventHandler( &HttpClientApp::onWrite, this ); console() << mHttpRequest << endl; mSession->write( mHttpRequest.toBuffer() ); }
void WebClientApp::onReadComplete() { mText.push_back( "Read complete" ); console() << "HTTP version: "; switch ( mHttpResponse.getHttpVersion() ) { case HttpVersion::HTTP_0_9: console() << "0.9"; break; case HttpVersion::HTTP_1_0: console() << "1.0"; break; case HttpVersion::HTTP_1_1: console() << "1.1"; break; case HttpVersion::HTTP_2_0: console() << "2.0"; break; } console() << endl; console() << "Status code: " << mHttpResponse.getStatusCode() << endl; console() << "Reason: " << mHttpResponse.getReason() << endl; console() << "Header fields: " << endl; for ( const KeyValuePair& kvp : mHttpResponse.getHeaders() ) { console() << ">> " << kvp.first << ": " << kvp.second << endl; } console() << endl; console() << "Body:" << endl; console() << HttpResponse::bufferToString( mHttpResponse.getBody() ) << endl; mSession->close(); }
void TcpClientApp::write() { // This sample is meant to work with only one session at a time. if ( mSession && mSession->getSocket()->is_open() ) { // Write data is packaged as a ci::Buffer. This allows // you to send any kind of data. Because it's more common to // work with strings, the session object has static convenience // methods for converting between std::string and ci::Buffer. Buffer buffer = TcpSession::stringToBuffer( mRequest ); mSession->write( buffer ); } else { // Before we can write, we need to establish a connection // and create a session. Check out the onConnect method. mText.push_back( "Connecting to: " + mHost + ":" + toString( mPort ) ); mClient->connect( mHost, (uint16_t)mPort ); } }
void TcpClientApp::onWrite( size_t bytesTransferred ) { mText.push_back( toString( bytesTransferred ) + " bytes written" ); // After successfully sending your request to the server, you // should expect a response. Start reading immediately. mSession->read(); }
void WebClientApp::write() { // This sample is meant to work with only one session at a time if ( mSession && mSession->getSocket()->is_open() ) { return; } mText.push_back( "Connecting to:\n" + mHost + ":" + toString( mPort ) ); mClient->connect( mHost, (uint16_t)mPort ); }
void WebClientApp::onRead( ci::BufferRef buffer ) { mText.push_back(toString( buffer->getSize() ) + " bytes read" ); if ( !mHttpResponse.hasHeader() ) { mHttpResponse.parseHeader( HttpResponse::bufferToString( buffer ) ); buffer = HttpResponse::removeHeader( buffer ); } mHttpResponse.append( buffer ); mSession->read(); }
void TcpClientApp::onConnect( TcpSessionRef session ) { mText.push_back( "Connected" ); // Get the session from the argument and set callbacks. // Note that you can use lambdas. mSession = session; mSession->connectCloseEventHandler( [ & ]() { mText.push_back( "Disconnected" ); } ); mSession->connectErrorEventHandler( &TcpClientApp::onError, this ); mSession->connectReadCompleteEventHandler( [ & ]() { mText.push_back( "Read complete" ); } ); mSession->connectReadEventHandler( &TcpClientApp::onRead, this ); mSession->connectWriteEventHandler( &TcpClientApp::onWrite, this ); write(); }
void TcpClientApp::onRead( ci::Buffer buffer ) { mText.push_back( toString( buffer.getDataSize() ) + " bytes read" ); // Responses are passed in the read callback as ci::Buffer. Use // a convenience method on the session object to convert it to // a std::string. string response = TcpSession::bufferToString( buffer ); mText.push_back( response ); // Closing the connection after reading mimics the behavior // of a HTTP client. To keep the connection open and continue // communicating with the server, comment the line below. mSession->close(); }
void OPCClient::onConnect( TcpSessionRef session ){ ci::app::console()<< "OPCClient::onConnect "<< endl; boost::asio::ip::tcp::no_delay noDelayOption(true); session->getSocket()->set_option(noDelayOption); // Get the session from the argument and set callbacks. // Note that you can use lambdas. mSession = session; mSession->connectCloseEventHandler( [ & ]() { ci::app::console()<< "Disconnected"<< endl; } ); mSession->connectErrorEventHandler( &OPCClient::onError, this ); mSession->connectReadCompleteEventHandler( [ & ]() { ci::app::console()<< "Read complete"<< endl; } ); mConnecting = false; }
void HttpClientApp::write() { if ( mSession && mSession->getSocket()->is_open() ) { return; } // Reset download stats mBytesRead = 0; mContentLength = 0; // Update request body string index = toString( mIndex ); mFilename = index; mHttpRequest.setBody( HttpRequest::stringToBuffer( index ) ); mText.push_back( "Connecting to:\n" + mHost + ":2000" ); // Ports <1024 are restricted to root mClient->connect( mHost, 2000 ); }
void WebClientApp::onWrite( size_t bytesTransferred ) { mText.push_back(toString( bytesTransferred ) + " bytes written" ); mSession->read(); }
void HttpClientApp::onRead( ci::BufferRef buffer ) { size_t sz = buffer->getSize(); mBytesRead += sz; mText.push_back( toString( sz ) + " bytes read" ); if ( !mHttpResponse.hasHeader() ) { // Parse header mHttpResponse.parseHeader( HttpResponse::bufferToString( buffer ) ); buffer = HttpResponse::removeHeader( buffer ); // Get content-length for ( const KeyValuePair& kvp : mHttpResponse.getHeaders() ) { if ( kvp.first == "Content-Length" ) { mContentLength = fromString<size_t>( kvp.second ); break; } } } // Append buffer to body mHttpResponse.append( buffer ); if ( mBytesRead < mContentLength ) { // Keep reading until we hit the content length mSession->read(); } else { mText.push_back( "Read complete" ); mText.push_back( toString( mHttpResponse.getStatusCode() ) + " " + mHttpResponse.getReason() ); if ( mHttpResponse.getStatusCode() == 200 ) { for ( const KeyValuePair& kvp : mHttpResponse.getHeaders() ) { // Choose file extension based on MIME type if ( kvp.first == "Content-Type" ) { string mime = kvp.second; if ( mime == "audio/mp3" ) { mFilename += ".mp3"; } else if ( mime == "image/jpeg" ) { mFilename += ".jpg"; } else if ( mime == "image/png" ) { mFilename += ".png"; } } else if ( kvp.first == "Connection" ) { // Close connection if requested by server if ( kvp.second == "close" ) { mSession->close(); } } } // Save the file fs::path path = getAppPath(); #if !defined ( CINDER_MSW ) path = path.parent_path(); #endif path = path / mFilename; OStreamFileRef file = writeFileStream( path ); file->write( mHttpResponse.getBody() ); mText.push_back( mFilename + " downloaded" ); } else { // Write error mText.push_back( "Response: " + HttpResponse::bufferToString( mHttpResponse.getBody() ) ); mSession->close(); } } }