- From: Akritidis Xristoforos <cakrit@hol.net>
- Date: Fri, 19 Sep 2003 07:30:52 +0300
- To: <erikvcl@silcom.com>, <www-lib@w3.org>
> As I see from the mailing list postings, this issue is covered frequently. > I'm still having trouble! I got a great deal of help from Josh Watts' > posting back in 2001, but my application still isn't working. I believe I sent some code on this, not long ago. I have been using the code that follows as a generic http request library. The only things I haven't implemented that I might are saving the ftp results (I only check if it the file is there) and ssl. Look for 'basic' authentication below and you'll be ok. All you need to use the library is define your own debug function. Changed the subject to add some keywords. /* wwwapi.h */ #ifdef __cplusplus extern "C" { #endif extern void www_init (void); extern void www_terminate (void); extern int www_request (char* outputformat, char **HTMLheader, char ** HTMLresponse, char *url, char *username, char *password, ...); #ifdef __cplusplus } #endif #include "wwwapi.h" #include "WWWHTTP.h" #include "WWWInit.h" #include "HTUTree.h" #include "HTNet.h" #include "HTAABrow.h" /* ** Local context structure used in the HTNet object. */ typedef enum _HTFTPState { FTP_SUCCESS = -2, FTP_ERROR = -1, FTP_BEGIN = 0, FTP_NEED_CCON, /* Control connection */ FTP_NEED_LOGIN, FTP_NEED_DCON, /* Data connection */ FTP_NEED_DATA, FTP_NEED_SERVER /* For directory listings */ } HTFTPState; typedef struct _ftp_ctrl { HTChunk * cmd; int repcode; char * reply; char * uid; char * passwd; char * account; HTFTPState state; /* State of the connection */ int substate; /* For hierarchical states */ BOOL sent; /* Read or write command */ BOOL cwd; /* Done cwd */ BOOL reset; /* Expect greeting */ FTPServerType server; /* Type of server */ HTNet * cnet; /* Control connection */ HTNet * dnet; /* Data connection */ BOOL alreadyLoggedIn; } ftp_ctrl; // 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) return status; return status; } 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(); // Anchor holding the URL. Need it for POST requests HTAnchor * anchor = NULL; // Structure holding authentication info MYBasic * basic; /* ftp Automatic Authentication */ HTNet * cnet; ftp_ctrl * ctrl; 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; // Set the username and password for ftp requests if (strcmp("ftp",outputformat) == 0) { cnet = HTRequest_net(request); ctrl = (ftp_ctrl *) HTNet_context(cnet); if (ctrl) { StrAllocCopy(ctrl->uid, username); StrAllocCopy(ctrl->passwd, password); } } 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, 19 September 2003 00:35:27 UTC