-
Notifications
You must be signed in to change notification settings - Fork 0
/
RequestSender.cs
156 lines (136 loc) · 6.22 KB
/
RequestSender.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
using Newtonsoft.Json.Linq;
using StorageAccountData.Entities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
namespace StorageAccountData
{
public class RequestSender
{
private readonly string account;
private readonly string table;
private readonly byte[] sharedKey;
UpdatedObjectConverter objectConverter = new UpdatedObjectConverter();
//account - Settings -> Access Key -> Storage Account Name
//key - Settings -> Access Key -> Key1 lub Key2 (bez znaczenia ktory)
//table - nazwa tabeli, na ktorej beda dokonywane zmiany
public RequestSender(string account, string key, string table)
{
this.account = account;
this.table = table;
sharedKey = Convert.FromBase64String(key);
}
private void WriteRequest(HttpWebRequest request, string json)
{
//dodawanie do zadania jsona, bedacy obrazem dodawanego/edytowanego rekordu
using (StreamWriter stream = new StreamWriter(request.GetRequestStream()))
{
stream.Write(json);
}
}
private string CreateAuthorizationString(HttpWebRequest request)
{
string resource = request.RequestUri.PathAndQuery;
if (resource.Contains("?"))
{
resource = resource.Substring(0, resource.IndexOf("?"));
}
//tworzenie signature, który jest kodem HMAC opartym na skrótach (HMAC)
//skonstruowanym z żądania i obliczonym przy użyciu algorytmu SHA256,
//a następnie zakodowanym przy użyciu kodowania Base64
string stringToSignature = string.Format($"{request.Headers["x-ms-date"]}\n/{account}{resource}");
HMACSHA256 hasher = new HMACSHA256(sharedKey);
string signedSignature = Convert.ToBase64String(hasher.ComputeHash(Encoding.UTF8.GetBytes(stringToSignature)));
//zwracanie naglowka wedlug wymaganego formatu
return string.Format($"SharedKeyLite {account}:{signedSignature}");
}
public HttpWebRequest SendRequest(string method, string newObject, StorageEntity searchedObject)
{
HttpWebRequest request;
//jesli wyszukiwany jest jakis rekord (dla GET lub PUT) to w linku przekazujemy jego wlasciwosci
//PartitionKey oraz RowKey
if (searchedObject == null)
{
request = HttpWebRequest.
Create($"https://{account}.table.core.windows.net/{table}") as HttpWebRequest;
}
else
{
request = HttpWebRequest.
Create($"https://{account}.table.core.windows.net/{table}(PartitionKey='{searchedObject.PartitionKey}',RowKey='{searchedObject.RowKey}')") as HttpWebRequest;
}
request.Method = method;
//Jesli wykonujemy delete to dodajemy wymagany header If-Match, ktory nawet jak nie znajdzie zasobu to i tak wykona
//zadanie
if (method.Equals("DELETE"))
{
request.Headers.Add("If-Match", "*");
}
else if (!method.Equals("GET"))
{
WriteRequest(request, newObject);
}
//dziejsza data w formacie dla np. 28.07.2020 WT, 20 Jul 2020 20:45:30 GMT
request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture));
//wersja uslugi azure storage
request.Headers.Add("x-ms-version", "2015-12-11");
request.ContentType = "application/json";
request.Accept = "application/json";
request.Headers.Add("Authorization", CreateAuthorizationString(request));
return request;
}
public string GetResponseCommand(HttpWebRequest request)
{
try
{
//pobieranie odpowiedzi z serwera, jesli wszystko jest ok zwracany jest string "Changes saved",
//w przeciwnym wypadku wiadomosc dotyczaca bledu
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
return "Changes saved";
}
catch (Exception ex)
{
return ex.Message;
}
}
public IEnumerable<UpdatedEntity> GetResponseQueryForAll(HttpWebRequest request)
{
//pobieranie odpowiedzi z serwera
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (StreamReader responseReader = new StreamReader(response.GetResponseStream()))
{
//odpowiedź z serwera
string responseJson = responseReader.ReadToEnd();
JToken values = JObject.Parse(responseJson)["value"];
List<UpdatedEntity> entities = new List<UpdatedEntity>();
foreach (JToken value in values)
{
//konwersja na slownik
Dictionary<string, string> dictionary = value.ToObject<Dictionary<string, string>>();
//konwersja na obiekt i dodawanie do listy
entities.Add(objectConverter.JsonToEntity(dictionary));
}
return entities;
}
}
public UpdatedEntity GetResponseQuery(HttpWebRequest request)
{
//pobieranie odpowiedzi z serwera
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (StreamReader responseReader = new StreamReader(response.GetResponseStream()))
{
//odpowiedź z serwera
string responseJson = responseReader.ReadToEnd();
//konwertowanie otrzymanego jsona na slownik, a nastepnie zwracanie go jako obiekt UpdatedEntity
JToken value = JObject.Parse(responseJson);
Dictionary<string, string> dictionary = value.ToObject<Dictionary<string, string>>();
dictionary.Remove("odata.metadata");
return objectConverter.JsonToEntity(dictionary);
}
}
}
}