PUBLIC void httpDefaultOutgoingServiceStage(HttpQueue *q) { HttpPacket *packet; for (packet = httpGetPacket(q); packet; packet = httpGetPacket(q)) { if (!httpWillNextQueueAcceptPacket(q, packet)) { httpPutBackPacket(q, packet); return; } httpPutPacketToNext(q, packet); } }
static void outgoingProxyService(HttpQueue *q) { HttpPacket *packet; for (packet = httpGetPacket(q); packet; packet = httpGetPacket(q)) { if (packet->flags & HTTP_PACKET_DATA) { if (!httpWillNextQueueAcceptPacket(q, packet)) { mprTrace(7, "OutgoingProxyService downstream full, putback"); httpPutBackPacket(q, packet); return; } } httpPutPacketToNext(q, packet); } }
static void outgoingRangeService(HttpQueue *q) { HttpPacket *packet; HttpStream *stream; HttpTx *tx; stream = q->stream; tx = stream->tx; if (!(q->flags & HTTP_QUEUE_SERVICED)) { /* The httpContentNotModified routine can set outputRanges to zero if returning not-modified. */ if (!fixRangeLength(stream, q)) { if (!q->servicing) { httpRemoveQueue(q); } tx->outputRanges = 0; tx->status = HTTP_CODE_OK; } } for (packet = httpGetPacket(q); packet; packet = httpGetPacket(q)) { if (packet->flags & HTTP_PACKET_DATA) { if ((packet = selectBytes(q, packet)) == 0) { continue; } } else if (packet->flags & HTTP_PACKET_END) { if (tx->rangeBoundary) { httpPutPacketToNext(q, createFinalRangePacket(stream)); } } if (!httpWillNextQueueAcceptPacket(q, packet)) { httpPutBackPacket(q, packet); return; } httpPutPacketToNext(q, packet); } }
/* This will be enabled when caching is enabled for the route and there is no acceptable cache data to use. OR - manual caching has been enabled. */ static void outgoingCacheFilterService(HttpQueue *q) { HttpPacket *packet, *data; HttpConn *conn; HttpTx *tx; MprKey *kp; cchar *cachedData; ssize size; int foundDataPacket; conn = q->conn; tx = conn->tx; foundDataPacket = 0; cachedData = 0; if (tx->status < 200 || tx->status > 299) { tx->cacheBuffer = 0; } /* This routine will save cached responses to tx->cacheBuffer. It will also send cached data if the X-SendCache header is present. Normal caching is done by cacheHandler */ if (mprLookupKey(conn->tx->headers, "X-SendCache") != 0) { if (fetchCachedResponse(conn)) { mprLog(3, "cacheFilter: write cached content for '%s'", conn->rx->uri); cachedData = setHeadersFromCache(conn, tx->cachedContent); tx->length = slen(cachedData); } } for (packet = httpGetPacket(q); packet; packet = httpGetPacket(q)) { if (!httpWillNextQueueAcceptPacket(q, packet)) { httpPutBackPacket(q, packet); return; } if (packet->flags & HTTP_PACKET_HEADER) { if (!cachedData && tx->cacheBuffer) { /* Add defined headers to the start of the cache buffer. Separate with a double newline. */ mprPutFmtToBuf(tx->cacheBuffer, "X-Status: %d\n", tx->status); for (kp = 0; (kp = mprGetNextKey(tx->headers, kp)) != 0; ) { mprPutFmtToBuf(tx->cacheBuffer, "%s: %s\n", kp->key, kp->data); } mprPutCharToBuf(tx->cacheBuffer, '\n'); } } else if (packet->flags & HTTP_PACKET_DATA) { if (cachedData) { /* Using X-SendCache. Replace the data with the cached response. */ mprFlushBuf(packet->content); mprPutBlockToBuf(packet->content, cachedData, (ssize) tx->length); } else if (tx->cacheBuffer) { /* Save the response packet to the cache buffer. Will write below in saveCachedResponse. */ size = mprGetBufLength(packet->content); if ((tx->cacheBufferLength + size) < conn->limits->cacheItemSize) { mprPutBlockToBuf(tx->cacheBuffer, mprGetBufStart(packet->content), mprGetBufLength(packet->content)); tx->cacheBufferLength += size; } else { tx->cacheBuffer = 0; mprLog(3, "cacheFilter: Item too big to cache %d bytes, limit %d", tx->cacheBufferLength + size, conn->limits->cacheItemSize); } } foundDataPacket = 1; } else if (packet->flags & HTTP_PACKET_END) { if (cachedData && !foundDataPacket) { /* Using X-SendCache but there was no data packet to replace. So do the write here */ data = httpCreateDataPacket((ssize) tx->length); mprPutBlockToBuf(data->content, cachedData, (ssize) tx->length); httpPutPacketToNext(q, data); } else if (tx->cacheBuffer) { /* Save the cache buffer to the cache store */ saveCachedResponse(conn); } } httpPutPacketToNext(q, packet); } }