📄 upl_plgn.c
字号:
/************************************************************************
*
* Copyright (c) 1993-2001 Accelerated Technology, Inc.
*
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the
* subject matter of this material. All manufacturing, reproduction,
* use, and sales rights pertaining to this subject matter are governed
* by the license agreement. The recipient of this software implicitly
* accepts the terms of the license.
*
*************************************************************************/
/************************************************************************
*
* FILE NAME VERSION
*
* upl_plgn.c - Upload Plugin 1.5
*
* COMPONENT
*
* Nucleus WebServ
*
* DESCRIPTION
*
* This file contains all files related to the upload plugin. To
* exclude this feature see WS_FILE_UPLOAD_PLGN defined in ws_cfg.h.
*
* DATA STRUCTURES
*
* None
*
* FUNCTIONS
*
* UPL_File_Upload Plugin to upload a file into the
* system.
* UPL_Save_Upload_File Saves an uploaded file to memory.
* UPL_Save_File Save file in memory.
*
* DEPENDENCIES
*
* ncl.h
* externs.h
* nu_websr.h
*
*************************************************************************/
#include "webserv/inc/nu_websr.h"
extern NU_MEMORY_POOL System_Memory;
#ifdef WS_FILE_UPLOAD_PLGN
static STATUS UPL_Save_File(CHAR *fname, CHAR **filemem, INT32 length);
static STATUS UPL_Save_Upload_File(WS_REQUEST * req, CHAR * fname,CHAR **filemem, INT32 length);
extern WS_FS_FILE *HTTP_Fs_File;
#define UPL_CRLFCRLF "\r\n\r\n" /* End of Entity Header Message */
#define UPL_FILE_NAME_TAG "save-as-filename"
/************************************************************************
*
* FUNCTION
*
* UPL_File_Upload
*
* DESCRIPTION
*
* This routine uploads a file to the local file system
* This feature is implememted as a plugin. To exclude
* this feature see WS_FILE_UPLOAD_PLGN defined in ws_cfg.h .
*
* INPUTS
*
* tok Pointer to Token structure that
* holds current token arguments
* (Name and Value) and pointer to
* next token arguments.
* req
*
* OUTPUTS
*
* FAILURE
*
*************************************************************************/
INT UPL_File_Upload(WS_REQUEST * req)
{
CHAR bound[64];
CHAR fname[WS_URI_LEN];
CHAR *s, *t, *l;
CHAR * fstart;
CHAR * fend;
CHAR *buffer;
CHAR *buf;
INT32 content_length;
CHAR * content_start;
CHAR * filemem= 0;
INT i;
INT32 count;
CHAR * req_buf_end;
STATUS status;
INT32 buf_bytes;
#ifdef NU_WEBSERV_DEBUG
printf("UPL_File_Upload()\n");
#endif
/* Allocate Memory for Receive Buffer */
status = NU_Allocate_Memory(&System_Memory, (VOID **)&buffer, WS_RECEIVE_SIZE, NU_NO_SUSPEND);
if( status != NU_SUCCESS)
{
HTTP_Send_Client_HTML_Msg(req,"File Upload Error-no memory");
return(WS_REQ_PROCEED);
}
/* Prepare to check first Packet of Incoming HTTP data */
s = req->ws_rdata->ws_lbuf;
/* Set the End of the Packet */
req_buf_end = &req->ws_rdata->ws_lbuf[req->ws_nbytes];
/* Get to the first Sequence delimeter CRLF */
while(*s)
s++;
/* Enter Loop to point to data */
while(1)
{
s++;
l = s;
/* Search for Mulipart/form-data Mime */
s = HTTP_Find_Token("multipart/form-data", l, req_buf_end);
if( s )
{
/* Search for the Content-Length MIME */
s = HTTP_Find_Token("Content-Length:", s, req_buf_end);
if(s)
{
/* Increment Pointer to Content String within Buffer */
s = s + 16;
/* get the length of the multiform data (with file) */
content_length = NU_ATOL(s);
#ifdef NU_WEBSERV_DEBUG
printf("Content-Length = %lu \n", content_length);
#endif
/* Look for the CRLFCRLF Token in the packet */
s = HTTP_Find_Token(UPL_CRLFCRLF, s, req_buf_end);
/* Set the Content Start for calculating the Start of
* incoming data.
*/
content_start = s + 4;
/* Search for the boundary= tag */
s = HTTP_Find_Token("boundary=", l, req_buf_end);
if( s )
{
/* Increment Pointer to the Boundary Delimeter */
s += 9;
/* Get the boundary to use for finding the End of the Data */
t = bound;
while( (*s == '"'))
s++;
while(*s && (*s != '\n') && (*s != '\r') )
{
*t++ = *s++;
}
*t= '\0';
/* Look for bound in the packet */
s = HTTP_Find_Token(bound, s, req_buf_end);
if(!s)
{
/*
* Didn't find boundary as expected get Next Packet
* and check for what is expected.
*/
i = WS_Read_Net(req, buffer, WS_RECEIVE_SIZE,
(TICKS_PER_SECOND >> 1));
if ( i <= 0)
{
HTTP_Send_Client_HTML_Msg(req, "File Upload Error-Expected Packet");
NU_Deallocate_Memory((VOID **)buffer);
return(WS_REQ_PROCEED);
}
/* Set up pointers */
s = buffer;
req_buf_end = buffer + i;
/*
* Set content_start variable to point to beginning
* of content.
*/
content_start = s;
}
/* Search for save-as-filename in packet to get to Filename */
t = HTTP_Find_Token(UPL_FILE_NAME_TAG, s, req_buf_end);
if(t)
{
/* Increment Pointer to Filename */
s = t + sizeof(UPL_FILE_NAME_TAG) + 4;
/* Get the Filename */
t = fname;
while((*s != '\n') && (*s !='\r') && (*s) )
*t++ = *s++;
*t = '\0';
/* Look for the CRLFCRLF delimeter to point to the start
* of actual packet data.
*/
s = HTTP_Find_Token(UPL_CRLFCRLF, s, req_buf_end);
/* start of the upload data */
fstart = s + 4;
/* Exit out of while loop because we are pointing at data */
break;
}
}/* If bound */
}/* s = Content-Length */
} /* T equal Multiform Data */
else
{
/* Didn't get any Relevent Data to start with so Let's try
* and get another packet.
*/
i = WS_Read_Net(req, buffer, WS_RECEIVE_SIZE, (TICKS_PER_SECOND >> 1));
if ( i <= 0)
{
HTTP_Send_Client_HTML_Msg(req, "File Upload Error-Expected Packet");
NU_Deallocate_Memory((VOID **)buffer);
return(WS_REQ_PROCEED);
}
/* Setup pointers the buffer and the end of buffer */
s = buffer;
req_buf_end = &buffer[i];
/* Go back to the top of the while loop and try again */
}/* end else */
}/* while(1) */
/* At this point we should be pointing the data in the packet or we got an
* error on reception of data. If we do not have an error then we should
* look and see if the boundary is in the buffer. If the boundary is present
* then we have the whole file in the first buffer.
*/
t = HTTP_Find_Token(bound, s, req_buf_end);
if( t )
{
/* whole file in in the first buffer */
fend = t - 2;
/* Set the number of buffer bytes left in the last packet. */
buf_bytes = fend - fstart;
/* Allocate Memory for the filemem buffer */
status = NU_Allocate_Memory(&System_Memory, (VOID **)&filemem,
(UNSIGNED)buf_bytes + 1, (UNSIGNED)NU_NO_SUSPEND);
if( status != NU_SUCCESS)
{
HTTP_Send_Client_HTML_Msg(req, "File Upload Error-no memory");
NU_Deallocate_Memory((VOID **)buffer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -