Re: using threads in libwww

Vic Bancroft <[email protected]>
Newsgroups gmane.comp.lib.libwww
Message-ID <Pine.SOL.4.21.0210090005580.26243-300000@zweb>
Well, there are a few issues I had with your example to compile in 
linux.  Without knowing your compiler or Makefile, it may not be a
thing you are required to do.  I needed to add several headers, 

  #include <netdb.h>
  #include <sys/stat.h>
  #include <unistd.h>

in addition to the ones found in -I/usr/local/include/w3c-libwww/

It was also necessary to define HAVE_STRERROR to avoid a conflict.
A simple way is to define it on the command line along with _REENTRANT,
however the proper way is to use the www configuration header,

  #include <wwwconf.h>

A compiler warning can be removed if FALSE is used instead of NULL
when checking the return value of HTPostAnchor(), e.g.,

  PUBLIC HTChunk * PostAnchorToChunk (HTParentAnchor *    source,
                                      HTAnchor *             destination,
                                      HTRequest *            request)

  {
      if (source && destination && request) {
          HTChunk * chunk = NULL;
          HTStream * target = HTStreamToChunk(request, &chunk, 0);
          HTRequest_setOutputStream(request, target);
          if (HTPostAnchor(source, destination, request) != FALSE)
              return chunk;
          else {
              HTChunk_delete(chunk);
              return NULL;
          }
      }
      return NULL;
 }

In a similar way, main should usually return an int.  It makes for a
more flexible program to take variable program parameters, giving,

  int main( int argc, char** argv )

for program entry point.  I suggest taking in server url and file url.

I did not take the time to trim what libraries were actually being used, so I
just included them all, ending up with a compile line as follows,

  gcc hss.c -D_REENTRANT -lpthread -lwwwapp -lwwwgopher -lwwwnews -lwwwcache
      -lwwwhtml -lwwwstream -lwwwcore -lwwwhttp -lwwwtelnet -lwwwdir -lwwwinit 
      -lwwwtrans -lwwwfile -lwwwmime -lwwwutils -lwwwftp -lwwwmux -lwwwxml
      -lwwwzip -lxmlparse -lxmltok -lmd5 -I/usr/local/include/w3c-libwww/ -o hss

The modified code is attached along with the output log of a run . . . 

more,
l8r,

------------------------------------------------------------------- 
Victor Bancroft, Principal Engineer, Zvolve Systems [v]770.551.4505 
1050 Crown Pointe Pkwy, Suite 300, Atlanta GA 30338 [f]770.551.4509 
Fellow, Artificial Intelligence Center              [v]706.542-0358 
Athens, Georgia  30602, U.S.A           http://ai.uga.edu/~bancroft
hss.log (text/plain, 3.2 KB)
  [bancroft@localhost libwww]$ echo '<a b=c/>' > xmlinput
  [bancroft@localhost libwww]$ ./hss
  Now going to call post data...
  Request..... Created 0x80516c0
  ChunkStream. Chunk 0x8052200 created with max size 0
  HTAccess.... Accessing document http://tom.sine.com:7001/servlet/Spider
  Net Before.. calling 0x400442c0 (request 0x80516c0, context (nil))
  Net Before.. calling 0x400448a0 (request 0x80516c0, context (nil))
  URL Tree.... did NOT find `w3c-AA'
  Credentials. verified
  Net Before.. calling 0x400aea70 (request 0x80516c0, context (nil))
  URL Tree.... did NOT find `w3c-pep'
  Net Before.. calling 0x400441c4 (request 0x80516c0, context (nil))
  Net Object.. 0x8052590 created with hash 0
  Net Object.. starting request 0x80516c0 (retry=1) with net object 0x8052590
  HTTP........ Looking for `http://tom.sine.com:7001/servlet/Spider'
  HTHost parse Looking up `tom.sine.com' on port 7001
  Event....... Created event 0x8053120 with context 0x8053058, priority 20, and timeout 10000
  Event....... Created event 0x8053138 with context 0x8053058, priority 20, and timeout 10000
  Event....... Created event 0x8053150 with context 0x8053058, priority 20, and timeout 10000
  Host info... added `tom.sine.com' with host 0x8053058 to list 0x8052368
  Host connect Grabbing lock on Host 0x8053058 with 0x8052590
  Host info... Added Net 0x8052590 (request 0x80516c0) to pipe on Host 0x8053058, 1 requests made, 1 requests in pipe, 0 pending
  HTHost...... No ActivateRequest callback handler registered
  HTHost 0x8053058 going to state TCP_CHANNEL.
  HTHost 0x8053058 going to state TCP_DNS.
  Looking up tom.sine.com
  Looking up tom.sine.com
  Error....... Add  73	Severity: 1	Parameter: `No such file or directory'	Where: `gethostbyname'
  HTDoConnect. Can't locate `tom.sine.com'
  Error....... Add  51	Severity: 1	Parameter: `tom.sine.com'	Where: `HTDoConnect'
  HTHost 0x8053058 going to state TCP_ERROR.
  HTHost 0x8053058 going to state TCP_BEGIN.
  Host connect Unlocking Host 0x8053058
  HTTP Clean.. Called with status -906, net 0x8052590
  Net Object.. Delete 0x8052590 and call AFTER filters
  Host info... Remove 0x8052590 from pipe
  Net Object.. Check for pending Net objects
  Net Object.. Freeing object 0x8052590
  Response.... Created 0x8054fa0
  Net After... calling 0x40044970 (request 0x80516c0, response 0x8054fa0, status -906, context (nil))
  Net After... calling 0x400aeb30 (request 0x80516c0, response 0x8054fa0, status -906, context (nil))
  Net After... calling 0x40044420 (request 0x80516c0, response 0x8054fa0, status -906, context (nil))
  Fatal Error: Can't locate remote host (tom.sine.com) 
  Reason: gethostbyname operation failed (No such file or directory)
  Load End.... Request ended with code -906
  Net After... calling 0x8048f4c (request 0x80516c0, response 0x8054fa0, status -906, context (nil))
  Request..... Delete 0x80516c0
  Request..... Deleting dangling output stream
  Chunkstream. FREEING...
  Response.... Delete 0x8054fa0
  WWWLibTerm.. Cleaning up LIBRARY OF COMMON CODE
  Net Object.. Kill ALL Net objects!!!
  Event....... Deleted event (nil)
  Event....... Deleted event (nil)
  Event....... Deleted event (nil)
