📄 sflhttp.c
字号:
f_tmp = fopen (tmp_name, "wb");
}
}
p_next = (char *) memfind ((byte *) p_data,
/* read_size */
MULTI_BUFFER_SIZE + REST_BUFFER_SIZE - (p_data - buffer),
(byte *) separator, sep_size, FALSE);
if (p_next != NULL)
{
/* The next attribute-value pair was found */
*p_next = '\0';
save_multipart_header (table, header_tab, p_data, tmp_name,
local_format);
if (f_tmp)
{
/* Special case:
The next attribute value is found AND "f_tmp" is opened.
That means that the download file is completely in the
buffer and so we can save it to disk.
*/
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);
/* Now we need to check the buffer. If the buffer is full
then we must read the rest of "f_source". The rest will
be written into the the buffer at REST_BUFFER_SIZE.
*/
if (read_size == MULTI_BUFFER_SIZE)
rest_read_size = fread (&buffer [MULTI_BUFFER_SIZE], 1,
REST_BUFFER_SIZE, f_source);
}
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)
{
/* We need to test if the buffer is large enough. If
not, we use the additional buffer size starting at
position REST_BUFFER_SIZE.
*/
if (read_size == (MULTI_BUFFER_SIZE - sep_size))
{
/* Attach the rest of the file */
rest_read_size = fread (&buffer [MULTI_BUFFER_SIZE], 1,
REST_BUFFER_SIZE, f_source);
}
*p_next = '\0';
save_multipart_header (table, header_tab,
p_data, tmp_name, local_format);
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
{
/* We did not find the next separator, so we write the
file and continue.
*/
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);
}
/* -------------------------------------------------------------------------
Function: http_multipart2url
Synopsis: Convert a symbol table to a string in format :
name=value&name=value&name=value ....
-------------------------------------------------------------------------*/
static DESCR *
http_multipart2url (const SYMTAB *symtab)
{
DESCR
*descr; /* Formatted descriptor */
SYMBOL
*symbol; /* Pointer to symbol */
char
*p_char,
*p_val;
qbyte
buffer_length = 0;
if (!symtab)
return (NULL); /* Return NULL if argument is null */
/* Calculate length of buffer */
for (symbol = symtab-> symbols; symbol; symbol = symbol-> next)
buffer_length += strlen (symbol-> name) + strlen (symbol-> value) + 2;
/* On 16-bit systems, check that buffer will fit into max. block size */
# if (UINT_MAX == 0xFFFFU)
if (buffer_length > UINT_MAX - 32)
return (NULL);
# endif
/* Now allocate the descriptor */
descr = mem_descr (NULL, (size_t) buffer_length + 1);
if (descr == NULL)
return (NULL);
p_char = (char *) descr-> data;
for (symbol = symtab-> symbols; symbol; symbol = symbol-> next)
{
if (symbol != symtab-> symbols)
*p_char++ = '&';
p_val = symbol-> name;
while (*p_val)
*p_char++ = *p_val++;
*p_char++ = '=';
p_val = symbol-> value;
while (*p_val)
*p_char++ = *p_val++;
}
*p_char = '\0';
return (descr);
}
/* -------------------------------------------------------------------------
Function: save_multipart_header
Synopsis: Store field name and value in symbol table.
-------------------------------------------------------------------------*/
static void
save_multipart_header (SYMTAB *table, SYMTAB *header, char *data,
char *tmp_name, const char *local_format)
{
SYMBOL
*sym_filename,
*symbol;
char
*copyfmt,
*percent,
*tmp_val,
*value;
/* Check if is a file uploaded or form field */
if ((sym_filename = sym_lookup_symbol (header, "filename")) != NULL)
{
symbol = sym_lookup_symbol (header, "name");
if (symbol)
{
value = http_escape (sym_filename-> value, NULL, 0);
if (value)
{
sym_assume_symbol (table, symbol-> value, value);
mem_free (value);
}
/* Construct temporary name by replacing %s in the format string
* by the variable name. We don't use sprintf because it's too
* dangerous here: the format string can cause havoc.
*/
copyfmt = mem_strdup (local_format);
percent = strchr (copyfmt, '%');
if (percent && percent [1] == 's')
{
percent [0] = '\0';
tmp_val = xstrcpy (NULL, copyfmt, symbol-> value, percent + 2, NULL);
}
else
tmp_val = xstrcpy (NULL, symbol-> value, "_tmp", NULL);
value = http_escape (tmp_name, NULL, 0);
if (value)
{
sym_assume_symbol (table, tmp_val, value);
mem_free (value);
}
mem_strfree (&tmp_val);
mem_strfree (©fmt);
}
}
else
{
symbol = sym_lookup_symbol (header, "name");
if (symbol)
{
value = http_escape (data, NULL, 0);
if (value)
{
sym_assume_symbol (table, symbol-> value, value);
mem_free (value);
}
}
}
}
/* -------------------------------------------------------------------------
Function: multipart_decode_header
Synopsis: Decode mime header of a part.
-------------------------------------------------------------------------*/
static void
multipart_decode_header (char *header, SYMTAB *table)
{
char
*p,
*variable,
*value = "";
ASSERT (header);
ASSERT (table);
p = header;
variable = header;
while (*p)
{
if ((*p == ':' && *(p + 1) == ' ')
|| *p == '=')
{
*p++ = '\0';
if (*p == ' ' || *p == '"')
p++;
value = p;
}
else
if (*p == ';' || *p == '\r'|| *p == '\n')
{
if (*(p - 1) == '"')
*(p - 1) = '\0';
else
*p = '\0';
http_unescape (value, NULL);
sym_assume_symbol (table, variable, value);
p++;
while (*p == ' ' || *p == '\r' || *p == '\n')
p++;
variable = p;
}
p++;
}
if (p != header && *(p - 1) == '"')
*(p - 1) = '\0';
http_unescape (value, NULL);
sym_assume_symbol (table, variable, value);
}
/* ---------------------------------------------------------------------[<]-
Function: is_full_url
Synopsis: If the specified URI string starts with a URL scheme, returns
TRUE, else returns FALSE. A schema is one or more of [A-Za-z0-9+-.]
followed by a ':'.
---------------------------------------------------------------------[>]-*/
Bool
is_full_url (const char *string)
{
Bool
scheme_size = 0;
ASSERT (string);
while (*string)
{
if (isalpha (*string)
|| isdigit (*string)
|| *string == '+'
|| *string == '-'
|| *string == '.')
scheme_size++; /* So far, a valid scheme name */
else
if (*string == ':')
return (scheme_size > 0); /* Okay if ':' was not first char */
else
return (FALSE); /* No scheme name found */
string++;
}
return (FALSE); /* End of string but no scheme */
}
/* ---------------------------------------------------------------------[<]-
Function: build_full_url
Synopsis: If the specified URI string does not start with a URL schema
or a directory delimiter, we add the path of the base URI, and return
the resulting full URI. This is provided as a freshly-allocated string
w
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -