static void discardOutput(void *handle) { MaConn *conn; conn = (MaConn*) handle; maDiscardData(conn->response->queue[MA_QUEUE_SEND].nextQ->nextQ, 0); }
void maDiscardPipeData(MaConn *conn) { MaResponse *resp; MaQueue *q, *qhead; resp = conn->response; qhead = &resp->queue[MA_QUEUE_SEND]; for (q = qhead->nextQ; q != qhead; q = q->nextQ) { maDiscardData(q, 0); } qhead = &resp->queue[MA_QUEUE_RECEIVE]; for (q = qhead->nextQ; q != qhead; q = q->nextQ) { maDiscardData(q, 0); } }
/* * Build the IO vector. This connector uses the send file API which permits multiple IO blocks to be written with * file data. This is used to write transfer the headers and chunk encoding boundaries. Return the count of bytes to * be written. */ static int64 buildSendVec(MaQueue *q) { MaConn *conn; MaResponse *resp; MaPacket *packet; conn = q->conn; resp = conn->response; mprAssert(q->ioIndex == 0); q->ioCount = 0; q->ioFile = 0; /* * Examine each packet and accumulate as many packets into the I/O vector as possible. Can only have one data packet at * a time due to the limitations of the sendfile API (on Linux). And the data packet must be after all the * vector entries. Leave the packets on the queue for now, they are removed after the IO is complete for the * entire packet. */ for (packet = q->first; packet; packet = packet->next) { if (packet->flags & MA_PACKET_HEADER) { maFillHeaders(conn, packet); q->count += maGetPacketLength(packet); } else if (maGetPacketLength(packet) == 0 && packet->esize == 0) { q->flags |= MA_QUEUE_EOF; if (packet->prefix == NULL) { break; } } else if (resp->flags & MA_RESP_NO_BODY) { maDiscardData(q, 0); continue; } if (q->ioFile || q->ioIndex >= (MA_MAX_IOVEC - 2)) { break; } addPacketForSend(q, packet); } return q->ioCount; }
/* * Build the IO vector. Return the count of bytes to be written. Return -1 for EOF. */ static int64 buildNetVec(MaQueue *q) { MaConn *conn; MaResponse *resp; MaPacket *packet; conn = q->conn; resp = conn->response; /* * Examine each packet and accumulate as many packets into the I/O vector as possible. Leave the packets on the queue * for now, they are removed after the IO is complete for the entire packet. */ for (packet = q->first; packet; packet = packet->next) { if (packet->flags & MA_PACKET_HEADER) { if (resp->chunkSize <= 0 && q->count > 0 && resp->length < 0) { /* Incase no chunking filter and we've not seen all the data yet */ conn->keepAliveCount = 0; } maFillHeaders(conn, packet); q->count += maGetPacketLength(packet); } else if (maGetPacketLength(packet) == 0) { q->flags |= MA_QUEUE_EOF; if (packet->prefix == NULL) { break; } } else if (resp->flags & MA_RESP_NO_BODY) { maDiscardData(q, 0); continue; } if (q->ioIndex >= (MA_MAX_IOVEC - 2)) { break; } addPacketForNet(q, packet); } return q->ioCount; }