public void ThrowWebServiceException <TResponse>(HttpResponseMessage httpRes, object request, string requestUri, object response) { if (log.IsDebugEnabled) { log.DebugFormat("Status Code : {0}", httpRes.StatusCode); log.DebugFormat("Status Description : {0}", httpRes.ReasonPhrase); } var serviceEx = new WebServiceException(httpRes.ReasonPhrase) { StatusCode = (int)httpRes.StatusCode, StatusDescription = httpRes.ReasonPhrase, ResponseHeaders = httpRes.Headers.ToWebHeaderCollection() }; try { var contentType = httpRes.GetContentType(); var bytes = GetResponseBytes(response); if (bytes != null) { if (string.IsNullOrEmpty(contentType) || contentType.MatchesContentType(ContentType)) { using (__requestAccess()) { var stream = MemoryStreamFactory.GetStream(bytes); serviceEx.ResponseBody = bytes.FromUtf8Bytes(); serviceEx.ResponseDto = JsonSerializer.DeserializeFromStream <TResponse>(stream); if (stream.CanRead) { stream.Dispose(); //alt ms throws when you dispose twice } } } else { serviceEx.ResponseBody = bytes.FromUtf8Bytes(); } } } catch (Exception innerEx) { // Oh, well, we tried throw new WebServiceException(httpRes.ReasonPhrase, innerEx) { StatusCode = (int)httpRes.StatusCode, StatusDescription = httpRes.ReasonPhrase, ResponseBody = serviceEx.ResponseBody }; } //Escape deserialize exception handling and throw here throw serviceEx; //var authEx = ex as AuthenticationException; //if (authEx != null) //{ // throw WebRequestUtils.CreateCustomException(requestUri, authEx); //} }
public HttpResult(byte[] responseBytes, string contentType) : this(null, contentType, HttpStatusCode.OK) { this.AllowsPartialResponse = true; this.ResponseStream = MemoryStreamFactory.GetStream(responseBytes); }
private Exception HandleResponseError <TResponse>(Exception exception, string url, object request) { var webEx = exception as WebException; if (PclExportClient.Instance.IsWebException(webEx)) { var errorResponse = (HttpWebResponse)webEx.Response; Log.Error(webEx); if (Log.IsDebugEnabled) { Log.Debug($"Status Code : {errorResponse.StatusCode}"); Log.Debug($"Status Description : {errorResponse.StatusDescription}"); } var serviceEx = new WebServiceException(errorResponse.StatusDescription) { StatusCode = (int)errorResponse.StatusCode, StatusDescription = errorResponse.StatusDescription, ResponseHeaders = errorResponse.Headers }; try { using var stream = errorResponse.ResponseStream(); var bytes = stream.ReadFully(); serviceEx.ResponseBody = bytes.FromUtf8Bytes(); var errorResponseType = WebRequestUtils.GetErrorResponseDtoType <TResponse>(request); if (stream.CanSeek) { PclExport.Instance.ResetStream(stream); serviceEx.ResponseDto = this.StreamDeserializer(errorResponseType, stream); } else //Android { using var ms = MemoryStreamFactory.GetStream(bytes); serviceEx.ResponseDto = this.StreamDeserializer(errorResponseType, ms); } return(serviceEx); } catch (Exception innerEx) { // Oh, well, we tried Log.Debug($"WebException Reading Response Error: {innerEx.Message}", innerEx); return(new WebServiceException(errorResponse.StatusDescription, innerEx) { StatusCode = (int)errorResponse.StatusCode, StatusDescription = errorResponse.StatusDescription, ResponseHeaders = errorResponse.Headers }); } } if (exception is AuthenticationException authEx) { var customEx = WebRequestUtils.CreateCustomException(url, authEx); Log.Debug($"AuthenticationException: {customEx.Message}", customEx); return(authEx); } Log.Debug($"Exception Reading Response Error: {exception.Message}", exception); return(exception); }
public string SerializeToString(IRequest req, object response) { var contentType = req.ResponseContentType; StreamSerializerDelegate responseStreamWriter; if (this.ContentTypeSerializers.TryGetValue(contentType, out responseStreamWriter) || this.ContentTypeSerializers.TryGetValue(ContentFormat.GetRealContentType(contentType), out responseStreamWriter)) { using (var ms = MemoryStreamFactory.GetStream()) { responseStreamWriter(req, response, ms); ms.Position = 0; var result = new StreamReader(ms, UTF8EncodingWithoutBom).ReadToEnd(); return(result); } } ResponseSerializerDelegate responseWriter; if (this.ContentTypeResponseSerializers.TryGetValue(contentType, out responseWriter) || this.ContentTypeResponseSerializers.TryGetValue(ContentFormat.GetRealContentType(contentType), out responseWriter)) { using (var ms = MemoryStreamFactory.GetStream()) { var httpRes = new HttpResponseStreamWrapper(ms, req) { KeepOpen = true, //Don't let view engines close the OutputStream }; responseWriter(req, response, httpRes); var bytes = ms.ToArray(); var result = bytes.FromUtf8Bytes(); return(result); } } var contentTypeAttr = ContentFormat.GetEndpointAttributes(contentType); switch (contentTypeAttr) { case RequestAttributes.Xml: return(XmlSerializer.SerializeToString(response)); case RequestAttributes.Json: return(JsonDataContractSerializer.Instance.SerializeToString(response)); case RequestAttributes.Jsv: return(TypeSerializer.SerializeToString(response)); #if !NETSTANDARD1_6 case RequestAttributes.Soap11: return(SoapHandler.SerializeSoap11ToBytes(req, response).FromUtf8Bytes()); case RequestAttributes.Soap12: return(SoapHandler.SerializeSoap12ToBytes(req, response).FromUtf8Bytes()); #endif } throw new NotSupportedException("ContentType not supported: " + contentType); }
public void PreAuthenticate(IRequest req, IResponse res) { if (req.OperationName != null && IgnoreForOperationTypes.Contains(req.OperationName)) { return; } var bearerToken = req.GetBearerToken() ?? req.GetCookieValue(Keywords.TokenCookie); if (bearerToken != null) { var parts = bearerToken.Split('.'); if (parts.Length == 3) { if (RequireSecureConnection && !req.IsSecureConnection) { throw HttpError.Forbidden(ErrorMessages.JwtRequiresSecureConnection); } var header = parts[0]; var payload = parts[1]; var signatureBytes = parts[2].FromBase64UrlSafe(); var headerJson = header.FromBase64UrlSafe().FromUtf8Bytes(); var payloadBytes = payload.FromBase64UrlSafe(); var headerData = headerJson.FromJson <Dictionary <string, string> >(); var bytesToSign = string.Concat(header, ".", payload).ToUtf8Bytes(); var algorithm = headerData["alg"]; //Potential Security Risk for relying on user-specified algorithm: https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/ if (RequireHashAlgorithm && algorithm != HashAlgorithm) { throw new NotSupportedException("Invalid algoritm '{0}', expected '{1}'".Fmt(algorithm, HashAlgorithm)); } if (!VerifyPayload(algorithm, bytesToSign, signatureBytes)) { return; } var payloadJson = payloadBytes.FromUtf8Bytes(); var jwtPayload = JsonObject.Parse(payloadJson); var session = CreateSessionFromPayload(req, jwtPayload); req.Items[Keywords.Session] = session; } else if (parts.Length == 5) //Encrypted JWE Token { if (RequireSecureConnection && !req.IsSecureConnection) { throw HttpError.Forbidden(ErrorMessages.JwtRequiresSecureConnection); } if (PrivateKey == null || PublicKey == null) { throw new NotSupportedException("PrivateKey is required to DecryptPayload"); } var jweHeaderBase64Url = parts[0]; var jweEncKeyBase64Url = parts[1]; var ivBase64Url = parts[2]; var cipherTextBase64Url = parts[3]; var tagBase64Url = parts[4]; var sentTag = tagBase64Url.FromBase64UrlSafe(); var aadBytes = (jweHeaderBase64Url + "." + jweEncKeyBase64Url).ToUtf8Bytes(); var iv = ivBase64Url.FromBase64UrlSafe(); var cipherText = cipherTextBase64Url.FromBase64UrlSafe(); var jweEncKey = jweEncKeyBase64Url.FromBase64UrlSafe(); var cryptAuthKeys256 = RsaUtils.Decrypt(jweEncKey, PrivateKey.Value, UseRsaKeyLength); var authKey = new byte[128 / 8]; var cryptKey = new byte[128 / 8]; Buffer.BlockCopy(cryptAuthKeys256, 0, authKey, 0, authKey.Length); Buffer.BlockCopy(cryptAuthKeys256, authKey.Length, cryptKey, 0, cryptKey.Length); using (var hmac = new HMACSHA256(authKey)) using (var encryptedStream = new MemoryStream()) { using (var writer = new BinaryWriter(encryptedStream)) { writer.Write(aadBytes); writer.Write(iv); writer.Write(cipherText); writer.Flush(); var calcTag = hmac.ComputeHash(encryptedStream.ToArray()); if (!calcTag.EquivalentTo(sentTag)) { return; } } } JsonObject jwtPayload; using (var aes = new AesManaged { KeySize = 128, BlockSize = 128, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 }) using (var decryptor = aes.CreateDecryptor(cryptKey, iv)) using (var ms = MemoryStreamFactory.GetStream(cipherText)) using (var cryptStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) { var jwtPayloadBytes = cryptStream.ReadFully(); jwtPayload = JsonObject.Parse(jwtPayloadBytes.FromUtf8Bytes()); } var session = CreateSessionFromPayload(req, jwtPayload); req.Items[Keywords.Session] = session; } } }
private async Task <T> SendWebRequestAsync <T>(string httpMethod, string absoluteUrl, object request, CancellationToken token, bool recall = false) { if (httpMethod == null) { throw new ArgumentNullException(nameof(httpMethod)); } this.PopulateRequestMetadata(request); var requestUri = absoluteUrl; var hasQueryString = request != null && !HttpUtils.HasRequestBody(httpMethod); if (hasQueryString) { var queryString = QueryStringSerializer.SerializeToString(request); if (!string.IsNullOrEmpty(queryString)) { requestUri += "?" + queryString; } } var webReq = this.CreateHttpWebRequest(requestUri); if (webReq != null && Proxy != null) { webReq.Proxy = Proxy; } var timedOut = false; ITimer timer = null; timer = PclExportClient.Instance.CreateTimer(state => { timedOut = true; webReq?.Abort(); webReq = null; timer?.Cancel(); timer = null; }, this.Timeout.GetValueOrDefault(DefaultTimeout), this); Exception ResolveException(Exception ex) { if (token.IsCancellationRequested) { return(new OperationCanceledException(token)); } if (timedOut) { return(PclExportClient.Instance.CreateTimeoutException(ex, "The request timed out")); } return(ex); } bool returningWebResponse = false; HttpWebResponse webRes = null; T Complete(T response) { timer.Cancel(); PclExportClient.Instance.SynchronizeCookies(this); ResultsFilterResponse?.Invoke(webRes, response, httpMethod, absoluteUrl, request); return(response); } webReq.Accept = ContentType; if (this.EmulateHttpViaPost) { webReq.Method = "POST"; webReq.Headers[HttpHeaders.XHttpMethodOverride] = httpMethod; } else { webReq.Method = httpMethod; } PclExportClient.Instance.AddHeader(webReq, Headers); PclExport.Instance.Config(webReq, userAgent: UserAgent); if (this.authInfo != null && !string.IsNullOrEmpty(this.UserName)) { webReq.AddAuthInfo(this.UserName, this.Password, authInfo); } else if (this.BearerToken != null) { webReq.Headers[HttpHeaders.Authorization] = "Bearer " + this.BearerToken; } else if (this.Credentials != null) { webReq.Credentials = this.Credentials; } else if (this.AlwaysSendBasicAuthHeader) { webReq.AddBasicAuth(this.UserName, this.Password); } if (!DisableAutoCompression) { PclExport.Instance.AddCompression(webReq); } ApplyWebRequestFilters(webReq); try { if (HttpUtils.HasRequestBody(webReq.Method)) { webReq.ContentType = ContentType; if (RequestCompressionType != null) { webReq.Headers[HttpHeaders.ContentEncoding] = RequestCompressionType; } using var requestStream = await webReq.GetRequestStreamAsync().ConfigAwait(); token.ThrowIfCancellationRequested(); if (request != null) { StreamSerializer(null, request, requestStream); } } } catch (Exception ex) { if (Log.IsDebugEnabled) { Log.Debug($"Error Sending Request: {ex.Message}", ex); } throw HandleResponseError <T>(ResolveException(ex), requestUri, request); } try { webRes = (HttpWebResponse)await webReq.GetResponseAsync().ConfigAwait(); { token.ThrowIfCancellationRequested(); ApplyWebResponseFilters(webRes); returningWebResponse = typeof(T) == typeof(HttpWebResponse); if (returningWebResponse) { return(Complete((T)(object)webRes)); } var responseStream = webRes.ResponseStream(); var responseBodyLength = webRes.ContentLength; var bufferRead = new byte[BufferSize]; var totalRead = 0; int read; var ms = MemoryStreamFactory.GetStream(); while ((read = await responseStream.ReadAsync(bufferRead, 0, bufferRead.Length, token).ConfigAwait()) != 0) { await ms.WriteAsync(bufferRead, 0, read, token).ConfigAwait(); totalRead += read; OnDownloadProgress?.Invoke(totalRead, responseBodyLength); } try { ms.Position = 0; if (typeof(T) == typeof(Stream)) { return(Complete((T)(object)ms)); } else { var stream = ms; try { if (typeof(T) == typeof(string)) { return(Complete((T)(object)await stream.ReadToEndAsync().ConfigAwait())); } else if (typeof(T) == typeof(byte[])) { return(Complete((T)(object)stream.ToArray())); } else { return(Complete((T)this.StreamDeserializer(typeof(T), stream))); } } finally { if (stream.CanRead) { stream.Dispose(); // Not yet disposed, but could've been. } } } } catch (Exception ex) { if (Log.IsDebugEnabled) { Log.Debug($"Error Reading Response Error: {ex.Message}", ex); } throw; } finally { responseStream.Close(); } } } catch (Exception ex) { var webEx = ex as WebException; var firstCall = !recall; if (firstCall && WebRequestUtils.ShouldAuthenticate(webEx, (!string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password)) || Credentials != null || BearerToken != null || RefreshToken != null || OnAuthenticationRequired != null)) { try { if (RefreshToken != null) { var refreshRequest = new GetAccessToken { RefreshToken = RefreshToken, UseTokenCookie = UseTokenCookie, }; var uri = this.RefreshTokenUri ?? this.BaseUri.CombineWith(refreshRequest.ToPostUrl()); GetAccessTokenResponse tokenResponse; try { tokenResponse = (await uri.PostJsonToUrlAsync(refreshRequest, requestFilter: req => { if (UseTokenCookie) { req.CookieContainer = CookieContainer; } }).ConfigAwait()).FromJson <GetAccessTokenResponse>(); } catch (WebException refreshEx) { var webServiceEx = ServiceClientBase.ToWebServiceException(refreshEx, stream => StreamDeserializer(typeof(T), stream), ContentType); if (webServiceEx != null) { throw new RefreshTokenException(webServiceEx); } throw new RefreshTokenException(refreshEx.Message, refreshEx); } var accessToken = tokenResponse?.AccessToken; var refreshClient = webReq = (HttpWebRequest)WebRequest.Create(requestUri); var tokenCookie = this.CookieContainer.GetTokenCookie(BaseUri); if (UseTokenCookie) { if (tokenCookie == null) { throw new RefreshTokenException("Could not retrieve new AccessToken Cooke from: " + uri); } refreshClient.CookieContainer.SetTokenCookie(BaseUri, tokenCookie); } else { if (string.IsNullOrEmpty(accessToken)) { throw new RefreshTokenException("Could not retrieve new AccessToken from: " + uri); } if (tokenCookie != null) { this.CookieContainer.SetTokenCookie(accessToken, BaseUri); refreshClient.CookieContainer.SetTokenCookie(BaseUri, accessToken); } else { refreshClient.AddBearerToken(this.BearerToken = accessToken); } } return(await SendWebRequestAsync <T>(httpMethod, absoluteUrl, request, token, recall : true).ConfigAwait()); } OnAuthenticationRequired?.Invoke(); var newReq = (HttpWebRequest)WebRequest.Create(requestUri); if (StoreCookies) { newReq.CookieContainer = CookieContainer; } HandleAuthException(ex, webReq); return(await SendWebRequestAsync <T>(httpMethod, absoluteUrl, request, token, recall : true).ConfigAwait()); } catch (WebServiceException) { throw; } catch (Exception /*subEx*/) { throw HandleResponseError <T>(ResolveException(ex), requestUri, request); } } if (ExceptionFilter != null && webEx?.Response != null) { var cachedResponse = ExceptionFilter(webEx, webEx.Response, requestUri, typeof(T)); if (cachedResponse is T variable) { return(variable); } } throw HandleResponseError <T>(ResolveException(ex), requestUri, request); } finally { if (!returningWebResponse) { webRes?.Dispose(); } } }
public static string CreateEncryptedJweToken(JsonObject jwtPayload, RSAParameters publicKey) { //From: http://self-issued.info/docs/draft-ietf-jose-json-web-encryption-09.html#RSACBCExample var jweHeader = new JsonObject { { "alg", "RSA-OAEP" }, { "enc", "A128CBC-HS256" }, { "kid", Convert.ToBase64String(publicKey.Modulus).Substring(0, 3) }, }; var jweHeaderBase64Url = jweHeader.ToJson().ToUtf8Bytes().ToBase64UrlSafe(); var authKey = new byte[128 / 8]; var cryptKey = new byte[128 / 8]; var cryptAuthKeys256 = AesUtils.CreateKey(); Buffer.BlockCopy(cryptAuthKeys256, 0, authKey, 0, authKey.Length); Buffer.BlockCopy(cryptAuthKeys256, authKey.Length, cryptKey, 0, cryptKey.Length); var aes = Aes.Create(); aes.KeySize = 128; aes.BlockSize = 128; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; using (aes) { aes.GenerateIV(); var iv = aes.IV; aes.Key = cryptKey; var jweEncKey = RsaUtils.Encrypt(cryptAuthKeys256, publicKey, UseRsaKeyLength); var jweEncKeyBase64Url = jweEncKey.ToBase64UrlSafe(); var ivBase64Url = iv.ToBase64UrlSafe(); var aad = jweHeaderBase64Url + "." + jweEncKeyBase64Url; var aadBytes = aad.ToUtf8Bytes(); var payloadBytes = jwtPayload.ToJson().ToUtf8Bytes(); using (var cipherStream = MemoryStreamFactory.GetStream()) using (var encrypter = aes.CreateEncryptor(cryptKey, iv)) using (var cryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write)) using (var writer = new BinaryWriter(cryptoStream)) { writer.Write(payloadBytes); cryptoStream.FlushFinalBlock(); using (var hmac = new HMACSHA256(authKey)) using (var encryptedStream = MemoryStreamFactory.GetStream()) using (var bw = new BinaryWriter(encryptedStream)) { bw.Write(aadBytes); bw.Write(iv); bw.Write(cipherStream.GetBuffer(), 0, (int)cipherStream.Length); bw.Flush(); var tag = hmac.ComputeHash(encryptedStream.GetBuffer(), 0, (int)encryptedStream.Length); var cipherTextBase64Url = cipherStream.ToBase64UrlSafe(); var tagBase64Url = tag.ToBase64UrlSafe(); var jweToken = jweHeaderBase64Url + "." + jweEncKeyBase64Url + "." + ivBase64Url + "." + cipherTextBase64Url + "." + tagBase64Url; return(jweToken); } } } }
public void PreAuthenticate(IRequest req, IResponse res) { if (req.OperationName != null && IgnoreForOperationTypes.Contains(req.OperationName)) { return; } var bearerToken = req.GetBearerToken() ?? req.GetCookieValue(Keywords.TokenCookie); if (bearerToken != null) { var parts = bearerToken.Split('.'); if (parts.Length == 3) { if (RequireSecureConnection && !req.IsSecureConnection) { throw HttpError.Forbidden(ErrorMessages.JwtRequiresSecureConnection); } var jwtPayload = GetVerifiedJwtPayload(parts); if (jwtPayload == null) //not verified { return; } if (ValidateToken != null) { if (!ValidateToken(jwtPayload, req)) { throw HttpError.Forbidden(ErrorMessages.TokenInvalid); } } var session = CreateSessionFromPayload(req, jwtPayload); req.Items[Keywords.Session] = session; } else if (parts.Length == 5) //Encrypted JWE Token { if (RequireSecureConnection && !req.IsSecureConnection) { throw HttpError.Forbidden(ErrorMessages.JwtRequiresSecureConnection); } if (PrivateKey == null || PublicKey == null) { throw new NotSupportedException("PrivateKey is required to DecryptPayload"); } var jweHeaderBase64Url = parts[0]; var jweEncKeyBase64Url = parts[1]; var ivBase64Url = parts[2]; var cipherTextBase64Url = parts[3]; var tagBase64Url = parts[4]; var sentTag = tagBase64Url.FromBase64UrlSafe(); var aadBytes = (jweHeaderBase64Url + "." + jweEncKeyBase64Url).ToUtf8Bytes(); var iv = ivBase64Url.FromBase64UrlSafe(); var cipherText = cipherTextBase64Url.FromBase64UrlSafe(); var jweEncKey = jweEncKeyBase64Url.FromBase64UrlSafe(); var cryptAuthKeys256 = RsaUtils.Decrypt(jweEncKey, PrivateKey.Value, UseRsaKeyLength); var authKey = new byte[128 / 8]; var cryptKey = new byte[128 / 8]; Buffer.BlockCopy(cryptAuthKeys256, 0, authKey, 0, authKey.Length); Buffer.BlockCopy(cryptAuthKeys256, authKey.Length, cryptKey, 0, cryptKey.Length); using (var hmac = new HMACSHA256(authKey)) using (var encryptedStream = new MemoryStream()) { using (var writer = new BinaryWriter(encryptedStream)) { writer.Write(aadBytes); writer.Write(iv); writer.Write(cipherText); writer.Flush(); var calcTag = hmac.ComputeHash(encryptedStream.ToArray()); if (!calcTag.EquivalentTo(sentTag)) { return; } } } JsonObject jwtPayload; var aes = Aes.Create(); aes.KeySize = 128; aes.BlockSize = 128; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; using (aes) using (var decryptor = aes.CreateDecryptor(cryptKey, iv)) using (var ms = MemoryStreamFactory.GetStream(cipherText)) using (var cryptStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) { var jwtPayloadBytes = cryptStream.ReadFully(); jwtPayload = JsonObject.Parse(jwtPayloadBytes.FromUtf8Bytes()); } if (ValidateToken != null) { if (!ValidateToken(jwtPayload, req)) { throw HttpError.Forbidden(ErrorMessages.TokenInvalid); } } var session = CreateSessionFromPayload(req, jwtPayload); req.Items[Keywords.Session] = session; } } }
public override async Task ProcessRequestAsync(IRequest httpReq, IResponse httpRes, string operationName) { if (page == null && pagePath != null) { var pages = httpReq.TryResolve<ITemplatePages>(); page = pages.GetPage(pagePath) ?? throw new FileNotFoundException($"Template Page not found '{pagePath}'"); if (!string.IsNullOrEmpty(layoutPath)) { layoutPage = pages.GetPage(layoutPath) ?? throw new FileNotFoundException($"Template Page not found '{layoutPath}'"); } } var args = httpReq.GetTemplateRequestParams(); if (Args != null) { foreach (var entry in Args) { args[entry.Key] = entry.Value; } } var pageResult = new PageResult(page) { Args = args, LayoutPage = layoutPage, Model = Model, }; try { httpRes.ContentType = page.Format.ContentType; if (OutputStream != null) { await pageResult.WriteToAsync(OutputStream); } else { // Buffering improves perf when running behind a reverse proxy (recommended for .NET Core) using (var ms = MemoryStreamFactory.GetStream()) { await pageResult.WriteToAsync(ms); if (pageResult.Args.TryGetValue(TemplateConstants.Return, out var response)) { if (response is Task<object> responseTask) response = await responseTask; if (response is IRawString raw) response = raw.ToRawString(); if (response != null) { var httpResult = TemplateApiPagesService.ToHttpResult(pageResult, response); await httpRes.WriteToResponse(httpReq, httpResult); return; } } ms.Position = 0; await ms.WriteToAsync(httpRes.OutputStream); } } } catch (Exception ex) { await page.Format.OnViewException(pageResult, httpReq, ex); } }
internal static MemoryStream CreateBufferedStream(this IResponse response) { return(MemoryStreamFactory.GetStream()); }
public static void WriteQueryString(TextWriter writer, object value) { try { JsState.QueryStringMode = true; var i = 0; foreach (var propertyWriter in PropertyWriters) { var propertyValue = propertyWriter.GetterFn((T)value); if (propertyValue == null) { continue; } if (i++ > 0) { writer.Write('&'); } var propertyType = propertyValue.GetType(); var strValue = propertyValue as string; var isEnumerable = strValue == null && !propertyType.IsValueType() && propertyType.HasInterface(typeof(IEnumerable)); if (QueryStringSerializer.ComplexTypeStrategy != null && !isEnumerable && (propertyType.IsUserType() || propertyType.IsInterface())) { if (QueryStringSerializer.ComplexTypeStrategy(writer, propertyWriter.PropertyName, propertyValue)) { continue; } } Serializer.WritePropertyName(writer, propertyWriter.PropertyName); writer.Write('='); if (strValue != null) { writer.Write(strValue.UrlEncode()); } else if (!isEnumerable) { propertyWriter.WriteFn(writer, propertyValue); } else { //Trim brackets in top-level lists in QueryStrings, e.g: ?a=[1,2,3] => ?a=1,2,3 using (var ms = MemoryStreamFactory.GetStream()) { var enumerableWriter = new StreamWriter(ms); //ms disposed in using propertyWriter.WriteFn(enumerableWriter, propertyValue); enumerableWriter.Flush(); var output = ms.ToArray().FromUtf8Bytes(); output = output.Trim(ArrayBrackets); writer.Write(output); } } } } finally { JsState.QueryStringMode = false; } }