blob: a3fd8e1cf45a13a5b767449f75cbfcae6831dd5c [file]
/** @file
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include "ts/ts.h"
#include "HttpHeader.h"
#include "Range.h"
#include "Stage.h"
#include <netinet/in.h>
#include <string>
#include <unordered_map>
struct Config;
enum BlockState {
Pending, // waiting for response
Active, // processing current block
PendingRef, // waiting for reference refetch response
ActiveRef, // processing current reference refetch
Done,
Passthru, // non 206 response passthru
Fail,
};
struct Data {
Data(Data const &) = delete;
Data &operator=(Data const &) = delete;
Config *const m_config;
sockaddr_storage m_client_ip;
// cached effective URL for use during async intercept processing
std::string m_effective_url;
// for pristine/effective url coming in
TSMBuffer m_urlbuf{nullptr};
TSMLoc m_urlloc{nullptr};
char m_hostname[8192];
int m_hostlen{0};
// best identifier headers, initially from reference slice
char m_etag[8192];
int m_etaglen{0};
char m_lastmodified[33];
int m_lastmodifiedlen{0};
int64_t m_contentlen{-1};
TSHttpStatus m_statustype{TS_HTTP_STATUS_NONE}; // 200 or 206
const char *m_method_type{nullptr}; // type of header request
Range m_req_range; // converted to half open interval
int64_t m_blocknum{-1}; // block number to work on, -1 bad/stop
int64_t m_blockexpected{0}; // body bytes expected
int64_t m_blockskip{0}; // number of bytes to skip in this block
int64_t m_blockconsumed{0}; // body bytes consumed
int64_t m_purge_hits{0}; // blocks a purge actually removed
int m_purge_misses{0}; // consecutive uncached blocks the walk has seen
int m_purge_miss_bound{0}; // from the config or the request header
TSHttpStatus m_purge_error{TS_HTTP_STATUS_NONE}; // block failure that ended the walk
BlockState m_blockstate{Pending}; // is there an active slice block
int64_t m_bytestosend{0}; // header + content bytes to send
int64_t m_bytessent{0}; // number of bytes written to the client
// default buffer size and water mark
TSIOBufferSizeIndex m_buffer_index{TS_IOBUFFER_SIZE_INDEX_32K};
TSIOBufferWaterMark m_buffer_water_mark{TS_IOBUFFER_WATER_MARK_PLUGIN_VC_DEFAULT};
bool m_server_block_header_parsed{false};
bool m_server_first_header_parsed{false};
Stage m_upstream;
Stage m_dnstream;
bool m_prefetchable{false};
int64_t m_prefetch_hwm{-1}; // highest block this request has scheduled for prefetch
HdrMgr m_req_hdrmgr; // manager for server request
HdrMgr m_resp_hdrmgr; // manager for client response
TSHttpParser m_http_parser{nullptr}; //!< cached for reuse
explicit Data(Config *const config) : m_config(config)
{
m_hostname[0] = '\0';
m_etag[0] = '\0';
m_lastmodified[0] = '\0';
memset(&m_client_ip, 0, sizeof(m_client_ip));
}
// HEAD only; a purge sends just a header too but never reaches the transfer path
bool
onlyHeader() const
{
return m_method_type == TS_HTTP_METHOD_HEAD;
}
bool
is_purge() const
{
return m_method_type == TS_HTTP_METHOD_PURGE;
}
// The purge range, closed against the object length once known. m_req_range
// stays as sent so a longer extent can widen the walk; a clamp could only shrink.
Range
purge_range() const
{
return (m_contentlen < 0) ? m_req_range : m_req_range.intersectedWith(Range(0, m_contentlen));
}
~Data()
{
if (nullptr != m_urlbuf) {
if (nullptr != m_urlloc) {
TSHandleMLocRelease(m_urlbuf, TS_NULL_MLOC, m_urlloc);
m_urlloc = nullptr;
}
TSMBufferDestroy(m_urlbuf);
m_urlbuf = nullptr;
}
if (nullptr != m_http_parser) {
TSHttpParserDestroy(m_http_parser);
m_http_parser = nullptr;
}
}
};