void httpCreateRxPipeline(HttpConn *conn, HttpRoute *route) { HttpTx *tx; HttpRx *rx; HttpQueue *q; HttpStage *stage, *filter; int next; mprAssert(conn); mprAssert(route); rx = conn->rx; tx = conn->tx; rx->inputPipeline = mprCreateList(-1, 0); if (route) { for (next = 0; (filter = mprGetNextItem(route->inputStages, &next)) != 0; ) { if (matchFilter(conn, filter, route, HTTP_STAGE_RX) == HTTP_ROUTE_OK) { mprAddItem(rx->inputPipeline, filter); } } } mprAddItem(rx->inputPipeline, tx->handler); /* Create the incoming queue heads and open the queues. */ q = tx->queue[HTTP_QUEUE_RX]; for (next = 0; (stage = mprGetNextItem(rx->inputPipeline, &next)) != 0; ) { q = httpCreateQueue(conn, stage, HTTP_QUEUE_RX, q); } conn->readq = tx->queue[HTTP_QUEUE_RX]->prevQ; if (!conn->endpoint) { pairQueues(conn); openQueues(conn); } }
PUBLIC void httpCreateRxPipeline(HttpConn *conn, HttpRoute *route) { HttpTx *tx; HttpRx *rx; HttpQueue *q; HttpStage *stage, *filter; int next; assert(conn); assert(route); rx = conn->rx; tx = conn->tx; rx->inputPipeline = mprCreateList(-1, MPR_LIST_STABLE); if (route) { for (next = 0; (filter = mprGetNextItem(route->inputStages, &next)) != 0; ) { if (matchFilter(conn, filter, route, HTTP_STAGE_RX) == HTTP_ROUTE_OK) { mprAddItem(rx->inputPipeline, filter); } } } mprAddItem(rx->inputPipeline, tx->handler ? tx->handler : conn->http->clientHandler); /* Create the incoming queue heads and open the queues. */ q = tx->queue[HTTP_QUEUE_RX]; for (next = 0; (stage = mprGetNextItem(rx->inputPipeline, &next)) != 0; ) { q = httpCreateQueue(conn, stage, HTTP_QUEUE_RX, q); } if (httpClientConn(conn)) { pairQueues(conn); openQueues(conn); } }
void httpCreateTxPipeline(HttpConn *conn, HttpRoute *route) { Http *http; HttpTx *tx; HttpRx *rx; HttpQueue *q; HttpStage *stage, *filter; int next, hasOutputFilters; mprAssert(conn); mprAssert(route); http = conn->http; rx = conn->rx; tx = conn->tx; tx->outputPipeline = mprCreateList(-1, 0); if (tx->handler == 0) { tx->handler = http->passHandler; } mprAddItem(tx->outputPipeline, tx->handler); hasOutputFilters = 0; if (route->outputStages) { for (next = 0; (filter = mprGetNextItem(route->outputStages, &next)) != 0; ) { if (matchFilter(conn, filter, route, HTTP_STAGE_TX) == HTTP_ROUTE_OK) { mprAddItem(tx->outputPipeline, filter); mprLog(4, "Select output filter: \"%s\"", filter->name); hasOutputFilters = 1; } } } if (tx->connector == 0) { if (tx->handler == http->fileHandler && (rx->flags & HTTP_GET) && !hasOutputFilters && !conn->secure && httpShouldTrace(conn, HTTP_TRACE_TX, HTTP_TRACE_BODY, tx->ext) < 0) { tx->connector = http->sendConnector; } else if (route && route->connector) { tx->connector = route->connector; } else { tx->connector = http->netConnector; } } mprAddItem(tx->outputPipeline, tx->connector); mprLog(4, "Select connector: \"%s\"", tx->connector->name); /* Create the outgoing queue heads and open the queues */ q = tx->queue[HTTP_QUEUE_TX]; for (next = 0; (stage = mprGetNextItem(tx->outputPipeline, &next)) != 0; ) { q = httpCreateQueue(conn, stage, HTTP_QUEUE_TX, q); } conn->writeq = tx->queue[HTTP_QUEUE_TX]->nextQ; conn->connectorq = tx->queue[HTTP_QUEUE_TX]->prevQ; pairQueues(conn); /* Put the header before opening the queues incase an open routine actually services and completes the request httpHandleOptionsTrace does this when called from openFile() in fileHandler. */ httpPutForService(conn->writeq, httpCreateHeaderPacket(), HTTP_DELAY_SERVICE); openQueues(conn); /* Refinalize if httpFinalize was called before the Tx pipeline was created */ if (conn->refinalize) { conn->finalized = 0; httpFinalize(conn); } }
PUBLIC void httpCreateTxPipeline(HttpConn *conn, HttpRoute *route) { Http *http; HttpTx *tx; HttpRx *rx; HttpQueue *q; HttpStage *stage, *filter; int next, hasOutputFilters; assert(conn); assert(route); http = conn->http; rx = conn->rx; tx = conn->tx; tx->outputPipeline = mprCreateList(-1, 0); if (conn->endpoint) { if (tx->handler == 0 || tx->finalized) { tx->handler = http->passHandler; } mprAddItem(tx->outputPipeline, tx->handler); } hasOutputFilters = 0; if (route->outputStages) { for (next = 0; (filter = mprGetNextItem(route->outputStages, &next)) != 0; ) { if (matchFilter(conn, filter, route, HTTP_STAGE_TX) == HTTP_ROUTE_OK) { mprAddItem(tx->outputPipeline, filter); if (rx->traceLevel >= 0) { mprLog(rx->traceLevel, "Select output filter: \"%s\"", filter->name); } hasOutputFilters = 1; } } } if (tx->connector == 0) { #if !BIT_ROM if (tx->handler == http->fileHandler && (rx->flags & HTTP_GET) && !hasOutputFilters && !conn->secure && httpShouldTrace(conn, HTTP_TRACE_TX, HTTP_TRACE_BODY, tx->ext) < 0) { tx->connector = http->sendConnector; } else #endif if (route && route->connector) { tx->connector = route->connector; } else { tx->connector = http->netConnector; } } mprAddItem(tx->outputPipeline, tx->connector); if (rx->traceLevel >= 0) { mprLog(rx->traceLevel + 1, "Select connector: \"%s\"", tx->connector->name); } /* Create the outgoing queue heads and open the queues */ q = tx->queue[HTTP_QUEUE_TX]; for (next = 0; (stage = mprGetNextItem(tx->outputPipeline, &next)) != 0; ) { q = httpCreateQueue(conn, stage, HTTP_QUEUE_TX, q); } conn->connectorq = tx->queue[HTTP_QUEUE_TX]->prevQ; /* Double the connector max hi-water mark. This optimization permits connectors to accept packets without unnecesary flow control. */ conn->connectorq->max *= 2; pairQueues(conn); /* Put the header before opening the queues incase an open routine actually services and completes the request */ httpPutForService(conn->writeq, httpCreateHeaderPacket(), HTTP_DELAY_SERVICE); /* Open the pipelien stages. This calls the open entrypoints on all stages */ openQueues(conn); }
PUBLIC void httpCreateTxPipeline(HttpConn *conn, HttpRoute *route) { Http *http; HttpTx *tx; HttpRx *rx; HttpQueue *q; HttpStage *stage, *filter; int next; assert(conn); assert(route); http = conn->http; rx = conn->rx; tx = conn->tx; tx->outputPipeline = mprCreateList(-1, MPR_LIST_STABLE); if (httpServerConn(conn)) { if (tx->handler == 0 || tx->finalized) { tx->handler = http->passHandler; } mprAddItem(tx->outputPipeline, tx->handler); } if (route->outputStages) { for (next = 0; (filter = mprGetNextItem(route->outputStages, &next)) != 0; ) { if (matchFilter(conn, filter, route, HTTP_STAGE_TX) == HTTP_ROUTE_OK) { mprAddItem(tx->outputPipeline, filter); tx->flags |= HTTP_TX_HAS_FILTERS; } } } if (tx->connector == 0) { #if !ME_ROM if (tx->handler == http->fileHandler && (rx->flags & HTTP_GET) && !(tx->flags & HTTP_TX_HAS_FILTERS) && !conn->secure && !httpTracing(conn)) { tx->connector = http->sendConnector; } else #endif tx->connector = (route && route->connector) ? route->connector : http->netConnector; } mprAddItem(tx->outputPipeline, tx->connector); /* Create the outgoing queue heads and open the queues */ q = tx->queue[HTTP_QUEUE_TX]; for (next = 0; (stage = mprGetNextItem(tx->outputPipeline, &next)) != 0; ) { q = httpCreateQueue(conn, stage, HTTP_QUEUE_TX, q); } conn->connectorq = tx->queue[HTTP_QUEUE_TX]->prevQ; /* Double the connector max hi-water mark. This optimization permits connectors to accept packets without unnecesary flow control. */ conn->connectorq->max *= 2; pairQueues(conn); /* Put the header before opening the queues incase an open routine actually services and completes the request */ httpPutForService(conn->writeq, httpCreateHeaderPacket(), HTTP_DELAY_SERVICE); /* Open the pipeline stages. This calls the open entrypoints on all stages. */ openQueues(conn); if (conn->error) { if (tx->handler != http->passHandler) { tx->handler = http->passHandler; httpAssignQueue(conn->writeq, tx->handler, HTTP_QUEUE_TX); } } tx->flags |= HTTP_TX_PIPELINE; if (conn->endpoint) { httpTrace(conn, "request.pipeline", "context", "route:'%s',handler:'%s',target:'%s',endpoint:'%s:%d',host:'%s',referrer:'%s',filename:'%s'", rx->route->pattern, tx->handler->name, rx->route->targetRule, conn->endpoint->ip, conn->endpoint->port, conn->host->name ? conn->host->name : "default", rx->referrer ? rx->referrer : "", tx->filename ? tx->filename : ""); } }