2012-07-16 14 views
5

मैं S3 के लिए एक HttpWebRequest बना रही हूँ, और मैं कुछ इस तरह करने के लिए तिथि हैडर स्थापित करने के लिए कोशिश कर रहा हूँ:सी # HttpWebRequest दिनांक हेडर का प्रारूपण

"सोम, 16 जुला 2012 01:16:18 -

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

लेकिन, जब मैं अनुरोध के हेडर को देखो, यहाँ मैं क्या मिलता है: 0000 "

यहाँ मैं क्या कोशिश की है है

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

मुझे विश्वास है कि अनुरोध पर 403 का कारण हो सकता है। एडब्ल्यूएस त्रुटि डॉक्स का उल्लेख:

403 निषिद्ध - अनुरोध समय और सर्वर के समय के बीच का अंतर बहुत बड़ा है।

इस तारीख को हल करने के लिए कोई सुझाव बहुत सराहना की जाएगी। धन्यवाद!

उत्तर

13

मिल वहाँ कुछ चीजों को स्पष्ट करने हैं हाथ से अनुरोध ठीक में:

  • आपकी तिथि पैटर्न गलत है।

  • HttpWebRequest request.Date हैडर केवल .NET फ्रेमवर्क 4 में संशोधित करने के किया जा सकता है और प्रलेखन के अनुसार, System.Net नाम स्थान हमेशा जीएमटी (UTC) प्रारूप का उपयोग कर मानक फार्म के रूप में इस शीर्ष लेख लिखेंगे। तो, जो भी आप अपनी तिथि को प्रारूपित करने के लिए कर सकते हैं, काम नहीं करेंगे!

  • अन्य .NET फ़्रेमवर्क संस्करणों में आप HttpWebRequest request.Date हैडर को संशोधित करने के जब तक आप हैक का एक प्रकार का उपयोग अपनी स्वयं की तिथि निर्धारित करने के लिए है क्योंकि यह सही जीएमटी (यूटीसी) प्रारूप में वास्तविक तिथि का उपयोग करेगा में सक्षम नहीं होगा और प्रारूप (नीचे देखें)।आपकी समस्या के लिए


समाधान (परीक्षण किया है और काम कर रहे):

आपका आयात:

using System.Net; 
using System.Reflection; 

प्रारूप में आज की तारीख जाओ: सोमवार, 16 जुला 2012 01:16:18 -0000

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

यहाँ आता है मुश्किल बात है, तो आप ऐसा करने से HttpWebRequest तारीख हैडर हैक कर सकते हैं:

(अब request.Date = something; करते हैं, निम्नलिखित के साथ बदलने मत करो)

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

अपने अनुरोध से तारीख प्राप्त करें (केवल परीक्षण करने के लिए):

// "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"); 

इस बिंदु पर आपने सफलतापूर्वक अपने प्रारूप और दिनांक मूल्य को HttpWebRequest दिनांक शीर्षलेख पर सेट कर दिया था!

आशा इस मान लिया जाये कि आप प्राधिकरण हैडर काम करने के लिए तिथि हैडर सेट करना चाहते हैं :-)

+1

आप आदमी हैं। – Mitciv

+1

ग्रेट समाधान और उदाहरण। मुझे अपनी तिथि के लिए यूनिक्स टाइम स्टैम्प (दशमलव) का उपयोग करना होगा, और यह एकदम सही समाधान था। चीयर्स! – wloescher

+1

मेरी इच्छा है कि मैं इसे एक से अधिक बार बढ़ा सकता हूं! महान जवाब :) – Winnie

1

HttpWebRequest उचित रूप से तिथि को प्रारूपित करेगा। आपकी समस्या यह है कि आपको एक वैध वर्तमान तिथि जमा करनी होगी। आपको यह देखना होगा कि कंप्यूटर की घड़ी सही है, और फिर आप समय क्षेत्र और UTC और GMT मुद्दों के बारे में उचित तिथि भेज रहे हैं कि ...

दोनों की कोशिश:

