#include "hash.h"Include dependency graph for mime.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Data Structures | |
| struct | mimePart |
| struct | mimeBuf |
Defines | |
| #define | MIMEBUFSIZE 32*1024 |
Functions | |
| char * | getMimeHeaderMainVal (char *header) |
| char * | getMimeHeaderFieldVal (char *header, char *field) |
| mimeBuf * | initMimeBuf (int d) |
| mimePart * | parseMultiParts (struct mimeBuf *b, char *altHeader) |
| #define MIMEBUFSIZE 32*1024 |
| char* getMimeHeaderFieldVal | ( | char * | header, | |
| char * | field | |||
| ) |
Definition at line 333 of file mime.c.
References cloneString(), errAbort(), and TRUE.
Referenced by cgiParseMultipart(), and parseMultiParts().
00337 { 00338 char value[1024]; 00339 char *fld = header; 00340 int i = 0; 00341 char *puncChars = ",;: \t\r\n"; /* punctuation chars */ 00342 while (TRUE) 00343 { 00344 fld = strstr(fld,field); 00345 if (!fld) 00346 return NULL; 00347 if (fld > header && strchr(puncChars,fld[-1])) 00348 { 00349 fld+=strlen(field); 00350 if (*fld == '=') 00351 { 00352 ++fld; 00353 break; 00354 } 00355 } 00356 else 00357 { 00358 ++fld; 00359 } 00360 } 00361 if (*fld == '"') 00362 { 00363 puncChars = "\""; /* quoted */ 00364 ++fld; 00365 } 00366 i=0; 00367 while(TRUE) 00368 { 00369 char c = *fld++; 00370 if (c==0 || strchr(puncChars,c)) 00371 break; 00372 value[i++] = c; 00373 if (i >= sizeof(value)) 00374 errAbort("error: %s= value too long (>%lu) in MIME header Content-type:%s",field,(unsigned long)sizeof(value),header); 00375 } 00376 value[i] = 0; 00377 00378 return cloneString(value); 00379 00380 }
Here is the call graph for this function:

Here is the caller graph for this function:

| char* getMimeHeaderMainVal | ( | char * | header | ) |
Definition at line 306 of file mime.c.
References cloneString(), errAbort(), and TRUE.
Referenced by cgiParseMultipart().
00310 { 00311 char value[1024]; 00312 char *h = header; 00313 int i = 0; 00314 char *puncChars = ",;: \t\r\n"; /* punctuation chars */ 00315 i=0; 00316 /* The header should have already been trimmed of leading and trailing spaces */ 00317 while(TRUE) 00318 { 00319 char c = *h++; 00320 if (c==0 || strchr(puncChars,c)) 00321 break; 00322 value[i++] = c; 00323 if (i >= sizeof(value)) 00324 errAbort("error: main value too long (>%lu) in MIME header Content-type:%s",(unsigned long)sizeof(value),header); 00325 } 00326 value[i] = 0; 00327 00328 return cloneString(value); 00329 00330 }
Here is the call graph for this function:

Here is the caller graph for this function:

| struct mimeBuf* initMimeBuf | ( | int | d | ) | [read] |
Definition at line 289 of file mime.c.
References AllocA, mimeBuf::blen, mimeBuf::boundary, mimeBuf::buf, mimeBuf::d, mimeBuf::eod, mimeBuf::eoi, mimeBuf::eom, mimeBuf::i, and moreMimeBuf().
Referenced by cgiParseMultipart().
00293 { 00294 struct mimeBuf *b=AllocA(*b); 00295 b->d = d; 00296 b->boundary = NULL; 00297 b->blen = 0; 00298 b->eom = b->buf+MIMEBUFSIZE; 00299 b->eoi = b->eom; 00300 b->eod = b->eom; 00301 b->i = b->eom; 00302 moreMimeBuf(b); 00303 return b; 00304 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 403 of file mime.c.
References AllocA, mimePart::binary, mimeBuf::boundary, carefulClose(), cloneString(), mimePart::data, dyStringAppendN(), dyStringCannibalize(), dyStringNew, dyStringPrintf(), mimeBuf::eoi, mimeBuf::eom, errAbort(), FALSE, mimePart::fileName, tempName::forCgi, freeDyString(), freez(), getChunkMB(), getcMB(), getLineMB(), getMimeHeaderFieldVal(), getNewLineByType(), hashFindVal(), mimePart::hdr, mimeBuf::i, makeTempName(), MAXBOUNDARY, MAXDATASIZE, MAXPARTSIZE, moreMimeBuf(), mimePart::multi, mustOpen(), mustWrite(), needLargeMem(), newDyString(), nlt_dos, nlt_mac, nlt_unix, parseMultiParts(), readPartHeaderMB(), safef(), sameOk, sameString, setBoundaryMB(), setEopMB(), mimePart::size, slAddHead, slReverse(), startsWith(), dyString::string, dyString::stringSize, touppers(), and TRUE.
Referenced by cgiParseMultipart(), and parseMultiParts().
00411 { 00412 struct mimePart *p=AllocA(*p); 00413 char *parentboundary = NULL, *boundary = NULL; 00414 char *ct = NULL; 00415 boolean autoBoundary = FALSE; 00416 00417 00418 //debug 00419 //fprintf(stderr,"altHeader=[%s]\n",altHeader); 00420 00421 if (sameOk(altHeader, "autoBoundary")) 00422 { /* process things with no explicit header. 00423 * look for *MIME* \n\n-- */ 00424 struct dyString *dy = dyStringNew(0); 00425 char *prevPrevLine = NULL; 00426 char *prevLine = NULL; 00427 char *line = NULL; 00428 boolean found = FALSE; 00429 autoBoundary = TRUE; 00430 while (TRUE) 00431 { 00432 if (b->i >= b->eoi && b->eoi < b->eom) /* at end of input */ 00433 break; 00434 line = getLineMB(b); 00435 if (line && startsWith("--",line) // && 00436 //sameString(prevLine,"") && 00437 //prevPrevLine && 00438 //stringIn("MULTI",prevPrevLine) && 00439 //stringIn("MIME",prevPrevLine) 00440 ) 00441 { 00442 found = TRUE; 00443 break; 00444 } 00445 freez(&prevPrevLine); 00446 prevPrevLine = prevLine; 00447 prevLine = line; 00448 if (prevPrevLine) 00449 touppers(prevPrevLine); 00450 } 00451 if (!found) 00452 errAbort("autoBoundary: No initial boundary found."); 00453 00454 dyStringPrintf(dy, "CONTENT-TYPE:multipart/form-data; boundary=%s%s%s", 00455 line+2, getNewLineByType(), getNewLineByType() ); 00456 altHeader = dyStringCannibalize(&dy); 00457 00458 //debug 00459 //fprintf(stderr,"autoBoundary altHeader = [%s]\n",altHeader); 00460 //fflush(stderr); 00461 00462 freez(&prevPrevLine); 00463 freez(&prevLine); 00464 freez(&line); 00465 } 00466 00467 //debug 00468 //fprintf(stderr,"\n"); 00469 readPartHeaderMB(b,p,altHeader); 00470 00471 ct = hashFindVal(p->hdr,"content-type"); /* use lowercase key */ 00472 //debug 00473 //fprintf(stderr,"ct from hash:%s\n",ct); 00474 //fflush(stderr); 00475 00476 if (ct && startsWith("multipart/",ct)) 00477 { 00478 char bound[MAXBOUNDARY]; 00479 char *bnd = NULL; 00480 struct mimePart *child = NULL; 00481 00482 /* these 3 vars just for processing epilog chunk: */ 00483 char *bp=NULL; 00484 int size=0; 00485 boolean hasZeros=FALSE; 00486 00487 /* save */ 00488 parentboundary = b->boundary; 00489 00490 boundary = getMimeHeaderFieldVal(ct,"boundary"); 00491 if (strlen(boundary) >= MAXBOUNDARY) 00492 errAbort("error: boundary= value too long in MIME header Content-type:%s",ct); 00493 safef(bound, sizeof(bound), "--%s",boundary); /* do not prepend CRLF to boundary yet */ 00494 freez(&boundary); 00495 boundary = cloneString(bound); 00496 //debug 00497 //fprintf(stderr,"initial boundary parsed:%s\n",boundary); 00498 //fflush(stderr); 00499 00500 if (!autoBoundary) 00501 { 00502 /* skip any extra "prolog" before the initial boundary marker */ 00503 while (TRUE) 00504 { 00505 bnd = getLineMB(b); 00506 if (sameString(bnd,boundary)) 00507 break; 00508 freez(&bnd); 00509 } 00510 //debug 00511 //fprintf(stderr,"initial boundary found:%s\n",bnd); 00512 //fflush(stderr); 00513 freez(&bnd); 00514 } 00515 00516 /* include crlf in the boundary so bodies won't have trailing a CRLF 00517 * this is done here so that in case there's no extra CRLF 00518 * between the header and the boundary, it will still work, 00519 * so we only prepend the CRLF to the boundary after initial found */ 00520 safef(bound,sizeof(bound),"%s%s", getNewLineByType(), boundary); 00521 freez(&boundary); 00522 boundary=cloneString(bound); 00523 00524 setBoundaryMB(b, boundary); 00525 00526 while(TRUE) 00527 { 00528 int i = 0; 00529 char c1 = ' ', c2 = ' '; 00530 child = parseMultiParts(b,NULL); 00531 slAddHead(&p->multi,child); 00532 //call getLine, compare to boundary 00533 /* skip extra initial boundary marker - it's moot anyway */ 00534 freez(&bnd); 00535 //debug 00536 //fprintf(stderr,"post-parse pre-getLineMB dumpMB: "); 00537 //dumpMB(b); //debug 00538 for (i=0;i<strlen(boundary);++i) 00539 bound[i] = getcMB(b); 00540 bound[i] = 0; 00541 if (!sameString(bound,boundary)) 00542 errAbort("expected boundary %s, but found %s in MIME",boundary,bound); 00543 //debug 00544 //fprintf(stderr,"\nfound boundary:%s\n",bound); 00545 //fflush(stderr); 00546 c1 = getcMB(b); 00547 if (c1 == '-') 00548 { 00549 c2 = getcMB(b); 00550 if (c2 == '-') 00551 break; /* last boundary found */ 00552 else 00553 errAbort("expected -- after boundary %s, but found %c%c in MIME",boundary,c1,c2); 00554 } 00555 if (nlType == nlt_dos) 00556 c2 = getcMB(b); 00557 switch (nlType) 00558 { 00559 case nlt_dos: 00560 if (c1 == 0x0d && c2 == 0x0a) 00561 break; 00562 else 00563 errAbort("expected CRLF after boundary %s, but found %c%c in MIME",boundary,c1,c2); 00564 case nlt_unix: 00565 if (c1 == 0x0a) 00566 break; 00567 else 00568 errAbort("expected LF after boundary %s, but found %c in MIME",boundary,c1); 00569 case nlt_mac: 00570 if (c1 == 0x0d) 00571 break; 00572 else 00573 errAbort("expected CR after boundary %s, but found %c in MIME",boundary,c1); 00574 default: 00575 errAbort("unexpected nlType %d after boundary %s",nlType,boundary); 00576 } 00577 setEopMB(b); 00578 } 00579 freez(&bnd); 00580 slReverse(&p->multi); 00581 /* restore */ 00582 freez(&boundary); 00583 boundary = parentboundary; 00584 //debug 00585 //fprintf(stderr,"restoring parent boundary = %s\n",boundary); 00586 setBoundaryMB(b, boundary); 00587 00588 /* dump any "epilog" that may be between the 00589 * end of the child boundary and the parent boundary */ 00590 getChunkMB(b, &bp, &size, &hasZeros); 00591 //debug 00592 //fprintf(stderr,"epilog size=%d\n",size); 00593 00594 00595 } 00596 else 00597 { 00598 char *bp=NULL; 00599 int size=0; 00600 boolean hasZeros=FALSE; 00601 boolean toobig=FALSE; 00602 boolean asFile=FALSE; 00603 boolean convert=FALSE; 00604 FILE *f = NULL; 00605 struct dyString *dy=newDyString(1024); 00606 //debug 00607 //fprintf(stderr,"starting new part (non-multi), dumpMB: \n"); 00608 //dumpMB(b); //debug 00609 00610 //debug 00611 //ct = hashFindVal(p->hdr,"content-transfer-encoding"); /* use lowercase key */ 00612 //fprintf(stderr,"cte from hash:%s\n",ct); 00613 00614 while(TRUE) 00615 { 00616 // break if eop, eod, eoi 00617 getChunkMB(b, &bp, &size, &hasZeros); 00618 //debug 00619 //fprintf(stderr,"bp=%lu size=%d, hasZeros=%d \n", 00620 // (unsigned long) bp, 00621 // size, 00622 // hasZeros); 00623 if (hasZeros) 00624 { 00625 p->binary=TRUE; 00626 } 00627 //if (hasZeros && !asFile) 00628 // { 00629 // convert=TRUE; 00630 // } 00631 if (!asFile && p->size+size > MAXPARTSIZE) 00632 { 00633 toobig = TRUE; 00634 convert=TRUE; 00635 } 00636 if (convert) 00637 { 00638 struct tempName uploadedData; 00639 convert=FALSE; 00640 asFile = TRUE; 00641 makeTempName(&uploadedData, "hgSs", ".cgi"); 00642 p->fileName=cloneString(uploadedData.forCgi); 00643 f = mustOpen(p->fileName,"w"); 00644 mustWrite(f,dy->string,dy->stringSize); 00645 freeDyString(&dy); 00646 } 00647 if (asFile) 00648 { 00649 mustWrite(f,bp,size); 00650 } 00651 else 00652 { 00653 dyStringAppendN(dy,bp,size); 00654 } 00655 p->size+=size; 00656 if (p->size > MAXDATASIZE) 00657 errAbort("max data size allowable for upload in MIME exceeded %llu",(unsigned long long)MAXDATASIZE); 00658 00659 00660 if (b->eop && b->i == b->eop) /* end of part */ 00661 { 00662 break; 00663 } 00664 if (b->i == b->eoi && b->eoi < b->eom) /* end of data */ 00665 { 00666 break; 00667 } 00668 moreMimeBuf(b); 00669 } 00670 if (dy) 00671 { 00672 p->data=needLargeMem(dy->stringSize+1); 00673 memcpy(p->data,dy->string,dy->stringSize); 00674 p->data[dy->stringSize] = 0; 00675 freeDyString(&dy); 00676 } 00677 if (f) 00678 carefulClose(&f); 00679 00680 //debug 00681 //fprintf(stderr,"p->fileName=%s p->data=[%s]\n",p->fileName,p->data); 00682 00683 } 00684 00685 return p; 00686 }
Here is the call graph for this function:

Here is the caller graph for this function:

1.5.2