33805b | 2000-08-12 | Per Hedbor | | #define NO_PIKE_SHORTHAND
#include "global.h"
#include "config.h"
#include "machine.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <limits.h>
#include "fdlib.h"
#include "stralloc.h"
#include "pike_macros.h"
#include "machine.h"
#include "object.h"
#include "constants.h"
#include "interpret.h"
#include "svalue.h"
#include "mapping.h"
#include "array.h"
#include "builtin_functions.h"
#include "module_support.h"
#include "backend.h"
#include "threads.h"
#include "operators.h"
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | |
#include "module_magic.h"
|
33805b | 2000-08-12 | Per Hedbor | |
|
525ff5 | 2001-06-21 | Martin Stjernholm | | #define THP ((struct header_buf *)Pike_fp->current_storage)
|
33805b | 2000-08-12 | Per Hedbor | | struct header_buf
{
char headers[8192];
char *pnt;
|
aad584 | 2000-08-12 | Henrik Grubbström (Grubba) | | ptrdiff_t left;
|
a52013 | 2001-02-20 | Per Hedbor | | int slash_n, spc;
|
33805b | 2000-08-12 | Per Hedbor | | };
static void f_hp_feed( INT32 args )
{
struct pike_string *str = Pike_sp[-1].u.string;
|
a52013 | 2001-02-20 | Per Hedbor | | struct header_buf *hp = THP;
int tot_slash_n=hp->slash_n, slash_n = 0, spc = hp->spc, cnt, num;
|
33805b | 2000-08-12 | Per Hedbor | | char *pp,*ep;
struct svalue *tmp;
struct mapping *headers;
|
aad584 | 2000-08-12 | Henrik Grubbström (Grubba) | | ptrdiff_t os=0, i, j, l;
|
33805b | 2000-08-12 | Per Hedbor | | unsigned char *in;
|
a52013 | 2001-02-20 | Per Hedbor | |
|
33805b | 2000-08-12 | Per Hedbor | | if( Pike_sp[-1].type != PIKE_T_STRING )
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Wrong type of argument to feed()\n");
|
33805b | 2000-08-12 | Per Hedbor | |
|
a52013 | 2001-02-20 | Per Hedbor | | if( str->len >= hp->left )
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Too many headers\n");
|
33805b | 2000-08-12 | Per Hedbor | |
|
a52013 | 2001-02-20 | Per Hedbor | | MEMCPY( hp->pnt, str->str, str->len );
|
40ca33 | 2001-02-01 | Per Hedbor | | pop_n_elems( args );
|
a52013 | 2001-02-20 | Per Hedbor | | for( ep=(hp->pnt+str->len),pp=MAXIMUM(hp->headers,hp->pnt-3);
|
40ca33 | 2001-02-01 | Per Hedbor | | pp<ep && slash_n<2; pp++ )
if( *pp == ' ' ) spc++;
else if( *pp == '\n' ) slash_n++, tot_slash_n++;
else if( *pp != '\r' ) slash_n=0;
|
33805b | 2000-08-12 | Per Hedbor | |
|
a52013 | 2001-02-20 | Per Hedbor | | hp->slash_n = tot_slash_n;
hp->spc = spc;
hp->left -= str->len;
hp->pnt += str->len;
hp->pnt[0] = 0;
|
40ca33 | 2001-02-01 | Per Hedbor | |
|
33805b | 2000-08-12 | Per Hedbor | | if( slash_n != 2 )
{
|
40ca33 | 2001-02-01 | Per Hedbor | |
if( (spc < 2) && tot_slash_n )
{
push_text( "" );
|
a52013 | 2001-02-20 | Per Hedbor | | push_text( hp->headers );
|
40ca33 | 2001-02-01 | Per Hedbor | | f_aggregate_mapping( 0 );
f_aggregate( 3 );
return;
}
|
33805b | 2000-08-12 | Per Hedbor | | push_int( 0 );
return;
}
|
a52013 | 2001-02-20 | Per Hedbor | | push_string( make_shared_binary_string( pp, hp->pnt - pp ) );
|
33805b | 2000-08-12 | Per Hedbor | | headers = allocate_mapping( 5 );
|
a52013 | 2001-02-20 | Per Hedbor | | in = hp->headers;
l = pp - hp->headers;
|
4a8449 | 2000-08-13 | David Hedbor | |
|
33805b | 2000-08-12 | Per Hedbor | |
for( i = 0; i < l; i++ )
if( in[i] == '\n' )
break;
if( in[i-1] != '\r' )
i++;
push_string( make_shared_binary_string( in, i-1 ) );
in += i; l -= i;
if( *in == '\n' ) (in++),(l--);
for(i = 0; i < l; i++)
{
|
cee3ed | 2000-08-14 | Per Hedbor | | if(in[i] > 64 && in[i] < 91) in[i]+=32;
|
4a8449 | 2000-08-13 | David Hedbor | | else if( in[i] == ':' )
|
33805b | 2000-08-12 | Per Hedbor | | {
push_string(make_shared_binary_string((char*)in+os,i-os));
os = i+1;
while(in[os]==' ') os++;
for(j=os;j<l;j++)
if( in[j] == '\n' || in[j]=='\r')
break;
|
40ca33 | 2001-02-01 | Per Hedbor | |
|
33805b | 2000-08-12 | Per Hedbor | | push_string(make_shared_binary_string((char*)in+os,j-os));
if((tmp = low_mapping_lookup(headers, Pike_sp-2)))
{
f_aggregate( 1 );
if( tmp->type == PIKE_T_ARRAY )
{
tmp->u.array->refs++;
push_array(tmp->u.array);
map_delete(headers, Pike_sp-3);
f_add(2);
} else {
tmp->u.string->refs++;
push_string(tmp->u.string);
f_aggregate(1);
map_delete(headers, Pike_sp-3);
f_add(2);
}
}
mapping_insert(headers, Pike_sp-2, Pike_sp-1);
pop_n_elems(2);
if( in[j+1] == '\n' ) j++;
|
4a8449 | 2000-08-13 | David Hedbor | | os = j+1;
i = j;
|
33805b | 2000-08-12 | Per Hedbor | | }
}
push_mapping( headers );
|
40ca33 | 2001-02-01 | Per Hedbor | | f_aggregate( 3 );
|
33805b | 2000-08-12 | Per Hedbor | | }
static void f_hp_create( INT32 args )
{
THP->pnt = THP->headers;
THP->left = 8192;
|
a52013 | 2001-02-20 | Per Hedbor | | THP->spc = THP->slash_n = 0;
pop_n_elems(args);
push_int(0);
|
33805b | 2000-08-12 | Per Hedbor | | }
static void f_make_http_headers( INT32 args )
{
int total_len = 0, e;
char *pnt;
struct mapping *m;
struct keypair *k;
struct pike_string *res;
if( Pike_sp[-1].type != PIKE_T_MAPPING )
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Wrong argument type to make_http_headers(mapping heads)\n");
|
33805b | 2000-08-12 | Per Hedbor | |
m = Pike_sp[-1].u.mapping;
NEW_MAPPING_LOOP( m->data )
{
if( k->ind.type != PIKE_T_STRING || k->ind.u.string->size_shift )
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Wrong argument type to make_http_headers("
|
33805b | 2000-08-12 | Per Hedbor | | "mapping(string(8bit):string(8bit)|array(string(8bit))) heads)\n");
if( k->val.type == PIKE_T_STRING )
total_len += k->val.u.string->len + 2 + k->ind.u.string->len + 2;
else if( k->val.type == PIKE_T_ARRAY )
{
struct array *a = k->val.u.array;
|
aad584 | 2000-08-12 | Henrik Grubbström (Grubba) | | ptrdiff_t i, kl = k->ind.u.string->len + 2 ;
|
33805b | 2000-08-12 | Per Hedbor | | for( i = 0; i<a->size; i++ )
if( a->item[i].type != PIKE_T_STRING||a->item[i].u.string->size_shift )
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Wrong argument type to make_http_headers("
|
33805b | 2000-08-12 | Per Hedbor | | "mapping(string(8bit):string(8bit)|"
"array(string(8bit))) heads)\n");
else
total_len += kl + a->item[i].u.string->len + 2;
} else
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Wrong argument type to make_http_headers("
|
33805b | 2000-08-12 | Per Hedbor | | "mapping(string(8bit):string(8bit)|"
"array(string(8bit))) heads)\n");
}
total_len += 2;
res = begin_shared_string( total_len );
pnt = (char *)res->str;
#define STRADD(X)\
for( l=X.u.string->len,s=X.u.string->str,c=0; c<l; c++ )\
*(pnt++)=*(s++);
NEW_MAPPING_LOOP( m->data )
{
char *s;
|
aad584 | 2000-08-12 | Henrik Grubbström (Grubba) | | ptrdiff_t l, c;
|
33805b | 2000-08-12 | Per Hedbor | | if( k->val.type == PIKE_T_STRING )
{
STRADD( k->ind ); *(pnt++) = ':'; *(pnt++) = ' ';
STRADD( k->val ); *(pnt++) = '\r'; *(pnt++) = '\n';
}
else
{
struct array *a = k->val.u.array;
|
aad584 | 2000-08-12 | Henrik Grubbström (Grubba) | | ptrdiff_t i, kl = k->ind.u.string->len + 2;
|
33805b | 2000-08-12 | Per Hedbor | | for( i = 0; i<a->size; i++ )
{
STRADD( k->ind ); *(pnt++) = ':'; *(pnt++) = ' ';
STRADD( a->item[i] );*(pnt++) = '\r';*(pnt++) = '\n';
}
}
}
*(pnt++) = '\r';
*(pnt++) = '\n';
pop_n_elems( args );
push_string( end_shared_string( res ) );
}
static void f_http_decode_string(INT32 args)
{
int proc;
char *foo,*bar,*end;
struct pike_string *newstr;
if (!args || Pike_sp[-args].type != PIKE_T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Invalid argument to http_decode_string(STRING);\n");
|
33805b | 2000-08-12 | Per Hedbor | |
foo=bar=Pike_sp[-args].u.string->str;
end=foo+Pike_sp[-args].u.string->len;
for (proc=0; foo<end; ) if (*foo=='%') { proc++; foo+=3; } else foo++;
if (!proc) { pop_n_elems(args-1); return; }
newstr=begin_shared_string((foo-bar)-proc*2);
foo=newstr->str;
for (proc=0; bar<end; foo++)
if (*bar=='%')
{
if (bar<end-2)
*foo=(((bar[1]<'A')?(bar[1]&15):((bar[1]+9)&15))<<4)|
((bar[2]<'A')?(bar[2]&15):((bar[2]+9)&15));
else
*foo=0;
bar+=3;
}
else { *foo=*(bar++); }
pop_n_elems(args);
push_string(end_shared_string(newstr));
}
|
e99537 | 2001-06-30 | Per Hedbor | | static void f_html_encode_string( INT32 args )
{
struct pike_string *str;
int newlen;
if( args != 1 )
Pike_error("Wrong number of arguments to html_encode_string\n" );
if( Pike_sp[-args].type != PIKE_T_STRING )
{
struct pike_string *s;
void o_cast(struct pike_string *type, INT32 run_time_type);
MAKE_CONSTANT_SHARED_STRING( s, tString );
o_cast(s, PIKE_T_STRING);
}
str = Pike_sp[-1].u.string;
newlen = str->len;
#define COUNT(T) { \
T *s = (T *)str->str; \
int i; \
for( i = 0; i<str->len; i++ ) \
switch( s[i] ) \
{ \
case 0: /* � */ \
case '<': /* < */ \
case '>': newlen+=3; break;/* > */ \
case '&': /* & */ \
case '"': /* " */ \
case '\'': newlen+=4;break;/* ' */ \
} \
}
#define ADD(X) if(sizeof(X)-sizeof("")==4) ADD4(X); else ADD5(X)
#define ADD4(X) ((d[0] = X[0]), (d[1] = X[1]), (d[2] = X[2]), (d[3] = X[3]),\
(d+=3))
#define ADD5(X) ((d[0] = X[0]), (d[1] = X[1]), (d[2] = X[2]), (d[3] = X[3]),\
(d[4] = X[4]), (d+=4))
#define REPLACE(T) { \
T *s = (T *)str->str; \
T *d = (T *)res->str; \
int i; \
for( i = 0; i<str->len; i++,s++,d++ ) \
switch( *s ) \
{ \
case 0: ADD("�"); break; \
case '&': ADD("&"); break; \
case '<': ADD("<"); break; \
case '>': ADD(">"); break; \
case '"': ADD("""); break; \
case '\'':ADD("'"); break; \
default: *d = *s; break; \
} \
} \
switch( str->size_shift )
{
case 0: COUNT(unsigned char); break;
case 1: COUNT(unsigned short); break;
case 2: COUNT(int); break;
}
if( newlen == str->len )
return;
{
struct pike_string *res = begin_wide_shared_string(newlen,str->size_shift);
switch( str->size_shift )
{
case 0: REPLACE(unsigned char); break;
case 1: REPLACE(unsigned short); break;
case 2: REPLACE(int); break;
}
pop_stack();
push_string( low_end_shared_string( res ) );
}
}
|
33805b | 2000-08-12 | Per Hedbor | | void pike_module_init()
{
pike_add_function("make_http_headers", f_make_http_headers,
"function(mapping(string:string|array(string)):string)", 0 );
pike_add_function("http_decode_string", f_http_decode_string,
"function(string:string)", 0 );
|
e99537 | 2001-06-30 | Per Hedbor | | pike_add_function("html_encode_string", f_html_encode_string,
"function(mixed:string)", 0 );
|
33805b | 2000-08-12 | Per Hedbor | | start_new_program();
ADD_STORAGE( struct header_buf );
pike_add_function( "feed", f_hp_feed, "function(string:array(string|mapping))",0 );
|
a52013 | 2001-02-20 | Per Hedbor | | pike_add_function( "create", f_hp_create, "function(:void)", ID_STATIC );
|
33805b | 2000-08-12 | Per Hedbor | | end_class( "HeaderParser", 0 );
}
void pike_module_exit()
{
}
|