~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to proxy/http2/HttpTunnel.h

  • Committer: Bazaar Package Importer
  • Author(s): Arno Toell
  • Date: 2011-01-13 11:49:18 UTC
  • Revision ID: james.westby@ubuntu.com-20110113114918-vu422h8dknrgkj15
Tags: upstream-2.1.5-unstable
ImportĀ upstreamĀ versionĀ 2.1.5-unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 
 
3
  A brief file description
 
4
 
 
5
  @section license License
 
6
 
 
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
 
14
 
 
15
      http://www.apache.org/licenses/LICENSE-2.0
 
16
 
 
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.
 
22
 */
 
23
 
 
24
/****************************************************************************
 
25
 
 
26
   HttpTunnel.h
 
27
 
 
28
   Description:
 
29
 
 
30
 
 
31
****************************************************************************/
 
32
 
 
33
#ifndef _HTTP_TUNNEL_H_
 
34
#define _HTTP_TUNNEL_H_
 
35
 
 
36
#include "libts.h"
 
37
#include "P_EventSystem.h"
 
38
 
 
39
// Get rid of any previous definition first... /leif
 
40
#ifdef MAX_PRODUCERS
 
41
#undef MAX_PRODUCERS
 
42
#endif
 
43
#ifdef MAX_CONSUMERS
 
44
#undef MAX_CONSUMERS
 
45
#endif
 
46
#define MAX_PRODUCERS   2
 
47
#define MAX_CONSUMERS   4
 
48
 
 
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)
 
52
 
 
53
#define HTTP_TUNNEL_STATIC_PRODUCER  (VConnection*)!0
 
54
 
 
55
//YTS Team, yamsat Plugin
 
56
#define ALLOCATE_AND_WRITE_TO_BUF 1
 
57
#define WRITE_TO_BUF 2
 
58
 
 
59
struct HttpTunnelProducer;
 
60
class HttpSM;
 
61
class HttpPagesHandler;
 
62
typedef int (HttpSM::*HttpSMHandler) (int event, void *data);
 
63
 
 
64
struct HttpTunnelConsumer;
 
65
struct HttpTunnelProducer;
 
66
typedef int (HttpSM::*HttpProducerHandler) (int event, HttpTunnelProducer * p);
 
67
typedef int (HttpSM::*HttpConsumerHandler) (int event, HttpTunnelConsumer * c);
 
68
 
 
69
enum HttpTunnelType_t
 
70
{
 
71
  HT_HTTP_SERVER,
 
72
  HT_HTTP_CLIENT,
 
73
  HT_CACHE_READ,
 
74
  HT_CACHE_WRITE,
 
75
  HT_TRANSFORM,
 
76
  HT_STATIC
 
77
};
 
78
 
 
79
enum TunnelChunkingAction_t
 
80
{
 
81
  TCA_CHUNK_CONTENT,
 
82
  TCA_DECHUNK_CONTENT,
 
83
  TCA_PASSTHRU_CHUNKED_CONTENT,
 
84
  TCA_PASSTHRU_DECHUNKED_CONTENT
 
85
};
 
86
 
 
87
struct ChunkedHandler
 
88
{
 
89
  enum ChunkedState
 
90
  {
 
91
    CHUNK_READ_CHUNK = 0,
 
92
    CHUNK_READ_SIZE_START,
 
93
    CHUNK_READ_SIZE,
 
94
    CHUNK_READ_SIZE_CRLF,
 
95
    CHUNK_READ_TRAILER_BLANK,
 
96
    CHUNK_READ_TRAILER_CR,
 
97
    CHUNK_READ_TRAILER_LINE,
 
98
    CHUNK_READ_ERROR,
 
99
    CHUNK_READ_DONE,
 
100
    CHUNK_WRITE_CHUNK,
 
101
    CHUNK_WRITE_DONE,
 
102
    CHUNK_FLOW_CONTROL
 
103
  };
 
104
 
 
105
  IOBufferReader *chunked_reader;
 
106
  MIOBuffer *dechunked_buffer;
 
107
  int64_t dechunked_size;
 
108
 
 
109
  IOBufferReader *dechunked_reader;
 
110
  MIOBuffer *chunked_buffer;
 
111
  int64_t chunked_size;
 
112
 
 
113
  bool truncation;
 
114
  int64_t skip_bytes;
 
115
 
 
116
  ChunkedState state;
 
117
  int64_t cur_chunk_size;
 
118
  int64_t bytes_left;
 
119
  int last_server_event;
 
120
 
 
121
  // Parsing Info
 
122
  int running_sum;
 
123
  int num_digits;
 
124
 
 
125
  ChunkedHandler();
 
126
 
 
127
  void init(IOBufferReader * buffer_in, HttpTunnelProducer * p);
 
128
 
 
129
  // Returns true if complete, false otherwise
 
130
  bool process_chunked_content();
 
131
  bool generate_chunked_content();
 
132
 
 
133
private:
 
134
  void read_size();
 
135
  void read_chunk();
 
136
  void read_trailer();
 
137
  int64_t transfer_bytes();
 
138
};
 
139
 
 
140
struct HttpTunnelConsumer
 
141
{
 
142
  HttpTunnelConsumer();
 
143
 
 
144
  LINK(HttpTunnelConsumer, link);
 
145
  HttpTunnelProducer *producer;
 
146
  HttpTunnelProducer *self_producer;
 
147
 
 
148
  HttpTunnelType_t vc_type;
 
149
  VConnection *vc;
 
150
  IOBufferReader *buffer_reader;
 
151
  HttpConsumerHandler vc_handler;
 
152
  VIO *write_vio;
 
153
 
 
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
 
157
 
 
158
  bool alive;
 
159
  bool write_success;
 
160
  const char *name;
 
161
};
 
162
 
 
163
struct HttpTunnelProducer
 
164
{
 
165
  HttpTunnelProducer();
 
166
 
 
167
  DLL<HttpTunnelConsumer> consumer_list;
 
168
  HttpTunnelConsumer *self_consumer;
 
169
  VConnection *vc;
 
170
  HttpProducerHandler vc_handler;
 
171
  VIO *read_vio;
 
172
  MIOBuffer *read_buffer;
 
173
  IOBufferReader *buffer_start;
 
174
  HttpTunnelType_t vc_type;
 
175
 
 
176
  ChunkedHandler chunked_handler;
 
177
  TunnelChunkingAction_t chunking_action;
 
178
 
 
179
  bool do_chunking;
 
180
  bool do_dechunking;
 
181
  bool do_chunked_passthru;
 
182
 
 
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
 
188
 
 
189
  int num_consumers;
 
190
 
 
191
  bool alive;
 
192
  bool read_success;
 
193
  const char *name;
 
194
};
 
195
 
 
196
class PostDataBuffers
 
197
{
 
198
public:
 
199
  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]");  }
 
203
 
 
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;
 
209
};
 
210
 
 
211
class HttpTunnel:public Continuation
 
212
{
 
213
  friend class HttpPagesHandler;
 
214
  friend class CoreUtils;
 
215
public:
 
216
  HttpTunnel();
 
217
 
 
218
  void init(HttpSM * sm_arg, ProxyMutex * amutex);
 
219
  void reset();
 
220
  void kill_tunnel();
 
221
  bool is_tunnel_active() { return active; }
 
222
  bool is_tunnel_alive();
 
223
  bool is_there_cache_write();
 
224
 
 
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();
 
230
 
 
231
  HttpTunnelProducer *add_producer(VConnection * vc,
 
232
                                   int64_t nbytes,
 
233
                                   IOBufferReader * reader_start,
 
234
                                   HttpProducerHandler sm_handler, HttpTunnelType_t vc_type, const char *name);
 
235
 
 
236
  void set_producer_chunking_action(HttpTunnelProducer * p, int64_t skip_bytes, TunnelChunkingAction_t action);
 
237
 
 
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);
 
242
 
 
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);
 
248
 
 
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);
 
260
 
 
261
  void close_vc(HttpTunnelProducer * p);
 
262
  void close_vc(HttpTunnelConsumer * c);
 
263
 
 
264
private:
 
265
 
 
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);
 
270
 
 
271
  HttpTunnelProducer *get_producer(VIO * vio);
 
272
  HttpTunnelConsumer *get_consumer(VIO * vio);
 
273
 
 
274
  HttpTunnelProducer *alloc_producer();
 
275
  HttpTunnelConsumer *alloc_consumer();
 
276
 
 
277
  int num_producers;
 
278
  int num_consumers;
 
279
  HttpTunnelConsumer consumers[MAX_CONSUMERS];
 
280
  HttpTunnelProducer producers[MAX_PRODUCERS];
 
281
  HttpSM *sm;
 
282
 
 
283
  bool active;
 
284
 
 
285
public:
 
286
  PostDataBuffers * postbuf;
 
287
};
 
288
 
 
289
extern void init_max_chunk_buf();
 
290
 
 
291
// void HttpTunnel::abort_cache_write_finish_others
 
292
//
 
293
//    Abort all downstream cache writes and finsish
 
294
//      all other local consumers
 
295
//
 