request.Date = DateTime.Now; 
request.Date = DateTime.UtcNow; 

कि में से एक काम करने की जरूरत है (और दोनों काम करना चाहिए यदि HttpWebRequest ठीक से कार्यान्वित किया गया है)।

मामले में, काम नहीं करता है fiddler का उपयोग देखने के लिए क्या हो रहा है, और जब तक आप यह काम कर रहा

0

मदद करता है।

अमेज़ॅन एक और कस्टम हेडर प्रदान करता है जो दिनांक (यदि प्रदान किया गया हो) के बजाय उपयोग किया जाएगा। यदि आप दिनांक शीर्षलेख सेट करने में असमर्थ हैं, तो आप इसके बजाय कस्टम हेडर, x-amz-date का उपयोग कर सकते हैं।

यहाँ अमेज़न के डॉक्स here

+0

कृपया एक लिंक छोड़ने के बजाय इस पोस्ट में अधिक जानकारी पोस्ट करें। यह भविष्य के आगंतुकों के लिए अधिक उपयोगी है, खोजों में बेहतर दिखाता है और अगर लिंक खराब हो जाता है तो जारी रहेगा। –

0

आप का उपयोग करना चाहिए "एक्स-Amz-तिथि" शीर्षक के लिए लिंक है।

public void GetObject(string AccessKeyID, string SecretKey){   
     /*objectKey = folder/folder/filename.zzz*/ 
     var url = "http://somehost/bucket/objectkey" 

     HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url); 
     /*Fiddler proxy*/ 
     /*request.Proxy = new WebProxy("http://127.0.0.1:8888");*/ 

     request.Headers.Add("X-Amz-Date",String.Format("{0:ddd,' 'dd' 'MMM' 'yyyy' 'HH':'mm':'ss' 'K}", DateTime.Now)); 
     request.Headers.Add("Authorization", $"AWS {AccessKeyID}:{SignAuthorizationString(request, SecretKey)}"); 

     WebResponse response = request.GetResponse(); 
     } 
private string SignAuthorizationString(HttpWebRequest request, string SecretKey){ 
     //TODO: DOCS - http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html 

     string canonicalizedResource = request.RequestUri.PathAndQuery; 
     string canonicalizedAmzHeaders = ComposeSignatureAmzHeadersForSigning(request); 
     string stringToSign = request.Method + "\n" 
           + request.Headers.Get("Content-MD5") + "\n" 
           + request.ContentType + "\n" 
           + request.Headers.Get("Date") + "\n" /*Here the date will be blank*/ 
           + canonicalizedAmzHeaders + canonicalizedResource; 

     return GetSignedMessage(SecretKey, stringToSign); 
     } 
private string ComposeSignatureAmzHeadersForSigning(HttpWebRequest request){ 
     SortedDictionary<string, string> headersDictionary = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase); 
     foreach (string _key in request.Headers.Keys) 
     { 
      key = _key.ToLower(); 
      if (key.StartsWith("x-amz")) 
      { 
       if ("x-amz-meta-reviewedby".Equals(key)) 
       { 
        if (headersDictionary.ContainsKey(key)) 
         headersDictionary[key] = headersDictionary[key] + "," + request.Headers[key]; 
        else 
         headersDictionary[key] = request.Headers[key]; 
       } 
       else 
        headersDictionary[key] = request.Headers.Get(key); 
      } 
     } 
     StringBuilder stringBuilder = new StringBuilder(); 
     foreach (var pair in headersDictionary) 
     { 
      stringBuilder.Append(pair.Key) 
       .Append(":") 
       .Append(pair.Value) 
       .Append("\n"); 

     } 
     return stringBuilder.ToString(); 
     } 
private static string GetSignedMessage(string key, string message){ 
     var crypt = HMACSHA1.Create(); 
     crypt.Key = Encoding.ASCII.GetBytes(key); 
     crypt.ComputeHash(Encoding.UTF8.GetBytes(message)); 

     return Convert.ToBase64String(crypt.Hash); 
     } 
संबंधित मुद्दे