3
A brief file description
5
@section license License
7
Licensed to the Apache Software Foundation (ASF) under one
8
or more contributor license agreements. See the NOTICE file
9
distributed with this work for additional information
10
regarding copyright ownership. The ASF licenses this file
11
to you under the Apache License, Version 2.0 (the
12
"License"); you may not use this file except in compliance
13
with the License. You may obtain a copy of the License at
15
http://www.apache.org/licenses/LICENSE-2.0
17
Unless required by applicable law or agreed to in writing, software
18
distributed under the License is distributed on an "AS IS" BASIS,
19
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
See the License for the specific language governing permissions and
21
limitations under the License.
24
/****************************************************************************
31
****************************************************************************/
33
#ifndef _HTTP_TUNNEL_H_
34
#define _HTTP_TUNNEL_H_
37
#include "P_EventSystem.h"
39
// Get rid of any previous definition first... /leif
46
#define MAX_PRODUCERS 2
47
#define MAX_CONSUMERS 4
49
#define HTTP_TUNNEL_EVENT_DONE (HTTP_TUNNEL_EVENTS_START + 1)
50
#define HTTP_TUNNEL_EVENT_PRECOMPLETE (HTTP_TUNNEL_EVENTS_START + 2)
51
#define HTTP_TUNNEL_EVENT_CONSUMER_DETACH (HTTP_TUNNEL_EVENTS_START + 3)
53
#define HTTP_TUNNEL_STATIC_PRODUCER (VConnection*)!0
55
//YTS Team, yamsat Plugin
56
#define ALLOCATE_AND_WRITE_TO_BUF 1
57
#define WRITE_TO_BUF 2
59
struct HttpTunnelProducer;
61
class HttpPagesHandler;
62
typedef int (HttpSM::*HttpSMHandler) (int event, void *data);
64
struct HttpTunnelConsumer;
65
struct HttpTunnelProducer;
66
typedef int (HttpSM::*HttpProducerHandler) (int event, HttpTunnelProducer * p);
67
typedef int (HttpSM::*HttpConsumerHandler) (int event, HttpTunnelConsumer * c);
79
enum TunnelChunkingAction_t
83
TCA_PASSTHRU_CHUNKED_CONTENT,
84
TCA_PASSTHRU_DECHUNKED_CONTENT
92
CHUNK_READ_SIZE_START,
95
CHUNK_READ_TRAILER_BLANK,
96
CHUNK_READ_TRAILER_CR,
97
CHUNK_READ_TRAILER_LINE,
105
IOBufferReader *chunked_reader;
106
MIOBuffer *dechunked_buffer;
107
int64_t dechunked_size;
109
IOBufferReader *dechunked_reader;
110
MIOBuffer *chunked_buffer;
111
int64_t chunked_size;
117
int64_t cur_chunk_size;
119
int last_server_event;
127
void init(IOBufferReader * buffer_in, HttpTunnelProducer * p);
129
// Returns true if complete, false otherwise
130
bool process_chunked_content();
131
bool generate_chunked_content();
137
int64_t transfer_bytes();
140
struct HttpTunnelConsumer
142
HttpTunnelConsumer();
144
LINK(HttpTunnelConsumer, link);
145
HttpTunnelProducer *producer;
146
HttpTunnelProducer *self_producer;
148
HttpTunnelType_t vc_type;
150
IOBufferReader *buffer_reader;
151
HttpConsumerHandler vc_handler;
154
int64_t skip_bytes; // bytes to skip at beginning of stream
155
int64_t bytes_written; // total bytes written to the vc
156
int handler_state; // state used the handlers
163
struct HttpTunnelProducer
165
HttpTunnelProducer();
167
DLL<HttpTunnelConsumer> consumer_list;
168
HttpTunnelConsumer *self_consumer;
170
HttpProducerHandler vc_handler;
172
MIOBuffer *read_buffer;
173
IOBufferReader *buffer_start;
174
HttpTunnelType_t vc_type;
176
ChunkedHandler chunked_handler;
177
TunnelChunkingAction_t chunking_action;
181
bool do_chunked_passthru;
183
int64_t init_bytes_done; // bytes passed in buffer
184
int64_t nbytes; // total bytes (client's perspective)
185
int64_t ntodo; // what this vc needs to do
186
int64_t bytes_read; // total bytes read from the vc
187
int handler_state; // state used the handlers
196
class PostDataBuffers
200
: postdata_producer_buffer(NULL), postdata_copy_buffer(NULL), postdata_producer_reader(NULL),
201
postdata_copy_buffer_start(NULL), ua_buffer_reader(NULL)
202
{ Debug("http_redirect", "[PostDataBuffers::PostDataBuffers]"); }
204
MIOBuffer *postdata_producer_buffer;
205
MIOBuffer *postdata_copy_buffer;
206
IOBufferReader *postdata_producer_reader;
207
IOBufferReader *postdata_copy_buffer_start;
208
IOBufferReader *ua_buffer_reader;
211
class HttpTunnel:public Continuation
213
friend class HttpPagesHandler;
214
friend class CoreUtils;
218
void init(HttpSM * sm_arg, ProxyMutex * amutex);
221
bool is_tunnel_active() { return active; }
222
bool is_tunnel_alive();
223
bool is_there_cache_write();
225
// YTS Team, yamsat Plugin
226
void copy_partial_post_data();
227
void allocate_redirect_postdata_producer_buffer();
228
void allocate_redirect_postdata_buffers(IOBufferReader * ua_reader);
229
void deallocate_redirect_postdata_buffers();
231
HttpTunnelProducer *add_producer(VConnection * vc,
233
IOBufferReader * reader_start,
234
HttpProducerHandler sm_handler, HttpTunnelType_t vc_type, const char *name);
236
void set_producer_chunking_action(HttpTunnelProducer * p, int64_t skip_bytes, TunnelChunkingAction_t action);
238
HttpTunnelConsumer *add_consumer(VConnection * vc,
239
VConnection * producer,
240
HttpConsumerHandler sm_handler,
241
HttpTunnelType_t vc_type, const char *name, int64_t skip_bytes = 0);
243
int deallocate_buffers();
244
DLL<HttpTunnelConsumer> *get_consumers(VConnection * vc);
245
HttpTunnelProducer *get_producer(VConnection * vc);
246
HttpTunnelConsumer *get_consumer(VConnection * vc);
247
void tunnel_run(HttpTunnelProducer * p = NULL);
249
int main_handler(int event, void *data);
250
bool consumer_handler(int event, HttpTunnelConsumer * c);
251
bool producer_handler(int event, HttpTunnelProducer * p);
252
int producer_handler_dechunked(int event, HttpTunnelProducer * p);
253
int producer_handler_chunked(int event, HttpTunnelProducer * p);
254
void local_finish_all(HttpTunnelProducer * p);
255
void chain_finish_all(HttpTunnelProducer * p);
256
void chain_abort_cache_write(HttpTunnelProducer * p);
257
void chain_abort_all(HttpTunnelProducer * p);
258
void abort_cache_write_finish_others(HttpTunnelProducer * p);
259
void append_message_to_producer_buffer(HttpTunnelProducer * p, const char *msg, int64_t msg_len);
261
void close_vc(HttpTunnelProducer * p);
262
void close_vc(HttpTunnelConsumer * c);
266
void internal_error();
267
void finish_all_internal(HttpTunnelProducer * p, bool chain);
268
void update_stats_after_abort(HttpTunnelType_t t);
269
void producer_run(HttpTunnelProducer * p);
271
HttpTunnelProducer *get_producer(VIO * vio);
272
HttpTunnelConsumer *get_consumer(VIO * vio);
274
HttpTunnelProducer *alloc_producer();
275
HttpTunnelConsumer *alloc_consumer();
279
HttpTunnelConsumer consumers[MAX_CONSUMERS];
280
HttpTunnelProducer producers[MAX_PRODUCERS];
286
PostDataBuffers * postbuf;
289
extern void init_max_chunk_buf();
291
// void HttpTunnel::abort_cache_write_finish_others
293
// Abort all downstream cache writes and finsish
294
// all other local consumers
297
HttpTunnel::abort_cache_write_finish_others(HttpTunnelProducer * p)
299
chain_abort_cache_write(p);
303
// void HttpTunnel::local_finish_all(HttpTunnelProducer* p)
305
// After the producer has finished, causes direct consumers
306
// to finish their writes
309
HttpTunnel::local_finish_all(HttpTunnelProducer * p)
311
finish_all_internal(p, false);
314
// void HttpTunnel::chain_finish_all(HttpTunnelProducer* p)
316
// After the producer has finished, cause everyone
317
// downstream in the tunnel to send everything
318
// that producer has placed in the buffer
321
HttpTunnel::chain_finish_all(HttpTunnelProducer * p)
323
finish_all_internal(p, true);
327
HttpTunnel::is_tunnel_alive()
329
bool tunnel_alive = false;
331
for (int i = 0; i < MAX_PRODUCERS; i++) {
332
if (producers[i].alive == true) {
338
for (int i = 0; i < MAX_CONSUMERS; i++) {
339
if (consumers[i].alive == true) {
351
HttpTunnel::init(HttpSM * sm_arg, ProxyMutex * amutex)
356
SET_HANDLER(&HttpTunnel::main_handler);
359
inline HttpTunnelProducer *
360
HttpTunnel::get_producer(VConnection * vc)
362
for (int i = 0; i < MAX_PRODUCERS; i++) {
363
if (producers[i].vc == vc) {
364
return producers + i;
370
inline HttpTunnelConsumer *
371
HttpTunnel::get_consumer(VConnection * vc)
373
for (int i = 0; i < MAX_CONSUMERS; i++) {
374
if (consumers[i].vc == vc) {
375
return consumers + i;
381
inline HttpTunnelProducer *
382
HttpTunnel::get_producer(VIO * vio)
384
for (int i = 0; i < MAX_PRODUCERS; i++) {
385
if (producers[i].read_vio == vio) {
386
return producers + i;
392
inline HttpTunnelConsumer *
393
HttpTunnel::get_consumer(VIO * vio)
395
for (int i = 0; i < MAX_CONSUMERS; i++) {
396
if (consumers[i].write_vio == vio) {
397
return consumers + i;
404
HttpTunnel::append_message_to_producer_buffer(HttpTunnelProducer * p, const char *msg, int64_t msg_len)
406
if (p == NULL || p->read_buffer == NULL)
409
p->read_buffer->write(msg, msg_len);
410
p->nbytes += msg_len;
411
p->bytes_read += msg_len;
415
HttpTunnel::is_there_cache_write()
417
for (int i = 0; i < MAX_CONSUMERS; i++) {
418
if (consumers[i].vc_type == HT_CACHE_WRITE && consumers[i].vc != NULL) {