#include "TSRM.h"
#endif
+#include "rfc1867.h"
+
#if WIN32||WINNT
#define STRCASECMP stricmp
#else
#define DEFAULT_POST_CONTENT_TYPE "application/x-www-form-urlencoded"
static sapi_post_content_type_reader supported_post_content_types[] = {
- { DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data },
+ { DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data },
+ { MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, rfc1867_post_reader },
{ NULL, 0, NULL }
};
#undef SAPI_POST_BLOCK_SIZE
#define SAPI_POST_BLOCK_SIZE 2
+
static void sapi_read_post_data(SLS_D)
{
sapi_post_content_type_reader *post_content_type_reader;
uint content_type_length = strlen(SG(request_info).content_type);
char *content_type = estrndup(SG(request_info).content_type, content_type_length);
-
- zend_str_tolower(content_type, content_type_length);
+ char *p;
+ char oldchar=0;
+
+ /* dedicated implementation for increased performance:
+ * - Make the content type lowercase
+ * - Trim descriptive data, stay with the content-type only
+ */
+ for (p=content_type; p<content_type+content_type_length; p++) {
+ switch (*p) {
+ case ';':
+ case ',':
+ case ' ':
+ content_type_length = p-content_type;
+ oldchar = *p;
+ *p = 0;
+ break;
+ default:
+ *p = tolower(*p);
+ break;
+ }
+ }
if (zend_hash_find(&known_post_content_types, content_type, content_type_length+1, (void **) &post_content_type_reader)==FAILURE) {
- sapi_module.sapi_error(E_CORE_ERROR, "Unsupported content type: '%s'", content_type);
+ sapi_module.sapi_error(E_COMPILE_ERROR, "Unsupported content type: '%s'", content_type);
return;
}
- post_content_type_reader->post_reader(SLS_C);
+ if (oldchar) {
+ *(p-1) = oldchar;
+ }
+ post_content_type_reader->post_reader(content_type SLS_CC);
+ efree(content_type);
}
} sapi_globals_struct;
-typedef struct _sapi_post_content_type_reader {
- char *content_type;
- uint content_type_len;
- void (*post_reader)(SLS_D);
-} sapi_post_content_type_reader;
-
-
#ifdef ZTS
# define SLS_D sapi_globals_struct *sapi_globals
# define SLS_DC , SLS_D
extern SAPI_API sapi_globals_struct sapi_globals;
#endif
+typedef struct _sapi_post_content_type_reader {
+ char *content_type;
+ uint content_type_len;
+ void (*post_reader)(char *content_type_dup SLS_DC);
+} sapi_post_content_type_reader;
+
SAPI_API void sapi_startup(sapi_module_struct *sf);
SAPI_API void sapi_activate(SLS_D);
#define SAPI_DEFAULT_CONTENT_TYPE "Content-Type: text/html"
-#define SAPI_POST_READER_FUNC(post_reader) void post_reader(SLS_D)
+#define SAPI_POST_READER_FUNC(post_reader) void post_reader(char *content_type_dup SLS_DC)
#endif /* _NEW_SAPI_H */
\ No newline at end of file
--- /dev/null
+#include "rfc1867.h"
+
+SAPI_POST_READER_FUNC(rfc1867_post_reader)
+{
+ char *boundary;
+ uint boundary_len;
+ char input_buffer[FILE_UPLOAD_INPUT_BUFFER_SIZE];
+ uint read_bytes;
+
+ boundary = strstr(content_type_dup, "boundary");
+ if (!boundary || !(boundary=strchr(boundary, '='))) {
+ sapi_module.sapi_error(E_COMPILE_ERROR, "Missing boundary in multipart/form-data POST data");
+ return;
+ }
+ boundary++;
+ boundary_len = strlen(boundary);
+
+ for (;;) {
+ read_bytes = sapi_module.read_post(input_buffer, FILE_UPLOAD_INPUT_BUFFER_SIZE-100 SLS_CC);
+ if (read_bytes<=0) {
+ break;
+ }
+ }
+}
--- /dev/null
+#ifndef _RFC1867_H
+#define _RFC1867_H
+
+#include "SAPI.h"
+
+#define MULTIPART_CONTENT_TYPE "multipart/form-data"
+
+SAPI_POST_READER_FUNC(rfc1867_post_reader);
+
+#define FILE_UPLOAD_INPUT_BUFFER_SIZE 8192
+
+#endif /* _RFC1867_H */
\ No newline at end of file
# PROP Ignore_Export_Lib 0\r
# PROP Target_Dir ""\r
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHP4DLLTS_EXPORTS" /YX /FD /c\r
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\libzend" /I "." /I "regex\\" /I "..\tsrm" /I "..\bindlib_w32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "PHP4DLLTS_EXPORTS" /D "MSVC5" /D "PHP_EXPORTS" /D "LIBZEND_EXPORTS" /D "TSRM_EXPORTS" /D "SAPI_EXPORTS" /D "ZTS" /D "WIN32" /D "_MBCS" /D ZEND_DEBUG=0 /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\libzend" /I "." /I "regex\\" /I "..\tsrm" /I "..\bindlib_w32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "PHP4DLLTS_EXPORTS" /D "MSVC5" /D "PHP_EXPORTS" /D "LIBZEND_EXPORTS" /D "TSRM_EXPORTS" /D "SAPI_EXPORTS" /D "ZTS" /D "WIN32" /D "_MBCS" /D ZEND_DEBUG=0 /FR /YX /FD /c\r
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
# ADD BASE RSC /l 0x40d /d "NDEBUG"\r
# End Source File\r
# Begin Source File\r
\r
+SOURCE=.\rfc1867.c\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=.\safe_mode.c\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
+SOURCE=.\rfc1867.h\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=.\safe_mode.h\r
# End Source File\r
# Begin Source File\r