Beispiel #1
0
static void ParseKeyValueStringArray( DaoProcess *proc, DaoMap *map, char **p )
{
    int nc = 0;
    char buffer[ LOCAL_BUF_SIZE + 1 ];

    DaoValue *vk = (DaoValue*) DaoProcess_NewString( proc, NULL, 0 );
    DaoValue *vv = (DaoValue*) DaoProcess_NewString( proc, NULL, 0 );
    DString *key = DaoString_Get( DaoValue_CastString( vk ) );
    DString *value = DaoString_Get( DaoValue_CastString( vv ) );
    while( *p != NULL ) {
        char *c = *p;
        nc = 0;
        while( *c != '=' ) {
            if( nc >= LOCAL_BUF_SIZE ) {
                buffer[ nc ] = 0;
                DString_AppendChars( key, buffer );
                nc = 0;
            }
            buffer[ nc ] = *c;
            nc ++;
            c ++;
        }
        buffer[ nc ] = 0;
        DString_AppendChars( key, buffer );
        c ++;
        DString_AppendChars( value, c );
        DaoMap_Insert( map, vk, vv );
        DString_Clear( key );
        DString_Clear( value );
        p ++;
    }
}
Beispiel #2
0
static void SYS_EnvVars( DaoProcess *proc, DaoValue *p[], int N )
{
#define LOCAL_BUF_SIZE 256
	DaoMap *map = DaoProcess_PutMap( proc, 0 );
	DaoValue *vk = (DaoValue*) DaoProcess_NewMBString( proc, NULL, 0 );
	DaoValue *vv = (DaoValue*) DaoProcess_NewMBString( proc, NULL, 0 );
	DString *key = DaoString_Get( DaoValue_CastString( vk ) );
	DString *value = DaoString_Get( DaoValue_CastString( vv ) );
	char **envs = environ;
	char buffer[ LOCAL_BUF_SIZE + 1 ];
	int nc = 0;

	while( *envs != NULL ){
		char *c = *envs;
		nc = 0;
		while( *c != '=' ){
			if( nc >= LOCAL_BUF_SIZE ){
				buffer[ nc ] = 0;
				DString_AppendMBS( key, buffer );
				nc = 0;
			}
			buffer[ nc ] = *c;
			nc ++;
			c ++;
		}
		buffer[ nc ] = 0;
		DString_AppendMBS( key, buffer );
		c ++;
		DString_AppendMBS( value, c );
		DaoMap_Insert( map, vk, vv );
		DString_Clear( key );
		DString_Clear( value );
		envs ++;
	}
}
Beispiel #3
0
static void ParseKeyValueString( DaoProcess *proc, DaoMap *mulmap, DaoMap *map, const char *data )
{
    const char *end = data + strlen( data );
    DaoValue *vk = (DaoValue*) DaoProcess_NewString( proc, NULL, 0 );
    DaoValue *vv = (DaoValue*) DaoProcess_NewString( proc, NULL, 0 );
    DString *key = DaoString_Get( DaoValue_CastString( vk ) );
    DString *value = DaoString_Get( DaoValue_CastString( vv ) );
    DString *buffer = key;

    buffer->size = 0;
    for(; data < end; ++data) {
        if( buffer->size >= buffer->bufSize ) DString_Reserve( buffer, 1.5*buffer->size + 8 );
        if( *data == '=' ) {
            buffer->chars[ buffer->size ] = 0;
            buffer = value;
            buffer->size = 0;
        } else if( *data == '&' || *data == ';' ) {
            buffer->chars[ buffer->size ] = 0;
            InsertKeyValue( proc, mulmap, map, vk, vv );
            DString_Reset( key, 0 );   /* also detaching shared memory; */
            DString_Reset( value, 0 ); /* also detaching shared memory; */
            buffer = key;
        } else if( *data != ' ' ) {
            if( *data == '%' ) {
                char a = tolower( data[1] );
                char b = tolower( data[2] );
                buffer->chars[ buffer->size ++ ] = (char) ((HEXTOI(a) << 4) | HEXTOI(b));
                data += 2;
            } else if( *data == '+' ) {
                buffer->chars[ buffer->size ++ ] = ' ';
            } else {
                buffer->chars[ buffer->size ++ ] = *data;
            }
        }
    }
    if( key->size ) InsertKeyValue( proc, mulmap, map, vk, vv );
}
Beispiel #4
0
static void PreparePostData( DaoProcess *proc, DaoMap *httpPOSTS, DaoMap *httpPOST, DaoMap *httpFILE )
{
    DString *fname;
    DString *buffer = DString_New();
    DaoValue *vk = (DaoValue*) DaoProcess_NewString( proc, NULL, 0 );
    DaoValue *vv = (DaoValue*) DaoProcess_NewString( proc, NULL, 0 );
    DString *key = DaoString_Get( DaoValue_CastString( vk ) );
    DString *value = DaoString_Get( DaoValue_CastString( vv ) );
    char *content_length = getenv( "CONTENT_LENGTH" );
    char *content_type = getenv( "CONTENT_TYPE" );
    const char *boundary;
    char postbuf[1024];
    daoint postlen, boundarylen, len = 0;
    daoint pos, pos2, pos_rnrn, offset;

    if( content_length != NULL ) len = strtol( content_length, NULL, 10);
    if( len == 0 ) return;
    DString_SetSharing( buffer, 0 );
    if( content_type == NULL || strstr( content_type, "multipart/form-data" ) == NULL ) {
        postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
        while( postlen ) {
            DString_AppendBytes( buffer, postbuf, postlen );
            postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
        }
        ParseKeyValueString( proc, httpPOSTS, httpPOST, buffer->chars );
        DString_Delete( buffer );
        return;
    }
    boundary = strstr( content_type, "boundary=" ) + strlen( "boundary=" );
    boundarylen = strlen( boundary );

    fname = DString_New();
    buffer->size = 0;
    for(;;) {
        postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
        if( postlen == 0 && buffer->size < boundarylen ) break;

        DString_AppendBytes( buffer, postbuf, postlen );
        while( strstr( buffer->chars, "\r\n\r\n" ) == 0 && postlen != 0 ) {
            postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
            DString_AppendBytes( buffer, postbuf, postlen );
        }
        //printf( "###############\n%s\n", buffer->chars );

        key->size = 0;
        fname->size = 0;
        pos = DString_FindChars( buffer, "name=", 20 ); /* Skip: Content-Disposition: ; */
        pos2 = DString_FindChar( buffer, '\"', pos+6 );
        DString_SubString( buffer, key, pos + 6, pos2 - pos - 6 );

        pos_rnrn = DString_FindChars( buffer, "\r\n\r\n", pos2 );
        pos = DString_FindChars( buffer, "filename=", pos2 );
        if( pos != DAO_NULLPOS && pos < pos_rnrn ) {
            daoint pos3 = DString_FindChar( buffer, '\"', pos+10 );
            DString_SubString( buffer, fname, pos + 10, pos3 - pos - 10 );
        }

        buffer->size -= pos_rnrn + 4;
        memmove( buffer->chars, buffer->chars + pos_rnrn + 4, buffer->size );
        if( fname->size == 0 ) {
            offset = 0;
            while( (pos2 = DString_FindChars( buffer, boundary, offset )) == DAO_NULLPOS ) {
                offset = buffer->size - boundarylen;
                if( offset < 0 ) offset = 0;
                postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
                DString_AppendBytes( buffer, postbuf, postlen );
            }
            DString_SubString( buffer, value, 0, pos2 - 4 ); /* \r\n-- */
            DaoMap_Insert( httpPOST, (DaoValue*) vk, (DaoValue*) vv );
            buffer->size -= pos2 + boundarylen;
            memmove( buffer->chars, buffer->chars + pos2 + boundarylen, buffer->size );
        } else {
            DaoInteger isize = {DAO_INTEGER,0,0,0,0,0};
            DaoFileStream *stream = _DaoFileStream_New();
            DaoTuple *tuple = DaoTuple_New(3);
            FILE *file = tmpfile();

            DaoString_Set( (DaoString*) vv, fname );
            stream->file = file;
            stream->base.mode |= DAO_STREAM_READABLE|DAO_STREAM_WRITABLE;
            _DaoFileStream_InitCallbacks( stream );
            DaoTuple_SetType( tuple, daox_type_namestream );
            DaoTuple_SetItem( tuple, (DaoValue*) vv, 0 );
            DaoTuple_SetItem( tuple, (DaoValue*) stream, 2 );
            DaoMap_Insert( httpFILE, (DaoValue*) vk, (DaoValue*) tuple );

            offset = 0;
            while( (pos2 = DString_FindChars( buffer, boundary, 0 )) == DAO_NULLPOS ) {
                offset = buffer->size - boundarylen;
                if( offset > 0 ) {
                    isize.value += offset;
                    fwrite( buffer->chars, 1, offset, file );
                    buffer->size -= offset;
                    memmove( buffer->chars, buffer->chars + offset, buffer->size );
                }
                postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
                DString_AppendBytes( buffer, postbuf, postlen );
            }
            isize.value += pos2 - 4;
            fwrite( buffer->chars, 1, pos2 - 4, file );  /* \r\n-- */
            buffer->size -= pos2 + boundarylen;
            memmove( buffer->chars, buffer->chars + pos2 + boundarylen, buffer->size );
            rewind( file );
            DaoTuple_SetItem( tuple, (DaoValue*) & isize, 1 );
        }
    }
    DString_Delete( buffer );
}
static void ParseKeyValueString( DaoProcess *proc, DaoMap *mulmap, DaoMap *map, const char *s )
{
	int i = 0;
	int nc = 0;
	int len = 0;
	char buffer[ LOCAL_BUF_SIZE + 1 ];
	
	DaoValue *vk = (DaoValue*) DaoProcess_NewMBString( proc, NULL, 0 );
	DaoValue *vv = (DaoValue*) DaoProcess_NewMBString( proc, NULL, 0 );
	DString *key = DaoString_Get( DaoValue_CastString( vk ) );
	DString *value = DaoString_Get( DaoValue_CastString( vv ) );

	len = strlen( s );
	nc = 0;
	int isKey = 1;
	char tmp[3];
	tmp[2] = 0;
	for(i=0; i<len; i++){
		if( s[i] == '=' ){
			buffer[nc] = 0;
			DString_AppendMBS( key, buffer );
			nc = 0;
			isKey = 0;
		}else if( s[i] == '&' || s[i] == ';' || i+1==len ){
			if( i+1 == len ){
				buffer[ nc ] = s[i];
				nc ++;
			}
			if( DString_Size( key ) > 0 ){
				buffer[ nc ] = 0;
				DString_AppendMBS( value, buffer );
				InsertKeyValue( proc, mulmap, map, vk, vv );
				DString_Clear( key );
				DString_Clear( value );
				nc = 0;
				isKey = 1;
			}else if( nc > 0 ){
				buffer[ nc ] = 0;
				DString_AppendMBS( key, buffer );
				DString_SetMBS( value, "NULL" );
				InsertKeyValue( proc, mulmap, map, vk, vv );
				DString_Clear( key );
				DString_Clear( value );
				nc = 0;
				isKey = 1;
			}
		}else if( s[i] != ' ' ){
			if( nc >= LOCAL_BUF_SIZE ){
				buffer[ nc ] = 0;
				if( isKey ){
					DString_AppendMBS( key, buffer );
				}else{
					DString_AppendMBS( value, buffer );
				}
				nc = 0;
			}
			if( s[i] == '%' ){
				tmp[0] = s[i+1];
				tmp[1] = s[i+2];
				buffer[ nc ] = strtol( tmp, NULL, 16 );
				i += 2;
			}else if( s[i] == '+' ){
				buffer[ nc ] = ' ';
			}else{
				buffer[ nc ] = s[i];
			}
			nc ++;
		}
	}
	if( DString_Size( key ) > 0 ){
		buffer[ nc ] = 0;
		DString_AppendMBS( value, buffer );
		InsertKeyValue( proc, mulmap, map, vk, vv );
	}else if( nc > 0 ){
		buffer[ nc ] = 0;
		DString_AppendMBS( key, buffer );
		DString_SetMBS( value, "NULL" );
		InsertKeyValue( proc, mulmap, map, vk, vv );
	}
}
static void PreparePostData( DaoProcess *proc, DaoMap *httpPOSTS, DaoMap *httpPOST, DaoMap *httpFILE )
{
	DaoValue *vk = (DaoValue*) DaoProcess_NewMBString( proc, NULL, 0 );
	DaoValue *vv = (DaoValue*) DaoProcess_NewMBString( proc, NULL, 0 );
	DString *key = DaoString_Get( DaoValue_CastString( vk ) );
	DString *value = DaoString_Get( DaoValue_CastString( vv ) );
	DString *dynaBuffer = DString_New(1);
	int i = 0;
	int len = 0;
	char buffer[ LOCAL_BUF_SIZE + 1 ];
	char *last = buffer + (LOCAL_BUF_SIZE-1);
	
	char *contentLength = getenv( "CONTENT_LENGTH" );
	char *contentType = getenv( "CONTENT_TYPE" );
	len = 0;
	*last = 0;
	if( contentLength != NULL ) len = strtol( contentLength, NULL, 10);
	if( contentType != NULL ){
		//printf( "CONTENT_TYPE = %s\n", contentType );
		if( strstr( contentType, "multipart/form-data" ) == NULL ){
			i = 0;
			DString_Clear( dynaBuffer );
			while( i < len ){
				int n = 0;
				int ch = getchar();
				while( ch != EOF ){
					buffer[n] = (char)ch;
					n ++;
					if( n == LOCAL_BUF_SIZE ) break;
					ch = getchar();
				}
				buffer[ n ] = 0;
				//printf( "%s|||||||||||||||||\n", buffer );
				char *p = strchr( buffer, '&' );
				if( p != NULL ){
					*p = 0; // null-terminating
					p++;
					DString_AppendMBS( dynaBuffer, buffer );
					ParseKeyValueString( proc, httpPOSTS, httpPOST, DString_GetMBS( dynaBuffer ) );
					DString_Clear( dynaBuffer );
					DString_AppendMBS( dynaBuffer, p );
				}else{
					DString_AppendMBS( dynaBuffer, buffer );
				}
				i += LOCAL_BUF_SIZE;
			}
			ParseKeyValueString( proc, httpPOSTS, httpPOST, DString_GetMBS( dynaBuffer ) );
		}else{
			char *boundary = strstr( contentType, "boundary" );
			boundary = strstr( boundary, "=" ) + 1;
			i = 0;
			char *part = NULL;
			while( ! feof( stdin ) ){
				if( part == NULL ) part = fgets( buffer, LOCAL_BUF_SIZE, stdin );
				if( part == NULL ) break;
				if( strstr( part, boundary ) == NULL ) break;

				// read content information
				DString_Clear( dynaBuffer );
				buffer[ LOCAL_BUF_SIZE ] = 0; // null-terminating
				char *p = fgets( buffer, LOCAL_BUF_SIZE, stdin );
				if( p == NULL ) break; // the last boundary scanned
				p = strchr( p, '\n' );
				*p = 0; // null-terminating
				DString_AppendMBS( dynaBuffer, buffer );
				char *info = (char*)DString_GetMBS( dynaBuffer );
				info = strchr( info, '=' );
				info += 2; // at char after name="
				p = info;
				while( *p != '\"' ) p ++;
				*p = 0; // null-terminating
				DString_SetMBS( key,  info );
				p ++;
				if( (p = strstr(p,"filename") ) == NULL ){
					p = fgets( buffer, LOCAL_BUF_SIZE, stdin );
					p = fgets( buffer, LOCAL_BUF_SIZE, stdin );
					// now real data:
					DString_Clear( value );
					while( p != NULL && strstr( p, boundary ) == NULL ){
						char *t = strstr( p, "\r\n" );
						if( t != NULL ) *t = 0;
						DString_AppendMBS( value, buffer );
						if( feof( stdin ) ) break;
						p = fgets( buffer, LOCAL_BUF_SIZE, stdin );
						t = strchr( p, '\n' );
						if( t!= NULL ) *(t+1) = 0;
					}
					if( p != NULL ) part = p;
					DaoMap_Insert( httpPOST, vk, vv );
				}else{
					DaoValue *vs = (DaoValue*) DaoProcess_NewStream( proc, tmpfile() );
					FILE *file = DaoStream_GetFile( DaoValue_CastStream( vs ) );
					char *t = NULL;
					p = strchr( p, '\"' ) + 1;
					info = p;
					while( *p != '\"' ) p ++;
					*p = 0; // null-terminating
					//XXX stream->TYPER->SetName( stream, info );
					DString_Clear( value );
					// Content-Type ...\r\n
					p = fgets( buffer, LOCAL_BUF_SIZE, stdin );
					// \r\n
					p = fgets( buffer, LOCAL_BUF_SIZE, stdin );
					// data
#if 0
					int count = fread( buffer, 1, LOCAL_BUF_SIZE, stdin );
					while( count && strstr( buffer, boundary ) == NULL ){
						fwrite( buffer, 1, count, file );
						fprintf( file, "%s\n", "===========================" );
						if( feof( stdin ) ) break;
						count = fread( buffer, 1, LOCAL_BUF_SIZE, stdin );
					}
#else
					char tail[3] = { 0, 0, 0 };
					int count, ntail = 0;
					p = fgets( buffer, LOCAL_BUF_SIZE, stdin );

					while( p != NULL && strstr( p, boundary ) == NULL ){
						if( feof( stdin ) ){
							// XXX
							break;
						}else{
							t = p;
							while( t != last && (*t) != '\n' ) t ++;
							if( (*t) == '\n' ){
								count = t-p+1;
								if( count >= 2 ){
									count -= 2;
									if( ntail ) fwrite( tail, 1, ntail, file );
									tail[0] = p[ count ];
									tail[1] = p[ count+1 ];
									ntail = 2;
									fwrite( p, 1, count, file );
								}else if( count == 1 ){
									if( ntail == 2 ){
										fwrite( tail, 1, 1, file );
										tail[0] = tail[1];
										tail[1] = p[0];
									}else if( ntail ==1 ){
										tail[1] = p[0];
										ntail = 2;
									}else{
										tail[0] = p[0];
										ntail = 1;
									}
								}
							}else{
								if( ntail ) fwrite( tail, 1, ntail, file );
								count = LOCAL_BUF_SIZE-3;
								tail[0] = p[ count ];
								tail[1] = p[ count+1 ];
								ntail = 2;
								fwrite( p, 1, count, file );
							}
						}
						p = fgets( buffer, LOCAL_BUF_SIZE, stdin );
					}
#endif
					//if( p != NULL ) part = p;
					rewind( file );
					DaoMap_Insert( httpFILE, vk, vs );
				}
			}
		}
	}
	DString_Delete( dynaBuffer );
}