Create a Streaming Request
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let GetUnixEpochTimeStamp = | |
//test: "1318622958" | |
let secs = (System.DateTime.UtcNow.Subtract(new DateTime(1970,1,1))).TotalSeconds | |
Convert.ToInt64(secs).ToString(System.Globalization.CultureInfo.InvariantCulture) | |
let GetNonce = | |
//test: let nonce = "kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg" | |
Guid.NewGuid().ToString().Replace("-", String.Empty) //32 alphanumeric chars | |
let EncodeChar (c:char) = | |
let bytes = System.Text.Encoding.UTF8.GetBytes([|c|]) | |
bytes | |
|> Seq.map(fun b -> "%" + b.ToString("X2")) | |
|> System.String.Concat | |
let PercentEncode (s:string) = | |
let chars = s.ToCharArray() | |
chars | |
|> Seq.map(fun c-> | |
match c with | |
| c when c >= '0' && c <= '9' -> System.Convert.ToString(c) | |
| c when c >= 'a' && c <= 'z' -> System.Convert.ToString(c) | |
| c when c >= 'A' && c <= 'Z' -> System.Convert.ToString(c) | |
| '.' | '-' | '_' |'~' -> System.Convert.ToString(c) | |
| _ -> EncodeChar(c) | |
) | |
|> System.String.Concat | |
let Sign_HMAC_SHA1 (sig_ready:string) = | |
let signing_key = (PercentEncode consumer_secret) + "&" + (PercentEncode access_token_secret) | |
let keyBytes = System.Text.Encoding.ASCII.GetBytes(signing_key) | |
use hmac = new System.Security.Cryptography.HMACSHA1(keyBytes) | |
let byteArray = System.Text.Encoding.ASCII.GetBytes(sig_ready) | |
use mem_stream = new MemoryStream(byteArray) | |
let signed = hmac.ComputeHash(mem_stream) | |
Convert.ToBase64String(signed,Base64FormattingOptions.None) | |
let ComposeSignatureParamString (keyvalues:SortedDictionary<string,string>) = | |
keyvalues | |
|> Seq.sortBy(fun (KeyValue(k,v)) -> PercentEncode k ) //twitter needs keys to be percent encoded before sorting | |
|> Seq.map(fun kvp -> (PercentEncode kvp.Key) + "=" + (PercentEncode kvp.Value) + "&" ) | |
|> System.String.Concat | |
|> fun k-> k.TrimEnd('&') //remove the excess & at the end | |
let ComposeOAuthString (keyvalues:SortedDictionary<string,string>) (sig_base_string:string) = | |
keyvalues.Add("oauth_consumer_key",consumer_key) | |
keyvalues.Add("oauth_token",access_token) | |
keyvalues.Add("oauth_nonce", GetNonce) | |
keyvalues.Add("oauth_version","1.0") | |
keyvalues.Add("oauth_timestamp", GetUnixEpochTimeStamp) | |
keyvalues.Add("oauth_signature_method","HMAC-SHA1") | |
let param_string = ComposeSignatureParamString keyvalues | |
let pre_signed_sig = sig_base_string + "&" + (PercentEncode param_string) | |
let signed_sig = Sign_HMAC_SHA1 pre_signed_sig | |
keyvalues.Add("oauth_signature", signed_sig) | |
//Authorization header should only contain oauth_ prefixed keys | |
keyvalues | |
|> Seq.filter(fun x-> x.Key.StartsWith("oauth_")) | |
|> Seq.map(fun x-> PercentEncode x.Key + "=" + "\"" + PercentEncode x.Value + "\", ") | |
|> System.String.Concat | |
|> fun k->k.TrimEnd(' ',',') | |
let GetStreamingWebResource (endpoint:string) (optional_params:SortedDictionary<string,string>) = | |
let url = StreamBaseUrl + endpoint | |
let sig_base_string = WebRequestMethods.Http.Get + "&" + (PercentEncode url) | |
let dict = optional_params | |
let query_string = | |
dict | |
|> Seq.map( fun kv-> String.Format("{0}={1}", (System.Net.WebUtility.UrlEncode kv.Key), | |
(System.Net.WebUtility.UrlEncode kv.Value)) ) | |
|> Seq.fold(fun s1 s2-> s1 + s2 + "&") "?" | |
let url = endpoint + query_string.TrimEnd(' ','&') | |
let w = WebRequest.Create(StreamBaseUrl + url) :?> HttpWebRequest | |
w.UserAgent <- "ixmx" | |
let oauth = ComposeOAuthString dict sig_base_string | |
w.Headers.Add("Authorization", "OAuth " + oauth) | |
w.Method <- WebRequestMethods.Http.Get | |
w.ContentType <- "application/x-www-form-urlencoded" | |
w |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment