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 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 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 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; }
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 ); }