public HttpResult(byte[] responseBytes, string contentType) : this(null, contentType, HttpStatusCode.OK) { this.AllowsPartialResponse = true; this.ResponseStream = MemoryStreamFactory.GetStream(responseBytes); }
private void HandleResponseError <TResponse>(Exception exception, AsyncState <TResponse> state) { var webEx = exception as WebException; if (PclExportClient.Instance.IsWebException(webEx)) { var errorResponse = (HttpWebResponse)webEx.Response; Log.Error(webEx); if (Log.IsDebugEnabled) { Log.DebugFormat("Status Code : {0}", errorResponse.StatusCode); Log.DebugFormat("Status Description : {0}", errorResponse.StatusDescription); } var serviceEx = new WebServiceException(errorResponse.StatusDescription) { StatusCode = (int)errorResponse.StatusCode, StatusDescription = errorResponse.StatusDescription, ResponseHeaders = errorResponse.Headers }; try { using (var stream = errorResponse.GetResponseStream()) { var bytes = stream.ReadFully(); serviceEx.ResponseBody = bytes.FromUtf8Bytes(); var errorResponseType = WebRequestUtils.GetErrorResponseDtoType <TResponse>(state.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); } } state.HandleError(serviceEx.ResponseDto, serviceEx); } } catch (Exception innerEx) { // Oh, well, we tried Log.Debug(string.Format("WebException Reading Response Error: {0}", innerEx.Message), innerEx); state.HandleError(default(TResponse), new WebServiceException(errorResponse.StatusDescription, innerEx) { StatusCode = (int)errorResponse.StatusCode, StatusDescription = errorResponse.StatusDescription, ResponseHeaders = errorResponse.Headers }); } return; } var authEx = exception as AuthenticationException; if (authEx != null) { var customEx = WebRequestUtils.CreateCustomException(state.Url, authEx); Log.Debug(string.Format("AuthenticationException: {0}", customEx.Message), customEx); state.HandleError(default(TResponse), authEx); } Log.Debug(string.Format("Exception Reading Response Error: {0}", exception.Message), exception); state.HandleError(default(TResponse), exception); CancelAsyncFn = null; }
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); 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().ConfigureAwait(false)) { 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().ConfigureAwait(false); { 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).ConfigureAwait(false)) != 0) { ms.Write(bufferRead, 0, read); 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)stream.ReadToEnd())); } 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 }; var uri = this.RefreshTokenUri ?? this.BaseUri.CombineWith(refreshRequest.ToPostUrl()); GetAccessTokenResponse tokenResponse; try { tokenResponse = uri.PostJsonToUrl(refreshRequest) .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; if (string.IsNullOrEmpty(accessToken)) { throw new RefreshTokenException("Could not retrieve new AccessToken from: " + uri); } var refreshClient = webReq = (HttpWebRequest)WebRequest.Create(requestUri); if (this.CookieContainer.GetTokenCookie(BaseUri) != 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).ConfigureAwait(false)); } 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).ConfigureAwait(false)); } 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(); } } }
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 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 feature = HostContext.GetPlugin <TemplatePagesFeature>(); var args = httpReq.GetTemplateRequestParams(importRequestParams: feature.ImportRequestParams); 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); } }
public override MemoryStream ToMemoryStream(ReadOnlySpan <byte> source) => MemoryStreamFactory.GetStream(source.ToArray());
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); } } } }
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; } }
public static IMessage <T> ToMessage <T>(this BasicGetResult msgResult) { if (msgResult == null) { return(null); } var props = msgResult.BasicProperties; T body; if (string.IsNullOrEmpty(props.ContentType) || props.ContentType.MatchesContentType(MimeTypes.Json)) { var json = msgResult.Body.FromUtf8Bytes(); body = json.FromJson <T>(); } else { var deserializer = HostContext.ContentTypes.GetStreamDeserializer(props.ContentType); if (deserializer == null) { throw new NotSupportedException("Unknown Content-Type: " + props.ContentType); } var ms = MemoryStreamFactory.GetStream(msgResult.Body); body = (T)deserializer(typeof(T), ms); ms.Dispose(); } var message = new Message <T>(body) { Id = props.MessageId != null?Guid.Parse(props.MessageId) : new Guid(), CreatedDate = ((int)props.Timestamp.UnixTime).FromUnixTime(), Priority = props.Priority, ReplyTo = props.ReplyTo, Tag = msgResult.DeliveryTag.ToString(), RetryAttempts = msgResult.Redelivered ? 1 : 0, }; if (props.CorrelationId != null) { message.ReplyId = Guid.Parse(props.CorrelationId); } if (props.Headers != null) { foreach (var entry in props.Headers) { if (entry.Key == "Error") { var errors = entry.Value; if (errors != null) { var errorsJson = errors is byte[] errorBytes ? errorBytes.FromUtf8Bytes() : errors.ToString(); message.Error = errorsJson.FromJson <ResponseStatus>(); } } else { if (message.Meta == null) { message.Meta = new Dictionary <string, string>(); } var value = entry.Value is byte[] bytes ? bytes.FromUtf8Bytes() : entry.Value?.ToString(); message.Meta[entry.Key] = value; } } } return(message); }
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 async Task Any(EvalScript request) { var feature = HostContext.AssertPlugin <DesktopFeature>(); RequestUtils.AssertAccessRole(base.Request, accessRole: feature.AccessRole, authSecret: request.AuthSecret); var appHost = HostContext.AppHost; string script; var method = ((script = request.EvaluateScript) != null ? nameof(request.EvaluateScript) : (script = request.EvaluateCode) != null ? nameof(request.EvaluateCode) : (script = request.EvaluateLisp) != null ? nameof(request.EvaluateLisp) : (script = request.RenderScript) != null ? nameof(request.RenderScript) : (script = request.RenderCode) != null ? nameof(request.RenderCode) : (script = request.RenderLisp) != null ? nameof(request.RenderLisp) : null) ?? ((script = request.EvaluateScriptAsync) != null ? nameof(request.EvaluateScriptAsync) : (script = request.EvaluateCodeAsync) != null ? nameof(request.EvaluateCodeAsync) : (script = request.EvaluateLispAsync) != null ? nameof(request.EvaluateLispAsync) : (script = request.RenderScriptAsync) != null ? nameof(request.RenderScriptAsync) : (script = request.RenderCodeAsync) != null ? nameof(request.RenderCodeAsync) : (script = request.RenderLispAsync) != null ? nameof(request.RenderLispAsync) : null) ?? throw new ArgumentNullException(nameof(request.EvaluateCode)); async Task HandleExceptionAsync(Exception e) { log.Error(e.Message, e); base.Response.StatusCode = 500; base.Response.StatusDescription = e.GetType().Name; base.Response.ContentType = MimeTypes.PlainText; await base.Response.OutputStream.WriteAsync(MemoryProvider.Instance.ToUtf8(e.ToString().AsSpan())); await base.Response.EndRequestAsync(skipHeaders : true); } async Task SetResult(object value, string resultType = " result") { base.Response.ContentType = MimeTypes.Json; base.Response.StatusCode = 200; base.Response.StatusDescription = method + resultType; await base.Response.EndRequestAsync(skipHeaders : false, async res => { using var ms = MemoryStreamFactory.GetStream(); JsonSerializer.SerializeToStream(value, ms); ms.Position = 0; await ms.CopyToAsync(base.Response.OutputStream); }); } async Task SetOutput(PageResult result) { base.Response.StatusCode = 200; base.Response.StatusDescription = method + " result"; base.Response.ContentType = MimeTypes.PlainText; await base.Response.EndRequestAsync(skipHeaders : false, async res => { using var ms = MemoryStreamFactory.GetStream(); await result.RenderToStreamAsync(ms); ms.Position = 0; await ms.CopyToAsync(res.OutputStream); }); } var args = new Dictionary <string, object> { [ScriptConstants.Request] = base.Request, }; if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.EvaluateScript))) { await SetResult(await appHost.ScriptContext.EvaluateAsync(script, args)); } else if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.RenderScript))) { await SetOutput(new PageResult(appHost.ScriptContext.SharpScriptPage(script)).AssignArgs(args)); } else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.EvaluateCode))) { await SetResult(await appHost.ScriptContext.EvaluateCodeAsync(ScriptCodeUtils.EnsureReturn(script), args)); } else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.RenderCode))) { await SetOutput(new PageResult(appHost.ScriptContext.CodeSharpPage(script)).AssignArgs(args)); } else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.EvaluateLisp))) { await SetResult(await appHost.ScriptContext.EvaluateLispAsync(ScriptLispUtils.EnsureReturn(script), args)); } else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.RenderLisp))) { await SetOutput(new PageResult(appHost.ScriptContext.LispSharpPage(script)).AssignArgs(args)); } if (base.Response.IsClosed) { return; } async Task setResultAsync(Task <object> valueTask, string resultType = " result") { try { base.Response.ContentType = MimeTypes.Json; base.Response.StatusCode = 200; base.Response.StatusDescription = method + resultType; await base.Response.EndRequestAsync(skipHeaders : false, async res => { using var ms = MemoryStreamFactory.GetStream(); JsonSerializer.SerializeToStream(await valueTask, ms); await ms.CopyToAsync(base.Response.OutputStream); }); } catch (Exception e) { await HandleExceptionAsync(e); } } async Task setOutputAsync(PageResult result) { try { base.Response.StatusCode = 200; base.Response.StatusDescription = method + " async result"; base.Response.ContentType = MimeTypes.PlainText; await base.Response.EndRequestAsync(skipHeaders : false, async res => { using var ms = MemoryStreamFactory.GetStream(); await result.RenderToStreamAsync(ms); await ms.CopyToAsync(res.OutputStream); }); } catch (Exception e) { await HandleExceptionAsync(e); } } if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.EvaluateScriptAsync))) { await Task.Run(async() => await setResultAsync(appHost.ScriptContext.EvaluateAsync(script, args), " async result")); } else if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.RenderScriptAsync))) { await Task.Run(async() => await setOutputAsync(new PageResult(appHost.ScriptContext.SharpScriptPage(script)).AssignArgs(args))); } else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.EvaluateCodeAsync))) { await Task.Run(async() => await setResultAsync(appHost.ScriptContext.EvaluateCodeAsync(ScriptCodeUtils.EnsureReturn(script), args), " async result")); } else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.RenderCodeAsync))) { await Task.Run(async() => await setOutputAsync(new PageResult(appHost.ScriptContext.CodeSharpPage(script)).AssignArgs(args))); } else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.EvaluateLispAsync))) { await Task.Run(async() => await setResultAsync(appHost.ScriptContext.EvaluateLispAsync(ScriptLispUtils.EnsureReturn(script), args), " async result")); } else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.RenderLispAsync))) { await Task.Run(async() => await setOutputAsync(new PageResult(appHost.ScriptContext.LispSharpPage(script)).AssignArgs(args))); } else { throw new NotSupportedException($"Unsupported script API '{method}', supported: " + "EvaluateScript/Async, EvaluateCode/Async, EvaluateLisp/Async"); } }
public static void WriteQueryString(TextWriter writer, object instance) { try { JsState.QueryStringMode = true; var config = JsConfig <T> .GetConfig(); var i = 0; var typedInstance = (T)instance; foreach (var propertyWriter in PropertyWriters) { var propertyValue = propertyWriter.GetterFn(typedInstance); 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) { var nonEnumerableUserType = !isEnumerable && (propertyType.IsUserType() || propertyType.IsInterface); if (nonEnumerableUserType || propertyType.IsOrHasGenericInterfaceTypeOf(typeof(IDictionary <,>))) { if (QueryStringSerializer.ComplexTypeStrategy(writer, propertyWriter.GetPropertyName(config), propertyValue)) { continue; } } } Serializer.WritePropertyName(writer, propertyWriter.GetPropertyName(config)); 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.ReadToEnd(); output = output.Trim(ArrayBrackets); writer.Write(output); } } } } finally { JsState.QueryStringMode = false; } }
public override Stream OpenRead() { return(MemoryStreamFactory.GetStream(ByteContents ?? (TextContents ?? "").ToUtf8Bytes())); }
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; 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()); } var session = CreateSessionFromPayload(req, jwtPayload); req.Items[Keywords.Session] = session; } } }
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)); case RequestAttributes.Soap11: return(SoapHandler.SerializeSoap11ToBytes(req, response).FromUtf8Bytes()); case RequestAttributes.Soap12: return(SoapHandler.SerializeSoap12ToBytes(req, response).FromUtf8Bytes()); } throw new NotSupportedException("ContentType not supported: " + contentType); }
public async Task githubMarkdown(ScriptScopeContext scope, string markdownPath) { var file = Context.ProtectedMethods.ResolveFile(nameof(githubMarkdown), scope, markdownPath); var htmlFilePath = file.VirtualPath.LastLeftPart('.') + ".html"; var cacheKey = nameof(GitHubMarkdownScripts) + ">" + htmlFilePath; var htmlFile = Context.VirtualFiles.GetFile(htmlFilePath); if (htmlFile != null && htmlFile.LastModified >= file.LastModified) { if (UseMemoryCache) { byte[] bytes; if (!Context.Cache.TryGetValue(cacheKey, out object oBytes)) { using (var stream = htmlFile.OpenRead()) { var ms = MemoryStreamFactory.GetStream(); using (ms) { await stream.CopyToAsync(ms); ms.Position = 0; bytes = ms.ToArray(); Context.Cache[cacheKey] = bytes; } } } else { bytes = (byte[])oBytes; } scope.OutputStream.Write(bytes, 0, bytes.Length); } else { using (var htmlReader = htmlFile.OpenRead()) { await htmlReader.CopyToAsync(scope.OutputStream); } } } else { var ms = MemoryStreamFactory.GetStream(); using (ms) { using (var stream = file.OpenRead()) { await stream.CopyToAsync(ms); } ms.Position = 0; var bytes = ms.ToArray(); var htmlBytes = RepositoryContext == null ? await ApiBaseUrl.CombineWith("markdown", "raw") .PostBytesToUrlAsync(bytes, contentType: MimeTypes.PlainText, requestFilter: x => x.UserAgent = "#Script") : await ApiBaseUrl.CombineWith("markdown") .PostBytesToUrlAsync(new Dictionary <string, string> { { "text", bytes.FromUtf8Bytes() }, { "mode", Mode }, { "context", RepositoryContext } }.ToJson().ToUtf8Bytes(), contentType: MimeTypes.Json, requestFilter: x => x.UserAgent = "#Script"); var headerBytes = "<div class=\"gfm\">".ToUtf8Bytes(); var footerBytes = "</div>".ToUtf8Bytes(); var wrappedBytes = new byte[headerBytes.Length + htmlBytes.Length + footerBytes.Length]; System.Buffer.BlockCopy(headerBytes, 0, wrappedBytes, 0, headerBytes.Length); System.Buffer.BlockCopy(htmlBytes, 0, wrappedBytes, headerBytes.Length, htmlBytes.Length); System.Buffer.BlockCopy(footerBytes, 0, wrappedBytes, headerBytes.Length + htmlBytes.Length, footerBytes.Length); if (Context.VirtualFiles is IVirtualFiles vfs) { var fs = vfs.GetFileSystemVirtualFiles(); fs.DeleteFile(htmlFilePath); fs.WriteFile(htmlFilePath, wrappedBytes); } if (UseMemoryCache) { Context.Cache[cacheKey] = wrappedBytes; } await scope.OutputStream.WriteAsync(wrappedBytes, 0, wrappedBytes.Length); } } }
public override async Task ProcessRequestAsync(IRequest httpReq, IResponse httpRes, string operationName) { 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); } }
public void PreAuthenticate(IRequest req, IResponse res) { if (req.OperationName != null && IgnoreForOperationTypes.Contains(req.OperationName)) { return; } var bearerToken = req.GetJwtToken(); 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; } } }