[Prev][Next][Index][Thread]

Re: Making POST (and PUT) requests



Didn't need to hack the library... here are some code snippets. I use
a class "URLClass" which has a bunch of spiffy methods, like
isPostURL() etc. Looks like the java class, acually. Anyway, here's
basically how I do a GET/POST.

DANGER DANGER DANGER DANGER!

I encountered two bugs in the library (4.0) which cause this code NOT
to work. The first is in streampipe(), which causes the output stream
of anything but a GET request to be HTBlackHole (i.e. /dev/null!), the
second being in HTMIME_put_block which causes anything using the
content_length field (like POST requests) to stop reading after
you've _read_ content_length bytes (the content_length is used for
telling the server how many bytes you're writing). I'm assuming Henrik
will have patches for these in a day or so.

Anyway, here's a sketch of how I do a POST. I personally think it's
far too convoluded, but that's me. 

/* printAnchor is a PostCallback function which does just that --- it
   prints the request->anchor->document to the target */
int printPostData(HTRequest *request, HTStream *target) {
  int status;

  if (!request || !request->anchor || !request->anchor->document)
    return HT_OK;

  /* this is normally a void * or a HyperDoc *, or something. */
  char *s = (char *) request->anchor->document;

  /* set the various MIME fields */
  HTRequest_setMethod(request, METHOD_POST);
  HTAnchor_setFormat(request->anchor, HTAtom_for("application/x-www-form-urlencoded"));
  HTAnchor_setLength(request->anchor, strlen(s));

  /* send the doc down the target stream */
  status = (*target->isa->put_string)(target, s);
  if (status != HT_OK) return status;

  /* and flush it. */
  status =  (*target->isa->flush)(target);
  return status;
}

int get_url(URLClass *url) {
    char *thisURL = url->toExternalForm(); // i.e. "http://some.dom";

    HTRequest *request = HTRequest_new();

    /* we do this so we can set the anchor->document, 
       which contains the postData. We gotta do some conversions though. */
    HTParentAnchor *anchor = (HTParentAnchor *) HTAnchor_findAddress(thisURL);
    HTRequest_setAnchor(request, (HTAnchor *) anchor);

    /* see if the url we have should be a POST or GET method */
    if (url->postData != "") 
      if (url->isPostURL()) {
	request->PostCallback = printPostData;
        HTAnchor_setDocument(anchor, (char *) url->postData);
      }

    /* this puts the request into the event loop queue; keep calling
       HTEvent_Loop until it returns. */
    return HTLoadAbsolute(thisURL, request);
}


References: