using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using RestSharp;
namespace SiriIntents.Server
{
public class HttpUtil
{
#region **********全局常量**********
///
/// 固定域名,正式环境
/// 公共域名就近解析
///
public const string GlobalRequestHttpsHost = "https://nearest.hdlcontrol.com";
//public const string GlobalRequestHttpsHost = "http://59.41.255.150:7777";
//public const string GlobalRequestHttpsHost = "https://test-gz.hdlcontrol.com";//mmmm
///
/// RegionMark
///
public const string RegionMark = "HDL";
///
/// 请求超时时间
///
public const int TIME_OUT = 15;
///
/// 特殊接口请求超时时间
///
public const int TIME_OUT_LONG = 20;
///
/// Bearer 暂时设为空,从登陆成功的返回的headerPrefix参数动态获取
///
//public const string TOKEN_BEARER = "Bearer ";
#endregion
#region **********网络请求封装**********
///
/// POST请求方法 body参数
/// 针对住宅相关接口封装
/// 调用住宅当前所在区域域名
/// 如果是分享住宅,使用主人的token进行相关操作
///
///
///
///
///
public static ResponsePackNew RequestHttpsPostFroHome(string apiPath, string bodyParameterJson, int mTimeout = TIME_OUT)
{
string urlHead = HttpServerRequest.Ins.DataManager.RegionUrl;
//var replaceToken = "";
//if (DB_ResidenceData.residenceData.residecenInfo.IsOthreShare)
//{
// replaceToken = DB_ResidenceData.residenceData.MasterToken;
//}
return RequestHttps(Method.POST, apiPath, bodyParameterJson, null, null, urlHead, "", mTimeout);
}
///
/// POST请求方法 body参数
///
///
///
///
///
///
///
///
public static ResponsePackNew RequestHttpsPost(string apiPath, string bodyParameterJson, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT)
{
return RequestHttps(Method.POST, apiPath, bodyParameterJson, null, null, urlHead, replaceToken, mTimeout);
}
///
/// POST请求方法 queryDictionary
///
///
///
///
///
///
///
///
public static ResponsePackNew RequestHttpsPost(string apiPath, Dictionary queryDictionary, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT)
{
return RequestHttps(Method.POST, apiPath, null, queryDictionary, null, urlHead, replaceToken, mTimeout);
}
///
/// 通用 请求服务器方法
///
///
///
///
///
///
///
///
///
///
static ResponsePackNew RequestHttpsBase(Method method, string apiPath, string bodyParameterJson = null, Dictionary queryDictionary = null, Dictionary urlSegmentDictionary = null, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT)
{
//Dome模式登录
#region HttpWebRequest
try
{
string requestFullUrl = urlHead + apiPath;
RestClient client = new RestClient(requestFullUrl);
RestRequest request = new RestRequest(method);
request.Timeout = mTimeout * 1000;
request.AddHeader("content-type", "application/json");
request.AddHeader("Authorization", HttpServerRequest.Ins.DataManager.AccessToken);
if (bodyParameterJson != null)
{
request.AddParameter("application/json", bodyParameterJson, ParameterType.RequestBody);
}
if (queryDictionary != null)
{
foreach (var data in queryDictionary)
{
request.AddQueryParameter(data.Key, data.Value.ToString());
}
}
if (urlSegmentDictionary != null)
{
foreach (var data in urlSegmentDictionary)
{
request.AddUrlSegment(data.Key, data.Value.ToString());
}
}
IRestResponse response = client.Execute(request);
if (response.StatusCode == HttpStatusCode.OK)
{
try
{
ResponsePackNew revertObj = new ResponsePackNew() { };
revertObj = Newtonsoft.Json.JsonConvert.DeserializeObject(response.Content);
//*****一些判空处理*****************
if (revertObj.Code == null)
{
revertObj.Code = StateCode.DATA_EXCEPTION;
}
if (revertObj.Data == null)
{
revertObj.Data = "";
}
//*****一些判空处理*****************
return revertObj;
}
catch (Exception ex)
{
return new ResponsePackNew() { Code = StateCode.DATA_EXCEPTION };
}
}
else
{
return new ResponsePackNew() { Code = StateCode.NETWORK_ERROR };
}
}
catch (Exception ex)
{
return new ResponsePackNew() { Code = StateCode.NETWORK_ERROR };
}
#endregion
}
///
/// 通用 请求服务器方法
/// 增加token过期处理
///
///
///
///
///
///
///
///
///
///
public static ResponsePackNew RequestHttps(Method method, string apiPath, string bodyParameterJson = null, Dictionary queryDictionary = null, Dictionary urlSegmentDictionary = null, string urlHead = "", string replaceToken = "", int mTimeout = TIME_OUT)
{
var responsePackNew = RequestHttpsBase(method, apiPath, bodyParameterJson, queryDictionary, urlSegmentDictionary, urlHead, replaceToken, mTimeout);
//*****************Token过期处理*****************
if (responsePackNew.Code == StateCode.TOKEN_EXPIRED)
{
//刷新Token
if (RefreshToken()) {
return RequestHttpsBase(method, apiPath, bodyParameterJson, queryDictionary, urlSegmentDictionary, urlHead, replaceToken, mTimeout);
}
else
{
return responsePackNew;
}
}
//*****************Token过期处理*****************
return responsePackNew;
}
///
/// 刷新 Token
///
///
static bool RefreshToken()
{
try
{
var requestJson = GetSignRequestJson(new RefreshTokenObj()
{
refreshToken = HttpServerRequest.Ins.DataManager.RefreshToken,
});
var revertObj = RequestHttpsBase(Method.POST, NewAPI.API_POST_Login, requestJson);
if (revertObj.Code == StateCode.SUCCESS)
{
var revertData = Newtonsoft.Json.JsonConvert.DeserializeObject(revertObj.Data.ToString());
HttpServerRequest.Ins.DataManager.AccessToken = revertData.headerPrefix + revertData.accessToken;
HttpServerRequest.Ins.DataManager.RefreshToken = revertData.refreshToken;
return true;
}
return false;
}
catch
{
return false;
}
}
#endregion
#region **********签名校验**********
///
///
///
const string APP_KEY = "QWERREWQ";//"COSDFPIN";
///
///
///
const string SECRET_KEY = "CPBUCTRLCPBUABCD";//"COSDFPJDCOSDFPJT";
///
/// 获取当前时间戳值
///
///
static string GetTimestamp()
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区
return ((long)(DateTime.Now - startTime).TotalMilliseconds).ToString(); // 相差秒数
//return ((long)(DateTime.Now - startTime).TotalSeconds).ToString(); // 相差秒数
}
///
///
///
///
///
static string SignMD5Encrypt(string s)
{
byte[] sign = MD5.Create().ComputeHash(UTF8Encoding.UTF8.GetBytes(s));
string signstr = string.Empty;
foreach (byte item in sign)
{
signstr += item.ToString("X2");
}
return signstr.ToLower();
}
///
/// 判断当前值是否需要参与签名,保持跟云端一致
/// 空字符串不参与
/// 数组,集合,对象不参与
///
///
///
static bool IfValueNeedSign(string valueStr)
{
if (string.IsNullOrEmpty(valueStr) || valueStr.StartsWith("{") || valueStr.StartsWith("["))
{
return false;
}
return true;
}
///
/// 2020-11-02
/// 基础服务的接口都要校验sign
/// 计算sign签名
///
///
public static string GetSignRequestJson(object requestObj,Dictionary paramDictionary = null)
{
try
{
//1. 将model实体转为Dictionary
if (paramDictionary == null)
{
paramDictionary = Newtonsoft.Json.JsonConvert.DeserializeObject>(Newtonsoft.Json.JsonConvert.SerializeObject(requestObj));
}
//2. 计算sign
if (paramDictionary != null)
{
paramDictionary.Add("appKey", APP_KEY);
paramDictionary.Add("timestamp", GetTimestamp());
//2.1 字典升序
paramDictionary = paramDictionary.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value);
//2.2 拼接按URL键值对
string str = string.Empty;
foreach (KeyValuePair item in paramDictionary)
{
//Value为null不参加校验
if (item.Value != null)
{
//Value.ToString()为null或者""也不参加校验
//if (!string.IsNullOrEmpty(item.Value.ToString()) && (item.Value is string || item.Value.GetType().IsValueType))
//{
//检测当前参数是否需要参与校验
if (IfValueNeedSign(item.Value.ToString()))
{
//如果是bool类型,要转小写
if (item.Value is bool)
{
str += item.Key + "=" + item.Value.ToString().ToLower() + "&";
}
else
{
str += item.Key + "=" + item.Value.ToString() + "&";
}
}
}
}
//2.3 拼接SECRET_KEY
str = str.Substring(0, str.Length - 1) + SECRET_KEY;
//2.4 MD5转换+转小写
var signstr = SignMD5Encrypt(str);
paramDictionary.Add("sign", signstr);
var signResult = Newtonsoft.Json.JsonConvert.SerializeObject(paramDictionary);
return signResult;
}
else
{
return "";
}
}
catch
{
return "";
}
}
#endregion
}
///
/// 响应参数
///
[Serializable]
public class ResponsePackNew
{
///
/// 响应状态码
///
public string Code;
///
/// 响应内容
///
public object Data;
///
/// 响应错误信息
///
public string message = "";
///
/// 这个是请求错误时的扩展数据,以后所有的附带扩展数据都会放在这里面动态维护
///
public object extra;
/////
///// isSuccess
/////
//public bool isSuccess;
/////
///// timestamp
/////
//public string timestamp;
}
}