📄 cgiparsem.c
字号:
//--------------------------------------------------------------------------
// IP Stack CGI Demonstration Program
//--------------------------------------------------------------------------
// cgiparsem.c
//
// Multipart CGI Parsing for "multipart/form-data" forms
//
// Author: Michael A. Denio
//
// Copyright 2003 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <netmain.h>
#include <_stack.h>
#include "cgiparsem.h"
//
// myscan()
//
// Simple scan function. Returns the index of the start of
// the terminator from the beginning of the buffer.
//
static int myscan( char *buffer, char *terminator, int buflen )
{
int i,len;
len = strlen( terminator );
buflen -= len;
for( i=0; buflen>=0; i++, buflen-- )
{
if( !strncmp( buffer+i, terminator, len ) )
return(i);
}
return(-1);
}
static char *CGI_CRLF = "\r\n";
//
// cgiParseMultiVars()
//
// This function is used to parse CGI data sent in the "multipart/form-data"
// format. The caller must pass in the entire CGI payload as a single buffer.
// The buffer will altered to add NULL termination to all names, types, and
// data fields.
//
// Returns the number of validated records, or -1 on parsing error.
//
int cgiParseMultiVars( char *buffer, int buflen, CGIPARSEREC *recs, int maxrecs )
{
char *divider;
int i,numrecs,fname;
char *tstr,*tmark,*tmarkv;
int tlen,divlen;
char c;
// Clear out the entire recs[] array
mmZeroInit( recs, sizeof(CGIPARSEREC) * maxrecs );
// First, read in our divider. The buffer must start with "--".
if( *buffer!='-' || *(buffer+1)!='-' )
return(-1);
// Scan for "\r\n" and put in "divider"
i = myscan( buffer, CGI_CRLF, buflen );
if( i < 3 ) // Minimum divider is "--?"
return(-1);
divider = buffer;
divlen = i;
*(divider+i) = 0; // Null terminate the string
buffer += i+2; // Step past the "/r/n"
buflen -= i+2;
numrecs = 0;
fname = 0;
for( ;; )
{
// Scan in the next token
i = myscan( buffer, CGI_CRLF, buflen );
if( i < 0 )
return(-1);
// If i==0, then we hit a "/r/n/r/n", in which case the
// next field should be the data.
if( !i )
{
buffer += 2; // Step past the "/r/n"
buflen -= 2;
// We must have read a name by now or we have an error
if( !fname )
return(-1);
// Scan for the divider
i = myscan( buffer, divider, buflen );
if( i < 2 ) // Minimum is "/r/nDivider"
return(-1);
// Two chars before divider must be "/r/n"
if( *(buffer+i-2)!='\r' || *(buffer+i-1)!='\n' )
return(-1);
// Null terminate and record info
*(buffer+i-2) = 0;
(recs+numrecs)->Data = buffer;
(recs+numrecs)->DataSize = i-2;
// We're done with this record
if( ++numrecs == maxrecs )
return( numrecs );
// Step past the data and the divider
buffer += i+divlen;
buflen -= i+divlen;
// This scan must be either "2" or Zero
i = myscan( buffer, CGI_CRLF, buflen );
if( i==2 )
{
// This may be the real terminator. At the end of
// the buffer, the data should be "--/r/n", so...
if( *buffer=='-' && *(buffer+1)=='-' )
return( numrecs );
else
return( -1 );
}
if( i!=0 )
return( -1 );
// Setup for next record
fname = 0;
buffer += 2;
buflen -= 2;
continue;
}
//
// Here we have a tag that precedes the data. The tag starts
// at [buffer], and is [i] characters in length.
//
// See if the tag is "Content-Disposition:"
//
if( !strncmp( buffer, "Content-Disposition:", 20 ) )
{
// We now do a sub-parsing on this string
tstr = buffer+20;
tlen = i-20;
// Step the main status beyond this tag
buffer += i+2; // Step past the "/r/n"
buflen -= i+2;
// Sub-parse the tag
tmark = tstr;
while( tlen > 0 )
{
c = *tstr++;
tlen--;
if( c==' ' || c==';' )
tmark = tstr;
if( c=='=' )
{
// Null terminate the field name
*(tstr-1) = 0;
// Find the quotes
tmarkv = 0;
i = 0;
while( tlen > 0 )
{
c = *tstr++;
tlen--;
if( c=='"' )
{
if( ++i == 1 )
tmarkv = tstr;
else
break;
}
}
// If we didn't get two quotes, we have an error
if( i != 2 )
return(-1);
// Null terminate the field value
*(tstr-1) = 0;
// We look for "name" and "filename" strings
if( !strcmp( tmark, "name" ) )
{
(recs+numrecs)->Name = tmarkv;
fname = 1;
}
if( !strcmp( tmark, "filename" ) )
(recs+numrecs)->Filename = tmarkv;
}
}
continue;
}
//
// See if the tag is "Content-Type:"
//
if( !strncmp( buffer, "Content-Type:", 13 ) )
{
// We now do a sub-parsing on this string
tstr = buffer+13;
tlen = i-13;
// Step the main status beyond this tag
buffer += i+2; // Step past the "/r/n"
buflen -= i+2;
// Here we'll just remove any leading spaces
while( *tstr == ' ' )
{
tstr++;
tlen--;
}
// Null terminate the string
*(buffer-2) = 0;
// Record it
(recs+numrecs)->Type = tstr;
continue;
}
// This is a tag we don't care about - just step past it
buffer += i+2; // Step past the "/r/n"
buflen -= i+2;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -