RE: Another POST question

Hi Gert,

There are my functions to do this. Probably some of the parts are not
needed. The multipatrt data are already combined in the file "local_filename".


BOOL 
Lib_s::postURL(const char* server/* where to post */, 
               int port, 
               const char* url /* url of the script on server */, 
               const char* local_filename /* name of file (muilipart data) to
                                             post */)

{
    HTParentAnchor * src = NULL;
    HTAnchor * dst = NULL;

    HTCacheMode_setEnabled(NO);
    HTRequest  * request = HTRequest_new();
    HTRequest_setRealm (request, "myNetwork");
    
        // this is a mess with the headers but it works this way so I am not
        // touching that.

    //#define DEFAULT_REQUEST_HEADERS 

    HTRequest_setRqHd(request, HT_C_ACCEPT_CHAR);
    HTRequest_addRqHd(request, HT_C_ACCEPT_ENC);
    HTRequest_addRqHd(request, HT_C_ACCEPT_LAN);
    HTRequest_addRqHd(request, HT_C_AUTH);
    HTRequest_addRqHd(request, HT_C_EXPECT);
    HTRequest_addRqHd(request, HT_C_HOST);
    HTRequest_addRqHd(request, HT_C_REFERER);
    HTRequest_addRqHd(request, HT_C_USER_AGENT);

    //request's entity headers

    HTRequest_setEnHd(request, HT_E_ALLOW);
    HTRequest_addEnHd(request, HT_E_CONTENT_BASE); 
    HTRequest_addEnHd(request, HT_E_CONTENT_LENGTH);
    HTRequest_addEnHd(request, HT_E_CONTENT_LOCATION);
    HTRequest_addEnHd(request, HT_E_CTE);
    HTRequest_addEnHd(request, HT_E_DERIVED_FROM);
    HTRequest_addEnHd(request, HT_E_ETAG);
    HTRequest_addEnHd(request, HT_E_TITLE);
    HTRequest_addEnHd(request, HT_E_URI);
    HTRequest_addEnHd(request, HT_E_VERSION);
  
    char dest[2048];

    sprintf(dest, "http://%s:%d/%s", server, port, url);

#ifdef EAI_DBG
    cerr << "\n------- postURL: destination = " << dest << endl;
#endif
    
    char buf[520];
        long myFileSize =  sizeOfFile(local_filename);
    
    //Read source file into memory
    FILE *  in = fopen(local_filename, "r");
    
    if (!in) 
      return NO;
    
    // now write file to the chunk..
    int n = 0;

#ifdef EAI_DBG
    cerr << "\n------- postURL: file length = " << myFileSize << endl;
#endif

//    char  * data = (char *) malloc(myFileSize * (sizeof(char)) + 1);
    char * data = new char[myFileSize + 1];
    
    if (!data) {
 #ifdef EAI_DBG
    cerr << "\n------- postURL: Cannot allocate requered lenght" << endl;
#endif       
        return NO;
    }
    
    char * ptr = data;
    long len = 0;
    
    while ((n = fread(buf, sizeof(char), 512, in)) > 0) 
    {
        memcpy((void *) ptr, (void *) buf, n);
        ptr = ptr + n;
        len += n;
    }

#ifdef EAI_DBG
    cerr << "\n------- postURL: data length = " << len << endl;
#endif

    /* Get an anchor object for the destination URI */
    dst = HTAnchor_findAddress(dest);   

    
    src = HTTmpAnchor(NULL);
    //src = HTParentAchor_new();
    
    HTAnchor_setDocument(src, data);
    HTAnchor_setFormat(src, WWW_SOURCE);   
    HTAnchor_setLength(src, len);

#ifdef EAI_DBG
    cerr << "\n------- postURL: data length = " << len << endl;
#endif
 
    //Set additional headers - add header generator
    BOOL override;
    
    HTList * generators = HTRequest_generator(request, &override);

    if (! generators)
      generators = HTList_new();
    
    HTGenerator_add(generators, post_header_gen);
    HTRequest_setGenerator(request, generators, NO); //??? YES - NO

    FILE * fp1 = NULL;
    
        /* If replace then open the file */
        if ((fp1 = fopen("/var/tmp/post_response.txt", "wb")) == NULL) {
            return NO;
        }
    
        /* Set the output stream and start the request */
        HTRequest_setOutputFormat(request, WWW_SOURCE);
        HTRequest_setOutputStream(request, HTFWriter_new(request, fp1, NO));
    
    
    // Add Authentication after-filter
    HTRequest_addAfter(request, HTAuthFilter, 
                       NULL, NULL, 
                       HT_NO_ACCESS /*| HT_ERROR | HT_NO_DATA*/, 
                       HT_FILTER_MIDDLE, NO);
    
    // Add custom after-filter
    HTRequest_addAfter(request, post_terminate_callback, 
                       NULL, 
                       NULL, 
                       HT_ALL /*| HT_ERROR | HT_NO_DATA*/, 
                       HT_FILTER_MIDDLE, NO);
    
    // this common for all requests filter will clean up and start next request
    HTRequest_addAfter(request, terminate_handler, 
                       NULL, NULL, 
                       HT_ALL, 
                       HT_FILTER_LAST, NO);
    
    HTTP_setBodyWriteDelay(21, 30);
    
    // start POST request 
    BOOL st = HTPostAnchor(src, dst, request);
    
    return st;
}

