forked from xuos/WebNet_XiUOS
773 lines
23 KiB
C
773 lines
23 KiB
C
/*
|
|
* File : wn_module_upload.c
|
|
* This file is part of RT-Thread RTOS
|
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
|
*
|
|
* This software is dual-licensed: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation. For the terms of this
|
|
* license, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* You are free to use this software under the terms of the GNU General
|
|
* Public License, but WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
* See the GNU General Public License for more details.
|
|
*
|
|
* Alternatively for commercial application, you can contact us
|
|
* by email <business@rt-thread.com> for commercial license.
|
|
*
|
|
* Change Logs:
|
|
* Date Author Notes
|
|
* 2022-05-09 chunyexixiaoyu the version transplanted from rt-thread
|
|
*/
|
|
#include <transform.h>
|
|
#include <webnet.h>
|
|
#include <wn_module.h>
|
|
#include <wn_utils.h>
|
|
|
|
#if defined(WEBNET_USING_UPLOAD)
|
|
|
|
#define MULTIPART_FORM_DATA_STRING "multipart/form-data"
|
|
#define BOUNDARY_STRING "boundary="
|
|
#define CONTENT_DISPOSITION_STRING "Content-Disposition:"
|
|
#define CONTENT_TYPE_STRING "Content-Type:"
|
|
#define CONTENT_RANGE_STRING "Content-Range:"
|
|
#define FORM_DATA_STRING "form-data"
|
|
#define FILENAME_STRING "filename=\""
|
|
#define FIELDNAME_STRING "name=\""
|
|
|
|
#define FIRST_BOUNDARY 2, upload_session->boundary, "\r\n"
|
|
#define NORMAL_BOUNDARY 3, "\r\n", upload_session->boundary, "\r\n"
|
|
#define COMMON_BOUNDARY 2, "\r\n", upload_session->boundary
|
|
#define LAST_BOUNDARY 3, "\r\n", upload_session->boundary, "--\r\n"
|
|
#define FIRST_BOUNDARY_SIZE (strlen(upload_session->boundary) + 2)
|
|
#define NORMAL_BOUNDARY_SIZE (strlen(upload_session->boundary) + 4)
|
|
#define COMMON_BOUNDARY_SIZE (strlen(upload_session->boundary) + 2)
|
|
#define LAST_BOUNDARY_SIZE (strlen(upload_session->boundary) + 6)
|
|
|
|
struct webnet_upload_name_entry
|
|
{
|
|
char *name;
|
|
char *value;
|
|
};
|
|
static const struct webnet_module_upload_entry **_upload_entries = NULL;
|
|
static uint16 _upload_entries_count = 0;
|
|
|
|
struct webnet_module_upload_session
|
|
{
|
|
char* boundary;
|
|
|
|
char* filename;
|
|
char* content_type;
|
|
|
|
struct webnet_upload_name_entry* name_entries;
|
|
uint16 name_entries_count;
|
|
uint16 file_opened;
|
|
|
|
/* upload entry */
|
|
const struct webnet_module_upload_entry* entry;
|
|
|
|
/* user data */
|
|
uint32 user_data;
|
|
};
|
|
|
|
static int str_begin_with_strs(const char* str, int num, ...)
|
|
{
|
|
char *match;
|
|
va_list args;
|
|
int index, result;
|
|
|
|
result = 1;
|
|
va_start(args,num);
|
|
for (index = 0; index < num; index ++)
|
|
{
|
|
match = va_arg(args, char*);
|
|
if (strncasecmp(str, match, strlen(match)) != 0)
|
|
{
|
|
result = 0;
|
|
break;
|
|
}
|
|
|
|
str += strlen(match);
|
|
}
|
|
va_end(args);
|
|
|
|
return result;
|
|
}
|
|
|
|
/* Search string on binary data */
|
|
static char *memstr(const char *haystack, uint32 length, const char *needle)
|
|
{
|
|
uint32 nl=strlen(needle);
|
|
uint32 hl=length;
|
|
uint32 i;
|
|
|
|
if (!nl) goto __found;
|
|
if (nl > length) return 0;
|
|
|
|
for (i=hl-nl+1; i; --i)
|
|
{
|
|
if (*haystack==*needle && !memcmp(haystack,needle,nl))
|
|
__found:
|
|
return (char*)haystack;
|
|
++haystack;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Search string array on binary data */
|
|
static char* memstrs(const char* str, uint32 length, int num, ...)
|
|
{
|
|
char *substr;
|
|
char *index_str, *ptr;
|
|
|
|
va_list args;
|
|
int index;
|
|
int total_size;
|
|
|
|
/* get the match total string length */
|
|
va_start(args, num);
|
|
total_size = 0;
|
|
for (index = 0; index < num; index ++)
|
|
{
|
|
index_str = va_arg(args, char*);
|
|
total_size += strlen(index_str);
|
|
}
|
|
va_end(args);
|
|
|
|
substr = wn_malloc(total_size + 1);
|
|
ptr = substr;
|
|
va_start(args, num);
|
|
for (index = 0; index < num; index++)
|
|
{
|
|
index_str = va_arg(args, char*);
|
|
memcpy(ptr, index_str, strlen(index_str));
|
|
ptr += strlen(index_str);
|
|
}
|
|
substr[total_size] = '\0';
|
|
va_end(args);
|
|
|
|
/* find in binary data */
|
|
ptr = memstr(str, length, substr);
|
|
wn_free(substr);
|
|
|
|
return ptr;
|
|
}
|
|
|
|
#if !(defined(__GNUC__) && !defined(__ARMCC_VERSION)/*GCC*/)
|
|
static void* memrchr(const void *s, int c, uint32 n)
|
|
{
|
|
register const char* t=s;
|
|
register const char* last=0;
|
|
int i;
|
|
|
|
t = t + n;
|
|
for (i=n; i; --i)
|
|
{
|
|
if (*t==c)
|
|
{
|
|
last=t;
|
|
break;
|
|
}
|
|
t--;
|
|
}
|
|
return (void*)last; /* man, what an utterly b0rken prototype */
|
|
}
|
|
#endif
|
|
|
|
static char* _webnet_module_upload_parse_header(struct webnet_session* session, char* buffer, uint32 length)
|
|
{
|
|
char *ptr, *ch, *end_ptr;
|
|
struct webnet_module_upload_session *upload_session;
|
|
char *name = NULL, *filename = NULL, *content_type = NULL;
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
|
|
ptr = buffer;
|
|
end_ptr = buffer + length;
|
|
/* begin with last boundary */
|
|
if (str_begin_with_strs(ptr, LAST_BOUNDARY))
|
|
{
|
|
ptr += LAST_BOUNDARY_SIZE;
|
|
return ptr;
|
|
}
|
|
/* begin with normal boundary */
|
|
if (str_begin_with_strs(ptr, NORMAL_BOUNDARY))
|
|
ptr += NORMAL_BOUNDARY_SIZE;
|
|
else if (str_begin_with_strs(ptr, FIRST_BOUNDARY))
|
|
ptr += FIRST_BOUNDARY_SIZE;
|
|
if (ptr == buffer) return NULL; /* not begin with boundary */
|
|
|
|
if (upload_session->filename != NULL &&
|
|
upload_session->content_type != NULL)
|
|
{
|
|
/* end of file name section */
|
|
wn_free(upload_session->filename);
|
|
wn_free(upload_session->content_type);
|
|
|
|
upload_session->filename = NULL;
|
|
upload_session->content_type = NULL;
|
|
}
|
|
|
|
while ((uint32)ptr - (uint32)buffer < length)
|
|
{
|
|
/* handle Content-Disposition: */
|
|
if (str_begin_with(ptr, CONTENT_DISPOSITION_STRING))
|
|
{
|
|
ptr += sizeof(CONTENT_DISPOSITION_STRING) - 1;
|
|
while (*ptr == ' ') ptr ++;
|
|
|
|
/* form-data */
|
|
if (str_begin_with(ptr, FORM_DATA_STRING))
|
|
{
|
|
ptr += sizeof(FORM_DATA_STRING) - 1;
|
|
while (*ptr == ' ' || *ptr == ';') ptr ++;
|
|
|
|
/* get name="str" */
|
|
if (str_begin_with(ptr, FIELDNAME_STRING))
|
|
{
|
|
ptr += sizeof(FIELDNAME_STRING) - 1;
|
|
name = ptr;
|
|
|
|
ch = memchr(ptr, '"', buffer - ptr);
|
|
if (ch != NULL)
|
|
{
|
|
*ch = '\0';
|
|
ch ++;
|
|
while (*ch == ' ' || *ch ==';') ch ++;
|
|
|
|
ptr = ch;
|
|
}
|
|
}
|
|
|
|
/* get filename="str" */
|
|
if (str_begin_with(ptr, FILENAME_STRING))
|
|
{
|
|
ptr += sizeof(FILENAME_STRING) - 1;
|
|
filename = ptr;
|
|
|
|
ch = memchr(ptr, '"', buffer - ptr);
|
|
if (ch != NULL)
|
|
{
|
|
*ch = '\0';
|
|
ch ++;
|
|
ptr = ch;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* handle Content-Type */
|
|
else if (str_begin_with(ptr, CONTENT_TYPE_STRING))
|
|
{
|
|
ptr += sizeof(CONTENT_TYPE_STRING) - 1;
|
|
while (*ptr == ' ') ptr ++;
|
|
|
|
content_type = ptr;
|
|
}
|
|
/* handle Content-Range: */
|
|
else if (str_begin_with(ptr, CONTENT_RANGE_STRING))
|
|
{
|
|
ptr += sizeof(CONTENT_RANGE_STRING) - 1;
|
|
while (*ptr == ' ') ptr ++;
|
|
}
|
|
/* whether end of header */
|
|
else if (str_begin_with(ptr, "\r\n"))
|
|
{
|
|
ptr += 2;
|
|
|
|
if (upload_session->filename != NULL)
|
|
{
|
|
wn_free(upload_session->filename);
|
|
upload_session->filename = NULL;
|
|
}
|
|
if (upload_session->content_type != NULL)
|
|
{
|
|
wn_free(upload_session->content_type);
|
|
upload_session->content_type = NULL;
|
|
}
|
|
|
|
if (filename != NULL)
|
|
{
|
|
upload_session->filename = wn_strdup(filename);
|
|
}
|
|
if (content_type != NULL)
|
|
{
|
|
upload_session->content_type = wn_strdup(content_type);
|
|
}
|
|
if (name != NULL)
|
|
{
|
|
/* add a name entry in the upload session */
|
|
if (upload_session->name_entries == NULL)
|
|
{
|
|
upload_session->name_entries_count = 1;
|
|
upload_session->name_entries = (struct webnet_upload_name_entry*)
|
|
wn_malloc(sizeof(struct webnet_upload_name_entry));
|
|
}
|
|
else
|
|
{
|
|
upload_session->name_entries_count += 1;
|
|
upload_session->name_entries = (struct webnet_upload_name_entry*)
|
|
wn_realloc(upload_session->name_entries,
|
|
sizeof(struct webnet_upload_name_entry) * upload_session->name_entries_count);
|
|
}
|
|
|
|
upload_session->name_entries[upload_session->name_entries_count - 1].name = wn_strdup(name);
|
|
upload_session->name_entries[upload_session->name_entries_count - 1].value = NULL;
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
/* skip this request header line */
|
|
ch = memstr(ptr, end_ptr - ptr, "\r\n");
|
|
*ch = '\0';
|
|
ch ++;
|
|
*ch = '\0';
|
|
ch ++;
|
|
ptr = ch;
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
static char* _next_possible_boundary(struct webnet_session* session, char* buffer, uint32 length)
|
|
{
|
|
char *ptr;
|
|
struct webnet_module_upload_session *upload_session;
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
|
|
/* try the beginning */
|
|
if (str_begin_with_strs(buffer, COMMON_BOUNDARY)) return buffer;
|
|
/* search in all the string */
|
|
ptr = memstrs(buffer, length, COMMON_BOUNDARY);
|
|
if (ptr != NULL) return ptr;
|
|
|
|
/* search from the end of string */
|
|
ptr = memrchr(buffer, '\r', length);
|
|
if (ptr == NULL ) return NULL;
|
|
if (ptr - buffer == length - 1) return ptr; /* only \r */
|
|
if (*(ptr + 1) == '\n' && ptr - buffer == length - 2) return NULL; /* only \r\n */
|
|
|
|
if (memcmp(ptr + 2, upload_session->boundary, length - (ptr - buffer + 2)) == 0) return ptr;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void _handle_section(struct webnet_session* session, char* buffer, uint32 length)
|
|
{
|
|
char *ptr;
|
|
struct webnet_module_upload_session *upload_session;
|
|
|
|
#define name_entry \
|
|
(upload_session->name_entries[upload_session->name_entries_count - 1])
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
if (upload_session->filename != NULL &&
|
|
upload_session->content_type != NULL&&
|
|
length != 0)
|
|
{
|
|
upload_session->entry->upload_write(session, buffer, length);
|
|
}
|
|
else
|
|
{
|
|
/* get name value */
|
|
ptr = memstr(buffer, length, "\r\n");
|
|
if (ptr != NULL)
|
|
{
|
|
int value_size = ptr - buffer + 1;
|
|
name_entry.value = wn_malloc(value_size);
|
|
memcpy(name_entry.value, buffer, value_size - 1);
|
|
name_entry.value[value_size - 1] = '\0';
|
|
}
|
|
}
|
|
}
|
|
|
|
static void _webnet_module_upload_handle(struct webnet_session* session, int event)
|
|
{
|
|
int length;
|
|
char *ptr, *end_ptr;
|
|
char *upload_buffer;
|
|
uint32 chunk_size;
|
|
struct webnet_module_upload_session *upload_session;
|
|
|
|
if (event != WEBNET_EVENT_READ) return;
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
upload_buffer = (char*)session->buffer;
|
|
|
|
/* read stream */
|
|
if (memstrs((const char *)session->buffer, session->buffer_offset, LAST_BOUNDARY))
|
|
{
|
|
length = session->buffer_offset;
|
|
}
|
|
else
|
|
{
|
|
if (session->buffer_offset != 0)
|
|
{
|
|
length = webnet_session_read(session,
|
|
(char*)&session->buffer[session->buffer_offset],
|
|
sizeof(session->buffer) - session->buffer_offset - 1);
|
|
if (length > 0)
|
|
{
|
|
length += session->buffer_offset;
|
|
}
|
|
else
|
|
{
|
|
length = session->buffer_offset;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
length = webnet_session_read(session, (char *)session->buffer, sizeof(session->buffer) - 1);
|
|
}
|
|
}
|
|
|
|
/* connection break out */
|
|
if (length <= 0)
|
|
{
|
|
/* read stream failed (connection break out), close this session */
|
|
session->session_phase = WEB_PHASE_CLOSE;
|
|
return;
|
|
}
|
|
end_ptr = (char*)(session->buffer + length);
|
|
|
|
session->buffer[length] = '\0';
|
|
while (upload_buffer < end_ptr)
|
|
{
|
|
if (str_begin_with_strs(upload_buffer, LAST_BOUNDARY))
|
|
{
|
|
/* upload done */
|
|
upload_session->entry->upload_done(session);
|
|
session->session_phase = WEB_PHASE_CLOSE;
|
|
return;
|
|
}
|
|
|
|
/* read more data */
|
|
if (end_ptr - upload_buffer < sizeof(session->buffer)/3 &&
|
|
memstrs(upload_buffer, end_ptr - upload_buffer, LAST_BOUNDARY) == NULL)
|
|
{
|
|
/* read more data */
|
|
memmove(session->buffer, upload_buffer, end_ptr - upload_buffer);
|
|
session->buffer_offset = end_ptr - upload_buffer;
|
|
return ;
|
|
}
|
|
|
|
ptr = _webnet_module_upload_parse_header(session, upload_buffer,
|
|
(uint32)end_ptr - (uint32)upload_buffer);
|
|
if (ptr == NULL)
|
|
{
|
|
/* not begin with a boundary */
|
|
ptr = _next_possible_boundary(session, upload_buffer,
|
|
(uint32)end_ptr - (uint32)upload_buffer);
|
|
if (ptr == NULL)
|
|
{
|
|
/* all are the data section */
|
|
_handle_section(session, upload_buffer, (uint32)end_ptr - (uint32)upload_buffer);
|
|
upload_buffer = end_ptr;
|
|
}
|
|
else
|
|
{
|
|
chunk_size = (uint32)ptr - (uint32)upload_buffer;
|
|
_handle_section(session, upload_buffer, chunk_size);
|
|
upload_buffer += chunk_size;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (upload_session->filename != NULL &&
|
|
upload_session->content_type != NULL)
|
|
{
|
|
if (upload_session->file_opened == 0)
|
|
{
|
|
/* open file */
|
|
upload_session->user_data = upload_session->entry->upload_open(session);
|
|
upload_session->file_opened = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (upload_session->file_opened == 1)
|
|
{
|
|
/* close file */
|
|
upload_session->entry->upload_close(session);
|
|
upload_session->user_data = 0;
|
|
upload_session->file_opened = 0;
|
|
}
|
|
}
|
|
|
|
upload_buffer = ptr;
|
|
ptr = _next_possible_boundary(session, upload_buffer,
|
|
(uint32)end_ptr - (uint32)upload_buffer);
|
|
if (ptr == NULL)
|
|
{
|
|
/* all are the data section */
|
|
_handle_section(session, upload_buffer, (uint32)end_ptr - (uint32)upload_buffer);
|
|
upload_buffer = end_ptr;
|
|
}
|
|
else
|
|
{
|
|
chunk_size = (uint32)ptr - (uint32)upload_buffer;
|
|
_handle_section(session, upload_buffer, chunk_size);
|
|
upload_buffer += chunk_size;
|
|
}
|
|
}
|
|
}
|
|
|
|
session->buffer_offset = 0;
|
|
}
|
|
|
|
static void _webnet_module_upload_close(struct webnet_session* session)
|
|
{
|
|
struct webnet_module_upload_session *upload_session;
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
if (upload_session == NULL) return;
|
|
|
|
/* close file */
|
|
if (upload_session->file_opened == 1)
|
|
{
|
|
upload_session->entry->upload_close(session);
|
|
upload_session->file_opened = 0;
|
|
}
|
|
|
|
/* free session */
|
|
if (upload_session->filename != NULL)
|
|
wn_free(upload_session->filename);
|
|
if (upload_session->content_type != NULL)
|
|
wn_free(upload_session->content_type);
|
|
if (upload_session->boundary != NULL)
|
|
wn_free(upload_session->boundary);
|
|
if (upload_session->entry != NULL)
|
|
{
|
|
uint32 index;
|
|
for (index = 0; index < upload_session->name_entries_count; index ++)
|
|
{
|
|
if (upload_session->name_entries[index].value != NULL)
|
|
wn_free(upload_session->name_entries[index].value);
|
|
if (upload_session->name_entries[index].name != NULL)
|
|
wn_free(upload_session->name_entries[index].name);
|
|
}
|
|
wn_free(upload_session->name_entries);
|
|
upload_session->name_entries = NULL;
|
|
}
|
|
wn_free(upload_session);
|
|
|
|
/* remove private data */
|
|
session->user_data = 0;
|
|
session->session_ops = NULL;
|
|
session->session_phase = WEB_PHASE_CLOSE;
|
|
}
|
|
|
|
static const struct webnet_session_ops _upload_ops =
|
|
{
|
|
_webnet_module_upload_handle,
|
|
_webnet_module_upload_close
|
|
};
|
|
|
|
int webnet_module_upload_open(struct webnet_session* session)
|
|
{
|
|
char* boundary;
|
|
uint32 index, length;
|
|
const struct webnet_module_upload_entry *entry = NULL;
|
|
struct webnet_module_upload_session *upload_session;
|
|
|
|
if (session->request->method != WEBNET_POST)
|
|
return WEBNET_MODULE_CONTINUE;
|
|
|
|
/* get upload entry */
|
|
for (index = 0; index < _upload_entries_count; index ++)
|
|
{
|
|
if (str_begin_with(session->request->path, _upload_entries[index]->url))
|
|
{
|
|
length = strlen(_upload_entries[index]->url);
|
|
if (session->request->path[length] == '\0' ||
|
|
session->request->path[length] == '?')
|
|
{
|
|
/* found entry */
|
|
entry = _upload_entries[index];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (entry == NULL) /* no this entry */
|
|
return WEBNET_MODULE_CONTINUE;
|
|
|
|
/* create a uploading session */
|
|
upload_session = (struct webnet_module_upload_session*) wn_malloc (
|
|
sizeof (struct webnet_module_upload_session));
|
|
if (upload_session == NULL) return 0; /* no memory */
|
|
|
|
/* get boundary */
|
|
boundary = strstr(session->request->content_type, BOUNDARY_STRING);
|
|
if (boundary != NULL)
|
|
{
|
|
int boundary_size;
|
|
|
|
/* make boundary */
|
|
boundary_size = strlen(boundary + sizeof(BOUNDARY_STRING) - 1) + 3;
|
|
upload_session->boundary = wn_malloc(boundary_size);
|
|
sprintf(upload_session->boundary, "--%s", boundary + sizeof(BOUNDARY_STRING) - 1);
|
|
}
|
|
upload_session->filename = NULL;
|
|
upload_session->content_type = NULL;
|
|
upload_session->name_entries = NULL;
|
|
upload_session->name_entries_count = 0;
|
|
upload_session->file_opened = 0;
|
|
upload_session->entry = entry;
|
|
upload_session->user_data = 0;
|
|
|
|
/* add this upload session into webnet session */
|
|
session->user_data = (uint32) upload_session;
|
|
/* set webnet session operations */
|
|
session->session_ops = &_upload_ops;
|
|
|
|
session->session_ops->session_handle(session, WEBNET_EVENT_READ);
|
|
|
|
return WEBNET_MODULE_FINISHED;
|
|
}
|
|
|
|
int webnet_module_upload(struct webnet_session* session, int event)
|
|
{
|
|
if (event == WEBNET_EVENT_URI_PHYSICAL)
|
|
{
|
|
return webnet_module_upload_open(session);
|
|
}
|
|
|
|
return WEBNET_MODULE_CONTINUE;
|
|
}
|
|
|
|
/* webnet upload module APIs */
|
|
void webnet_upload_add(const struct webnet_module_upload_entry* entry)
|
|
{
|
|
if (_upload_entries == NULL)
|
|
{
|
|
_upload_entries_count = 1;
|
|
|
|
/* first entries, malloc upload entry */
|
|
_upload_entries = (const struct webnet_module_upload_entry**)
|
|
wn_malloc (sizeof(struct webnet_module_upload_entry));
|
|
}
|
|
else
|
|
{
|
|
_upload_entries_count += 1;
|
|
_upload_entries = (const struct webnet_module_upload_entry**) wn_realloc (_upload_entries,
|
|
sizeof(void*) * _upload_entries_count);
|
|
}
|
|
assert(_upload_entries != NULL);
|
|
|
|
_upload_entries[_upload_entries_count - 1] = entry;
|
|
}
|
|
|
|
const char* webnet_upload_get_filename(struct webnet_session* session)
|
|
{
|
|
struct webnet_module_upload_session *upload_session;
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
if (upload_session == NULL) return NULL;
|
|
|
|
return upload_session->filename;
|
|
}
|
|
|
|
|
|
const char* webnet_upload_get_content_type(struct webnet_session* session)
|
|
{
|
|
struct webnet_module_upload_session *upload_session;
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
if (upload_session == NULL) return NULL;
|
|
|
|
return upload_session->content_type;
|
|
}
|
|
|
|
|
|
const char* webnet_upload_get_nameentry(struct webnet_session* session, const char* name)
|
|
{
|
|
uint32 index;
|
|
struct webnet_module_upload_session *upload_session;
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
if (upload_session == NULL) return NULL;
|
|
|
|
for (index = 0; index < upload_session->name_entries_count; index ++)
|
|
{
|
|
if (strcasecmp(upload_session->name_entries[index].name, name) == 0)
|
|
{
|
|
return upload_session->name_entries[index].value;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
const void* webnet_upload_get_userdata(struct webnet_session* session)
|
|
{
|
|
struct webnet_module_upload_session *upload_session;
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
if (upload_session == NULL) return NULL;
|
|
|
|
return (const void*) upload_session->user_data;
|
|
}
|
|
|
|
/* ---- upload file interface ---- */
|
|
int webnet_upload_file_open(struct webnet_session* session)
|
|
{
|
|
struct webnet_module_upload_session* upload_session;
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
if (upload_session->filename != NULL)
|
|
{
|
|
/* open file */
|
|
upload_session->user_data = open(upload_session->filename, O_WRONLY, 0);
|
|
return upload_session->user_data;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int webnet_upload_file_close(struct webnet_session* session)
|
|
{
|
|
int fd;
|
|
struct webnet_module_upload_session* upload_session;
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
fd = upload_session->user_data;
|
|
if (fd >= 0)
|
|
{
|
|
return close(fd);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int webnet_upload_file_write(struct webnet_session* session, const void* data, unsigned long length)
|
|
{
|
|
int fd;
|
|
struct webnet_module_upload_session* upload_session;
|
|
|
|
/* get upload session */
|
|
upload_session = (struct webnet_module_upload_session *)session->user_data;
|
|
fd = upload_session->user_data;
|
|
if (fd >= 0)
|
|
{
|
|
return write(fd, data, length);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif /* WEBNET_USING_UPLOAD */
|