Changeset 468

Show
Ignore:
Timestamp:
07/23/2005 08:30:54 PM (3 years ago)
Author:
jan
Message:

moved last-modified handling into a exported function and let mod_cml use it

Location:
branches/lighttpd-1.3.x/src
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • branches/lighttpd-1.3.x/src/mod_cml_lua.c

    r461 r468  
    248248                struct stat st; 
    249249                int curelem; 
     250                time_t last_mtime = 0; 
    250251                 
    251252                lua_pushstring(L, "output_include"); 
     
    253254                curelem = lua_gettop(L); 
    254255                lua_gettable(L, LUA_GLOBALSINDEX); 
     256 
     257                /* HOW-TO build a etag ? 
     258                 * as we don't just have one file we have to take the stat()  
     259                 * from all base files, merge them and build the etag from 
     260                 * it later. 
     261                 *  
     262                 * The mtime of the content is the mtime of the freshest base file 
     263                 *  
     264                 * */ 
    255265                 
    256266                lua_pushnil(L);  /* first key */ 
     
    286296                                } else { 
    287297                                        chunkqueue_append_file(con->write_queue, b, 0, st.st_size); 
     298                                        if (st.st_mtime > mtime) mtime = st.st_mtime; 
    288299                                } 
    289300                        } else { 
     
    302313                if (ret == 0) { 
    303314                        con->file_finished = 1; 
     315 
     316                        if (http_response_handle_cachable(srv, con, mtime)) { 
     317                                /* ok, the client already has our content,  
     318                                 * no need to send it again */ 
     319                                chunkqueue_reset(con->write_queue); 
     320                        } 
    304321                } else { 
    305322                        chunkqueue_reset(con->write_queue); 
  • branches/lighttpd-1.3.x/src/response.c

    r467 r468  
    852852 
    853853 
     854int http_response_handle_cachable(server *srv, connection *con, time_t mtime) { 
     855        if (con->http_status != 0) return 0; 
     856 
     857        /* 
     858         * 14.26 If-None-Match 
     859         *    [...] 
     860         *    If none of the entity tags match, then the server MAY perform the 
     861         *    requested method as if the If-None-Match header field did not exist, 
     862         *    but MUST also ignore any If-Modified-Since header field(s) in the 
     863         *    request. That is, if no entity tags match, then the server MUST NOT 
     864         *    return a 304 (Not Modified) response. 
     865         */ 
     866         
     867        /* last-modified handling */ 
     868        if (con->request.http_if_none_match) { 
     869                if (etag_is_equal(con->physical.etag, con->request.http_if_none_match)) { 
     870                        if (con->request.http_method == HTTP_METHOD_GET ||  
     871                            con->request.http_method == HTTP_METHOD_HEAD) { 
     872                                 
     873                                /* check if etag + last-modified */ 
     874                                if (con->request.http_if_modified_since) { 
     875                                        char buf[64]; 
     876                                        struct tm tm; 
     877                                        size_t used_len; 
     878                                        char *semicolon; 
     879                                 
     880                                        strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&mtime)); 
     881                                         
     882                                        if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) { 
     883                                                used_len = strlen(con->request.http_if_modified_since); 
     884                                        } else { 
     885                                                used_len = semicolon - con->request.http_if_modified_since; 
     886                                        } 
     887                                         
     888                                        if (0 == strncmp(con->request.http_if_modified_since, buf, used_len)) { 
     889                                                con->http_status = 304; 
     890                                                return 1; 
     891                                        } else { 
     892                                                /* convert to timestamp */ 
     893                                                if (used_len < sizeof(buf) - 1) { 
     894                                                        time_t t; 
     895                                                        strncpy(buf, con->request.http_if_modified_since, used_len); 
     896                                                        buf[used_len] = '\0'; 
     897                                                         
     898                                                        strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm); 
     899                                                         
     900                                                        if (-1 != (t = mktime(&tm)) && 
     901                                                            t <= mtime) { 
     902                                                                con->http_status = 304; 
     903                                                                return 1; 
     904                                                        } 
     905                                                } else { 
     906                                                        log_error_write(srv, __FILE__, __LINE__, "ss",  
     907                                                                        con->request.http_if_modified_since, buf); 
     908                                                         
     909                                                        con->http_status = 412; 
     910                                                        return 1; 
     911                                                } 
     912                                        } 
     913                                } else { 
     914                                        con->http_status = 304; 
     915                                        return 1; 
     916                                } 
     917                        } else { 
     918                                con->http_status = 412;  
     919                                return 1; 
     920                        } 
     921                } 
     922        } else if (con->request.http_if_modified_since) { 
     923                char buf[64]; 
     924                struct tm *tm; 
     925                size_t used_len; 
     926                char *semicolon; 
     927                 
     928                tm = gmtime(&(mtime)); 
     929                strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S GMT", tm); 
     930                 
     931                if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) { 
     932                        used_len = strlen(con->request.http_if_modified_since); 
     933                } else { 
     934                        used_len = semicolon - con->request.http_if_modified_since; 
     935                } 
     936                 
     937                if (0 == strncmp(con->request.http_if_modified_since, buf, used_len)) { 
     938                        con->http_status = 304; 
     939                        return 1; 
     940                } 
     941        } 
     942 
     943        return 0; 
     944} 
    854945 
    855946handler_t http_response_prepare(server *srv, connection *con) { 
     
    13501441                        /* generate e-tag */ 
    13511442                        etag_mutate(con->physical.etag, con->fce->etag); 
    1352                          
    1353                         /* 
    1354                          * 14.26 If-None-Match 
    1355                          *    [...] 
    1356                          *    If none of the entity tags match, then the server MAY perform the 
    1357                          *    requested method as if the If-None-Match header field did not exist, 
    1358                          *    but MUST also ignore any If-Modified-Since header field(s) in the 
    1359                          *    request. That is, if no entity tags match, then the server MUST NOT 
    1360                          *    return a 304 (Not Modified) response. 
    1361                          */ 
    1362                          
    1363                         /* last-modified handling */ 
    1364                         if (con->http_status == 0 &&  
    1365                             con->request.http_if_none_match) { 
    1366                                 if (etag_is_equal(con->physical.etag, con->request.http_if_none_match)) { 
    1367                                         if (con->request.http_method == HTTP_METHOD_GET ||  
    1368                                             con->request.http_method == HTTP_METHOD_HEAD) { 
     1443 
     1444                        http_response_handle_cachable(srv, con, con->fce->st.st_mtime); 
    13691445                                                 
    1370                                                 /* check if etag + last-modified */ 
    1371                                                 if (con->request.http_if_modified_since) { 
    1372                                                         char buf[64]; 
    1373                                                         struct tm tm; 
    1374                                                         size_t used_len; 
    1375                                                         char *semicolon; 
    1376                                                  
    1377                                                         strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(con->fce->st.st_mtime))); 
    1378                                                          
    1379                                                         if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) { 
    1380                                                                 used_len = strlen(con->request.http_if_modified_since); 
    1381                                                         } else { 
    1382                                                                 used_len = semicolon - con->request.http_if_modified_since; 
    1383                                                         } 
    1384                                                          
    1385                                                         if (0 == strncmp(con->request.http_if_modified_since, buf, used_len)) { 
    1386                                                                 con->http_status = 304; 
    1387                                                         } else { 
    1388                                                                 /* convert to timestamp */ 
    1389                                                                 if (used_len < sizeof(buf) - 1) { 
    1390                                                                         time_t t; 
    1391                                                                         strncpy(buf, con->request.http_if_modified_since, used_len); 
    1392                                                                         buf[used_len] = '\0'; 
    1393                                                                          
    1394                                                                         strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm); 
    1395                                                                          
    1396                                                                         if (-1 != (t = mktime(&tm)) && 
    1397                                                                             t <= con->fce->st.st_mtime) { 
    1398                                                                                 con->http_status = 304; 
    1399                                                                         } 
    1400                                                                 } else { 
    1401                                                                         log_error_write(srv, __FILE__, __LINE__, "ss",  
    1402                                                                                         con->request.http_if_modified_since, buf); 
    1403                                                                          
    1404                                                                         con->http_status = 412; 
    1405                                                                 } 
    1406                                                         } 
    1407                                                 } else { 
    1408                                                         con->http_status = 304; 
    1409                                                 } 
    1410                                         } else { 
    1411                                                 con->http_status = 412; 
    1412                                         } 
    1413                                 } 
    1414                         } else if (con->http_status == 0 && con->request.http_if_modified_since) { 
    1415                                 char buf[64]; 
    1416                                 struct tm *tm; 
    1417                                 size_t used_len; 
    1418                                 char *semicolon; 
    1419                                  
    1420                                 tm = gmtime(&(con->fce->st.st_mtime)); 
    1421                                 strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S GMT", tm); 
    1422                                  
    1423                                 if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) { 
    1424                                         used_len = strlen(con->request.http_if_modified_since); 
    1425                                 } else { 
    1426                                         used_len = semicolon - con->request.http_if_modified_since; 
    1427                                 } 
    1428                                  
    1429                                 if (0 == strncmp(con->request.http_if_modified_since, buf, used_len)) { 
    1430                                         con->http_status = 304; 
    1431                                 } 
    1432                         } 
    1433                          
    14341446                        if (con->http_status == 0 && con->request.http_range) { 
    14351447                                http_response_parse_range(srv, con); 
  • branches/lighttpd-1.3.x/src/response.h

    r26 r468  
    1515handler_t http_response_prepare(server *srv, connection *con); 
    1616int http_response_redirect_to_directory(server *srv, connection *con); 
     17int http_response_handle_cachable(server *srv, connection *con, time_t mtime); 
    1718 
    1819#endif