Exemple #1
0
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, &timestamp, &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, &timestamp, &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");
}
Exemple #5
0
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;
}
Exemple #8
0
 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);
 }
Exemple #9
0
 void add(hdr_histogram* to) {
   hdr_add(to, histogram_);
 }
Exemple #10
0
/**
 * 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;
}
Exemple #11
0
/**
 * 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;
}