Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# HttpWebRequest Date Header Formatting

Tags:

c#

amazon-s3

I'm making a HttpWebRequest to S3, and I'm trying to set the Date header to something like this:

"Mon, 16 Jul 2012 01:16:18 -0000"

Here is what I've tried:

string pattern = "ddd, dd MMM yyyy HH:mm:ss -0000";
request.Date = DateTime.ParseExact("Mon, 16 Jul 2012 01:16:18 -0000", pattern, null);

But, when I look at the headers of the request, here's what I get:

request.Headers.Get("Date");
// "Mon, 16 Jul 2012 07:16:18 GMT"

I believe this may the reason for a 403 on the request. The AWS error docs mention:

403 Forbidden - The difference between the request time and the server's time is too large.

Any suggestions for getting this date sorted out would be greatly appreciated. Thanks!

like image 612
Mitciv Avatar asked Jul 16 '12 01:07

Mitciv


1 Answers

There are some things to clarify:

  • Your date pattern is incorrect.

  • The HttpWebRequest request.Date header can be only get modified in .NET Framework 4 and according to the documentation, the System.Net namespace will always write this header as standard form using GMT (UTC) format. So, whatever you can do to format your date as you want, won't work!

  • In other .NET framework versions you won't be able to modify the HttpWebRequest request.Date header because it will use the actual date in correct GMT (UTC) format unless you use a kind of hack to set your own date and format (see below).


Solution for your problem (tested and working):

Your imports:

using System.Net;
using System.Reflection;

Get today's date in format: Mon, 16 Jul 2012 01:16:18 -0000

string today = String.Format("{0:ddd,' 'dd' 'MMM' 'yyyy' 'HH':'mm':'ss' 'K}", DateTime.Now);

Here comes the tricky thing, you can hack the HttpWebRequest date header by doing this:

(Don't do request.Date = something; anymore, replace it with the following)

MethodInfo priMethod = request.Headers.GetType().GetMethod("AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic);
priMethod.Invoke(request.Headers, new[] { "Date", today });

Get the date from your request (just to test):

// "myDate" will output the same date as the first moment: 
// Mon, 16 Jul 2012 01:16:18 -0000
// As you can see, you will never get this again:
// Mon, 16 Jul 2012 07:16:18 GMT
string myDate = request.Headers.Get("Date");

At this point you had successfully set your own format and date value to the HttpWebRequest date header!

Hope this helps :-)

like image 154
Oscar Jara Avatar answered Oct 14 '22 04:10

Oscar Jara