From 33805b2aa3b705b04c1b9f5f619eda24c2bb8d62 Mon Sep 17 00:00:00 2001 From: Per Hedbor <ph@opera.com> Date: Sat, 12 Aug 2000 08:18:22 +0200 Subject: [PATCH] New module for roxen specific stuff Rev: src/modules/_Roxen/.cvsignore:1.1 Rev: src/modules/_Roxen/Makefile.in:1.1 Rev: src/modules/_Roxen/acconfig.h:1.1 Rev: src/modules/_Roxen/configure.in:1.1 Rev: src/modules/_Roxen/roxen.c:1.1 --- .gitattributes | 2 + src/modules/_Roxen/.cvsignore | 15 ++ src/modules/_Roxen/.gitignore | 15 ++ src/modules/_Roxen/Makefile.in | 11 ++ src/modules/_Roxen/acconfig.h | 0 src/modules/_Roxen/configure.in | 6 + src/modules/_Roxen/roxen.c | 271 ++++++++++++++++++++++++++++++++ 7 files changed, 320 insertions(+) create mode 100644 src/modules/_Roxen/.cvsignore create mode 100644 src/modules/_Roxen/.gitignore create mode 100644 src/modules/_Roxen/Makefile.in create mode 100644 src/modules/_Roxen/acconfig.h create mode 100644 src/modules/_Roxen/configure.in create mode 100644 src/modules/_Roxen/roxen.c diff --git a/.gitattributes b/.gitattributes index fb3c607fc0..c7abbe7f33 100644 --- a/.gitattributes +++ b/.gitattributes @@ -449,6 +449,8 @@ testfont binary /src/modules/_Image_XFace/configure.in foreign_ident /src/modules/_Image_XFace/image_xface.c foreign_ident /src/modules/_Image_XFace/testsuite.in foreign_ident +/src/modules/_Roxen/Makefile.in foreign_ident +/src/modules/_Roxen/configure.in foreign_ident /src/modules/_math/Makefile.in foreign_ident /src/modules/_math/configure.in foreign_ident /src/modules/_math/math.c foreign_ident diff --git a/src/modules/_Roxen/.cvsignore b/src/modules/_Roxen/.cvsignore new file mode 100644 index 0000000000..d45d29b97f --- /dev/null +++ b/src/modules/_Roxen/.cvsignore @@ -0,0 +1,15 @@ +.pure +Makefile +config.h +config.h.in +config.log +config.status +configure +dependencies +linker_options +make_variables +modlist_headers +modlist_segment +module_testsuite +stamp-h +stamp-h.in diff --git a/src/modules/_Roxen/.gitignore b/src/modules/_Roxen/.gitignore new file mode 100644 index 0000000000..14854305fb --- /dev/null +++ b/src/modules/_Roxen/.gitignore @@ -0,0 +1,15 @@ +/.pure +/Makefile +/config.h +/config.h.in +/config.log +/config.status +/configure +/dependencies +/linker_options +/make_variables +/modlist_headers +/modlist_segment +/module_testsuite +/stamp-h +/stamp-h.in diff --git a/src/modules/_Roxen/Makefile.in b/src/modules/_Roxen/Makefile.in new file mode 100644 index 0000000000..e9832b7870 --- /dev/null +++ b/src/modules/_Roxen/Makefile.in @@ -0,0 +1,11 @@ +# $Id: Makefile.in,v 1.1 2000/08/12 06:18:22 per Exp $ +@make_variables@ +VPATH=@srcdir@:@srcdir@/../..:../.. +OBJS=roxen.o +MODULE_LDFLAGS=@LDFLAGS@ +# streamed_parser.o + +CONFIG_HEADERS=@CONFIG_HEADERS@ + +@dynamic_module_makefile@ +@dependencies@ diff --git a/src/modules/_Roxen/acconfig.h b/src/modules/_Roxen/acconfig.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/modules/_Roxen/configure.in b/src/modules/_Roxen/configure.in new file mode 100644 index 0000000000..2c626de821 --- /dev/null +++ b/src/modules/_Roxen/configure.in @@ -0,0 +1,6 @@ +# $Id: configure.in,v 1.1 2000/08/12 06:18:22 per Exp $ +AC_INIT(roxen.c) +AC_CONFIG_HEADER(config.h) +AC_MODULE_INIT() + +AC_OUTPUT(Makefile,echo FOO >stamp-h ) diff --git a/src/modules/_Roxen/roxen.c b/src/modules/_Roxen/roxen.c new file mode 100644 index 0000000000..5e6a76db2c --- /dev/null +++ b/src/modules/_Roxen/roxen.c @@ -0,0 +1,271 @@ +#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" + + +/**** CLASS HeaderParser */ + +#define THP ((struct header_buf *)Pike_fp->current_object->storage) +struct header_buf +{ + char headers[8192]; + char *pnt; + int left; +}; + +static void f_hp_feed( INT32 args ) +{ + struct pike_string *str = Pike_sp[-1].u.string; + int slash_n = 0, cnt, num; + char *pp,*ep; + struct svalue *tmp; + struct mapping *headers; + int os=0,i,j,l; + unsigned char *in; + + if( Pike_sp[-1].type != PIKE_T_STRING ) + error("Wrong type of argument to feed()\n"); + + if( str->len >= THP->left ) + error("Too many headers\n"); + + MEMCPY( THP->pnt, str->str, str->len ); + + for( ep=(THP->pnt+str->len), + pp=MAXIMUM(THP->headers,THP->pnt-3); + pp<ep && slash_n<2; + pp++ ) + if( *pp == '\n' ) + slash_n++; + else if( *pp != '\r' ) + slash_n=0; + + THP->left -= str->len; + THP->pnt += str->len; + THP->pnt[0] = 0; + pop_n_elems( args ); + if( slash_n != 2 ) + { + /* check for HTTP/0.9? */ + push_int( 0 ); + return; + } + + push_text( pp ); // leftovers + headers = allocate_mapping( 5 ); + in = THP->headers; + l = pp - THP->headers; + /* find first line here */ + 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++) + { + if( in[i] == ':' ) + { + /* in[os..i-1] == the header */ + for(j=os;j<i;j++) if(in[j] > 63 && in[j] < 91) in[j]+=32; + 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; + } + 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++; + os = i = j+1; + } + } + push_mapping( headers ); + f_aggregate( 3 ); /* data, headers */ +} + +static void f_hp_create( INT32 args ) +{ + THP->pnt = THP->headers; + THP->left = 8192; +} +/**** END CLASS HeaderParser */ + +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 ) + error("Wrong argument type to make_http_headers(mapping heads)\n"); + + m = Pike_sp[-1].u.mapping; + /* loop to check len */ + NEW_MAPPING_LOOP( m->data ) + { + if( k->ind.type != PIKE_T_STRING || k->ind.u.string->size_shift ) + error("Wrong argument type to make_http_headers(" + "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; + int i, kl = k->ind.u.string->len + 2 ; + for( i = 0; i<a->size; i++ ) + if( a->item[i].type != PIKE_T_STRING||a->item[i].u.string->size_shift ) + error("Wrong argument type to make_http_headers(" + "mapping(string(8bit):string(8bit)|" + "array(string(8bit))) heads)\n"); + else + total_len += kl + a->item[i].u.string->len + 2; + } else + error("Wrong argument type to make_http_headers(" + "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; + int l, c; + 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; + int i, kl = k->ind.u.string->len + 2; + 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) + error("Invalid argument to http_decode_string(STRING);\n"); + + foo=bar=Pike_sp[-args].u.string->str; + end=foo+Pike_sp[-args].u.string->len; + + /* count '%' characters */ + for (proc=0; foo<end; ) if (*foo=='%') { proc++; foo+=3; } else foo++; + + if (!proc) { pop_n_elems(args-1); return; } + + /* new string len is (foo-bar)-proc*2 */ + 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)); +} + + +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 ); + + start_new_program(); + ADD_STORAGE( struct header_buf ); + pike_add_function( "feed", f_hp_feed, "function(string:array(string|mapping))",0 ); + pike_add_function( "create", f_hp_create, "function(void:void)", 0 ); + end_class( "HeaderParser", 0 ); +} + +void pike_module_exit() +{ +} -- GitLab