int CgidConn::sendReqBody( const char * pBuf, int size ) { int ret; if ( m_iTotalPending == 0 ) { ret = write( pBuf, size ); } else { IOVec iov; iov.append( m_pPendingBuf, m_iTotalPending ); iov.append( pBuf, size ); ret = writev( iov ); if ( ret >= m_iTotalPending ) { ret = ret - m_iTotalPending; m_iTotalPending = 0; } else if ( ret > 0 ) { m_iTotalPending -= ret; m_pPendingBuf += ret; ret = 0; } } return ret; }
int BufferedOS::writevEx( IOVec &vec, int avoidCache ) { assert( m_pOS != NULL ); int ret; if ( !m_buf.empty() ) { int oldLen = vec.len(); m_buf.iov_insert( vec ); //FIXME: DEBUG Code //ret = 0; ret = m_pOS->writev( vec ); vec.pop_front( vec.len() - oldLen ); if ( ret > 0 ) { int pop = ret; if ( pop > m_buf.size() ) pop = m_buf.size(); m_buf.pop_front( pop ); ret -= pop; } } else //FIXME: DEBUG Code //ret = 0; ret = m_pOS->writev( vec ); if ( ret >= avoidCache ) { ret = m_buf.cache( vec.get(), vec.len(), ret ); } //if ( D_ENABLED( DL_MORE ) ) // LOG_D(( "bufferedOS::writev() return %d, %d bytes in cache\n", ret, m_buf.size() )); return ret; }
int BufferedOS::cacheWritev(IOVec &vector, int total) { if (m_buf.size() + total < 40960) { m_buf.cache(vector.get(), vector.len(), 0); return total; } else return writevEx(vector, 0); }
int BufferedOS::writevEx(IOVec &vec, int avoidCache) { assert(m_pOS != NULL); int ret; if (!m_buf.empty()) { int oldLen = vec.len(); m_buf.iovInsert(vec); //TEST: DEBUG Code //ret = 0; ret = m_pOS->writev(vec.get(), vec.len()); vec.pop_front(vec.len() - oldLen); if (ret > 0) { int pop = ret; if (pop > m_buf.size()) pop = m_buf.size(); m_buf.pop_front(pop); ret -= pop; } } else //TEST: DEBUG Code //ret = 0; ret = m_pOS->writev(vec.get(), vec.len()); if (ret >= avoidCache) ret = m_buf.cache(vec.get(), vec.len(), ret); //LS_DBG_H( "bufferedOS::writev() return %d, %d bytes in cache\n", ret, m_buf.size()); return ret; }
int SpdyStream::write(const char *buf, int len) { IOVec iov; int allowed; if (getState() == HIOS_DISCONNECTED) return LS_FAIL; allowed = getDataFrameSize(len); if (allowed <= 0) return 0; iov.append(buf, allowed); if (sendData(&iov, allowed) == -1) return LS_FAIL; return allowed; }
int ChunkOutputStream::buildIovec( IOVec& iovec, const char * pBuf, int size ) { int total = safe_snprintf( m_headerBuf, CHUNK_HEADER_SIZE, "%x\r\n", size + m_iCurSize ); iovec.append( m_headerBuf, total ); if ( m_iCurSize ) { iovec.append( m_bufChunk, m_iCurSize ); total += m_iCurSize; } if ( pBuf ) { iovec.append( (void *)pBuf, size ); total += size; } iovec.append( s_CRLF, 2 ); return total + 2; }
int writev( IOVec& iov ) { m_count = !m_count; if ( m_count ) { m_buf.append( (char *)(iov.begin()->iov_base), 1 ); return 1; } else return 0; }
void CheckIoHeader(IOVec io, char *phBuf) { IOVec::iterator it; unsigned char *p = NULL; char *ph = phBuf; //printf("->&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n"); for (it = io.begin(); it != io.end(); ++it) { p = (unsigned char *)it->iov_base; printf("Check: %.*s, %.*s\n", it->iov_len, p, it->iov_len, ph); CHECK(strncasecmp((const char *)p, ph, it->iov_len) == 0); if (strncasecmp((const char *)p, ph, it->iov_len) != 0) printf("p:\n%.*s\nph:\n%.*s\n", it->iov_len, p, it->iov_len, ph); ph += it->iov_len; } //printf("<-&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n"); }
int ChunkOutputStream::chunkedWrite( IOVec &iov, int &headerTotal, const char * pBuf, int size) { //printf( "****ChunkOutputStream::chunkedWrite()\n" ); IOVec::iterator iter = iov.end(); int bytes = buildIovec( iov, pBuf, size ); int total = bytes + headerTotal; int ret = m_pOS->writev( iov, total ); assert( m_iCurSize == 0 ); if ( ret >= total ) { iov.clear(); headerTotal = 0; m_iCurSize = 0; return size; } else if ( ret >= 0 ) { if( ret >= headerTotal ) { if ( ret == headerTotal ) { iov.clear(); } else { ret -= headerTotal; m_iTotalPending = bytes - ret; iov.setBegin( iter ); iov.finish( ret ); m_pLastBufBegin = pBuf; m_iLastBufLen = size; } headerTotal = 0; } else { if ( ret ) { headerTotal -= ret; iov.finish( ret ); } iov.setEnd( iter ); } return 0; } else iov.setEnd( iter ); return ret; }
int SpdyStream::write(const char *buf, int len) { IOVec iov; const char *p = buf; const char *pEnd = buf + len; int allowed; if (getState() == HIOS_DISCONNECTED) return LS_FAIL; while(pEnd - p > 0) { allowed = getDataFrameSize(pEnd - p); if (allowed <= 0) break; iov.append(p, allowed); if (sendData(&iov, allowed) == -1) return LS_FAIL; p += allowed; iov.clear(); } return p - buf; }
int BufferedOS::flush() { assert(m_pOS != NULL); int ret = 0; if (!m_buf.empty()) { IOVec iov; m_buf.getIOvec(iov); ret = m_pOS->writev(iov.get(), iov.len()); if (ret >= 0) { if (m_buf.size() <= ret) m_buf.clear(); else m_buf.pop_front(ret); // LS_DBG_H( "bufferedOS::flush() writen %d, %d bytes in cache\n", // ret, m_buf.size()); ret = m_buf.size(); } } return ret; }
int CacheOS::cacheWritev( IOVec &vec, int total, int * pRet) { int ret = 0; int bufSize; int written = 0; int count = vec.len(); const struct iovec * vector = vec.get(); for( ; count > 0; --count, ++vector ) { const char * pBuf =( const char *) vector->iov_base; bufSize = vector->iov_len; if (( pBuf != NULL )&&( bufSize > 0 )) written = cacheWrite( pBuf, bufSize, pRet ); if ( written > 0 ) ret += written; if ( ret < 0 ) break; if ( written < bufSize ) break; } return ret; }
void DisplayBothHeader(IOVec io, int format, short count, HttpRespHeaders * pRespHeaders) { IOVec::iterator it; unsigned char *p = NULL; it = io.begin(); p = (unsigned char *)it->iov_base; //return;//comment this out to view header data for (it = io.begin(); it != io.end(); ++it) { p = (unsigned char *)it->iov_base; for (unsigned int i = 0; i < it->iov_len; ++i) { if (format != 0) printf("%02X ", p[i]); else printf("%c", p[i]); } } printf("\r\nplain http Count = %d\r\n======================================================\r\n", count); displaySpdyHeaders(pRespHeaders); // if (format != 0) // { // AutoBuf buf; // for (it = io.begin(); it != io.end(); ++it) // { // buf.append( (const char *)it->iov_base, it->iov_len); // } // // if (format == 1) // { // char *p = buf.begin(); // short *tempNumS; // short tempNum; // // for (int j=0; j<count; ++j) // { // tempNumS = (short *)p; // tempNum = ntohs(*tempNumS); // p += 2; // for (int n=0; n<tempNum; ++n){ // printf("%c", *(p + n)); // } // printf(": "); // p += tempNum; // // tempNumS = (short *)p; // tempNum = ntohs(*tempNumS); // p += 2; // for (int n=0; n<tempNum; ++n){ // if (*(p + n) != 0) // printf("%c", *(p + n)); // else // printf("\r\n\t"); // } // printf("\r\n"); // p += tempNum; // } // } // else // { // char *p = buf.begin(); // int32_t *tempNumS; // int32_t tempNum; // // for (int j=0; j<count; ++j) // { // tempNumS = (int32_t *)p; // tempNum = ntohl(*tempNumS); // p += 4; // for (int n=0; n<tempNum; ++n){ // printf("%c", *(p + n)); // } // printf(": "); // p += tempNum; // // tempNumS = (int32_t *)p; // tempNum = ntohl(*tempNumS); // p += 4; // for (int n=0; n<tempNum; ++n){ // if (*(p + n) != 0) // printf("%c", *(p + n)); // else // printf("\r\n\t"); // } // printf("\r\n"); // p += tempNum; // } // } // // printf("\r\n*******************************************************************\r\n\r\n"); // // } }
void testWithHeader() { const char * header[] = { "HTTP/1.1 200 OK\r\n", "Content-Type: text/html\r\n", "Transfer-Encoding: chunked\r\n", "\r\n" }; TestOS1 testOS; TestOS test2; ChunkOutputStream chunkOS; IOVec iov; int hs = 0; int ht; int ret; int size; unsigned int i; const char * pBody = "Hello World"; for( i = 0 ; i < sizeof( header ) / sizeof( char *); ++i ) { iov.append( header[i], strlen( header[i] ) ); hs += strlen( header[i] ); } ht = hs; chunkOS.setStream( &test2, &iov ); chunkOS.open(); ret = chunkOS.write( iov, ht, pBody, 11 ); CHECK( ret == 11 ); ret = chunkOS.close(iov, ht); CHECK( ret == 0 ); size = test2.getBuf().size(); CHECK( size == hs + chunkLen( 11 ) + 5 ); CHECK( memcmp( test2.getBuf().c_str() + hs + chunkLen( 11 ) - 11 - 2, pBody, 11 ) == 0 ); hs = 0; for( i = 0 ; i < sizeof( header ) / sizeof( char *); ++i ) { iov.append( header[i], strlen( header[i] ) ); hs += strlen( header[i] ); } ht = hs; char achBuf[MAX_CHUNK_SIZE * 2]; memset( achBuf, 'c', MAX_CHUNK_SIZE ); memset( (char *)achBuf + MAX_CHUNK_SIZE, 'd', MAX_CHUNK_SIZE ); chunkOS.setStream( &testOS, &iov ); chunkOS.open(); while( ht > 0 ) { ret = chunkOS.write( iov, ht, achBuf, MAX_CHUNK_SIZE ); CHECK( ret == 0 ); } CHECK( iov.len() == 0 ); const char * pBuf = testOS.getBuf().c_str(); for( i = 0 ; i < sizeof( header ) / sizeof( char *); ++i ) { CHECK( strncmp( pBuf, header[i], strlen( header[i] )) == 0 ); pBuf += strlen( header[i] ); } while( ret == 0 ) { ret = chunkOS.write( iov, ht, achBuf, MAX_CHUNK_SIZE ); } CHECK( ret == MAX_CHUNK_SIZE ); pBuf = testOS.getBuf().c_str(); CHECK( memcmp( pBuf + hs + chunkLen( MAX_CHUNK_SIZE ) - MAX_CHUNK_SIZE - 2, achBuf, MAX_CHUNK_SIZE ) == 0 ); ret = 0; while( ret == 0 ) { ret = chunkOS.write( iov, ht, (char *)achBuf + MAX_CHUNK_SIZE, MAX_CHUNK_SIZE ); } CHECK( ret == MAX_CHUNK_SIZE ); pBuf = testOS.getBuf().c_str() + hs + chunkLen( MAX_CHUNK_SIZE ) * 2 - MAX_CHUNK_SIZE - 2; CHECK( memcmp( pBuf, (char *)achBuf + MAX_CHUNK_SIZE, MAX_CHUNK_SIZE ) == 0 ); ret = chunkOS.close(iov, ht); CHECK( ret == 1 ); while( ret == 1 ) { ret = chunkOS.flush(); } CHECK( ret == 0 ); size = testOS.getBuf().size(); CHECK( size == hs + chunkLen( MAX_CHUNK_SIZE ) * 2 + 5 ); CHECK( memcmp( testOS.getBuf().c_str() + hs + chunkLen( MAX_CHUNK_SIZE ) * 2, "0\r\n\r\n", 5 ) == 0 ); }