static void netOutgoingService(MaQueue *q) { MaConn *conn; MaResponse *resp; int written, errCode; conn = q->conn; resp = conn->response; while (q->first || q->ioIndex) { written = 0; if (q->ioIndex == 0 && buildNetVec(q) <= 0) { break; } /* * Issue a single I/O request to write all the blocks in the I/O vector */ errCode = mprGetOsError(); mprAssert(q->ioIndex > 0); written = mprWriteSocketVector(conn->sock, q->iovec, q->ioIndex); mprLog(q, 5, "Net connector written %d", written); if (written < 0) { errCode = mprGetOsError(); if (errCode == EAGAIN || errCode == EWOULDBLOCK) { maRequestWriteBlocked(conn); break; } if (errCode == EPIPE || errCode == ECONNRESET) { maDisconnectConn(conn); } else { mprLog(conn, 7, "mprVectorWriteSocket failed, error %d", errCode); maDisconnectConn(conn); } freeNetPackets(q, MAXINT); break; } else if (written == 0) { /* * Socket full. Wait for an I/O event. Conn.c will setup listening for write events if the queue is non-empty */ maRequestWriteBlocked(conn); break; } else if (written > 0) { resp->bytesWritten += written; freeNetPackets(q, written); adjustNetVec(q, written); } } if (q->ioCount == 0 && q->flags & MA_QUEUE_EOF) { maCompleteRequest(conn); } }
static void netOutgoingService(HttpQueue *q) { HttpConn *conn; HttpTx *tx; ssize written; int errCode; conn = q->conn; tx = conn->tx; conn->lastActivity = conn->http->now; mprAssert(conn->sock); if (!conn->sock || conn->connectorComplete) { return; } if (tx->flags & HTTP_TX_NO_BODY) { httpDiscardQueueData(q, 1); } if ((tx->bytesWritten + q->count) > conn->limits->transmissionBodySize) { httpError(conn, HTTP_CODE_REQUEST_TOO_LARGE | ((tx->bytesWritten) ? HTTP_ABORT : 0), "Http transmission aborted. Exceeded transmission max body of %,Ld bytes", conn->limits->transmissionBodySize); if (tx->bytesWritten) { httpConnectorComplete(conn); return; } } if (tx->flags & HTTP_TX_SENDFILE) { /* Relay via the send connector */ if (tx->file == 0) { if (tx->flags & HTTP_TX_HEADERS_CREATED) { tx->flags &= ~HTTP_TX_SENDFILE; } else { tx->connector = conn->http->sendConnector; httpSendOpen(q); } } if (tx->file) { httpSendOutgoingService(q); return; } } while (q->first || q->ioIndex) { if (q->ioIndex == 0 && buildNetVec(q) <= 0) { break; } /* Issue a single I/O request to write all the blocks in the I/O vector */ mprAssert(q->ioIndex > 0); written = mprWriteSocketVector(conn->sock, q->iovec, q->ioIndex); LOG(5, "Net connector wrote %d, written so far %Ld, q->count %d/%d", written, tx->bytesWritten, q->count, q->max); if (written < 0) { errCode = mprGetError(q); if (errCode == EAGAIN || errCode == EWOULDBLOCK) { /* Socket full, wait for an I/O event */ httpSocketBlocked(conn); break; } if (errCode != EPIPE && errCode != ECONNRESET) { LOG(5, "netOutgoingService write failed, error %d", errCode); } httpError(conn, HTTP_ABORT | HTTP_CODE_COMMS_ERROR, "Write error %d", errCode); httpConnectorComplete(conn); break; } else if (written == 0) { /* Socket full, wait for an I/O event */ httpSocketBlocked(conn); break; } else if (written > 0) { tx->bytesWritten += written; freeNetPackets(q, written); adjustNetVec(q, written); } } if (q->ioCount == 0) { if ((q->flags & HTTP_QUEUE_EOF)) { httpConnectorComplete(conn); } else { httpNotifyWritable(conn); } } }