--- postprocessor.c.orig 2012-01-30 10:05:44.000000000 -0700 +++ postprocessor.c 2012-01-30 10:06:35.000000000 -0700 @@ -39,6 +39,7 @@ enum PP_State PP_Error, PP_Done, PP_Init, + PP_NextBoundary, /* url encoding-states */ PP_ProcessValue, @@ -492,7 +493,8 @@ find_boundary (struct MHD_PostProcessor } if ((0 != memcmp ("--", buf, 2)) || (0 != memcmp (&buf[2], boundary, blen))) { - pp->state = PP_Error; + if (pp->state != PP_Init) + pp->state = PP_Error; return MHD_NO; /* expected boundary */ } /* remove boundary from buffer */ @@ -823,6 +825,25 @@ post_process_multipart (struct MHD_PostP pp->state = PP_Error; return MHD_NO; case PP_Init: + /** + * Per RFC2046 5.1.1 NOTE TO IMPLEMENTORS, consume anything + * prior to the first multipart boundary: + * + * > There appears to be room for additional information prior + * > to the first boundary delimiter line and following the + * > final boundary delimiter line. These areas should + * > generally be left blank, and implementations must ignore + * > anything that appears before the first boundary delimiter + * > line or after the last one. + */ + if (MHD_NO == find_boundary (pp, + pp->boundary, + pp->blen, + &ioff, + PP_ProcessEntryHeaders, PP_Done)) + ++ioff; + break; + case PP_NextBoundary: if (MHD_NO == find_boundary (pp, pp->boundary, pp->blen, @@ -914,7 +935,7 @@ post_process_multipart (struct MHD_PostP pp->nlen, &ioff, PP_Nested_PerformMarking, - PP_Init /* or PP_Error? */ )) + PP_NextBoundary /* or PP_Error? */ )) { if (pp->state == PP_Error) return MHD_NO; @@ -955,7 +976,7 @@ post_process_multipart (struct MHD_PostP pp->nested_boundary, pp->nlen, PP_Nested_PerformCleanup, - PP_Init)) + PP_NextBoundary)) { if (pp->state == PP_Error) return MHD_NO;