////////////////////////////////////////////////////////  post_header_gen
//
// Generates additional headers for POST request
//

int post_header_gen (HTRequest * request, HTStream * stream)
{ 
     
    sprintf(headers, "%s%c%c", headers, CR, LF);
#ifdef EAI_DBG
    cerr << "\n======== post_header_gen: headers = " << headers << endl;
#endif
 
    (*stream->isa->put_block)(stream, headers, strlen(headers));
     
    return HT_OK;
}


//////////////////////////////////////////////////////////////
// post_terminate_callback
//
// Local after filter - registered by postURL for POST requests only
// Sends results of POST to client 


int 
Lib_s::post_terminate_callback (HTRequest * request, HTResponse *
                                response,
                                void * param, int status) 
{
  
   if (status == HT_NO_ACCESS) // Auth required - handled by another filter
      return HT_OK; 

    HTCacheMode_setEnabled(YES);    
    
    // replace the global realm guess with the latest realm
    const char * new_realm = HTRequest_realm(request);
    if (new_realm)
      strcpy(realm, new_realm);
    
    HTParentAnchor * src = HTRequest_entityAnchor(request);
    char * ent_data = (char *) HTAnchor_document(src);
    delete [] ent_data;
    HTAnchor_setDocument(src, NULL);
    
    FILE *  in = fopen("/var/tmp/post_response.txt", "r");
    
    if (!in) {
        char temp[30];
        sprintf (temp, "error %d %d", status, EAIErrCode);

        // Answer client is the function that sends info back to client
        // throuch the socket 
        
        AnswerClient("temp", strlen(temp));    
        remove("/var/tmp/post_response.txt");        
        return HT_OK;
    }

    int n = 0;
    char data[2048];
    char temp[2048];
    
    memset(data, 0, 2048);
    memset(temp, 0, 2048);
    
    //char * ptr = data;
    int len = 0;
    char  buf[520];
    
    // read data from file to memory     
    while ((n = fread(buf, sizeof(char), 512, in)) > 0) 
    {
        strncpy(data, buf, n);
        len += n;
    }
    
    data[len] = '\0';
    
    //int strSize = strlen(data) + 10;
    
#ifdef EAI_DBG
    cerr << "--- data = " << data << endl
         << "--- len = " << len << endl;
#endif

    // EAIErrCode is my global var
    sprintf(temp, "%d %d %d %s", status, EAIErrCode, len, data);
    
#ifdef EAI_DBG
    cerr << "Sending to client: answer =  " << temp << endl;
#endif

    AnswerClient(temp, strlen(temp));
    
    remove("/var/tmp/post_response.txt");
    
    return HT_OK;
}


////////////////////////////////////////////////

Hope this helps,

Olga Antropova.


On 11-Mar-99 Gert Koning wrote:
> Hi there libwww'ers
> 
> How can I POST with multipart/form-data and get the result in a memory
> chunk? In other words, I need a function like HTPostFormAnchorToChunk(), but
> in stead of taking an HTAssocList it should take my multipart/form-data
> somehow.
> 
> Thanks,
> Gert Koning
> University of South Africa

----------------------------------
E-Mail: olga <olga@eai.com>
Date: 11-Mar-99
Time: 09:52:59

This message was sent by XFMail
----------------------------------

Received on Thursday, 11 March 1999 11:03:42 UTC