private string HttpPost(string URI, string Parameters, HttpHeader headers) { WebRequest req = WebRequest.Create(URI); if (headers != null) { req.Headers = headers.ToWebHeaderCollection(); } req.ContentType = "application/x-www-form-urlencoded"; req.Method = "POST"; byte[] bytes = Encoding.ASCII.GetBytes(Parameters); req.ContentLength = bytes.Length; Stream os = req.GetRequestStream(); os.Write(bytes, 0, bytes.Length); os.Close(); WebResponse resp = req.GetResponse(); if (resp == null) { return null; } StreamReader sr = new StreamReader(resp.GetResponseStream()); return sr.ReadToEnd().Trim(); }
private static ParseInfo Parse(byte[] buffer, int offset, int length) { // First Line HttpParser parser = new HttpParser(buffer, offset, length); string method; string uri; HttpVersion version; parser.Token(out method).Space().RequestUri(out uri).Space().Version(out version).CarriageReturnLineFeed(); ParseInfo parseInfo = new ParseInfo { Length = length, Version = version, Method = method == null ? null : new HttpRequestMethod(method), Uri = uri, }; if (!parser.Success) return parseInfo; int firstLineLength = parser.Offset - offset; // Header int? endHeaderOffset; HttpHeader header = new HttpHeader(GetHeaderFields(out endHeaderOffset, buffer, offset + firstLineLength, length - firstLineLength)); parseInfo.Header = header; if (endHeaderOffset == null) return parseInfo; int headerLength = endHeaderOffset.Value - offset - firstLineLength; // Body Datagram body = ParseBody(buffer, offset + firstLineLength + headerLength, length - firstLineLength - headerLength, IsBodyPossible(header), header); parseInfo.Body = body; parseInfo.Length = firstLineLength + headerLength + body.Length; return parseInfo; }
public string Request(string url, HttpRequestParameter parameter, HttpMethod method, HttpHeader headers) { string _params = string.Empty; if (parameter != null && parameter.Count > 0) { _params = parameter.ToString(); } if (method == HttpMethod.GET) { if (url.Contains("?")) { url = url + "&" + _params; } else { url = url + "?" + _params; } return HttpGet(url, headers); } else { return HttpPost(url, _params, headers); } }
public void Add(HttpHeader header) { lock (base.SyncRoot) { base.InnerList.Add(header); } }
public HttpResponse(HttpRequest request, HttpHeader headers, Byte[] binaryData, HttpStatusCode statusCode = HttpStatusCode.OK) { Request = request; Headers = headers; ResponseData = binaryData; StatusCode = statusCode; }
private void ClearPreviousHeaders(string method, HttpHeader header) { foreach (var previous in _headers[method].Where(x => x.Equals(header)).ToList()) { _headers[method].Remove(previous); } }
public override Handler Parse() { var header = new HttpHeader(); SetValue(HttpHeaderProperty, header); return GetNextHandler(); }
public HttpResponse(HttpRequest request, HttpHeader headers, String content, HttpStatusCode statusCode = HttpStatusCode.OK) { Request = request; Headers = headers; ResponseData = Headers.GetEncodingFromContentType().GetBytes(content); _content = content; StatusCode = statusCode; }
public void Can_Add_Additional_Values() { const string SOME_FIELD = "Authorization"; var header = new HttpHeader(SOME_FIELD, "OAuth realm=\"http://photos.example.net/photos\""); header.AddValue("oauth_consumer_key=\"dpf43f3p2l4k3l03\""); Assert.That(header.Value, Is.EqualTo("OAuth realm=\"http://photos.example.net/photos\", oauth_consumer_key=\"dpf43f3p2l4k3l03\"")); }
public void Register(string method, HttpHeader header) { if (!_headers.ContainsKey(method)) { _headers.Add(method, new List<HttpHeader>()); } ClearPreviousHeaders(method, header); _headers[method].Add(header); }
public void Remove(HttpHeader header) { if (this.Contains(header)) { lock (base.SyncRoot) { base.InnerList.Remove(header); } } }
/** * Constructor. * * @param socket The socket connection used for this handler. * @param header The HTTP header sent with this request. * @param gameId The game this connection is operating on. * * @throws IOException If something goes wrong with the socket. */ protected RequestHandler(ISocketWrapper socket, HttpHeader header, string gameId) { _header = header; _socket = socket; //writer_ = new StreamWriter(socket_.getOutputStream()); //writer_ = new StreamWriter(socket_.GetStream()); _writer = _socket.GetWriter(); GameId = gameId; }
public HttpRequestBuilder(string baseUrl) { BaseUrl = new HttpUri(baseUrl); ResourceUrl = string.Empty; Method = HttpMethod.GET; QueryParams = new List<KeyValuePair<string, string>>(); SuffixQueryParams = new List<KeyValuePair<string, string>>(); Segments = new Dictionary<string, string>(); Headers = new HttpHeader(); Cookies = new Dictionary<string, string>(); FormData = new List<HttpFormData>(); }
public void Should_Create_Simple_Header_With_Given_Single_Value() { const string SOME_FIELD = "Transfer-Encoding"; const string SOME_VALUE = "chunked"; var header = new HttpHeader(SOME_FIELD, SOME_VALUE); Assert.That(header.Field, Is.EqualTo(SOME_FIELD)); Assert.That(header.Value, Is.EqualTo(SOME_VALUE)); Assert.That(header.Values.Count(), Is.EqualTo(1)); Assert.That(header.ToString(), Is.EqualTo("Transfer-Encoding: chunked")); }
public HttpRequest(string url, HttpAccept httpAccept = null) { UriBuilder = new UriBuilder(url); Headers = new HttpHeader(); _segments = new Dictionary<string, string>(); AllowAutoRedirect = true; Cookies = new Dictionary<string, string>(); if (httpAccept != null) { Headers.Accept = httpAccept.Value; } }
protected virtual void AddRequestHeaders(HttpWebRequest webRequest, HttpHeader headers) { foreach (var header in headers) { switch (header.Key) { case "Accept": webRequest.Accept = header.Value.ToString(); break; case "Connection": webRequest.Connection = header.Value.ToString(); break; case "Content-Length": webRequest.ContentLength = Convert.ToInt64(header.Value); break; case "Content-Type": webRequest.ContentType = header.Value.ToString(); break; case "Date": webRequest.Date = (DateTime)header.Value; break; case "Expect": webRequest.Expect = header.Value.ToString(); break; case "Host": webRequest.Host = header.Value.ToString(); break; case "If-Modified-Since": webRequest.IfModifiedSince = (DateTime)header.Value; break; case "Range": throw new NotImplementedException(); break; case "Referer": webRequest.Referer = header.Value.ToString(); break; case "Transfer-Encoding": webRequest.TransferEncoding = header.Value.ToString(); break; case "User-Agent": throw new NotSupportedException("User-Agent other than Sonarr not allowed."); case "Proxy-Connection": throw new NotImplementedException(); break; default: webRequest.Headers.Add(header.Key, header.Value.ToString()); break; } } }
public void HeaderImport1() { string header = "Post\r\nname:henry\r\nemail:[email protected]\r\n\r\n"; byte[] data = Encoding.UTF8.GetBytes(header); int offset = 0; int count = data.Length; byte[] buffer = new byte[1024 * 4]; HttpHeader hh = new HttpHeader(buffer); if (hh.Import(data, ref offset, ref count)) { Assert.AreEqual(hh.RequestType, "Post"); Assert.AreEqual(hh["name"], "henry"); Assert.AreEqual(hh["email"], "*****@*****.**"); hh = new HttpHeader(buffer); } header = "Get\r\nname:henry\r\n"; data = Encoding.UTF8.GetBytes(header); offset = 0; count = data.Length; hh.Import(data, ref offset, ref count); header = "email:[email protected]"; data = Encoding.UTF8.GetBytes(header); offset = 0; count = data.Length; hh.Import(data, ref offset, ref count); header = "\r"; data = Encoding.UTF8.GetBytes(header); offset = 0; count = data.Length; hh.Import(data, ref offset, ref count); header = "\n\r\n"; data = Encoding.UTF8.GetBytes(header); offset = 0; count = data.Length; if (hh.Import(data, ref offset, ref count)) { Assert.AreEqual(hh.RequestType, "Get"); Assert.AreEqual(hh["name"], "henry"); Assert.AreEqual(hh["email"], "*****@*****.**"); } }
public override object Authorize (HttpHeader Header, HttpServer.Method Method, IHttpServerResource Resource, System.Net.EndPoint RemoteEndPoint, out string UserName, out UnauthorizedReason Reason) { string SessionId = Header.GetCookie ("SessionId"); if (MainClass.CheckSession (SessionId, out UserName)) { Reason = UnauthorizedReason.NoError; return UserName; } else { Reason = UnauthorizedReason.OldCredentialsTryAgain; return null; } }
public HttpRequest(string url, HttpAccept httpAccept = null) { Url = new HttpUri(url); Headers = new HttpHeader(); AllowAutoRedirect = true; Cookies = new Dictionary<string, string>(); if (!RuntimeInfoBase.IsProduction) { AllowAutoRedirect = false; } if (httpAccept != null) { Headers.Accept = httpAccept.Value; } }
public void AddHeader(HttpHeader header, string value, string charset="utf-8") { switch (header) { case HttpHeader.AcceptRanges: AddHeader("Accept-Ranges", value); return; case HttpHeader.ContentLength: AddHeader("Content-Length", value); return; case HttpHeader.ContentType: if (value.Contains("charset=")) AddHeader("Content-Type", value); else AddHeader("Content-Type", string.Format("{0};charset={1}",value, charset)); return; case HttpHeader.Date: AddHeader("Date", value); return; case HttpHeader.Server: AddHeader("Server", value); return; case HttpHeader.Connection: AddHeader("Connection", value); return; case HttpHeader.TransferEncoding: AddHeader("Transfer-Encoding", value); return; } }
private string HttpGet(string URI, HttpHeader headers) { WebRequest req = WebRequest.Create(URI); WebResponse resp = req.GetResponse(); if (headers != null) { req.Headers = headers.ToWebHeaderCollection(); } if (resp == null) { return null; } StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream()); return sr.ReadToEnd().Trim(); }
protected void Page_Load(object sender, EventArgs e) { ILinkedInService service = _linkedInService; try { Uri requestUri = new Uri(Constants.TestApiStandardProfileRequest_Uri); HttpHeader httpHeader = new HttpHeader { Name = Constants.TestApiStandardProfileRequest_HttpHeader_Name, Value = Constants.TestApiStandardProfileRequest_HttpHeader_Value }; Person person = service.GetOutOfNetworkProfile(requestUri, new List<HttpHeader> { httpHeader }); console.Text += Utilities.SerializeToXml<Person>(person); } catch (LinkedInException lie) { console.Text += lie.Message; } }
public override void AddHeader(HttpHeader header) { }
public void HandleLoginRequest(HttpHeader request) { LogonData loginForm = Json.CreateObject <LogonData>(request.Content); LogonResult loginResult = new LogonResult(); if (loginForm == null) { loginResult.AuthenticationState = "LOGIN"; loginResult.ErrorCode = "UNABLE_TO_DECODE"; loginResult.ErrorMessage = "There was an internal error while connecting to Battle.net. Please try again later."; SendResponse(HttpCode.BadRequest, loginResult); return; } string login = ""; string password = ""; for (int i = 0; i < loginForm.Inputs.Count; ++i) { switch (loginForm.Inputs[i].Id) { case "account_name": login = loginForm.Inputs[i].Value; break; case "password": password = loginForm.Inputs[i].Value; break; } } PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SelBnetAuthentication); stmt.AddValue(0, login); SQLResult result = DB.Login.Query(stmt); if (!result.IsEmpty()) { uint accountId = result.Read <uint>(0); string pass_hash = result.Read <string>(1); uint failedLogins = result.Read <uint>(2); string loginTicket = result.Read <string>(3); uint loginTicketExpiry = result.Read <uint>(4); bool isBanned = result.Read <ulong>(5) != 0; if (CalculateShaPassHash(login.ToUpper(), password.ToUpper()) == pass_hash) { if (loginTicket.IsEmpty() || loginTicketExpiry < Time.UnixTime) { byte[] ticket = new byte[0].GenerateRandomKey(20); loginTicket = "TC-" + ticket.ToHexString(); } stmt = DB.Login.GetPreparedStatement(LoginStatements.UpdBnetAuthentication); stmt.AddValue(0, loginTicket); stmt.AddValue(1, Time.UnixTime + 3600); stmt.AddValue(2, accountId); DB.Login.Execute(stmt); loginResult.LoginTicket = loginTicket; } else if (!isBanned) { uint maxWrongPassword = ConfigMgr.GetDefaultValue("WrongPass.MaxCount", 0u); if (ConfigMgr.GetDefaultValue("WrongPass.Logging", false)) { Log.outDebug(LogFilter.Network, $"[{request.Host}, Account {login}, Id {accountId}] Attempted to connect with wrong password!"); } if (maxWrongPassword != 0) { SQLTransaction trans = new SQLTransaction(); stmt = DB.Login.GetPreparedStatement(LoginStatements.UpdBnetFailedLogins); stmt.AddValue(0, accountId); trans.Append(stmt); ++failedLogins; Log.outDebug(LogFilter.Network, $"MaxWrongPass : {maxWrongPassword}, failed_login : {accountId}"); if (failedLogins >= maxWrongPassword) { BanMode banType = ConfigMgr.GetDefaultValue("WrongPass.BanType", BanMode.IP); int banTime = ConfigMgr.GetDefaultValue("WrongPass.BanTime", 600); if (banType == BanMode.Account) { stmt = DB.Login.GetPreparedStatement(LoginStatements.InsBnetAccountAutoBanned); stmt.AddValue(0, accountId); } else { stmt = DB.Login.GetPreparedStatement(LoginStatements.InsIpAutoBanned); stmt.AddValue(0, request.Host); } stmt.AddValue(1, banTime); trans.Append(stmt); stmt = DB.Login.GetPreparedStatement(LoginStatements.UpdBnetResetFailedLogins); stmt.AddValue(0, accountId); trans.Append(stmt); } DB.Login.CommitTransaction(trans); } } loginResult.AuthenticationState = "DONE"; SendResponse(HttpCode.Ok, loginResult); } else { loginResult.AuthenticationState = "LOGIN"; loginResult.ErrorCode = "UNABLE_TO_DECODE"; loginResult.ErrorMessage = "There was an internal error while connecting to Battle.net. Please try again later."; SendResponse(HttpCode.BadRequest, loginResult); } }
protected IObservable <T> CreateObservable <T>(Endpoint endpoint, HttpHeader header, T entity, SerializationReason serializationReason) { var body = serializer.Serialize <T>(entity, serializationReason); return(CreateObservable <T>(endpoint, header, body)); }
public async Task ResourceCreateOrUpdateWithIdentityValidateMessage() { var mockResponse = new MockResponse((int)HttpStatusCode.OK); var content = @"{ 'location': 'South Central US', 'tags' : { 'department':'finance', 'tagname':'tagvalue' }, 'properties': { 'name':'site3', 'siteMode': 'Standard', 'computeMode':'Dedicated', 'provisioningState':'Succeeded' }, 'identity': { 'type': 'SystemAssigned', 'principalId': 'foo' } }".Replace("'", "\""); var header = new HttpHeader("x-ms-request-id", "1"); mockResponse.AddHeader(header); mockResponse.SetContent(content); var mockTransport = new MockTransport(mockResponse); var client = GetResourceManagementClient(mockTransport); var raw = await client.Resources.StartCreateOrUpdateAsync( "foo", "Microsoft.Web", string.Empty, "sites", "site3", "2014-01-04", new GenericResource { Location = "South Central US", Tags = { { "department", "finance" }, { "tagname", "tagvalue" } }, Properties = @"{ 'name':'site3', 'siteMode': 'Standard', 'computeMode':'Dedicated' }", Identity = new Identity { Type = ResourceIdentityType.SystemAssigned } } ); var result = (await WaitForCompletionAsync(raw)).Value; // Validate headers var request = mockTransport.Requests[0]; Assert.AreEqual(HttpMethod.Put.Method, request.Method.Method); Assert.IsTrue(request.Headers.Contains("Authorization")); // Validate payload Stream stream = new MemoryStream(); await request.Content.WriteToAsync(stream, default); stream.Position = 0; var resquestContent = new StreamReader(stream).ReadToEnd(); var json = JsonDocument.Parse(resquestContent).RootElement; Assert.AreEqual("South Central US", json.GetProperty("location").GetString()); Assert.AreEqual("finance", json.GetProperty("tags").GetProperty("department").GetString()); Assert.AreEqual("tagvalue", json.GetProperty("tags").GetProperty("tagname").GetString()); // Validate result Assert.AreEqual("South Central US", result.Location); Assert.AreEqual("Succeeded", JsonDocument.Parse(JsonSerializer.Serialize(result.Properties)).RootElement.GetProperty("provisioningState").GetString()); Assert.AreEqual("finance", result.Tags["department"]); Assert.AreEqual("tagvalue", result.Tags["tagname"]); Assert.AreEqual("Dedicated", JsonDocument.Parse(JsonSerializer.Serialize(result.Properties)).RootElement.GetProperty("computeMode").GetString()); Assert.AreEqual("SystemAssigned", result.Identity.Type.ToString()); Assert.AreEqual("foo", result.Identity.PrincipalId); }
public void ProcessRequest(HttpCwsContext context) { try { // Only respond to POST requests made to the listen URL's path if (parent.listenUrl.Path == context.Request.Url.AbsolutePath) { if (context.Request.HttpMethod == "POST") { // GET the individual relay to observe its updated state HttpClientRequest req = new HttpClientRequest(); string linkString = context.Request.Headers["Link"]; // The notification POST request contains a link to the updated resource in the Link header. // in compliance with the RESTful WebHooks standard at // https://webhooks.pbworks.com/w/page/13385128/RESTful%20WebHooks // This URL will be nested between the '<' and '>' characters, // as described in https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link int startIndex = linkString.IndexOf('<') + 1; int endIndex = linkString.IndexOf('>'); string linkUrlString = linkString.Substring(startIndex, endIndex - startIndex); UrlParser relayUrl = new UrlParser(linkUrlString); req.Url = relayUrl; req.RequestType = RequestType.Get; HttpHeader acceptHeader = new HttpHeader("Accept", "application/vnd.collection+json"); req.Header.AddHeader(acceptHeader); req.FinalizeHeader(); HttpClientResponse res = parent.client.Dispatch(req); int rlyID; string newState = ""; if (res.Code == 200) { JObject item = JsonConvert.DeserializeObject <JObject>(res.ContentString); rlyID = (int)item["collection"]["items"][0]["data"][0]["value"]; newState = (string)item["collection"]["items"][0]["data"][1]["value"]; } else { CrestronConsole.PrintLine("Failed to get individual relay"); return; } // log the notification message to console CrestronConsole.PrintLine("NOTIFICATION: Relay #" + rlyID + "'s state changed to " + newState); // respond to notification with 200 OK context.Response.StatusCode = 200; context.Response.StatusDescription = "OK"; context.Response.End(); } else { context.Response.StatusCode = 405; context.Response.StatusDescription = "Method Not Allowed"; context.Response.End(); } } else // ignore all other URLs besides the listener URL { CrestronConsole.PrintLine("Sending back a 404"); context.Response.StatusCode = 404; context.Response.StatusDescription = "Not Found"; context.Response.End(); } } catch (Exception e) { try { // Respond with error message context.Response.StatusCode = 500; context.Response.StatusDescription = "Internal Server Error"; context.Response.End(); CrestronConsole.PrintLine("Error in ProcessRequest: " + e.Message); } catch (Exception ex) { CrestronConsole.PrintLine("ProcessRequest unable to send error response: " + ex.Message); } } finally { ErrorLog.Notice("Served response to " + context.Request.UserHostName); } }
/// <summary> /// 获取html 携带cookies /// </summary> /// <param name="getUrl"></param> /// <param name="cookieContainer"></param> /// <param name="header"></param> /// <returns></returns> public static string HttpGetRequestWithCookies(string getUrl, CookieContainer cookieContainer, HttpHeader header) { HttpWebRequest httpWebRequest = null; HttpWebResponse httpWebResponse = null; try { httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(getUrl); httpWebRequest.CookieContainer = cookieContainer; httpWebRequest.ContentType = header.contentType; httpWebRequest.ServicePoint.ConnectionLimit = header.maxTry;//客户端同时可以建立的 http 连接数 httpWebRequest.Referer = getUrl; httpWebRequest.Accept = header.accept; httpWebRequest.UserAgent = header.userAgent; httpWebRequest.Method = "GET"; httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); Stream responseStream = httpWebResponse.GetResponseStream(); StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); string html = streamReader.ReadToEnd(); streamReader.Close(); responseStream.Close(); httpWebRequest.Abort(); httpWebResponse.Close(); return(html); } catch (Exception e) { if (httpWebRequest != null) { httpWebRequest.Abort(); } if (httpWebResponse != null) { httpWebResponse.Close(); } return(string.Empty); } }
/// <summary> /// Handle windows NTLM/Kerberos authentication. /// Note: NTLM/Kerberos cannot do a man in middle operation /// we do for HTTPS requests. /// As such we will be sending local credentials of current /// User to server to authenticate requests. /// To disable this set ProxyServer.EnableWinAuth to false. /// </summary> internal async Task Handle401UnAuthorized(SessionEventArgs args) { string headerName = null; HttpHeader authHeader = null; var response = args.WebSession.Response; // check in non-unique headers first var header = response.Headers.NonUniqueHeaders.FirstOrDefault(x => authHeaderNames.Contains(x.Key)); if (!header.Equals(new KeyValuePair <string, List <HttpHeader> >())) { headerName = header.Key; } if (headerName != null) { authHeader = response.Headers.NonUniqueHeaders[headerName] .FirstOrDefault( x => authSchemes.Any(y => x.Value.StartsWith(y, StringComparison.OrdinalIgnoreCase))); } // check in unique headers if (authHeader == null) { headerName = null; // check in non-unique headers first var uHeader = response.Headers.Headers.FirstOrDefault(x => authHeaderNames.Contains(x.Key)); if (!uHeader.Equals(new KeyValuePair <string, HttpHeader>())) { headerName = uHeader.Key; } if (headerName != null) { authHeader = authSchemes.Any(x => response.Headers.Headers[headerName].Value .StartsWith(x, StringComparison.OrdinalIgnoreCase)) ? response.Headers.Headers[headerName] : null; } } if (authHeader != null) { string scheme = authSchemes.Contains(authHeader.Value) ? authHeader.Value : null; var expectedAuthState = scheme == null ? State.WinAuthState.INITIAL_TOKEN : State.WinAuthState.UNAUTHORIZED; if (!WinAuthEndPoint.ValidateWinAuthState(args.WebSession.Data, expectedAuthState)) { // Invalid state, create proper error message to client await RewriteUnauthorizedResponse(args); return; } var request = args.WebSession.Request; // clear any existing headers to avoid confusing bad servers request.Headers.RemoveHeader(KnownHeaders.Authorization); // initial value will match exactly any of the schemes if (scheme != null) { string clientToken = WinAuthHandler.GetInitialAuthToken(request.Host, scheme, args.WebSession.Data); string auth = string.Concat(scheme, clientToken); // replace existing authorization header if any request.Headers.SetOrAddHeaderValue(KnownHeaders.Authorization, auth); // don't need to send body for Authorization request if (request.HasBody) { request.ContentLength = 0; } } else { // challenge value will start with any of the scheme selected scheme = authSchemes.First(x => authHeader.Value.StartsWith(x, StringComparison.OrdinalIgnoreCase) && authHeader.Value.Length > x.Length + 1); string serverToken = authHeader.Value.Substring(scheme.Length + 1); string clientToken = WinAuthHandler.GetFinalAuthToken(request.Host, serverToken, args.WebSession.Data); string auth = string.Concat(scheme, clientToken); // there will be an existing header from initial client request request.Headers.SetOrAddHeaderValue(KnownHeaders.Authorization, auth); // send body for final auth request if (request.OriginalHasBody) { request.ContentLength = request.Body.Length; } } // Need to revisit this. // Should we cache all Set-Cokiee headers from server during auth process // and send it to client after auth? // Let ResponseHandler send the updated request args.ReRequest = true; } }
private void FillConfigurationElementWithData(ConfigurationElement item2Fill, HttpHeader header) { // item2Fill.SetAttributeValue(NameAttribute, header.Key); item2Fill.SetAttributeValue(ValueAttribute, header.Value); }
private ConfigurationElement CreateCustomHttpHeader(ConfigurationElementCollection collection, HttpHeader header) { // Skip elements either empty or with empty data if (header == null || String.IsNullOrEmpty(header.Key)) { return(null); } // ConfigurationElement header2Add = collection.CreateElement("add"); // FillConfigurationElementWithData(header2Add, header); // return(header2Add); }
/// <summary> /// Creates a TCP connection to server /// </summary> /// <param name="remoteHostName">The remote hostname.</param> /// <param name="remotePort">The remote port.</param> /// <param name="httpVersion">The http version to use.</param> /// <param name="isHttps">Is this a HTTPS request.</param> /// <param name="applicationProtocols">The list of HTTPS application level protocol to negotiate if needed.</param> /// <param name="isConnect">Is this a CONNECT request.</param> /// <param name="proxyServer">The current ProxyServer instance.</param> /// <param name="upStreamEndPoint">The local upstream endpoint to make request via.</param> /// <param name="externalProxy">The external proxy to make request via.</param> /// <param name="cancellationToken">The cancellation token for this async task.</param> /// <returns></returns> private async Task <TcpServerConnection> CreateClient(string remoteHostName, int remotePort, Version httpVersion, bool isHttps, List <SslApplicationProtocol> applicationProtocols, bool isConnect, ProxyServer proxyServer, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy, CancellationToken cancellationToken) { bool useUpstreamProxy = false; // check if external proxy is set for HTTP/HTTPS if (externalProxy != null && !(externalProxy.HostName == remoteHostName && externalProxy.Port == remotePort)) { useUpstreamProxy = true; // check if we need to ByPass if (externalProxy.BypassLocalhost && NetworkHelper.IsLocalIpAddress(remoteHostName)) { useUpstreamProxy = false; } } TcpClient tcpClient = null; CustomBufferedStream stream = null; SslApplicationProtocol negotiatedApplicationProtocol = default; try { tcpClient = new TcpClient(upStreamEndPoint) { ReceiveTimeout = proxyServer.ConnectionTimeOutSeconds * 1000, SendTimeout = proxyServer.ConnectionTimeOutSeconds * 1000, SendBufferSize = proxyServer.BufferSize, ReceiveBufferSize = proxyServer.BufferSize }; await proxyServer.InvokeConnectionCreateEvent(tcpClient, false); // If this proxy uses another external proxy then create a tunnel request for HTTP/HTTPS connections if (useUpstreamProxy) { await tcpClient.ConnectAsync(externalProxy.HostName, externalProxy.Port); } else { await tcpClient.ConnectAsync(remoteHostName, remotePort); } stream = new CustomBufferedStream(tcpClient.GetStream(), proxyServer.BufferSize); if (useUpstreamProxy && (isConnect || isHttps)) { var writer = new HttpRequestWriter(stream, proxyServer.BufferSize); var connectRequest = new ConnectRequest { OriginalUrl = $"{remoteHostName}:{remotePort}", HttpVersion = httpVersion }; connectRequest.Headers.AddHeader(KnownHeaders.Connection, KnownHeaders.ConnectionKeepAlive); if (!string.IsNullOrEmpty(externalProxy.UserName) && externalProxy.Password != null) { connectRequest.Headers.AddHeader(HttpHeader.ProxyConnectionKeepAlive); connectRequest.Headers.AddHeader( HttpHeader.GetProxyAuthorizationHeader(externalProxy.UserName, externalProxy.Password)); } await writer.WriteRequestAsync(connectRequest, cancellationToken : cancellationToken); string httpStatus = await stream.ReadLineAsync(cancellationToken); Response.ParseResponseLine(httpStatus, out _, out int statusCode, out string statusDescription); if (statusCode != 200 && !statusDescription.EqualsIgnoreCase("OK") && !statusDescription.EqualsIgnoreCase("Connection Established")) { throw new Exception("Upstream proxy failed to create a secure tunnel"); } await stream.ReadAndIgnoreAllLinesAsync(cancellationToken); } if (isHttps) { var sslStream = new SslStream(stream, false, proxyServer.ValidateServerCertificate, proxyServer.SelectClientCertificate); stream = new CustomBufferedStream(sslStream, proxyServer.BufferSize); var options = new SslClientAuthenticationOptions { ApplicationProtocols = applicationProtocols, TargetHost = remoteHostName, ClientCertificates = null, EnabledSslProtocols = proxyServer.SupportedSslProtocols, CertificateRevocationCheckMode = proxyServer.CheckCertificateRevocation }; await sslStream.AuthenticateAsClientAsync(options, cancellationToken); #if NETCOREAPP2_1 negotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol; #endif } } catch (Exception) { stream?.Dispose(); tcpClient?.Close(); throw; } return(new TcpServerConnection(proxyServer, tcpClient) { UpStreamProxy = externalProxy, UpStreamEndPoint = upStreamEndPoint, HostName = remoteHostName, Port = remotePort, IsHttps = isHttps, NegotiatedApplicationProtocol = negotiatedApplicationProtocol, UseUpstreamProxy = useUpstreamProxy, StreamWriter = new HttpRequestWriter(stream, proxyServer.BufferSize), Stream = stream, Version = httpVersion }); }
/// <summary> /// Handle windows NTLM authentication /// Can expand this for Kerberos in future /// Note: NTLM/Kerberos cannot do a man in middle operation /// we do for HTTPS requests. /// As such we will be sending local credentials of current /// User to server to authenticate requests. /// To disable this set ProxyServer.EnableWinAuth to false /// </summary> internal async Task <bool> Handle401UnAuthorized(SessionEventArgs args) { string headerName = null; HttpHeader authHeader = null; //check in non-unique headers first var header = args.WebSession.Response .NonUniqueResponseHeaders .FirstOrDefault(x => authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase))); if (!header.Equals(new KeyValuePair <string, List <HttpHeader> >())) { headerName = header.Key; } if (headerName != null) { authHeader = args.WebSession.Response .NonUniqueResponseHeaders[headerName] .Where(x => authSchemes.Any(y => x.Value.StartsWith(y, StringComparison.OrdinalIgnoreCase))) .FirstOrDefault(); } //check in unique headers if (authHeader == null) { //check in non-unique headers first var uHeader = args.WebSession.Response .ResponseHeaders .FirstOrDefault(x => authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase))); if (!uHeader.Equals(new KeyValuePair <string, HttpHeader>())) { headerName = uHeader.Key; } if (headerName != null) { authHeader = authSchemes.Any(x => args.WebSession.Response .ResponseHeaders[headerName].Value.StartsWith(x, StringComparison.OrdinalIgnoreCase)) ? args.WebSession.Response.ResponseHeaders[headerName] : null; } } if (authHeader != null) { var scheme = authSchemes.FirstOrDefault(x => authHeader.Value.Equals(x, StringComparison.OrdinalIgnoreCase)); //initial value will match exactly any of the schemes if (scheme != null) { var clientToken = WinAuthHandler.GetInitialAuthToken(args.WebSession.Request.Host, scheme, args.Id); args.WebSession.Request.RequestHeaders.Add("Authorization", new HttpHeader("Authorization", string.Concat(scheme, clientToken))); } //challenge value will start with any of the scheme selected else { scheme = authSchemes.FirstOrDefault(x => authHeader.Value.StartsWith(x, StringComparison.OrdinalIgnoreCase) && authHeader.Value.Length > x.Length + 1); var serverToken = authHeader.Value.Substring(scheme.Length + 1); var clientToken = WinAuthHandler.GetFinalAuthToken(args.WebSession.Request.Host, serverToken, args.Id); args.WebSession.Request.RequestHeaders["Authorization"] = new HttpHeader("Authorization", string.Concat(scheme, clientToken)); } //clear current response await args.ClearResponse(); var disposed = await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args, false); return(disposed); } return(false); }
public void AddHeader(HttpHeader header) { //CoreValidator.ThrowIfNull(header, name: nameof(header)); this.Headers.AddHeader(header); }
protected IObservable <T> CreateObservable <T>(Endpoint endpoint, HttpHeader header, string body = "") => CreateObservable <T>(endpoint, new [] { header }, body);
public void AddHeader(HttpHeader header) => this.Headers.Add(header);
public async Task ResourceLinkCRUD() { var mockResponse = new MockResponse((int)HttpStatusCode.Created); var content = @"{ 'id': '/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm/providers/Microsoft.Resources/links/myLink', 'name': 'myLink', 'properties': { 'sourceId': '/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm', 'targetId': '/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm2', 'notes': 'myLinkNotes' } }".Replace("'", "\""); mockResponse.SetContent(content); var mockTransport = new MockTransport(mockResponse); var client = GetResourceManagementClient(mockTransport); var result = (await client.ResourceLinks.CreateOrUpdateAsync( linkId: "/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm/providers/Microsoft.Resources/links/myLink", parameters: new ResourceLink { Properties = new ResourceLinkProperties("/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm2") { Notes = "myLinkNotes" } })).Value; // Validate headers var request = mockTransport.Requests[0]; Assert.IsTrue(request.Headers.Contains(new HttpHeader("Content-Type", "application/json"))); Assert.AreEqual(HttpMethod.Put.Method, request.Method.Method); Assert.IsTrue(request.Headers.Contains("Authorization")); // Validate payload Stream stream = new MemoryStream(); await request.Content.WriteToAsync(stream, default); stream.Position = 0; var resquestContent = new StreamReader(stream).ReadToEnd(); var json = JsonDocument.Parse(resquestContent).RootElement; Assert.AreEqual("/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm2", json.GetProperty("properties").GetProperty("targetId").GetString()); Assert.AreEqual("myLinkNotes", json.GetProperty("properties").GetProperty("notes").GetString()); // Validate response Assert.AreEqual("/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm/providers/Microsoft.Resources/links/myLink", result.Id); Assert.AreEqual("/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm", result.Properties.SourceId); Assert.AreEqual("/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm2", result.Properties.TargetId); Assert.AreEqual("myLinkNotes", result.Properties.Notes); Assert.AreEqual("myLink", result.Name); //Get resource link and validate properties mockResponse = new MockResponse((int)HttpStatusCode.OK); content = @"{ 'id': '/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm/providers/Microsoft.Resources/links/myLink', 'name': 'myLink', 'properties': { 'sourceId': '/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm', 'targetId': '/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm2', 'notes': 'myLinkNotes' } }".Replace("'", "\""); mockResponse.SetContent(content); mockTransport = new MockTransport(mockResponse); client = GetResourceManagementClient(mockTransport); var getResult = (await client.ResourceLinks.GetAsync("/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm/providers/Microsoft.Resources/links/myLink")).Value; // Validate response Assert.AreEqual("/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm/providers/Microsoft.Resources/links/myLink", getResult.Id); Assert.AreEqual("/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm", getResult.Properties.SourceId); Assert.AreEqual("/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm2", getResult.Properties.TargetId); Assert.AreEqual("myLinkNotes", getResult.Properties.Notes); Assert.AreEqual("myLink", getResult.Name); //Delete resource link mockResponse = new MockResponse((int)HttpStatusCode.OK); content = JsonDocument.Parse("{}").RootElement.ToString(); var header = new HttpHeader("x-ms-request-id", "1"); mockResponse.AddHeader(header); mockResponse.SetContent(content); mockTransport = new MockTransport(mockResponse); client = GetResourceManagementClient(mockTransport); await client.ResourceLinks.DeleteAsync("/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm/providers/Microsoft.Resources/links/myLink"); // Validate headers request = mockTransport.Requests[0]; Assert.AreEqual(HttpMethod.Delete.Method, request.Method.Method); try { await client.ResourceLinks.GetAsync("/subscriptions/abc123/resourcegroups/myGroup/providers/Microsoft.Web/serverFarms/myFarm/providers/Microsoft.Resources/links/myLink"); } catch (Exception ex) { Assert.NotNull(ex); } }
/// <summary> /// Определяет, содержится ли указанный HTTP-заголовок. /// </summary> /// <param name="header">HTTP-заголовок.</param> /// <returns>Значение <see langword="true"/>, если указанный HTTP-заголовок содержится, иначе значение <see langword="false"/>.</returns> public bool ContainsHeader(HttpHeader header) { return ContainsHeader(Http.Headers[header]); }
public void AddHeader(HttpHeader header) { this.Headers.AddHeader(header); }
// Subscribe to a random relay port on the server control system. The RelayMonitor will print notifications // to the console when this relay changes state public void Subscribe(string serverHostname) { try { if (subscribed) { CrestronConsole.PrintLine("The monitor can only subscribe to one relay at a time. Unsubscribe first"); return; } // point serverAPIUrl at the root of the remote CWS server serverAPIUrl = new UrlParser("http://" + serverHostname + "/cws/api/"); // GET the relay collection and derive the number of relays // available on the control system from the response HttpClientRequest req = new HttpClientRequest(); UrlParser collectionUrl = new UrlParser(serverAPIUrl, "relays"); // complete URL = baseUrl + relativeUrl req.Url = collectionUrl; req.RequestType = RequestType.Get; HttpHeader acceptHeader = new HttpHeader("Accept", "application/vnd.collection+json"); req.Header.AddHeader(acceptHeader); req.FinalizeHeader(); HttpClientResponse res = client.Dispatch(req); if (res.Code == 200) { CrestronConsole.PrintLine("Received GET response for the relay collection"); string json = res.ContentString; JObject collection = JsonConvert.DeserializeObject <JObject>(json); JArray list = (JArray)collection["collection"]["items"]; int relayCount = list.Count; Random rnd = new Random(); rlyID = rnd.Next(1, relayCount + 1); CrestronConsole.PrintLine("Server control system has " + relayCount + " relays. Subscribing to relay #" + rlyID + "..."); // Subscribe the the web-hook for the Relay #rlyID req = new HttpClientRequest(); UrlParser webhookUrl = new UrlParser(serverAPIUrl, "relays/" + rlyID + "/web-hooks"); req.Url = webhookUrl; req.RequestType = RequestType.Post; // add the Content-Type and Notification-Type headers as required by the RESTful WebHooks standard HttpHeaders headers = new HttpHeaders(); headers.SetHeaderValue("Content-Type", "text/uri-list"); // webhook expects POST body to contain a single URL headers.SetHeaderValue("Notification-Type", "UPDATED"); // monitor wants to know when relay state is changed req.Header = headers; req.FinalizeHeader(); req.ContentString = listenUrl.ToString(); res = client.Dispatch(req); if (res.Code == 201) // successful POST, subscription resource has been created { subscriptionUrl = new UrlParser(res.Header["Location"].Value); // save the obscure URL to the new subscription resource subscribed = true; CrestronConsole.PrintLine("Subscribed to Relay #" + rlyID); CrestronConsole.PrintLine("Subscription resource URL: " + subscriptionUrl); } else { CrestronConsole.PrintLine("Failed to subscribe to " + rlyID); } // Must call Dispose on the HttpClientResponse object to end this HTTP session res.Dispose(); } else { CrestronConsole.PrintLine("Failed to get relay collection"); return; } } catch (Exception e) { CrestronConsole.PrintLine("Error in Subscribe(): " + e.Message); } finally { } }
/// <summary> /// Encode the header field into the header block. /// </summary> /// <param name="output">Output.</param> /// <param name="name">Name.</param> /// <param name="value">Value.</param> /// <param name="sensitive">If set to <c>true</c> sensitive.</param> /// <param name="indexType">Index type.</param> /// <param name="useStaticName">Use static name.</param> public void EncodeHeader(BinaryWriter output, ByteString name, ByteString value, bool sensitive = false, HpackUtil.IndexType indexType = HpackUtil.IndexType.Incremental, bool useStaticName = true) { // If the header value is sensitive then it must never be indexed if (sensitive) { int nameIndex = getNameIndex(name); encodeLiteral(output, name, value, HpackUtil.IndexType.Never, nameIndex); return; } // If the peer will only use the static table if (MaxHeaderTableSize == 0) { int staticTableIndex = StaticTable.GetIndex(name, value); if (staticTableIndex == -1) { int nameIndex = StaticTable.GetIndex(name); encodeLiteral(output, name, value, HpackUtil.IndexType.None, nameIndex); } else { encodeInteger(output, 0x80, 7, staticTableIndex); } return; } int headerSize = HttpHeader.SizeOf(name, value); // If the headerSize is greater than the max table size then it must be encoded literally if (headerSize > MaxHeaderTableSize) { int nameIndex = getNameIndex(name); encodeLiteral(output, name, value, HpackUtil.IndexType.None, nameIndex); return; } var headerField = getEntry(name, value); if (headerField != null) { int index = getIndex(headerField.Index) + StaticTable.Length; // Section 6.1. Indexed Header Field Representation encodeInteger(output, 0x80, 7, index); } else { int staticTableIndex = StaticTable.GetIndex(name, value); if (staticTableIndex != -1) { // Section 6.1. Indexed Header Field Representation encodeInteger(output, 0x80, 7, staticTableIndex); } else { int nameIndex = useStaticName ? getNameIndex(name) : -1; ensureCapacity(headerSize); encodeLiteral(output, name, value, indexType, nameIndex); add(name, value); } } }
public async Task ProviderGetValidateMessage() { var mockResponse = new MockResponse((int)HttpStatusCode.OK); var content = @"{ 'namespace': 'Microsoft.Websites', 'registrationState': 'Registered', 'resourceTypes': [ { 'resourceType': 'sites', 'locations': [ 'Central US' ], 'aliases': [{ 'name': 'Microsoft.Compute/virtualMachines/sku.name', 'paths': [{ 'path': 'properties.hardwareProfile.vmSize', 'apiVersions': [ '2015-05-01-preview', '2015-06-15', '2016-03-30', '2016-04-30-preview' ] }] }, { 'name': 'Microsoft.Compute/virtualMachines/imagePublisher', 'paths': [{ 'path': 'properties.storageProfile.imageReference.publisher', 'apiVersions': [ '2015-05-01-preview', '2015-06-15', '2016-03-30', '2016-04-30-preview' ] }] }] }, { 'resourceType': 'sites/pages', 'locations': [ 'West US' ] }] }".Replace("'", "\""); mockResponse.SetContent(content); var header = new HttpHeader("x-ms-request-id", "1"); mockResponse.AddHeader(header); var mockTransport = new MockTransport(mockResponse); var client = GetResourceManagementClient(mockTransport); var result = (await client.Providers.GetAsync("Microsoft.Websites", expand: "resourceTypes/aliases")).Value; // Validate headers var request = mockTransport.Requests[0]; Assert.AreEqual(HttpMethod.Get.Method, request.Method.Method); Assert.IsTrue(request.Headers.Contains("Authorization")); // Validate result Assert.AreEqual("Microsoft.Websites", result.Namespace); Assert.AreEqual("Registered", result.RegistrationState); Assert.AreEqual(2, result.ResourceTypes.Count); Assert.AreEqual("sites", result.ResourceTypes[0].ResourceType); Assert.AreEqual(1, result.ResourceTypes[0].Locations.Count); Assert.AreEqual("Central US", result.ResourceTypes[0].Locations[0]); Assert.AreEqual(2, result.ResourceTypes[0].Aliases.Count); Assert.AreEqual("Microsoft.Compute/virtualMachines/sku.name", result.ResourceTypes[0].Aliases[0].Name); Assert.AreEqual(1, result.ResourceTypes[0].Aliases[0].Paths.Count); Assert.AreEqual("properties.hardwareProfile.vmSize", result.ResourceTypes[0].Aliases[0].Paths[0].Path); }
/// <summary> /// Возвращает значение HTTP-заголовка. /// </summary> /// <param name="header">HTTP-заголовок.</param> /// <value>Значение HTTP-заголовка, если он задан, иначе пустая строка.</value> public string this[HttpHeader header] { get { return this[HttpHelper.HttpHeaders[header]]; } }
private static ParseInfo Parse(byte[] buffer, int offset, int length) { // First Line HttpParser parser = new HttpParser(buffer, offset, length); HttpVersion version; uint? statusCode; Datagram reasonPhrase; parser.Version(out version).Space().DecimalNumber(3, out statusCode).Space().SkipSpaces().ReasonPhrase(out reasonPhrase).CarriageReturnLineFeed(); ParseInfo parseInfo = new ParseInfo { Length = length, Version = version, StatusCode = statusCode, ReasonPhrase = reasonPhrase }; if (!parser.Success) return parseInfo; int firstLineLength = parser.Offset - offset; // Header int? endHeaderOffset; HttpHeader header = new HttpHeader(GetHeaderFields(out endHeaderOffset, buffer, offset + firstLineLength, length - firstLineLength)); parseInfo.Header = header; if (endHeaderOffset == null) return parseInfo; int headerLength = endHeaderOffset.Value - offset - firstLineLength; // Body Datagram body = ParseBody(buffer, offset + firstLineLength + headerLength, length - firstLineLength - headerLength, IsBodyPossible(statusCode.Value), header); parseInfo.Body = body; parseInfo.Length = firstLineLength + headerLength + body.Length; return parseInfo; }
protected IObservable <T> CreateObservable <T>(Endpoint endpoint, HttpHeader header, string body = "", ResponseValidator <T> responseValidator = null) => CreateObservable(endpoint, new[] { header }, body, responseValidator);
public override void AddHeader(HttpHeader header) { _headers.Add(header); }
public void Can_Create_Know_Header() { var header = new HttpHeader(HttpHeader.KnownHeaders.Authorization, "test"); Assert.That(header.Field, Is.EqualTo("Authorization")); }
/// <summary> /// 解析连接请求信息 /// </summary> /// <param name="bytes">原始数量</param> /// <param name="localEndpoint">服务器终结点</param> /// <param name="remoteEndpoint">远程端的IP和端口</param> /// <returns></returns> private static HttpRequest From(byte[] bytes, IPEndPoint localEndpoint, IPEndPoint remoteEndpoint) { const string pattern = @"^(?<method>[^\s]+)\s(?<path>[^\s]+)\sHTTP\/1\.1\r\n" + @"((?<field_name>[^:\r\n]+):\s(?<field_value>[^\r\n]*)\r\n)+" + @"\r\n"; var match = Regex.Match(Encoding.ASCII.GetString(bytes), pattern, RegexOptions.IgnoreCase); if (match.Success == false) { return null; } var httpMethod = HttpRequest.GetHttpMethod(match.Groups["method"].Value); var httpHeader = new HttpHeader(match.Groups["field_name"].Captures, match.Groups["field_value"].Captures); if (httpMethod != HttpMethod.GET && bytes.Length - match.Length < httpHeader.ContentLength) { return null; } var request = new HttpRequest { InputStrem = bytes, LocalEndPoint = localEndpoint, RemoteEndPoint = remoteEndpoint, HttpMethod = httpMethod, Headers = httpHeader }; request.Url = new Uri("http://localhost:" + localEndpoint.Port + match.Groups["path"].Value); request.Path = request.Url.AbsolutePath; request.Query = new HttpNameValueCollection(request.Url.Query.TrimStart('?')); var form = string.Empty; if (httpMethod != HttpMethod.GET) { var contentType = request.Headers.TryGet<string>("Content-Type"); if (StringEquals(contentType, "application/x-www-form-urlencoded") == true) { form = Encoding.UTF8.GetString(bytes, match.Length, bytes.Length - match.Length); } } request.Form = new HttpNameValueCollection(form); return request; }
public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies) { if (!CheckAvailability()) { throw new ApplicationException("Curl failed to initialize."); } lock (CurlGlobalHandle.Instance) { Stream responseStream = new MemoryStream(); Stream headerStream = new MemoryStream(); using (var curlEasy = new CurlEasy()) { curlEasy.AutoReferer = false; curlEasy.WriteFunction = (b, s, n, o) => { responseStream.Write(b, 0, s * n); return s * n; }; curlEasy.HeaderFunction = (b, s, n, o) => { headerStream.Write(b, 0, s * n); return s * n; }; AddProxy(curlEasy, request); curlEasy.Url = request.Url.FullUri; switch (request.Method) { case HttpMethod.GET: curlEasy.HttpGet = true; break; case HttpMethod.POST: curlEasy.Post = true; break; case HttpMethod.PUT: curlEasy.Put = true; break; default: throw new NotSupportedException(string.Format("HttpCurl method {0} not supported", request.Method)); } curlEasy.UserAgent = request.UseSimplifiedUserAgent ? UserAgentBuilder.UserAgentSimplified : UserAgentBuilder.UserAgent; ; curlEasy.FollowLocation = request.AllowAutoRedirect; if (request.RequestTimeout != TimeSpan.Zero) { curlEasy.Timeout = (int)Math.Ceiling(request.RequestTimeout.TotalSeconds); } if (OsInfo.IsWindows) { curlEasy.CaInfo = _caBundleFilePath; } if (cookies != null) { curlEasy.Cookie = cookies.GetCookieHeader((Uri)request.Url); } if (request.ContentData != null) { curlEasy.PostFieldSize = request.ContentData.Length; curlEasy.SetOpt(CurlOption.CopyPostFields, new string(Array.ConvertAll(request.ContentData, v => (char)v))); } // Yes, we have to keep a ref to the object to prevent corrupting the unmanaged state using (var httpRequestHeaders = SerializeHeaders(request)) { curlEasy.HttpHeader = httpRequestHeaders; var result = curlEasy.Perform(); if (result != CurlCode.Ok) { switch (result) { case CurlCode.SslCaCert: case (CurlCode)77: throw new WebException(string.Format("Curl Error {0} for Url {1}, issues with your operating system SSL Root Certificate Bundle (ca-bundle).", result, curlEasy.Url)); default: throw new WebException(string.Format("Curl Error {0} for Url {1}", result, curlEasy.Url)); } } } var webHeaderCollection = ProcessHeaderStream(request, cookies, headerStream); var responseData = ProcessResponseStream(request, responseStream, webHeaderCollection); var httpHeader = new HttpHeader(webHeaderCollection); return new HttpResponse(request, httpHeader, responseData, (HttpStatusCode)curlEasy.ResponseCode); } } }
/// <summary> /// Creates a TCP connection to server /// </summary> /// <param name="remoteHostName">The remote hostname.</param> /// <param name="remotePort">The remote port.</param> /// <param name="httpVersion">The http version to use.</param> /// <param name="isHttps">Is this a HTTPS request.</param> /// <param name="sslProtocol">The SSL protocol.</param> /// <param name="applicationProtocols">The list of HTTPS application level protocol to negotiate if needed.</param> /// <param name="isConnect">Is this a CONNECT request.</param> /// <param name="proxyServer">The current ProxyServer instance.</param> /// <param name="session">The http session.</param> /// <param name="upStreamEndPoint">The local upstream endpoint to make request via.</param> /// <param name="externalProxy">The external proxy to make request via.</param> /// <param name="cacheKey">The connection cache key</param> /// <param name="cancellationToken">The cancellation token for this async task.</param> /// <returns></returns> private async Task <TcpServerConnection> createServerConnection(string remoteHostName, int remotePort, Version httpVersion, bool isHttps, SslProtocols sslProtocol, List <SslApplicationProtocol>?applicationProtocols, bool isConnect, ProxyServer proxyServer, SessionEventArgsBase?session, IPEndPoint?upStreamEndPoint, IExternalProxy?externalProxy, string cacheKey, CancellationToken cancellationToken) { // deny connection to proxy end points to avoid infinite connection loop. if (Server.ProxyEndPoints.Any(x => x.Port == remotePort) && NetworkHelper.IsLocalIpAddress(remoteHostName)) { throw new Exception($"A client is making HTTP request to one of the listening ports of this proxy {remoteHostName}:{remotePort}"); } if (externalProxy != null) { if (Server.ProxyEndPoints.Any(x => x.Port == externalProxy.Port) && NetworkHelper.IsLocalIpAddress(externalProxy.HostName)) { throw new Exception($"A client is making HTTP request via external proxy to one of the listening ports of this proxy {remoteHostName}:{remotePort}"); } } bool useUpstreamProxy1 = false; // check if external proxy is set for HTTP/HTTPS if (externalProxy != null && !(externalProxy.HostName == remoteHostName && externalProxy.Port == remotePort)) { useUpstreamProxy1 = true; // check if we need to ByPass if (externalProxy.BypassLocalhost && NetworkHelper.IsLocalIpAddress(remoteHostName)) { useUpstreamProxy1 = false; } } if (!useUpstreamProxy1) { externalProxy = null; } TcpClient? tcpClient = null; HttpServerStream?stream = null; SslApplicationProtocol negotiatedApplicationProtocol = default; bool retry = true; var enabledSslProtocols = sslProtocol; retry: try { string hostname = externalProxy != null ? externalProxy.HostName : remoteHostName; int port = externalProxy?.Port ?? remotePort; var ipAddresses = await Dns.GetHostAddressesAsync(hostname); if (ipAddresses == null || ipAddresses.Length == 0) { throw new Exception($"Could not resolve the hostname {hostname}"); } if (session != null) { session.TimeLine["Dns Resolved"] = DateTime.Now; } Array.Sort(ipAddresses, (x, y) => x.AddressFamily.CompareTo(y.AddressFamily)); Exception lastException = null; for (int i = 0; i < ipAddresses.Length; i++) { try { var ipAddress = ipAddresses[i]; if (upStreamEndPoint == null) { tcpClient = new TcpClient(ipAddress.AddressFamily); } else { tcpClient = new TcpClient(upStreamEndPoint); } tcpClient.NoDelay = proxyServer.NoDelay; tcpClient.ReceiveTimeout = proxyServer.ConnectionTimeOutSeconds * 1000; tcpClient.SendTimeout = proxyServer.ConnectionTimeOutSeconds * 1000; tcpClient.LingerState = new LingerOption(true, proxyServer.TcpTimeWaitSeconds); if (proxyServer.ReuseSocket && RunTime.IsSocketReuseAvailable) { tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } var connectTask = tcpClient.ConnectAsync(ipAddress, port); await Task.WhenAny(connectTask, Task.Delay(proxyServer.ConnectTimeOutSeconds * 1000)); if (!connectTask.IsCompleted || !tcpClient.Connected) { // here we can just do some cleanup and let the loop continue since // we will either get a connection or wind up with a null tcpClient // which will throw try { connectTask.Dispose(); } catch { // ignore } try { #if NET45 tcpClient?.Close(); #else tcpClient?.Dispose(); #endif tcpClient = null; } catch { // ignore } continue; } break; } catch (Exception e) { // dispose the current TcpClient and try the next address lastException = e; #if NET45 tcpClient?.Close(); #else tcpClient?.Dispose(); #endif tcpClient = null; } } if (tcpClient == null) { if (session != null && proxyServer.CustomUpStreamProxyFailureFunc != null) { var newUpstreamProxy = await proxyServer.CustomUpStreamProxyFailureFunc(session); if (newUpstreamProxy != null) { session.CustomUpStreamProxyUsed = newUpstreamProxy; session.TimeLine["Retrying Upstream Proxy Connection"] = DateTime.Now; return(await createServerConnection(remoteHostName, remotePort, httpVersion, isHttps, sslProtocol, applicationProtocols, isConnect, proxyServer, session, upStreamEndPoint, externalProxy, cacheKey, cancellationToken)); } } throw new Exception($"Could not establish connection to {hostname}", lastException); } if (session != null) { session.TimeLine["Connection Established"] = DateTime.Now; } await proxyServer.InvokeConnectionCreateEvent(tcpClient, false); stream = new HttpServerStream(tcpClient.GetStream(), proxyServer.BufferPool); if (externalProxy != null && (isConnect || isHttps)) { string authority = $"{remoteHostName}:{remotePort}"; var connectRequest = new ConnectRequest(authority) { IsHttps = isHttps, RequestUriString8 = HttpHeader.Encoding.GetBytes(authority), HttpVersion = httpVersion }; connectRequest.Headers.AddHeader(KnownHeaders.Connection, KnownHeaders.ConnectionKeepAlive); if (!string.IsNullOrEmpty(externalProxy.UserName) && externalProxy.Password != null) { connectRequest.Headers.AddHeader(HttpHeader.ProxyConnectionKeepAlive); connectRequest.Headers.AddHeader(HttpHeader.GetProxyAuthorizationHeader(externalProxy.UserName, externalProxy.Password)); } await stream.WriteRequestAsync(connectRequest, cancellationToken); var httpStatus = await stream.ReadResponseStatus(cancellationToken); if (httpStatus.StatusCode != 200 && !httpStatus.Description.EqualsIgnoreCase("OK") && !httpStatus.Description.EqualsIgnoreCase("Connection Established")) { throw new Exception("Upstream proxy failed to create a secure tunnel"); } await stream.ReadAndIgnoreAllLinesAsync(cancellationToken); } if (isHttps) { var sslStream = new SslStream(stream, false, proxyServer.ValidateServerCertificate, proxyServer.SelectClientCertificate); stream = new HttpServerStream(sslStream, proxyServer.BufferPool); var options = new SslClientAuthenticationOptions { ApplicationProtocols = applicationProtocols, TargetHost = remoteHostName, ClientCertificates = null !, EnabledSslProtocols = enabledSslProtocols, CertificateRevocationCheckMode = proxyServer.CheckCertificateRevocation }; await sslStream.AuthenticateAsClientAsync(options, cancellationToken); #if NETSTANDARD2_1 negotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol; #endif if (session != null) { session.TimeLine["HTTPS Established"] = DateTime.Now; } } } catch (IOException ex) when(ex.HResult == unchecked ((int)0x80131620) && retry && enabledSslProtocols >= SslProtocols.Tls11) { stream?.Dispose(); tcpClient?.Close(); enabledSslProtocols = SslProtocols.Tls; retry = false; goto retry; } catch (Exception) { stream?.Dispose(); tcpClient?.Close(); throw; } return(new TcpServerConnection(proxyServer, tcpClient, stream, remoteHostName, remotePort, isHttps, negotiatedApplicationProtocol, httpVersion, externalProxy, upStreamEndPoint, cacheKey)); }
protected IObservable <string> CreateObservable(Endpoint endpoint, HttpHeader header, string body = "") => createObservable(endpoint, new[] { header }, body, Task.FromResult);
public (HttpHeader Header, string Body) GetResponse(string url) { Uri theURL = new Uri(url); Console.OutputEncoding = Encoding.UTF8; HttpHeader receiverHeader; Byte[] buffer = new Byte[1]; using (Socket bannerGrabSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { bannerGrabSocket.ReceiveTimeout = 5000; bannerGrabSocket.SendTimeout = 5000; try { var result = bannerGrabSocket.BeginConnect(theURL.Host, 80, null, null); // Error if an invalid IP bool success = result.AsyncWaitHandle.WaitOne(5000, true); if (success) { // It got a reply if (bannerGrabSocket.Connected) { // And that reply is that it's open! string header = "GET " + theURL.AbsolutePath + " HTTP/1.1" + Environment.NewLine; header += "Host: " + theURL.Host + Environment.NewLine; header += "User-Agent: curl/7.55.1" + Environment.NewLine; header += "Accept: */*" + Environment.NewLine; header += Environment.NewLine; Byte[] cmdBytes = Encoding.ASCII.GetBytes(header.ToCharArray()); bannerGrabSocket.Send(cmdBytes, cmdBytes.Length, 0); string headerString = ""; string bodyString = ""; byte[] bodyBuff = new byte[0]; while (true) { bannerGrabSocket.Receive(buffer, 0, 1, 0); headerString += Encoding.ASCII.GetString(buffer); if (headerString.Contains("\r\n\r\n")) { // header is received, parsing content length receiverHeader = new HttpHeader(headerString); if (headerString.Contains("Content-Length:")) { Regex reg = new Regex("\\\r\nContent-Length: (.*?)\\\r\n"); // :| Match m = reg.Match(headerString); int contentLength = int.Parse(m.Groups[1].ToString()); // read the body bodyBuff = new byte[contentLength]; bannerGrabSocket.Receive(bodyBuff, 0, contentLength, 0); bodyString = Encoding.ASCII.GetString(bodyBuff); } else if (headerString.Contains("Transfer-Encoding: chunked")) { int chunkSize = -1; string chunkedIntData = ""; string chunkedString = ""; while (chunkSize != 0) { chunkedIntData = ""; while (true) { bannerGrabSocket.Receive(buffer, 0, 1, 0); chunkedIntData += Encoding.ASCII.GetString(buffer); if (chunkedIntData.EndsWith("\r\n")) { chunkedIntData = chunkedIntData.Trim("\r\n".ToCharArray()); try { chunkSize = int.Parse(chunkedIntData, System.Globalization.NumberStyles.HexNumber); } catch (Exception ex) { Console.WriteLine("Error - ReeWebClient.GetResponse.ChunkSizeException: Unable to parse chunk size: " + chunkedIntData); return(null, "Error - ReeWebClient.GetResponse.ChunkSizeException: Unable to parse chunk size: " + chunkedIntData); } // Console.WriteLine(chunkSize); bodyBuff = new byte[chunkSize]; for (int j = 0; j < chunkSize; j++) { bannerGrabSocket.Receive(bodyBuff, j, 1, 0); } bodyString += Encoding.UTF8.GetString(bodyBuff); bannerGrabSocket.Receive(new byte[2], 0, 2, 0); break; } } } // Console.WriteLine("Found a Chunk Size of 0! Ending..."); } else { Console.WriteLine("Error - ReeWebClient.GetResponse.MalformedHeaderException: " + headerString); return(null, "Error - ReeWebClient.GetResponse.MalformedHeaderException: " + headerString); } break; } } // End - Now deal! bannerGrabSocket.Close(); // Response contains header, 2 new lines, then the body return(receiverHeader, bodyString); } else { // And that reply is that it's closed bannerGrabSocket.Close(); return(null, "Reecon - Closed"); } } else { // Failed - Probably timed out bannerGrabSocket.Close(); return(null, "Reecon - Closed"); } } catch (SocketException ex) { Console.WriteLine("Error - ReeWebClient.GetResponse.SocketException: " + ex.Message); return(null, "Error - ReeWebClient.GetResponse.SocketException: " + ex.Message); } catch (Exception ex) { Console.WriteLine("Error - ReeWebClient.GetResponse.Exception: " + ex.Message); return(null, "Error - ReeWebClient.GetResponse.Exception: " + ex.Message); } finally { bannerGrabSocket.Close(); } } }
/// <summary> /// Only to get Api Server public key, by sending JEdixWin Client Name /// </summary> /// <param name="token"></param> /// <returns></returns> public static async Task <bool> ExchangePublicKey(CancellationToken token = new CancellationToken()) { using (var clientKeyExchange = new AparteHttpClient(WinClient.ApiServiceUri, HttpHeader.ExchangePublicKeyHeader())) { var content = JsonSerializer.GetStringContent(new { Name = KeyFile.JEDIX_WIN_CLIENT_NAME }); using (var response = await clientKeyExchange.PostAsync("api/Account/ExchangePublicKeys", content, token).ConfigureAwait(false)) { if (response.IsSuccessStatusCode) { var jwsString = await response.Content.ReadAsStringAsync(); var jws = JWT.ParseFromBase64Url(jwsString); WinClient.ServerPublicKey = jws[JWTConstant.CLAIM_PUBLIC_KEY]; } } } return(ApiClient.WinClient.IsClientAuthorized); }
/// <summary> /// Important Step to get verified if this JEdixWin is authentic by Api Server. /// PKI Encrypted Header is created by HttpHeader.VerifyClientHeader(ServerPublicKey) /// which contains KeyFile.JEDIX_WIN_CLIENT_SECRET encrypted by ServerPublicKey /// </summary> /// <param name="token"></param> /// <returns></returns> public static async Task <bool> VerifyClient(CancellationToken token = new CancellationToken()) { if (!WinClient.IsClientAuthorized) { using (var clientKeyExchange = new AparteHttpClient(WinClient.ApiServiceUri, HttpHeader.VerifyClientHeader(WinClient.ServerPublicKey))) { var content = JsonSerializer.GetStringContent(null); using (var response = await clientKeyExchange.PostAsync("api/Account/VerifyClient", content, token).ConfigureAwait(false)) { if (response.IsSuccessStatusCode) { var jwsString = await response.Content.ReadAsStringAsync(); var jws = JWEAsymmetric.Parse(jwsString.Replace("\"", ""), WinClient.PRIVATE_KEY); WinClient.SharedSymmetricKey = jws[JWTConstant.CLAIM_SYMMETRIC_KEY]; WinClient.IsClientAuthorized = true; } else { WinClient.IsClientAuthorized = false; } } } } return(WinClient.IsClientAuthorized); }
/// <summary> /// Handle windows NTLM authentication /// Can expand this for Kerberos in future /// Note: NTLM/Kerberos cannot do a man in middle operation /// we do for HTTPS requests. /// As such we will be sending local credentials of current /// User to server to authenticate requests. /// To disable this set ProxyServer.EnableWinAuth to false /// </summary> internal async Task <bool> Handle401UnAuthorized(SessionEventArgs args) { string headerName = null; HttpHeader authHeader = null; //check in non-unique headers first var header = args.WebSession.Response.ResponseHeaders.NonUniqueHeaders.FirstOrDefault( x => authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase))); if (!header.Equals(new KeyValuePair <string, List <HttpHeader> >())) { headerName = header.Key; } if (headerName != null) { authHeader = args.WebSession.Response.ResponseHeaders.NonUniqueHeaders[headerName] .FirstOrDefault(x => authSchemes.Any(y => x.Value.StartsWith(y, StringComparison.OrdinalIgnoreCase))); } //check in unique headers if (authHeader == null) { //check in non-unique headers first var uHeader = args.WebSession.Response.ResponseHeaders.Headers.FirstOrDefault(x => authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase))); if (!uHeader.Equals(new KeyValuePair <string, HttpHeader>())) { headerName = uHeader.Key; } if (headerName != null) { authHeader = authSchemes.Any(x => args.WebSession.Response.ResponseHeaders.Headers[headerName].Value .StartsWith(x, StringComparison.OrdinalIgnoreCase)) ? args.WebSession.Response.ResponseHeaders.Headers[headerName] : null; } } if (authHeader != null) { string scheme = authSchemes.FirstOrDefault(x => authHeader.Value.Equals(x, StringComparison.OrdinalIgnoreCase)); //clear any existing headers to avoid confusing bad servers if (args.WebSession.Request.RequestHeaders.NonUniqueHeaders.ContainsKey("Authorization")) { args.WebSession.Request.RequestHeaders.NonUniqueHeaders.Remove("Authorization"); } //initial value will match exactly any of the schemes if (scheme != null) { string clientToken = WinAuthHandler.GetInitialAuthToken(args.WebSession.Request.Host, scheme, args.Id); var auth = new HttpHeader("Authorization", string.Concat(scheme, clientToken)); //replace existing authorization header if any if (args.WebSession.Request.RequestHeaders.Headers.ContainsKey("Authorization")) { args.WebSession.Request.RequestHeaders.Headers["Authorization"] = auth; } else { args.WebSession.Request.RequestHeaders.Headers.Add("Authorization", auth); } //don't need to send body for Authorization request if (args.WebSession.Request.HasBody) { args.WebSession.Request.ContentLength = 0; } } //challenge value will start with any of the scheme selected else { scheme = authSchemes.FirstOrDefault(x => authHeader.Value.StartsWith(x, StringComparison.OrdinalIgnoreCase) && authHeader.Value.Length > x.Length + 1); string serverToken = authHeader.Value.Substring(scheme.Length + 1); string clientToken = WinAuthHandler.GetFinalAuthToken(args.WebSession.Request.Host, serverToken, args.Id); //there will be an existing header from initial client request args.WebSession.Request.RequestHeaders.Headers["Authorization"] = new HttpHeader("Authorization", string.Concat(scheme, clientToken)); //send body for final auth request if (args.WebSession.Request.HasBody) { args.WebSession.Request.ContentLength = args.WebSession.Request.RequestBody.Length; } } //Need to revisit this. //Should we cache all Set-Cokiee headers from server during auth process //and send it to client after auth? //clear current server response await args.ClearResponse(); //request again with updated authorization header //and server cookies bool disposed = await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args, false); return(disposed); } return(false); }
protected virtual void AddRequestHeaders(HttpRequestMessage webRequest, HttpHeader headers) { foreach (var header in headers) { switch (header.Key) { case "Accept": webRequest.Headers.Accept.ParseAdd(header.Value); break; case "Connection": webRequest.Headers.Connection.Clear(); webRequest.Headers.Connection.Add(header.Value); break; case "Content-Length": AddContentHeader(webRequest, "Content-Length", header.Value); break; case "Content-Type": AddContentHeader(webRequest, "Content-Type", header.Value); break; case "Date": webRequest.Headers.Remove("Date"); webRequest.Headers.Date = HttpHeader.ParseDateTime(header.Value); break; case "Expect": webRequest.Headers.Expect.ParseAdd(header.Value); break; case "Host": webRequest.Headers.Host = header.Value; break; case "If-Modified-Since": webRequest.Headers.IfModifiedSince = HttpHeader.ParseDateTime(header.Value); break; case "Referer": webRequest.Headers.Add("Referer", header.Value); break; case "Transfer-Encoding": webRequest.Headers.TransferEncoding.ParseAdd(header.Value); break; case "User-Agent": webRequest.Headers.UserAgent.ParseAdd(header.Value); break; case "Proxy-Connection": throw new NotImplementedException(); default: webRequest.Headers.Add(header.Key, header.Value); break; } } }
/// <summary> /// Добавляет временный HTTP-заголовок запроса. Такой заголовок перекрывает заголовок установленный через индексатор. /// </summary> /// <param name="header">HTTP-заголовок.</param> /// <param name="value">Значение HTTP-заголовка.</param> /// <exception cref="System.ArgumentNullException">Значение параметра <paramref name="value"/> равно <see langword="null"/>.</exception> /// <exception cref="System.ArgumentException"> /// Значение параметра <paramref name="value"/> является пустой строкой. /// -или- /// Установка значения HTTP-заголовка, который должен задаваться с помощью специального свойства/метода. /// </exception> /// <remarks>Данный HTTP-заголовок будет стёрт после первого запроса.</remarks> public HttpRequest AddHeader(HttpHeader header, string value) { AddHeader(Http.Headers[header], value); return this; }
protected IObservable <List <TInterface> > CreateListObservable <TModel, TInterface>(Endpoint endpoint, HttpHeader header, List <TModel> entities, SerializationReason serializationReason, IWorkspaceFeatureCollection features = null) where TModel : class, TInterface { var body = serializer.Serialize(entities, serializationReason, features); return(CreateListObservable <TModel, TInterface>(endpoint, header, body)); }
/// <summary> /// Возвращает или задаёт значение HTTP-заголовка. /// </summary> /// <param name="header">HTTP-заголовок.</param> /// <value>Значение HTTP-заголовка, если он задан, иначе пустая строка. Если задать значение <see langword="null"/> или пустую строку, то HTTP-заголовок будет удалён из списка.</value> /// <exception cref="System.ArgumentException">Установка значения HTTP-заголовка, который должен задаваться с помощью специального свойства/метода.</exception> /// <remarks>Список HTTP-заголовков, которые должны задаваться только с помощью специальных свойств/методов: /// <list type="table"> /// <item> /// <description>Accept-Encoding</description> /// </item> /// <item> /// <description>Content-Length</description> /// </item> /// <item> /// <description>Content-Type</description> /// </item> /// <item> /// <description>Cookie</description> /// </item> /// <item> /// <description>Connection</description> /// </item> /// <item> /// <description>Proxy-Connection</description> /// </item> /// <item> /// <description>Host</description> /// </item> /// </list> /// </remarks> public string this[HttpHeader header] { get { return this[Http.Headers[header]]; } set { this[Http.Headers[header]] = value; } }
protected IObservable <List <TInterface> > CreateListObservable <TModel, TInterface>(Endpoint endpoint, HttpHeader header, string body = "") where TModel : class, TInterface => CreateListObservable <TModel, TInterface>(endpoint, new[] { header }, body);