296
inline void
 
297
HttpTunnel::abort_cache_write_finish_others(HttpTunnelProducer * p)
 
298
{
 
299
  chain_abort_cache_write(p);
 
300
  local_finish_all(p);
 
301
}
 
302
 
 
303
// void HttpTunnel::local_finish_all(HttpTunnelProducer* p)
 
304
//
 
305
//   After the producer has finished, causes direct consumers
 
306
//      to finish their writes
 
307
//
 
308
inline void
 
309
HttpTunnel::local_finish_all(HttpTunnelProducer * p)
 
310
{
 
311
  finish_all_internal(p, false);
 
312
}
 
313
 
 
314
// void HttpTunnel::chain_finish_all(HttpTunnelProducer* p)
 
315
//
 
316
//   After the producer has finished, cause everyone
 
317
//    downstream in the tunnel to send everything
 
318
//    that producer has placed in the buffer
 
319
//
 
320
inline void
 
321
HttpTunnel::chain_finish_all(HttpTunnelProducer * p)
 
322
{
 
323
  finish_all_internal(p, true);
 
324
}
 
325
 
 
326
inline bool
 
327
HttpTunnel::is_tunnel_alive()
 
328
{
 
329
  bool tunnel_alive = false;
 
330
 
 
331
  for (int i = 0; i < MAX_PRODUCERS; i++) {
 
332
    if (producers[i].alive == true) {
 
333
      tunnel_alive = true;
 
334
      break;
 
335
    }
 
336
  }
 
337
  if (!tunnel_alive) {
 
338
    for (int i = 0; i < MAX_CONSUMERS; i++) {
 
339
      if (consumers[i].alive == true) {
 
340
        tunnel_alive = true;
 
341
        break;
 
342
      }
 
343
    }
 
344
 
 
345
  }
 
346
 
 
347
  return tunnel_alive;
 
348
}
 
349
 
 
350
inline void
 
351
HttpTunnel::init(HttpSM * sm_arg, ProxyMutex * amutex)
 
352
{
 
353
  sm = sm_arg;
 
354
  active = false;
 
355
  mutex = amutex;
 
356
  SET_HANDLER(&HttpTunnel::main_handler);
 
357
}
 
358
 
 
359
inline HttpTunnelProducer *
 
360
HttpTunnel::get_producer(VConnection * vc)
 
361
{
 
362
  for (int i = 0; i < MAX_PRODUCERS; i++) {
 
363
    if (producers[i].vc == vc) {
 
364
      return producers + i;
 
365
    }
 
366
  }
 
367
  return NULL;
 
368
}
 
369
 
 
370
inline HttpTunnelConsumer *
 
371
HttpTunnel::get_consumer(VConnection * vc)
 
372
{
 
373
  for (int i = 0; i < MAX_CONSUMERS; i++) {
 
374
    if (consumers[i].vc == vc) {
 
375
      return consumers + i;
 
376
    }
 
377
  }
 
378
  return NULL;
 
379
}
 
380
 
 
381
inline HttpTunnelProducer *
 
382
HttpTunnel::get_producer(VIO * vio)
 
383
{
 
384
  for (int i = 0; i < MAX_PRODUCERS; i++) {
 
385
    if (producers[i].read_vio == vio) {
 
386
      return producers + i;
 
387
    }
 
388
  }
 
389
  return NULL;
 
390
}
 
391
 
 
392
inline HttpTunnelConsumer *
 
393
HttpTunnel::get_consumer(VIO * vio)
 
394
{
 
395
  for (int i = 0; i < MAX_CONSUMERS; i++) {
 
396
    if (consumers[i].write_vio == vio) {
 
397
      return consumers + i;
 
398
    }
 
399
  }
 
400
  return NULL;
 
401
}
 
402
 
 
403
inline void
 
404
HttpTunnel::append_message_to_producer_buffer(HttpTunnelProducer * p, const char *msg, int64_t msg_len)
 
405
{
 
406
  if (p == NULL || p->read_buffer == NULL)
 
407
    return;
 
408
 
 
409
  p->read_buffer->write(msg, msg_len);
 
410
  p->nbytes += msg_len;
 
411
  p->bytes_read += msg_len;
 
412
}
 
413
 
 
414
inline bool
 
415
HttpTunnel::is_there_cache_write()
 
416
{
 
417
  for (int i = 0; i < MAX_CONSUMERS; i++) {
 
418
    if (consumers[i].vc_type == HT_CACHE_WRITE && consumers[i].vc != NULL) {
 
419
      return true;
 
420
    }
 
421
  }
 
422
  return false;
 
423
}
 
424
#endif