int MultipartFormPeek(MultipartFormRef const form, MultipartEvent *const type, uv_buf_t *const buf) { if(!form) return UV_EINVAL; if(!type) return UV_EINVAL; if(!buf) return UV_EINVAL; uv_buf_t raw[1]; HTTPEvent t; int rc; ssize_t len; for(;;) { if(MultipartNothing != form->type) break; rc = HTTPConnectionPeek(form->conn, &t, raw); if(rc < 0) return rc; if(HTTPMessageEnd == t) { *raw = uv_buf_init(NULL, 0); t = HTTPBody; } if(HTTPBody != t) { assertf(0, "Multipart unexpected HTTP event: %d\n", t); return UV_UNKNOWN; } len = multipart_parser_execute(form->parser, raw->base, raw->len); if(len < 0) { alogf("Multipart parse error\n"); return -1; } HTTPConnectionPop(form->conn, len); } assertf(MultipartNothing != form->type, "MultipartFormPeek must return an event"); *type = form->type; *buf = *form->out; return 0; }
int main() { int i = 0; const char *boundary = "------WebKitFormBoundaryakSAdU8jNn0LWuxK"; multipart_parser *mtp = multipart_parser_init(boundary, &mt_parser_settings); i = multipart_parser_execute(mtp, post_data, sizeof(post_data)); fprintf(stderr, "res %d , boundary len %lu\n", i, strlen(boundary)); return 0; }
TEST_P(extractMultipartParamTest, extract_multipart) { size_t consumed = 0; multipartParam const & p = GetParam(); parser = multipart_parser_create(p.boundary, strlen(p.boundary), &setting); ASSERT_NE(parser, (multipart_parser*)NULL); multipart_parser_set_data(parser, this); for(int i=0; i < p.bufcnt; i++){ ASSERT_TRUE(bufused + strlen(p.bufs[i]) < buflen); memcpy(buf+bufused, p.bufs[i], strlen(p.bufs[i])); bufused += strlen(p.bufs[i]); consumed = multipart_parser_execute(parser, buf + total_consumed, bufused - total_consumed); total_consumed += consumed; } ASSERT_EQ(cksum, p.expected_cksum); }
int multipart_parse(evhtp_request_t *req, const char *content_type, const char *address, const char *buff, int post_size) { int err_no = 0; char *boundary = NULL, *boundary_end = NULL; char *boundaryPattern = NULL; int boundary_len = 0; mp_arg_t *mp_arg = NULL; evbuffer_add_printf(req->buffer_out, "<html>\n<head>\n" "<title>Upload Result</title>\n" "</head>\n" "<body>\n" ); if(strstr(content_type, "boundary") == 0) { LOG_PRINT(LOG_DEBUG, "boundary NOT found!"); LOG_PRINT(LOG_ERROR, "%s fail post parse", address); err_no = 6; goto done; } boundary = strchr(content_type, '='); boundary++; boundary_len = strlen(boundary); if(boundary[0] == '"') { boundary++; boundary_end = strchr(boundary, '"'); if (!boundary_end) { LOG_PRINT(LOG_DEBUG, "Invalid boundary in multipart/form-data POST data"); LOG_PRINT(LOG_ERROR, "%s fail post parse", address); err_no = 6; goto done; } } else { /* search for the end of the boundary */ boundary_end = strpbrk(boundary, ",;"); } if (boundary_end) { boundary_end[0] = '\0'; boundary_len = boundary_end-boundary; } LOG_PRINT(LOG_DEBUG, "boundary Find. boundary = %s", boundary); boundaryPattern = (char *)malloc(boundary_len + 3); if(boundaryPattern == NULL) { LOG_PRINT(LOG_DEBUG, "boundarypattern malloc failed!"); LOG_PRINT(LOG_ERROR, "%s fail malloc", address); err_no = 0; goto done; } snprintf(boundaryPattern, boundary_len + 3, "--%s", boundary); LOG_PRINT(LOG_DEBUG, "boundaryPattern = %s, strlen = %d", boundaryPattern, (int)strlen(boundaryPattern)); multipart_parser* parser = multipart_parser_init(boundaryPattern); if(!parser) { LOG_PRINT(LOG_DEBUG, "Multipart_parser Init Failed!"); LOG_PRINT(LOG_ERROR, "%s fail post save", address); err_no = 0; goto done; } mp_arg = (mp_arg_t *)malloc(sizeof(mp_arg_t)); if(!mp_arg) { LOG_PRINT(LOG_DEBUG, "Multipart_parser Arg Malloc Failed!"); LOG_PRINT(LOG_ERROR, "%s fail post save", address); err_no = 0; goto done; } evthr_t *thread = get_request_thr(req); thr_arg_t *thr_arg = (thr_arg_t *)evthr_get_aux(thread); mp_arg->req = req; mp_arg->thr_arg = thr_arg; str_lcpy(mp_arg->address, address, 16); mp_arg->partno = 0; mp_arg->succno = 0; mp_arg->check_name = 0; multipart_parser_set_data(parser, mp_arg); multipart_parser_execute(parser, buff, post_size); multipart_parser_free(parser); if(mp_arg->succno == 0) { evbuffer_add_printf(req->buffer_out, "<h1>Upload Failed!</h1>\n"); } evbuffer_add_printf(req->buffer_out, "</body>\n</html>\n"); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0)); err_no = -1; done: free(boundaryPattern); free(mp_arg); return err_no; }