comparison src/http/ngx_http_request.c @ 2090:72b09c4dd8f7 stable-0.6

r2005, r2006 merge: test user agent in header callback
author Igor Sysoev <igor@sysoev.ru>
date Mon, 07 Jul 2008 10:13:55 +0000
parents f32cc6df6bd6
children 65cff41e9a4e
comparison
equal deleted inserted replaced
2002:da31545030a8 2090:72b09c4dd8f7
20 static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r, 20 static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
21 ngx_table_elt_t *h, ngx_uint_t offset); 21 ngx_table_elt_t *h, ngx_uint_t offset);
22 static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r, 22 static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
23 ngx_table_elt_t *h, ngx_uint_t offset); 23 ngx_table_elt_t *h, ngx_uint_t offset);
24 static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r, 24 static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
25 ngx_table_elt_t *h, ngx_uint_t offset);
26 static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
25 ngx_table_elt_t *h, ngx_uint_t offset); 27 ngx_table_elt_t *h, ngx_uint_t offset);
26 static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r, 28 static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
27 ngx_table_elt_t *h, ngx_uint_t offset); 29 ngx_table_elt_t *h, ngx_uint_t offset);
28 30
29 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); 31 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
70 72
71 ngx_http_header_t ngx_http_headers_in[] = { 73 ngx_http_header_t ngx_http_headers_in[] = {
72 { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host), 74 { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
73 ngx_http_process_unique_header_line }, 75 ngx_http_process_unique_header_line },
74 76
75 { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection), 77 { ngx_string("Connection"), 0, ngx_http_process_connection },
76 ngx_http_process_connection },
77 78
78 { ngx_string("If-Modified-Since"), 79 { ngx_string("If-Modified-Since"),
79 offsetof(ngx_http_headers_in_t, if_modified_since), 80 offsetof(ngx_http_headers_in_t, if_modified_since),
80 ngx_http_process_unique_header_line }, 81 ngx_http_process_unique_header_line },
81 82
82 { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent), 83 { ngx_string("User-Agent"), 0, ngx_http_process_user_agent },
83 ngx_http_process_header_line },
84 84
85 { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer), 85 { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer),
86 ngx_http_process_header_line }, 86 ngx_http_process_header_line },
87 87
88 { ngx_string("Content-Length"), 88 { ngx_string("Content-Length"),
1248 return NGX_ERROR; 1248 return NGX_ERROR;
1249 } 1249 }
1250 1250
1251 1251
1252 static ngx_int_t 1252 static ngx_int_t
1253 ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
1254 ngx_uint_t offset)
1255 {
1256 u_char *ua, *user_agent;
1257
1258 if (r->headers_in.user_agent) {
1259 return NGX_OK;
1260 }
1261
1262 r->headers_in.user_agent = h;
1263
1264 /* check some widespread browsers while the header is in CPU cache */
1265
1266 user_agent = h->value.data;
1267
1268 ua = ngx_strstrn(user_agent, "MSIE", 4 - 1);
1269
1270 if (ua && ua + 8 < user_agent + h->value.len) {
1271
1272 r->headers_in.msie = 1;
1273
1274 if (ua[4] == ' ' && ua[5] == '4' && ua[6] == '.') {
1275 r->headers_in.msie4 = 1;
1276 }
1277
1278 #if 0
1279 /* MSIE ignores the SSL "close notify" alert */
1280 if (c->ssl) {
1281 c->ssl->no_send_shutdown = 1;
1282 }
1283 #endif
1284 }
1285
1286 if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
1287 r->headers_in.opera = 1;
1288 r->headers_in.msie = 0;
1289 r->headers_in.msie4 = 0;
1290 }
1291
1292 if (!r->headers_in.msie && !r->headers_in.opera) {
1293
1294 if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
1295 r->headers_in.gecko = 1;
1296
1297 } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
1298 r->headers_in.konqueror = 1;
1299 }
1300 }
1301
1302 return NGX_OK;
1303 }
1304
1305
1306 static ngx_int_t
1253 ngx_http_process_request_header(ngx_http_request_t *r) 1307 ngx_http_process_request_header(ngx_http_request_t *r)
1254 { 1308 {
1255 size_t len; 1309 size_t len;
1256 u_char *host, *ua, *user_agent, ch; 1310 u_char *host, ch;
1257 ngx_uint_t hash; 1311 ngx_uint_t hash;
1258 1312
1259 if (r->headers_in.host) { 1313 if (r->headers_in.host) {
1260 1314
1261 hash = 0; 1315 hash = 0;
1348 if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) { 1402 if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
1349 if (r->headers_in.keep_alive) { 1403 if (r->headers_in.keep_alive) {
1350 r->headers_in.keep_alive_n = 1404 r->headers_in.keep_alive_n =
1351 ngx_atotm(r->headers_in.keep_alive->value.data, 1405 ngx_atotm(r->headers_in.keep_alive->value.data,
1352 r->headers_in.keep_alive->value.len); 1406 r->headers_in.keep_alive->value.len);
1353 }
1354 }
1355
1356 if (r->headers_in.user_agent) {
1357
1358 /*
1359 * check some widespread browsers while the headers are still
1360 * in CPU cache
1361 */
1362
1363 user_agent = r->headers_in.user_agent->value.data;
1364
1365 ua = ngx_strstrn(user_agent, "MSIE", 4 - 1);
1366
1367 if (ua && ua + 8 < user_agent + r->headers_in.user_agent->value.len) {
1368
1369 r->headers_in.msie = 1;
1370
1371 if (ua[4] == ' ' && ua[5] == '4' && ua[6] == '.') {
1372 r->headers_in.msie4 = 1;
1373 }
1374
1375 #if 0
1376 /* MSIE ignores the SSL "close notify" alert */
1377 if (c->ssl) {
1378 c->ssl->no_send_shutdown = 1;
1379 }
1380 #endif
1381 }
1382
1383 if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
1384 r->headers_in.opera = 1;
1385 r->headers_in.msie = 0;
1386 r->headers_in.msie4 = 0;
1387 }
1388
1389 if (!r->headers_in.msie && !r->headers_in.opera) {
1390
1391 if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
1392 r->headers_in.gecko = 1;
1393
1394 } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
1395 r->headers_in.konqueror = 1;
1396 }
1397 } 1407 }
1398 } 1408 }
1399 1409
1400 return NGX_OK; 1410 return NGX_OK;
1401 } 1411 }