void maSendPackets(MaQueue *q) { MaPacket *packet; for (packet = maGet(q); packet; packet = maGet(q)) { maPutNext(q, packet); } }
/* * Apply chunks to dynamic outgoing data. */ static void outgoingChunkService(MaQueue *q) { MaConn *conn; MaPacket *packet; MaResponse *resp; conn = q->conn; resp = conn->response; if (!(q->flags & MA_QUEUE_SERVICED)) { /* * If the last packet is the end packet, we have all the data. Thus we know the actual content length * and can bypass the chunk handler. */ if (q->last->flags & MA_PACKET_END) { if (resp->chunkSize < 0 && resp->length <= 0) { /* * Set the response content length and thus disable chunking -- not needed as we know the entity length. */ resp->length = q->count; } } else { if (resp->chunkSize < 0 && resp->entityLength < 0) { resp->chunkSize = (int) min(conn->http->limits.maxChunkSize, q->max); } } } if (resp->chunkSize <= 0) { maDefaultOutgoingServiceStage(q); } else { for (packet = maGet(q); packet; packet = maGet(q)) { if (!(packet->flags & MA_PACKET_HEADER)) { if (maGetPacketLength(packet) > resp->chunkSize) { maResizePacket(q, packet, resp->chunkSize); } } if (!maWillNextQueueAccept(q, packet)) { maPutBack(q, packet); return; } if (!(packet->flags & MA_PACKET_HEADER)) { setChunkPrefix(q, packet); } maPutNext(q, packet); } } }
static void writeToCGI(MaQueue *q) { MaConn *conn; MaPacket *packet; MprCmd *cmd; MprBuf *buf; int len, rc, err; cmd = (MprCmd*) q->pair->queueData; mprAssert(cmd); conn = q->conn; for (packet = maGet(q); packet && !conn->requestFailed; packet = maGet(q)) { buf = packet->content; len = mprGetBufLength(buf); mprAssert(len > 0); rc = mprWriteCmdPipe(cmd, MPR_CMD_STDIN, mprGetBufStart(buf), len); mprLog(q, 5, "CGI: write %d bytes to gateway. Rc rc %d, errno %d", len, rc, mprGetOsError()); if (rc < 0) { err = mprGetError(); if (err == EINTR) { continue; } else if (err == EAGAIN || err == EWOULDBLOCK) { break; } mprLog(q, 2, "CGI: write to gateway failed for %d bytes, rc %d, errno %d", len, rc, mprGetOsError()); mprCloseCmdFd(cmd, MPR_CMD_STDIN); maFailRequest(conn, MPR_HTTP_CODE_BAD_GATEWAY, "Can't write body data to CGI gateway"); break; } else { mprLog(q, 5, "CGI: write to gateway %d bytes asked to write %d", rc, len); mprAdjustBufStart(buf, rc); if (mprGetBufLength(buf) > 0) { maPutBack(q, packet); } else { maFreePacket(q, packet); } } } }
/* * Clear entries from the IO vector that have actually been transmitted. This supports partial writes due to the socket * being full. Don't come here if we've seen all the packets and all the data has been completely written. ie. small files * don't come here. */ static void freeSentPackets(MaQueue *q, int64 bytes) { MaPacket *packet; int64 len; mprAssert(q->first); mprAssert(q->count >= 0); mprAssert(bytes >= 0); while ((packet = q->first) != 0) { if (packet->prefix) { len = mprGetBufLength(packet->prefix); len = min(len, bytes); mprAdjustBufStart(packet->prefix, (int) len); bytes -= len; /* Prefixes don't count in the q->count. No need to adjust */ if (mprGetBufLength(packet->prefix) == 0) { mprFree(packet->prefix); packet->prefix = 0; } } if (packet->esize) { len = min(packet->esize, bytes); packet->esize -= len; packet->epos += len; bytes -= len; mprAssert(packet->esize >= 0); mprAssert(bytes == 0); if (packet->esize > 0) { break; } } else if ((len = maGetPacketLength(packet)) > 0) { len = min(len, bytes); mprAdjustBufStart(packet->content, (int) len); bytes -= len; q->count -= (int) len; mprAssert(q->count >= 0); } if (maGetPacketLength(packet) == 0) { if ((packet = maGet(q)) != 0) { maFreePacket(q, packet); } } mprAssert(bytes >= 0); if (bytes == 0) { break; } } }
static void freeNetPackets(MaQueue *q, int64 bytes) { MaPacket *packet; int len; mprAssert(q->first); mprAssert(q->count >= 0); mprAssert(bytes >= 0); while ((packet = q->first) != 0) { if (packet->prefix) { len = mprGetBufLength(packet->prefix); len = (int) min(len, bytes); mprAdjustBufStart(packet->prefix, len); bytes -= len; /* Prefixes don't count in the q->count. No need to adjust */ if (mprGetBufLength(packet->prefix) == 0) { mprFree(packet->prefix); packet->prefix = 0; } } if (packet->content) { len = mprGetBufLength(packet->content); len = (int) min(len, bytes); mprAdjustBufStart(packet->content, len); bytes -= len; q->count -= len; mprAssert(q->count >= 0); } if (packet->content == 0 || mprGetBufLength(packet->content) == 0) { /* * This will remove the packet from the queue and will re-enable upstream disabled queues. */ if ((packet = maGet(q)) != 0) { maFreePacket(q, packet); } } mprAssert(bytes >= 0); if (bytes == 0) { break; } } }