- From: Akritidis Xristoforos <cakrit@hol.net>
- Date: Fri, 29 Aug 2003 09:37:32 +0300
- To: "Jerry G. Chiuan" <jerry@oridus.com>, <www-lib@w3.org>
I see that people keep coming across the same problems I encountered on the fateful day I dug my teeth into wwwlib. It was a real nightmare and confirmed my belief that a library without documentation is basically unusable, unless you become an expert in it. I've become no expert, but I managed to write an api that does http POST requests with any number of arguments, handles authentication and stores the result body and headers in two separate strings. It's far from perfect (see the hard-coded 'outputformat = "xml"' for example, but it will get you where you're going fast. All you need to do is call www_init(), www_request with the options you want, as many times as you like, and www_terminate() when you're done. Just make sure you change my custom debug function to something else (printf, HTprint, whatever...) You may use this, modify it as you please... If it becomes good enough, maybe we can put it in the distribution? Christopher #include "WWWLib.h" #include "WWWHTTP.h" #include "WWWInit.h" #include "HTUTree.h" #include "HTNet.h" #include "HTAABrow.h" // variable length string that gets the entire response HTChunk * result_chunk = NULL; // Avoid printing progress messages PUBLIC BOOL HTProgress (HTRequest * request, HTAlertOpcode op, int msgnum, const char * dfault, void * input, HTAlertPar * reply) { char * msg = HTDialog_progressMessage(request, op, msgnum, dfault, input); if (msg) { debug(D_DEBUG,"%s\n", msg); HT_FREE(msg); } if (reply) return YES; return YES; } // Declaration and constructor for authentication information. typedef struct _MYBasic { /* Basic challenge and credentials */ char * uid; char * pw; BOOL retry; /* Should we ask the user again? */ BOOL proxy; /* Proxy authentication */ } MYBasic; PRIVATE MYBasic * MYBasic_new(char * username, char* password) { MYBasic * me = NULL; if ((me = (MYBasic *) HT_CALLOC(1, sizeof(MYBasic))) == NULL) HT_OUTOFMEM("MYBasic_new"); me->uid = strdup(username); me->pw = strdup(password); me->retry = NO; me->proxy = NO; return me; } PRIVATE int printer (const char * fmt, va_list pArgs) { s_debug(D_DEBUG, fmt, pArgs); return 0; } PRIVATE int tracer (const char * fmt, va_list pArgs) { s_debug(D_ANALYSIS, fmt, pArgs); return 0; } PRIVATE int terminate_handler (HTRequest * request, HTResponse * response, void * param, int status) { char statuscode[64]; sprintf (statuscode,"%d",status); HTResponse_addHeader(response,"status",statuscode); HTEventList_stopLoop (); if (request && response && param && status) return HT_ERROR; return HT_ERROR; } void www_init(void) { /* Need our own trace and print functions */ HTPrint_setCallback(printer); HTTrace_setCallback(tracer); /* Get trace messages */ if (log_facilities & D_ANALYSIS) { HTSetTraceMessageMask("sop"); } /* Add our own filter to update the history list */ HTNet_addAfter(terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST); /* Set the timeout for long we are going to wait for a response */ HTHost_setEventTimeout(20000); /* Initialize libwww core */ HTProfile_newNoCacheClient("TestApp", "1.0"); HTAlert_setInteractive(NO); } void www_terminate(void) { /* Terminate the Library */ HTProfile_delete(); } int www_request (char* outputformat, char **HTMLheader, char ** HTMLresponse, char *url, char *username, char *password, ...) { // Everything requires a request stream HTRequest * request = HTRequest_new(); // Structure holding authentication info MYBasic * basic; // Anchor holding the URL. Need it for POST requests HTAnchor * anchor = NULL; char * cwd = HTGetCurrentDirectoryURL(); char * absolute_url; char * name_value=NULL; int RETURNVALUE=0; // Get arbitrary number of arguments for the cgi we will call // Put the arguments in an association list, to be used in PUT and GET requests HTAssocList * formfields = NULL; va_list argsvar; va_start (argsvar, password); name_value=va_arg(argsvar,char *); if (name_value) { formfields = HTAssocList_new (); do { HTParseFormInput(formfields,name_value); debug(D_DEBUG,"argument '%s'", name_value); name_value=va_arg(argsvar,char *); } while (name_value); } va_end(argsvar); if (!url) return 1; debug(D_DEBUG,"www_request %s", url); // Escape illegal characters. Basically spaces and greek letters absolute_url = HTParse(url, cwd, PARSE_ALL); /* We want raw output including headers */ if (strcmp(outputformat,"xml") == 0) { HTRequest_setOutputFormat(request, HTAtom_for("text/xml")); } else { HTRequest_setOutputFormat(request, WWW_SOURCE); } /* Close connection immediately */ HTRequest_addConnection(request, "close", ""); /* Automatic Authentication */ if (username && password) { basic = MYBasic_new(username,password); HTBasic_generate (request, basic, 0); } debug(D_DEBUG,"absolute_url=%s",absolute_url); /* Get an anchor object for the URL */ anchor = HTAnchor_findAddress(absolute_url); // Load the url if (formfields) { // Load with a POST result_chunk = HTPostFormAnchorToChunk(formfields, anchor, request); /* Clean up the form fields */ HTAssocList_delete(formfields); } else { // Load with a GET result_chunk = HTLoadAnchorToChunk (anchor, request); } HT_FREE(absolute_url); HT_FREE(cwd); (*HTMLheader) = NULL; (*HTMLresponse) = NULL; if (result_chunk) { /* Go into the event loop... */ HTEventList_loop(request); (*HTMLresponse) = HTChunk_toCString(result_chunk); debug(D_ANALYSIS, "Response : %s", *HTMLresponse); // Get headers and status code { HTResponse *response = HTRequest_response(request); if (response) { HTAssocList * headers = HTResponse_header(response); if (headers) { HTAssoc * pres; (*HTMLheader) = (char *) malloc (sizeof(char) * 1024); (*HTMLheader)[0] = '\0'; while ((pres = (HTAssoc *) HTAssocList_nextObject(headers))) { char * name = HTAssoc_name(pres); char * value = HTAssoc_value(pres); if (strcmp(name,"status") == 0) { RETURNVALUE = atoi(value); } else { debug(D_DEBUG,"HEADER %s = %s", name, value); sprintf(*HTMLheader,"%s%s = %s\n",*HTMLheader,name,value); } } } } } } /* Clean up the request */ HTRequest_delete(request); return RETURNVALUE; }
Received on Friday, 29 August 2003 02:37:51 UTC