/// <summary> /// Used when creating generic requests /// </summary> internal RequestParameters(Context context, Method method, IResource resource, string protocolIdentifier = null, string viewName = null) { TraceId = context.InitialTraceId; Context = context; Method = method; Headers = new Headers(); iresource = resource; IsWebSocketUpgrade = Context.WebSocket?.Status == WebSocketStatus.Waiting; Uri = new URI { ResourceSpecifier = resource.Name, ViewName = viewName }; CachedProtocolProvider = ProtocolController.ResolveProtocolProvider(protocolIdentifier); }
/// <summary> /// Used when performing CheckOrigin /// </summary> internal RequestParameters(Context context, string uri, Headers headers) { TraceId = context.InitialTraceId; Context = context; Headers = headers ?? new Headers(); Uri = URI.ParseInternal(uri, PercentCharsEscaped(headers), context, out var cachedProtocolProvider); var hasMacro = Uri?.Macro != null; if (hasMacro) { if (Uri.Macro.OverwriteHeaders) { Uri.Macro.Headers?.ForEach(pair => Headers[pair.Key] = pair.Value); } else { Uri.Macro.Headers?.ForEach(pair => { var currentValue = Headers.SafeGet(pair.Key); if (string.IsNullOrWhiteSpace(currentValue) || currentValue == "*/*") { Headers[pair.Key] = pair.Value; } }); } } CachedProtocolProvider = cachedProtocolProvider; UnparsedUri = uri; try { var _ = IResource; } catch (Exception e) { Error = e.AsError(); } if (Error == null && Uri?.HasError == true) { Error = Uri.Error; } }
private async Task <IResult> _GetResult() { try { var sw = Stopwatch.StartNew(); var method = new HttpMethod(Method.ToString()); var message = new HttpRequestMessage(method, URI); switch (Method) { case Method.POST: case Method.PATCH: case Method.PUT: if (GetBody().HasContent) { message.Content = new StreamContent(GetBody().Stream); message.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(Headers.ContentType.ToString()); } break; } Headers.Metadata = "full"; Headers.ContentType = null; Headers.ForEach(header => message.Headers.Add(header.Key, header.Value)); var response = await HttpClient.SendAsync(message); switch (response?.StatusCode) { case null: case HttpStatusCode.GatewayTimeout: case HttpStatusCode.RequestTimeout: return(new Timeout(URI.ToString()).AsResultOf(this)); case HttpStatusCode.BadGateway: return(new BadGateway(URI.ToString()).AsResultOf(this)); } var responseHeaders = new Headers(); response.Headers.ForEach(header => responseHeaders[header.Key] = header.Value.FirstOrDefault()); response.Content.Headers.ForEach(header => responseHeaders[header.Key] = header.Value.FirstOrDefault()); var metadata = responseHeaders.Metadata?.Split(';'); if (metadata?.Length != 3) { return(new ExternalServiceNotRESTar(URI).AsResultOf(this)); } var(resultType, resourceName, data) = (metadata[0], metadata[1], metadata[2]); if (string.IsNullOrWhiteSpace(resultType)) { return(new ExternalServiceNotRESTar(URI).AsResultOf(this)); } RemoteResource = new RemoteResource(resourceName); var stream = default(RESTarStream); if (response.Content != null) { if (!(responseHeaders.ContentType is ContentType contentType)) { return(new ExternalServiceNotRESTar(URI).AsResultOf(this)); } var _stream = new RESTarStream(contentType); await response.Content.CopyToAsync(_stream); stream = _stream.Rewind(); } IResult getResult() { int nr; ErrorCodes ec; switch (resultType) { case nameof(Entities <object>) when ulong.TryParse(responseHeaders.EntityCount, out var count): return(new RemoteEntities(this, stream, count)); case nameof(Head) when int.TryParse(data, out nr): return(new Head(this, nr)); case nameof(Report) when int.TryParse(data, out nr): return(new Report(this, nr)); case nameof(Binary): return(new Binary(this, stream, responseHeaders.ContentType ?? ContentType.DefaultOutput)); case nameof(NoContent): return(new NoContent(this)); case nameof(InsertedEntities) when int.TryParse(data, out nr): return(new InsertedEntities(this, nr)); case nameof(UpdatedEntities) when int.TryParse(data, out nr): return(new UpdatedEntities(this, nr)); case nameof(DeletedEntities) when int.TryParse(data, out nr): return(new DeletedEntities(this, nr)); case nameof(SafePostedEntities) when data.TSplit(',') is var vt && int.TryParse(vt.Item1, out var upd) && int.TryParse(vt.Item2, out var ins): return(new SafePostedEntities(this, upd, ins)); case nameof(BadRequest) when Enum.TryParse(data, out ec): return(new RemoteBadRequest(ec)); case nameof(NotFound) when Enum.TryParse(data, out ec): return(new RemoteNotFound(ec)); case nameof(Forbidden) when Enum.TryParse(data, out ec): return(new RemoteForbidden(ec)); case nameof(Results.Internal) when Enum.TryParse(data, out ec): return(new RemoteInternal(ec)); case nameof(FeatureNotImplemented): return(new FeatureNotImplemented(null)); case nameof(InfiniteLoop): return(new InfiniteLoop()); case nameof(MethodNotAllowed): return(new MethodNotAllowed(Method, Resource, false)); case nameof(NotAcceptable): return(new NotAcceptable(Headers.Accept.ToString())); case nameof(UnsupportedContent): return(new UnsupportedContent(Headers.ContentType.ToString())); case nameof(UpgradeRequired): return(new UpgradeRequired(Resource.Name)); default: return(new RemoteOther(this, response.StatusCode, response.ReasonPhrase)); } } var result = getResult(); if (result is Error error) { result = error.AsResultOf(this); } responseHeaders.ForEach(result.Headers.Put); TimeElapsed = sw.Elapsed; return(result); } catch (Exception e) { return(new ExternalServiceNotRESTar(URI, e).AsResultOf(this)); } }
/// <summary> /// Used when creating parsed requests /// </summary> internal RequestParameters(Context context, Method method, string uri, byte[] body, Headers headers) { TraceId = context.InitialTraceId; Context = context; Method = method; Headers = headers ?? new Headers(); IsWebSocketUpgrade = Context.WebSocket?.Status == WebSocketStatus.Waiting; Uri = URI.ParseInternal(uri, PercentCharsEscaped(headers), context, out var cachedProtocolProvider); var hasMacro = Uri?.Macro != null; if (hasMacro) { if (Uri.Macro.OverwriteHeaders) { Uri.Macro.Headers?.ForEach(pair => Headers[pair.Key] = pair.Value); } else { Uri.Macro.Headers?.ForEach(pair => { var currentValue = Headers.SafeGet(pair.Key); if (string.IsNullOrWhiteSpace(currentValue) || currentValue == "*/*") { Headers[pair.Key] = pair.Value; } }); } } CachedProtocolProvider = cachedProtocolProvider; UnparsedUri = uri; if (Uri?.HasError == true) { Error = Uri.Error; return; } try { var _ = IResource; } catch (Exception e) { Error = e.AsError(); } if (hasMacro) { if (Uri.Macro.OverwriteBody) { if (Uri.Macro.HasBody) { BodyBytes = Uri.Macro.Body; Headers.ContentType = Providers.Json.ContentType; } } else { if (!(body?.Length > 0) && Uri.Macro.HasBody) { BodyBytes = Uri.Macro.Body; Headers.ContentType = Providers.Json.ContentType; } else { BodyBytes = body; } } } else { BodyBytes = body; } HasBody = BodyBytes?.Length > 0; }