hss.c (text/plain, 3.4 KB)
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/socket.h>
#include <time.h>
#include <strings.h>
#include <fcntl.h>
#include <pthread.h>
#include <wwwconf.h>
#include "WWWLib.h"
#include "WWWInit.h"


HTChunk * chunk = NULL;
#define SAMPLE_DATA_FILE "xmlinput"
void *postData(void *arg);
int postData1 (unsigned char *buff , char* dst_url);


PUBLIC HTChunk * PostAnchorToChunk (HTParentAnchor *  source,
				    HTAnchor *        destination,
				    HTRequest *       request)

{
  if (source && destination && request) {
    HTChunk * chunk = NULL;
    HTStream * target = HTStreamToChunk(request, &chunk, 0);
    HTRequest_setOutputStream(request, target);
    if (HTPostAnchor(source, destination, request) != FALSE)
      return chunk;
    else {
      HTChunk_delete(chunk);
      return NULL;
    }
  }
  return NULL;
}
PRIVATE int terminate_handler (HTRequest * request, HTResponse * response,
                               void * param, int status)
{
  char * string;
  string = HTChunk_toCString(chunk);
  if (string)
    printf("string : %s\n", string);
  else printf ("No response");
  HT_FREE(string);

  /* We are done with this request */
  HTRequest_delete(request);

  /* Terminate libwww */
  HTProfile_delete();

  exit(0);
}

int main( int argc, char** argv )
{
  pthread_t      thr;
  pthread_attr_t  attr;
  FILE *fp;
  int i=0, c;
  unsigned char buff[10000];

  fp = fopen (SAMPLE_DATA_FILE,"r");
  if (!fp)
    {
      printf ("Can not open <%s>\n",SAMPLE_DATA_FILE);
      exit (0);
    }

  /* read xmlinput file */
  while ((c = getc(fp))!=EOF)
    buff[i++] = (unsigned char) c;
  buff[i] = '\0';

#if 0
  postData1(buff, "http://tom.sine.com:7001/servlet/Spider");   
#endif

#if 1
  pthread_attr_init(&attr);                                  
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  if(pthread_create(&thr, (pthread_attr_t *)&attr, postData, (void *)buff)) {
    fprintf(stderr, "failed to create a thread\n");
  }
  pthread_attr_destroy(&attr);
  sleep (20);
#endif

}

void *postData(void *arg)
{
  unsigned char *buff = (unsigned char *) arg;

  printf ("Now going to call post data...\n");
  /* send data to HTTP client */
  postData1(buff, "http://tom.sine.com:7001/servlet/Spider");

}

int postData1 (unsigned char *buff , char *dst_url)
{
  HTRequest * request = NULL;
  HTParentAnchor * src = NULL;
  HTAnchor * dst = NULL;
  char dst_str[128];
  char data[10000];

  /* Create a new premptive client */
  HTProfile_newNoCacheClient("libwww-POST", "1.0");

  /* 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(10000); /* 10 seconds timeout */
  HTSetTraceMessageMask("sop");

  strcpy(dst_str, dst_url);
  strcpy (data,buff);

  if (data && *data && dst_str && *dst_str)
    {
      request = HTRequest_new();
      HTRequest_setOutputFormat(request, WWW_SOURCE);

      dst = HTAnchor_findAddress(dst_str);
      src = HTTmpAnchor(NULL);
      HTAnchor_setDocument(src, data);
      HTAnchor_setLength(src, strlen(data));

      chunk = PostAnchorToChunk(src, dst, request);
      HTEventList_loop(request);
    }
  return 0;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.