Feersum

 view release on metacpan or  search on metacpan

Feersum.xs  view on Meta::CPAN

        return ch - 'A' + 10;
    else if ('a' <= ch && ch <= 'f')
        return ch - 'a' + 10;
    return -1;
}

static void
uri_decode_sv (SV *sv)
{
    STRLEN len;
    char *ptr, *end, *decoded;

    ptr = SvPV(sv, len);
    end = SvEND(sv);

    // quickly scan for % so we can ignore decoding that portion of the string
    while (ptr < end) {
        if (unlikely(*ptr == '%')) goto needs_decode;
        ptr++;
    }
    return;

needs_decode:

    // Up until ptr have been "decoded" already by virtue of those chars not
    // being encoded.
    decoded = ptr;

    for (; ptr < end; ptr++) {
        if (unlikely(*ptr == '%') && likely(end - ptr >= 2)) {
            int c1 = hex_decode(ptr[1]);
            int c2 = hex_decode(ptr[2]);
            if (likely(c1 != -1 && c2 != -1)) {
                *decoded++ = (c1 << 4) + c2;
                ptr += 2;
                continue;
            }
        }
        *decoded++ = *ptr;
    }

    *decoded = '\0'; // play nice with C

    ptr = SvPV_nolen(sv);
    SvCUR_set(sv, decoded-ptr);
}

INLINE_UNLESS_DEBUG void
feersum_set_remote_info(pTHX_ struct feer_req *r, struct sockaddr *sa)
{
    switch (sa->sa_family) {
        case AF_INET:
            r->addr = newSV(INET_ADDRSTRLEN);
            SvCUR_set(r->addr, INET_ADDRSTRLEN);
            struct sockaddr_in *in = (struct sockaddr_in *)sa;

lib/Feersum/Connection.pm  view on Meta::CPAN

=item C<< my $env = $req->uri >>

full request uri (psgi REQUEST_URI)

=item C<< my $env = $req->protocol >>

protocol (psgi SERVER_PROTOCOL)

=item C<< my $env = $req->path >>

percent decoded request path (psgi PATH_INFO)

=item C<< my $env = $req->query >>

request query (psgi QUERY_STRING)

=item C<< my $env = $req->content_length >>

body content lenght (psgi CONTENT_LENGTH)

=item C<< my $env = $req->input >>

picohttpparser-git/picohttpparser.h  view on Meta::CPAN

    size_t bytes_left_in_chunk; /* number of bytes left in current chunk */
    char consume_trailer;       /* if trailing headers should be consumed */
    char _hex_count;
    char _state;
    uint64_t _total_read;
    uint64_t _total_overhead;
};

/* the function rewrites the buffer given as (buf, bufsz) removing the chunked-
 * encoding headers.  When the function returns without an error, bufsz is
 * updated to the length of the decoded data available.  Applications should
 * repeatedly call the function while it returns -2 (incomplete) every time
 * supplying newly arrived data.  If the end of the chunked-encoded data is
 * found, the function returns a non-negative number indicating the number of
 * octets left undecoded, that starts from the offset returned by `*bufsz`.
 * Returns -1 on error.
 */
ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_t *bufsz);

/* returns if the chunked decoder is in middle of chunked data */
int phr_decode_chunked_is_in_data(struct phr_chunked_decoder *decoder);

#ifdef __cplusplus
}
#endif

picohttpparser-git/test.c  view on Meta::CPAN

    ok(bufis(headers[1].name, headers[1].name_len, "Cookie"));
    ok(bufis(headers[1].value, headers[1].value_len, ""));

    PARSE("Host: example.com\r\nCookie: \r\n\r", 0, -2, "partial");

    PARSE("Host: e\7fample.com\r\nCookie: \r\n\r", 0, -1, "error");

#undef PARSE
}

