- 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