blob: 984887ddc8ebc08132199d8ab58d9f8ffab71e79 [file] [log] [blame]
/** @file
A brief file description
@section license License
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.
*/
/***************************************************************************
*
* FetchSM.h header file for Fetch Page
*
****************************************************************************/
#pragma once
#include "P_Net.h"
#include "HttpSM.h"
#include "HttpTunnel.h"
class PluginVC;
class FetchSM : public Continuation
{
public:
FetchSM() {}
void
init_comm()
{
cont_mutex.clear();
req_buffer = new_MIOBuffer(HTTP_HEADER_BUFFER_SIZE_INDEX);
req_reader = req_buffer->alloc_reader();
resp_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_32K);
resp_reader = resp_buffer->alloc_reader();
http_parser_init(&http_parser);
client_response_hdr.create(HTTP_TYPE_RESPONSE);
SET_HANDLER(&FetchSM::fetch_handler);
}
void
init(Continuation *cont, TSFetchWakeUpOptions options, TSFetchEvent events, const char *headers, int length, sockaddr const *addr)
{
Debug("FetchSM", "[%s] FetchSM initialized for request with headers\n--\n%.*s\n--", __FUNCTION__, length, headers);
init_comm();
contp = cont;
callback_events = events;
callback_options = options;
_addr.assign(addr);
writeRequest(headers, length);
mutex = new_ProxyMutex();
//
// We had dropped response_buffer/response_reader to avoid unnecessary
// memory copying. But for the original TSFetchURL() API, PluginVC may
// stop adding data to resp_buffer when the pending data in resp_buffer
// reach its water_mark.
//
// So we should set the water_mark of resp_buffer with a large value,
// INT64_MAX would be reasonable.
resp_buffer->water_mark = INT64_MAX;
}
void
set_fetch_flags(int flags)
{
fetch_flags = flags;
}
int fetch_handler(int event, void *data);
void process_fetch_read(int event);
void process_fetch_write(int event);
void httpConnect();
void cleanUp();
void get_info_from_buffer(IOBufferReader *reader);
char *resp_get(int *length);
TSMBuffer resp_hdr_bufp();
TSMLoc resp_hdr_mloc();
//
// Extended APIs for FetchSM
//
// *flags* can be bitwise OR of several TSFetchFlags
//
void ext_init(Continuation *cont, const char *method, const char *url, const char *version, const sockaddr *client_addr,
int flags);
void ext_add_header(const char *name, int name_len, const char *value, int value_len);
void ext_launch();
void ext_destroy();
ssize_t ext_read_data(char *buf, size_t len);
void ext_write_data(const void *data, size_t len);
void ext_set_user_data(void *data);
void *ext_get_user_data();
bool
get_internal_request()
{
return is_internal_request;
}
void
set_internal_request(bool val)
{
is_internal_request = val;
}
private:
int InvokePlugin(int event, void *data);
void InvokePluginExt(int error_event = 0);
void
writeRequest(const char *headers, int length)
{
if (length == -1)
req_buffer->write(headers, strlen(headers));
else
req_buffer->write(headers, length);
}
int64_t
getReqLen() const
{
return req_reader->read_avail();
}
/// Check if the comma supporting MIME field @a name has @a value in it.
bool check_for_field_value(const char *name, size_t name_len, char const *value, size_t value_len);
bool has_body();
bool check_body_done();
bool check_chunked();
bool check_connection_close();
int dechunk_body();
int recursion = 0;
PluginVC *http_vc = nullptr;
VIO *read_vio = nullptr;
VIO *write_vio = nullptr;
MIOBuffer *req_buffer = nullptr;
IOBufferReader *req_reader = nullptr;
char *client_response = nullptr;
int client_bytes = 0;
MIOBuffer *resp_buffer = nullptr; // response to HttpConnect Call
IOBufferReader *resp_reader = nullptr;
Continuation *contp = nullptr;
Ptr<ProxyMutex> cont_mutex;
HTTPParser http_parser;
HTTPHdr client_response_hdr;
ChunkedHandler chunked_handler;
TSFetchEvent callback_events;
TSFetchWakeUpOptions callback_options = NO_CALLBACK;
bool req_finished = false;
bool header_done = false;
bool is_method_head = false;
bool is_internal_request = true;
bool destroyed = false;
IpEndpoint _addr;
int resp_is_chunked = -1;
int resp_received_close = -1;
int fetch_flags = 0;
void *user_data = nullptr;
bool has_sent_header = false;
int64_t req_content_length = 0;
int64_t resp_content_length = -1;
int64_t resp_received_body_len = 0;
};