Re: Problems with data POST

Hi!
I've a similar problem, but I'm doing a GET into a server...  I have 
'-1' as value to status and content-length, and only a few bytes of the 
URL appears in the chunk.. :(  I've tried it against Apache and Jigsaw 
servers, and the result is always the same : at the first request it 
works, but at the following requests it returns status '-1', etc..
I left my code (a small example based on libwww's eventloop example) in 
attachment for those who may want to see it... 

Anybody has an idea about that? Any idea? Anything???

Manuele

Alik Kurdjukov wrote:

>Hello!
>
>I'm posting some data (in message body) to the server, that supports
>keep-alive. The posting works fine, server replies immidiately. But I
>have some strange timeout (about 10 seconds) from last bytes read to
>call of terminate_handler. The status returned to the handler is -1, but
>the result chunk is correct. What's wrong? Maybe I need to set some
>timeout or something?
>
/*
** $Id$
** myget.c - example showing how to get xml files
**
** Manuele Kirsch Pinheiro
*/

#include "WWWLib.h"
#include "WWWInit.h"
#include "WWWLib.h"
#include "WWWApp.h"
#include "WWWInit.h"

#ifndef W3C_VERSION
#define W3C_VERSION		"Unspecified"
#endif

#define APP_NAME		"MyGet"
#define APP_VERSION		"0.1"


#define FROM			"manuele@inf.ufrgs.br"
#define HP			"http://gnome.inrialpes.fr:1959/upload/I.html"

#if defined(__svr4__)
#define CATCH_SIG
#endif


/*
 * Request context
 */ 
typedef struct _Context {
    HTChunk * chunk;
} Context;


/*
 * Application context
 */ 
typedef struct _App {
    HTRequest *		console_request;
    HTEvent *		console_event;
    HTList *		active;			  /* List of active contexts */
} App;


/*
 * Callback functions 
 */
PRIVATE HTEventCallback console_parser;
PRIVATE HTNetAfter request_terminater;
PRIVATE HTNetAfter local_request_terminater; 
PRIVATE HTNetAfter local_request_first; 
PRIVATE int printer (const char * fmt, va_list pArgs);
PRIVATE int tracer (const char * fmt, va_list pArgs);


/*
 * Prototypes
 */ 
PRIVATE App * App_new (void);
PRIVATE BOOL App_delete (App * me);
PRIVATE void Context_new (HTRequest * request, HTChunk * chunk, App * app); 
PRIVATE void Context_delete (Context * ctx);
PRIVATE HTRequest * Request_new (App * app);
PRIVATE BOOL Request_delete (App * app, HTRequest * request);
PRIVATE int request_terminater (HTRequest * request, HTResponse * response,
				void * param, int status); 
PRIVATE int console_parser (SOCKET s, void * param, HTEventType type);
PRIVATE int local_request_terminater (HTRequest * request, HTResponse * response,
	            	              void * param, int status); 
PRIVATE int local_request_first (HTRequest * request, HTResponse * response,
	            	              void * param, int status); 

PRIVATE App * Init (void);
PRIVATE void my_headers (HTRequest *request);
PRIVATE void my_get_document (App *app, char *dst);


/*
 ** printer : output messages function
 */
PRIVATE int printer (const char * fmt, va_list pArgs) {
    return (vfprintf(stderr, fmt, pArgs));
}


/*
 ** trace : trace messages function
 */
PRIVATE int tracer (const char * fmt, va_list pArgs) {
    return (vfprintf(stderr, fmt, pArgs));
}



/*
** App_new : creates a new application context
** Returns : App *	application context
 */ 
PRIVATE App * App_new (void) {
    App * me = NULL;
    
    if ((me = (App *) HT_CALLOC(1, sizeof(App))) == NULL)	
        HT_OUTOFMEM("App_new");

    /* setting everybody */
    me->console_request = HTRequest_new();
    me->console_event = HTEvent_new(console_parser, me, HT_PRIORITY_MAX, -1);
    me->active = HTList_new();

    /* Register stdin as our console */
    if (isatty(STDIN_FILENO)) 
        HTEventList_register(STDIN_FILENO, HTEvent_READ, me->console_event);
    
    /* Add our own request terminate handler */
    HTNet_addAfter(request_terminater, NULL, me, HT_ALL, HT_FILTER_LAST); 
    
    HTPrint ("MyGet: Application context created\n");
    
    return me;
}



/*
 ** App_delete : removes an application context object
 ** Parameter : App * app	application context to be removed
 ** Returns : BOOL	YES - operation succed
 **               	NO - operation failed
 */               	 
PRIVATE BOOL App_delete (App * me) {
    HTRequest * req = NULL;	

    HTPrint ("MyGet: Removing application context\n");

    if (me) {
	    
	/* killing any remaining active requests */
	HTNet_killAll();

	/* freeing all remaining request objects */
	while (!HTList_isEmpty(me->active)) {
	    req = (HTRequest *) HTList_nextObject (me->active);
	    if (req)  Request_delete (me,req);
	}

	/* clean up everything */
	HTRequest_delete(me->console_request);
	HTEvent_delete (me->console_event);
	HTList_free (me->active);
		
	HT_FREE(me);

	/* stopping event loop */    
        HTEventList_stopLoop();
	
	/* Terminate libwww */
	HTProfile_delete();

	return YES;
    }
    return NO;
}


/*
 ** Context_new : creates a new request context
 ** Parameters : HTRequest * request
 **              HTChunk * chunk
 **              App * app
 */
PRIVATE void Context_new (HTRequest * request, HTChunk * chunk, App * app) {
    Context * ctx = NULL;

    if ( (ctx = (Context *) HT_CALLOC(1, sizeof(Context))) == NULL ) {
        App_delete (app);
	HT_OUTOFMEM("Contect_new");
    }

    HTPrint ("MyGet: Setting request context...\n");
    ctx->chunk = chunk;
    HTRequest_setContext(request,ctx);    
}


/*
 ** Context_delete : removes the request context
 ** Parameters : Context * ctx
 */
PRIVATE void Context_delete (Context * ctx) {
    if (ctx && ctx->chunk) {
        HTPrint ("MyGet: Removing request context...\n");
	HTChunk_delete (ctx->chunk);
	HT_FREE (ctx);
    }
}

/*
 ** Request_new : creates a new request 
 ** Parameters : App * app 	application context
 ** Returns : HTRequest *
 */ 
PRIVATE HTRequest * Request_new (App * app)
{
    HTRequest * request = HTRequest_new();

    HTPrint ("MyGet: creating a new request\n");
    HTPrint ("\tapp %s active %s \n",(app)?"OK":"NULL", \
		              (app && app->active)?"OK":"NULL");
    
    /* setting request format */
    /*HTRequest_setOutputFormat(request, HTAtom_for ("text/xml"));*/    
    HTRequest_setOutputFormat(request, WWW_SOURCE);     
    /*HTRequest_setOutputFormat(request, WWW_RAW);   */ 

    HTRequest_addConnection (request,"close","");
    
    /* method and some headers */
    HTRequest_setMethod (request,METHOD_GET);
    HTRequest_addExtraHeader (request,"From",FROM);
    HTRequest_addCacheControl (request, "no-cache","");

    /*request fail test */
    /*HTRequest_addExtraHeader (request,"Host","gnome");*/

    HTRequest_addAfter (request, local_request_terminater, NULL, app, \
		        HT_ALL ,HT_FILTER_LAST , NO);
    HTRequest_addAfter (request, local_request_first, NULL, app, \
		        HT_ALL ,HT_FILTER_FIRST , NO);

    HTRequest_deleteCacheControl (request);

    if (!app->active) app->active = HTList_new();
    HTList_addObject(app->active, request);

    return request;
}


/*
 ** Request_delete : removes a request 
 ** Parameters : App * app	application context
 ** 		 HTRequest * request
 ** Returns : BOOL	YES if operation succeed
 **               	NO if operation failed
 */
PRIVATE BOOL Request_delete (App * app, HTRequest * request)
{
    HTPrint ("MyGet: removing request\n");
    HTPrint ("\tapp %s active %s request %s \n", \
		    (app)?"OK":"NULL",(app && app->active)?"OK":"NULL", \
		    (request)?"OK":"NULL");
    
    if (app && app->active && request) {
        HTPrint ("Request deleted \n");	
	HTList_removeObject(app->active, request);
	HTRequest_delete(request);
	return YES;
    }
    return NO;
}



/*
 ** console_parser : treats the user's interaction on the console
 ** Function's type : HTEventCallback
 */ 
PRIVATE int console_parser (SOCKET s, void * param, HTEventType type)
{
    App * app = (App *) param;
    HTRequest * new_request = NULL;
    //HTAnchor * dst = NULL;
    char buf[128];
    char * full_dst;
    char * cwd;

    /* reading console */
    if (!fgets(buf, sizeof(buf), stdin)) return HT_ERROR;

    if (toupper(buf[0]) == 'Q') {	/* Quit the program */
        App_delete(app);
	exit (0);
    }
    else { /* take the target address */
	cwd =  HTGetCurrentDirectoryURL();	
	full_dst = HTParse (buf,cwd,PARSE_ALL);    
        //dst = HTAnchor_findAddress (full_dst);

	HTPrint ("Getting %s\n",full_dst);	/* load the document */
	//my_get_document (app,dst);		
	my_get_document (app,full_dst);		
        //HTEventList_newLoop();

	HT_FREE (full_dst);
	HT_FREE (cwd);
    }
    return HT_OK;
}


/*
 ** request_terminater : global filter to delete the requests
 ** Funtion's type : HTNetAfter
 */ 
PRIVATE int request_terminater (HTRequest * request, HTResponse * response,
				void * param, int status) 
{
    App * app = (App *) param;
    Context * ctx = NULL;
    
    HTPrint ("MyGet: GLOBAL FILTER (request_terminater)\n");
    
    ctx = (Context *) HTRequest_context(request);
    HTPrint ("\tapp %s \tctx %s\n",(app)?"OK":"NULL",(ctx)?"OK":"NULL");	
    
    HTPrint ("MyGet: context object deleted\n");
    Context_delete (ctx);    
        
    Request_delete(app, request);
   
    return HT_OK;
}


/*
 ** local_request_terminater : local after filter to treat the request's results
 ** Function's type : HTNetAfter
 */
PRIVATE int local_request_terminater (HTRequest * request, HTResponse * response,
				void * param, int status) 
{
    Context * ctx = NULL;	
    App * app = (App *) param;
    
    HTPrint ("MyGet: LOCAL FILTER (local_request_terminater)\n");
    HTPrint ("\tapp %s\n\trequest %s\n",(app)?"OK":"NULL",(request)?"OK":"NULL");	
   
    HTPrint ("\tstatus: %d\n",status);
    
    if (response) {
	HTAssoc * h = NULL;    
	HTAssocList * headers = NULL; 
	
        HTPrint ("\tContent-length: %d \n\tIs Cachable: %c\n\tis Cached: %c \n\tReason: %s\n", \
		  HTResponse_length(response),\
		  (HTResponse_isCachable(response))?'Y':'N',
		  (HTResponse_isCached(response,YES))?'Y':'N',
		  (HTResponse_reason(response))?HTResponse_reason(response):"NULL");
    	HTPrint ("\tFormat : %s \n",(char *)HTAtom_name(HTResponse_format(response))); 
    }
    else 
	HTPrint ("\tResponse NULL\n");
   
   /* if (status == HT_LOADED) { */
	//my_headers (request);
   	
        ctx = (Context *) HTRequest_context(request);
        if ( ctx && ctx->chunk && HTChunk_data(ctx->chunk))    
           HTPrint ("MyGet: Loaded: \n%s\n",HTChunk_data(ctx->chunk));	    
        else
           HTPrint ("MyGet: No data available\n");
   /* } 
    else {	
        HTPrint ("MyGet: Document not loaded\n"); 	    
	return HT_ERROR;
    }
   */
    return HT_OK;
}


/*
 ** local_request_first : local after filter to treat the request's headers
 ** Function's type : HTNetAfter
 */
PRIVATE int local_request_first (HTRequest * request, HTResponse * response,
	            	              void * param, int status) {

	my_headers (request);
}

/*
 ** Init : application initialization 
 ** Returns : App * 	application context
 */ 
PRIVATE App * Init (void) {
    App * app = NULL;

    HTPrint ("MyGet: starting application\n");

    /* Initiate libwww */
    HTProfile_newHTMLNoCacheClient(APP_NAME, APP_VERSION);

    app = App_new();
    
    /* Gotta set up our own traces */
    HTPrint_setCallback(printer);
    HTTrace_setCallback(tracer);    
    
#if 0
    HTSetTraceMessageMask("ot");
#endif
    
     /* HTEventList_newLoop(); */ 
    
    return app;
}

/*
 ** my_headers : shows anchor's headers
 ** Parameters : HTRequest * request
 */  
PRIVATE void my_headers (HTRequest *request) {
    HTAssoc * h = NULL;    
    HTAssocList * headers = NULL; 
    HTParentAnchor * anchor = NULL;

    HTPrint ("MyGet: Searching headers...\n");  	
    
    anchor = HTRequest_anchor (request);
    headers = HTAnchor_header(anchor);
    
    HTPrint ("\tanchor %s\n",(anchor)?"OK":"NULL");  	
    
    h = HTAssocList_nextObject(headers);
    while (anchor && headers && h ) {
       HTPrint ("\t%s : %s\n",HTAssoc_name(h),HTAssoc_value(h));
       h = HTAssocList_nextObject(headers);
    }
}

/*
 ** my_get_document: retrives the document
 ** Parameters: App * app	application context
 **             char * dst	URL destiny
 */             
PRIVATE void my_get_document (App *app, char *dst) {
    HTRequest * request = NULL;
    HTList * errors = NULL;
    HTChunk * chunk = NULL;
 

    HTPrint ("MyGet: loading anchor\n");
    HTPrint ("\tapp %s url %s\n",(app)?"OK":"NULL",dst);

    request = Request_new (app);
    //HTRequest_setAnchor (request,dst);
    if ( request && (chunk = HTLoadToChunk (dst,request))) {	
        HTPrint ("MyGet: setting context\n");
        //HTEventList_newLoop(); 
        Context_new (request,chunk,app);        
    }
    else
        HTPrint ("MyGet: load to chunk failed\n");    
    
}



/* ******************************************************************** */
int main (int argc, char ** argv)
{
    App * app = NULL;
    
    app = Init();
    if (app) {
        my_get_document (app,HP);
        HTEventList_newLoop();
    }

	
	
}

Received on Wednesday, 23 January 2002 10:28:01 UTC