Ignore:
Timestamp:
05/09/11 23:05:31 (9 years ago)
Author:
Admin
Message:

WebIf: Add parsing for etag, keepalive and if-modified-sinced header. Implement if-modified-since header parsing so that images, js and css are not transmitted on refreshs if unchanged.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/oscam-http-helpers.c

    r5201 r5212  
    313313}
    314314
     315/* Parses the date out of a "If-Modified-Since"-header. Note that the original string is modified. */
     316time_t parse_modifiedsince(char * value){
     317    int32_t day = -1, month = -1, year = -1, hour = -1, minutes = -1, seconds = -1;
     318    char months[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
     319    char *str, *saveptr1 = NULL;
     320    time_t modifiedheader = 0;
     321    value += 18;
     322    // Parse over weekday at beginning...
     323    while(value[0] == ' ' && value[0] != '\0') ++value;
     324    while(value[0] != ' ' && value[0] != '\0') ++value;
     325    // According to http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 three different timeformats are allowed so we need a bit logic to parse all of them...
     326    if(value[0] != '\0'){
     327        ++value;
     328        for(month = 0; month < 12; ++month){
     329            if(strstr(value, months[month])) break;
     330        }
     331        if(month > 11) month = -1;
     332        for (str=strtok_r(value, " ", &saveptr1); str; str=strtok_r(NULL, " ", &saveptr1)){
     333            switch(strlen(str)){
     334                case 1:
     335                case 2:
     336                    day = atoi(str);
     337                    break;
     338               
     339                case 4:
     340                    if(str[0] != 'G')
     341                        year = atoi(str);
     342                    break;
     343                   
     344                case 8:
     345                    if(str[2] == ':' && str[5] == ':'){
     346                        hour = atoi(str);
     347                        minutes = atoi(str + 3);
     348                        seconds = atoi(str + 6);
     349                    }
     350                    break;
     351                   
     352                case 9:
     353                    if(str[2] == '-' && str[6] == '-'){
     354                        day = atoi(str);
     355                        year = atoi(str + 6) + 2000;
     356                    }
     357                    break;
     358            }
     359        }
     360        if(day > 0 && day < 32 && month > 0 && year > 0 && year < 9999 && hour > -1 && hour < 24 && minutes > -1 && minutes < 60 && seconds > -1 && seconds < 60){
     361            struct tm timeinfo;
     362            memset(&timeinfo, 0, sizeof(timeinfo));
     363            timeinfo.tm_mday = day;
     364            timeinfo.tm_mon = month;
     365            timeinfo.tm_year = year - 1900;
     366            timeinfo.tm_hour = hour;
     367            timeinfo.tm_min = minutes;
     368            timeinfo.tm_sec = seconds;
     369            modifiedheader = timegm(&timeinfo);
     370        }
     371    }   
     372    return modifiedheader;
     373}
     374
    315375/* Calculates the currently valid nonce value and copies it to result. Please note that result needs to be at least (MD5_DIGEST_LENGTH * 2) + 1 large. */
    316376void calculate_nonce(char *result){
     
    430490    if(!cache){
    431491        pos += snprintf(pos, sizeof(buf)-(pos-buf),"Cache-Control: no-store, no-cache, must-revalidate\r\n");
    432         pos += snprintf(pos, sizeof(buf)-(pos-buf),"Expires: Sat, 26 Jul 1997 05:00:00 GMT\r\n");
     492        pos += snprintf(pos, sizeof(buf)-(pos-buf),"Expires: Sat, 10 Jan 2000 05:00:00 GMT\r\n");
    433493    } else {
    434494        pos += snprintf(pos, sizeof(buf)-(pos-buf),"Cache-Control: public, max-age=7200\r\n");
    435495    }
    436496    pos += snprintf(pos, sizeof(buf)-(pos-buf),"Content-Length: %d\r\n", length);
    437     pos += snprintf(pos, sizeof(buf)-(pos-buf),"Last-Modified: %s\r\n", timebuf);
     497    if(status != 304) pos += snprintf(pos, sizeof(buf)-(pos-buf),"Last-Modified: %s\r\n", timebuf);
    438498    pos += snprintf(pos, sizeof(buf)-(pos-buf), "Connection: close\r\n");
    439499    pos += snprintf(pos, sizeof(buf)-(pos-buf),"\r\n");
     
    445505 * function for sending files.
    446506 */
    447 void send_file(FILE *f, char *filename){
     507void send_file(FILE *f, char *filename, time_t modifiedheader){
    448508    int32_t fileno = 0;
    449509    char* mimetype = "";
     
    465525        struct stat st;
    466526       
    467         stat(filename, &st);       
     527        stat(filename, &st);
     528        if(st.st_mtime < modifiedheader){
     529            send_headers(f, 304, "Not Modified", NULL, NULL, 1, 0, 0);
     530            return;
     531        }
    468532        if((fp = fopen(filename, "r"))==NULL) return;
    469533        send_headers(f, 200, "OK", NULL, mimetype, 1, st.st_size, 0);
     
    475539        fclose (fp);
    476540    } else {
     541        if((fileno == 1 || fileno == 2) && first_client->login < modifiedheader){
     542            send_headers(f, 304, "Not Modified", NULL, NULL, 1, 0, 0);
     543            return;
     544        }
    477545        if (fileno == 1){
    478546            send_headers(f, 200, "OK", NULL, mimetype, 1, strlen(CSS), 0);
Note: See TracChangeset for help on using the changeset viewer.