mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
- [FEATURE] QUIC and HTTP/3 Internet Draft 31 support. Drop ID-30 and ID-31 support. - [BUGFIX] Divide-by-zero in newly enabled conn stats code when no packets were sent. - [BUGFIX] Memory leak in gQUIC client when server hello cannot be parsed. - [BUGFIX] Server Initial packet size calculation. - Log user-agent and CONN_CLOSE reason when peer reports error. - Example programs: Specify ALPN for echo and md5 clients and servers (issue #184). - Example programs: Don't add "QUIC_" prefix to lines in keylog file (issue #185). - http_server: Fix fd leak in preadv mode; fix preadv() usage when reading from disk.
1644 lines
82 KiB
C
1644 lines
82 KiB
C
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc. See LICENSE. */
|
|
/* Test packet resizing */
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <inttypes.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/queue.h>
|
|
#ifndef WIN32
|
|
#include <unistd.h>
|
|
#else
|
|
#include "getopt.h"
|
|
#endif
|
|
|
|
#define LSQUIC_TEST 1
|
|
#include "lsquic.h"
|
|
#include "lsquic_types.h"
|
|
#include "lsquic_int_types.h"
|
|
#include "lsquic_packet_common.h"
|
|
#include "lsquic_packet_in.h"
|
|
#include "lsquic_packet_out.h"
|
|
#include "lsquic_packet_resize.h"
|
|
#include "lsquic_parse.h"
|
|
#include "lsquic_hash.h"
|
|
#include "lsquic_conn.h"
|
|
#include "lsquic_mm.h"
|
|
#include "lsquic_enc_sess.h"
|
|
#include "lsquic_sfcw.h"
|
|
#include "lsquic_varint.h"
|
|
#include "lsquic_hq.h"
|
|
#include "lsquic_stream.h"
|
|
#include "lsquic_engine_public.h"
|
|
|
|
#include "lsquic_logger.h"
|
|
|
|
#define N_STREAMS 4
|
|
|
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
|
|
static const char *s_data[N_STREAMS];
|
|
static size_t s_data_sz[N_STREAMS];
|
|
|
|
|
|
struct test_spec
|
|
{
|
|
int lineno;
|
|
int expect_error;
|
|
unsigned versions;
|
|
const char *desc;
|
|
const char *prog;
|
|
};
|
|
|
|
/* Here we rely on the fact that QUIC_FRAME_STREAM is 1 and other valid frames
|
|
* are in a contiguous range.
|
|
*/
|
|
#define letter_2_frame_type(letter_) ((int) ((letter_) - 'a') + QUIC_FRAME_ACK)
|
|
#define frame_type_2_letter(frame_type_) ('a' + ((frame_type_) - QUIC_FRAME_ACK))
|
|
|
|
|
|
/* DSL specification:
|
|
*
|
|
* P\d+ Set maximum packet size
|
|
* N Create new packet, append to input queue, and set as current
|
|
* S\d+-\d+f? The first number is stream ID; these values must be in
|
|
* range [0, 3]. The second number is the maximum number of
|
|
* bytes to read from stream, potentially filling the current
|
|
* packet. If `f' is set, set FIN flag.
|
|
* C\d+-\d+ Like 'S' above, but CRYPTO frame. Note that there is no 'f'
|
|
* flag as CRYPTO frames have no FINs.
|
|
* c\d+-\d+ RST_STREAM frame. It's different from frames [abd-z] in that
|
|
* n_unacked is changed.
|
|
* V Verify contents of packets, both STREAM and non-STREAM frames.
|
|
* R Resize packets
|
|
* L\d Label, valid values in range [0, 9]
|
|
* J\d[=<>]\d+ Jump to label if packet size is valid [1200, 65527]
|
|
* I\d+ Increase packet size
|
|
* D\d+ Decrease packet size
|
|
* [abd-z]\d+ Frame of type [a-z] of some bytes. See letter_2_frame_type()
|
|
* to see how the mapping works.
|
|
* F\d+ Standalone FIN frame.
|
|
*/
|
|
|
|
|
|
static struct test_spec test_specs[] =
|
|
{
|
|
{
|
|
.lineno = __LINE__,
|
|
.desc = "split one packet with single STREAM frame into two",
|
|
.prog = "P2000;N;a7;S0-2000;V;P1500;R;V;",
|
|
},
|
|
{
|
|
.lineno = __LINE__,
|
|
.desc = "split one 6000-byte packet with single STREAM frame into many, looping",
|
|
.prog = "P6000;N;S0-6000;V;L0;D100;R;V;J0>1200;L1;I29;R;V;J1<7000;",
|
|
},
|
|
{
|
|
.lineno = __LINE__,
|
|
.desc = "split three 1500-byte packets with several STREAM frames from different streams",
|
|
.prog = "P1500;"
|
|
"N;p20;S0-200;S1-300;S2-200;h18;S3-20f;t2;S2-2000;"
|
|
"N;c0-30;j11;S2-2000;"
|
|
"N;S2-2000;"
|
|
"V;"
|
|
"L0;D1;R;V;J0>1200;"
|
|
,
|
|
},
|
|
{
|
|
.lineno = __LINE__,
|
|
.desc = "one packet, STREAM frame and and empty STREAM FIN frame, split down by 1",
|
|
.prog = "P2000;N;S0-1900;F0;V;L0;D1;R;V;J0>1200;",
|
|
},
|
|
{
|
|
.lineno = __LINE__,
|
|
.desc = "one packet, STREAM frame and and empty STREAM FIN frame, split down by 31",
|
|
.prog = "P2000;N;S0-1900;F0;V;L0;D31;R;V;J0>1200;",
|
|
},
|
|
{
|
|
.lineno = __LINE__,
|
|
.desc = "one packet, STREAM frame with a FIN, split down by 1",
|
|
.prog = "P2000;N;S0-1900f;V;L0;D1;R;V;J0>1200;",
|
|
},
|
|
{
|
|
.lineno = __LINE__,
|
|
.desc = "one packet, STREAM frame with a FIN, split down by 31",
|
|
.prog = "P2000;N;S0-1900f;V;L0;D31;R;V;J0>1200;",
|
|
},
|
|
{
|
|
.lineno = __LINE__,
|
|
.desc = "one packet, frame too large",
|
|
.prog = "P2000;N;m1500;V;P1000;R;",
|
|
.expect_error = 1,
|
|
},
|
|
{
|
|
.lineno = __LINE__,
|
|
.desc = "split one packet with single CRYPTO frame into two",
|
|
.prog = "P1252;N;C0-2000;V;P1200;R;V;",
|
|
.versions = LSQUIC_IETF_VERSIONS,
|
|
},
|
|
};
|
|
|
|
|
|
struct stream_read_cursor
|
|
{
|
|
const char *data; /* Points to data that is used as circular buffer */
|
|
unsigned data_sz; /* Size of data pointed to by data */
|
|
unsigned off; /* Current offset */
|
|
unsigned nread; /* Total number of bytes consumed from stream (packetized) */
|
|
int fin; /* FIN is set, see fin_off */
|
|
unsigned fin_off; /* Value of final offset */
|
|
};
|
|
|
|
|
|
struct test_ctx
|
|
{
|
|
TAILQ_HEAD(, lsquic_packet_out) packets[2]; /* We move them from one queue to the other */
|
|
int cur_input; /* 0 or 1, indexes packets */
|
|
unsigned n_non_stream_frames;
|
|
struct stream_read_cursor stream_cursors[N_STREAMS];
|
|
struct lsquic_stream streams[N_STREAMS];
|
|
struct lsquic_engine_public enpub;
|
|
struct lsquic_conn lconn;
|
|
struct network_path path;
|
|
};
|
|
|
|
|
|
static void
|
|
init_test_ctx (struct test_ctx *ctx, const struct test_spec *spec,
|
|
enum lsquic_version version)
|
|
{
|
|
unsigned i;
|
|
|
|
memset(ctx, 0, sizeof(*ctx));
|
|
TAILQ_INIT(&ctx->packets[0]);
|
|
TAILQ_INIT(&ctx->packets[1]);
|
|
for (i = 0; i < N_STREAMS; ++i)
|
|
{
|
|
ctx->stream_cursors[i].data = s_data[i];
|
|
ctx->stream_cursors[i].data_sz = s_data_sz[i];
|
|
}
|
|
lsquic_mm_init(&ctx->enpub.enp_mm);
|
|
ctx->lconn.cn_flags |= LSCONN_HANDSHAKE_DONE; /* For short packet headers */
|
|
ctx->lconn.cn_pf = select_pf_by_ver(version);
|
|
ctx->lconn.cn_esf_c = select_esf_common_by_ver(version);
|
|
LSCONN_INITIALIZE(&ctx->lconn);
|
|
ctx->lconn.cn_cces_buf[0].cce_cid.len = sizeof(spec->lineno);
|
|
memcpy(ctx->lconn.cn_cces_buf[0].cce_cid.idbuf, &spec->lineno, sizeof(spec->lineno));
|
|
}
|
|
|
|
|
|
static void
|
|
cleanup_test_ctx (struct test_ctx *ctx)
|
|
{
|
|
struct lsquic_packet_out *packet_out;
|
|
unsigned i;
|
|
|
|
for (i = 0; i < 2; ++i)
|
|
while (packet_out = TAILQ_FIRST(&ctx->packets[i]), packet_out != NULL)
|
|
{
|
|
TAILQ_REMOVE(&ctx->packets[i], packet_out, po_next);
|
|
lsquic_packet_out_destroy(packet_out, &ctx->enpub, NULL);
|
|
}
|
|
lsquic_mm_cleanup(&ctx->enpub.enp_mm);
|
|
}
|
|
|
|
|
|
static struct lsquic_packet_out *
|
|
new_packet (struct test_ctx *ctx)
|
|
{
|
|
struct lsquic_packet_out *packet_out;
|
|
static lsquic_packno_t packno; /* Each packet gets unique packet number
|
|
* to make them easier to track.
|
|
*/
|
|
|
|
packet_out = lsquic_packet_out_new(&ctx->enpub.enp_mm, ctx->enpub.enp_mm.malo.packet_out, 1,
|
|
&ctx->lconn, PACKNO_BITS_0, 0, NULL, &ctx->path, HETY_NOT_SET);
|
|
if (packet_out)
|
|
packet_out->po_packno = packno++;
|
|
|
|
return packet_out;
|
|
}
|
|
|
|
|
|
static struct lsquic_packet_out *
|
|
new_input_packet (struct test_ctx *ctx)
|
|
{
|
|
struct lsquic_packet_out *packet_out;
|
|
|
|
packet_out = new_packet(ctx);
|
|
if (packet_out)
|
|
TAILQ_INSERT_TAIL(&ctx->packets[ctx->cur_input], packet_out, po_next);
|
|
|
|
return packet_out;
|
|
}
|
|
|
|
|
|
struct my_read_ctx {
|
|
struct stream_read_cursor *cursor;
|
|
/* XXX Turns out, gQUIC and IETF QUIC STREAM frame generators differ in
|
|
* what they pass to the read() function. The former does not limit
|
|
* itself to pf_gen_stream_frame()'s `size'. Rather than change and
|
|
* retest gQUIC code, put a limiter in this unit test file instead.
|
|
*/
|
|
size_t max;
|
|
int fin;
|
|
};
|
|
|
|
|
|
static size_t
|
|
my_gsf_read (void *stream, void *buf, size_t len, int *fin)
|
|
{
|
|
struct my_read_ctx *const mctx = stream;
|
|
struct stream_read_cursor *const cursor = mctx->cursor;
|
|
unsigned char *p = buf, *end;
|
|
size_t n;
|
|
|
|
if (len > mctx->max)
|
|
len = mctx->max;
|
|
|
|
end = p + len;
|
|
|
|
while (p < end)
|
|
{
|
|
n = MIN(end - p, cursor->data_sz - cursor->off);
|
|
memcpy(p, cursor->data + cursor->off, n);
|
|
cursor->off += n;
|
|
if (cursor->off == cursor->data_sz)
|
|
cursor->off = 0;
|
|
cursor->nread += n;
|
|
p += n;
|
|
}
|
|
|
|
if (mctx->fin)
|
|
{
|
|
cursor->fin = 1;
|
|
cursor->fin_off = cursor->nread;
|
|
LSQ_DEBUG("set FIN at offset %u", cursor->fin_off);
|
|
}
|
|
|
|
*fin = mctx->fin;
|
|
return len;
|
|
}
|
|
|
|
|
|
static void
|
|
make_stream_frame (struct test_ctx *ctx, struct lsquic_packet_out *packet_out,
|
|
enum quic_frame_type frame_type, lsquic_stream_id_t stream_id,
|
|
size_t nbytes, int fin)
|
|
{
|
|
struct my_read_ctx mctx = { &ctx->stream_cursors[stream_id], nbytes, fin, };
|
|
int w;
|
|
|
|
assert(!ctx->stream_cursors[stream_id].fin);
|
|
|
|
if (nbytes == 0 && fin)
|
|
{
|
|
ctx->stream_cursors[stream_id].fin = 1;
|
|
ctx->stream_cursors[stream_id].fin_off
|
|
= ctx->stream_cursors[stream_id].nread;
|
|
LSQ_DEBUG("set FIN at offset %u", ctx->stream_cursors[stream_id].fin_off);
|
|
}
|
|
|
|
w = (&ctx->lconn.cn_pf->pf_gen_stream_frame)
|
|
[frame_type == QUIC_FRAME_CRYPTO](
|
|
packet_out->po_data + packet_out->po_data_sz,
|
|
lsquic_packet_out_avail(packet_out),
|
|
stream_id, ctx->stream_cursors[stream_id].nread,
|
|
nbytes == 0 && fin, nbytes, my_gsf_read, &mctx);
|
|
assert(w > 0);
|
|
LSQ_DEBUG("wrote %s frame of %d bytes", frame_type_2_str[frame_type], w);
|
|
lsquic_packet_out_add_stream(packet_out, &ctx->enpub.enp_mm,
|
|
&ctx->streams[stream_id], frame_type,
|
|
packet_out->po_data_sz, w);
|
|
packet_out->po_data_sz += w;
|
|
packet_out->po_frame_types |= 1 << frame_type;
|
|
if (0 == lsquic_packet_out_avail(packet_out))
|
|
packet_out->po_flags |= PO_STREAM_END;
|
|
}
|
|
|
|
|
|
static void
|
|
make_non_stream_frame (struct test_ctx *ctx,
|
|
struct lsquic_packet_out *packet_out, enum quic_frame_type frame_type,
|
|
size_t nbytes)
|
|
{
|
|
static unsigned char fill_byte;
|
|
|
|
/* We don't truncate non-STREAM frames because we don't chop them up */
|
|
assert(nbytes <= lsquic_packet_out_avail(packet_out));
|
|
|
|
memset(packet_out->po_data + packet_out->po_data_sz, fill_byte, nbytes);
|
|
lsquic_packet_out_add_frame(packet_out, &ctx->enpub.enp_mm,
|
|
fill_byte, frame_type, packet_out->po_data_sz, nbytes);
|
|
packet_out->po_data_sz += nbytes;
|
|
packet_out->po_frame_types |= 1 << frame_type;
|
|
if ((1 << frame_type) & BQUIC_FRAME_REGEN_MASK)
|
|
packet_out->po_regen_sz += nbytes;
|
|
LSQ_DEBUG("wrote %s frame of %zd bytes", frame_type_2_str[frame_type],
|
|
nbytes);
|
|
++fill_byte;
|
|
++ctx->n_non_stream_frames;
|
|
}
|
|
|
|
|
|
static void
|
|
make_rst_stream_frame (struct test_ctx *ctx,
|
|
struct lsquic_packet_out *packet_out, lsquic_stream_id_t stream_id,
|
|
size_t nbytes)
|
|
{
|
|
int s;
|
|
|
|
/* We don't truncate non-STREAM frames because we don't chop them up */
|
|
assert(nbytes <= lsquic_packet_out_avail(packet_out));
|
|
|
|
memset(packet_out->po_data + packet_out->po_data_sz, 'R', nbytes);
|
|
s = lsquic_packet_out_add_stream(packet_out, &ctx->enpub.enp_mm,
|
|
&ctx->streams[stream_id], QUIC_FRAME_RST_STREAM,
|
|
packet_out->po_data_sz, nbytes);
|
|
assert(s == 0);
|
|
packet_out->po_data_sz += nbytes;
|
|
packet_out->po_frame_types |= 1 << QUIC_FRAME_RST_STREAM;
|
|
LSQ_DEBUG("wrote %s frame of %zd bytes",
|
|
frame_type_2_str[QUIC_FRAME_RST_STREAM], nbytes);
|
|
++ctx->n_non_stream_frames;
|
|
}
|
|
|
|
|
|
/* STREAM frame ordering assumptions, with or without FINs, are specific to
|
|
* this unit test. These assumptions do not have to hold in real code.
|
|
* The assumptions are made in order to verify the operation of the "packet
|
|
* resize" module.
|
|
*/
|
|
static void
|
|
verify_stream_contents (struct test_ctx *ctx, lsquic_stream_id_t stream_id)
|
|
{
|
|
char *data;
|
|
size_t len;
|
|
int dummy_fin = -1, parsed_len, seen_fin;
|
|
struct lsquic_packet_out *packet_out;
|
|
struct stream_read_cursor cursor;
|
|
struct my_read_ctx mctx;
|
|
struct stream_frame stream_frame;
|
|
struct packet_out_frec_iter pofi;
|
|
struct frame_rec *frec;
|
|
unsigned off, frec_count;
|
|
|
|
LSQ_DEBUG("verifying stream #%"PRIu64, stream_id);
|
|
data = malloc(ctx->stream_cursors[stream_id].nread);
|
|
assert(data);
|
|
/* Copy cursor to re-read from the beginning and not affect real cursor */
|
|
cursor = ctx->stream_cursors[stream_id];
|
|
cursor.off = 0;
|
|
mctx = (struct my_read_ctx) { &cursor, ctx->stream_cursors[stream_id].nread, 0, };
|
|
len = my_gsf_read(&mctx, data, ctx->stream_cursors[stream_id].nread, &dummy_fin);
|
|
assert(len == ctx->stream_cursors[stream_id].nread);
|
|
assert(dummy_fin == 0); /* Self-check */
|
|
|
|
/* Go packet by packet, and within each packet, frame by frame, and
|
|
* compare STREAM frame contents.
|
|
*/
|
|
off = 0;
|
|
seen_fin = 0;
|
|
frec_count = 0;
|
|
TAILQ_FOREACH(packet_out, &ctx->packets[ctx->cur_input], po_next)
|
|
{
|
|
LSQ_DEBUG("examining packet #%"PRIu64, packet_out->po_packno);
|
|
assert(packet_out->po_data_sz <= packet_out->po_n_alloc);
|
|
assert(packet_out->po_data_sz <= ctx->path.np_pack_size);
|
|
for (frec = lsquic_pofi_first(&pofi, packet_out); frec;
|
|
frec = lsquic_pofi_next(&pofi))
|
|
{
|
|
if (!(((1 << frec->fe_frame_type) & (QUIC_FTBIT_STREAM|QUIC_FTBIT_CRYPTO|QUIC_FTBIT_RST_STREAM))
|
|
&& frec->fe_stream == &ctx->streams[stream_id]))
|
|
continue;
|
|
assert(!seen_fin);
|
|
++frec_count;
|
|
if (frec->fe_frame_type == QUIC_FRAME_RST_STREAM)
|
|
continue;
|
|
parsed_len = (&ctx->lconn.cn_pf->pf_parse_stream_frame)
|
|
[frec->fe_frame_type == QUIC_FRAME_CRYPTO]
|
|
(packet_out->po_data + frec->fe_off, frec->fe_len, &stream_frame);
|
|
assert(parsed_len > 0);
|
|
assert(parsed_len == frec->fe_len);
|
|
LSQ_DEBUG("verify stream %"PRIu64", contents %hu bytes",
|
|
stream_id, stream_frame.data_frame.df_size);
|
|
assert(stream_frame.data_frame.df_offset == off);
|
|
assert(stream_frame.data_frame.df_size <= len - off);
|
|
assert(0 == memcmp(stream_frame.data_frame.df_data, data + off,
|
|
stream_frame.data_frame.df_size));
|
|
off += stream_frame.data_frame.df_size;
|
|
if (stream_frame.data_frame.df_fin)
|
|
{
|
|
assert(ctx->stream_cursors[stream_id].fin);
|
|
assert(ctx->stream_cursors[stream_id].fin_off == off);
|
|
seen_fin = 1;
|
|
}
|
|
if (frec->fe_off + frec->fe_len == packet_out->po_n_alloc)
|
|
assert(packet_out->po_flags & PO_STREAM_END);
|
|
if (!(packet_out->po_flags & PO_STREAM_END))
|
|
assert(frec->fe_off + frec->fe_len < packet_out->po_n_alloc);
|
|
}
|
|
}
|
|
|
|
if (ctx->stream_cursors[stream_id].fin)
|
|
assert(seen_fin);
|
|
assert(frec_count == ctx->streams[stream_id].n_unacked);
|
|
free(data);
|
|
}
|
|
|
|
|
|
/* Verify that non-STREAM frames are in the same order, of the same size, and
|
|
* same contents.
|
|
*/
|
|
static void
|
|
verify_non_stream_frames (struct test_ctx *ctx, const struct test_spec *spec)
|
|
{
|
|
const char *pos;
|
|
int w;
|
|
unsigned count, regen_sz, off;
|
|
struct lsquic_packet_out *packet_out;
|
|
struct packet_out_frec_iter pofi;
|
|
struct frame_rec *frec;
|
|
unsigned char fill;
|
|
char frame_str[30];
|
|
|
|
LSQ_DEBUG("verifying non-STREAM frames");
|
|
|
|
/* Go packet by packet, and within each packet, frame by frame, and
|
|
* verify relative position of non-STREAM frames (must be in the same
|
|
* order as in the order they were inserted) and their contents.
|
|
*/
|
|
count = 0;
|
|
pos = spec->prog;
|
|
TAILQ_FOREACH(packet_out, &ctx->packets[ctx->cur_input], po_next)
|
|
{
|
|
regen_sz = 0;
|
|
off = 0;
|
|
LSQ_DEBUG("examining packet #%"PRIu64, packet_out->po_packno);
|
|
assert(packet_out->po_data_sz <= packet_out->po_n_alloc);
|
|
assert(packet_out->po_data_sz <= ctx->path.np_pack_size);
|
|
for (frec = lsquic_pofi_first(&pofi, packet_out); frec;
|
|
frec = lsquic_pofi_next(&pofi))
|
|
{
|
|
if ((1 << frec->fe_frame_type) & BQUIC_FRAME_REGEN_MASK)
|
|
{
|
|
assert(regen_sz == 0 || regen_sz == off);
|
|
regen_sz += frec->fe_len;
|
|
}
|
|
off += frec->fe_len;
|
|
if ((1 << frec->fe_frame_type)
|
|
& (QUIC_FTBIT_STREAM|QUIC_FTBIT_CRYPTO))
|
|
continue;
|
|
++count;
|
|
LSQ_DEBUG("checking %hu-byte %s", frec->fe_len,
|
|
frame_type_2_str[frec->fe_frame_type]);
|
|
if (frec->fe_frame_type == QUIC_FRAME_RST_STREAM)
|
|
w = snprintf(frame_str, sizeof(frame_str), "%c%u-%hu;",
|
|
frame_type_2_letter(frec->fe_frame_type),
|
|
(unsigned) (frec->fe_stream - ctx->streams), frec->fe_len);
|
|
else
|
|
w = snprintf(frame_str, sizeof(frame_str), "%c%hu;",
|
|
frame_type_2_letter(frec->fe_frame_type), frec->fe_len);
|
|
pos = strstr(pos, frame_str);
|
|
assert(pos);
|
|
pos += w;
|
|
/* Now check contents */
|
|
fill = frec->fe_frame_type == QUIC_FRAME_RST_STREAM
|
|
? 'R' : (unsigned char) frec->fe_u.data;
|
|
for (w = 0; w < (int) frec->fe_len; ++w)
|
|
assert(packet_out->po_data[frec->fe_off + w] == fill);
|
|
}
|
|
assert(packet_out->po_regen_sz == regen_sz);
|
|
assert(packet_out->po_data_sz == off);
|
|
}
|
|
|
|
assert(count == ctx->n_non_stream_frames);
|
|
}
|
|
|
|
|
|
static void
|
|
verify_packet_contents (struct test_ctx *ctx, const struct test_spec *spec)
|
|
{
|
|
lsquic_stream_id_t stream_id;
|
|
|
|
for (stream_id = 0; stream_id < N_STREAMS; ++stream_id)
|
|
verify_stream_contents(ctx, stream_id);
|
|
verify_non_stream_frames(ctx, spec);
|
|
}
|
|
|
|
|
|
static struct lsquic_packet_out *
|
|
my_pri_next_packet (void *ctxp)
|
|
{
|
|
struct test_ctx *ctx = ctxp;
|
|
struct lsquic_packet_out *packet_out;
|
|
|
|
packet_out = TAILQ_FIRST(&ctx->packets[ctx->cur_input]);
|
|
if (packet_out)
|
|
LSQ_DEBUG("%s: return packet #%"PRIu64, __func__,
|
|
packet_out->po_packno);
|
|
else
|
|
LSQ_DEBUG("%s: out of packets", __func__);
|
|
|
|
return packet_out;
|
|
}
|
|
|
|
|
|
static void
|
|
my_pri_discard_packet (void *ctxp, struct lsquic_packet_out *packet_out)
|
|
{
|
|
struct test_ctx *ctx = ctxp;
|
|
|
|
LSQ_DEBUG("%s: discard packet #%"PRIu64, __func__, packet_out->po_packno);
|
|
TAILQ_REMOVE(&ctx->packets[ctx->cur_input], packet_out, po_next);
|
|
lsquic_packet_out_destroy(packet_out, &ctx->enpub, NULL);
|
|
}
|
|
|
|
|
|
static struct lsquic_packet_out *
|
|
my_pri_new_packet (void *ctx)
|
|
{
|
|
LSQ_DEBUG("%s: grab a new packet", __func__);
|
|
return new_packet(ctx);
|
|
}
|
|
|
|
|
|
static const struct packet_resize_if my_pr_if =
|
|
{
|
|
.pri_next_packet = my_pri_next_packet,
|
|
.pri_new_packet = my_pri_new_packet,
|
|
.pri_discard_packet = my_pri_discard_packet,
|
|
};
|
|
|
|
|
|
static int
|
|
resize_packets (struct test_ctx *ctx)
|
|
{
|
|
struct packet_resize_ctx prctx;
|
|
struct lsquic_packet_out *new;
|
|
|
|
lsquic_packet_resize_init(&prctx, &ctx->enpub, &ctx->lconn, ctx, &my_pr_if);
|
|
|
|
while (new = lsquic_packet_resize_next(&prctx), new != NULL)
|
|
{
|
|
TAILQ_INSERT_TAIL(&ctx->packets[!ctx->cur_input], new, po_next);
|
|
LSQ_DEBUG("append new packet #%"PRIu64, new->po_packno);
|
|
}
|
|
ctx->cur_input = !ctx->cur_input;
|
|
LSQ_DEBUG("switch cur_input to %d", ctx->cur_input);
|
|
return lsquic_packet_resize_is_error(&prctx) ? -1 : 0;
|
|
}
|
|
|
|
|
|
static void
|
|
run_test (const struct test_spec *spec, enum lsquic_version version)
|
|
{
|
|
struct lsquic_packet_out *packet_out;
|
|
struct test_ctx ctx;
|
|
long stream_id, nbytes;
|
|
char L[4] = "L?;", op, cmd;
|
|
const char *pc, *addr;
|
|
int jump, s;
|
|
enum quic_frame_type frame_type;
|
|
|
|
LSQ_INFO("Running test on line %d: %s", spec->lineno, spec->desc);
|
|
if (spec->versions && !(spec->versions & (1 << version)))
|
|
{
|
|
LSQ_INFO("Not applicable to version %s, skip",
|
|
lsquic_ver2str[version]);
|
|
return;
|
|
}
|
|
|
|
init_test_ctx(&ctx, spec, version);
|
|
|
|
packet_out = NULL;
|
|
for (pc = spec->prog; *pc; ++pc)
|
|
{
|
|
cmd = *pc++;
|
|
switch (cmd)
|
|
{
|
|
case 'P':
|
|
ctx.path.np_pack_size = strtol(pc, (char **) &pc, 10);
|
|
LSQ_DEBUG("P: set packet size to %hu bytes", ctx.path.np_pack_size);
|
|
break;
|
|
case 'N':
|
|
packet_out = new_input_packet(&ctx);
|
|
LSQ_DEBUG("N: create new input packet");
|
|
break;
|
|
case 'S':
|
|
case 'C':
|
|
stream_id = strtol(pc, (char **) &pc, 10);
|
|
assert('-' == *pc);
|
|
assert(stream_id >= 0 && stream_id < N_STREAMS);
|
|
nbytes = strtol(pc + 1, (char **) &pc, 10);
|
|
assert(nbytes > 0);
|
|
LSQ_DEBUG("%c: create frame for stream %ld of at most %ld bytes",
|
|
cmd, stream_id, nbytes);
|
|
if (cmd == 'S' && *pc == 'f')
|
|
++pc;
|
|
make_stream_frame(&ctx, packet_out,
|
|
cmd == 'S' ? QUIC_FRAME_STREAM : QUIC_FRAME_CRYPTO,
|
|
stream_id, nbytes, pc[-1] == 'f');
|
|
break;
|
|
case 'F':
|
|
stream_id = strtol(pc, (char **) &pc, 10);
|
|
make_stream_frame(&ctx, packet_out, QUIC_FRAME_STREAM, stream_id,
|
|
0, 1);
|
|
break;
|
|
case 'V':
|
|
LSQ_DEBUG("V: verify packet contents");
|
|
verify_packet_contents(&ctx, spec);
|
|
break;
|
|
case 'R':
|
|
LSQ_DEBUG("R: resize packets");
|
|
s = resize_packets(&ctx);
|
|
if (0 != s)
|
|
{
|
|
LSQ_DEBUG("got error, expected: %d", spec->expect_error);
|
|
assert(spec->expect_error);
|
|
assert(pc[0] == ';');
|
|
assert(pc[1] == '\0');
|
|
goto end;
|
|
}
|
|
break;
|
|
case 'D':
|
|
nbytes = strtol(pc, (char **) &pc, 10);
|
|
ctx.path.np_pack_size -= nbytes;
|
|
LSQ_DEBUG("D: decrease packet size by %ld to %hu bytes",
|
|
nbytes, ctx.path.np_pack_size);
|
|
break;
|
|
case 'I':
|
|
nbytes = strtol(pc, (char **) &pc, 10);
|
|
ctx.path.np_pack_size += nbytes;
|
|
LSQ_DEBUG("I: increase packet size by %ld to %hu bytes",
|
|
nbytes, ctx.path.np_pack_size);
|
|
break;
|
|
case 'L':
|
|
assert(*pc >= '0' && *pc <= '9');
|
|
++pc;
|
|
break;
|
|
case 'J':
|
|
assert(*pc >= '0' && *pc <= '9');
|
|
L[1] = *pc++;
|
|
addr = strstr(spec->prog, L);
|
|
assert(addr);
|
|
op = *pc++;
|
|
nbytes = strtol(pc, (char **) &pc, 10);
|
|
switch (op)
|
|
{
|
|
case '=': jump = ctx.path.np_pack_size == nbytes; break;
|
|
case '<': jump = ctx.path.np_pack_size < nbytes; break;
|
|
case '>': jump = ctx.path.np_pack_size > nbytes; break;
|
|
default: jump = 0; assert(0); break;
|
|
}
|
|
LSQ_DEBUG("J: jump if (%hu %c %ld) -> %sjumping",
|
|
ctx.path.np_pack_size, op, nbytes, jump ? "" : "not ");
|
|
if (jump)
|
|
pc = addr + 2;
|
|
break;
|
|
case 'c':
|
|
stream_id = strtol(pc, (char **) &pc, 10);
|
|
assert('-' == *pc);
|
|
assert(stream_id >= 0 && stream_id < N_STREAMS);
|
|
nbytes = strtol(pc + 1, (char **) &pc, 10);
|
|
assert(nbytes > 0);
|
|
make_rst_stream_frame(&ctx, packet_out, stream_id, nbytes);
|
|
break;
|
|
case 'a': case 'b': case 'd': case 'e': case 'f': case 'g':
|
|
case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
|
|
case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
|
|
case 'v': case 'w': case 'x': case 'y': case 'z':
|
|
frame_type = letter_2_frame_type(cmd);
|
|
nbytes = strtol(pc, (char **) &pc, 10);
|
|
make_non_stream_frame(&ctx, packet_out, frame_type, nbytes);
|
|
break;
|
|
default:
|
|
assert(0);
|
|
goto end;
|
|
}
|
|
assert(*pc == ';');
|
|
}
|
|
|
|
end:
|
|
cleanup_test_ctx(&ctx);
|
|
}
|
|
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
const struct test_spec *spec;
|
|
enum lsquic_version version;
|
|
int opt;
|
|
|
|
lsquic_log_to_fstream(stderr, LLTS_HHMMSSMS);
|
|
(void) lsquic_set_log_level("info");
|
|
while (opt = getopt(argc, argv, "l:L:h"), opt != -1)
|
|
{
|
|
switch (opt)
|
|
{
|
|
case 'L':
|
|
if (0 != lsquic_set_log_level(optarg))
|
|
{
|
|
perror("lsquic_set_log_level");
|
|
return 1;
|
|
}
|
|
break;
|
|
case 'l':
|
|
if (0 != lsquic_logger_lopt(optarg))
|
|
{
|
|
perror("lsquic_logger_lopt");
|
|
return 1;
|
|
}
|
|
break;
|
|
case 'h':
|
|
printf("usage: %s [options]\n", argv[0]);
|
|
return 0;
|
|
default:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
for (version = 0; version < N_LSQVER; ++version)
|
|
{
|
|
if (!((1 << version) & LSQUIC_DF_VERSIONS))
|
|
continue;
|
|
LSQ_INFO("testing version %s", lsquic_ver2str[version]);
|
|
for (spec = test_specs; spec < test_specs + sizeof(test_specs) / sizeof(test_specs[0]); ++spec)
|
|
run_test(spec, version);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
#define DATA_0 \
|
|
"ON BEING IDLE.\n" \
|
|
"\n" \
|
|
"Now, this is a subject on which I flatter myself I really am _au fait_.\n" \
|
|
"The gentleman who, when I was young, bathed me at wisdom's font for nine\n" \
|
|
"guineas a term--no extras--used to say he never knew a boy who could\n" \
|
|
"do less work in more time; and I remember my poor grandmother once\n" \
|
|
"incidentally observing, in the course of an instruction upon the use\n" \
|
|
"of the Prayer-book, that it was highly improbable that I should ever do\n" \
|
|
"much that I ought not to do, but that she felt convinced beyond a doubt\n" \
|
|
"that I should leave undone pretty well everything that I ought to do.\n" \
|
|
"\n" \
|
|
"I am afraid I have somewhat belied half the dear old lady's prophecy.\n" \
|
|
"Heaven help me! I have done a good many things that I ought not to have\n" \
|
|
"done, in spite of my laziness. But I have fully confirmed the accuracy\n" \
|
|
"of her judgment so far as neglecting much that I ought not to have\n" \
|
|
"neglected is concerned. Idling always has been my strong point. I take\n" \
|
|
"no credit to myself in the matter--it is a gift. Few possess it. There\n" \
|
|
"are plenty of lazy people and plenty of slow-coaches, but a genuine\n" \
|
|
"idler is a rarity. He is not a man who slouches about with his hands in\n" \
|
|
"his pockets. On the contrary, his most startling characteristic is that\n" \
|
|
"he is always intensely busy.\n" \
|
|
"\n" \
|
|
"It is impossible to enjoy idling thoroughly unless one has plenty of\n" \
|
|
"work to do. There is no fun in doing nothing when you have nothing to\n" \
|
|
"do. Wasting time is merely an occupation then, and a most exhausting\n" \
|
|
"one. Idleness, like kisses, to be sweet must be stolen.\n" \
|
|
"\n" \
|
|
"Many years ago, when I was a young man, I was taken very ill--I never\n" \
|
|
"could see myself that much was the matter with me, except that I had\n" \
|
|
"a beastly cold. But I suppose it was something very serious, for the\n" \
|
|
"doctor said that I ought to have come to him a month before, and that\n" \
|
|
"if it (whatever it was) had gone on for another week he would not have\n" \
|
|
"answered for the consequences. It is an extraordinary thing, but I\n" \
|
|
"never knew a doctor called into any case yet but what it transpired\n" \
|
|
"that another day's delay would have rendered cure hopeless. Our medical\n" \
|
|
"guide, philosopher, and friend is like the hero in a melodrama--he\n" \
|
|
"always comes upon the scene just, and only just, in the nick of time. It\n" \
|
|
"is Providence, that is what it is.\n" \
|
|
"\n" \
|
|
"Well, as I was saying, I was very ill and was ordered to Buxton for a\n" \
|
|
"month, with strict injunctions to do nothing whatever all the while\n" \
|
|
"that I was there. \"Rest is what you require,\" said the doctor, \"perfect\n" \
|
|
"rest.\"\n" \
|
|
"\n" \
|
|
"It seemed a delightful prospect. \"This man evidently understands my\n" \
|
|
"complaint,\" said I, and I pictured to myself a glorious time--a four\n" \
|
|
"weeks' _dolce far niente_ with a dash of illness in it. Not too much\n" \
|
|
"illness, but just illness enough--just sufficient to give it the flavor\n" \
|
|
"of suffering and make it poetical. I should get up late, sip chocolate,\n" \
|
|
"and have my breakfast in slippers and a dressing-gown. I should lie out\n" \
|
|
"in the garden in a hammock and read sentimental novels with a melancholy\n" \
|
|
"ending, until the books should fall from my listless hand, and I should\n" \
|
|
"recline there, dreamily gazing into the deep blue of the firmament,\n" \
|
|
"watching the fleecy clouds floating like white-sailed ships across\n" \
|
|
"its depths, and listening to the joyous song of the birds and the low\n" \
|
|
"rustling of the trees. Or, on becoming too weak to go out of doors,\n" \
|
|
"I should sit propped up with pillows at the open window of the\n" \
|
|
"ground-floor front, and look wasted and interesting, so that all the\n" \
|
|
"pretty girls would sigh as they passed by.\n" \
|
|
"\n" \
|
|
"And twice a day I should go down in a Bath chair to the Colonnade to\n" \
|
|
"drink the waters. Oh, those waters! I knew nothing about them then,\n" \
|
|
"and was rather taken with the idea. \"Drinking the waters\" sounded\n" \
|
|
"fashionable and Queen Anne-fied, and I thought I should like them. But,\n" \
|
|
"ugh! after the first three or four mornings! Sam Weller's description of\n" \
|
|
"them as \"having a taste of warm flat-irons\" conveys only a faint idea of\n" \
|
|
"their hideous nauseousness. If anything could make a sick man get well\n" \
|
|
"quickly, it would be the knowledge that he must drink a glassful of them\n" \
|
|
"every day until he was recovered. I drank them neat for six consecutive\n" \
|
|
"days, and they nearly killed me; but after then I adopted the plan of\n" \
|
|
"taking a stiff glass of brandy-and-water immediately on the top of them,\n" \
|
|
"and found much relief thereby. I have been informed since, by various\n" \
|
|
"eminent medical gentlemen, that the alcohol must have entirely\n" \
|
|
"counteracted the effects of the chalybeate properties contained in the\n" \
|
|
"water. I am glad I was lucky enough to hit upon the right thing.\n" \
|
|
"\n" \
|
|
"But \"drinking the waters\" was only a small portion of the torture I\n" \
|
|
"experienced during that memorable month--a month which was, without\n" \
|
|
"exception, the most miserable I have ever spent. During the best part of\n" \
|
|
"it I religiously followed the doctor's mandate and did nothing whatever,\n" \
|
|
"except moon about the house and garden and go out for two hours a day in\n" \
|
|
"a Bath chair. That did break the monotony to a certain extent. There is\n" \
|
|
"more excitement about Bath-chairing--especially if you are not used to\n" \
|
|
"the exhilarating exercise--than might appear to the casual observer. A\n" \
|
|
"sense of danger, such as a mere outsider might not understand, is ever\n" \
|
|
"present to the mind of the occupant. He feels convinced every minute\n" \
|
|
"that the whole concern is going over, a conviction which becomes\n" \
|
|
"especially lively whenever a ditch or a stretch of newly macadamized\n" \
|
|
"road comes in sight. Every vehicle that passes he expects is going to\n" \
|
|
"run into him; and he never finds himself ascending or descending a\n" \
|
|
"hill without immediately beginning to speculate upon his chances,\n" \
|
|
"supposing--as seems extremely probable--that the weak-kneed controller\n" \
|
|
"of his destiny should let go.\n" \
|
|
"\n" \
|
|
"But even this diversion failed to enliven after awhile, and the _ennui_\n" \
|
|
"became perfectly unbearable. I felt my mind giving way under it. It is\n" \
|
|
"not a strong mind, and I thought it would be unwise to tax it too far.\n" \
|
|
"So somewhere about the twentieth morning I got up early, had a good\n" \
|
|
"breakfast, and walked straight off to Hayfield, at the foot of the\n" \
|
|
"Kinder Scout--a pleasant, busy little town, reached through a lovely\n" \
|
|
"valley, and with two sweetly pretty women in it. At least they were\n" \
|
|
"sweetly pretty then; one passed me on the bridge and, I think, smiled;\n" \
|
|
"and the other was standing at an open door, making an unremunerative\n" \
|
|
"investment of kisses upon a red-faced baby. But it is years ago, and I\n" \
|
|
"dare say they have both grown stout and snappish since that time.\n" \
|
|
"Coming back, I saw an old man breaking stones, and it roused such strong\n" \
|
|
"longing in me to use my arms that I offered him a drink to let me take\n" \
|
|
"his place. He was a kindly old man and he humored me. I went for those\n" \
|
|
"stones with the accumulated energy of three weeks, and did more work in\n" \
|
|
"half an hour than he had done all day. But it did not make him jealous.\n" \
|
|
"\n" \
|
|
"Having taken the plunge, I went further and further into dissipation,\n" \
|
|
"going out for a long walk every morning and listening to the band in\n" \
|
|
"the pavilion every evening. But the days still passed slowly\n" \
|
|
"notwithstanding, and I was heartily glad when the last one came and I\n" \
|
|
"was being whirled away from gouty, consumptive Buxton to London with its\n" \
|
|
"stern work and life. I looked out of the carriage as we rushed through\n" \
|
|
"Hendon in the evening. The lurid glare overhanging the mighty city\n" \
|
|
"seemed to warm my heart, and when, later on, my cab rattled out of St.\n" \
|
|
"Pancras' station, the old familiar roar that came swelling up around me\n" \
|
|
"sounded the sweetest music I had heard for many a long day.\n" \
|
|
"\n" \
|
|
"I certainly did not enjoy that month's idling. I like idling when I\n" \
|
|
"ought not to be idling; not when it is the only thing I have to do. That\n" \
|
|
"is my pig-headed nature. The time when I like best to stand with my\n" \
|
|
"back to the fire, calculating how much I owe, is when my desk is heaped\n" \
|
|
"highest with letters that must be answered by the next post. When I like\n" \
|
|
"to dawdle longest over my dinner is when I have a heavy evening's work\n" \
|
|
"before me. And if, for some urgent reason, I ought to be up particularly\n" \
|
|
"early in the morning, it is then, more than at any other time, that I\n" \
|
|
"love to lie an extra half-hour in bed.\n" \
|
|
"\n" \
|
|
"Ah! how delicious it is to turn over and go to sleep again: \"just for\n" \
|
|
"five minutes.\" Is there any human being, I wonder, besides the hero of\n" \
|
|
"a Sunday-school \"tale for boys,\" who ever gets up willingly? There\n" \
|
|
"are some men to whom getting up at the proper time is an utter\n" \
|
|
"impossibility. If eight o'clock happens to be the time that they should\n" \
|
|
"turn out, then they lie till half-past. If circumstances change and\n" \
|
|
"half-past eight becomes early enough for them, then it is nine before\n" \
|
|
"they can rise. They are like the statesman of whom it was said that he\n" \
|
|
"was always punctually half an hour late. They try all manner of schemes.\n" \
|
|
"They buy alarm-clocks (artful contrivances that go off at the wrong time\n" \
|
|
"and alarm the wrong people). They tell Sarah Jane to knock at the door\n" \
|
|
"and call them, and Sarah Jane does knock at the door and does call them,\n" \
|
|
"and they grunt back \"awri\" and then go comfortably to sleep again. I\n" \
|
|
"knew one man who would actually get out and have a cold bath; and even\n" \
|
|
"that was of no use, for afterward he would jump into bed again to warm\n" \
|
|
"himself.\n" \
|
|
"\n" \
|
|
"I think myself that I could keep out of bed all right if I once got\n" \
|
|
"out. It is the wrenching away of the head from the pillow that I find so\n" \
|
|
"hard, and no amount of over-night determination makes it easier. I say\n" \
|
|
"to myself, after having wasted the whole evening, \"Well, I won't do\n" \
|
|
"any more work to-night; I'll get up early to-morrow morning;\" and I am\n" \
|
|
"thoroughly resolved to do so--then. In the morning, however, I feel less\n" \
|
|
"enthusiastic about the idea, and reflect that it would have been much\n" \
|
|
"better if I had stopped up last night. And then there is the trouble of\n" \
|
|
"dressing, and the more one thinks about that the more one wants to put\n" \
|
|
"it off.\n" \
|
|
"\n" \
|
|
"It is a strange thing this bed, this mimic grave, where we stretch our\n" \
|
|
"tired limbs and sink away so quietly into the silence and rest. \"O bed,\n" \
|
|
"O bed, delicious bed, that heaven on earth to the weary head,\" as sang\n" \
|
|
"poor Hood, you are a kind old nurse to us fretful boys and girls. Clever\n" \
|
|
"and foolish, naughty and good, you take us all in your motherly lap and\n" \
|
|
"hush our wayward crying. The strong man full of care--the sick man\n" \
|
|
"full of pain--the little maiden sobbing for her faithless lover--like\n" \
|
|
"children we lay our aching heads on your white bosom, and you gently\n" \
|
|
"soothe us off to by-by.\n" \
|
|
"\n" \
|
|
"Our trouble is sore indeed when you turn away and will not comfort us.\n" \
|
|
"How long the dawn seems coming when we cannot sleep! Oh! those hideous\n" \
|
|
"nights when we toss and turn in fever and pain, when we lie, like living\n" \
|
|
"men among the dead, staring out into the dark hours that drift so slowly\n" \
|
|
"between us and the light. And oh! those still more hideous nights when\n" \
|
|
"we sit by another in pain, when the low fire startles us every now and\n" \
|
|
"then with a falling cinder, and the tick of the clock seems a hammer\n" \
|
|
"beating out the life that we are watching.\n" \
|
|
"\n" \
|
|
"But enough of beds and bedrooms. I have kept to them too long, even for\n" \
|
|
"an idle fellow. Let us come out and have a smoke. That wastes time just\n" \
|
|
"as well and does not look so bad. Tobacco has been a blessing to us\n" \
|
|
"idlers. What the civil-service clerk before Sir Walter's time found\n" \
|
|
"to occupy their minds with it is hard to imagine. I attribute the\n" \
|
|
"quarrelsome nature of the Middle Ages young men entirely to the want of\n" \
|
|
"the soothing weed. They had no work to do and could not smoke, and\n" \
|
|
"the consequence was they were forever fighting and rowing. If, by any\n" \
|
|
"extraordinary chance, there was no war going, then they got up a deadly\n" \
|
|
"family feud with the next-door neighbor, and if, in spite of this, they\n" \
|
|
"still had a few spare moments on their hands, they occupied them with\n" \
|
|
"discussions as to whose sweetheart was the best looking, the arguments\n" \
|
|
"employed on both sides being battle-axes, clubs, etc. Questions of taste\n" \
|
|
"were soon decided in those days. When a twelfth-century youth fell in\n" \
|
|
"love he did not take three paces backward, gaze into her eyes, and tell\n" \
|
|
"her she was too beautiful to live. He said he would step outside and see\n" \
|
|
"about it. And if, when he got out, he met a man and broke his head--the\n" \
|
|
"other man's head, I mean--then that proved that his--the first\n" \
|
|
"fellow's--girl was a pretty girl. But if the other fellow broke _his_\n" \
|
|
"head--not his own, you know, but the other fellow's--the other fellow\n" \
|
|
"to the second fellow, that is, because of course the other fellow would\n" \
|
|
"only be the other fellow to him, not the first fellow who--well, if he\n" \
|
|
"broke his head, then _his_ girl--not the other fellow's, but the fellow\n" \
|
|
"who _was_ the--Look here, if A broke B's head, then A's girl was a\n" \
|
|
"pretty girl; but if B broke A's head, then A's girl wasn't a pretty\n" \
|
|
"girl, but B's girl was. That was their method of conducting art\n" \
|
|
"criticism.\n" \
|
|
"\n" \
|
|
"Nowadays we light a pipe and let the girls fight it out among\n" \
|
|
"themselves.\n" \
|
|
"\n" \
|
|
"They do it very well. They are getting to do all our work. They are\n" \
|
|
"doctors, and barristers, and artists. They manage theaters, and promote\n" \
|
|
"swindles, and edit newspapers. I am looking forward to the time when we\n" \
|
|
"men shall have nothing to do but lie in bed till twelve, read two novels\n" \
|
|
"a day, have nice little five-o'clock teas all to ourselves, and tax\n" \
|
|
"our brains with nothing more trying than discussions upon the latest\n" \
|
|
"patterns in trousers and arguments as to what Mr. Jones' coat was\n" \
|
|
"made of and whether it fitted him. It is a glorious prospect--for idle\n" \
|
|
"fellows.\n"
|
|
|
|
#define DATA_1 \
|
|
"ON BEING IN LOVE.\n" \
|
|
"\n" \
|
|
"You've been in love, of course! If not you've got it to come. Love is\n" \
|
|
"like the measles; we all have to go through it. Also like the measles,\n" \
|
|
"we take it only once. One never need be afraid of catching it a second\n" \
|
|
"time. The man who has had it can go into the most dangerous places and\n" \
|
|
"play the most foolhardy tricks with perfect safety. He can picnic in\n" \
|
|
"shady woods, ramble through leafy aisles, and linger on mossy seats to\n" \
|
|
"watch the sunset. He fears a quiet country-house no more than he would\n" \
|
|
"his own club. He can join a family party to go down the Rhine. He can,\n" \
|
|
"to see the last of a friend, venture into the very jaws of the marriage\n" \
|
|
"ceremony itself. He can keep his head through the whirl of a ravishing\n" \
|
|
"waltz, and rest afterward in a dark conservatory, catching nothing more\n" \
|
|
"lasting than a cold. He can brave a moonlight walk adown sweet-scented\n" \
|
|
"lanes or a twilight pull among the somber rushes. He can get over a\n" \
|
|
"stile without danger, scramble through a tangled hedge without being\n" \
|
|
"caught, come down a slippery path without falling. He can look into\n" \
|
|
"sunny eyes and not be dazzled. He listens to the siren voices, yet sails\n" \
|
|
"on with unveered helm. He clasps white hands in his, but no electric\n" \
|
|
"\"Lulu\"-like force holds him bound in their dainty pressure.\n" \
|
|
"\n" \
|
|
"No, we never sicken with love twice. Cupid spends no second arrow on\n" \
|
|
"the same heart. Love's handmaids are our life-long friends. Respect, and\n" \
|
|
"admiration, and affection, our doors may always be left open for, but\n" \
|
|
"their great celestial master, in his royal progress, pays but one visit\n" \
|
|
"and departs. We like, we cherish, we are very, very fond of--but we\n" \
|
|
"never love again. A man's heart is a firework that once in its time\n" \
|
|
"flashes heavenward. Meteor-like, it blazes for a moment and lights\n" \
|
|
"with its glory the whole world beneath. Then the night of our sordid\n" \
|
|
"commonplace life closes in around it, and the burned-out case, falling\n" \
|
|
"back to earth, lies useless and uncared for, slowly smoldering into\n" \
|
|
"ashes. Once, breaking loose from our prison bonds, we dare, as mighty\n" \
|
|
"old Prometheus dared, to scale the Olympian mount and snatch from\n" \
|
|
"Phoebus' chariot the fire of the gods. Happy those who, hastening down\n" \
|
|
"again ere it dies out, can kindle their earthly altars at its flame.\n" \
|
|
"Love is too pure a light to burn long among the noisome gases that we\n" \
|
|
"breathe, but before it is choked out we may use it as a torch to ignite\n" \
|
|
"the cozy fire of affection.\n" \
|
|
"\n" \
|
|
"And, after all, that warming glow is more suited to our cold little back\n" \
|
|
"parlor of a world than is the burning spirit love. Love should be the\n" \
|
|
"vestal fire of some mighty temple--some vast dim fane whose organ music\n" \
|
|
"is the rolling of the spheres. Affection will burn cheerily when the\n" \
|
|
"white flame of love is flickered out. Affection is a fire that can be\n" \
|
|
"fed from day to day and be piled up ever higher as the wintry years draw\n" \
|
|
"nigh. Old men and women can sit by it with their thin hands clasped, the\n" \
|
|
"little children can nestle down in front, the friend and neighbor has\n" \
|
|
"his welcome corner by its side, and even shaggy Fido and sleek Titty can\n" \
|
|
"toast their noses at the bars.\n" \
|
|
"\n" \
|
|
"Let us heap the coals of kindness upon that fire. Throw on your pleasant\n" \
|
|
"words, your gentle pressures of the hand, your thoughtful and unselfish\n" \
|
|
"deeds. Fan it with good-humor, patience, and forbearance. You can let\n" \
|
|
"the wind blow and the rain fall unheeded then, for your hearth will be\n" \
|
|
"warm and bright, and the faces round it will make sunshine in spite of\n" \
|
|
"the clouds without.\n" \
|
|
"\n" \
|
|
"I am afraid, dear Edwin and Angelina, you expect too much from love.\n" \
|
|
"You think there is enough of your little hearts to feed this fierce,\n" \
|
|
"devouring passion for all your long lives. Ah, young folk! don't rely\n" \
|
|
"too much upon that unsteady flicker. It will dwindle and dwindle as the\n" \
|
|
"months roll on, and there is no replenishing the fuel. You will watch it\n" \
|
|
"die out in anger and disappointment. To each it will seem that it is the\n" \
|
|
"other who is growing colder. Edwin sees with bitterness that Angelina no\n" \
|
|
"longer runs to the gate to meet him, all smiles and blushes; and when he\n" \
|
|
"has a cough now she doesn't begin to cry and, putting her arms round his\n" \
|
|
"neck, say that she cannot live without him. The most she will probably\n" \
|
|
"do is to suggest a lozenge, and even that in a tone implying that it is\n" \
|
|
"the noise more than anything else she is anxious to get rid of.\n" \
|
|
"\n" \
|
|
"Poor little Angelina, too, sheds silent tears, for Edwin has given up\n" \
|
|
"carrying her old handkerchief in the inside pocket of his waistcoat.\n" \
|
|
"\n" \
|
|
"Both are astonished at the falling off in the other one, but neither\n" \
|
|
"sees their own change. If they did they would not suffer as they do.\n" \
|
|
"They would look for the cause in the right quarter--in the littleness\n" \
|
|
"of poor human nature--join hands over their common failing, and start\n" \
|
|
"building their house anew on a more earthly and enduring foundation.\n" \
|
|
"But we are so blind to our own shortcomings, so wide awake to those\n" \
|
|
"of others. Everything that happens to us is always the other person's\n" \
|
|
"fault. Angelina would have gone on loving Edwin forever and ever and\n" \
|
|
"ever if only Edwin had not grown so strange and different. Edwin would\n" \
|
|
"have adored Angelina through eternity if Angelina had only remained the\n" \
|
|
"same as when he first adored her.\n" \
|
|
"\n" \
|
|
"It is a cheerless hour for you both when the lamp of love has gone out\n" \
|
|
"and the fire of affection is not yet lit, and you have to grope about\n" \
|
|
"in the cold, raw dawn of life to kindle it. God grant it catches light\n" \
|
|
"before the day is too far spent. Many sit shivering by the dead coals\n" \
|
|
"till night come.\n" \
|
|
"\n" \
|
|
"But, there, of what use is it to preach? Who that feels the rush of\n" \
|
|
"young love through his veins can think it will ever flow feeble and\n" \
|
|
"slow! To the boy of twenty it seems impossible that he will not love as\n" \
|
|
"wildly at sixty as he does then. He cannot call to mind any middle-aged\n" \
|
|
"or elderly gentleman of his acquaintance who is known to exhibit\n" \
|
|
"symptoms of frantic attachment, but that does not interfere in his\n" \
|
|
"belief in himself. His love will never fall, whoever else's may. Nobody\n" \
|
|
"ever loved as he loves, and so, of course, the rest of the world's\n" \
|
|
"experience can be no guide in his case. Alas! alas! ere thirty he has\n" \
|
|
"joined the ranks of the sneerers. It is not his fault. Our passions,\n" \
|
|
"both the good and bad, cease with our blushes. We do not hate, nor\n" \
|
|
"grieve, nor joy, nor despair in our thirties like we did in our teens.\n" \
|
|
"Disappointment does not suggest suicide, and we quaff success without\n" \
|
|
"intoxication.\n" \
|
|
"\n" \
|
|
"We take all things in a minor key as we grow older. There are few\n" \
|
|
"majestic passages in the later acts of life's opera. Ambition takes\n" \
|
|
"a less ambitious aim. Honor becomes more reasonable and conveniently\n" \
|
|
"adapts itself to circumstances. And love--love dies. \"Irreverence for\n" \
|
|
"the dreams of youth\" soon creeps like a killing frost upon our hearts.\n" \
|
|
"The tender shoots and the expanding flowers are nipped and withered, and\n" \
|
|
"of a vine that yearned to stretch its tendrils round the world there is\n" \
|
|
"left but a sapless stump.\n" \
|
|
"\n" \
|
|
"My fair friends will deem all this rank heresy, I know. So far from a\n" \
|
|
"man's not loving after he has passed boyhood, it is not till there is a\n" \
|
|
"good deal of gray in his hair that they think his protestations at all\n" \
|
|
"worthy of attention. Young ladies take their notions of our sex from the\n" \
|
|
"novels written by their own, and compared with the monstrosities\n" \
|
|
"that masquerade for men in the pages of that nightmare literature,\n" \
|
|
"Pythagoras' plucked bird and Frankenstein's demon were fair average\n" \
|
|
"specimens of humanity.\n" \
|
|
"\n" \
|
|
"In these so-called books, the chief lover, or Greek god, as he is\n" \
|
|
"admiringly referred to--by the way, they do not say which \"Greek god\"\n" \
|
|
"it is that the gentleman bears such a striking likeness to; it might be\n" \
|
|
"hump-backed Vulcan, or double-faced Janus, or even driveling Silenus,\n" \
|
|
"the god of abstruse mysteries. He resembles the whole family of them,\n" \
|
|
"however, in being a blackguard, and perhaps this is what is meant. To\n" \
|
|
"even the little manliness his classical prototypes possessed, though,\n" \
|
|
"he can lay no claim whatever, being a listless effeminate noodle, on\n" \
|
|
"the shady side of forty. But oh! the depth and strength of this elderly\n" \
|
|
"party's emotion for some bread-and-butter school-girl! Hide your heads,\n" \
|
|
"ye young Romeos and Leanders! this _blase_ old beau loves with an\n" \
|
|
"hysterical fervor that requires four adjectives to every noun to\n" \
|
|
"properly describe.\n" \
|
|
"\n" \
|
|
"It is well, dear ladies, for us old sinners that you study only books.\n" \
|
|
"Did you read mankind, you would know that the lad's shy stammering tells\n" \
|
|
"a truer tale than our bold eloquence. A boy's love comes from a full\n" \
|
|
"heart; a man's is more often the result of a full stomach. Indeed, a\n" \
|
|
"man's sluggish current may not be called love, compared with the rushing\n" \
|
|
"fountain that wells up when a boy's heart is struck with the heavenly\n" \
|
|
"rod. If you would taste love, drink of the pure stream that youth pours\n" \
|
|
"out at your feet. Do not wait till it has become a muddy river before\n" \
|
|
"you stoop to catch its waves.\n" \
|
|
"\n" \
|
|
"Or is it that you like its bitter flavor--that the clear, limpid water\n" \
|
|
"is insipid to your palate and that the pollution of its after-course\n" \
|
|
"gives it a relish to your lips? Must we believe those who tell us that a\n" \
|
|
"hand foul with the filth of a shameful life is the only one a young girl\n" \
|
|
"cares to be caressed by?\n" \
|
|
"\n" \
|
|
"That is the teaching that is bawled out day by day from between those\n" \
|
|
"yellow covers. Do they ever pause to think, I wonder, those devil's\n" \
|
|
"ladyhelps, what mischief they are doing crawling about God's garden, and\n" \
|
|
"telling childish Eves and silly Adams that sin is sweet and that decency\n" \
|
|
"is ridiculous and vulgar? How many an innocent girl do they not degrade\n" \
|
|
"into an evil-minded woman? To how many a weak lad do they not point out\n" \
|
|
"the dirty by-path as the shortest cut to a maiden's heart? It is not as\n" \
|
|
"if they wrote of life as it really is. Speak truth, and right will take\n" \
|
|
"care of itself. But their pictures are coarse daubs painted from the\n" \
|
|
"sickly fancies of their own diseased imagination.\n" \
|
|
"\n" \
|
|
"We want to think of women not--as their own sex would show them--as\n" \
|
|
"Lorleis luring us to destruction, but as good angels beckoning us\n" \
|
|
"upward. They have more power for good or evil than they dream of. It is\n" \
|
|
"just at the very age when a man's character is forming that he tumbles\n" \
|
|
"into love, and then the lass he loves has the making or marring of him.\n" \
|
|
"Unconsciously he molds himself to what she would have him, good or bad.\n" \
|
|
"I am sorry to have to be ungallant enough to say that I do not think\n" \
|
|
"they always use their influence for the best. Too often the female world\n" \
|
|
"is bounded hard and fast within the limits of the commonplace. Their\n" \
|
|
"ideal hero is a prince of littleness, and to become that many a powerful\n" \
|
|
"mind, enchanted by love, is \"lost to life and use and name and fame.\"\n" \
|
|
"\n" \
|
|
"And yet, women, you could make us so much better if you only would. It\n" \
|
|
"rests with you, more than with all the preachers, to roll this world a\n" \
|
|
"little nearer heaven. Chivalry is not dead: it only sleeps for want\n" \
|
|
"of work to do. It is you who must wake it to noble deeds. You must be\n" \
|
|
"worthy of knightly worship.\n" \
|
|
"\n" \
|
|
"You must be higher than ourselves. It was for Una that the Red Cross\n" \
|
|
"Knight did war. For no painted, mincing court dame could the dragon have\n" \
|
|
"been slain. Oh, ladies fair, be fair in mind and soul as well as face,\n" \
|
|
"so that brave knights may win glory in your service! Oh, woman, throw\n" \
|
|
"off your disguising cloaks of selfishness, effrontery, and affectation!\n" \
|
|
"Stand forth once more a queen in your royal robe of simple purity. A\n" \
|
|
"thousand swords, now rusting in ignoble sloth, shall leap from their\n" \
|
|
"scabbards to do battle for your honor against wrong. A thousand Sir\n" \
|
|
"Rolands shall lay lance in rest, and Fear, Avarice, Pleasure, and\n" \
|
|
"Ambition shall go down in the dust before your colors.\n" \
|
|
"\n" \
|
|
"What noble deeds were we not ripe for in the days when we loved?\n" \
|
|
"What noble lives could we not have lived for her sake? Our love was\n" \
|
|
"a religion we could have died for. It was no mere human creature like\n" \
|
|
"ourselves that we adored. It was a queen that we paid homage to, a\n" \
|
|
"goddess that we worshiped.\n" \
|
|
"\n" \
|
|
"And how madly we did worship! And how sweet it was to worship! Ah, lad,\n" \
|
|
"cherish love's young dream while it lasts! You will know too soon how\n" \
|
|
"truly little Tom Moore sang when he said that there was nothing half so\n" \
|
|
"sweet in life. Even when it brings misery it is a wild, romantic misery,\n" \
|
|
"all unlike the dull, worldly pain of after-sorrows. When you have lost\n" \
|
|
"her--when the light is gone out from your life and the world stretches\n" \
|
|
"before you a long, dark horror, even then a half-enchantment mingles\n" \
|
|
"with your despair.\n" \
|
|
"\n" \
|
|
"And who would not risk its terrors to gain its raptures? Ah, what\n" \
|
|
"raptures they were! The mere recollection thrills you. How delicious\n" \
|
|
"it was to tell her that you loved her, that you lived for her, that\n" \
|
|
"you would die for her! How you did rave, to be sure, what floods of\n" \
|
|
"extravagant nonsense you poured forth, and oh, how cruel it was of\n" \
|
|
"her to pretend not to believe you! In what awe you stood of her! How\n" \
|
|
"miserable you were when you had offended her! And yet, how pleasant to\n" \
|
|
"be bullied by her and to sue for pardon without having the slightest\n" \
|
|
"notion of what your fault was! How dark the world was when she snubbed\n" \
|
|
"you, as she often did, the little rogue, just to see you look wretched;\n" \
|
|
"how sunny when she smiled! How jealous you were of every one about\n" \
|
|
"her! How you hated every man she shook hands with, every woman she\n" \
|
|
"kissed--the maid that did her hair, the boy that cleaned her shoes, the\n" \
|
|
"dog she nursed--though you had to be respectful to the last-named! How\n" \
|
|
"you looked forward to seeing her, how stupid you were when you did see\n" \
|
|
"her, staring at her without saying a word! How impossible it was for\n" \
|
|
"you to go out at any time of the day or night without finding yourself\n" \
|
|
"eventually opposite her windows! You hadn't pluck enough to go in, but\n" \
|
|
"you hung about the corner and gazed at the outside. Oh, if the house had\n" \
|
|
"only caught fire--it was insured, so it wouldn't have mattered--and you\n" \
|
|
"could have rushed in and saved her at the risk of your life, and have\n" \
|
|
"been terribly burned and injured! Anything to serve her. Even in little\n" \
|
|
"things that was so sweet. How you would watch her, spaniel-like, to\n" \
|
|
"anticipate her slightest wish! How proud you were to do her bidding! How\n" \
|
|
"delightful it was to be ordered about by her! To devote your whole life\n" \
|
|
"to her and to never think of yourself seemed such a simple thing. You\n" \
|
|
"would go without a holiday to lay a humble offering at her shrine, and\n" \
|
|
"felt more than repaid if she only deigned to accept it. How precious to\n" \
|
|
"you was everything that she had hallowed by her touch--her little glove,\n" \
|
|
"the ribbon she had worn, the rose that had nestled in her hair and whose\n" \
|
|
"withered leaves still mark the poems you never care to look at now.\n" \
|
|
"\n" \
|
|
"And oh, how beautiful she was, how wondrous beautiful! It was as some\n" \
|
|
"angel entering the room, and all else became plain and earthly. She was\n" \
|
|
"too sacred to be touched. It seemed almost presumption to gaze at her.\n" \
|
|
"You would as soon have thought of kissing her as of singing comic songs\n" \
|
|
"in a cathedral. It was desecration enough to kneel and timidly raise the\n" \
|
|
"gracious little hand to your lips.\n" \
|
|
"\n" \
|
|
"Ah, those foolish days, those foolish days when we were unselfish and\n" \
|
|
"pure-minded; those foolish days when our simple hearts were full\n" \
|
|
"of truth, and faith, and reverence! Ah, those foolish days of noble\n" \
|
|
"longings and of noble strivings! And oh, these wise, clever days when we\n" \
|
|
"know that money is the only prize worth striving for, when we believe in\n" \
|
|
"nothing else but meanness and lies, when we care for no living creature\n" \
|
|
"but ourselves!\n"
|
|
|
|
#define DATA_2 \
|
|
"ON BEING IN THE BLUES.\n" \
|
|
"\n" \
|
|
"I can enjoy feeling melancholy, and there is a good deal of satisfaction\n" \
|
|
"about being thoroughly miserable; but nobody likes a fit of the blues.\n" \
|
|
"Nevertheless, everybody has them; notwithstanding which, nobody can tell\n" \
|
|
"why. There is no accounting for them. You are just as likely to have one\n" \
|
|
"on the day after you have come into a large fortune as on the day after\n" \
|
|
"you have left your new silk umbrella in the train. Its effect upon you\n" \
|
|
"is somewhat similar to what would probably be produced by a combined\n" \
|
|
"attack of toothache, indigestion, and cold in the head. You become\n" \
|
|
"stupid, restless, and irritable; rude to strangers and dangerous toward\n" \
|
|
"your friends; clumsy, maudlin, and quarrelsome; a nuisance to yourself\n" \
|
|
"and everybody about you.\n" \
|
|
"\n" \
|
|
"While it is on you can do nothing and think of nothing, though feeling\n" \
|
|
"at the time bound to do something. You can't sit still so put on your\n" \
|
|
"hat and go for a walk; but before you get to the corner of the street\n" \
|
|
"you wish you hadn't come out and you turn back. You open a book and try\n" \
|
|
"to read, but you find Shakespeare trite and commonplace, Dickens is dull\n" \
|
|
"and prosy, Thackeray a bore, and Carlyle too sentimental. You throw the\n" \
|
|
"book aside and call the author names. Then you \"shoo\" the cat out of\n" \
|
|
"the room and kick the door to after her. You think you will write your\n" \
|
|
"letters, but after sticking at \"Dearest Auntie: I find I have five\n" \
|
|
"minutes to spare, and so hasten to write to you,\" for a quarter of an\n" \
|
|
"hour, without being able to think of another sentence, you tumble the\n" \
|
|
"paper into the desk, fling the wet pen down upon the table-cloth,\n" \
|
|
"and start up with the resolution of going to see the Thompsons. While\n" \
|
|
"pulling on your gloves, however, it occurs to you that the Thompsons are\n" \
|
|
"idiots; that they never have supper; and that you will be expected to\n" \
|
|
"jump the baby. You curse the Thompsons and decide not to go.\n" \
|
|
"\n" \
|
|
"By this time you feel completely crushed. You bury your face in your\n" \
|
|
"hands and think you would like to die and go to heaven. You picture to\n" \
|
|
"yourself your own sick-bed, with all your friends and relations standing\n" \
|
|
"round you weeping. You bless them all, especially the young and pretty\n" \
|
|
"ones. They will value you when you are gone, so you say to yourself,\n" \
|
|
"and learn too late what they have lost; and you bitterly contrast their\n" \
|
|
"presumed regard for you then with their decided want of veneration now.\n" \
|
|
"\n" \
|
|
"These reflections make you feel a little more cheerful, but only for a\n" \
|
|
"brief period; for the next moment you think what a fool you must be\n" \
|
|
"to imagine for an instant that anybody would be sorry at anything that\n" \
|
|
"might happen to you. Who would care two straws (whatever precise amount\n" \
|
|
"of care two straws may represent) whether you are blown up, or hung\n" \
|
|
"up, or married, or drowned? Nobody cares for you. You never have\n" \
|
|
"been properly appreciated, never met with your due deserts in any one\n" \
|
|
"particular. You review the whole of your past life, and it is painfully\n" \
|
|
"apparent that you have been ill-used from your cradle.\n" \
|
|
"\n" \
|
|
"Half an hour's indulgence in these considerations works you up into\n" \
|
|
"a state of savage fury against everybody and everything, especially\n" \
|
|
"yourself, whom anatomical reasons alone prevent your kicking. Bed-time\n" \
|
|
"at last comes, to save you from doing something rash, and you spring\n" \
|
|
"upstairs, throw off your clothes, leaving them strewn all over the room,\n" \
|
|
"blow out the candle, and jump into bed as if you had backed yourself\n" \
|
|
"for a heavy wager to do the whole thing against time. There you toss\n" \
|
|
"and tumble about for a couple of hours or so, varying the monotony by\n" \
|
|
"occasionally jerking the clothes off and getting out and putting them\n" \
|
|
"on again. At length you drop into an uneasy and fitful slumber, have bad\n" \
|
|
"dreams, and wake up late the next morning.\n" \
|
|
"\n" \
|
|
"At least, this is all we poor single men can do under the circumstances.\n" \
|
|
"Married men bully their wives, grumble at the dinner, and insist on the\n" \
|
|
"children's going to bed. All of which, creating, as it does, a good deal\n" \
|
|
"of disturbance in the house, must be a great relief to the feelings of a\n" \
|
|
"man in the blues, rows being the only form of amusement in which he can\n" \
|
|
"take any interest.\n" \
|
|
"\n" \
|
|
"The symptoms of the infirmity are much the same in every case, but the\n" \
|
|
"affliction itself is variously termed. The poet says that \"a feeling\n" \
|
|
"of sadness comes o'er him.\" 'Arry refers to the heavings of his wayward\n" \
|
|
"heart by confiding to Jimee that he has \"got the blooming hump.\" Your\n" \
|
|
"sister doesn't know what is the matter with her to-night. She feels out\n" \
|
|
"of sorts altogether and hopes nothing is going to happen. The every-day\n" \
|
|
"young man is \"so awful glad to meet you, old fellow,\" for he does \"feel\n" \
|
|
"so jolly miserable this evening.\" As for myself, I generally say that \"I\n" \
|
|
"have a strange, unsettled feeling to-night\" and \"think I'll go out.\"\n" \
|
|
"\n" \
|
|
"By the way, it never does come except in the evening. In the sun-time,\n" \
|
|
"when the world is bounding forward full of life, we cannot stay to sigh\n" \
|
|
"and sulk. The roar of the working day drowns the voices of the elfin\n" \
|
|
"sprites that are ever singing their low-toned _miserere_ in our ears.\n" \
|
|
"In the day we are angry, disappointed, or indignant, but never \"in the\n" \
|
|
"blues\" and never melancholy. When things go wrong at ten o'clock in the\n" \
|
|
"morning we--or rather you--swear and knock the furniture about; but if\n" \
|
|
"the misfortune comes at ten P.M., we read poetry or sit in the dark and\n" \
|
|
"think what a hollow world this is.\n" \
|
|
"\n" \
|
|
"But, as a rule, it is not trouble that makes us melancholy. The\n" \
|
|
"actuality is too stern a thing for sentiment. We linger to weep over\n" \
|
|
"a picture, but from the original we should quickly turn our eyes away.\n" \
|
|
"There is no pathos in real misery: no luxury in real grief. We do not\n" \
|
|
"toy with sharp swords nor hug a gnawing fox to our breast for choice.\n" \
|
|
"When a man or woman loves to brood over a sorrow and takes care to keep\n" \
|
|
"it green in their memory, you may be sure it is no longer a pain to\n" \
|
|
"them. However they may have suffered from it at first, the recollection\n" \
|
|
"has become by then a pleasure. Many dear old ladies who daily look at\n" \
|
|
"tiny shoes lying in lavender-scented drawers, and weep as they think of\n" \
|
|
"the tiny feet whose toddling march is done, and sweet-faced young ones\n" \
|
|
"who place each night beneath their pillow some lock that once curled on\n" \
|
|
"a boyish head that the salt waves have kissed to death, will call me\n" \
|
|
"a nasty cynical brute and say I'm talking nonsense; but I believe,\n" \
|
|
"nevertheless, that if they will ask themselves truthfully whether they\n" \
|
|
"find it unpleasant to dwell thus on their sorrow, they will be compelled\n" \
|
|
"to answer \"No.\" Tears are as sweet as laughter to some natures. The\n" \
|
|
"proverbial Englishman, we know from old chronicler Froissart, takes his\n" \
|
|
"pleasures sadly, and the Englishwoman goes a step further and takes her\n" \
|
|
"pleasures in sadness itself.\n" \
|
|
"\n" \
|
|
"I am not sneering. I would not for a moment sneer at anything that\n" \
|
|
"helps to keep hearts tender in this hard old world. We men are cold and\n" \
|
|
"common-sensed enough for all; we would not have women the same. No, no,\n" \
|
|
"ladies dear, be always sentimental and soft-hearted, as you are--be the\n" \
|
|
"soothing butter to our coarse dry bread. Besides, sentiment is to women\n" \
|
|
"what fun is to us. They do not care for our humor, surely it would be\n" \
|
|
"unfair to deny them their grief. And who shall say that their mode of\n" \
|
|
"enjoyment is not as sensible as ours? Why assume that a doubled-up\n" \
|
|
"body, a contorted, purple face, and a gaping mouth emitting a series\n" \
|
|
"of ear-splitting shrieks point to a state of more intelligent happiness\n" \
|
|
"than a pensive face reposing upon a little white hand, and a pair of\n" \
|
|
"gentle tear-dimmed eyes looking back through Time's dark avenue upon a\n" \
|
|
"fading past?\n" \
|
|
"\n" \
|
|
"I am glad when I see Regret walked with as a friend--glad because I know\n" \
|
|
"the saltness has been washed from out the tears, and that the sting must\n" \
|
|
"have been plucked from the beautiful face of Sorrow ere we dare press\n" \
|
|
"her pale lips to ours. Time has laid his healing hand upon the wound\n" \
|
|
"when we can look back upon the pain we once fainted under and no\n" \
|
|
"bitterness or despair rises in our hearts. The burden is no longer\n" \
|
|
"heavy when we have for our past troubles only the same sweet mingling of\n" \
|
|
"pleasure and pity that we feel when old knight-hearted Colonel Newcome\n" \
|
|
"answers \"_adsum_\" to the great roll-call, or when Tom and Maggie\n" \
|
|
"Tulliver, clasping hands through the mists that have divided them, go\n" \
|
|
"down, locked in each other's arms, beneath the swollen waters of the\n" \
|
|
"Floss.\n" \
|
|
"\n" \
|
|
"Talking of poor Tom and Maggie Tulliver brings to my mind a saying of\n" \
|
|
"George Eliot's in connection with this subject of melancholy. She\n" \
|
|
"speaks somewhere of the \"sadness of a summer's evening.\" How wonderfully\n" \
|
|
"true--like everything that came from that wonderful pen--the observation\n" \
|
|
"is! Who has not felt the sorrowful enchantment of those lingering\n" \
|
|
"sunsets? The world belongs to Melancholy then, a thoughtful deep-eyed\n" \
|
|
"maiden who loves not the glare of day. It is not till \"light thickens\n" \
|
|
"and the crow wings to the rocky wood\" that she steals forth from her\n" \
|
|
"groves. Her palace is in twilight land. It is there she meets us. At her\n" \
|
|
"shadowy gate she takes our hand in hers and walks beside us through\n" \
|
|
"her mystic realm. We see no form, but seem to hear the rustling of her\n" \
|
|
"wings.\n" \
|
|
"\n" \
|
|
"Even in the toiling hum-drum city her spirit comes to us. There is a\n" \
|
|
"somber presence in each long, dull street; and the dark river creeps\n" \
|
|
"ghostlike under the black arches, as if bearing some hidden secret\n" \
|
|
"beneath its muddy waves.\n" \
|
|
"\n" \
|
|
"In the silent country, when the trees and hedges loom dim and blurred\n" \
|
|
"against the rising night, and the bat's wing flutters in our face, and\n" \
|
|
"the land-rail's cry sounds drearily across the fields, the spell sinks\n" \
|
|
"deeper still into our hearts. We seem in that hour to be standing by\n" \
|
|
"some unseen death-bed, and in the swaying of the elms we hear the sigh\n" \
|
|
"of the dying day.\n" \
|
|
"\n" \
|
|
"A solemn sadness reigns. A great peace is around us. In its light\n" \
|
|
"our cares of the working day grow small and trivial, and bread and\n" \
|
|
"cheese--ay, and even kisses--do not seem the only things worth striving\n" \
|
|
"for. Thoughts we cannot speak but only listen to flood in upon us, and\n" \
|
|
"standing in the stillness under earth's darkening dome, we feel that we\n" \
|
|
"are greater than our petty lives. Hung round with those dusky curtains,\n" \
|
|
"the world is no longer a mere dingy workshop, but a stately temple\n" \
|
|
"wherein man may worship, and where at times in the dimness his groping\n" \
|
|
"hands touch God's.\n"
|
|
|
|
#define DATA_3 \
|
|
"ON BEING HARD UP.\n" \
|
|
"\n" \
|
|
"It is a most remarkable thing. I sat down with the full intention of\n" \
|
|
"writing something clever and original; but for the life of me I can't\n" \
|
|
"think of anything clever and original--at least, not at this moment. The\n" \
|
|
"only thing I can think about now is being hard up. I suppose having my\n" \
|
|
"hands in my pockets has made me think about this. I always do sit with\n" \
|
|
"my hands in my pockets except when I am in the company of my sisters,\n" \
|
|
"my cousins, or my aunts; and they kick up such a shindy--I should say\n" \
|
|
"expostulate so eloquently upon the subject--that I have to give in and\n" \
|
|
"take them out--my hands I mean. The chorus to their objections is that\n" \
|
|
"it is not gentlemanly. I am hanged if I can see why. I could understand\n" \
|
|
"its not being considered gentlemanly to put your hands in other people's\n" \
|
|
"pockets (especially by the other people), but how, O ye sticklers for\n" \
|
|
"what looks this and what looks that, can putting his hands in his own\n" \
|
|
"pockets make a man less gentle? Perhaps you are right, though. Now I\n" \
|
|
"come to think of it, I have heard some people grumble most savagely when\n" \
|
|
"doing it. But they were mostly old gentlemen. We young fellows, as a\n" \
|
|
"rule, are never quite at ease unless we have our hands in our pockets.\n" \
|
|
"We are awkward and shifty. We are like what a music-hall Lion Comique\n" \
|
|
"would be without his opera-hat, if such a thing can be imagined. But let\n" \
|
|
"us put our hands in our trousers pockets, and let there be some small\n" \
|
|
"change in the right-hand one and a bunch of keys in the left, and we\n" \
|
|
"will face a female post-office clerk.\n" \
|
|
"\n" \
|
|
"It is a little difficult to know what to do with your hands, even in\n" \
|
|
"your pockets, when there is nothing else there. Years ago, when my whole\n" \
|
|
"capital would occasionally come down to \"what in town the people call\n" \
|
|
"a bob,\" I would recklessly spend a penny of it, merely for the sake of\n" \
|
|
"having the change, all in coppers, to jingle. You don't feel nearly so\n" \
|
|
"hard up with eleven pence in your pocket as you do with a shilling. Had\n" \
|
|
"I been \"La-di-da,\" that impecunious youth about whom we superior folk\n" \
|
|
"are so sarcastic, I would have changed my penny for two ha'pennies.\n" \
|
|
"\n" \
|
|
"I can speak with authority on the subject of being hard up. I have been\n" \
|
|
"a provincial actor. If further evidence be required, which I do not\n" \
|
|
"think likely, I can add that I have been a \"gentleman connected with the\n" \
|
|
"press.\" I have lived on 15 shilling a week. I have lived a week on 10,\n" \
|
|
"owing the other 5; and I have lived for a fortnight on a great-coat.\n" \
|
|
"\n" \
|
|
"It is wonderful what an insight into domestic economy being really hard\n" \
|
|
"up gives one. If you want to find out the value of money, live on\n" \
|
|
"15 shillings a week and see how much you can put by for clothes and\n" \
|
|
"recreation. You will find out that it is worth while to wait for the\n" \
|
|
"farthing change, that it is worth while to walk a mile to save a\n" \
|
|
"penny, that a glass of beer is a luxury to be indulged in only at rare\n" \
|
|
"intervals, and that a collar can be worn for four days.\n" \
|
|
"\n" \
|
|
"Try it just before you get married. It will be excellent practice. Let\n" \
|
|
"your son and heir try it before sending him to college. He won't grumble\n" \
|
|
"at a hundred a year pocket-money then. There are some people to whom it\n" \
|
|
"would do a world of good. There is that delicate blossom who can't drink\n" \
|
|
"any claret under ninety-four, and who would as soon think of dining\n" \
|
|
"off cat's meat as off plain roast mutton. You do come across these\n" \
|
|
"poor wretches now and then, though, to the credit of humanity, they are\n" \
|
|
"principally confined to that fearful and wonderful society known only\n" \
|
|
"to lady novelists. I never hear of one of these creatures discussing a\n" \
|
|
"_menu_ card but I feel a mad desire to drag him off to the bar of\n" \
|
|
"some common east-end public-house and cram a sixpenny dinner down his\n" \
|
|
"throat--beefsteak pudding, fourpence; potatoes, a penny; half a pint of\n" \
|
|
"porter, a penny. The recollection of it (and the mingled fragrance of\n" \
|
|
"beer, tobacco, and roast pork generally leaves a vivid impression) might\n" \
|
|
"induce him to turn up his nose a little less frequently in the future\n" \
|
|
"at everything that is put before him. Then there is that generous party,\n" \
|
|
"the cadger's delight, who is so free with his small change, but who\n" \
|
|
"never thinks of paying his debts. It might teach even him a little\n" \
|
|
"common sense. \"I always give the waiter a shilling. One can't give the\n" \
|
|
"fellow less, you know,\" explained a young government clerk with whom I\n" \
|
|
"was lunching the other day in Regent Street. I agreed with him as to the\n" \
|
|
"utter impossibility of making it elevenpence ha'penny; but at the same\n" \
|
|
"time I resolved to one day decoy him to an eating-house I remembered\n" \
|
|
"near Covent Garden, where the waiter, for the better discharge of his\n" \
|
|
"duties, goes about in his shirt-sleeves--and very dirty sleeves they\n" \
|
|
"are, too, when it gets near the end of the month. I know that waiter.\n" \
|
|
"If my friend gives him anything beyond a penny, the man will insist on\n" \
|
|
"shaking hands with him then and there as a mark of his esteem; of that I\n" \
|
|
"feel sure.\n" \
|
|
"\n" \
|
|
"There have been a good many funny things said and written about\n" \
|
|
"hardupishness, but the reality is not funny, for all that. It is not\n" \
|
|
"funny to have to haggle over pennies. It isn't funny to be thought\n" \
|
|
"mean and stingy. It isn't funny to be shabby and to be ashamed of your\n" \
|
|
"address. No, there is nothing at all funny in poverty--to the poor. It\n" \
|
|
"is hell upon earth to a sensitive man; and many a brave gentleman who\n" \
|
|
"would have faced the labors of Hercules has had his heart broken by its\n" \
|
|
"petty miseries.\n" \
|
|
"\n" \
|
|
"It is not the actual discomforts themselves that are hard to bear.\n" \
|
|
"Who would mind roughing it a bit if that were all it meant? What cared\n" \
|
|
"Robinson Crusoe for a patch on his trousers? Did he wear trousers? I\n" \
|
|
"forget; or did he go about as he does in the pantomimes? What did it\n" \
|
|
"matter to him if his toes did stick out of his boots? and what if\n" \
|
|
"his umbrella was a cotton one, so long as it kept the rain off? His\n" \
|
|
"shabbiness did not trouble him; there was none of his friends round\n" \
|
|
"about to sneer him.\n" \
|
|
"\n" \
|
|
"Being poor is a mere trifle. It is being known to be poor that is the\n" \
|
|
"sting. It is not cold that makes a man without a great-coat hurry along\n" \
|
|
"so quickly. It is not all shame at telling lies--which he knows will\n" \
|
|
"not be believed--that makes him turn so red when he informs you that\n" \
|
|
"he considers great-coats unhealthy and never carries an umbrella on\n" \
|
|
"principle. It is easy enough to say that poverty is no crime. No; if\n" \
|
|
"it were men wouldn't be ashamed of it. It's a blunder, though, and is\n" \
|
|
"punished as such. A poor man is despised the whole world over; despised\n" \
|
|
"as much by a Christian as by a lord, as much by a demagogue as by a\n" \
|
|
"footman, and not all the copy-book maxims ever set for ink stained youth\n" \
|
|
"will make him respected. Appearances are everything, so far as human\n" \
|
|
"opinion goes, and the man who will walk down Piccadilly arm in arm with\n" \
|
|
"the most notorious scamp in London, provided he is a well-dressed one,\n" \
|
|
"will slink up a back street to say a couple of words to a seedy-looking\n" \
|
|
"gentleman. And the seedy-looking gentleman knows this--no one\n" \
|
|
"better--and will go a mile round to avoid meeting an acquaintance. Those\n" \
|
|
"that knew him in his prosperity need never trouble themselves to look\n" \
|
|
"the other way. He is a thousand times more anxious that they should not\n" \
|
|
"see him than they can be; and as to their assistance, there is nothing\n" \
|
|
"he dreads more than the offer of it. All he wants is to be forgotten;\n" \
|
|
"and in this respect he is generally fortunate enough to get what he\n" \
|
|
"wants.\n" \
|
|
"\n" \
|
|
"One becomes used to being hard up, as one becomes used to everything\n" \
|
|
"else, by the help of that wonderful old homeopathic doctor, Time. You\n" \
|
|
"can tell at a glance the difference between the old hand and the novice;\n" \
|
|
"between the case-hardened man who has been used to shift and struggle\n" \
|
|
"for years and the poor devil of a beginner striving to hide his misery,\n" \
|
|
"and in a constant agony of fear lest he should be found out. Nothing\n" \
|
|
"shows this difference more clearly than the way in which each will pawn\n" \
|
|
"his watch. As the poet says somewhere: \"True ease in pawning comes from\n" \
|
|
"art, not chance.\" The one goes into his \"uncle's\" with as much composure\n" \
|
|
"as he would into his tailor's--very likely with more. The assistant is\n" \
|
|
"even civil and attends to him at once, to the great indignation of the\n" \
|
|
"lady in the next box, who, however, sarcastically observes that she\n" \
|
|
"don't mind being kept waiting \"if it is a regular customer.\" Why, from\n" \
|
|
"the pleasant and businesslike manner in which the transaction is carried\n" \
|
|
"out, it might be a large purchase in the three per cents. Yet what a\n" \
|
|
"piece of work a man makes of his first \"pop.\" A boy popping his first\n" \
|
|
"question is confidence itself compared with him. He hangs about outside\n" \
|
|
"the shop until he has succeeded in attracting the attention of all the\n" \
|
|
"loafers in the neighborhood and has aroused strong suspicions in the\n" \
|
|
"mind of the policeman on the beat. At last, after a careful examination\n" \
|
|
"of the contents of the windows, made for the purpose of impressing the\n" \
|
|
"bystanders with the notion that he is going in to purchase a diamond\n" \
|
|
"bracelet or some such trifle, he enters, trying to do so with a careless\n" \
|
|
"swagger, and giving himself really the air of a member of the swell mob.\n" \
|
|
"When inside he speaks in so low a voice as to be perfectly inaudible,\n" \
|
|
"and has to say it all over again. When, in the course of his rambling\n" \
|
|
"conversation about a \"friend\" of his, the word \"lend\" is reached, he is\n" \
|
|
"promptly told to go up the court on the right and take the first door\n" \
|
|
"round the corner. He comes out of the shop with a face that you could\n" \
|
|
"easily light a cigarette at, and firmly under the impression that the\n" \
|
|
"whole population of the district is watching him. When he does get\n" \
|
|
"to the right place he has forgotten his name and address and is in a\n" \
|
|
"general condition of hopeless imbecility. Asked in a severe tone how he\n" \
|
|
"came by \"this,\" he stammers and contradicts himself, and it is only a\n" \
|
|
"miracle if he does not confess to having stolen it that very day. He is\n" \
|
|
"thereupon informed that they don't want anything to do with his sort,\n" \
|
|
"and that he had better get out of this as quickly as possible, which he\n" \
|
|
"does, recollecting nothing more until he finds himself three miles off,\n" \
|
|
"without the slightest knowledge how he got there.\n" \
|
|
"\n" \
|
|
"By the way, how awkward it is, though, having to depend on public-houses\n" \
|
|
"and churches for the time. The former are generally too fast and the\n" \
|
|
"latter too slow. Besides which, your efforts to get a glimpse of\n" \
|
|
"the public house clock from the outside are attended with great\n" \
|
|
"difficulties. If you gently push the swing-door ajar and peer in you\n" \
|
|
"draw upon yourself the contemptuous looks of the barmaid, who at once\n" \
|
|
"puts you down in the same category with area sneaks and cadgers. You\n" \
|
|
"also create a certain amount of agitation among the married portion of\n" \
|
|
"the customers. You don't see the clock because it is behind the door;\n" \
|
|
"and in trying to withdraw quietly you jam your head. The only other\n" \
|
|
"method is to jump up and down outside the window. After this latter\n" \
|
|
"proceeding, however, if you do not bring out a banjo and commence to\n" \
|
|
"sing, the youthful inhabitants of the neighborhood, who have gathered\n" \
|
|
"round in expectation, become disappointed.\n" \
|
|
"\n" \
|
|
"I should like to know, too, by what mysterious law of nature it is that\n" \
|
|
"before you have left your watch \"to be repaired\" half an hour, some one\n" \
|
|
"is sure to stop you in the street and conspicuously ask you the time.\n" \
|
|
"Nobody even feels the slightest curiosity on the subject when you've got\n" \
|
|
"it on.\n" \
|
|
"\n" \
|
|
"Dear old ladies and gentlemen who know nothing about being hard up--and\n" \
|
|
"may they never, bless their gray old heads--look upon the pawn-shop\n" \
|
|
"as the last stage of degradation; but those who know it better (and my\n" \
|
|
"readers have no doubt, noticed this themselves) are often surprised,\n" \
|
|
"like the little boy who dreamed he went to heaven, at meeting so many\n" \
|
|
"people there that they never expected to see. For my part, I think it a\n" \
|
|
"much more independent course than borrowing from friends, and I always\n" \
|
|
"try to impress this upon those of my acquaintance who incline toward\n" \
|
|
"\"wanting a couple of pounds till the day after to-morrow.\" But they\n" \
|
|
"won't all see it. One of them once remarked that he objected to the\n" \
|
|
"principle of the thing. I fancy if he had said it was the interest that\n" \
|
|
"he objected to he would have been nearer the truth: twenty-five per\n" \
|
|
"cent. certainly does come heavy.\n" \
|
|
"\n" \
|
|
"There are degrees in being hard up. We are all hard up, more or\n" \
|
|
"less--most of us more. Some are hard up for a thousand pounds; some for\n" \
|
|
"a shilling. Just at this moment I am hard up myself for a fiver. I only\n" \
|
|
"want it for a day or two. I should be certain of paying it back within a\n" \
|
|
"week at the outside, and if any lady or gentleman among my readers would\n" \
|
|
"kindly lend it me, I should be very much obliged indeed. They could send\n" \
|
|
"it to me under cover to Messrs. Field & Tuer, only, in such case, please\n" \
|
|
"let the envelope be carefully sealed. I would give you my I.O.U. as\n" \
|
|
"security.\n"
|
|
|
|
static const char *s_data[N_STREAMS] = {
|
|
DATA_0,
|
|
DATA_1,
|
|
DATA_2,
|
|
DATA_3,
|
|
};
|
|
|
|
static size_t s_data_sz[N_STREAMS] = {
|
|
sizeof(DATA_0) - 1,
|
|
sizeof(DATA_1) - 1,
|
|
sizeof(DATA_2) - 1,
|
|
sizeof(DATA_3) - 1,
|
|
};
|