00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include "libts.h"
00025 #include <stdio.h>
00026 #include "Allocator.h"
00027 #include "Compatability.h"
00028 #include "HTTP.h"
00029 #include "HdrToken.h"
00030 #include "MIME.h"
00031 #include "Regex.h"
00032 #include "URL.h"
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 static const char *_hdrtoken_strs[] = {
00049   
00050   "Accept-Charset",
00051   "Accept-Encoding",
00052   "Accept-Language",
00053   "Accept-Ranges",
00054   "Accept",
00055   "Age",
00056   "Allow",
00057   "Approved",                   
00058   "Authorization",
00059   "Bytes",                      
00060   "Cache-Control",
00061   "Client-ip",
00062   "Connection",
00063   "Content-Base",
00064   "Content-Encoding",
00065   "Content-Language",
00066   "Content-Length",
00067   "Content-Location",
00068   "Content-MD5",
00069   "Content-Range",
00070   "Content-Type",
00071   "Control",                    
00072   "Cookie",
00073   "Date",
00074   "Distribution",               
00075   "Etag",
00076   "Expect",
00077   "Expires",
00078   "Followup-To",                
00079   "From",
00080   "Host",
00081   "If-Match",
00082   "If-Modified-Since",
00083   "If-None-Match",
00084   "If-Range",
00085   "If-Unmodified-Since",
00086   "Keep-Alive",
00087   "Keywords",                   
00088   "Last-Modified",
00089   "Lines",                      
00090   "Location",
00091   "Max-Forwards",
00092   "Message-ID",                 
00093   "MIME-Version",
00094   "Newsgroups",                 
00095   "Organization",               
00096   "Path",                       
00097   "Pragma",
00098   "Proxy-Authenticate",
00099   "Proxy-Authorization",
00100   "Proxy-Connection",
00101   "Public",
00102   "Range",
00103   "References",                 
00104   "Referer",
00105   "Reply-To",                   
00106   "Retry-After",
00107   "Sender",                     
00108   "Server",
00109   "Set-Cookie",
00110   "Subject",                    
00111   "Summary",                    
00112   "Transfer-Encoding",
00113   "Upgrade",
00114   "User-Agent",
00115   "Vary",
00116   "Via",
00117   "Warning",
00118   "Www-Authenticate",
00119   "Xref",                       
00120   "@DataInfo",                  
00121   
00122   
00123   "compress",
00124   "deflate",
00125   "gzip",
00126   "identity",
00127   
00128   
00129   "max-age",
00130   "max-stale",
00131   "min-fresh",
00132   "must-revalidate",
00133   "no-cache",
00134   "no-store",
00135   "no-transform",
00136   "only-if-cached",
00137   "private",
00138   "proxy-revalidate",
00139   "s-maxage",
00140   "need-revalidate-once",
00141   
00142   
00143   "none",
00144   "chunked",
00145   "close",
00146   
00147   
00148   "websocket",
00149   "Sec-WebSocket-Key",
00150   "Sec-WebSocket-Version",
00151 
00152   
00153   "file",
00154   "ftp",
00155   "gopher",
00156   "https",
00157   "http",
00158   "mailto",
00159   "news",
00160   "nntp",
00161   "prospero",
00162   "telnet",
00163   "tunnel",
00164   "wais",
00165   "pnm",
00166   "rtspu",
00167   "rtsp",
00168   "mmsu",
00169   "mmst",
00170   "mms",
00171   "wss",
00172   "ws",
00173   
00174   
00175   "CONNECT",
00176   "DELETE",
00177   "GET",
00178   "POST",
00179   "HEAD",
00180   "ICP_QUERY",
00181   "OPTIONS",
00182   "PURGE",
00183   "PUT",
00184   "TRACE",
00185   "PUSH",
00186   
00187   
00188   "X-ID",
00189   "X-Forwarded-For",
00190   "TE",
00191   "Strict-Transport-Security",
00192   "100-continue"
00193 };
00194 
00195 static HdrTokenTypeBinding _hdrtoken_strs_type_initializers[] = {
00196   {"file", HDRTOKEN_TYPE_SCHEME},
00197   {"ftp", HDRTOKEN_TYPE_SCHEME},
00198   {"gopher", HDRTOKEN_TYPE_SCHEME},
00199   {"http", HDRTOKEN_TYPE_SCHEME},
00200   {"https", HDRTOKEN_TYPE_SCHEME},
00201   {"mailto", HDRTOKEN_TYPE_SCHEME},
00202   {"news", HDRTOKEN_TYPE_SCHEME},
00203   {"nntp", HDRTOKEN_TYPE_SCHEME},
00204   {"prospero", HDRTOKEN_TYPE_SCHEME},
00205   {"telnet", HDRTOKEN_TYPE_SCHEME},
00206   {"tunnel", HDRTOKEN_TYPE_SCHEME},
00207   {"wais", HDRTOKEN_TYPE_SCHEME},
00208   {"pnm", HDRTOKEN_TYPE_SCHEME},
00209   {"rtsp", HDRTOKEN_TYPE_SCHEME},
00210   {"rtspu", HDRTOKEN_TYPE_SCHEME},
00211   {"mms", HDRTOKEN_TYPE_SCHEME},
00212   {"mmsu", HDRTOKEN_TYPE_SCHEME},
00213   {"mmst", HDRTOKEN_TYPE_SCHEME},
00214   {"wss", HDRTOKEN_TYPE_SCHEME},
00215   {"ws", HDRTOKEN_TYPE_SCHEME},
00216 
00217   {"CONNECT", HDRTOKEN_TYPE_METHOD},
00218   {"DELETE", HDRTOKEN_TYPE_METHOD},
00219   {"GET", HDRTOKEN_TYPE_METHOD},
00220   {"HEAD", HDRTOKEN_TYPE_METHOD},
00221   {"ICP_QUERY", HDRTOKEN_TYPE_METHOD},
00222   {"OPTIONS", HDRTOKEN_TYPE_METHOD},
00223   {"POST", HDRTOKEN_TYPE_METHOD},
00224   {"PURGE", HDRTOKEN_TYPE_METHOD},
00225   {"PUT", HDRTOKEN_TYPE_METHOD},
00226   {"TRACE", HDRTOKEN_TYPE_METHOD},
00227   {"PUSH", HDRTOKEN_TYPE_METHOD},
00228 
00229   {"max-age", HDRTOKEN_TYPE_CACHE_CONTROL},
00230   {"max-stale", HDRTOKEN_TYPE_CACHE_CONTROL},
00231   {"min-fresh", HDRTOKEN_TYPE_CACHE_CONTROL},
00232   {"must-revalidate", HDRTOKEN_TYPE_CACHE_CONTROL},
00233   {"no-cache", HDRTOKEN_TYPE_CACHE_CONTROL},
00234   {"no-store", HDRTOKEN_TYPE_CACHE_CONTROL},
00235   {"no-transform", HDRTOKEN_TYPE_CACHE_CONTROL},
00236   {"only-if-cached", HDRTOKEN_TYPE_CACHE_CONTROL},
00237   {"private", HDRTOKEN_TYPE_CACHE_CONTROL},
00238   {"proxy-revalidate", HDRTOKEN_TYPE_CACHE_CONTROL},
00239   {"public", HDRTOKEN_TYPE_CACHE_CONTROL},
00240   {"s-maxage", HDRTOKEN_TYPE_CACHE_CONTROL},
00241   {"need-revalidate-once", HDRTOKEN_TYPE_CACHE_CONTROL},
00242 
00243   {(char *) NULL, (HdrTokenType) 0}
00244 };
00245 
00246 
00247 static HdrTokenFieldInfo _hdrtoken_strs_field_initializers[] = {
00248   {"Accept", MIME_SLOTID_ACCEPT, MIME_PRESENCE_ACCEPT, (HTIF_COMMAS | HTIF_MULTVALS)},
00249   {"Accept-Charset", MIME_SLOTID_ACCEPT_CHARSET, MIME_PRESENCE_ACCEPT_CHARSET, (HTIF_COMMAS | HTIF_MULTVALS)},
00250   {"Accept-Encoding", MIME_SLOTID_ACCEPT_ENCODING, MIME_PRESENCE_ACCEPT_ENCODING, (HTIF_COMMAS | HTIF_MULTVALS)},
00251   {"Accept-Language", MIME_SLOTID_ACCEPT_LANGUAGE, MIME_PRESENCE_ACCEPT_LANGUAGE, (HTIF_COMMAS | HTIF_MULTVALS)},
00252   {"Accept-Ranges", MIME_SLOTID_NONE, MIME_PRESENCE_ACCEPT_RANGES, (HTIF_COMMAS | HTIF_MULTVALS)},
00253   {"Age", MIME_SLOTID_AGE, MIME_PRESENCE_AGE, HTIF_NONE},
00254   {"Allow", MIME_SLOTID_NONE, MIME_PRESENCE_ALLOW, (HTIF_COMMAS | HTIF_MULTVALS)},
00255   {"Approved", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00256   {"Authorization", MIME_SLOTID_AUTHORIZATION, MIME_PRESENCE_AUTHORIZATION, HTIF_NONE},
00257   {"Bytes", MIME_SLOTID_NONE, MIME_PRESENCE_BYTES, HTIF_NONE},
00258   {"Cache-Control", MIME_SLOTID_CACHE_CONTROL, MIME_PRESENCE_CACHE_CONTROL, (HTIF_COMMAS | HTIF_MULTVALS)},
00259   {"Client-ip", MIME_SLOTID_CLIENT_IP, MIME_PRESENCE_CLIENT_IP, HTIF_NONE},
00260   {"Connection", MIME_SLOTID_CONNECTION, MIME_PRESENCE_CONNECTION, (HTIF_COMMAS | HTIF_MULTVALS | HTIF_HOPBYHOP)},
00261   {"Content-Base", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00262   {"Content-Encoding", MIME_SLOTID_CONTENT_ENCODING, MIME_PRESENCE_CONTENT_ENCODING, (HTIF_COMMAS | HTIF_MULTVALS)},
00263   {"Content-Language", MIME_SLOTID_CONTENT_LANGUAGE, MIME_PRESENCE_CONTENT_LANGUAGE, (HTIF_COMMAS | HTIF_MULTVALS)},
00264   {"Content-Length", MIME_SLOTID_CONTENT_LENGTH, MIME_PRESENCE_CONTENT_LENGTH, HTIF_NONE},
00265   {"Content-Location", MIME_SLOTID_NONE, MIME_PRESENCE_CONTENT_LOCATION, HTIF_NONE},
00266   {"Content-MD5", MIME_SLOTID_NONE, MIME_PRESENCE_CONTENT_MD5, HTIF_NONE},
00267   {"Content-Range", MIME_SLOTID_NONE, MIME_PRESENCE_CONTENT_RANGE, HTIF_NONE},
00268   {"Content-Type", MIME_SLOTID_CONTENT_TYPE, MIME_PRESENCE_CONTENT_TYPE, HTIF_NONE},
00269   {"Control", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00270   {"Cookie", MIME_SLOTID_COOKIE, MIME_PRESENCE_COOKIE, (HTIF_MULTVALS)},
00271   {"Date", MIME_SLOTID_DATE, MIME_PRESENCE_DATE, HTIF_NONE},
00272   {"Distribution", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00273   {"Etag", MIME_SLOTID_NONE, MIME_PRESENCE_ETAG, HTIF_NONE},
00274   {"Expires", MIME_SLOTID_EXPIRES, MIME_PRESENCE_EXPIRES, HTIF_NONE},
00275   {"Followup-To", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00276   {"From", MIME_SLOTID_NONE, MIME_PRESENCE_FROM, HTIF_NONE},
00277   {"Host", MIME_SLOTID_NONE, MIME_PRESENCE_HOST, HTIF_NONE},
00278   {"If-Match", MIME_SLOTID_IF_MATCH, MIME_PRESENCE_IF_MATCH, (HTIF_COMMAS | HTIF_MULTVALS)},
00279   {"If-Modified-Since", MIME_SLOTID_IF_MODIFIED_SINCE, MIME_PRESENCE_IF_MODIFIED_SINCE, HTIF_NONE},
00280   {"If-None-Match", MIME_SLOTID_IF_NONE_MATCH, MIME_PRESENCE_IF_NONE_MATCH, (HTIF_COMMAS | HTIF_MULTVALS)},
00281   {"If-Range", MIME_SLOTID_IF_RANGE, MIME_PRESENCE_IF_RANGE, HTIF_NONE},
00282   {"If-Unmodified-Since", MIME_SLOTID_IF_UNMODIFIED_SINCE, MIME_PRESENCE_IF_UNMODIFIED_SINCE, HTIF_NONE},
00283   {"Keep-Alive", MIME_SLOTID_NONE, MIME_PRESENCE_KEEP_ALIVE, (HTIF_HOPBYHOP)},
00284   {"Keywords", MIME_SLOTID_NONE, MIME_PRESENCE_KEYWORDS, HTIF_NONE},
00285   {"Last-Modified", MIME_SLOTID_LAST_MODIFIED, MIME_PRESENCE_LAST_MODIFIED, HTIF_NONE},
00286   {"Lines", MIME_SLOTID_NONE, MIME_PRESENCE_LINES, HTIF_NONE},
00287   {"Location", MIME_SLOTID_NONE, MIME_PRESENCE_LOCATION, (HTIF_MULTVALS)},
00288   {"Max-Forwards", MIME_SLOTID_NONE, MIME_PRESENCE_MAX_FORWARDS, HTIF_NONE},
00289   {"Message-ID", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00290   {"Newsgroups", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00291   {"Organization", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00292   {"Path", MIME_SLOTID_NONE, MIME_PRESENCE_PATH, HTIF_NONE},
00293   {"Pragma", MIME_SLOTID_PRAGMA, MIME_PRESENCE_PRAGMA, (HTIF_COMMAS | HTIF_MULTVALS)},
00294   {"Proxy-Authenticate", MIME_SLOTID_NONE, MIME_PRESENCE_PROXY_AUTHENTICATE, (HTIF_HOPBYHOP | HTIF_PROXYAUTH)},
00295   {"Proxy-Authorization", MIME_SLOTID_NONE, MIME_PRESENCE_PROXY_AUTHORIZATION, (HTIF_HOPBYHOP | HTIF_PROXYAUTH)},
00296   {"Proxy-Connection", MIME_SLOTID_PROXY_CONNECTION, MIME_PRESENCE_PROXY_CONNECTION,
00297    (HTIF_COMMAS | HTIF_MULTVALS | HTIF_HOPBYHOP)},
00298   {"Public", MIME_SLOTID_NONE, MIME_PRESENCE_PUBLIC, (HTIF_COMMAS | HTIF_MULTVALS)},
00299   {"Range", MIME_SLOTID_RANGE, MIME_PRESENCE_RANGE, (HTIF_COMMAS | HTIF_MULTVALS)},
00300   {"References", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00301   {"Referer", MIME_SLOTID_NONE, MIME_PRESENCE_REFERER, HTIF_NONE},
00302   {"Reply-To", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00303   {"Retry-After", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00304   {"Sender", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00305   {"Server", MIME_SLOTID_NONE, MIME_PRESENCE_SERVER, HTIF_NONE},
00306   {"Set-Cookie", MIME_SLOTID_SET_COOKIE, MIME_PRESENCE_SET_COOKIE, (HTIF_MULTVALS)},
00307   {"Strict-Transport-Security", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, (HTIF_MULTVALS)},
00308   {"Subject", MIME_SLOTID_NONE, MIME_PRESENCE_SUBJECT, HTIF_NONE},
00309   {"Summary", MIME_SLOTID_NONE, MIME_PRESENCE_SUMMARY, HTIF_NONE},
00310   {"TE", MIME_SLOTID_TE, MIME_PRESENCE_TE, (HTIF_COMMAS | HTIF_MULTVALS | HTIF_HOPBYHOP)},
00311   {"Transfer-Encoding", MIME_SLOTID_TRANSFER_ENCODING, MIME_PRESENCE_TRANSFER_ENCODING, (HTIF_COMMAS | HTIF_MULTVALS)},
00312   {"Upgrade", MIME_SLOTID_NONE, MIME_PRESENCE_UPGRADE, (HTIF_COMMAS | HTIF_MULTVALS | HTIF_HOPBYHOP)},
00313   {"User-Agent", MIME_SLOTID_USER_AGENT, MIME_PRESENCE_USER_AGENT, HTIF_NONE},
00314   {"Vary", MIME_SLOTID_VARY, MIME_PRESENCE_VARY, (HTIF_COMMAS | HTIF_MULTVALS)},
00315   {"Via", MIME_SLOTID_VIA, MIME_PRESENCE_VIA, (HTIF_COMMAS | HTIF_MULTVALS)},
00316   {"Warning", MIME_SLOTID_NONE, MIME_PRESENCE_WARNING, (HTIF_COMMAS | HTIF_MULTVALS)},
00317   {"Www-Authenticate", MIME_SLOTID_WWW_AUTHENTICATE, MIME_PRESENCE_WWW_AUTHENTICATE, HTIF_NONE},
00318   {"Xref", MIME_SLOTID_NONE, MIME_PRESENCE_XREF, HTIF_NONE},
00319   {"@DataInfo", MIME_SLOTID_NONE, MIME_PRESENCE_INT_DATA_INFO, HTIF_NONE},
00320   {"X-ID", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, (HTIF_COMMAS | HTIF_MULTVALS | HTIF_HOPBYHOP)},
00321   {"X-Forwarded-For", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, (HTIF_COMMAS | HTIF_MULTVALS)},
00322   {"Sec-WebSocket-Key", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00323   {"Sec-WebSocket-Version", MIME_SLOTID_NONE, MIME_PRESENCE_NONE, HTIF_NONE},
00324   {NULL, 0, 0, 0}
00325 };
00326 
00327 const char *_hdrtoken_strs_heap_f = NULL;       
00328 const char *_hdrtoken_strs_heap_l = NULL;       
00329 
00330 int hdrtoken_num_wks = SIZEOF(_hdrtoken_strs);  
00331 
00332 const char *hdrtoken_strs[SIZEOF(_hdrtoken_strs)];      
00333 int hdrtoken_str_lengths[SIZEOF(_hdrtoken_strs)];       
00334 HdrTokenType hdrtoken_str_token_types[SIZEOF(_hdrtoken_strs)];  
00335 int32_t hdrtoken_str_slotids[SIZEOF(_hdrtoken_strs)];     
00336 uint64_t hdrtoken_str_masks[SIZEOF(_hdrtoken_strs)];      
00337 uint32_t hdrtoken_str_flags[SIZEOF(_hdrtoken_strs)];      
00338 
00339 DFA *hdrtoken_strs_dfa = NULL;
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 #define HDRTOKEN_HASH_TABLE_SIZE        65536
00348 #define HDRTOKEN_HASH_TABLE_MASK        HDRTOKEN_HASH_TABLE_SIZE-1
00349 
00350 struct HdrTokenHashBucket
00351 {
00352   const char *wks;
00353   uint32_t hash;
00354 };
00355 
00356 HdrTokenHashBucket hdrtoken_hash_table[HDRTOKEN_HASH_TABLE_SIZE];
00357 
00358 
00359 
00360 
00361 #define TINY_MASK(x) (((u_int32_t)1<<(x))-1)
00362 
00363 inline uint32_t
00364 hash_to_slot(uint32_t hash)
00365 {
00366   return ((hash>>15) ^ hash) & TINY_MASK(15);
00367 }
00368 
00369 inline uint32_t
00370 hdrtoken_hash(const unsigned char *string, unsigned int length)
00371 {
00372   static const uint32_t InitialFNV = 2166136261U;
00373   static const int32_t FNVMultiple = 16777619;
00374 
00375   uint32_t hash = InitialFNV;
00376 
00377   for (size_t i = 0; i < length; i++)  {
00378       hash = hash ^ (toupper(string[i])); 
00379       hash = hash * FNVMultiple;          
00380   }
00381 
00382   return hash;
00383 }
00384 
00385 
00386 
00387 
00388 static const char *_hdrtoken_commonly_tokenized_strs[] = {
00389   
00390   "Accept-Charset",
00391   "Accept-Encoding",
00392   "Accept-Language",
00393   "Accept-Ranges",
00394   "Accept",
00395   "Age",
00396   "Allow",
00397   "Approved",                   
00398   "Authorization",
00399   "Bytes",                      
00400   "Cache-Control",
00401   "Client-ip",
00402   "Connection",
00403   "Content-Base",
00404   "Content-Encoding",
00405   "Content-Language",
00406   "Content-Length",
00407   "Content-Location",
00408   "Content-MD5",
00409   "Content-Range",
00410   "Content-Type",
00411   "Control",                    
00412   "Cookie",
00413   "Date",
00414   "Distribution",               
00415   "Etag",
00416   "Expect",
00417   "Expires",
00418   "Followup-To",                
00419   "From",
00420   "Host",
00421   "If-Match",
00422   "If-Modified-Since",
00423   "If-None-Match",
00424   "If-Range",
00425   "If-Unmodified-Since",
00426   "Keep-Alive",
00427   "Keywords",                   
00428   "Last-Modified",
00429   "Lines",                      
00430   "Location",
00431   "Max-Forwards",
00432   "Message-ID",                 
00433   "MIME-Version",
00434   "Newsgroups",                 
00435   "Organization",               
00436   "Path",                       
00437   "Pragma",
00438   "Proxy-Authenticate",
00439   "Proxy-Authorization",
00440   "Proxy-Connection",
00441   "Public",
00442   "Range",
00443   "References",                 
00444   "Referer",
00445   "Reply-To",                   
00446   "Retry-After",
00447   "Sender",                     
00448   "Server",
00449   "Set-Cookie",
00450   "Subject",                    
00451   "Summary",                    
00452   "Transfer-Encoding",
00453   "Upgrade",
00454   "User-Agent",
00455   "Vary",
00456   "Via",
00457   "Warning",
00458   "Www-Authenticate",
00459   "Xref",                       
00460   "@DataInfo",                  
00461   
00462   
00463   "compress",
00464   "deflate",
00465   "gzip",
00466   "identity",
00467   
00468   
00469   "max-age",
00470   "max-stale",
00471   "min-fresh",
00472   "must-revalidate",
00473   "no-cache",
00474   "no-store",
00475   "no-transform",
00476   "only-if-cached",
00477   "private",
00478   "proxy-revalidate",
00479   "s-maxage",
00480   "need-revalidate-once",
00481   
00482   
00483   "none",
00484   "chunked",
00485   "close",
00486   
00487   
00488   "websocket",
00489   "Sec-WebSocket-Key",
00490   "Sec-WebSocket-Version",
00491 
00492   
00493   "file",
00494   "ftp",
00495   "gopher",
00496   "https",
00497   "http",
00498   "mailto",
00499   "news",
00500   "nntp",
00501   "prospero",
00502   "telnet",
00503   "tunnel",
00504   "wais",
00505   "pnm",
00506   "rtspu",
00507   "rtsp",
00508   "mmsu",
00509   "mmst",
00510   "mms",
00511   "wss",
00512   "ws",
00513   
00514   
00515   "CONNECT",
00516   "DELETE",
00517   "GET",
00518   "POST",
00519   "HEAD",
00520   "ICP_QUERY",
00521   "OPTIONS",
00522   "PURGE",
00523   "PUT",
00524   "TRACE",
00525   "PUSH",
00526   
00527   
00528   "X-ID",
00529   "X-Forwarded-For",
00530   "TE",
00531   "Strict-Transport-Security",
00532   "100-continue"
00533 };
00534 
00535 
00536 
00537 
00538 void
00539 hdrtoken_hash_init()
00540 {
00541   uint32_t i;
00542   int num_collisions;
00543 
00544   memset(hdrtoken_hash_table, 0, sizeof(hdrtoken_hash_table));
00545   num_collisions = 0;
00546 
00547   for (i = 0; i < (int) SIZEOF(_hdrtoken_commonly_tokenized_strs); i++) {
00548     
00549     unsigned const char *wks;
00550     int wks_idx = hdrtoken_tokenize_dfa(_hdrtoken_commonly_tokenized_strs[i],
00551                                         (int) strlen(_hdrtoken_commonly_tokenized_strs[i]),
00552                                         (const char **) &wks);
00553     ink_release_assert(wks_idx >= 0);
00554 
00555     uint32_t hash = hdrtoken_hash(wks, hdrtoken_str_lengths[wks_idx]);
00556     uint32_t slot = hash_to_slot(hash);
00557 
00558     if (hdrtoken_hash_table[slot].wks) {
00559       printf("ERROR: hdrtoken_hash_table[%u] collision: '%s' replacing '%s'\n",
00560              slot, (const char*)wks, hdrtoken_hash_table[slot].wks);
00561       ++num_collisions;
00562     }
00563     hdrtoken_hash_table[slot].wks = (const char *)wks;
00564     hdrtoken_hash_table[slot].hash = hash;
00565   }
00566 
00567   if (num_collisions > 0)
00568     abort();
00569 }
00570 
00571 
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 
00581 
00582 static inline unsigned int
00583 snap_up_to_multiple(unsigned int n, unsigned int unit)
00584 {
00585   return ((n + (unit - 1)) / unit) * unit;
00586 }
00587 
00588 
00589 
00590 void
00591 hdrtoken_init()
00592 {
00593   static int inited = 0;
00594 
00595   int i;
00596 
00597   if (!inited) {
00598     inited = 1;
00599 
00600     hdrtoken_strs_dfa = new DFA;
00601     hdrtoken_strs_dfa->compile(_hdrtoken_strs, SIZEOF(_hdrtoken_strs), (REFlags) (RE_CASE_INSENSITIVE));
00602 
00603     
00604     
00605     
00606     
00607     
00608     
00609 
00610     int heap_size = 0;
00611     for (i = 0; i < (int) SIZEOF(_hdrtoken_strs); i++) {
00612       hdrtoken_str_lengths[i] = (int) strlen(_hdrtoken_strs[i]);
00613       int sstr_len = snap_up_to_multiple(hdrtoken_str_lengths[i] + 1, sizeof(HdrTokenHeapPrefix));
00614       int packed_prefix_str_len = sizeof(HdrTokenHeapPrefix) + sstr_len;
00615       heap_size += packed_prefix_str_len;
00616     }
00617 
00618     _hdrtoken_strs_heap_f = (const char *)ats_malloc(heap_size);
00619     _hdrtoken_strs_heap_l = _hdrtoken_strs_heap_f + heap_size - 1;
00620 
00621     char *heap_ptr = (char *) _hdrtoken_strs_heap_f;
00622 
00623     for (i = 0; i < (int) SIZEOF(_hdrtoken_strs); i++) {
00624       HdrTokenHeapPrefix prefix;
00625 
00626       memset(&prefix, 0, sizeof(HdrTokenHeapPrefix));
00627 
00628       prefix.wks_idx = i;
00629       prefix.wks_length = hdrtoken_str_lengths[i];
00630       prefix.wks_token_type = HDRTOKEN_TYPE_OTHER;      
00631       prefix.wks_info.name = NULL;      
00632       prefix.wks_info.slotid = MIME_SLOTID_NONE;        
00633       prefix.wks_info.mask = TOK_64_CONST(0);   
00634       prefix.wks_info.flags = MIME_FLAGS_MULTVALS;      
00635 
00636       int sstr_len = snap_up_to_multiple(hdrtoken_str_lengths[i] + 1, sizeof(HdrTokenHeapPrefix));
00637 
00638       *(HdrTokenHeapPrefix *) heap_ptr = prefix;        
00639       heap_ptr += sizeof(HdrTokenHeapPrefix);   
00640       hdrtoken_strs[i] = heap_ptr;      
00641       
00642       ink_strlcpy((char *) hdrtoken_strs[i], _hdrtoken_strs[i], heap_size - sizeof(HdrTokenHeapPrefix));     
00643       heap_ptr += sstr_len;     
00644       heap_size -= sstr_len;
00645     }
00646 
00647     
00648     for (i = 0; _hdrtoken_strs_type_initializers[i].name != NULL; i++) {
00649       int wks_idx;
00650       HdrTokenHeapPrefix *prefix;
00651 
00652       wks_idx = hdrtoken_tokenize_dfa(_hdrtoken_strs_type_initializers[i].name,
00653                                       (int) strlen(_hdrtoken_strs_type_initializers[i].name));
00654 
00655       ink_assert((wks_idx >= 0) && (wks_idx < (int) SIZEOF(hdrtoken_strs)));
00656       
00657       prefix = hdrtoken_index_to_prefix(wks_idx);
00658       prefix->wks_token_type = _hdrtoken_strs_type_initializers[i].type;
00659     }
00660 
00661     
00662     for (i = 0; _hdrtoken_strs_field_initializers[i].name != NULL; i++) {
00663       int wks_idx;
00664       HdrTokenHeapPrefix *prefix;
00665 
00666       wks_idx = hdrtoken_tokenize_dfa(_hdrtoken_strs_field_initializers[i].name,
00667                                       (int) strlen(_hdrtoken_strs_field_initializers[i].name));
00668 
00669       ink_assert((wks_idx >= 0) && (wks_idx < (int) SIZEOF(hdrtoken_strs)));
00670       prefix = hdrtoken_index_to_prefix(wks_idx);
00671       prefix->wks_info.slotid = _hdrtoken_strs_field_initializers[i].slotid;
00672       prefix->wks_info.flags = _hdrtoken_strs_field_initializers[i].flags;
00673       prefix->wks_info.mask = _hdrtoken_strs_field_initializers[i].mask;
00674     }
00675 
00676     for (i = 0; i < (int) SIZEOF(_hdrtoken_strs); i++) {
00677       HdrTokenHeapPrefix *prefix = hdrtoken_index_to_prefix(i);
00678       prefix->wks_info.name = hdrtoken_strs[i];
00679       hdrtoken_str_token_types[i] = prefix->wks_token_type;     
00680       hdrtoken_str_slotids[i] = prefix->wks_info.slotid;        
00681       hdrtoken_str_masks[i] = prefix->wks_info.mask;    
00682       hdrtoken_str_flags[i] = prefix->wks_info.flags;   
00683     }
00684 
00685     hdrtoken_hash_init();
00686   }
00687 }
00688 
00689 
00690 
00691 
00692 int
00693 hdrtoken_tokenize_dfa(const char *string, int string_len, const char **wks_string_out)
00694 {
00695   int wks_idx;
00696   
00697   wks_idx = hdrtoken_strs_dfa->match(string, string_len);
00698 
00699   if (wks_idx < 0)
00700     wks_idx = -1;
00701   if (wks_string_out) {
00702     if (wks_idx >= 0)
00703       *wks_string_out = hdrtoken_index_to_wks(wks_idx);
00704     else
00705       *wks_string_out = NULL;
00706   }
00707   
00708 
00709   return wks_idx;
00710 }
00711 
00712 
00713 
00714 
00715 int
00716 hdrtoken_tokenize(const char *string, int string_len, const char **wks_string_out)
00717 {
00718   int wks_idx;
00719   HdrTokenHashBucket *bucket;
00720 
00721   ink_assert(string != NULL);
00722 
00723   if (hdrtoken_is_wks(string)) {
00724     wks_idx = hdrtoken_wks_to_index(string);
00725     if (wks_string_out)
00726       *wks_string_out = string;
00727     return wks_idx;
00728   }
00729 
00730   uint32_t hash = hdrtoken_hash((const unsigned char *) string, (unsigned int) string_len);
00731   uint32_t slot = hash_to_slot(hash);
00732 
00733   bucket = &(hdrtoken_hash_table[slot]);
00734   if ((bucket->wks != NULL) &&
00735       (bucket->hash == hash) &&
00736       (hdrtoken_wks_to_length(bucket->wks) == string_len)) {
00737     wks_idx = hdrtoken_wks_to_index(bucket->wks);
00738     if (wks_string_out)
00739       *wks_string_out = bucket->wks;
00740     return wks_idx;
00741   }
00742 
00743   Debug("hdr_token", "Did not find a WKS for '%.*s'", string_len, string);
00744   return -1;
00745 }
00746 
00747 
00748 
00749 
00750 const char *
00751 hdrtoken_string_to_wks(const char *string)
00752 {
00753   const char *wks = NULL;
00754   hdrtoken_tokenize(string, (int) strlen(string), &wks);
00755   return wks;
00756 }
00757 
00758 
00759 
00760 
00761 const char *
00762 hdrtoken_string_to_wks(const char *string, int length)
00763 {
00764   const char *wks = NULL;
00765   hdrtoken_tokenize(string, length, &wks);
00766   return wks;
00767 }