Blob Service REST API - Put Blob returning 403 Forbidden when x-ms-blob-content-type is set - api

I've successfully been able to create Blobs in my container, but when I try to set the x-ms-blob-content-type header, no Blob is created and I get a 403 error. Here is my code:
var authorizationHeader = CreateAuthorizationHeader(stringToSign);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(blobEndpoint + urlPath);
request.Method = requestMethod;
request.Headers["x-ms-blob-type"] = blobType;
request.Headers["x-ms-date"] = dateInRfc1123Format;
request.Headers["x-ms-version"] = storageServiceVersion;
request.Headers["Authorization"] = authorizationHeader;
request.ContentLength = blobLength;
try
{
using (Stream requestStream = await request.GetRequestStreamAsync())
{
requestStream.Write(blobContent, 0, blobLength);
}
using(HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
{
var eTag = response.Headers["ETag"];
}
}
But whenever I try to add either of these lines, I get a 403:
request.Headers["x-ms-blob-content-type"] = "image/jpeg";
//or
request.ContentType = "image/jpeg";
Have any of you encountered this? Appreciate any feedback, thanks!
UPDATE: adding the stringToSign code below.
var canonicalizedHeaders = String.Format(
"x-ms-blob-type:{0}\nx-ms-date:{1}\nx-ms-version:{2}",
blobType,
dateInRfc1123Format,
storageServiceVersion);
var canonicalizedResource = String.Format("/{0}/{1}", account, urlPath);
var stringToSign = String.Format(
"{0}\n\n\n{1}\n\n\n\n\n\n\n\n\n{2}\n{3}",
requestMethod,
blobLength,
canonicalizedHeaders,
canonicalizedResource);

Did you add x-ms-blob-content-type in both canonicalizedHeaders and in request headers? When adding it to canonicalizedHeaders, please make sure that this would be the first entry as the headers need to be sorted. I took your code and added the header and it worked perfectly fine. Here's my code:
private static async Task UploadBlob()
{
var blobType = "BlockBlob";
var dateInRfc1123Format = DateTime.UtcNow.ToString("R");
var storageServiceVersion = "2014-02-14";
var blobContentType = "image/png";
var canonicalizedHeaders = String.Format("x-ms-blob-content-type:{0}\nx-ms-blob-type:{1}\nx-ms-date:{2}\nx-ms-version:{3}", blobContentType, blobType, dateInRfc1123Format, storageServiceVersion);
var urlPath = "test-test/AlarmClock1.png";
var canonicalizedResource = String.Format("/{0}/{1}", accountName, urlPath);
var requestMethod = "PUT";
var fileContents = File.ReadAllBytes(#"D:\images\images\AlarmClock1.png");
var blobLength = fileContents.Length;
var stringToSign = String.Format("{0}\n\n\n{1}\n\n\n\n\n\n\n\n\n{2}\n{3}", requestMethod, blobLength, canonicalizedHeaders, canonicalizedResource);
var authorizationHeader = SignThis(stringToSign);
var blobEndpoint = "https://myaccountname.blob.core.windows.net/";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(blobEndpoint + urlPath);
request.Method = requestMethod;
request.Headers["x-ms-blob-content-type"] = blobContentType;
request.Headers["x-ms-blob-type"] = blobType;
request.Headers["x-ms-date"] = dateInRfc1123Format;
request.Headers["x-ms-version"] = storageServiceVersion;
request.Headers["Authorization"] = authorizationHeader;
request.ContentLength = blobLength;
try
{
using (Stream requestStream = await request.GetRequestStreamAsync())
{
requestStream.Write(fileContents, 0, blobLength);
}
using(HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
{
var eTag = response.Headers["ETag"];
}
}
catch (Exception excep)
{
}
}

Related

Error when uploading file using Microsoft Graph API

I am trying to upload a large file to One Drive using Microsoft Graph API.
Uploading to One Drive works normally, but the file is damaged.
Please help me to solve the problem.
public ActionResult UploadLargeFiles(string id, [FromForm]IFormFile files)
{
string fileName = files.FileName;
int fileSize = Convert.ToInt32(files.Length);
var uploadProvider = new JObject();
var res = new JArray();
var isExistence = _mailService.GetUploadFolder(id);
if (isExistence != HttpStatusCode.OK)
{
var createFolder = _mailService.CreateUploadFolder(id);
if (createFolder != HttpStatusCode.Created)
{
return BadRequest(ModelState);
}
}
if (files.Length > 0)
{
var uploadSessionUrl = _mailService.CreateUploadSession(id, fileName);
if (uploadSessionUrl != null)
{
if (fileSize < 4194304)
{
uploadProvider = _mailService.UploadByteFile(id, uploadSessionUrl, files);
res.Add(uploadProvider);
}
}
else
{
return BadRequest(ModelState);
}
}
return Ok();
}
createUploadSession
public string CreateUploadSession(string upn, string fileName)
{
var uploadSession = _mailGraphService.CreateUploadSession(upn, fileName).Result;
var sessionResult = new UploadSessionDTO(uploadSession);
return sessionResult.uploadUrl;
}
public async Task<UploadSessionDTO> CreateUploadSession(string upn, string fileName)
{
this.InitHttpClient();
var jObject = JObject.FromObject(new { item = new Dictionary<string, object> { { "#microsoft.graph.conflictBehavior", "rename" } }, fileSystemInfo = new Dictionary<string, object> { { "#odata.type", "microsoft.graph.fileSystemInfo" } }, name = fileName });
var toJson = JsonConvert.SerializeObject(jObject);
var content = new StringContent(toJson, Encoding.UTF8, "application/json");
var response = await _client.PostAsync("users/"+ upn + "/drive/root:/MailFiles/" + fileName +":/createUploadSession", content);
if (!response.IsSuccessStatusCode)
return null;
var strData = await response.Content.ReadAsStringAsync();
dynamic uploadSession = JsonConvert.DeserializeObject<UploadSessionDTO>(strData);
return uploadSession;
}
public JObject LargeFileUpload(string upn, string url, IFormFile files)
{
var responseCode = HttpStatusCode.OK;
var jObject = new JObject();
int idx = 0;
int fileSize = Convert.ToInt32(files.Length);
int fragSize = 4 * 1024 * 1024; //4MB => 4 * 1024 * 1024;
var byteRemaining = fileSize;
var numFragments = (byteRemaining / fragSize) + 1;
while (idx < numFragments)
{
var chunkSize = fragSize;
var start = idx * fragSize;
var end = idx * fragSize + chunkSize - 1;
var offset = idx * fragSize;
if (byteRemaining < chunkSize)
{
chunkSize = byteRemaining;
end = fileSize - 1;
}
var contentRange = " bytes " + start + "-" + end + "/" + fileSize;
byte[] file = new byte[chunkSize];
using (var client = new HttpClient())
{
var content = new ByteArrayContent(file);
content.Headers.Add("Content-Length", chunkSize.ToString());
content.Headers.Add("Content-Range", contentRange);
var response = client.PutAsync(url, content);
var strData = response.Result.Content.ReadAsStringAsync().Result;
responseCode = response.Result.StatusCode;
//업로드 성공
if (responseCode == HttpStatusCode.Created)
{
JObject data = JObject.Parse(strData);
string downloadUrl = data["#content.downloadUrl"].ToString();
string itemId = data["id"].ToString();
//파일 크기 -> kb로 변환
fileSize = fileSize / 1000;
jObject = JObject.FromObject(new { name = files.Name, id = itemId, url = downloadUrl, size = (double)fileSize });
}
//업로드 충돌
else if (responseCode == HttpStatusCode.Conflict)
{
var restart = RestartByteFile(upn, url, files.Name);
responseCode = restart;
}
}
byteRemaining = byteRemaining - chunkSize;
idx++;
}
if (responseCode == HttpStatusCode.Created) { return jObject; }
else return jObject = JObject.FromObject(new { result = "실패" });
}
When I checked OneDrive, the file was uploaded normally, and when I downloaded and opened the file, it came out as a damaged file.
I wonder why the file gets corrupted when uploaded, and how to fix it.
If the problem cannot be solved, please let us know that it cannot be solved.

Get trending topics of twitter api with C#

I get "401 Unauthorized" error while trying to get the current trends using the twitter api but the below code work fine if I try to get some other response like user_timeline,available,tweets. Below is my code please tell me where iam wrong.
var oauth_token = "****";
var oauth_token_secret = "****";
var oauth_consumer_key = "****";
var oauth_consumer_secret = "****";
// oauth implementation details
var oauth_version = "1.0";
var oauth_signature_method = "HMAC-SHA1";
// unique request details
var oauth_nonce = Convert.ToBase64String(
new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
var timeSpan = DateTime.UtcNow
- new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();
// message api details
var status = "Updating status via REST API if this works";
//var resource_url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
//var resource_url = "https://api.twitter.com/1.1/search/tweets.json";
// var resource_url = "https://api.twitter.com/1.1/trends/place.json";
var resource_url = "https://api.twitter.com/1.1/trends/available.json";
//var screen_name = "screenname";
var query = "india";
var id = "1";
// create oauth signature
//var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
// "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&screen_name={6}";
//var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
//"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&q={6}";
var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&id={6}";
var baseString = string.Format(baseFormat,
oauth_consumer_key,
oauth_nonce,
oauth_signature_method,
oauth_timestamp,
oauth_token,
oauth_version,
id);
baseString = string.Concat("GET&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString));
var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
"&", Uri.EscapeDataString(oauth_token_secret));
string oauth_signature;
using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
{
oauth_signature = Convert.ToBase64String(
hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
}
// create the request header
var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
"oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
"oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
"oauth_version=\"{6}\"";
var authHeader = string.Format(headerFormat,
Uri.EscapeDataString(oauth_nonce),
Uri.EscapeDataString(oauth_signature_method),
Uri.EscapeDataString(oauth_timestamp),
Uri.EscapeDataString(oauth_consumer_key),
Uri.EscapeDataString(oauth_token),
Uri.EscapeDataString(oauth_signature),
Uri.EscapeDataString(oauth_version)
);
// make the request
ServicePointManager.Expect100Continue = false;
//var postBody = "screen_name=" + Uri.EscapeDataString(screen_name);
//var postBody = "q=" + Uri.EscapeDataString(query);
var postBody = "id=" + Uri.EscapeDataString(id);
// resource_url += "?" + postBody;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url);
request.Headers.Add("Authorization", authHeader);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
WebResponse response = request.GetResponse();
string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();
Console.ReadLine();

using AE.Net.Mail how to send mail with image inline

I using AE.Net.Mail in .net project.
I sent html mail and file attachment by gmail api and it work perfect.
But i dont know way to embed an image in body mail with it?
Somebody help me ?
string To = txtTo.Text;
string Subject = txtEmailSubject.Text;
string Body = hdfEmailContentSend.Value;
string InputAttachmentArr = hdfInputAttachmentArr.Value;
var msg = new AE.Net.Mail.MailMessage();
msg.From = new MailAddress("haunguyen1791990#gmail.com", "=?UTF-8?B?" + EncodeTo64UTF8(User.FullName) + "?=");
msg.ReplyTo.Add(msg.From);
msg.To.Add(new MailAddress(To));
msg.Subject = "=?UTF-8?B?" + EncodeTo64UTF8(Subject) + "?=";
msg.Body = Body;
var result = SendMessage(InputAttachmentArr, msg, "");
private Google.Apis.Gmail.v1.Data.Message SendMessage(string InputAttachmentArr, AE.Net.Mail.MailMessage msg, string ThreadId) {
try {
bool isAttackFile = false;
string boundary = "boundary_" + DateTime.Now.ToString("yyyyMMddHHmmss");
var service = CRMGmailUtils.DefineServiceGet(Server.MapPath(".") + "\\client_secret.json");
//get info file attachment
List<string> lstAttachFile = InputAttachmentArr.Split(',').ToList();
lstAttachFile.RemoveAll(item => item.Length == 0);
foreach (var item in lstAttachFile) {
string filePath = Server.MapPath("~/" + "Upload/gmail/" + item);
var bytes = File.ReadAllBytes(filePath);
AE.Net.Mail.Attachment file = new AE.Net.Mail.Attachment(bytes, GetMimeType(item), item, true);
msg.Attachments.Add(file);
isAttackFile = true;
}
var msgStr = new StringWriter();
//if file attachment not exists, set type mail is html
if (!isAttackFile) {
msg.ContentType = "text/html";
}
msg.Save(msgStr);
string data = msgStr.ToString();
//else i customize body mail with new boundary
if (isAttackFile) {
string beginBody = "Content-Type: multipart/alternative; boundary=" + boundary;
//beginBody += "\n\n--" + boundary;
//beginBody += "\nContent-Type: text/plain; charset=UTF-8";
//beginBody += "\n\n*2*";
beginBody += "\n\n--" + boundary;
beginBody += "\nContent-Type: text/html; charset=UTF-8";
string endBody = "\n\n--" + boundary + "--";
msg.Body += endBody;
string parentBoundary = Regex.Match(data, #"----(.*?)--").Groups[1].Value;
Regex rgx = new Regex("----" + parentBoundary);
data = rgx.Replace(data, "----" + parentBoundary + "\n" + beginBody, 1);
}
string raw = Base64UrlEncode(data.ToString());
var result = new Google.Apis.Gmail.v1.Data.Message();
//case send with reply
if (!string.IsNullOrEmpty(ThreadId)) {
result = service.Users.Messages.Send(new Google.Apis.Gmail.v1.Data.Message { Raw = raw, ThreadId = ThreadId }, "me").Execute();
} else {
//case send new mail
result = service.Users.Messages.Send(new Google.Apis.Gmail.v1.Data.Message { Raw = raw }, "me").Execute();
}
DeleteAttackFile(lstAttachFile);
return result;
} catch (Exception objEx) {
throw objEx;
}
}

Quickblox add new user from c#

I want to create the user in Quickblox with the help of my application.I am using the Microsoft dotnet.Any one can share the code for that.
public string Timestamp()
{
long ticks = DateTime.UtcNow.Ticks - DateTime.Parse("01/01/1970 00:00:00").Ticks;
ticks /= 10000000;
return ticks.ToString();
}
public string Hash(string input, string key)
{
var encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(key);
HMACSHA1 myhmacsha1 = new HMACSHA1(keyByte);
byte[] byteArray = Encoding.ASCII.GetBytes(input);
MemoryStream stream = new MemoryStream(byteArray);
byte[] hashValue = myhmacsha1.ComputeHash(stream);
return string.Join("", Array.ConvertAll(hashValue, b => b.ToString("x2")));
}
public string GetToken()
{
if (HttpContext.Current == null || String.IsNullOrEmpty(Convert.ToString(HttpContext.Current.Cache["QuickBloxToken"])))
{
string url = "https://api.quickblox.com"; //ConfigurationManager.AppSettings["ChatUrl"].ToString();
HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(url + "/session.xml");
httpWReq.UserAgent = ".NET Framework Test Client";
string application_id = System.Configuration.ConfigurationManager.AppSettings["QuickApplication_id"].ToString();
string auth_key = System.Configuration.ConfigurationManager.AppSettings["QuickAuth_key"].ToString();
string timestamp = Timestamp();
string auth_secret = System.Configuration.ConfigurationManager.AppSettings["QuickAuth_secret"].ToString();
ASCIIEncoding encoding = new ASCIIEncoding();
string postData = "application_id=" + application_id;
postData += "&auth_key=" + auth_key;
Random rand = new Random();
postData += "&nonce=" + rand.Next(1000, 9999);
postData += "&timestamp=" + timestamp;
string signature = Hash(postData, auth_secret);
postData += "&signature=" + signature;
byte[] data = encoding.GetBytes(postData);
httpWReq.Method = "POST";
httpWReq.ContentLength = data.Length;
httpWReq.Headers["QuickBlox-REST-API-Version"] = "0.1.0";
using (Stream stream = httpWReq.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(responseString);
var nodes = xmlDoc.SelectNodes("session");
string token = nodes[0].SelectSingleNode("token").InnerText;
if (HttpContext.Current != null)
HttpContext.Current.Cache.Add("QuickBloxToken", token, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 70, 0), System.Web.Caching.CacheItemPriority.Default, null);
return token;
}
else
return Convert.ToString(HttpContext.Current.Cache["QuickBloxToken"]);
}
try
{
userName = userName.ToLower();
fullName = ConvertintoTitleCase(fullName);
string ExistingUserID = string.Empty;
string token = GetToken();
string login, password;
login = userName;
password = "abcd12345#";
HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create("http://api.quickblox.com/users.xml");
string postData = "user[login]=" + login;
postData += "&user[password]=" + password;
postData += "&user[full_name]=" + fullName;
postData += "&user[email]=vikash#icreon.com";
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(postData);
httpWReq.UserAgent = ".NET Framework Test Client";
httpWReq.Method = "POST";
httpWReq.ContentLength = data.Length;
//httpWReq.ContentType = "application/x-www-form-urlencoded";
httpWReq.Headers["QuickBlox-REST-API-Version"] = "0.1.0";
httpWReq.Headers["QB-Token"] = token;
using (Stream stream = httpWReq.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
XDocument xmlDoc = XDocument.Parse(responseString);
var UserID = (from uid in xmlDoc.Elements(XName.Get("user"))
select uid.Element("id").Value).FirstOrDefault();
id = UserID.ToString();
return true;
}
catch (Exception ex)
{
id = string.Empty;
return false;
}

How can I pass a notification to multiple users with GCM?

I am trying :
private void GcmPushNotification(string deviceId)
{
string message="New post from Admin";
string GoogleAppID = "AIzaSyCYesJ5dCK8-O-tf8ZxADELQx5e05P-l5I";
var SENDER_ID = "854837747831";
var value = message;
WebRequest tRequest;
tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
tRequest.Method = "post";
// --- text
tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message="
+ value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
tRequest.Headers.Add(string.Format("Authorization: key={0}", GoogleAppID));
Console.WriteLine(postData);
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;
Stream dataStream = tRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse tResponse = tRequest.GetResponse();
dataStream = tResponse.GetResponseStream();
StreamReader tReader = new StreamReader(dataStream);
String sResponseFromServer = tReader.ReadToEnd();
tReader.Close();
dataStream.Close();
tResponse.Close();
}
If you want to send the same notification to multiple devices (up to 1000 registration IDs), you have to use the JSON request format instead of the URL encoded you are currently using.
For example (taken from here):
Content-Type:application/json
Authorization:key=AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA
{
"registration_ids" : ["APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx..."],
"data" : {
...
},
}