Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
28e92293
Commit
28e92293
authored
Mar 04, 2011
by
Juan Lang
Committed by
Alexandre Julliard
Mar 07, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wininet: Store entries in url cache with valid last-modified date.
parent
f9f43118
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
176 additions
and
52 deletions
+176
-52
http.c
dlls/wininet/http.c
+175
-52
internet.h
dlls/wininet/internet.h
+1
-0
No files found.
dlls/wininet/http.c
View file @
28e92293
...
...
@@ -1572,14 +1572,12 @@ static void HTTPREQ_Destroy(object_header_t *hdr)
if
(
request
->
hCacheFile
)
{
WCHAR
url
[
INTERNET_MAX_URL_LENGTH
];
FILETIME
ft
;
CloseHandle
(
request
->
hCacheFile
);
memset
(
&
ft
,
0
,
sizeof
(
FILETIME
));
if
(
HTTP_GetRequestURL
(
request
,
url
))
{
CommitUrlCacheEntryW
(
url
,
request
->
cacheFile
,
request
->
expires
,
ft
,
NORMAL_CACHE_ENTRY
,
NULL
,
0
,
NULL
,
0
);
CommitUrlCacheEntryW
(
url
,
request
->
cacheFile
,
request
->
expires
,
request
->
last_modified
,
NORMAL_CACHE_ENTRY
,
NULL
,
0
,
NULL
,
0
);
}
}
...
...
@@ -3630,50 +3628,81 @@ static WORD HTTP_ParseMonth(LPCWSTR month)
return
0
;
}
/*
FIXME: only accepts dates in RFC 1123 format, which is the only correct
*
format for HTTP, but which may not be the only format actually seen in the
*
wild. http://www.hackcraft.net/web/datetime/ suggests at least RFC 850
*
dates and dates as formatted by asctime() should be accepted as well
.
/*
Parses the string pointed to by *str, assumed to be a 24-hour time HH:MM:SS,
*
optionally preceded by whitespace.
*
Upon success, returns TRUE, sets the wHour, wMinute, and wSecond fields of
*
st, and sets *str to the first character after the time format
.
*/
static
BOOL
HTTP_Parse
Date
(
LPCWSTR
value
,
FILETIME
*
ft
)
static
BOOL
HTTP_Parse
Time
(
SYSTEMTIME
*
st
,
LPCWSTR
*
str
)
{
static
const
WCHAR
gmt
[]
=
{
'G'
,
'M'
,
'T'
,
0
}
;
WCHAR
*
ptr
,
*
nextPtr
,
day
[
4
],
month
[
4
],
*
month
Ptr
;
LPCWSTR
ptr
=
*
str
;
WCHAR
*
next
Ptr
;
unsigned
long
num
;
SYSTEMTIME
st
;
ptr
=
strchrW
(
value
,
','
);
if
(
!
ptr
)
while
(
isspaceW
(
*
ptr
))
ptr
++
;
num
=
strtoulW
(
ptr
,
&
nextPtr
,
10
);
if
(
!
nextPtr
||
nextPtr
<=
ptr
||
*
nextPtr
!=
':'
)
{
ERR
(
"unexpected
date format %s
\n
"
,
debugstr_w
(
value
));
ERR
(
"unexpected
time format %s
\n
"
,
debugstr_w
(
ptr
));
return
FALSE
;
}
if
(
ptr
-
value
!=
3
)
if
(
num
>
2
3
)
{
ERR
(
"unexpected
weekday %s
\n
"
,
debugstr_wn
(
value
,
ptr
-
value
));
ERR
(
"unexpected
hour in time format %s
\n
"
,
debugstr_w
(
ptr
));
return
FALSE
;
}
memcpy
(
day
,
value
,
(
ptr
-
value
)
*
sizeof
(
WCHAR
))
;
day
[
3
]
=
0
;
st
.
wDayOfWeek
=
HTTP_ParseDay
(
day
);
if
(
st
.
wDayOfWeek
>
6
)
ptr
=
nextPtr
+
1
;
st
->
wHour
=
(
WORD
)
num
;
num
=
strtoulW
(
ptr
,
&
nextPtr
,
10
);
if
(
!
nextPtr
||
nextPtr
<=
ptr
||
*
nextPtr
!=
':'
)
{
ERR
(
"unexpected
weekday %s
\n
"
,
debugstr_wn
(
value
,
ptr
-
value
));
ERR
(
"unexpected
time format %s
\n
"
,
debugstr_w
(
ptr
));
return
FALSE
;
}
ptr
++
;
if
(
num
>
59
)
{
ERR
(
"unexpected minute in time format %s
\n
"
,
debugstr_w
(
ptr
));
return
FALSE
;
}
ptr
=
nextPtr
+
1
;
st
->
wMinute
=
(
WORD
)
num
;
num
=
strtoulW
(
ptr
,
&
nextPtr
,
10
);
if
(
!
nextPtr
||
nextPtr
<=
ptr
)
{
ERR
(
"unexpected time format %s
\n
"
,
debugstr_w
(
ptr
));
return
FALSE
;
}
if
(
num
>
59
)
{
ERR
(
"unexpected second in time format %s
\n
"
,
debugstr_w
(
ptr
));
return
FALSE
;
}
ptr
=
nextPtr
+
1
;
*
str
=
ptr
;
st
->
wSecond
=
(
WORD
)
num
;
return
TRUE
;
}
while
(
isspaceW
(
*
ptr
))
ptr
++
;
static
BOOL
HTTP_ParseDateAsAsctime
(
LPCWSTR
value
,
FILETIME
*
ft
)
{
static
const
WCHAR
gmt
[]
=
{
'G'
,
'M'
,
'T'
,
0
};
WCHAR
day
[
4
],
*
dayPtr
,
month
[
4
],
*
monthPtr
,
*
nextPtr
;
LPCWSTR
ptr
;
SYSTEMTIME
st
=
{
0
};
unsigned
long
num
;
num
=
strtoulW
(
ptr
,
&
nextPtr
,
10
);
if
(
!
nextPtr
||
nextPtr
<=
ptr
||
!
num
||
num
>
31
)
for
(
ptr
=
value
,
dayPtr
=
day
;
*
ptr
&&
!
isspaceW
(
*
ptr
)
&&
dayPtr
-
day
<
sizeof
(
day
)
/
sizeof
(
day
[
0
])
-
1
;
ptr
++
,
dayPtr
++
)
*
dayPtr
=
*
ptr
;
*
dayPtr
=
0
;
st
.
wDayOfWeek
=
HTTP_ParseDay
(
day
);
if
(
st
.
wDayOfWeek
>=
7
)
{
ERR
(
"unexpected
day %s
\n
"
,
debugstr_w
(
value
));
ERR
(
"unexpected
weekday %s
\n
"
,
debugstr_w
(
day
));
return
FALSE
;
}
ptr
=
nextPtr
;
st
.
wDay
=
(
WORD
)
num
;
while
(
isspaceW
(
*
ptr
))
ptr
++
;
...
...
@@ -3694,56 +3723,113 @@ static BOOL HTTP_ParseDate(LPCWSTR value, FILETIME *ft)
ptr
++
;
num
=
strtoulW
(
ptr
,
&
nextPtr
,
10
);
if
(
!
nextPtr
||
nextPtr
<=
ptr
||
num
<
1601
||
num
>
30827
)
if
(
!
nextPtr
||
nextPtr
<=
ptr
||
!
num
||
num
>
31
)
{
ERR
(
"unexpected
year %s
\n
"
,
debugstr_w
(
value
));
ERR
(
"unexpected
day %s
\n
"
,
debugstr_w
(
ptr
));
return
FALSE
;
}
ptr
=
nextPtr
;
st
.
wYear
=
(
WORD
)
num
;
st
.
wDay
=
(
WORD
)
num
;
while
(
isspaceW
(
*
ptr
))
ptr
++
;
if
(
!
HTTP_ParseTime
(
&
st
,
&
ptr
))
return
FALSE
;
while
(
isspaceW
(
*
ptr
))
ptr
++
;
num
=
strtoulW
(
ptr
,
&
nextPtr
,
10
);
if
(
!
nextPtr
||
nextPtr
<=
ptr
||
*
nextPtr
!=
':'
)
if
(
!
nextPtr
||
nextPtr
<=
ptr
||
num
<
1601
||
num
>
30827
)
{
ERR
(
"unexpected
time format
%s
\n
"
,
debugstr_w
(
ptr
));
ERR
(
"unexpected
year
%s
\n
"
,
debugstr_w
(
ptr
));
return
FALSE
;
}
if
(
num
>
23
)
ptr
=
nextPtr
;
st
.
wYear
=
(
WORD
)
num
;
while
(
isspaceW
(
*
ptr
))
ptr
++
;
/* asctime() doesn't report a timezone, but some web servers do, so accept
* with or without GMT.
*/
if
(
*
ptr
&&
strcmpW
(
ptr
,
gmt
))
{
ERR
(
"unexpected
hour in time format
%s
\n
"
,
debugstr_w
(
ptr
));
ERR
(
"unexpected
timezone
%s
\n
"
,
debugstr_w
(
ptr
));
return
FALSE
;
}
ptr
=
nextPtr
+
1
;
st
.
wHour
=
(
WORD
)
num
;
num
=
strtoulW
(
ptr
,
&
nextPtr
,
10
);
if
(
!
nextPtr
||
nextPtr
<=
ptr
||
*
nextPtr
!=
':'
)
return
SystemTimeToFileTime
(
&
st
,
ft
);
}
static
BOOL
HTTP_ParseRfc1123Date
(
LPCWSTR
value
,
FILETIME
*
ft
)
{
static
const
WCHAR
gmt
[]
=
{
'G'
,
'M'
,
'T'
,
0
};
WCHAR
*
nextPtr
,
day
[
4
],
month
[
4
],
*
monthPtr
;
LPCWSTR
ptr
;
unsigned
long
num
;
SYSTEMTIME
st
;
ptr
=
strchrW
(
value
,
','
);
if
(
!
ptr
)
return
FALSE
;
if
(
ptr
-
value
!=
3
)
{
ERR
(
"unexpected
time format %s
\n
"
,
debugstr_w
(
ptr
));
ERR
(
"unexpected
weekday %s
\n
"
,
debugstr_wn
(
value
,
ptr
-
value
));
return
FALSE
;
}
if
(
num
>
59
)
memcpy
(
day
,
value
,
(
ptr
-
value
)
*
sizeof
(
WCHAR
));
day
[
3
]
=
0
;
st
.
wDayOfWeek
=
HTTP_ParseDay
(
day
);
if
(
st
.
wDayOfWeek
>
6
)
{
ERR
(
"unexpected
minute in time format %s
\n
"
,
debugstr_w
(
ptr
));
ERR
(
"unexpected
weekday %s
\n
"
,
debugstr_wn
(
value
,
ptr
-
value
));
return
FALSE
;
}
ptr
=
nextPtr
+
1
;
st
.
wMinute
=
(
WORD
)
num
;
ptr
++
;
while
(
isspaceW
(
*
ptr
))
ptr
++
;
num
=
strtoulW
(
ptr
,
&
nextPtr
,
10
);
if
(
!
nextPtr
||
nextPtr
<=
ptr
)
if
(
!
nextPtr
||
nextPtr
<=
ptr
||
!
num
||
num
>
31
)
{
ERR
(
"unexpected
time format %s
\n
"
,
debugstr_w
(
ptr
));
ERR
(
"unexpected
day %s
\n
"
,
debugstr_w
(
value
));
return
FALSE
;
}
if
(
num
>
59
)
ptr
=
nextPtr
;
st
.
wDay
=
(
WORD
)
num
;
while
(
isspaceW
(
*
ptr
))
ptr
++
;
for
(
monthPtr
=
month
;
!
isspace
(
*
ptr
)
&&
monthPtr
-
month
<
sizeof
(
month
)
/
sizeof
(
month
[
0
])
-
1
;
monthPtr
++
,
ptr
++
)
*
monthPtr
=
*
ptr
;
*
monthPtr
=
0
;
st
.
wMonth
=
HTTP_ParseMonth
(
month
);
if
(
!
st
.
wMonth
||
st
.
wMonth
>
12
)
{
ERR
(
"unexpected
second in time format %s
\n
"
,
debugstr_w
(
ptr
));
ERR
(
"unexpected
month %s
\n
"
,
debugstr_w
(
month
));
return
FALSE
;
}
ptr
=
nextPtr
+
1
;
st
.
wSecond
=
(
WORD
)
num
;
while
(
isspaceW
(
*
ptr
))
ptr
++
;
num
=
strtoulW
(
ptr
,
&
nextPtr
,
10
);
if
(
!
nextPtr
||
nextPtr
<=
ptr
||
num
<
1601
||
num
>
30827
)
{
ERR
(
"unexpected year %s
\n
"
,
debugstr_w
(
value
));
return
FALSE
;
}
ptr
=
nextPtr
;
st
.
wYear
=
(
WORD
)
num
;
if
(
!
HTTP_ParseTime
(
&
st
,
&
ptr
))
return
FALSE
;
while
(
isspaceW
(
*
ptr
))
ptr
++
;
...
...
@@ -3756,6 +3842,26 @@ static BOOL HTTP_ParseDate(LPCWSTR value, FILETIME *ft)
return
SystemTimeToFileTime
(
&
st
,
ft
);
}
/* FIXME: only accepts dates in RFC 1123 format and asctime() format,
* which may not be the only formats actually seen in the wild.
* http://www.hackcraft.net/web/datetime/ suggests at least RFC 850 dates
* should be accepted as well.
*/
static
BOOL
HTTP_ParseDate
(
LPCWSTR
value
,
FILETIME
*
ft
)
{
BOOL
ret
;
if
(
strchrW
(
value
,
','
))
ret
=
HTTP_ParseRfc1123Date
(
value
,
ft
);
else
{
ret
=
HTTP_ParseDateAsAsctime
(
value
,
ft
);
if
(
!
ret
)
ERR
(
"unexpected date format %s
\n
"
,
debugstr_w
(
value
));
}
return
ret
;
}
static
void
HTTP_ProcessExpires
(
http_request_t
*
request
)
{
BOOL
expirationFound
=
FALSE
;
...
...
@@ -3843,6 +3949,21 @@ static void HTTP_ProcessExpires(http_request_t *request)
}
}
static
void
HTTP_ProcessLastModified
(
http_request_t
*
request
)
{
int
headerIndex
;
headerIndex
=
HTTP_GetCustomHeaderIndex
(
request
,
szLast_Modified
,
0
,
FALSE
);
if
(
headerIndex
!=
-
1
)
{
LPHTTPHEADERW
expiresHeader
=
&
request
->
custHeaders
[
headerIndex
];
FILETIME
ft
;
if
(
HTTP_ParseDate
(
expiresHeader
->
lpszValue
,
&
ft
))
request
->
last_modified
=
ft
;
}
}
static
void
HTTP_CacheRequest
(
http_request_t
*
request
)
{
WCHAR
url
[
INTERNET_MAX_URL_LENGTH
];
...
...
@@ -4051,6 +4172,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
HTTP_ProcessCookies
(
request
);
HTTP_ProcessExpires
(
request
);
HTTP_ProcessLastModified
(
request
);
if
(
!
set_content_length
(
request
))
HTTP_FinishedReading
(
request
);
...
...
@@ -4214,6 +4336,7 @@ static DWORD HTTP_HttpEndRequestW(http_request_t *request, DWORD dwFlags, DWORD_
/* process cookies here. Is this right? */
HTTP_ProcessCookies
(
request
);
HTTP_ProcessExpires
(
request
);
HTTP_ProcessLastModified
(
request
);
if
(
!
set_content_length
(
request
))
HTTP_FinishedReading
(
request
);
...
...
dlls/wininet/internet.h
View file @
28e92293
...
...
@@ -274,6 +274,7 @@ typedef struct
DWORD
bytesWritten
;
HTTPHEADERW
*
custHeaders
;
DWORD
nCustHeaders
;
FILETIME
last_modified
;
HANDLE
hCacheFile
;
LPWSTR
cacheFile
;
FILETIME
expires
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment