I would appreciate some help because I am really new to C#. I need to return the response headers back, I need the 3 numbers of status code only actually. The code of the page for the web service is `
<%# Page Language="C#" ContentType="application/json;charset=utf-8"%>
<%# Import Namespace="System.Net" %>
<%# Import Namespace="System.IO" %>
<%# Import Namespace="System.Xml" %>
<%# Import Namespace="System.Web" %>
<%# Import Namespace="Newtonsoft.Json" %>
<%# Import Namespace="Newtonsoft.Json.Linq" %>
<%# Import Namespace="System.Collections.Generic" %>
<%# Import Namespace="log4net" %>
<script runat="server">
static readonly ILog m_Log = LogManager.GetLogger("getWebRequest");
String appUrlEncoded = "application/x-www-form-urlencoded";
String appJson = "application/json";
String textXml = "text/xml";
String appXml = "application/xml";
String textPlain = "text/plain";
/************************ fetchURL *******************/
String fetchURL(string url, string protocol, string enctype, string parameters,
string readWriteTimeout, string conTimeout,
string userName, string password, JObject CustomHeaders, JToken JsonContent)
{
m_Log.Debug("fetchURL(" + url + ", " + protocol + ", " + enctype + ", " + parameters + ", " +
readWriteTimeout + ", " + conTimeout + ", " + userName + ", " + password + ") in");
String result = "";
String method ="GET";
String loginCredentials = userName + ":" + password;
// Accepting self-signed certificates
ServicePointManager.ServerCertificateValidationCallback += delegate(
object
sender,
System.Security.Cryptography.X509Certificates.X509Certificate
pCertificate,
System.Security.Cryptography.X509Certificates.X509Chain pChain,
System.Net.Security.SslPolicyErrors pSSLPolicyErrors)
{
return true;
};
try
{
if (protocol.EndsWith("get") || protocol.EndsWith("delete"))
{
url = url + (String.IsNullOrEmpty(parameters) ? "" : ("?" + parameters));
}
method = protocol.ToUpper();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = method;
request.ContentType = enctype;
request.Timeout = Int32.Parse(conTimeout);
request.ReadWriteTimeout = Int32.Parse(readWriteTimeout);
if (loginCredentials.Length>1)
{
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(loginCredentials)));
}
if (CustomHeaders != null)
{
//Custom HTTP headers
JEnumerable<JProperty> children = CustomHeaders.Children<JProperty>();
foreach (JProperty child in children)
{
string strKey = child.Name;
string strValue = "";
if (child == null || child.Value == null)
continue;
if (child.Value.Type.Equals(JsonTokenType.String))
{
strValue = (String)((JValue)child.Value).Value;
}
else
{
strValue = child.Value.ToString();
}
m_Log.Debug("request key: '" + strKey + "' -- value: '" + strValue + "'");
if (strKey.Trim().Equals("Accept"))
{
request.Accept = strValue;
}
else if (strKey.Trim().Equals("Connection"))
{
request.Connection = strValue;
}
else if (strKey.Trim().Equals("Content-Length"))
{
request.ContentLength = strValue.Length;
}
else if (strKey.Trim().Equals("Content-Type"))
{
request.ContentType = strValue;
}
else if (strKey.Trim().Equals("Expect"))
{
request.Expect = strValue;
}
else if (strKey.Trim().Equals("If-Modified-Since"))
{
request.IfModifiedSince = DateTime.Parse(strValue);
}
else if (strKey.Trim().Equals("Referer"))
{
request.Referer = strValue;
}
else if (strKey.Trim().Equals("Transfer-Encoding"))
{
request.TransferEncoding = strValue;
}
else if (strKey.Trim().Equals("User-Agent"))
{
request.UserAgent = strValue;
}
else
{
request.Headers.Add(strKey, strValue);
}
}
}
if (method.Equals("POST") || method.Equals("PUT"))
{
using (Stream writeStream = request.GetRequestStream())
{
UTF8Encoding encoding = new UTF8Encoding();
if (enctype.Equals(appJson))
{
if (JsonContent != null)
{
if (JsonContent is JObject)
{
JObject obj = (JObject)JsonContent;
m_Log.Debug(enctype + " encoding JObject: " + obj.ToString());
byte[] bytes = encoding.GetBytes(obj.ToString());
writeStream.Write(bytes, 0, bytes.Length);
}
else
{
JObject obj = new JObject();
obj.Add(new JProperty("content", JsonContent));
m_Log.Debug(enctype + " encoding: " + obj.ToString());
byte[] bytes = encoding.GetBytes(obj.ToString());
writeStream.Write(bytes, 0, bytes.Length);
}
}
}
else if (enctype.Equals(appUrlEncoded))
{
m_Log.Debug(enctype + " encoding parameters: " + parameters);
byte[] bytes = encoding.GetBytes(parameters);
writeStream.Write(bytes, 0, bytes.Length);
}
writeStream.Close();
}
}
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
StreamReader input = new StreamReader(webResponse.GetResponseStream());
result = "";
result += convertToJson(input, webResponse.ContentType);
}
catch (Exception e)
{
Dictionary<string, string> d1 = new Dictionary<string, string>();
string value = "error.com.genesyslab.composer.servererror message= " + e.Message.ToString();
d1.Add("errorMsg", value);
result = Newtonsoft.Json.JavaScriptConvert.SerializeObject(d1);
Response.AppendToLog("GeneralException:" + result);
}
m_Log.Debug("result: " + result);
m_Log.Debug("fetchURL() out");
return result;
}
string parseResultData(StreamReader reader, JsonTextReader jsonReader, string initialData)
{
m_Log.Debug("parseResultData(" + initialData + ") In");
string json = "";
try
{
jsonReader.Read();
// JSON string
json += initialData;
Response.AppendToLog("ContentTypeUnkJSON");
m_Log.Debug("parseResultData() Out");
return json;
}
catch (JsonReaderException)
{
m_Log.Debug("parseResultData() JsonReaderException");
// not a valid JSON - check for XML
try
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(initialData);
reader.Close();
json = Newtonsoft.Json.JavaScriptConvert.SerializeXmlNode(doc.DocumentElement);
Response.AppendToLog("ContentTypeUnkXML");
m_Log.Debug("parseResultData() Out");
return json;
}
catch (Exception e)
{
m_Log.Debug("parseResultData() Exception: " + e.Message);
Response.AppendToLog("ContentTypeUnkTEXT");
Response.AppendToLog("Exception Occured: " +e.Message.ToString());
Dictionary<string, string> d1 = new Dictionary<string, string>();
d1.Add("result", initialData);
string jsonText = Newtonsoft.Json.JavaScriptConvert.SerializeObject(d1);
return jsonText;
}
}
}
/**************convertToJson****************************/
string convertToJson(StreamReader reader, string contentType)
{
m_Log.Debug("convertToJson(" + contentType + ") In");
string json = "";
string data = reader.ReadToEnd();
// Parse into a JSON string
TextReader txReader = new StringReader(data);
Newtonsoft.Json.JsonTextReader jsonReader = new JsonTextReader(txReader);
if (contentType != null && contentType.Length != 0)
{
Response.AppendToLog("Content-Type:" + contentType.ToString());
if (contentType.ToLower().StartsWith(textXml) ||
contentType.ToLower().StartsWith(appXml))
{
try
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(data);
reader.Close();
json = Newtonsoft.Json.JavaScriptConvert.SerializeXmlNode(doc.DocumentElement);
m_Log.Debug("convertToJson() Out");
return json;
}
catch (XmlException e)
{
Response.AppendToLog("ContentTypeXMLFalse");
m_Log.Error("convertToJson() Error in decoding XML: " + e.Message);
throw new XmlException("Error in decoding XML: " + e.Message, e);
}
}
else if (contentType.ToLower().StartsWith(appJson))
{
jsonReader.Read();
// JSON string
json += data;
Response.AppendToLog("ContentTypeJSON");
m_Log.Debug("convertToJson() ContentTypeJSON Out");
return json;
}
else if (contentType.ToLower().StartsWith(textPlain))
{
Response.AppendToLog("ContentTypeTEXT");
Dictionary<string, string> d1 = new Dictionary<string, string>();
d1.Add("result", data);
d1.Add("headers", "");
string jsonText = Newtonsoft.Json.JavaScriptConvert.SerializeObject(d1);
Response.AppendToLog("ContentTypeTEXT:" + jsonText);
m_Log.Debug("convertToJson() ContentTypeTEXT Out");
return jsonText;
}
else
{
Response.AppendToLog("unknown Content-Type:" + contentType);
m_Log.Debug("convertToJson() unknown Content-Type Out");
return (parseResultData(reader, jsonReader, data));
}
}
else
{
Response.AppendToLog("Content-Type NULL");
m_Log.Debug("convertToJson() Content-Type NULL");
return( parseResultData(reader, jsonReader, data) );
}
}
</script>
<%
log4net.Config.XmlConfigurator.Configure();
m_Log.Debug("_________________________________________________");
m_Log.Debug("getWebRequest() In");
// extract parameters
String WebUrl ="";
String Protocol= "";
String EncType = "";
Boolean AuthenAccess = false;
String UserName ="";
String Password ="";
String readWriteTimeout = "20000"; // timeout in milliseconds
String conTimeout = "20000"; // timeout in milliseconds
Stream ins = HttpContext.Current.Request.InputStream;
StreamReader reader = new StreamReader(ins);
string jsonStr = reader.ReadToEnd();
JObject requestObj = JObject.Parse(jsonStr);
m_Log.Debug("requestObj: " + requestObj.ToString());
WebUrl = (string)requestObj["WebUrl"];
Protocol = (string)requestObj["Protocol"];
EncType = (string)requestObj["Enctype"];
AuthenAccess = (Boolean)requestObj["AuthenAccess"];
if (AuthenAccess)
{
UserName = (string)requestObj["UserName"];
Password = (string)requestObj["Password"];
}
// the value passed from the block property overrides the
// global value in the composer.properties
String timeout = (string)requestObj["Timeout"];
if (timeout != null && timeout.Trim().Length > 0)
{
try
{
int timeoutInt = Int32.Parse(timeout);
if (timeoutInt != -1)
{
conTimeout = Convert.ToString(timeoutInt * 1000);
readWriteTimeout = Convert.ToString(timeoutInt * 1000);
}
}
catch (FormatException)
{
// ignore an invalid value
}
}
String ParamStr = "";
int QueryPos = WebUrl.IndexOf('?');
if ((Protocol.EndsWith("get") || Protocol.EndsWith("delete")) && (QueryPos > 0))
{
String QueryString = WebUrl.Substring(QueryPos + 1, WebUrl.Length - (QueryPos + 1));
WebUrl = WebUrl.Substring(0, QueryPos);
String[] Pairs = QueryString.Split('&');
foreach (String Pair in Pairs)
{
string strKey = "";
string strValue = "";
int Pos = Pair.IndexOf('=');
if (Pos == -1)
{
strKey = Pair;
strValue = null;
}
else
{
try
{
strKey = Server.UrlDecode(Pair.Substring(0, Pos));
strValue = Server.UrlDecode(Pair.Substring(Pos + 1, Pair.Length - (Pos + 1)));
}
catch (Exception ex)
{
m_Log.Error("Exception parsing queryString:" + ex.Message);
}
}
if (!ParamStr.Equals(""))
{
ParamStr = ParamStr + "&";
}
ParamStr = ParamStr + Server.UrlEncode(strKey) + "=" + Server.UrlEncode(strValue);
}
}
JObject Parameters = (JObject)requestObj["Parameters"];
if (Parameters != null)
{
JEnumerable<JProperty> children = Parameters.Children<JProperty>();
foreach (JProperty child in children)
{
string strKey = child.Name;
string strValue = "";
if (child == null || child.Value == null)
continue;
if (child.Value.Type.Equals(JsonTokenType.String))
{
strValue = (String)((JValue)child.Value).Value;
}
else
{
strValue = child.Value.ToString();
}
// add to map
if (!ParamStr.Equals(""))
{
ParamStr = ParamStr + "&";
}
ParamStr = ParamStr + Server.UrlEncode(strKey) + "=" + Server.UrlEncode(strValue);
}
}
m_Log.Debug("ParamStr: " + ParamStr);
JObject CustomHeaders = (JObject)requestObj["CustomHeaders"];
JToken JsonContent = (JToken)requestObj["JsonContent"];
//relative path processing
string relativePath = "http://localhost:";
if (WebUrl.StartsWith("."))
{
int slashindex = WebUrl.IndexOf("/");
if (slashindex != -1)
{
int n = WebUrl.Length;
WebUrl = WebUrl.Substring(slashindex + 1, n - slashindex-1);
}
relativePath += HttpContext.Current.Request.ServerVariables["SERVER_PORT"];
relativePath = relativePath + HttpContext.Current.Request.RawUrl.ToString();
int boundary = relativePath.IndexOf("include");
if(boundary !=-1){
relativePath = relativePath.Substring(0, boundary);
}
WebUrl = relativePath + WebUrl;
m_Log.Debug("urlStr: " + WebUrl);
}
m_Log.Debug("WebUrl: " + WebUrl);
if (WebUrl.Length > 0)
{
Response.Write(fetchURL(WebUrl, Protocol, EncType, ParamStr, readWriteTimeout, conTimeout,
UserName, Password, CustomHeaders, JsonContent));
}
m_Log.Debug("getWebRequest() Out");
%>
`
As you can see I have inserted a "header" key-value pair in my returned json repsonse. How do I attach the value of the repsonse headers in the headers property? I have tried webResponse.Headers with no luck.
Thank you very much in advance!
Related
I've been wrestling with this for a while now and can't seem to find a solution. The closest I've come is PHP code for Oauth-1 by Joe Chung (https://github.com/joechung/oauth_yahoo), but I can't get my head wrapped around it.
I'm using Asp.Net, and this code is in the ContactController. I have no trouble Getting contacts from Yahoo. The problem is Adding a contact to a user's Yahoo address book. The program proceeds through the Yahoo login process, and there are no errors. But the contact is not saved. I hope someone can take a look at this and tell me what I'm missing.
Thanks.
private string AddYahooContact(string responseFromServer, string contactIdForYahoo)
{
// Some of this from http://www.yogihosting.com/implementing-yahoo-contact-reader-in-asp-net-and-csharp/
responseFromServer = responseFromServer.Substring(1, responseFromServer.Length - 2);
string accessToken = "", xoauthYahooGuid = "", refreshToken = "";
string[] splitByComma = responseFromServer.Split(',');
foreach (string value in splitByComma)
{
if (value.Contains("access_token"))
{
string[] accessTokenSplitByColon = value.Split(':');
accessToken = accessTokenSplitByColon[1].Replace('"'.ToString(), "");
}
else if (value.Contains("xoauth_yahoo_guid"))
{
string[] xoauthYahooGuidSplitByColon = value.Split(':');
xoauthYahooGuid = xoauthYahooGuidSplitByColon[1].Replace('"'.ToString(), "");
}
else if (value.Contains("refresh_token"))
{
string[] refreshTokenSplitByColon = value.Split(':');
refreshToken = refreshTokenSplitByColon[1].Replace('"'.ToString(), "");
}
}
// How to build contactUrl from https://developer.yahoo.com/social/rest_api_guide/contacts-resource.html#contacts-xml_request_put
// This is Yahoo's address to add a contact
string contactUrl = "https://social.yahooapis.com/v1/user/" + xoauthYahooGuid + "/contacts";
// Much of this from https://developer.yahoo.com/dotnet/howto-rest_cs.html
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(contactUrl);
webRequest.Method = "POST";
webRequest.Headers["Authorization"] = "Bearer " + accessToken;
webRequest.ContentType = "application/x-www-form-urlencoded"; // Tried "application/x-www-form-urlencoded & application/xml" & "text/xml".
// Create the data we want to send
string yahooContact = BuildYahooContact(contactIdForYahoo);
byte[] byteData = UTF8Encoding.UTF8.GetBytes(yahooContact);
webRequest.ContentLength = byteData.Length;
using (Stream postStream = webRequest.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
responseFromServer = "";
try
{
using (HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
responseFromServer = reader.ReadToEnd();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return yahooContact;
}
private string BuildYahooContact(string contactIdForYahoo)
{
Guid contactId = Guid.Parse(contactIdForYahoo);
Models.Contact contact = GetContactForId(contactId); // And find the contact
string firstName = "";
string lastName = "";
if (contact.FullName != null)
{
int index = contact.FullName.IndexOf(" ");
if (index > 0)
{
firstName = contact.FullName.Substring(0, index);
lastName = (contact.FullName.Substring(index + 1));
}
else
{
lastName = contact.FullName;
}
}
StringBuilder data = new StringBuilder();
data.Append("<contact>");
data.Append("<fields><type>name</type><value>");
data.Append("<givenName>" + firstName + "</givenName><middleName/>");
data.Append("<familyName>" + lastName + "</familyName>");
data.Append("<prefix/><suffix/><givenNameSound/><familyNameSound/>");
data.Append("</value></fields>");
data.Append("<fields><type>address</type>");
data.Append("<value><street>" + contact.Address + "</street>");
data.Append("<city>" + contact.City + "</city>");
data.Append("<stateOrProvince>" + contact.State + "</stateOrProvince>");
data.Append("<postalCode>" + contact.Zip + "</postalCode>");
data.Append("<country>United States</country>");
data.Append("<countryCode>US</countryCode>");
data.Append("</value></fields>");
data.Append("<fields><type>notes</type><value>" + contact.Note + "</value></fields>");
data.Append("<fields><type>link</type><value>" + contact.Website + "</value></fields>");
data.Append("<fields><type>email</type><value>" + contact.Email + "</value></fields>");
data.Append("<fields><type>phone</type><value>" + contact.BusinessPhone + "</value><flags>WORK</flags></fields>");
data.Append("<fields><type>phone</type><value>" + contact.BestPhone + "</value><flags>MOBILE</flags></fields>");
data.Append("<fields><type>phone</type><value>" + contact.SecondPhone + "</value><flags>PERSONAL</flags></fields>");
data.Append("<categories><category><name>GoGoContract</name></category></categories>");
data.Append("</contact>");
return data.ToString();
}
I am trying to download mp3 from http://www.audiodump.com/. The site has a lot of redirections. However I managed getting a part of it working.
This is my method for getting all informations such as DL links, titles, mp3 durations.
private void _InetGetHTMLSearch(string sArtist)
{
if(_AudioDumpQuery == string.Empty)
{
//return string.Empty;
}
string[] sStringArray;
string sResearchURL = "http://www.audiodump.biz/music.html?" + _AudioDumpQuery + sArtist.Replace(" ", "+");
string aRet;
HttpWebRequest webReq = (HttpWebRequest)HttpWebRequest.Create(sResearchURL);
webReq.Referer = "http://www.audiodump.com/";
try
{
webReq.CookieContainer = new CookieContainer();
webReq.Method = "GET";
using (WebResponse response = webReq.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream);
aRet = reader.ReadToEnd();
//Console.WriteLine(aRet);
string[] aTable = _StringBetween(aRet, "<BR><table", "table><BR>", RegexOptions.Singleline);
if (aTable != null)
{
string[] aInfos = _StringBetween(aTable[0], ". <a href=\"", "<a href=\"");
if (aInfos != null)
{
for(int i = 0; i < aInfos.Length; i++)
{
aInfos[i] = aInfos[i].Replace("\">", "*");
aInfos[i] = aInfos[i].Replace("</a> (", "*");
aInfos[i] = aInfos[i].Remove(aInfos[i].Length - 2);
sStringArray = aInfos[i].Split('*');
aLinks.Add(sStringArray[0]);
aTitles.Add(sStringArray[1]);
sStringArray[2] = sStringArray[2].Replace("`", "'");
sStringArray[2] = sStringArray[2].Replace("dont", "don't");
sStringArray[2] = sStringArray[2].Replace("lets", "let's");
sStringArray[2] = sStringArray[2].Replace("cant", "can't");
sStringArray[2] = sStringArray[2].Replace("shes", "she's");
sStringArray[2] = sStringArray[2].Replace("aint", "ain't");
sStringArray[2] = sStringArray[2].Replace("didnt", "didn't");
sStringArray[2] = sStringArray[2].Replace("im", "i'm");
sStringArray[2] = sStringArray[2].Replace("youre", "you're");
sStringArray[2] = sStringArray[2].Replace("ive", "i've");
sStringArray[2] = sStringArray[2].Replace("youll", "you'll");
sStringArray[2] = sStringArray[2].Replace("'", "'");
sStringArray[2] = sStringArray[2].Replace("'", "simplequotes");
sStringArray[2] = sStringArray[2].Replace("vk.com", "");
sStringArray[2] = _StringReplaceCyrillicChars(sStringArray[2]);
sStringArray[2] = Regex.Replace(sStringArray[2], #"<[^>]+>| ", "").Trim();
sStringArray[2] = Regex.Replace(sStringArray[2], #"\s{2,}", " ");
sStringArray[2] = sStringArray[2].TrimStart('\'');
sStringArray[2] = sStringArray[2].TrimStart('-');
sStringArray[2] = sStringArray[2].TrimEnd('-');
sStringArray[2] = sStringArray[2].Replace("- -", "-");
sStringArray[2] = sStringArray[2].Replace("http", "");
sStringArray[2] = sStringArray[2].Replace("www", "");
sStringArray[2] = sStringArray[2].Replace("mp3", "");
sStringArray[2] = sStringArray[2].Replace("simplequotes", "'");
aDurations.Add(sStringArray[2]);
}
}
else
{
//Console.WriteLine("Debug");
}
}
else
{
//Console.WriteLine("Debug 2");
}
//return aRet;
}
}
}
catch (Exception ex)
{
//return null;
////Console.WriteLine("Debug message: " + ex.Message);
}
}
I simply had to add referrer to prevent the search from redirection webReq.Referer = "http://www.audiodump.com/";
However when I want to download the mp3 I can't get it working. The urls are correct and checked with the ones I get when I download them manually rather than programmatically.
This is my mp3 download part:
private void _DoDownload(string dArtist, ref string dPath)
{
if (!Contain && skip <= 3 && !Downloading)
{
Random rnd = new Random();
int Link = rnd.Next(5);
_InetGetHTMLSearch(dArtist);
Console.WriteLine("--------------------------------> " + aLinks[0]);
string path = mp3Path + "\\" + dArtist + ".mp3";
if (DownloadOne(aLinks[Link], path, false))
{
hTimmer.Start();
Downloading = true;
}
}
else if (Downloading)
{
int actualBytes = strm.Read(barr, 0, arrSize);
fs.Write(barr, 0, actualBytes);
bytesCounter += actualBytes;
double percent = 0d;
if (fileLength > 0)
percent =
100.0d * bytesCounter /
(preloadedLength + fileLength);
label1.Text = Math.Round(percent).ToString() + "%";
if (Math.Round(percent) >= 100)
{
string path = mp3Path + "\\" + dArtist + ".mp3";
label1.Text = "";
dPath = path;
aLinks.Clear();
hTimmer.Stop();
hTimmer.Reset();
fs.Flush();
fs.Close();
lastArtistName = "N/A";
Downloading = false;
}
if (Math.Round(percent) <= 1)
{
if (hTimmer.ElapsedMilliseconds >= 3000)
{
string path = mp3Path + "\\" + dArtist + ".mp3";
hTimmer.Stop();
hTimmer.Reset();
fs.Flush();
fs.Close();
File.Delete(path);
Contain = false;
skip += 1;
Downloading = false;
}
}
}
}
private static string ConvertUrlToFileName(string url)
{
string[] terms = url.Split(
new string[] { ":", "//" },
StringSplitOptions.RemoveEmptyEntries);
string fname = terms[terms.Length - 1];
fname = fname.Replace('/', '.');
return fname;
} //ConvertUrlToFileName
private static long GetExistingFileLength(string filename)
{
if (!File.Exists(filename)) return 0;
FileInfo info = new FileInfo(filename);
return info.Length;
} //GetExistingFileLength
private static bool DownloadOne(string url, string existingFilename, bool quiet)
{
ServicePointManager.DefaultConnectionLimit = 20;
HttpWebRequest webRequest;
HttpWebResponse webResponse;
IWebProxy proxy = null; //SA???
//fmt = CreateFormat(
//"{0}: {1:#} of {2:#} ({3:g3}%)", "#");
try
{
fname = existingFilename;
if (fname == null)
fname = ConvertUrlToFileName(url);
if (File.Exists(existingFilename))
{
File.Delete(existingFilename);
}
webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.UserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A";
webRequest.Referer = "http://www.audiodump.com/";
preloadedLength = GetExistingFileLength(fname);
if (preloadedLength > 0)
webRequest.AddRange((int)preloadedLength);
webRequest.Proxy = proxy; //SA??? or DefineProxy
webResponse = (HttpWebResponse)webRequest.GetResponse();
fs = new FileStream(fname, FileMode.Append, FileAccess.Write);
fileLength = webResponse.ContentLength;
strm = webResponse.GetResponseStream();
if (strm != null)
{
bytesCounter = preloadedLength;
return true;
}
else
{
return false;
}
}
catch (Exception e)
{
//Console.WriteLine(
//"{0}: {1} '{2}'",
// url, e.GetType().FullName,
//e.Message);
return false;
}
//exception
} //DownloadOne
The method _DoDownload() is executed from a timer which runs every 250 milliseconds. This way works perfectly on other sites. However audiodump is giving me hard time with these redirections.
I am not a genius with httprequest. I managed solving the search issue however the download part is freaking me out. Any advice on how to manage the download issue?
You just need to set referrer to the page from where you got that download link. For example you grabbed links to files from page "http://www.audiodump.biz/music.html?q=whatever", then when downloading file set that as Referrer, not just "http://www.audiodump.biz".
I've made a console app (don't judge for it being badly written, I can't even do classes properly and I know that RegEx doesn't work with XML/HTML, but let's not mind that I'm not even a programmer)
int retryCount = 0;
int retryCount02 = 0;
int innerpercentage = 1;
HttpWebResponse response = null;
HttpWebResponse response02 = null;
//WebRequest groupingurl = WebRequest.Create("supersecretlink");
WebRequest groupingurl = WebRequest.Create("anothersupersecretlink"); // temp
var groupingurlread = (HttpWebResponse)groupingurl.GetResponse();
using (var groupingreader = new StreamReader(groupingurlread.GetResponseStream(), Encoding.ASCII))
{
string responseGrouping = groupingreader.ReadToEnd();
Console.WriteLine("--------");
var pattern = #"""ClassID"" Value=""(.*?)""";
var matches = Regex.Matches(responseGrouping, pattern)
.OfType<Match>()
.Select(m => m.Groups[1].Value)
.ToArray();
int percentage = 1;
int percentagedone = matches.Length;
foreach (string r in matches)
{
while (true)
{
try
{
var url = "themostseriouslinkever";
string req = File.ReadAllText(#"somanylinksrighthere", Encoding.Default);
var go = url + req;
go = String.Format(go, r);
WebRequest request = WebRequest.Create(go);
response = (HttpWebResponse)request.GetResponse();
break;
}
catch (WebException)
{
Console.WriteLine("Retry No. {0}", retryCount+1);
if (++retryCount < 3) continue;
throw;
}
}
retryCount = 0;
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
{
string responseText = reader.ReadToEnd();
pattern = #"<PartNumber>(.*?)</PartNumber>";
matches = Regex.Matches(responseText, pattern)
.OfType<Match>()
.Select(m => m.Groups[1].Value)
.ToArray();
int innerpercentagedone = matches.Length;
foreach (string bbb in matches)
{
// -----
//Console.WriteLine(bbb);
while (true)
{
try
{
var url02 = "anothersecret";
string req02 = File.ReadAllText(#"seeecreet", Encoding.Default);
var go02 = url02 + req02;
go02 = string.Format(go02, bbb);
WebRequest request02 = WebRequest.Create(go02);
response02 = (HttpWebResponse)request02.GetResponse();
break;
}
catch (WebException)
{
Console.WriteLine("Retry No. {0}", retryCount02+1);
if (++retryCount02 < 3) continue;
throw;
}
}
retryCount02 = 0;
using (var reader02 = new StreamReader(response02.GetResponseStream(), Encoding.ASCII))
{
string responseText02 = reader02.ReadToEnd();
responseText02 = Regex.Replace(responseText02, (#"<\?xml.*\?>"), "");
//Console.WriteLine(responseText02);
//Console.WriteLine("</PartNumber>.*<");
responseText = Regex.Replace(responseText, ((#"<PartNumber>" + bbb + #"<\/PartNumber>")), responseText02);
//Console.WriteLine(responseText);
Console.Clear();
Console.WriteLine("(" + percentage + ") " + innerpercentage + "/" + innerpercentagedone + ". Total: " + percentage + " / " + percentagedone);
innerpercentage++;
}
}
//string mydocpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
using (StreamWriter outputFile = new StreamWriter(#"D:\Downloads\edasltxmlrequest\ConsoleApplication1\ConsoleApplication1\bin\Debug\test\" + r + ".xml"))
{
outputFile.WriteLine(responseText);
}
//Console.Clear();
//Console.WriteLine(percentage + " / " + percentagedone);
percentage++;
innerpercentage = 1;
//Console.WriteLine(responseText);
}
}
Console.WriteLine("--------");
Console.ReadLine();
}
}
}
So I wanted to ask if it's possible to make it run as a web app (http://www.amazingwebsite.com/ThisThingIWroteRightThere.php
I have searched the web, and is new to this still. Please have some patience with me.
What I want to do is this:
- I have a TreeView called "treeTO".
- I connect to my FTP Server and I want to populate everything here (the directories, sub directories, and the files, whatever it may be) in the treeview.
- This is my code I have so far:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + ActiveServer.Server + "/");
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.Credentials = new NetworkCredential(ActiveServer.UserName, ActiveServer.Password);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
-This returns me the following text: Logs, Data, and WwwRoot.
I struggle to add this to the treeview and then loop through the folders to add everything to the treeview.
So here´s my working Solution for you!
Of course you have to replace the Value of "root" with the rootURL of your FTP-Server and in the Method GetWebRequest() replace "username" and "password" with your Credentials!
You need this Class to Hold Details
public class FTPListDetail
{
public bool IsDirectory
{
get
{
return !string.IsNullOrWhiteSpace(Dir) && Dir.ToLower().Equals("d");
}
}
internal string Dir { get; set; }
public string Permission { get; set; }
public string Filecode { get; set; }
public string Owner { get; set; }
public string Group { get; set; }
public string Name { get; set; }
public string FullPath { get; set; }
}
and here is the Code-Behind for your WinForm-App
private void button1_Click(object sender, EventArgs e)
{
var root = "ftp://ftp.yourFTPServer.at";
treeView1.Nodes.Clear();
treeView1.Nodes.Add(CreateDirectoryNode(root, "root"));
}
private TreeNode CreateDirectoryNode(string path, string name)
{
var directoryNode = new TreeNode(name);
var directoryListing = GetDirectoryListing(path);
var directories = directoryListing.Where(d => d.IsDirectory);
var files = directoryListing.Where(d => !d.IsDirectory);
foreach (var dir in directories)
{
directoryNode.Nodes.Add(CreateDirectoryNode(dir.FullPath, dir.Name));
}
foreach (var file in files)
{
directoryNode.Nodes.Add(new TreeNode(file.Name));
}
return directoryNode;
}
public IEnumerable<FTPListDetail> GetDirectoryListing(string rootUri)
{
var CurrentRemoteDirectory = rootUri;
var result = new StringBuilder();
var request = GetWebRequest(WebRequestMethods.Ftp.ListDirectoryDetails, CurrentRemoteDirectory);
using (var response = request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
string line = reader.ReadLine();
while (line != null)
{
result.Append(line);
result.Append("\n");
line = reader.ReadLine();
}
if (string.IsNullOrEmpty(result.ToString()))
{
return new List<FTPListDetail>();
}
result.Remove(result.ToString().LastIndexOf("\n"), 1);
var results = result.ToString().Split('\n');
string regex =
#"^" + //# Start of line
#"(?<dir>[\-ld])" + //# File size
#"(?<permission>[\-rwx]{9})" + //# Whitespace \n
#"\s+" + //# Whitespace \n
#"(?<filecode>\d+)" +
#"\s+" + //# Whitespace \n
#"(?<owner>\w+)" +
#"\s+" + //# Whitespace \n
#"(?<group>\w+)" +
#"\s+" + //# Whitespace \n
#"(?<size>\d+)" +
#"\s+" + //# Whitespace \n
#"(?<month>\w{3})" + //# Month (3 letters) \n
#"\s+" + //# Whitespace \n
#"(?<day>\d{1,2})" + //# Day (1 or 2 digits) \n
#"\s+" + //# Whitespace \n
#"(?<timeyear>[\d:]{4,5})" + //# Time or year \n
#"\s+" + //# Whitespace \n
#"(?<filename>(.*))" + //# Filename \n
#"$"; //# End of line
var myresult = new List<FTPListDetail>();
foreach (var parsed in results)
{
var split = new Regex(regex)
.Match(parsed);
var dir = split.Groups["dir"].ToString();
var permission = split.Groups["permission"].ToString();
var filecode = split.Groups["filecode"].ToString();
var owner = split.Groups["owner"].ToString();
var group = split.Groups["group"].ToString();
var filename = split.Groups["filename"].ToString();
myresult.Add(new FTPListDetail()
{
Dir = dir,
Filecode = filecode,
Group = group,
FullPath = CurrentRemoteDirectory + "/" + filename,
Name = filename,
Owner = owner,
Permission = permission,
});
};
return myresult;
}
}
}
private FtpWebRequest GetWebRequest(string method, string uri)
{
Uri serverUri = new Uri(uri);
if (serverUri.Scheme != Uri.UriSchemeFtp)
{
return null;
}
var reqFTP = (FtpWebRequest)FtpWebRequest.Create(serverUri);
reqFTP.Method = method;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential("yourUser", "yourPassword");
reqFTP.Proxy = null;
reqFTP.KeepAlive = false;
reqFTP.UsePassive = false;
return reqFTP;
}
There is a reason why no FTP client on the planet preemptively populates a treeview on an FTP server or displays file icons in the treeview. Either one of these will take FOREVER.
What you'll need to do is rethink how you are doing this. When you first connect you are going to want to just populate the tree up until the initial dir and then the initial directory. You do NOT want to put files in your tree view because that will also eat up too much memory in many real world situations. Just add folders (and use the same ICON for >99% of those).
This is what it should look like when you first log in:
/
-home
-joe
-public_html
-docs
-uploads
Notice that, '/' and 'home' are not fully read at this point, we just insert them as placeholders for the user to click on. After that, you just want to add the directories in the clicked folder which aren't there each time the users clicks a folder.
This strategy is going to make life a million times easier. Even if you want to try those more complicated ways to handle this you'll want to start out with the basics.
I used this class
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
namespace Backup_service
{
internal class Ftp_Client
{
//поля
//поле для хранения имени фтп-сервера
private string _Host;
//поле для хранения логина
private string _UserName;
//поле для хранения пароля
private string _Password;
//объект для запроса данных
private FtpWebRequest ftpRequest;
//объект для получения данных
private FtpWebResponse ftpResponse;
//флаг использования SSL
private bool _UseSSL = false;
//фтп-сервер
public string Host
{
get
{
return _Host;
}
set
{
_Host = value;
}
}
//логин
public string UserName
{
get
{
return _UserName;
}
set
{
_UserName = value;
}
}
//пароль
public string Password
{
get
{
return _Password;
}
set
{
_Password = value;
}
}
//Для установки SSL-чтобы данные нельзя было перехватить
public bool UseSSL
{
get
{
return _UseSSL;
}
set
{
_UseSSL = value;
}
}
//Реализеум команду LIST для получения подробного списока файлов на FTP-сервере
public FileStruct[] ListDirectory(string path)
{
if (path == null || path == "")
{
path = "/";
}
//Создаем объект запроса
ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);
//логин и пароль
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
//команда фтп LIST
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
ftpRequest.EnableSsl = _UseSSL;
//Получаем входящий поток
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
//переменная для хранения всей полученной информации
string content = "";
StreamReader sr = new StreamReader(ftpResponse.GetResponseStream(), System.Text.Encoding.ASCII);
content = sr.ReadToEnd();
sr.Close();
ftpResponse.Close();
DirectoryListParser parser = new DirectoryListParser(content);
return parser.FullListing;
}
//метод протокола FTP RETR для загрузки файла с FTP-сервера
public void DownloadFile(string path, string currentfileName)
{
ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
//команда фтп RETR
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
ftpRequest.EnableSsl = _UseSSL;
//Файлы будут копироваться в кталог программы
if (!Directory.Exists(currentfileName))
{
Directory.CreateDirectory(currentfileName);
}
FileStream downloadedFile = new FileStream(currentfileName + #"\" + path.Substring(path.LastIndexOf('/') + 1), FileMode.Create, FileAccess.ReadWrite);
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
//Получаем входящий поток
Stream responseStream = ftpResponse.GetResponseStream();
//Буфер для считываемых данных
byte[] buffer = new byte[1024];
int size = 0;
while ((size = responseStream.Read(buffer, 0, 1024)) > 0)
{
downloadedFile.Write(buffer, 0, size);
}
ftpResponse.Close();
downloadedFile.Close();
responseStream.Close();
}
//метод протокола FTP STOR для загрузки файла на FTP-сервер
public void UploadFile(string path, string fileName)
{
//для имени файла
string shortName = fileName.Remove(0, fileName.LastIndexOf("\\") + 1);
FileStream uploadedFile = new FileStream(fileName, FileMode.Open, FileAccess.Read);
ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path + shortName);
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
ftpRequest.EnableSsl = _UseSSL;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
//Буфер для загружаемых данных
byte[] file_to_bytes = new byte[uploadedFile.Length];
//Считываем данные в буфер
uploadedFile.Read(file_to_bytes, 0, file_to_bytes.Length);
uploadedFile.Close();
//Поток для загрузки файла
Stream writer = ftpRequest.GetRequestStream();
writer.Write(file_to_bytes, 0, file_to_bytes.Length);
writer.Close();
}
//метод протокола FTP DELE для удаления файла с FTP-сервера
public void DeleteFile(string path)
{
ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
ftpRequest.EnableSsl = _UseSSL;
ftpRequest.Method = WebRequestMethods.Ftp.DeleteFile;
FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
}
//метод протокола FTP MKD для создания каталога на FTP-сервере
public void CreateDirectory(string path, string folderName)
{
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path + folderName);
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
ftpRequest.EnableSsl = _UseSSL;
ftpRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
}
//метод протокола FTP RMD для удаления каталога с FTP-сервера
public void RemoveDirectory(string path)
{
string filename = path;
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);
ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
ftpRequest.EnableSsl = _UseSSL;
ftpRequest.Method = WebRequestMethods.Ftp.RemoveDirectory;
FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
}
}
//Для парсинга полученного детального списка каталогов фтп-сервера
//Структура для хранения детальной информации о файле или каталоге
public struct FileStruct
{
public string Flags;
public string Owner;
public bool IsDirectory;
public string CreateTime;
public string Name;
}
public enum FileListStyle
{
UnixStyle,
WindowsStyle,
Unknown
}
//Класс для парсинга
public class DirectoryListParser
{
private List<FileStruct> _myListArray;
public FileStruct[] FullListing
{
get
{
return _myListArray.ToArray();
}
}
public FileStruct[] FileList
{
get
{
List<FileStruct> _fileList = new List<FileStruct>();
foreach (FileStruct thisstruct in _myListArray)
{
if (!thisstruct.IsDirectory)
{
_fileList.Add(thisstruct);
}
}
return _fileList.ToArray();
}
}
public FileStruct[] DirectoryList
{
get
{
List<FileStruct> _dirList = new List<FileStruct>();
foreach (FileStruct thisstruct in _myListArray)
{
if (thisstruct.IsDirectory)
{
_dirList.Add(thisstruct);
}
}
return _dirList.ToArray();
}
}
public DirectoryListParser(string responseString)
{
_myListArray = GetList(responseString);
}
private List<FileStruct> GetList(string datastring)
{
List<FileStruct> myListArray = new List<FileStruct>();
string[] dataRecords = datastring.Split('\n');
//Получаем стиль записей на сервере
FileListStyle _directoryListStyle = GuessFileListStyle(dataRecords);
foreach (string s in dataRecords)
{
if (_directoryListStyle != FileListStyle.Unknown && s != "")
{
FileStruct f = new FileStruct();
f.Name = "..";
switch (_directoryListStyle)
{
case FileListStyle.UnixStyle:
f = ParseFileStructFromUnixStyleRecord(s);
break;
case FileListStyle.WindowsStyle:
f = ParseFileStructFromWindowsStyleRecord(s);
break;
}
if (f.Name != "" && f.Name != "." && f.Name != "..")
{
myListArray.Add(f);
}
}
}
return myListArray;
}
//Парсинг, если фтп сервера работает на Windows
private FileStruct ParseFileStructFromWindowsStyleRecord(string Record)
{
//Предположим стиль записи 02-03-04 07:46PM <DIR> Append
FileStruct f = new FileStruct();
string processstr = Record.Trim();
//Получаем дату
string dateStr = processstr.Substring(0, 8);
processstr = (processstr.Substring(8, processstr.Length - 8)).Trim();
//Получаем время
string timeStr = processstr.Substring(0, 7);
processstr = (processstr.Substring(7, processstr.Length - 7)).Trim();
f.CreateTime = dateStr + " " + timeStr;
//Это папка или нет
if (processstr.Substring(0, 5) == "<DIR>")
{
f.IsDirectory = true;
processstr = (processstr.Substring(5, processstr.Length - 5)).Trim();
}
else
{
string[] strs = processstr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
processstr = strs[1];
f.IsDirectory = false;
}
//Остальное содержмое строки представляет имя каталога/файла
f.Name = processstr;
return f;
}
//Получаем на какой ОС работает фтп-сервер - от этого будет зависеть дальнейший парсинг
public FileListStyle GuessFileListStyle(string[] recordList)
{
foreach (string s in recordList)
{
//Если соблюдено условие, то используется стиль Unix
if (s.Length > 10
&& Regex.IsMatch(s.Substring(0, 10), "(-|d)((-|r)(-|w)(-|x)){3}"))
{
return FileListStyle.UnixStyle;
}
//Иначе стиль Windows
else if (s.Length > 8
&& Regex.IsMatch(s.Substring(0, 8), "[0-9]{2}-[0-9]{2}-[0-9]{2}"))
{
return FileListStyle.WindowsStyle;
}
}
return FileListStyle.Unknown;
}
//Если сервер работает на nix-ах
private FileStruct ParseFileStructFromUnixStyleRecord(string record)
{
//Предположим. тчо запись имеет формат dr-xr-xr-x 1 owner group 0 Nov 25 2002 bussys
FileStruct f = new FileStruct();
if (record[0] == '-' || record[0] == 'd')
{// правильная запись файла
string processstr = record.Trim();
f.Flags = processstr.Substring(0, 9);
f.IsDirectory = (f.Flags[0] == 'd');
processstr = (processstr.Substring(11)).Trim();
//отсекаем часть строки
_cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
f.Owner = _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
f.CreateTime = getCreateTimeString(record);
//Индекс начала имени файла
int fileNameIndex = record.IndexOf(f.CreateTime) + f.CreateTime.Length;
//Само имя файла
f.Name = record.Substring(fileNameIndex).Trim();
}
else
{
f.Name = "";
}
return f;
}
private string getCreateTimeString(string record)
{
//Получаем время
string month = "(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)";
string space = #"(\040)+";
string day = "([0-9]|[1-3][0-9])";
string year = "[1-2][0-9]{3}";
string time = "[0-9]{1,2}:[0-9]{2}";
Regex dateTimeRegex = new Regex(month + space + day + space + "(" + year + "|" + time + ")", RegexOptions.IgnoreCase);
Match match = dateTimeRegex.Match(record);
return match.Value;
}
private string _cutSubstringFromStringWithTrim(ref string s, char c, int startIndex)
{
int pos1 = s.IndexOf(c, startIndex);
string retString = s.Substring(0, pos1);
s = (s.Substring(pos1)).Trim();
return retString;
}
}
}
and this void
//Построение дерева файловой системы ftp сервера
private static void ListDirectory(TreeView treeView, string Host, string UserName, string password)
{
Ftp_Client ftp = new Ftp_Client();
ftp.Host = Host;
ftp.UserName = UserName;
ftp.Password = password;
treeView.Nodes.Clear();
var stack = new Stack<TreeNode>();
var rootDirectory = DOMAIN;
var node = new TreeNode(rootDirectory) { Tag = "/" };
stack.Push(node);
while (stack.Count > 0)
{
try
{
var currentNode = stack.Pop();
var directoryInfo = ftp.ListDirectory((string)currentNode.Tag);
foreach (var directory in directoryInfo)
{
if (directory.IsDirectory && directory.Name!="?") {
var childDirectoryNode = new TreeNode(directory.Name) { Tag = currentNode.Tag+directory.Name+'/'};
currentNode.Nodes.Add(childDirectoryNode);
stack.Push(childDirectoryNode);
}
}
foreach (var file in directoryInfo)
if (!file.IsDirectory && file.Name != "?")
currentNode.Nodes.Add(new TreeNode(file.Name) { Tag = currentNode.Tag + file.Name + "/f"}); ; //пометка f в конце пути означает, что это файл!
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
treeView.Nodes.Add(node);
}
calling by
ListDirectory(treeView1,DOMAIN,USER,PASS);
We've just changed to Twitter api 1.1, and now Tweeting doesn't work & returns an error "The remote server returned an error: (400) Bad Request." Researching on SO about this suggests that it's something to do with authentication, but we are sending the accessToken & secret which we've just got from the login page. It all worked fine with api 1.0. The code is -
public void Tweet(Action<string> response, string message)
{
StringBuilder sb = new StringBuilder();
sb.Append("POST&");
sb.Append(Uri.EscapeDataString(_postUrl));
sb.Append("&");
string oauthNonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
string timeStamp = MakeTimestamp();
var dict = new SortedDictionary<string, string>
{
{ "oauth_consumer_key", _oAuthConfig.ConsumerKey },
{ "oauth_nonce", oauthNonce },
{ "oauth_signature_method", "HMAC-SHA1" },
{ "oauth_timestamp", timeStamp },
{ "oauth_token", _accessToken },
{ "oauth_version", "1.0" },
};
foreach (var keyValuePair in dict)
{
sb.Append(Uri.EscapeDataString(string.Format("{0}={1}&", keyValuePair.Key, keyValuePair.Value)));
}
string encodedMessage = EscapeAdditionalChars(Uri.EscapeDataString(message));
sb.Append(Uri.EscapeDataString("status=" + encodedMessage));
string signatureBaseString = sb.ToString();
// create the signature
string signatureKey = Uri.EscapeDataString(_oAuthConfig.ConsumerSecret) + "&" + Uri.EscapeDataString(_accessTokenSecret);
var hmacsha1 = new HMACSHA1(new ASCIIEncoding().GetBytes(signatureKey));
string signatureString = Convert.ToBase64String(hmacsha1.ComputeHash(new ASCIIEncoding().GetBytes(signatureBaseString)));
// create the headers
string authorizationHeaderParams = String.Empty;
authorizationHeaderParams += "OAuth ";
authorizationHeaderParams += "oauth_consumer_key=\"" + _oAuthConfig.ConsumerKey + "\", ";
authorizationHeaderParams += "oauth_nonce=\"" + oauthNonce + "\", ";
authorizationHeaderParams += "oauth_signature=\"" + Uri.EscapeDataString(signatureString) + "\", ";
authorizationHeaderParams += "oauth_signature_method=\"" + "HMAC-SHA1" + "\", ";
authorizationHeaderParams += "oauth_timestamp=\"" + timeStamp + "\", ";
authorizationHeaderParams += "oauth_token=\"" + _accessToken + "\", ";
authorizationHeaderParams += "oauth_version=\"" + "1.0" + "\"";
string messageToPost = EscapeAdditionalChars(SpacesToPlusSigns(message));
// initialise the WebClient
WebClient client = new WebClient();
client.Headers [HttpRequestHeader.Authorization] = authorizationHeaderParams;
client.UploadDataCompleted += (s, eArgs) =>
{
if (eArgs.Error == null)
response(DefaultSuccessMessage());
else
response(eArgs.Error.Message);
};
try
{
Uri uri = new Uri(_postUrl);
try
{
client.UploadDataAsync(uri, "POST", Encoding.UTF8.GetBytes("status=" + messageToPost));
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
// Can happen if we had already favorited this status
Log.Info("TwitterService->Tweet error: " + e.Message);
response(DefaultErrorMessage());
}
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error 2: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
Log.Info("TwitterService->Tweet error 2: " + e.Message);
response(DefaultErrorMessage());
}
}
Basically, I'd like to be able to Tweet without using any 3rd party libraries such as Twitterizer (even TweetStation seems to be broken with api 1.1) - surely it can't be that difficult!
Any help much appreciated, as it feels a bit like a brick wall at the moment - I'm also fairly new to c#, which doesn't help...
Edited to show code which wasn't clear previously.
Finally found the solution, as usual with most of these things, it was pretty simple. Code below -
public void Tweet(Action<string> response, string message)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat ("status={0}", PercentEncode(message));
string content = sb.ToString();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_postUrl);
request.Headers.Add("Authorization", AuthorizeRequest(_accessToken, _accessTokenSecret, "POST", new Uri(_postUrl), content));
request.ContentType = "application/x-www-form-urlencoded";
request.ServicePoint.Expect100Continue = false;
request.Method = "POST";
try
{
try
{
using (Stream stream = request.GetRequestStream())
{
Byte[] streamContent = Encoding.UTF8.GetBytes("status=" + PercentEncode(message));
stream.Write(streamContent, 0, streamContent.Length);
}
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
string contents = "";
using (Stream stream = webResponse.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
contents = reader.ReadToEnd();
}
Console.WriteLine("Twitter response: " + contents);
response(DefaultSuccessMessage());
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
// Can happen if we had already favorited this status
Log.Info("TwitterService->Tweet error: " + e.Message);
response(DefaultErrorMessage());
}
}
catch (WebException e)
{
Log.Info("TwitterService->Tweet web error 2: " + e.Message);
response(DefaultErrorMessage());
}
catch (Exception e)
{
Log.Info("TwitterService->Tweet error 2: " + e.Message);
response(DefaultErrorMessage());
}
}
private string AuthorizeRequest(string oauthToken, string oauthTokenSecret, string method, Uri uri, string data)
{
string oauthNonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
var headers = new Dictionary<string, string>()
{
{ "oauth_consumer_key", _oAuthConfig.ConsumerKey },
{ "oauth_nonce", oauthNonce },
{ "oauth_signature_method", "HMAC-SHA1" },
{ "oauth_timestamp", MakeTimestamp() },
{ "oauth_token", oauthToken },
{ "oauth_verifier", PercentEncode(_authorizationVerifier) },
{ "oauth_version", "1.0A" }
};
var signatureHeaders = new Dictionary<string,string>(headers);
// Add the data and URL query string to the copy of the headers for computing the signature
if (data != null && data != "")
{
var parsed = HttpUtility.ParseQueryString(data);
foreach (string k in parsed.Keys)
{
signatureHeaders.Add(k, PercentEncode(parsed [k]));
}
}
var nvc = HttpUtility.ParseQueryString(uri.Query);
foreach (string key in nvc)
{
if (key != null)
signatureHeaders.Add(key, PercentEncode(nvc [key]));
}
string signature = MakeSignature (method, uri.GetLeftPart(UriPartial.Path), signatureHeaders);
string compositeSigningKey = MakeSigningKey(_oAuthConfig.ConsumerSecret, oauthTokenSecret);
string oauth_signature = MakeOAuthSignature(compositeSigningKey, signature);
headers.Add ("oauth_signature", PercentEncode(oauth_signature));
return HeadersToOAuth(headers);
}
private static string PercentEncode (string s)
{
var sb = new StringBuilder ();
foreach (byte c in Encoding.UTF8.GetBytes (s))
{
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.' || c == '~')
sb.Append ((char) c);
else
{
sb.AppendFormat ("%{0:X2}", c);
}
}
return sb.ToString ();
}
private static string MakeTimestamp ()
{
return ((long) (DateTime.UtcNow - _unixBaseTime).TotalSeconds).ToString ();
}
private static string MakeSignature (string method, string base_uri, Dictionary<string,string> headers)
{
var items = from k in headers.Keys orderby k
select k + "%3D" + PercentEncode (headers [k]);
return method + "&" + PercentEncode (base_uri) + "&" +
string.Join ("%26", items.ToArray ());
}
private static string MakeSigningKey (string consumerSecret, string oauthTokenSecret)
{
return PercentEncode (consumerSecret) + "&" + (oauthTokenSecret != null ? PercentEncode (oauthTokenSecret) : "");
}
private static string MakeOAuthSignature (string compositeSigningKey, string signatureBase)
{
var sha1 = new HMACSHA1 (Encoding.UTF8.GetBytes (compositeSigningKey));
return Convert.ToBase64String (sha1.ComputeHash (Encoding.UTF8.GetBytes (signatureBase)));
}
private static string HeadersToOAuth (Dictionary<string,string> headers)
{
return "OAuth " + String.Join (",", (from x in headers.Keys select String.Format ("{0}=\"{1}\"", x, headers [x])).ToArray ());
}
With Twitter api 1.0, I used a WebClient to post, that doesn't work with api 1.1, and it seems that the reason for this is that you can't set the ContentType or the ServicePoint.Expect100Continue properties - without these set as I've set them, the request is sent back as (401) unauthorized. Nothing to do with encoding problems in the end.
Thanks to others for the various helper methods.
I had exactly the same problem:
This is exactly what you need to do here:
Authenticate and request a user's timeline with Twitter API 1.1 oAuth
I have created a project for this at : https://github.com/andyhutch77/oAuthTwitterTimeline
It also includes an MVC, Web app and console demo.
I ran into this problem, or at least one striking similiar (from my noob perspective), recently for an app I am building. What seemed to solve it for me (after looking at the tool at dev.twitter.com) was simply to get rid of the quotes around the parameter names, so that (in your case):
I notice that you do in fact not have quotes around your parameter names. However, it confuses me that you send authentication details twice (hence my wrongheaded post.) It works for me without doing this, and I googled it briefly and found: https://dev.twitter.com/discussions/12322#comment-27120, which confirms this can be a problem generating an Authetication Error.
400 means you are not authenticated. I recommend getting user context.
https://dev.twitter.com/docs/auth/oauth#user-context