| iMatix home page
| << | < | > | >>
SFL Logo SFL
Version 1.91

 

http_multipart_decode

#include "sflhttp.h"
DESCR *
http_multipart_decode (const char *mime_file, const char *store_path)

Synopsis

Get form data from a multipart encoded data file. Each field have a entry in the symbol table. If the file content a file (INPUT field type FILE), the file is stored in a temporary file. Name of this file is added in symbol table, %variable_name%_tmp or if %variable_name% is numeric, %variable_name - 1%.

Source Code - (sflhttp.c)

{
    FILE
        *f_source,
        *f_tmp = NULL;
    char
        *tmp_name = NULL,
        *p_head,
        *p_data,
        *p_next,
        *buffer;
    int
        offset,
        read_size;
    static char
        separator [80 + 1];
    static int
        sep_size;
    SYMTAB
        *table,
        *header_tab;
    qbyte
        tmp_index = 1;
    DESCR
        *descr = NULL;

    buffer = mem_alloc (MULTI_BUFFER_SIZE + 1);
    if (buffer == NULL)
        return (NULL);

    table = sym create table ();
    if (table == NULL)
      {
        mem_free (buffer);
        return (NULL);
      }

    header_tab = sym create table ();
    if (header_tab == NULL)
      {
        mem_free (buffer);
        sym delete table (table);
        return (NULL);
      }

    f_source = fopen (mime_file, "rb");
    if (f_source == NULL)
      {
        mem_free (buffer);
        sym delete table (table);
        sym delete table (header_tab);
        return (NULL);
      }

    memset (separator, 0, sizeof (separator));
    separator [0] = 0x0D;
    separator [1] = 0x0A;
    fgets (&separator [2], 78, f_source);
    strconvch (&separator [2] , '\r', '\0');
    strconvch (&separator [2] , '\n', '\0');
    sep_size  = strlen (separator);

    read_size = fread (buffer, 1, MULTI_BUFFER_SIZE, f_source);
    p_next = buffer;
    while (read_size > 0)
      {
        sym empty table (header_tab);
        p_head = p_next;
        p_data = (char *) memfind ((byte *) p_head,
                          MULTI_BUFFER_SIZE - (p_head - buffer),
                          (byte *) "\r\n\r\n", 4, FALSE);
        if (p_data)
          {
            *p_data = '\0';
            p_data += 4;
          }
        if (p_head)
          {
            multipart_decode_header (p_head, header_tab);
            if (sym lookup symbol (header_tab, "filename") != NULL)
              {
                if (f_tmp != NULL)
                  {
                    ASSERT (tmp_name != NULL);
                    fclose (f_tmp);
                    f_tmp = NULL;
                    if (get file size (tmp_name) == 0)
                        file delete (tmp_name);
                  }
                tmp_name = get tmp file name (store_path, &tmp_index, "tmp");
                f_tmp = fopen (tmp_name, "wb");
              }
          }
        p_next = (char *) memfind ((byte *) p_data,
                          read_size - (p_data - buffer),
                          (byte *) separator, sep_size, FALSE);
        if (p_next != NULL)
          {
            *p_next = '\0';
            save_multipart_header (table, header_tab, p_data, tmp_name);
            if (f_tmp)
              {
                fwrite (p_data, p_next - p_data, 1, f_tmp);
                fclose (f_tmp);
                f_tmp = NULL;
                if (get file size (tmp_name) == 0)
                    file delete (tmp_name);
              }
            p_next += sep_size;

            /*  Found end of file marker                                     */
            if (*p_next == '-' && *(p_next + 1) == '-')
              {
                if (f_tmp)
                  {
                    fclose (f_tmp);
                    f_tmp = NULL;
                    if (get file size (tmp_name) == 0)
                        file delete (tmp_name);
                  }
                break;
              }
            else
                while (*p_next == '\r' || *p_next == '\n')
                    p_next++;
          }
        else
          {
            if (f_tmp)
                fwrite (p_data, &buffer [read_size - sep_size ] - p_data,
                        1, f_tmp);
            offset = 0;
            while (read_size > 0 && p_next == NULL)
              {
                memmove (buffer, &buffer [read_size - sep_size + offset ],
                                 sep_size);
                read_size = fread (&buffer [sep_size], 1,
                                   MULTI_BUFFER_SIZE - sep_size, f_source);
                p_next = (char *) memfind ((byte *) buffer,
                                  read_size + sep_size,
                                  (byte *) separator, sep_size, FALSE);
                if (p_next != NULL)
                  {
                    *p_next = '\0';
                    save_multipart_header (table, header_tab,
                                           p_data, tmp_name);
                    if (f_tmp)
                      {
                        fwrite (buffer, p_next - buffer, 1, f_tmp);
                        fclose (f_tmp);
                        f_tmp = NULL;
                        if (get file size (tmp_name) == 0)
                            file delete (tmp_name);
                      }
                    p_next += sep_size;

                   /*  Found end of file marker                              */
                   if (*p_next == '-' && *(p_next + 1) == '-')
                     {
                       read_size = 0;
                       break;
                     }
                   else
                       while (*p_next == '\r' || *p_next == '\n')
                           p_next++;
                   read_size += sep_size;
                  }
                else
                  {
                    if (f_tmp)
                        fwrite (buffer, read_size, 1, f_tmp);
                    offset = sep_size;
                  }

              }
          }
      }
    if (f_tmp)
      {
        fclose (f_tmp);
        if (get file size (tmp_name) == 0)
            file delete (tmp_name);
      }
    sym delete table (header_tab);
    fclose (f_source);
    mem_free (buffer);

    descr = http_multipart2url (table);
    sym delete table (table);

    return (descr);
}

| << | < | > | >> iMatix Copyright © 1996-98 iMatix