You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2012/08/15 19:51:06 UTC

git commit: COUCHDB-627 - Support all timezones

Updated Branches:
  refs/heads/master f5341a7dc -> b1a049bb7


COUCHDB-627 - Support all timezones

Some timezones are incorrectly handled by OTP's calendar module. The
ironic thing is that we only ever need the time in GMT (for HTTP
response headers and the log file).

This patch duplicates httpd_util:rfc1123_date/0 and /1 but uses
universal time everywhere, avoiding the broken conversion code.

Also relates to COUCHDB-1513, a duplicate of COUCHDB-627.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/b1a049bb
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/b1a049bb
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/b1a049bb

Branch: refs/heads/master
Commit: b1a049bb7091d3d75092b68bb3645ae909653547
Parents: f5341a7
Author: Robert Newson <rn...@apache.org>
Authored: Wed Aug 15 12:34:48 2012 +0100
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Aug 15 18:35:53 2012 +0100

----------------------------------------------------------------------
 src/couch_replicator/src/couch_replicator.erl |    4 +-
 src/couchdb/couch_httpd_misc_handlers.erl     |    6 +-
 src/couchdb/couch_log.erl                     |    2 +-
 src/couchdb/couch_server.erl                  |    2 +-
 src/couchdb/couch_util.erl                    |   42 ++++++++++++++++++++
 src/mochiweb/mochiweb_cookies.erl             |   12 +++---
 src/mochiweb/mochiweb_request.erl             |    6 +-
 7 files changed, 58 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/b1a049bb/src/couch_replicator/src/couch_replicator.erl
----------------------------------------------------------------------
diff --git a/src/couch_replicator/src/couch_replicator.erl b/src/couch_replicator/src/couch_replicator.erl
index e91e1ae..1ce2cf5 100644
--- a/src/couch_replicator/src/couch_replicator.erl
+++ b/src/couch_replicator/src/couch_replicator.erl
@@ -553,7 +553,7 @@ init_state(Rep) ->
         committed_seq = StartSeq,
         source_log = SourceLog,
         target_log = TargetLog,
-        rep_starttime = httpd_util:rfc1123_date(),
+        rep_starttime = couch_util:rfc1123_date(),
         src_starttime = get_value(<<"instance_start_time">>, SourceInfo),
         tgt_starttime = get_value(<<"instance_start_time">>, TargetInfo),
         session_id = couch_uuids:random(),
@@ -706,7 +706,7 @@ do_checkpoint(State) ->
         ?LOG_INFO("recording a checkpoint for `~s` -> `~s` at source update_seq ~p",
             [SourceName, TargetName, NewSeq]),
         StartTime = ?l2b(ReplicationStartTime),
-        EndTime = ?l2b(httpd_util:rfc1123_date()),
+        EndTime = ?l2b(couch_util:rfc1123_date()),
         NewHistoryEntry = {[
             {<<"session_id">>, SessionId},
             {<<"start_time">>, StartTime},

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b1a049bb/src/couchdb/couch_httpd_misc_handlers.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_misc_handlers.erl b/src/couchdb/couch_httpd_misc_handlers.erl
index 4025448..918665b 100644
--- a/src/couchdb/couch_httpd_misc_handlers.erl
+++ b/src/couchdb/couch_httpd_misc_handlers.erl
@@ -44,12 +44,12 @@ handle_welcome_req(Req, _) ->
     send_method_not_allowed(Req, "GET,HEAD").
 
 handle_favicon_req(#httpd{method='GET'}=Req, DocumentRoot) ->
-    {{Year,Month,Day},Time} = erlang:localtime(),
+    {{Year,Month,Day},Time} = erlang:universatime(),
     OneYearFromNow = {{Year+1,Month,Day},Time},
     CachingHeaders = [
         %favicon should expire a year from now
         {"Cache-Control", "public, max-age=31536000"},
-        {"Expires", httpd_util:rfc1123_date(OneYearFromNow)}
+        {"Expires", couch_util:rfc1123_date(OneYearFromNow)}
     ],
     couch_httpd:serve_file(Req, "favicon.ico", DocumentRoot, CachingHeaders);
 
@@ -103,7 +103,7 @@ handle_uuids_req(#httpd{method='GET'}=Req) ->
     Etag = couch_httpd:make_etag(UUIDs),
     couch_httpd:etag_respond(Req, Etag, fun() ->
         CacheBustingHeaders = [
-            {"Date", httpd_util:rfc1123_date()},
+            {"Date", couch_util:rfc1123_date()},
             {"Cache-Control", "no-cache"},
             % Past date, ON PURPOSE!
             {"Expires", "Fri, 01 Jan 1990 00:00:00 GMT"},

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b1a049bb/src/couchdb/couch_log.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_log.erl b/src/couchdb/couch_log.erl
index 8e24cab..a38c38a 100644
--- a/src/couchdb/couch_log.erl
+++ b/src/couchdb/couch_log.erl
@@ -159,7 +159,7 @@ log(#state{fd = Fd}, ConsoleMsg, FileMsg) ->
 get_log_messages(Pid, Level, Format, Args) ->
     ConsoleMsg = unicode:characters_to_binary(io_lib:format(
         "[~s] [~p] " ++ Format ++ "~n", [Level, Pid | Args])),
-    FileMsg = ["[", httpd_util:rfc1123_date(), "] ", ConsoleMsg],
+    FileMsg = ["[", couch_util:rfc1123_date(), "] ", ConsoleMsg],
     {ConsoleMsg, iolist_to_binary(FileMsg)}.
 
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b1a049bb/src/couchdb/couch_server.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_server.erl b/src/couchdb/couch_server.erl
index 8ebb7d6..650ce14 100644
--- a/src/couchdb/couch_server.erl
+++ b/src/couchdb/couch_server.erl
@@ -170,7 +170,7 @@ init([]) ->
     {ok, #server{root_dir=RootDir,
                 dbname_regexp=RegExp,
                 max_dbs_open=MaxDbsOpen,
-                start_time=httpd_util:rfc1123_date()}}.
+                start_time=couch_util:rfc1123_date()}}.
 
 terminate(_Reason, _Srv) ->
     lists:foreach(

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b1a049bb/src/couchdb/couch_util.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_util.erl b/src/couchdb/couch_util.erl
index d023bb6..afe3528 100644
--- a/src/couchdb/couch_util.erl
+++ b/src/couchdb/couch_util.erl
@@ -28,6 +28,7 @@
 -export([url_strip_password/1]).
 -export([encode_doc_id/1]).
 -export([with_db/2]).
+-export([rfc1123_date/0, rfc1123_date/1]).
 
 -include("couch_db.hrl").
 
@@ -445,3 +446,44 @@ with_db(DbName, Fun) ->
         Else ->
             throw(Else)
     end.
+
+rfc1123_date() ->
+    {{YYYY,MM,DD},{Hour,Min,Sec}} = calendar:universal_time(),
+    DayNumber = calendar:day_of_the_week({YYYY,MM,DD}),
+    lists:flatten(
+      io_lib:format("~s, ~2.2.0w ~3.s ~4.4.0w ~2.2.0w:~2.2.0w:~2.2.0w GMT",
+            [day(DayNumber),DD,month(MM),YYYY,Hour,Min,Sec])).
+
+rfc1123_date(undefined) ->
+    undefined;
+rfc1123_date(UniversalTime) ->
+    {{YYYY,MM,DD},{Hour,Min,Sec}} = UniversalTime,
+    DayNumber = calendar:day_of_the_week({YYYY,MM,DD}),
+    lists:flatten(
+      io_lib:format("~s, ~2.2.0w ~3.s ~4.4.0w ~2.2.0w:~2.2.0w:~2.2.0w GMT",
+            [day(DayNumber),DD,month(MM),YYYY,Hour,Min,Sec])).
+
+%% day
+
+day(1) -> "Mon";
+day(2) -> "Tue";
+day(3) -> "Wed";
+day(4) -> "Thu";
+day(5) -> "Fri";
+day(6) -> "Sat";
+day(7) -> "Sun".
+
+%% month
+
+month(1) -> "Jan";
+month(2) -> "Feb";
+month(3) -> "Mar";
+month(4) -> "Apr";
+month(5) -> "May";
+month(6) -> "Jun";
+month(7) -> "Jul";
+month(8) -> "Aug";
+month(9) -> "Sep";
+month(10) -> "Oct";
+month(11) -> "Nov";
+month(12) -> "Dec".

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b1a049bb/src/mochiweb/mochiweb_cookies.erl
----------------------------------------------------------------------
diff --git a/src/mochiweb/mochiweb_cookies.erl b/src/mochiweb/mochiweb_cookies.erl
index c090b71..1901d5e 100644
--- a/src/mochiweb/mochiweb_cookies.erl
+++ b/src/mochiweb/mochiweb_cookies.erl
@@ -49,9 +49,9 @@ cookie(Key, Value, Options) ->
             RawAge ->
                 When = case proplists:get_value(local_time, Options) of
                            undefined ->
-                               calendar:local_time();
+                               calendar:universal_time();
                            LocalTime ->
-                               LocalTime
+                               calendar:local_time_to_universal_time_dst(LocalTime)
                        end,
                 Age = case RawAge < 0 of
                           true ->
@@ -115,12 +115,12 @@ quote(V0) ->
         orelse erlang:error({cookie_quoting_required, V}),
     V.
 
-add_seconds(Secs, LocalTime) ->
-    Greg = calendar:datetime_to_gregorian_seconds(LocalTime),
+add_seconds(Secs, UniversalTime) ->
+    Greg = calendar:datetime_to_gregorian_seconds(UniversalTime),
     calendar:gregorian_seconds_to_datetime(Greg + Secs).
 
-age_to_cookie_date(Age, LocalTime) ->
-    httpd_util:rfc1123_date(add_seconds(Age, LocalTime)).
+age_to_cookie_date(Age, UniversalTime) ->
+    couch_util:rfc1123_date(add_seconds(Age, UniversalTime)).
 
 %% @spec parse_cookie(string()) -> [{K::string(), V::string()}]
 %% @doc Parse the contents of a Cookie header field, ignoring cookie

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b1a049bb/src/mochiweb/mochiweb_request.erl
----------------------------------------------------------------------
diff --git a/src/mochiweb/mochiweb_request.erl b/src/mochiweb/mochiweb_request.erl
index 8225778..2bc54c0 100644
--- a/src/mochiweb/mochiweb_request.erl
+++ b/src/mochiweb/mochiweb_request.erl
@@ -600,9 +600,9 @@ maybe_redirect(RelPath, FullPath, ExtraHeaders) ->
     end.
 
 maybe_serve_file(File, ExtraHeaders) ->
-    case file:read_file_info(File) of
+    case file:read_file_info(File, [{time, universal}]) of
         {ok, FileInfo} ->
-            LastModified = httpd_util:rfc1123_date(FileInfo#file_info.mtime),
+            LastModified = couch_util:rfc1123_date(FileInfo#file_info.mtime),
             case get_header_value("if-modified-since") of
                 LastModified ->
                     respond({304, ExtraHeaders, ""});
@@ -626,7 +626,7 @@ maybe_serve_file(File, ExtraHeaders) ->
 
 server_headers() ->
     [{"Server", "MochiWeb/1.0 (" ++ ?QUIP ++ ")"},
-     {"Date", httpd_util:rfc1123_date()}].
+     {"Date", couch_util:rfc1123_date()}].
 
 make_code(X) when is_integer(X) ->
     [integer_to_list(X), [" " | httpd_util:reason_phrase(X)]];