inc/mime.h File Reference

#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)
mimeBufinitMimeBuf (int d)
mimePartparseMultiParts (struct mimeBuf *b, char *altHeader)


Define Documentation

#define MIMEBUFSIZE   32*1024

Definition at line 11 of file mime.h.

Referenced by appendMimeVar().


Function Documentation

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:

struct mimePart* parseMultiParts ( struct mimeBuf b,
char *  altHeader 
) [read]

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:


Generated on Tue Dec 25 19:06:27 2007 for blat by  doxygen 1.5.2