|
HTTP Parser and message builder / objects in plain C Snapshot
|
#include "uri.h"#include "charclass.h"#include <string.h>#include <arpa/inet.h>#include "sutils.h"Go to the source code of this file.
Classes | |
| struct | tagURIPARSECTX |
Typedefs | |
| typedef struct tagURIPARSECTX | URIPARSECTX |
Functions | |
| M_INLINE int | is_mark (int8_t ch) |
| M_INLINE int | is_unreserved (int8_t ch) |
| M_INLINE int | is_reserved (int8_t ch) |
| char * | ctx_copy_string_raw (URIPARSECTX *ctx, char *start, char *end) |
| void | ctx_add_escaped_char (URIPARSECTX *ctx, char ch, int char_encoded) |
| char * | ctx_finish_escaped_string (URIPARSECTX *ctx) |
| void | ctx_undo_escaped_string (URIPARSECTX *ctx) |
| M_INLINE int | parse_escaped (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_uric (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_uric_sequence (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_pchar (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_pchar_sequence (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_segment (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_path_segments (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_ipv4_address (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_userinfo (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_domainlabel (char *ptr, char **next) |
| M_INLINE int | parse_hostname (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_ipv6_address (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_hostport (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_server (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_authority (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_scheme (URIPARSECTX *ctx, char *line, char **next) |
| M_INLINE int | parse_abs_path (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_net_path (URIPARSECTX *ctx, char *ptr, char **next) |
| M_INLINE int | parse_uric_no_slash (URIPARSECTX *ctx, char *ptr, char **next) |
| int | parse_opaque_part (URIPARSECTX *ctx, char *ptr, char **next) |
| int | parse_hier_part (URIPARSECTX *ctx, char *ptr, char **next, int parse_opaque) |
| int | URI_parse (URI *url, char *line) |
| typedef struct tagURIPARSECTX URIPARSECTX |
| void ctx_add_escaped_char | ( | URIPARSECTX * | ctx, |
| char | ch, | ||
| int | char_encoded | ||
| ) |
Definition at line 46 of file uri.c.
{
M_UNUSED( char_encoded );
* ctx->cdata_pos = ch;
* ( ctx->cdata_is_escaped_start + ( ctx->cdata_pos - ctx->cdata_pos_off ) ) = (char) char_encoded;
++ ctx->cdata_pos;
//ctx->cdata_pos - ctx->cdata_pos_start
}
| char* ctx_copy_string_raw | ( | URIPARSECTX * | ctx, |
| char * | start, | ||
| char * | end | ||
| ) |
Definition at line 35 of file uri.c.
{
char *ret = ctx->cdata_raw_pos;
strncpy( ctx->cdata_raw_pos, start, end - start );
ctx->cdata_raw_pos += end - start;
* ctx->cdata_raw_pos ++ ='\0';
return ret;
}
| char* ctx_finish_escaped_string | ( | URIPARSECTX * | ctx | ) |
Definition at line 58 of file uri.c.
{
char *ret = ctx->cdata_pos_start;
* ctx->cdata_pos ++ = '\0';
ctx->cdata_pos_start = ctx->cdata_pos;
return ret;
}
| void ctx_undo_escaped_string | ( | URIPARSECTX * | ctx | ) |
Definition at line 68 of file uri.c.
{
ctx->cdata_pos = ctx->cdata_pos_start;
}
| M_INLINE int is_mark | ( | int8_t | ch | ) |
| M_INLINE int is_reserved | ( | int8_t | ch | ) |
| M_INLINE int is_unreserved | ( | int8_t | ch | ) |
Definition at line 15 of file uri.c.
{
return is_alphanum(ch) || is_mark(ch);
}
| M_INLINE int parse_abs_path | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 407 of file uri.c.
{
char *start;
start = ptr;
if (*ptr == '/') {
ctx_add_escaped_char( ctx, '/', 0 );
*next = ++ptr;
}
if (parse_path_segments( ctx, ptr, next ) < 0) {
return -1;
}
if (*next != ptr) {
ctx->rep->path_raw = ctx_copy_string_raw(ctx, start, *next );
ctx->rep->path = ctx_finish_escaped_string(ctx);
}
return 0;
}
| M_INLINE int parse_authority | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 377 of file uri.c.
{
if (!parse_server( ctx, ptr, next)) {
return 0;
}
return -1;
}
| M_INLINE int parse_domainlabel | ( | char * | ptr, |
| char ** | next | ||
| ) |
Definition at line 241 of file uri.c.
{
if (!is_alphanum( *ptr) ) {
return -1;
}
for(ptr += 1; is_alphanum( *ptr ) || *ptr == '-'; ++ptr);
if (!is_alphanum( *(ptr-1) ) ) {
return -1;
}
*next = ptr;
return 0;
}
| M_INLINE int parse_escaped | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 75 of file uri.c.
{
int high,low;
int unescaped_char;
if (*ptr != '%') {
return 1;
}
high = is_hex_ext( *(ptr + 1) );
if (! high ) {
return -1;
}
low = is_hex_ext( *(ptr + 2) );
if (! low ) {
return -1;
}
unescaped_char = (high << 4) | low;
if (! (unescaped_char >=0 && unescaped_char <= 0x1F) ) {
ctx_add_escaped_char( ctx, unescaped_char, 1 );
}
*next = ptr + 3;
return 0;
}
| int parse_hier_part | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next, | ||
| int | parse_opaque | ||
| ) |
Definition at line 472 of file uri.c.
{
char *start;
if (ptr[0] == '/') {
if (ptr[1] == '/') {
if (parse_net_path( ctx, ptr + 2, next )) {
return -1;
}
} else {
//ctx_add_escaped_char( ctx, '/', 0 );
if (parse_abs_path( ctx, ptr, next )) {
return -1;
}
}
} else {
if (parse_opaque) {
return parse_opaque_part( ctx, ptr, next );
}
return -1;
}
ptr = *next;
if (*ptr == '?') {
ptr ++;
start = ptr;
if ( parse_uric_sequence( ctx, ptr, next ) == -1 ) {
return -1;
}
ptr = *next;
ctx->rep->query_raw = ctx_copy_string_raw(ctx, start, ptr );
ctx->rep->query = ctx_finish_escaped_string(ctx);
}
if ( *ptr != '#' ) {
return 0;
}
++ ptr;
start = ptr;
if (parse_uric_sequence( ctx, ptr, next ) == -1) {
return -1;
}
ptr = *next;
ctx->rep->fragment_raw = ctx_copy_string_raw(ctx, start, ptr );
ctx->rep->fragment = ctx_finish_escaped_string(ctx);
return 0;
}
| M_INLINE int parse_hostname | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 259 of file uri.c.
{
char *last_component;
char *start = ptr;
for ( ; ; ) {
last_component = ptr;
if (*ptr == '/') {
goto ok;
}
if (parse_domainlabel( ptr, next) < 0) {
return -1;
}
ptr = *next;
if (*ptr != '.') {
break;
}
++ptr;
}
// check that last component is top label
if (is_digit( * last_component ) ) {
return -1;
}
ok:
*next = ptr;
ctx->rep->flags |= URI_FLAGS_HOST_HOSTNAME;
ctx->rep->host = ctx_copy_string_raw(ctx, start, ptr );
return 0;
}
| M_INLINE int parse_hostport | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 331 of file uri.c.
{
char *start;
if ( ! parse_ipv4_address( ctx, ptr, next ) ) {
goto pport;
}
if ( ! parse_hostname( ctx, ptr, next) ) {
goto pport;
}
if ( ! parse_ipv6_address( ctx, ptr, next ) ) {
goto pport;
}
return -1;
pport:
ptr = *next;
if (*ptr != ':' ) {
return 0;
}
for( start = ptr = ptr + 1; is_digit( *ptr ); ++ ptr );
*next = ptr;
ctx->rep->port = atoi( start );
return 0;
}
| M_INLINE int parse_ipv4_address | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 184 of file uri.c.
{
int i;
char *start = ptr;
for (i=0; i < 4; i++) {
if (! is_digit(*ptr)) {
return -1;
}
for( ++ ptr; is_digit( *ptr ); ++ptr );
if ( i == 3) {
break;
}
if (*ptr != '.') {
return -1;
}
++ ptr;
}
*next = ptr;
ctx->rep->flags |= URI_FLAGS_HOST_IPv4;
ctx->rep->host = ctx_copy_string_raw(ctx, start, ptr );
return 0;
}
| M_INLINE int parse_ipv6_address | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 294 of file uri.c.
{
struct in6_addr addr;
char *dup, *start;
int rt;
if (*ptr != '[') {
return 1;
}
start = ptr;
for(;*ptr != ']' && *ptr != '\0'; ++ ptr);
if (*ptr != ']') {
return -1;
}
dup = strdup_range( start+1, ptr );
if (!dup) {
return -1;
}
rt = inet_pton( AF_INET6, dup, &addr);
free(dup);
if (rt == 1) {
ctx->rep->flags |= URI_FLAGS_HOST_IPv6;
ctx->rep->host = ctx_copy_string_raw(ctx, start, ptr );
*next = ptr + 1;
return 0;
}
return -1;
}
| M_INLINE int parse_net_path | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 428 of file uri.c.
{
if (! parse_authority( ctx, ptr, next )) {
ptr = *next;
if (*ptr == '/') {
return parse_abs_path( ctx, ptr, next );
}
}
return 0;
}
| int parse_opaque_part | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 453 of file uri.c.
{
char *start = ptr;
int rt;
if ( (rt = parse_uric_no_slash( ctx, ptr, next )) != 0 ) {
return rt;
}
if (parse_uric_sequence( ctx, ptr, next ) < 0) {
return -1;
}
ctx->rep->flags |= URI_FLAGS_IS_OPAQUE;
ctx->rep->opaque_raw = ctx_copy_string_raw(ctx, start, ptr );
ctx->rep->opaque = ctx_finish_escaped_string(ctx);
return 0;
}
| M_INLINE int parse_path_segments | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 168 of file uri.c.
{
if (parse_segment( ctx, ptr, next ) < 0) {
return -1;
}
ptr = *next;
while (*ptr == '/') {
ctx_add_escaped_char( ctx, '/', 0 );
ptr = *next = ptr + 1;
if (parse_segment( ctx, ptr, next ) < 0) {
return -1;
}
ptr = *next;
}
return 0;
}
| M_INLINE int parse_pchar | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 127 of file uri.c.
{
char ch = *ptr;
if (is_unreserved( ch ) || ch == ':' || ch == '@' || ch == '&' || ch == '=' || ch == '+' || ch == '$' || ch == ',') {
ctx_add_escaped_char( ctx, ch, 0 );
*next = ptr + 1;
return 0;
}
return parse_escaped( ctx, ptr, next );
}
| M_INLINE int parse_pchar_sequence | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 139 of file uri.c.
{
int rt;
while( (rt = parse_pchar( ctx, ptr, next )) == 0 ) {
ptr = *next;
}
return 0;
}
| M_INLINE int parse_scheme | ( | URIPARSECTX * | ctx, |
| char * | line, | ||
| char ** | next | ||
| ) |
Definition at line 387 of file uri.c.
{
char *start = line;
if (is_alpha( *line )) {
++line;
while( is_alphanum( *line ) || *line == '+' || *line == '-' || *line == '.') {
++line;
}
if ( *line == ':') {
ctx->rep->flags |= URI_FLAGS_HAS_SCHEME;
ctx->rep->scheme = ctx_copy_string_raw(ctx, start, line );
* next = line + 1;
return 0;
}
}
return -1;
}
| M_INLINE int parse_segment | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 150 of file uri.c.
{
if (parse_pchar_sequence( ctx, ptr, next ) < 0) {
return -1;
}
ptr = *next;
if (*ptr == ';') {
ctx_add_escaped_char( ctx, ';', 0 );
ptr = *next = ptr + 1;
if (parse_pchar_sequence( ctx, ptr, next ) < 0) {
return -1;
}
}
return 0;
}
| M_INLINE int parse_server | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 364 of file uri.c.
{
int rt ;
rt = parse_userinfo(ctx, ptr, next);
if (rt < 0) {
return -1;
}
ptr = *next;
return parse_hostport( ctx, ptr, next);
}
| M_INLINE int parse_uric | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 104 of file uri.c.
{
if (is_reserved( *ptr ) || is_unreserved( *ptr ) ) {
ctx_add_escaped_char( ctx, *ptr, 0 );
*next = ptr +1;
return 0;
}
return parse_escaped( ctx, ptr, next );
}
| M_INLINE int parse_uric_no_slash | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 440 of file uri.c.
{
if (is_unreserved( *ptr ) || *ptr == ';' || *ptr == '?' || *ptr == ':' || *ptr == '@' || *ptr == '&'
|| *ptr == '=' || *ptr == '+' || *ptr == '$' || *ptr == ',') {
ctx_add_escaped_char( ctx, *ptr, 0);
*next = ptr +1;
return 0;
}
return parse_escaped( ctx, ptr, next );
}
| M_INLINE int parse_uric_sequence | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 115 of file uri.c.
{
int rt;
while( (rt = parse_uric( ctx, ptr, next )) == 0 ) {
ptr = *next;
}
return rt;
}
| M_INLINE int parse_userinfo | ( | URIPARSECTX * | ctx, |
| char * | ptr, | ||
| char ** | next | ||
| ) |
Definition at line 213 of file uri.c.
{
char *start = ptr;
int rt;
while ( *ptr != '@' ) {
if ( is_unreserved( *ptr ) || *ptr == ';' || *ptr == ':' || *ptr == '&'
|| *ptr == '=' || *ptr == '+' || *ptr == '$' || *ptr == ',') {
ctx_add_escaped_char( ctx, *ptr, 0 );
++ ptr;
continue;
}
if ((rt = parse_escaped( ctx, ptr, next )) != 0) {
ctx_undo_escaped_string( ctx );
*next = start;
return rt;
}
ptr = *next;
}
ctx->rep->userinfo_raw = ctx_copy_string_raw(ctx, start, ptr );
ctx->rep->userinfo = ctx_finish_escaped_string(ctx);
*next = ptr + 1;
return 0;
}
1.7.4