static void test_chunked_at_once(int line, int consume_trailer, const char *encoded, const char *decoded, ssize_t expected)
{
    struct phr_chunked_decoder dec = {0};
    char *buf;
    size_t bufsz;
    ssize_t ret;

    dec.consume_trailer = consume_trailer;

    note("testing at-once, source at line %d", line);

    buf = strdup(encoded);
    bufsz = strlen(buf);

    ret = phr_decode_chunked(&dec, buf, &bufsz);

    ok(ret == expected);
    ok(bufsz == strlen(decoded));
    ok(bufis(buf, bufsz, decoded));
    if (expected >= 0) {
        if (ret == expected)
            ok(bufis(buf + bufsz, ret, encoded + strlen(encoded) - ret));
        else
            ok(0);
    }

    free(buf);
}

static void test_chunked_per_byte(int line, int consume_trailer, const char *encoded, const char *decoded, ssize_t expected)
{
    struct phr_chunked_decoder dec = {0};
    char *buf = malloc(strlen(encoded) + 1);
    size_t bytes_to_consume = strlen(encoded) - (expected >= 0 ? expected : 0), bytes_ready = 0, bufsz, i;
    ssize_t ret;

    dec.consume_trailer = consume_trailer;

    note("testing per-byte, source at line %d", line);

picohttpparser-git/test.c  view on Meta::CPAN

            ok(0);
            goto cleanup;
        }
        bytes_ready += bufsz;
    }
    strcpy(buf + bytes_ready, encoded + bytes_to_consume - 1);
    bufsz = strlen(buf + bytes_ready);
    ret = phr_decode_chunked(&dec, buf + bytes_ready, &bufsz);
    ok(ret == expected);
    bytes_ready += bufsz;
    ok(bytes_ready == strlen(decoded));
    ok(bufis(buf, bytes_ready, decoded));
    if (expected >= 0) {
        if (ret == expected)
            ok(bufis(buf + bytes_ready, expected, encoded + bytes_to_consume));
        else
            ok(0);
    }

cleanup:
    free(buf);
}

t/03-env-hash.t  view on Meta::CPAN

    is $env->{REQUEST_METHOD}, ($tn == 5 ? 'POST' : 'GET'), "got req method";
    like $env->{HTTP_USER_AGENT}, qr/FeersumSimpleClient/, "got UA";

    ok !exists $env->{HTTP_CONTENT_LENGTH}, "C-L is a promoted header";
    ok !exists $env->{HTTP_CONTENT_TYPE}, "C-T is a promoted header";

    if ($tn == 1) {
        is $env->{CONTENT_LENGTH}, 0, "got zero C-L";
        like $env->{HTTP_REFERER}, qr/wrong/, "got the Referer";
        is $env->{QUERY_STRING}, 'blar', "got query string";
        is $env->{PATH_INFO}, '/what is wrong?', "got decoded path info string";
        is $env->{REQUEST_URI}, '/what%20is%20wrong%3f?blar', "got full URI string";
    }
    elsif ($tn == 2) {
        is $env->{CONTENT_LENGTH}, 0, "got zero C-L";
        like $env->{HTTP_REFERER}, qr/good/, "got a Referer";
        is $env->{QUERY_STRING}, 'dlux=sonice', "got query string";
        is $env->{PATH_INFO}, '/what% is good?%2', "got decoded path info string";
        is $env->{REQUEST_URI}, '/what%%20is%20good%3F%2?dlux=sonice', "got full URI string";
    }
    elsif ($tn == 3) {
        is $env->{CONTENT_LENGTH}, 0, "got zero C-L";
        like $env->{HTTP_REFERER}, qr/ugly/, "got a Referer";
        is $env->{QUERY_STRING}, '', "got query string";
        is $env->{PATH_INFO}, '/no query', "got decoded path info string";
        is $env->{REQUEST_URI}, '/no%20query', "got full URI string";
    }
    elsif ($tn == 4) {
        is $env->{CONTENT_LENGTH}, 0, "got zero C-L";
    }
    elsif ($tn == 5) {
        is $env->{CONTENT_LENGTH}, 9, "got zero C-L";
        is $env->{CONTENT_TYPE}, 'text/plain; charset=US-ASCII',
            "C-T is a promoted header";
    }



( run in 1.458 second using v1.01-cache-2.11-cpan-a9ef4e587e4 )