int parse_headers(struct request *req, char *start, size_t len, struct pl *body) { int br=0; size_t *ct; enum http_hdr_id id; char *p = start; struct pl header, hval; header.p = start; header.l = 0; hval.p = NULL; hval.l = -2; ct = &header.l; while(len) { switch(*p) { case '\n': case '\r': br++; break; case ':': if(ct == &header.l) { ct = &hval.l; hval.p = p+2; } default: br = 0; } if(br) { if(header.l) { id = (enum http_hdr_id)hash_joaat_ci(header.p, header.l) & 0xFFF; hdr_add(req, id, &header, &hval); } header.p = p+1; header.l = -1; hval.l = -2; ct = &header.l; hval.p = NULL; } p++; (*ct)++; len--; if(br>3) { body->p = p; body->l = len; } } return 0; }
static char* decode_v0_log() { const char* v1_log = "jHiccup-2.0.1.logV0.hlog"; FILE* f = fopen(v1_log, "r"); mu_assert("Can not open v1 log file", f != NULL); struct hdr_histogram* accum; hdr_init(1, INT64_C(3600000000000), 3, &accum); struct hdr_histogram* h = NULL; struct hdr_log_reader reader; hdr_timespec timestamp; hdr_timespec interval; hdr_log_reader_init(&reader); int rc = hdr_log_read_header(&reader, f); mu_assert("Failed to read header", rc == 0); int histogram_count = 0; int64_t total_count = 0; while ((rc = hdr_log_read(&reader, f, &h, ×tamp, &interval)) != EOF) { mu_assert("Failed to read histogram", rc == 0); histogram_count++; total_count += h->total_count; int64_t dropped = hdr_add(accum, h); mu_assert("Dropped events", compare_int64(dropped, 0)); free(h); h = NULL; } mu_assert("Wrong number of histograms", compare_int(histogram_count, 81)); mu_assert("Wrong total count", compare_int64(total_count, 61256)); mu_assert("99.9 percentile wrong", compare_int64(1510998015, hdr_value_at_percentile(accum, 99.9))); mu_assert("max value wrong", compare_int64(1569718271, hdr_max(accum))); mu_assert("Seconds wrong", compare_int64(1438869961, reader.start_timestamp.tv_sec)); mu_assert("Nanoseconds wrong", compare_int64(225000000, reader.start_timestamp.tv_nsec)); return 0; }
static char* decode_v3_log() { const char* v3_log = "jHiccup-2.0.7S.logV3.hlog"; FILE* f = fopen(v3_log, "r"); mu_assert("Can not open v3 log file", f != NULL); struct hdr_histogram* accum; hdr_init(1, INT64_C(3600000000000), 3, &accum); struct hdr_histogram* h = NULL; struct hdr_log_reader reader; hdr_timespec timestamp; hdr_timespec interval; hdr_log_reader_init(&reader); int rc = hdr_log_read_header(&reader, f); mu_assert("Failed to read header", validate_return_code(rc)); int histogram_count = 0; int64_t total_count = 0; while ((rc = hdr_log_read(&reader, f, &h, ×tamp, &interval)) != EOF) { mu_assert("Failed to read histogram", validate_return_code(rc)); histogram_count++; total_count += h->total_count; int64_t dropped = hdr_add(accum, h); mu_assert("Dropped events", compare_int64(dropped, 0)); free(h); h = NULL; } mu_assert("Wrong number of histograms", compare_int(histogram_count, 62)); mu_assert("Wrong total count", compare_int64(total_count, 48761)); mu_assert("99.9 percentile wrong", compare_int64(1745879039, hdr_value_at_percentile(accum, 99.9))); mu_assert("max value wrong", compare_int64(1796210687, hdr_max(accum))); mu_assert("Seconds wrong", compare_int64(1441812279, reader.start_timestamp.tv_sec)); mu_assert("Nanoseconds wrong", compare_int64(474000000, reader.start_timestamp.tv_nsec)); return 0; }
ERL_NIF_TERM _hh_add(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { hh_ctx_t* ctx = NULL; hh_ctx_t* from = NULL; ErlNifResourceType* ctx_type = get_hh_ctx_type(env); if (argc != 2 || ctx_type == NULL || !enif_get_resource(env, argv[0], ctx_type, (void **)&ctx) || !enif_get_resource(env, argv[1], ctx_type, (void **)&from)) { return enif_make_badarg(env); } if (ctx != NULL) { return enif_make_long(env, hdr_add(ctx->data, from->data)); } return make_error(env, "bad_hdr_histogram_nif_impl"); }
static int http_connect(HTTPContext *s, const char *path, const char *hoststr, int flags, int wait) { int post, err, ch; char line[512], *q; hdr_clear(s); /* send http header */ post = flags & O_WRONLY; s->len = 0; s->tread = 0; s->bpos = 0; s->bsz = 0; snprintf(line, sizeof(line), "%s %s HTTP/1.0\r\n" "User-Agent: %s\r\n" "Host: %s\r\n" "Accept: */*\r\n" "Connection: keep-alive\r\n" "\r\n", post ? "POST" : "GET", path, //"Wget/1.9", "dcplaya_net", hoststr); if (http_write((uint32) s, line, strlen(line)) < 0) return -1; #ifdef DEBUG printf("http : sent header -->\n%s", line); #endif /* init input buffer */ s->line_count = 0; //s->location[0] = '\0'; if (post) { //sleep(1); return 0; } /* wait for header */ q = line; if (wait) thd_sleep(wait); for(;;) { ch = http_getc((uint32) s); #ifdef DEBUG //printf("%c", ch); #endif if (ch < 0) { printf("http header truncated\n"); return 0; } if (ch == '\n') { /* process line */ if (q > line && q[-1] == '\r') q--; *q = '\0'; #ifdef DEBUG printf("header='%s'\n", line); #endif if (line[0]) hdr_add(s, line); err = process_line(s, line, s->line_count); if (err < 0) return err; if (err == 0) return 0; //return s->len? 0 : -1; s->line_count++; q = line; } else { if ((q - line) < sizeof(line) - 1) *q++ = ch; } } }
static int hdr_decode_compressed_v2( _compression_flyweight* compression_flyweight, size_t length, struct hdr_histogram** histogram) { struct hdr_histogram* h = NULL; int result = 0; uint8_t* counts_array = NULL; _encoding_flyweight_v1 encoding_flyweight; z_stream strm; strm_init(&strm); if (inflateInit(&strm) != Z_OK) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int32_t compressed_length = be32toh(compression_flyweight->length); if (compressed_length < 0 || length - sizeof(_compression_flyweight) < (size_t)compressed_length) { FAIL_AND_CLEANUP(cleanup, result, EINVAL); } strm.next_in = compression_flyweight->data; strm.avail_in = (uInt) compressed_length; strm.next_out = (uint8_t *) &encoding_flyweight; strm.avail_out = sizeof(_encoding_flyweight_v1); if (inflate(&strm, Z_SYNC_FLUSH) != Z_OK) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int32_t encoding_cookie = get_cookie_base(be32toh(encoding_flyweight.cookie)); if (V2_ENCODING_COOKIE != encoding_cookie) { FAIL_AND_CLEANUP(cleanup, result, HDR_ENCODING_COOKIE_MISMATCH); } int32_t counts_limit = be32toh(encoding_flyweight.payload_len); int64_t lowest_trackable_value = be64toh(encoding_flyweight.lowest_trackable_value); int64_t highest_trackable_value = be64toh(encoding_flyweight.highest_trackable_value); int32_t significant_figures = be32toh(encoding_flyweight.significant_figures); if (hdr_init( lowest_trackable_value, highest_trackable_value, significant_figures, &h) != 0) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } // Make sure there at least 9 bytes to read // if there is a corrupt value at the end // of the array we won't read corrupt data or crash. if ((counts_array = calloc(1, (size_t) counts_limit + 9)) == NULL) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } strm.next_out = counts_array; strm.avail_out = (uInt) counts_limit; if (inflate(&strm, Z_FINISH) != Z_STREAM_END) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int r = _apply_to_counts_zz(h, counts_array, counts_limit); if (0 != r) { FAIL_AND_CLEANUP(cleanup, result, r); } h->normalizing_index_offset = be32toh(encoding_flyweight.normalizing_index_offset); h->conversion_ratio = int64_bits_to_double(be64toh(encoding_flyweight.conversion_ratio_bits)); hdr_reset_internal_counters(h); cleanup: (void)inflateEnd(&strm); free(counts_array); if (result != 0) { free(h); } else if (NULL == *histogram) { *histogram = h; } else { hdr_add(*histogram, h); free(h); } return result; }
static int hdr_decode_compressed_v0( _compression_flyweight* compression_flyweight, size_t length, struct hdr_histogram** histogram) { struct hdr_histogram* h = NULL; int result = 0; uint8_t* counts_array = NULL; _encoding_flyweight_v0 encoding_flyweight; z_stream strm; strm_init(&strm); if (inflateInit(&strm) != Z_OK) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int32_t compressed_length = be32toh(compression_flyweight->length); if (compressed_length < 0 || length - sizeof(_compression_flyweight) < (size_t)compressed_length) { FAIL_AND_CLEANUP(cleanup, result, EINVAL); } strm.next_in = compression_flyweight->data; strm.avail_in = (uInt) compressed_length; strm.next_out = (uint8_t *) &encoding_flyweight; strm.avail_out = sizeof(_encoding_flyweight_v0); if (inflate(&strm, Z_SYNC_FLUSH) != Z_OK) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int32_t encoding_cookie = get_cookie_base(be32toh(encoding_flyweight.cookie)); if (V0_ENCODING_COOKIE != encoding_cookie) { FAIL_AND_CLEANUP(cleanup, result, HDR_ENCODING_COOKIE_MISMATCH); } int32_t word_size = word_size_from_cookie(be32toh(encoding_flyweight.cookie)); int64_t lowest_trackable_value = be64toh(encoding_flyweight.lowest_trackable_value); int64_t highest_trackable_value = be64toh(encoding_flyweight.highest_trackable_value); int32_t significant_figures = be32toh(encoding_flyweight.significant_figures); if (hdr_init( lowest_trackable_value, highest_trackable_value, significant_figures, &h) != 0) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } int32_t counts_array_len = h->counts_len * word_size; if ((counts_array = calloc(1, (size_t) counts_array_len)) == NULL) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } strm.next_out = counts_array; strm.avail_out = (uInt) counts_array_len; if (inflate(&strm, Z_FINISH) != Z_STREAM_END) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } _apply_to_counts(h, word_size, counts_array, h->counts_len); hdr_reset_internal_counters(h); h->normalizing_index_offset = 0; h->conversion_ratio = 1.0; cleanup: (void)inflateEnd(&strm); free(counts_array); if (result != 0) { free(h); } else if (NULL == *histogram) { *histogram = h; } else { hdr_add(*histogram, h); free(h); } return result; }
void add(hdr_histogram* to) { int inactive_index = active_index_.exchange(!active_index_.load()); hdr_histogram* from = histograms_[inactive_index]; phaser_.flip_phase(); hdr_add(to, from); }
void add(hdr_histogram* to) { hdr_add(to, histogram_); }
/** * Decode a SIP message * * @param msgp Pointer to allocated SIP Message * @param mb Buffer containing SIP Message * * @return 0 if success, otherwise errorcode */ int sip_msg_decode(struct sip_msg **msgp, struct mbuf *mb) { struct pl x, y, z, e, name; const char *p, *v, *cv; struct sip_msg *msg; bool comsep, quote; enum sip_hdrid id = SIP_HDR_NONE; uint32_t ws, lf; size_t l; int err; if (!msgp || !mb) return EINVAL; p = (const char *)mbuf_buf(mb); l = mbuf_get_left(mb); if (re_regex(p, l, "[^ \t\r\n]+ [^ \t\r\n]+ [^\r\n]*[\r]*[\n]1", &x, &y, &z, NULL, &e) || x.p != (char *)mbuf_buf(mb)) return (l > STARTLINE_MAX) ? EBADMSG : ENODATA; msg = mem_zalloc(sizeof(*msg), destructor); if (!msg) return ENOMEM; err = hash_alloc(&msg->hdrht, HDR_HASH_SIZE); if (err) goto out; msg->tag = rand_u64(); msg->mb = mem_ref(mb); msg->req = (0 == pl_strcmp(&z, "SIP/2.0")); if (msg->req) { msg->met = x; msg->ruri = y; msg->ver = z; if (uri_decode(&msg->uri, &y)) { err = EBADMSG; goto out; } } else { msg->ver = x; msg->scode = pl_u32(&y); msg->reason = z; if (!msg->scode) { err = EBADMSG; goto out; } } l -= e.p + e.l - p; p = e.p + e.l; name.p = v = cv = NULL; name.l = ws = lf = 0; comsep = false; quote = false; for (; l > 0; p++, l--) { switch (*p) { case ' ': case '\t': lf = 0; /* folding */ ++ws; break; case '\r': ++ws; break; case '\n': ++ws; if (!lf++) break; ++p; --l; /* eoh */ /*@fallthrough@*/ default: if (lf || (*p == ',' && comsep && !quote)) { if (!name.l) { err = EBADMSG; goto out; } err = hdr_add(msg, &name, id, cv ? cv : p, cv ? p - cv - ws : 0, true, cv == v && lf); if (err) goto out; if (!lf) { /* comma separated */ cv = NULL; break; } if (cv != v) { err = hdr_add(msg, &name, id, v ? v : p, v ? p - v - ws : 0, false, true); if (err) goto out; } if (lf > 1) { /* eoh */ err = 0; goto out; } comsep = false; name.p = NULL; cv = v = NULL; lf = 0; } if (!name.p) { name.p = p; name.l = 0; ws = 0; } if (!name.l) { if (*p != ':') { ws = 0; break; } name.l = MAX((int)(p - name.p - ws), 0); if (!name.l) { err = EBADMSG; goto out; } id = hdr_hash(&name); comsep = hdr_comma_separated(id); break; } if (!cv) { quote = false; cv = p; } if (!v) { v = p; } if (*p == '"') quote = !quote; ws = 0; break; } } err = ENODATA; out: if (err) mem_deref(msg); else { *msgp = msg; mb->pos = mb->end - l; } return err; }
/** * Decode a HTTP message * * @param msgp Pointer to allocated HTTP Message * @param mb Buffer containing HTTP Message * @param req True for request, false for response * * @return 0 if success, otherwise errorcode */ int http_msg_decode(struct http_msg **msgp, struct mbuf *mb, bool req) { struct pl b, s, e, name, scode; const char *p, *cv; struct http_msg *msg; bool comsep, quote; enum http_hdrid id = HTTP_HDR_NONE; uint32_t ws, lf; size_t l; int err; if (!msgp || !mb) return EINVAL; p = (const char *)mbuf_buf(mb); l = mbuf_get_left(mb); if (re_regex(p, l, "[\r\n]*[^\r\n]+[\r]*[\n]1", &b, &s, NULL, &e)) return (l > STARTLINE_MAX) ? EBADMSG : ENODATA; msg = mem_zalloc(sizeof(*msg), destructor); if (!msg) return ENOMEM; msg->mb = mem_ref(mb); if (req) { if (re_regex(s.p, s.l, "[a-z]+ [^? ]+[^ ]* HTTP/[0-9.]+", &msg->met, &msg->path, &msg->prm, &msg->ver) || msg->met.p != s.p) { err = EBADMSG; goto out; } } else { if (re_regex(s.p, s.l, "HTTP/[0-9.]+ [0-9]+ [^]*", &msg->ver, &scode, &msg->reason) || msg->ver.p != s.p + 5) { err = EBADMSG; goto out; } msg->scode = pl_u32(&scode); } l -= e.p + e.l - p; p = e.p + e.l; name.p = cv = NULL; name.l = ws = lf = 0; comsep = false; quote = false; for (; l > 0; p++, l--) { switch (*p) { case ' ': case '\t': lf = 0; /* folding */ ++ws; break; case '\r': ++ws; break; case '\n': ++ws; if (!name.p) { ++p; --l; /* no headers */ err = 0; goto out; } if (!lf++) break; ++p; --l; /* eoh */ /*@fallthrough@*/ default: if (lf || (*p == ',' && comsep && !quote)) { if (!name.l) { err = EBADMSG; goto out; } err = hdr_add(msg, &name, id, cv ? cv : p, cv ? p - cv - ws : 0); if (err) goto out; if (!lf) { /* comma separated */ cv = NULL; break; } if (lf > 1) { /* eoh */ err = 0; goto out; } comsep = false; name.p = NULL; cv = NULL; lf = 0; } if (!name.p) { name.p = p; name.l = 0; ws = 0; } if (!name.l) { if (*p != ':') { ws = 0; break; } name.l = MAX((int)(p - name.p - ws), 0); if (!name.l) { err = EBADMSG; goto out; } id = hdr_hash(&name); comsep = hdr_comma_separated(id); break; } if (!cv) { quote = false; cv = p; } if (*p == '"') quote = !quote; ws = 0; break; } } err = ENODATA; out: if (err) mem_deref(msg); else { *msgp = msg; mb->pos = mb->end - l; } return err; }