Feersum
view release on metacpan or search on metacpan
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 )