Logo Search packages:      
Sourcecode: rapple version File versions  Download package

static int http_parse_multipart_string ( rpl_str_t  post_cnt,
rpl_c_str_t  bdy_param 
) [static]

Parses a multipart string and populates the form data structure.

Parameters:
post_cnt 
bdy_param 
Returns:
-1 on error, 0 on success.

Definition at line 230 of file http.c.

References http_create_parameter(), rpl_log_fatal(), rpl_me_malloc(), rpl_message_get(), and rpl_str_concat().

Referenced by http_parse_multipart_query().

                                                                       {
    rpl_str_t fp, sp, ep;
    rpl_str_t bdy;
    size_t length;
    int filesize;
    int tmp_fd;
    FILE *tmp_fp;
    /* Temporary filename for mkstemp */
    char tmp_templ[] = "rapple_XXXXXX";

    assert((post_cnt != NULL) && (bdy_param != NULL));

    /* see RFC2046 for exact details of how multipart boundaries are defined */
    length = sizeof(RPL_HTTP_MTP_FORM_BDY_PREFIX) + sizeof(bdy_param) + 1;
    bdy = rpl_str_concat(RPL_HTTP_MTP_FORM_BDY_PREFIX, bdy_param, RPL_STR_EOC);

    /* initialise the head of the list */
    data.key = NULL;
    data.value = NULL;
    data.next = NULL;

    /* position the form pointer */
    fp=strstr(post_cnt, bdy_param);
    fp += strlen(RPL_HTTP_MTP_FORM_BDY_PREFIX) + strlen(bdy_param);

    do {
        rpl_str_t key, value;

        /* acquire the key attribute */
        if((sp = strstr(fp, RPL_HTTP_MTP_FORM_NAME)) == NULL) {
            return -1; /* handle error : no name ? */
        }
        sp += strlen(RPL_HTTP_MTP_FORM_NAME) + 1;
        if((ep = strchr(sp, '"')) == NULL) {
            return -1; /* no matching " ! */
        }
        *ep = '\0';
        key = sp;
        fp = ep + 1;
        /* capture the filename if required */
        if(strcmp(RPL_HTTP_FILE_UPLOAD_CONTROL_NAME, sp) == 0) {
            if((sp=strstr(fp, RPL_HTTP_MTP_FORM_FILENAME)) == NULL) {
                return -1; /* handle error */
            }
            sp += strlen(RPL_HTTP_MTP_FORM_FILENAME) + 1;
            if((ep = strchr(sp, '"')) == NULL) {
                return -1; /* no matching " ! */
            }
            *ep = '\0';
            fp = ep + 1;
            filename = sp;

            /* now capture the content type */
            if((sp=strstr(fp,RPL_HTTP_MTP_CONTENT_TYPE)) == NULL) {
                /* check spec - is the content type mandatory ? */
                return -1;
            }
            sp += strlen(RPL_HTTP_MTP_CONTENT_TYPE);
            ep = strchr(sp,'\n');
            ep--;
            *ep = '\0';
            fp = ep + 2;
            content_type = (rpl_str_t) rpl_me_malloc(strlen(sp) + 1);
            sprintf(content_type, "%s", sp);

            /* now capture the file itself and make a local copy */
            sp = fp;
            while((ep = strstr(sp, RPL_HTTP_HDR_CRLF)) == NULL)
                sp++;
            sp = ep + strlen(RPL_HTTP_HDR_CRLF);
            fp = sp;

            while((ep = strstr(fp, bdy)) == NULL)
                fp++;
            ep--;

            filesize = ep - sp;
            tmp_fd = mkstemp(tmp_templ);
            if (tmp_fd == -1) {
                rpl_log_fatal(rpl_message_get("FS_TEMP_FILE_FAILED", tmp_filename, RPL_EOM));
            }
            if((tmp_fp = fdopen(tmp_fd, "wb")) == NULL) {
                rpl_log_fatal(rpl_message_get("FS_TEMP_FILE_FAILED", tmp_filename, RPL_EOM));
            }
            fwrite(sp, filesize - 1, 1, tmp_fp);
            fclose(tmp_fp);

            /* record some sensible key ? */
            continue;
        }

        /* acquire the value attribute */
        if((sp = strstr(fp, RPL_HTTP_HDR_SEP)) == NULL) {
            return -1; /* unable to locate separators */
        }
        sp += strlen(RPL_HTTP_HDR_SEP);
        if((ep = strstr(sp, bdy)) == NULL) {
            return -1; /* no matching closing boundary */
        }
        *(ep--) = '\0';
        value = sp;
        fp = ep + 2;

        http_create_parameter(key, value);

    } while(fp != NULL);

    return 0;
}


Generated by  Doxygen 1.6.0   Back to index