- From: <erikvcl@silcom.com>
- Date: Wed, 24 Sep 2003 13:19:26 -0700 (PDT)
- To: Akritidis Xristoforos <cakrit@hol.net>
- Cc: www-lib@w3.org
Hi, Thank you so much for this helpful bit of code. I now see how the authentication is supposed to work and I have gotten it to work successfully. Thanks again, Erik. On Fri, 19 Sep 2003, Akritidis Xristoforos wrote: > > > > 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 Wednesday, 24 September 2003 16:19:40 UTC