This source file includes following definitions.
- zlib_deflate_free
- zlib_inflate_free
- getstate
- zlib_input_filter
- zlib_output_filter
- readcb
- writecb
- errorcb
- test_bufferevent_zlib
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 #undef NDEBUG
  29 
  30 #ifdef WIN32
  31 #include <winsock2.h>
  32 #include <windows.h>
  33 #endif
  34 
  35 #include "event2/event-config.h"
  36 
  37 #include <sys/types.h>
  38 #ifndef WIN32
  39 #include <sys/socket.h>
  40 #include <sys/wait.h>
  41 #include <unistd.h>
  42 #include <netdb.h>
  43 #endif
  44 #include <signal.h>
  45 #include <stdio.h>
  46 #include <stdlib.h>
  47 #include <string.h>
  48 
  49 #include <assert.h>
  50 #include <errno.h>
  51 
  52 #include "event2/util.h"
  53 #include "event2/event.h"
  54 #include "event2/event_compat.h"
  55 #include "event2/buffer.h"
  56 #include "event2/bufferevent.h"
  57 
  58 #include "regress.h"
  59 
  60 
  61 
  62 
  63 
  64 
  65 
  66 
  67 #ifndef _LARGEFILE64_SOURCE
  68 #define _LARGEFILE64_SOURCE 0
  69 #endif
  70 #ifndef _LFS64_LARGEFILE
  71 #define _LFS64_LARGEFILE 0
  72 #endif
  73 #ifndef _FILE_OFFSET_BITS
  74 #define _FILE_OFFSET_BITS 0
  75 #endif
  76 #ifndef off64_t
  77 #define off64_t ev_int64_t
  78 #endif
  79 
  80 #include <zlib.h>
  81 
  82 static int infilter_calls;
  83 static int outfilter_calls;
  84 static int readcb_finished;
  85 static int writecb_finished;
  86 static int errorcb_invoked;
  87 
  88 
  89 
  90 
  91 
  92 static void
  93 zlib_deflate_free(void *ctx)
  94 {
  95         z_streamp p = ctx;
  96 
  97         assert(deflateEnd(p) == Z_OK);
  98 }
  99 
 100 static void
 101 zlib_inflate_free(void *ctx)
 102 {
 103         z_streamp p = ctx;
 104 
 105         assert(inflateEnd(p) == Z_OK);
 106 }
 107 
 108 static int
 109 getstate(enum bufferevent_flush_mode state)
 110 {
 111         switch (state) {
 112         case BEV_FINISHED:
 113                 return Z_FINISH;
 114         case BEV_FLUSH:
 115                 return Z_SYNC_FLUSH;
 116         case BEV_NORMAL:
 117         default:
 118                 return Z_NO_FLUSH;
 119         }
 120 }
 121 
 122 
 123 
 124 
 125 
 126 
 127 static enum bufferevent_filter_result
 128 zlib_input_filter(struct evbuffer *src, struct evbuffer *dst,
 129     ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx)
 130 {
 131         struct evbuffer_iovec v_in[1];
 132         struct evbuffer_iovec v_out[1];
 133         int nread, nwrite;
 134         int res, n;
 135 
 136         z_streamp p = ctx;
 137 
 138         do {
 139                 
 140                 n = evbuffer_peek(src, -1, NULL, v_in, 1);
 141                 if (n) {
 142                         p->avail_in = v_in[0].iov_len;
 143                         p->next_in = v_in[0].iov_base;
 144                 } else {
 145                         p->avail_in = 0;
 146                         p->next_in = 0;
 147                 }
 148 
 149                 evbuffer_reserve_space(dst, 4096, v_out, 1);
 150                 p->next_out = v_out[0].iov_base;
 151                 p->avail_out = v_out[0].iov_len;
 152 
 153                 
 154                 res = inflate(p, getstate(state));
 155 
 156                 
 157                 nread = v_in[0].iov_len - p->avail_in;
 158                 nwrite = v_out[0].iov_len - p->avail_out;
 159 
 160                 evbuffer_drain(src, nread);
 161                 v_out[0].iov_len = nwrite;
 162                 evbuffer_commit_space(dst, v_out, 1);
 163 
 164                 if (res==Z_BUF_ERROR) {
 165                         
 166 
 167 
 168                         if (nwrite == 0)
 169                                 return BEV_NEED_MORE;
 170                 } else {
 171                         assert(res == Z_OK || res == Z_STREAM_END);
 172                 }
 173 
 174         } while (evbuffer_get_length(src) > 0);
 175 
 176         ++infilter_calls;
 177 
 178         return (BEV_OK);
 179 }
 180 
 181 static enum bufferevent_filter_result
 182 zlib_output_filter(struct evbuffer *src, struct evbuffer *dst,
 183     ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx)
 184 {
 185         struct evbuffer_iovec v_in[1];
 186         struct evbuffer_iovec v_out[1];
 187         int nread, nwrite;
 188         int res, n;
 189 
 190         z_streamp p = ctx;
 191 
 192         do {
 193                 
 194                 n = evbuffer_peek(src, -1, NULL, v_in, 1);
 195                 if (n) {
 196                         p->avail_in = v_in[0].iov_len;
 197                         p->next_in = v_in[0].iov_base;
 198                 } else {
 199                         p->avail_in = 0;
 200                         p->next_in = 0;
 201                 }
 202 
 203                 evbuffer_reserve_space(dst, 4096, v_out, 1);
 204                 p->next_out = v_out[0].iov_base;
 205                 p->avail_out = v_out[0].iov_len;
 206 
 207                 
 208                 res = deflate(p, getstate(state));
 209 
 210                 
 211                 nread = v_in[0].iov_len - p->avail_in;
 212                 nwrite = v_out[0].iov_len - p->avail_out;
 213 
 214                 evbuffer_drain(src, nread);
 215                 v_out[0].iov_len = nwrite;
 216                 evbuffer_commit_space(dst, v_out, 1);
 217 
 218                 if (res==Z_BUF_ERROR) {
 219                         
 220 
 221 
 222                         if (nwrite == 0)
 223                                 return BEV_NEED_MORE;
 224                 } else {
 225                         assert(res == Z_OK || res == Z_STREAM_END);
 226                 }
 227 
 228         } while (evbuffer_get_length(src) > 0);
 229 
 230         ++outfilter_calls;
 231 
 232         return (BEV_OK);
 233 }
 234 
 235 
 236 
 237 
 238 
 239 static void
 240 readcb(struct bufferevent *bev, void *arg)
 241 {
 242         if (evbuffer_get_length(bufferevent_get_input(bev)) == 8333) {
 243                 struct evbuffer *evbuf = evbuffer_new();
 244                 assert(evbuf != NULL);
 245 
 246                 
 247                 bufferevent_read_buffer(bev, evbuf);
 248 
 249                 bufferevent_disable(bev, EV_READ);
 250 
 251                 if (evbuffer_get_length(evbuf) == 8333) {
 252                         ++readcb_finished;
 253                 }
 254 
 255                 evbuffer_free(evbuf);
 256         }
 257 }
 258 
 259 static void
 260 writecb(struct bufferevent *bev, void *arg)
 261 {
 262         if (evbuffer_get_length(bufferevent_get_output(bev)) == 0) {
 263                 ++writecb_finished;
 264         }
 265 }
 266 
 267 static void
 268 errorcb(struct bufferevent *bev, short what, void *arg)
 269 {
 270         errorcb_invoked = 1;
 271 }
 272 
 273 void
 274 test_bufferevent_zlib(void *arg)
 275 {
 276         struct bufferevent *bev1=NULL, *bev2=NULL;
 277         char buffer[8333];
 278         z_stream z_input, z_output;
 279         int i, r;
 280         evutil_socket_t pair[2] = {-1, -1};
 281         (void)arg;
 282 
 283         infilter_calls = outfilter_calls = readcb_finished = writecb_finished
 284             = errorcb_invoked = 0;
 285 
 286         if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
 287                 tt_abort_perror("socketpair");
 288         }
 289 
 290         evutil_make_socket_nonblocking(pair[0]);
 291         evutil_make_socket_nonblocking(pair[1]);
 292 
 293         bev1 = bufferevent_socket_new(NULL, pair[0], 0);
 294         bev2 = bufferevent_socket_new(NULL, pair[1], 0);
 295 
 296         memset(&z_output, 0, sizeof(z_output));
 297         r = deflateInit(&z_output, Z_DEFAULT_COMPRESSION);
 298         tt_int_op(r, ==, Z_OK);
 299         memset(&z_input, 0, sizeof(z_input));
 300         r = inflateInit(&z_input);
 301         tt_int_op(r, ==, Z_OK);
 302 
 303         
 304         bev1 = bufferevent_filter_new(bev1, NULL, zlib_output_filter,
 305             BEV_OPT_CLOSE_ON_FREE, zlib_deflate_free, &z_output);
 306         bev2 = bufferevent_filter_new(bev2, zlib_input_filter,
 307             NULL, BEV_OPT_CLOSE_ON_FREE, zlib_inflate_free, &z_input);
 308         bufferevent_setcb(bev1, readcb, writecb, errorcb, NULL);
 309         bufferevent_setcb(bev2, readcb, writecb, errorcb, NULL);
 310 
 311         bufferevent_disable(bev1, EV_READ);
 312         bufferevent_enable(bev1, EV_WRITE);
 313 
 314         bufferevent_enable(bev2, EV_READ);
 315 
 316         for (i = 0; i < (int)sizeof(buffer); i++)
 317                 buffer[i] = i;
 318 
 319         
 320         bufferevent_write(bev1, buffer, 1800);
 321         bufferevent_write(bev1, buffer + 1800, sizeof(buffer) - 1800);
 322 
 323         
 324         bufferevent_flush(bev1, EV_WRITE, BEV_FINISHED);
 325 
 326         event_dispatch();
 327 
 328         tt_want(infilter_calls);
 329         tt_want(outfilter_calls);
 330         tt_want(readcb_finished);
 331         tt_want(writecb_finished);
 332         tt_want(!errorcb_invoked);
 333 
 334         test_ok = 1;
 335 end:
 336         if (bev1)
 337                 bufferevent_free(bev1);
 338         if (bev2)
 339                 bufferevent_free(bev2);
 340 
 341         if (pair[0] >= 0)
 342                 evutil_closesocket(pair[0]);
 343         if (pair[1] >= 0)
 344                 evutil_closesocket(pair[1]);
 345 }