~ubuntu-branches/ubuntu/maverick/libtorrent-rasterbar/maverick

« back to all changes in this revision

Viewing changes to include/libtorrent/asio/ssl/stream.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Cristian Greco
  • Date: 2008-07-02 10:46:21 UTC
  • Revision ID: james.westby@ubuntu.com-20080702104621-jzx3pfke9lkcxfxn
Tags: upstream-0.13.1
ImportĀ upstreamĀ versionĀ 0.13.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// stream.hpp
 
3
// ~~~~~~~~~~
 
4
//
 
5
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
 
6
// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 
7
//
 
8
// Distributed under the Boost Software License, Version 1.0. (See accompanying
 
9
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
10
//
 
11
 
 
12
#ifndef ASIO_SSL_STREAM_HPP
 
13
#define ASIO_SSL_STREAM_HPP
 
14
 
 
15
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
 
16
# pragma once
 
17
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
18
 
 
19
#include "asio/detail/push_options.hpp"
 
20
 
 
21
#include "asio/detail/push_options.hpp"
 
22
#include <cstddef>
 
23
#include <boost/config.hpp>
 
24
#include <boost/noncopyable.hpp>
 
25
#include <boost/type_traits.hpp>
 
26
#include "asio/detail/pop_options.hpp"
 
27
 
 
28
#include "asio/error.hpp"
 
29
#include "asio/ssl/basic_context.hpp"
 
30
#include "asio/ssl/stream_base.hpp"
 
31
#include "asio/ssl/stream_service.hpp"
 
32
#include "asio/detail/throw_error.hpp"
 
33
 
 
34
namespace asio {
 
35
namespace ssl {
 
36
 
 
37
/// Provides stream-oriented functionality using SSL.
 
38
/**
 
39
 * The stream class template provides asynchronous and blocking stream-oriented
 
40
 * functionality using SSL.
 
41
 *
 
42
 * @par Thread Safety
 
43
 * @e Distinct @e objects: Safe.@n
 
44
 * @e Shared @e objects: Unsafe.
 
45
 *
 
46
 * @par Example
 
47
 * To use the SSL stream template with an ip::tcp::socket, you would write:
 
48
 * @code
 
49
 * asio::io_service io_service;
 
50
 * asio::ssl::context context(io_service, asio::ssl::context::sslv23);
 
51
 * asio::ssl::stream<asio::ip::tcp::socket> sock(io_service, context);
 
52
 * @endcode
 
53
 *
 
54
 * @par Concepts:
 
55
 * AsyncReadStream, AsyncWriteStream, Stream, SyncRead_Stream, SyncWriteStream.
 
56
 */
 
57
template <typename Stream, typename Service = stream_service>
 
58
class stream
 
59
  : public stream_base,
 
60
    private boost::noncopyable
 
61
{
 
62
public:
 
63
  /// The type of the next layer.
 
64
  typedef typename boost::remove_reference<Stream>::type next_layer_type;
 
65
 
 
66
  /// The type of the lowest layer.
 
67
  typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
 
68
 
 
69
  /// The type of the service that will be used to provide stream operations.
 
70
  typedef Service service_type;
 
71
 
 
72
  /// The native implementation type of the stream.
 
73
  typedef typename service_type::impl_type impl_type;
 
74
 
 
75
  /// Construct a stream.
 
76
  /**
 
77
   * This constructor creates a stream and initialises the underlying stream
 
78
   * object.
 
79
   *
 
80
   * @param arg The argument to be passed to initialise the underlying stream.
 
81
   *
 
82
   * @param context The SSL context to be used for the stream.
 
83
   */
 
84
  template <typename Arg, typename Context_Service>
 
85
  explicit stream(Arg& arg, basic_context<Context_Service>& context)
 
86
    : next_layer_(arg),
 
87
      service_(asio::use_service<Service>(next_layer_.get_io_service())),
 
88
      impl_(service_.null())
 
89
  {
 
90
    service_.create(impl_, next_layer_, context);
 
91
  }
 
92
 
 
93
  /// Destructor.
 
94
  ~stream()
 
95
  {
 
96
    service_.destroy(impl_, next_layer_);
 
97
  }
 
98
 
 
99
  /// (Deprecated: use get_io_service().) Get the io_service associated with
 
100
  /// the object.
 
101
  /**
 
102
   * This function may be used to obtain the io_service object that the stream
 
103
   * uses to dispatch handlers for asynchronous operations.
 
104
   *
 
105
   * @return A reference to the io_service object that stream will use to
 
106
   * dispatch handlers. Ownership is not transferred to the caller.
 
107
   */
 
108
  asio::io_service& io_service()
 
109
  {
 
110
    return next_layer_.get_io_service();
 
111
  }
 
112
 
 
113
  /// Get the io_service associated with the object.
 
114
  /**
 
115
   * This function may be used to obtain the io_service object that the stream
 
116
   * uses to dispatch handlers for asynchronous operations.
 
117
   *
 
118
   * @return A reference to the io_service object that stream will use to
 
119
   * dispatch handlers. Ownership is not transferred to the caller.
 
120
   */
 
121
  asio::io_service& get_io_service()
 
122
  {
 
123
    return next_layer_.get_io_service();
 
124
  }
 
125
 
 
126
  /// Get a reference to the next layer.
 
127
  /**
 
128
   * This function returns a reference to the next layer in a stack of stream
 
129
   * layers.
 
130
   *
 
131
   * @return A reference to the next layer in the stack of stream layers.
 
132
   * Ownership is not transferred to the caller.
 
133
   */
 
134
  next_layer_type& next_layer()
 
135
  {
 
136
    return next_layer_;
 
137
  }
 
138
 
 
139
  /// Get a reference to the lowest layer.
 
140
  /**
 
141
   * This function returns a reference to the lowest layer in a stack of
 
142
   * stream layers.
 
143
   *
 
144
   * @return A reference to the lowest layer in the stack of stream layers.
 
145
   * Ownership is not transferred to the caller.
 
146
   */
 
147
  lowest_layer_type& lowest_layer()
 
148
  {
 
149
    return next_layer_.lowest_layer();
 
150
  }
 
151
 
 
152
  /// Get the underlying implementation in the native type.
 
153
  /**
 
154
   * This function may be used to obtain the underlying implementation of the
 
155
   * context. This is intended to allow access to stream functionality that is
 
156
   * not otherwise provided.
 
157
   */
 
158
  impl_type impl()
 
159
  {
 
160
    return impl_;
 
161
  }
 
162
 
 
163
  /// Perform SSL handshaking.
 
164
  /**
 
165
   * This function is used to perform SSL handshaking on the stream. The
 
166
   * function call will block until handshaking is complete or an error occurs.
 
167
   *
 
168
   * @param type The type of handshaking to be performed, i.e. as a client or as
 
169
   * a server.
 
170
   *
 
171
   * @throws asio::system_error Thrown on failure.
 
172
   */
 
173
  void handshake(handshake_type type)
 
174
  {
 
175
    asio::error_code ec;
 
176
    service_.handshake(impl_, next_layer_, type, ec);
 
177
    asio::detail::throw_error(ec);
 
178
  }
 
179
 
 
180
  /// Perform SSL handshaking.
 
181
  /**
 
182
   * This function is used to perform SSL handshaking on the stream. The
 
183
   * function call will block until handshaking is complete or an error occurs.
 
184
   *
 
185
   * @param type The type of handshaking to be performed, i.e. as a client or as
 
186
   * a server.
 
187
   *
 
188
   * @param ec Set to indicate what error occurred, if any.
 
189
   */
 
190
  asio::error_code handshake(handshake_type type,
 
191
      asio::error_code& ec)
 
192
  {
 
193
    return service_.handshake(impl_, next_layer_, type, ec);
 
194
  }
 
195
 
 
196
  /// Start an asynchronous SSL handshake.
 
197
  /**
 
198
   * This function is used to asynchronously perform an SSL handshake on the
 
199
   * stream. This function call always returns immediately.
 
200
   *
 
201
   * @param type The type of handshaking to be performed, i.e. as a client or as
 
202
   * a server.
 
203
   *
 
204
   * @param handler The handler to be called when the handshake operation
 
205
   * completes. Copies will be made of the handler as required. The equivalent
 
206
   * function signature of the handler must be:
 
207
   * @code void handler(
 
208
   *   const asio::error_code& error // Result of operation.
 
209
   * ); @endcode
 
210
   */
 
211
  template <typename HandshakeHandler>
 
212
  void async_handshake(handshake_type type, HandshakeHandler handler)
 
213
  {
 
214
    service_.async_handshake(impl_, next_layer_, type, handler);
 
215
  }
 
216
 
 
217
  /// Shut down SSL on the stream.
 
218
  /**
 
219
   * This function is used to shut down SSL on the stream. The function call
 
220
   * will block until SSL has been shut down or an error occurs.
 
221
   *
 
222
   * @throws asio::system_error Thrown on failure.
 
223
   */
 
224
  void shutdown()
 
225
  {
 
226
    asio::error_code ec;
 
227
    service_.shutdown(impl_, next_layer_, ec);
 
228
    asio::detail::throw_error(ec);
 
229
  }
 
230
 
 
231
  /// Shut down SSL on the stream.
 
232
  /**
 
233
   * This function is used to shut down SSL on the stream. The function call
 
234
   * will block until SSL has been shut down or an error occurs.
 
235
   *
 
236
   * @param ec Set to indicate what error occurred, if any.
 
237
   */
 
238
  asio::error_code shutdown(asio::error_code& ec)
 
239
  {
 
240
    return service_.shutdown(impl_, next_layer_, ec);
 
241
  }
 
242
 
 
243
  /// Asynchronously shut down SSL on the stream.
 
244
  /**
 
245
   * This function is used to asynchronously shut down SSL on the stream. This
 
246
   * function call always returns immediately.
 
247
   *
 
248
   * @param handler The handler to be called when the handshake operation
 
249
   * completes. Copies will be made of the handler as required. The equivalent
 
250
   * function signature of the handler must be:
 
251
   * @code void handler(
 
252
   *   const asio::error_code& error // Result of operation.
 
253
   * ); @endcode
 
254
   */
 
255
  template <typename ShutdownHandler>
 
256
  void async_shutdown(ShutdownHandler handler)
 
257
  {
 
258
    service_.async_shutdown(impl_, next_layer_, handler);
 
259
  }
 
260
 
 
261
  /// Write some data to the stream.
 
262
  /**
 
263
   * This function is used to write data on the stream. The function call will
 
264
   * block until one or more bytes of data has been written successfully, or
 
265
   * until an error occurs.
 
266
   *
 
267
   * @param buffers The data to be written.
 
268
   *
 
269
   * @returns The number of bytes written.
 
270
   *
 
271
   * @throws asio::system_error Thrown on failure.
 
272
   *
 
273
   * @note The write_some operation may not transmit all of the data to the
 
274
   * peer. Consider using the @ref write function if you need to ensure that all
 
275
   * data is written before the blocking operation completes.
 
276
   */
 
277
  template <typename ConstBufferSequence>
 
278
  std::size_t write_some(const ConstBufferSequence& buffers)
 
279
  {
 
280
    asio::error_code ec;
 
281
    std::size_t s = service_.write_some(impl_, next_layer_, buffers, ec);
 
282
    asio::detail::throw_error(ec);
 
283
    return s;
 
284
  }
 
285
 
 
286
  /// Write some data to the stream.
 
287
  /**
 
288
   * This function is used to write data on the stream. The function call will
 
289
   * block until one or more bytes of data has been written successfully, or
 
290
   * until an error occurs.
 
291
   *
 
292
   * @param buffers The data to be written to the stream.
 
293
   *
 
294
   * @param ec Set to indicate what error occurred, if any.
 
295
   *
 
296
   * @returns The number of bytes written. Returns 0 if an error occurred.
 
297
   *
 
298
   * @note The write_some operation may not transmit all of the data to the
 
299
   * peer. Consider using the @ref write function if you need to ensure that all
 
300
   * data is written before the blocking operation completes.
 
301
   */
 
302
  template <typename ConstBufferSequence>
 
303
  std::size_t write_some(const ConstBufferSequence& buffers,
 
304
      asio::error_code& ec)
 
305
  {
 
306
    return service_.write_some(impl_, next_layer_, buffers, ec);
 
307
  }
 
308
 
 
309
  /// Start an asynchronous write.
 
310
  /**
 
311
   * This function is used to asynchronously write one or more bytes of data to
 
312
   * the stream. The function call always returns immediately.
 
313
   *
 
314
   * @param buffers The data to be written to the stream. Although the buffers
 
315
   * object may be copied as necessary, ownership of the underlying buffers is
 
316
   * retained by the caller, which must guarantee that they remain valid until
 
317
   * the handler is called.
 
318
   *
 
319
   * @param handler The handler to be called when the write operation completes.
 
320
   * Copies will be made of the handler as required. The equivalent function
 
321
   * signature of the handler must be:
 
322
   * @code void handler(
 
323
   *   const asio::error_code& error, // Result of operation.
 
324
   *   std::size_t bytes_transferred           // Number of bytes written.
 
325
   * ); @endcode
 
326
   *
 
327
   * @note The async_write_some operation may not transmit all of the data to
 
328
   * the peer. Consider using the @ref async_write function if you need to
 
329
   * ensure that all data is written before the blocking operation completes.
 
330
   */
 
331
  template <typename ConstBufferSequence, typename WriteHandler>
 
332
  void async_write_some(const ConstBufferSequence& buffers,
 
333
      WriteHandler handler)
 
334
  {
 
335
    service_.async_write_some(impl_, next_layer_, buffers, handler);
 
336
  }
 
337
 
 
338
  /// Read some data from the stream.
 
339
  /**
 
340
   * This function is used to read data from the stream. The function call will
 
341
   * block until one or more bytes of data has been read successfully, or until
 
342
   * an error occurs.
 
343
   *
 
344
   * @param buffers The buffers into which the data will be read.
 
345
   *
 
346
   * @returns The number of bytes read.
 
347
   *
 
348
   * @throws asio::system_error Thrown on failure.
 
349
   *
 
350
   * @note The read_some operation may not read all of the requested number of
 
351
   * bytes. Consider using the @ref read function if you need to ensure that the
 
352
   * requested amount of data is read before the blocking operation completes.
 
353
   */
 
354
  template <typename MutableBufferSequence>
 
355
  std::size_t read_some(const MutableBufferSequence& buffers)
 
356
  {
 
357
    asio::error_code ec;
 
358
    std::size_t s = service_.read_some(impl_, next_layer_, buffers, ec);
 
359
    asio::detail::throw_error(ec);
 
360
    return s;
 
361
  }
 
362
 
 
363
  /// Read some data from the stream.
 
364
  /**
 
365
   * This function is used to read data from the stream. The function call will
 
366
   * block until one or more bytes of data has been read successfully, or until
 
367
   * an error occurs.
 
368
   *
 
369
   * @param buffers The buffers into which the data will be read.
 
370
   *
 
371
   * @param ec Set to indicate what error occurred, if any.
 
372
   *
 
373
   * @returns The number of bytes read. Returns 0 if an error occurred.
 
374
   *
 
375
   * @note The read_some operation may not read all of the requested number of
 
376
   * bytes. Consider using the @ref read function if you need to ensure that the
 
377
   * requested amount of data is read before the blocking operation completes.
 
378
   */
 
379
  template <typename MutableBufferSequence>
 
380
  std::size_t read_some(const MutableBufferSequence& buffers,
 
381
      asio::error_code& ec)
 
382
  {
 
383
    return service_.read_some(impl_, next_layer_, buffers, ec);
 
384
  }
 
385
 
 
386
  /// Start an asynchronous read.
 
387
  /**
 
388
   * This function is used to asynchronously read one or more bytes of data from
 
389
   * the stream. The function call always returns immediately.
 
390
   *
 
391
   * @param buffers The buffers into which the data will be read. Although the
 
392
   * buffers object may be copied as necessary, ownership of the underlying
 
393
   * buffers is retained by the caller, which must guarantee that they remain
 
394
   * valid until the handler is called.
 
395
   *
 
396
   * @param handler The handler to be called when the read operation completes.
 
397
   * Copies will be made of the handler as required. The equivalent function
 
398
   * signature of the handler must be:
 
399
   * @code void handler(
 
400
   *   const asio::error_code& error, // Result of operation.
 
401
   *   std::size_t bytes_transferred           // Number of bytes read.
 
402
   * ); @endcode
 
403
   *
 
404
   * @note The async_read_some operation may not read all of the requested
 
405
   * number of bytes. Consider using the @ref async_read function if you need to
 
406
   * ensure that the requested amount of data is read before the asynchronous
 
407
   * operation completes.
 
408
   */
 
409
  template <typename MutableBufferSequence, typename ReadHandler>
 
410
  void async_read_some(const MutableBufferSequence& buffers,
 
411
      ReadHandler handler)
 
412
  {
 
413
    service_.async_read_some(impl_, next_layer_, buffers, handler);
 
414
  }
 
415
 
 
416
  /// Peek at the incoming data on the stream.
 
417
  /**
 
418
   * This function is used to peek at the incoming data on the stream, without
 
419
   * removing it from the input queue. The function call will block until data
 
420
   * has been read successfully or an error occurs.
 
421
   *
 
422
   * @param buffers The buffers into which the data will be read.
 
423
   *
 
424
   * @returns The number of bytes read.
 
425
   *
 
426
   * @throws asio::system_error Thrown on failure.
 
427
   */
 
428
  template <typename MutableBufferSequence>
 
429
  std::size_t peek(const MutableBufferSequence& buffers)
 
430
  {
 
431
    asio::error_code ec;
 
432
    std::size_t s = service_.peek(impl_, next_layer_, buffers, ec);
 
433
    asio::detail::throw_error(ec);
 
434
    return s;
 
435
  }
 
436
 
 
437
  /// Peek at the incoming data on the stream.
 
438
  /**
 
439
   * This function is used to peek at the incoming data on the stream, withoutxi
 
440
   * removing it from the input queue. The function call will block until data
 
441
   * has been read successfully or an error occurs.
 
442
   *
 
443
   * @param buffers The buffers into which the data will be read.
 
444
   *
 
445
   * @param ec Set to indicate what error occurred, if any.
 
446
   *
 
447
   * @returns The number of bytes read. Returns 0 if an error occurred.
 
448
   */
 
449
  template <typename MutableBufferSequence>
 
450
  std::size_t peek(const MutableBufferSequence& buffers,
 
451
      asio::error_code& ec)
 
452
  {
 
453
    return service_.peek(impl_, next_layer_, buffers, ec);
 
454
  }
 
455
 
 
456
  /// Determine the amount of data that may be read without blocking.
 
457
  /**
 
458
   * This function is used to determine the amount of data, in bytes, that may
 
459
   * be read from the stream without blocking.
 
460
   *
 
461
   * @returns The number of bytes of data that can be read without blocking.
 
462
   *
 
463
   * @throws asio::system_error Thrown on failure.
 
464
   */
 
465
  std::size_t in_avail()
 
466
  {
 
467
    asio::error_code ec;
 
468
    std::size_t s = service_.in_avail(impl_, next_layer_, ec);
 
469
    asio::detail::throw_error(ec);
 
470
    return s;
 
471
  }
 
472
 
 
473
  /// Determine the amount of data that may be read without blocking.
 
474
  /**
 
475
   * This function is used to determine the amount of data, in bytes, that may
 
476
   * be read from the stream without blocking.
 
477
   *
 
478
   * @param ec Set to indicate what error occurred, if any.
 
479
   *
 
480
   * @returns The number of bytes of data that can be read without blocking.
 
481
   */
 
482
  std::size_t in_avail(asio::error_code& ec)
 
483
  {
 
484
    return service_.in_avail(impl_, next_layer_, ec);
 
485
  }
 
486
 
 
487
private:
 
488
  /// The next layer.
 
489
  Stream next_layer_;
 
490
 
 
491
  /// The backend service implementation.
 
492
  service_type& service_;
 
493
 
 
494
  /// The underlying native implementation.
 
495
  impl_type impl_;
 
496
};
 
497
 
 
498
} // namespace ssl
 
499
} // namespace asio
 
500
 
 
501
#include "asio/detail/pop_options.hpp"
 
502
 
 
503
#endif // ASIO_SSL_STREAM_HPP