| 147 | } |
| 148 | |
| 149 | bool DateTime::fromHttpDate(const String& httpDate, time_t& time) |
| 150 | { |
| 151 | auto ptr = httpDate.c_str(); |
| 152 | |
| 153 | // Parse and return a decimal number and update ptr to the first non-numeric character after it |
| 154 | auto parseNumber = [&ptr]() { return strtol(ptr, const_cast<char**>(&ptr), 10); }; |
| 155 | |
| 156 | auto skipWhitespace = [&ptr]() -> void { |
| 157 | while(isspace(*ptr)) { |
| 158 | ++ptr; |
| 159 | } |
| 160 | }; |
| 161 | |
| 162 | skipWhitespace(); |
| 163 | if(!isdigit(*ptr)) { |
| 164 | // Don't actually use this value |
| 165 | uint8_t weekday; |
| 166 | if(!matchName(ptr, weekday, isoDayNames, 7)) { |
| 167 | return false; // Invalid day of week |
| 168 | } |
| 169 | if(ptr[0] == ',') { |
| 170 | // Accept "Sun,", etc. |
| 171 | ptr += 2; |
| 172 | } else if(strncmp(ptr, "day,", 4) == 0) { |
| 173 | // Accept "Sunday, ", etc |
| 174 | ptr += 5; |
| 175 | } else { |
| 176 | return false; |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | skipWhitespace(); |
| 181 | uint8_t day = parseNumber(); |
| 182 | if(*ptr != '-' && !isspace(*ptr)) { |
| 183 | return false; |
| 184 | } |
| 185 | ++ptr; |
| 186 | |
| 187 | // Should we check DayOfWeek against calculation from date? |
| 188 | // We could just ignore the DOW... |
| 189 | skipWhitespace(); |
| 190 | uint8_t month; |
| 191 | if(!matchName(ptr, month, isoMonthNames, 12)) { |
| 192 | return false; // Invalid month |
| 193 | } |
| 194 | if(*ptr != '-') { |
| 195 | // Skip over any other characters: assume that the full month name has been provided |
| 196 | while(*ptr != '\0' && !isspace(*ptr)) { |
| 197 | ++ptr; |
| 198 | } |
| 199 | if(*ptr == '\0') { |
| 200 | return false; |
| 201 | } |
| 202 | } |
| 203 | ++ptr; |
| 204 | |
| 205 | skipWhitespace(); |
| 206 | uint16_t year = parseNumber(); |
no test coverage detected