📄 parse.c
字号:
*/static voidmimeifrange(Hlex *h, char *){ int c, d, et; et = 0; c = getc(h); while(c == ' ' || c == '\t') c = getc(h); if(c == '"') et = 1; else if(c == 'W'){ d = getc(h); if(d == '/') et = 1; ungetc(h); } ungetc(h); if(et){ h->c->head.ifrangeetag = mimeetag(h, h->c->head.ifrangeetag); }else{ lexhead(h); h->c->head.ifrangedate = hdate2sec(h->wordval); }}static voidmimerange(Hlex *h, char *){ h->c->head.range = mimeranges(h, h->c->head.range);}/* * note: netscape and ie through versions 4.7 and 4 * support only basic authorization, so that is all that is supported here * * "Authorization" ":" "Basic" base64-user-pass * where base64-user-pass is the base64 encoding of * username ":" password */static voidmimeauthorization(Hlex *h, char *){ char *up, *p; int n; if(lex(h) != Word || cistrcmp(h->wordval, "basic") != 0) return; n = lexbase64(h); if(!n) return; /* * wipe out source for password, so it won't be logged. * it is replaced by a single =, * which is valid base64, but not ok for an auth reponse. * therefore future parses of the header field will not overwrite * authuser and authpass. */ memmove(h->c->hpos - (n - 1), h->c->hpos, h->c->hstop - h->c->hpos); h->c->hstop -= n - 1; *h->c->hstop = '\0'; h->c->hpos -= n - 1; h->c->hpos[-1] = '='; up = halloc(h->c, n + 1); n = dec64((uchar*)up, n, h->wordval, n); up[n] = '\0'; p = strchr(up, ':'); if(p != nil){ *p++ = '\0'; h->c->head.authuser = hstrdup(h->c, up); h->c->head.authpass = hstrdup(h->c, p); }}static voidmimeagent(Hlex *h, char *){ lexhead(h); h->c->head.client = hstrdup(h->c, h->wordval);}static voidmimefrom(Hlex *h, char *){ lexhead(h);}static voidmimehost(Hlex *h, char *){ char *hd; lexhead(h); for(hd = h->wordval; *hd == ' ' || *hd == '\t'; hd++) ; h->c->head.host = hlower(hstrdup(h->c, hd));}/* * if present, implies that a message body follows the headers * "content-length" ":" digits */static voidmimecontlen(Hlex *h, char *){ char *e; ulong v; if(lex(h) != Word) return; e = h->wordval; v = digtoul(e, &e); if(v == ~0UL || *e != '\0') return; h->c->head.contlen = v;}/* * mimexpect : "expect" ":" expects * expects : | expects "," expect * expect : "100-continue" | token | token "=" token expectparams | token "=" qstring expectparams * expectparams : ";" token | ";" token "=" token | token "=" qstring * for now, we merely parse "100-continue" or anything else. */static voidmimeexpect(Hlex *h, char *){ if(lex(h) != Word || cistrcmp(h->wordval, "100-continue") != 0 || lex(h) != '\n') h->c->head.expectother = 1; h->c->head.expectcont = 1;}static voidmimetransenc(Hlex *h, char *){ h->c->head.transenc = mimehfields(h);}static voidmimefresh(Hlex *h, char *){ char *s; lexhead(h); for(s = h->wordval; *s && (*s==' ' || *s=='\t'); s++) ; if(strncmp(s, "pathstat/", 9) == 0) h->c->head.fresh_thresh = atoi(s+9); else if(strncmp(s, "have/", 5) == 0) h->c->head.fresh_have = atoi(s+5);}static voidmimeignore(Hlex *h, char *){ lexhead(h);}static voidparsejump(Hlex *h, char *k){ int l, r, m; l = 1; r = nelem(mimehead) - 1; while(l <= r){ m = (r + l) >> 1; if(cistrcmp(mimehead[m].name, k) <= 0) l = m + 1; else r = m - 1; } m = l - 1; if(cistrcmp(mimehead[m].name, k) == 0 && !mimehead[m].ignore){ mimehead[m].seen = 1; (*mimehead[m].parse)(h, k); }else mimeignore(h, k);}static intlex(Hlex *h){ return h->tok = lex1(h, 0);}static intlexbase64(Hlex *h){ int c, n; n = 0; lex1(h, 1); while((c = getc(h)) >= 0){ if(!(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '+' || c == '/')){ ungetc(h); break; } if(n < HMaxWord-1) h->wordval[n++] = c; } h->wordval[n] = '\0'; return n;}/* * rfc 822/rfc 1521 lexical analyzer */static intlex1(Hlex *h, int skipwhite){ int level, c; if(h->eol) return '\n';top: c = getc(h); switch(c){ case '(': level = 1; while((c = getc(h)) >= 0){ if(c == '\\'){ c = getc(h); if(c < 0) return '\n'; continue; } if(c == '(') level++; else if(c == ')' && --level == 0) break; else if(c == '\n'){ c = getc(h); if(c < 0) return '\n'; if(c == ')' && --level == 0) break; if(c != ' ' && c != '\t'){ ungetc(h); return '\n'; } } } goto top; case ' ': case '\t': goto top; case '\r': c = getc(h); if(c != '\n'){ ungetc(h); goto top; } case '\n': if(h->tok == '\n'){ h->eol = 1; h->eoh = 1; return '\n'; } c = getc(h); if(c < 0){ h->eol = 1; return '\n'; } if(c != ' ' && c != '\t'){ ungetc(h); h->eol = 1; return '\n'; } goto top; case ')': case '<': case '>': case '[': case ']': case '@': case '/': case ',': case ';': case ':': case '?': case '=': if(skipwhite){ ungetc(h); return c; } return c; case '"': if(skipwhite){ ungetc(h); return c; } word(h, "\""); getc(h); /* skip the closing quote */ return QString; default: ungetc(h); if(skipwhite) return c; word(h, "\"(){}<>@,;:/[]?=\r\n \t"); if(h->wordval[0] == '\0'){ h->c->head.closeit = 1; hfail(h->c, HSyntax); longjmp(h->jmp, -1); } return Word; } /* not reached */}/* * return the rest of an rfc 822, including \n * do not map to lower case */static voidlexhead(Hlex *h){ int c, n; n = 0; while((c = getc(h)) >= 0){ if(c == '\r') c = wordcr(h); else if(c == '\n') c = wordnl(h); if(c == '\n') break; if(c == '\\'){ c = getc(h); if(c < 0) break; } if(n < HMaxWord-1) h->wordval[n++] = c; } h->tok = '\n'; h->eol = 1; h->wordval[n] = '\0';}static voidword(Hlex *h, char *stop){ int c, n; n = 0; while((c = getc(h)) >= 0){ if(c == '\r') c = wordcr(h); else if(c == '\n') c = wordnl(h); if(c == '\\'){ c = getc(h); if(c < 0) break; }else if(c < 32 || strchr(stop, c) != nil){ ungetc(h); break; } if(n < HMaxWord-1) h->wordval[n++] = c; } h->wordval[n] = '\0';}static intwordcr(Hlex *h){ int c; c = getc(h); if(c == '\n') return wordnl(h); ungetc(h); return ' ';}static intwordnl(Hlex *h){ int c; c = getc(h); if(c == ' ' || c == '\t') return c; ungetc(h); return '\n';}static intgetc(Hlex *h){ if(h->eoh) return -1; if(h->c->hpos < h->c->hstop) return *h->c->hpos++; h->eoh = 1; h->eol = 1; return -1;}static voidungetc(Hlex *h){ if(h->eoh) return; h->c->hpos--;}static ulongdigtoul(char *s, char **e){ ulong v; int c, ovfl; v = 0; ovfl = 0; for(;;){ c = *s; if(c < '0' || c > '9') break; s++; c -= '0'; if(v > UlongMax/10 || v == UlongMax/10 && c >= UlongMax%10) ovfl = 1; v = v * 10 + c; } if(e) *e = s; if(ovfl) return UlongMax; return v;}inthttp11(HConnect *c){ return c->req.vermaj > 1 || c->req.vermaj == 1 && c->req.vermin > 0;}char*hmkmimeboundary(HConnect *c){ char buf[32]; int i; srand((time(0)<<16)|getpid()); strcpy(buf, "upas-"); for(i = 5; i < sizeof(buf)-1; i++) buf[i] = 'a' + nrand(26); buf[i] = 0; return hstrdup(c, buf);}HSPairs*hmkspairs(HConnect *c, char *s, char *t, HSPairs *next){ HSPairs *sp; sp = halloc(c, sizeof *sp); sp->s = s; sp->t = t; sp->next = next; return sp;}HSPairs*hrevspairs(HSPairs *sp){ HSPairs *last, *next; last = nil; for(; sp != nil; sp = next){ next = sp->next; sp->next = last; last = sp; } return last;}HFields*hmkhfields(HConnect *c, char *s, HSPairs *p, HFields *next){ HFields *hf; hf = halloc(c, sizeof *hf); hf->s = s; hf->params = p; hf->next = next; return hf;}HFields*hrevhfields(HFields *hf){ HFields *last, *next; last = nil; for(; hf != nil; hf = next){ next = hf->next; hf->next = last; last = hf; } return last;}HContent*hmkcontent(HConnect *c, char *generic, char *specific, HContent *next){ HContent *ct; ct = halloc(c, sizeof(HContent)); ct->generic = generic; ct->specific = specific; ct->next = next; ct->q = 1; ct->mxb = 0; return ct;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -