Skip to content

Instantly share code, notes, and snippets.

@dgwynne
Created February 7, 2012 01:30
Show Gist options
  • Save dgwynne/1756453 to your computer and use it in GitHub Desktop.
Save dgwynne/1756453 to your computer and use it in GitHub Desktop.
tests for joyent/http-parser http_parser_parse_url()
/*
* Copyright (c) 2012 David Gwynne <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "http_parser.h"
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h> /* rand */
#include <string.h>
#include <stdarg.h>
struct url_test {
struct http_parser_url u;
char *name;
char *url;
int is_connect;
int rv;
};
#if 0
/* for reference... */
enum http_parser_url_fields
{ UF_SCHEMA = 0
, UF_HOST = 1
, UF_PORT = 2
, UF_PATH = 3
, UF_QUERY = 4
, UF_FRAGMENT = 5
, UF_MAX = 6
};
struct http_parser_url {
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
uint16_t port; /* Converted UF_PORT string */
struct {
uint16_t off; /* Offset into buffer in which field starts */
uint16_t len; /* Length of run in buffer */
} field_data[UF_MAX];
};
#endif
struct url_test tests[] = { {
{
(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH),
0,
{
{ 0, 4 }, /* UF_SCHEMA */
{ 7, 8 }, /* UF_HOST */
{ 0, 0 }, /* UF_PORT */
{ 15, 1 }, /* UF_PATH */
{ 0, 0 }, /* UF_QUERY */
{ 0, 0 } /* UF_FRAGMENT */
}
},
"proxy request",
"http://hostname/", 0,
0
}, {
{
(1 << UF_HOST) | (1 << UF_PORT),
8080,
{
{ 0, 0 }, /* UF_SCHEMA */
{ 0, 8 }, /* UF_HOST */
{ 9, 4 }, /* UF_PORT */
{ 0, 0 }, /* UF_PATH */
{ 0, 0 }, /* UF_QUERY */
{ 0, 0 } /* UF_FRAGMENT */
}
},
"connect url",
"hostname:8080", 1,
0
}, {
{
(1 << UF_PATH),
0,
{
{ 0, 0 }, /* UF_SCHEMA */
{ 0, 0 }, /* UF_HOST */
{ 0, 0 }, /* UF_PORT */
{ 0, 5 }, /* UF_PATH */
{ 0, 0 }, /* UF_QUERY */
{ 0, 0 } /* UF_FRAGMENT */
}
},
"plain path",
"/test", 0,
0
} };
void
dump_url(const char *url, struct http_parser_url *u)
{
char part[512];
int i;
printf("\tfields: 0x%x, port: %u\n", u->field_set, u->port);
for (i = 0; i < UF_MAX; i++) {
if (u->field_set & (1 << i)) {
memcpy(part, url + u->field_data[i].off,
u->field_data[i].len);
part[u->field_data[i].len] = '\0';
} else
part[0] = '\0';
printf("\tfield %u: off: %u len: %u part: \"%s\"\n", i,
u->field_data[i].off, u->field_data[i].len, part);
}
}
int
main(void) //int argc, char *argv[])
{
struct http_parser_url u;
struct url_test *test;
u_int i;
int rv;
for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) {
test = &tests[i];
memset(&u, 0, sizeof(u));
rv = http_parser_parse_url(test->url, strlen(test->url),
test->is_connect, &u);
if (test->rv == 0) {
if (rv != 0) {
printf("\"%s\" failed, unexpected rv %d\n",
test->name, rv);
exit(1);
}
if (memcmp(&u, &test->u, sizeof(u)) != 0) {
printf("\"%s\" failed, bad u\n", test->name);
printf("target u:\n");
dump_url(test->url, &test->u);
printf("result u:\n");
dump_url(test->url, &u);
exit(1);
}
}
}
return (0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment