public async void PathForApiType() { var api = new HttpApi<IPathForApi>(); var endpoint = api.Endpoints.Single().Value; var httpHandler = new MockHttpHandler(); await endpoint.Call(httpHandler, "http://localhost", new Dictionary<string, object> { ["key"] = "to" }); Assert.AreEqual("http://localhost/path/to/api", httpHandler.Request.Url.ToString()); }
public async Task ExportSyncMethod_CreatesRoute() { var sz = new JsonSerialiser(); using (var api = new HttpApi(sz, 9211)) { api.ExportSyncMethod(1, x => x * 12, "func1"); var url = new Uri(api.BaseEndpoint, "/func1/10"); var result = await api.TestRoute<int>(url); Assert.That(result, Is.EqualTo(120)); } }
public async Task Bind_To_PrimativeArgFunc_TestRoute() { var sz = new JsonSerialiser(); using (var api = new HttpApi(sz, 9211)) { api.Bind("/funcy/{i}").ToSyncronousMethod<int, int>(i => i * 5); var url = new Uri(api.BaseEndpoint, "/funcy/10"); var result = await api.TestRoute<int>(url); Assert.That(result, Is.EqualTo(50)); } }
public async Task ExportDefinedSyncMethod_CreatesRoute() { var sz = new JsonSerialiser(); using (var api = new HttpApi(sz, 9211)) { api.ExportSyncMethod(50, Functions.Random); var url = new Uri(api.BaseEndpoint, "/random/10"); var result = await api.TestRoute<int>(url); Assert.That(result, Is.AtLeast(0)); Assert.That(result, Is.AtMost(10)); } }
public async Task TestRoute_UndefinedRoute_Returns404() { var sz = new JsonSerialiser(); using (var api = new HttpApi(sz, 9211)) { var url = new Uri(api.BaseEndpoint, "/nothing/10"); try { var result = await api.TestRoute<int>(url); } catch (HttpException ex) { Assert.That(ex.Status, Is.EqualTo(HttpStatusCode.NotFound)); } } }
/// <summary> /// 绑定设备 /// </summary> /// <param name="deviceid"></param> /// <param name="userid"></param> /// <returns></returns> public static BaseModel BindDevice(int deviceid, int userid) { BaseModel bm = new BaseModel(); try { APIBindDeviceModel bdm = new APIBindDeviceModel(); bdm.DeviceId = deviceid; bdm.UserId = userid; bm = HttpApi.GetApiResult <DeviceCheckModel>("Device/BindDeviceForUser", bdm); ReadResource.ExecBack(bm, "BindDevice"); } catch (Exception ex) { LogHelper.ErrorLog(ex); return(new BaseModel { State = -1, Message = ex.Message }); } return(bm); }
/// <summary> /// 获取设备当前的健康数据 /// </summary> /// <param name="deviceId"></param> /// <returns></returns> public static HealthInfoModel GetHealthInfo(int deviceId) { APIHealthInfoModel model = new APIHealthInfoModel(); model.DeviceId = deviceId; model.TimeOffset = 8; HealthInfoModel hm = new HealthInfoModel(); try { hm = HttpApi.GetApiResult <HealthInfoModel>("Device/HealthInfo", model); ReadResource.ExecBack(hm, "HealthInfo"); } catch (Exception ex) { LogHelper.ErrorLog(ex); return(new HealthInfoModel { State = -1, Message = ex.Message }); } return(hm); }
public async Task Modifying_Request_Through_Cookie_Without_CSRF_Cookie_Is_Rejected(OrganizationRole role) { //Arrange var cookie = await HttpApi.GetCookieAsync(role); var itSystem = new { name = A <string>(), belongsToId = TestEnvironment.DefaultOrganizationId, organizationId = TestEnvironment.DefaultOrganizationId, AccessModifier = AccessModifier.Public }; var requestMessage = new HttpRequestMessage(HttpMethod.Post, TestEnvironment.CreateUrl("api/itsystem")) { Content = new StringContent(JsonConvert.SerializeObject(itSystem), Encoding.UTF8, "application/json") }; var cookieContainer = new CookieContainer(); cookieContainer.Add(cookie); var csrfToken = await HttpApi.GetCSRFToken(cookie); requestMessage.Headers.Add(Constants.CSRFValues.HeaderName, csrfToken.FormToken); //Act using (var client = new HttpClient(new HttpClientHandler { CookieContainer = cookieContainer })) { var response = await client.SendAsync(requestMessage); //Assert Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); } }
public async Task Can_Set_ContactPerson(OrganizationRole role) { //Arrange var login = await HttpApi.GetCookieAsync(role); const int organizationId = TestEnvironment.DefaultOrganizationId; var contactPersonDto = await OrganizationHelper.GetContactPersonAsync(organizationId); var name = A <string>(); var lastName = A <string>(); var email = A <string>(); var phone = A <string>(); //Act - perform the action with the actual role var result = await OrganizationHelper.ChangeContactPersonAsync(contactPersonDto.Id, organizationId, name, lastName, email, phone, login); //Assert Assert.Equal(contactPersonDto.Id, result.Id); Assert.Equal(email, result.Email); Assert.Equal(name, result.Name); Assert.Equal(lastName, result.LastName); Assert.Equal(phone, result.PhoneNumber); Assert.Equal(organizationId, result.OrganizationId); }
public async Task Can_Add_Stakeholder(OrganizationRole role) { //Arrange var login = await HttpApi.GetCookieAsync(role); var howToHandle = A <string>(); var name = A <string>(); var roleName = A <string>(); var downsides = howToHandle; var benefits = howToHandle; var significance = A <int>() % 5; //Act - perform the action with the actual role var result = await ItProjectHelper.AddStakeholderAsync(OrganizationId, _project.Id, name, roleName, downsides, benefits, howToHandle, significance, login); //Assert Assert.Equal(_project.Id, result.ItProjectId); Assert.Equal(name, result.Name); Assert.Equal(roleName, result.Role); Assert.Equal(downsides, result.Downsides); Assert.Equal(benefits, result.Benefits); Assert.Equal(howToHandle, result.HowToHandle); Assert.Equal(significance, result.Significance); }
public async Task Can_Add_Communication(OrganizationRole role) { //Arrange var login = await HttpApi.GetCookieAsync(role); var media = A <string>(); var message = A <string>(); var purpose = A <string>(); var targetAudience = A <string>(); var date = A <DateTime>().Date; var responsibleUserId = TestEnvironment.DefaultUserId; //Act - perform the action with the actual role var result = await ItProjectHelper.AddCommunicationAsync(OrganizationId, _project.Id, media, message, purpose, responsibleUserId, targetAudience, date, login); //Assert Assert.Equal(_project.Id, result.ItProjectId); Assert.Equal(media, result.Media); Assert.Equal(message, result.Message); Assert.Equal(purpose, result.Purpose); Assert.Equal(targetAudience, result.TargetAudiance); Assert.Equal(date, result.DueDate.GetValueOrDefault()); Assert.Equal(responsibleUserId, result.ResponsibleUserId.GetValueOrDefault()); }
public async Task Can_Add_MileStone(OrganizationRole role) { //Arrange var login = await HttpApi.GetCookieAsync(role); var description = A <string>(); var name = A <string>(); var note = A <string>(); var timeEstimate = A <int>(); var humanReadableId = A <string>(); var date = A <DateTime>().Date; //Act - perform the action with the actual role var result = await ItProjectHelper.AddMileStoneAsync(OrganizationId, _project.Id, description, name, note, humanReadableId, timeEstimate, date, login); //Assert Assert.Equal(_project.Id, result.AssociatedItProjectId.GetValueOrDefault()); Assert.Equal(description, result.Description); Assert.Equal(name, result.Name); Assert.Equal(note, result.Note); Assert.Equal(timeEstimate, result.TimeEstimate); Assert.Equal(date, result.Date.Value); Assert.Equal(humanReadableId, result.HumanReadableId); }
/* * 12.3 * HttpSendHttpResponse() and HttpSendResponseEntityBody() Flag Values. * The following flags can be used on calls to HttpSendHttpResponse() and HttpSendResponseEntityBody() API calls: * #define HTTP_SEND_RESPONSE_FLAG_DISCONNECT 0x00000001 #define HTTP_SEND_RESPONSE_FLAG_MORE_DATA 0x00000002 #define HTTP_SEND_RESPONSE_FLAG_RAW_HEADER 0x00000004 #define HTTP_SEND_RESPONSE_FLAG_VALID 0x00000007 * * HTTP_SEND_RESPONSE_FLAG_DISCONNECT: * specifies that the network connection should be disconnected immediately after * sending the response, overriding the HTTP protocol's persistent connection features. * HTTP_SEND_RESPONSE_FLAG_MORE_DATA: * specifies that additional entity body data will be sent by the caller. Thus, * the last call HttpSendResponseEntityBody for a RequestId, will have this flag reset. * HTTP_SEND_RESPONSE_RAW_HEADER: * specifies that a caller of HttpSendResponseEntityBody() is intentionally omitting * a call to HttpSendHttpResponse() in order to bypass normal header processing. The * actual HTTP header will be generated by the application and sent as entity body. * This flag should be passed on the first call to HttpSendResponseEntityBody, and * not after. Thus, flag is not applicable to HttpSendHttpResponse. */ // TODO: Consider using HTTP_SEND_RESPONSE_RAW_HEADER with HttpSendResponseEntityBody instead of calling HttpSendHttpResponse. // This will give us more control of the bytes that hit the wire, including encodings, HTTP 1.0, etc.. // It may also be faster to do this work in managed code and then pass down only one buffer. // What would we loose by bypassing HttpSendHttpResponse? // // TODO: Consider using the HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA flag for most/all responses rather than just Opaque. internal unsafe uint SendHeaders(HttpApiTypes.HTTP_DATA_CHUNK[]?dataChunks, ResponseStreamAsyncResult?asyncResult, HttpApiTypes.HTTP_FLAGS flags, bool isOpaqueUpgrade) { Debug.Assert(!HasStarted, "HttpListenerResponse::SendHeaders()|SentHeaders is true."); _responseState = ResponseState.Started; var reasonPhrase = GetReasonPhrase(StatusCode); uint statusCode; uint bytesSent; List <GCHandle>?pinnedHeaders = SerializeHeaders(isOpaqueUpgrade); try { if (dataChunks != null) { if (pinnedHeaders == null) { pinnedHeaders = new List <GCHandle>(); } var handle = GCHandle.Alloc(dataChunks, GCHandleType.Pinned); pinnedHeaders.Add(handle); _nativeResponse.Response_V1.EntityChunkCount = (ushort)dataChunks.Length; _nativeResponse.Response_V1.pEntityChunks = (HttpApiTypes.HTTP_DATA_CHUNK *)handle.AddrOfPinnedObject(); } else if (asyncResult != null && asyncResult.DataChunks != null) { _nativeResponse.Response_V1.EntityChunkCount = asyncResult.DataChunkCount; _nativeResponse.Response_V1.pEntityChunks = asyncResult.DataChunks; } else { _nativeResponse.Response_V1.EntityChunkCount = 0; _nativeResponse.Response_V1.pEntityChunks = null; } var cachePolicy = new HttpApiTypes.HTTP_CACHE_POLICY(); if (_cacheTtl.HasValue && _cacheTtl.Value > TimeSpan.Zero) { cachePolicy.Policy = HttpApiTypes.HTTP_CACHE_POLICY_TYPE.HttpCachePolicyTimeToLive; cachePolicy.SecondsToLive = (uint)Math.Min(_cacheTtl.Value.Ticks / TimeSpan.TicksPerSecond, Int32.MaxValue); } byte[] reasonPhraseBytes = HeaderEncoding.GetBytes(reasonPhrase); fixed(byte *pReasonPhrase = reasonPhraseBytes) { _nativeResponse.Response_V1.ReasonLength = (ushort)reasonPhraseBytes.Length; _nativeResponse.Response_V1.pReason = (byte *)pReasonPhrase; fixed(HttpApiTypes.HTTP_RESPONSE_V2 *pResponse = &_nativeResponse) { statusCode = HttpApi.HttpSendHttpResponse( RequestContext.Server.RequestQueue.Handle, Request.RequestId, (uint)flags, pResponse, &cachePolicy, &bytesSent, IntPtr.Zero, 0, asyncResult == null ? SafeNativeOverlapped.Zero : asyncResult.NativeOverlapped !, IntPtr.Zero); // GoAway is only supported on later versions. Retry. if (statusCode == ErrorCodes.ERROR_INVALID_PARAMETER && (flags & HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_GOAWAY) != 0) { flags &= ~HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_GOAWAY; statusCode = HttpApi.HttpSendHttpResponse( RequestContext.Server.RequestQueue.Handle, Request.RequestId, (uint)flags, pResponse, &cachePolicy, &bytesSent, IntPtr.Zero, 0, asyncResult == null ? SafeNativeOverlapped.Zero : asyncResult.NativeOverlapped !, IntPtr.Zero); // Succeeded without GoAway, disable them. if (statusCode != ErrorCodes.ERROR_INVALID_PARAMETER) { SupportsGoAway = false; } } if (asyncResult != null && statusCode == ErrorCodes.ERROR_SUCCESS && HttpSysListener.SkipIOCPCallbackOnSuccess) { asyncResult.BytesSent = bytesSent; // The caller will invoke IOCompleted } } } } finally { FreePinnedHeaders(pinnedHeaders); } return(statusCode); }
public async Task Bind_To_AnonymousMethodTwoParams_AndTestRoute() { var sz = new JsonSerialiser(); using (var api = new HttpApi(sz, 9211)) { api.Bind("/abc/{paramA}").To(new { paramA = 123, paramB = 16 }, a => Task.FromResult(new { x = a.paramA * 5, y = a.paramB * 4 })); var url = new Uri(api.BaseEndpoint, "/abc/44"); var result = await api.TestRoute(url, new { x = 0, y = 0 }); Assert.That(result.x, Is.EqualTo(220)); Assert.That(result.y, Is.EqualTo(16 * 4)); } }
public void EmptyPath() { var api = new HttpApi<IGetEmptyPath>(); Assert.AreEqual("http://localhost", api.Endpoints.Single().Value.Url.CreateUrl("http://localhost").ToString()); }
public AmadeusApi(HttpApi httpApi) : base(httpApi) { }
public async void MultipleQueryArguments() { var api = new HttpApi<IMultipeQueryArguments>(); var endpoint = api.Endpoints.Single().Value; var httpHandler = new MockHttpHandler(); await endpoint.Call(httpHandler, "http://localhost", new Dictionary<string, object> { ["ids"] = new[] { 1, 3 } }); Assert.AreEqual("http://localhost?ids=1&ids=3", httpHandler.Request.Url.ToString()); await endpoint.Call(httpHandler, "http://localhost", new Dictionary<string, object> { ["firstName"] = "John" }); Assert.AreEqual("http://localhost?firstName=John", httpHandler.Request.Url.ToString()); }
/// <summary> /// OAuth2的Token客户端 /// </summary> /// <param name="httpClientFactory"></param> /// <param name="httpApiOptionsMonitor"></param> public OAuth2TokenClient(IHttpClientFactory httpClientFactory, IOptionsMonitor <HttpApiOptions> httpApiOptionsMonitor) { this.httpClientFactory = httpClientFactory; this.httpApiOptions = httpApiOptionsMonitor.Get(HttpApi.GetName(typeof(OAuth2TokenClient))); }
public async Task Bind_To_DefinedFunc_TestRoute() { var sz = new JsonSerialiser(); using (var api = new HttpApi(sz, 9211)) { api.Bind("/factorial/{x}").ToSyncronousMethod<int, long>(Functions.Factorial); var url = new Uri(api.BaseEndpoint, "/factorial/10"); var expected = Functions.Factorial(10); Console.WriteLine("Expecting {0}", expected); var result = await api.TestRoute<long>(url); Assert.That(result, Is.EqualTo(expected)); } }
internal ApigwHttpApiEventbridgeDotnetCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { var eventBus = new EventBus(this, "MyEventBus", new EventBusProps { EventBusName = "MyEventBus" }); // Logging var eventLoggerRule = new Rule(this, "EventLoggerRule", new RuleProps { Description = "Log all events", EventPattern = new EventPattern { Region = new string[] { "us-west-2" } }, EventBus = eventBus }); var logGroup = new LogGroup(this, "EventLogGroup", new LogGroupProps { LogGroupName = "/aws/events/MyEventBus", }); eventLoggerRule.AddTarget(new EventTargets.CloudWatchLogGroup(logGroup)); // API var httpApi = new HttpApi(this, "MyHttpApi"); // There"s no Eventbridge integration available as CDK L2 yet, so we have to use L1 and create Role, Integration and Route var apiRole = new Role(this, "EventBridgeIntegrationRole", new RoleProps { AssumedBy = new ServicePrincipal("apigateway.amazonaws.com"), }); apiRole.AddToPolicy( new PolicyStatement(new PolicyStatementProps { Effect = Effect.ALLOW, Resources = new string[] { eventBus.EventBusArn }, Actions = new string[] { "events:PutEvents" }, }) ); var eventbridgeIntegration = new CfnIntegration( this, "EventBridgeIntegration", new CfnIntegrationProps { ApiId = httpApi.HttpApiId, IntegrationType = "AWS_PROXY", IntegrationSubtype = "EventBridge-PutEvents", CredentialsArn = apiRole.RoleArn, RequestParameters = new Dictionary <string, object> { ["Source"] = "WebApp", ["DetailType"] = "MyDetailType", ["Detail"] = "$request.body", ["EventBusName"] = eventBus.EventBusArn }, PayloadFormatVersion = "1.0", TimeoutInMillis = 10000, } ); new CfnRoute(this, "EventRoute", new CfnRouteProps { ApiId = httpApi.HttpApiId, RouteKey = "POST /", Target = $"integrations/{eventbridgeIntegration.Ref}", }); new CfnOutput(this, "apiUrl", new CfnOutputProps { Value = httpApi.Url !, Description = "HTTP API endpoint URL" });
protected async Task <(RepositoryResult result, dynamic body)> PostAsync(HttpApi api, object query = null) { var response = await api.PostAsync(query); return(await this.CreateResultAsync(response)); }
public AirportCodeFinder(HttpApi httpApi) : base(httpApi) { }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true)); string getUrlHttp = Configuration.GetValue <string>("IServerApiURL"); HttpApi.Register <IServerApi>().ConfigureHttpApiConfig(c => { c.HttpHost = new Uri(getUrlHttp); c.FormatOptions.DateTimeFormat = DateTimeFormats.ISO8601_WithMillisecond; }); services.AddHttpClient <IServerApi>().AddTypedClient <IServerApi>((client, p) => { return(HttpApi.Resolve <IServerApi>()); }); //autoMap var myAssembly = "ManageServerClient.Web.Blazor"; var configautoMap = new MapperConfiguration(cfg => { cfg.AddMaps(myAssembly); }); services.AddScoped <ClientWebSocket>(); services.AddSingleton(configautoMap); services.AddSingleton <AutoMapService>(); services.AddSingleton <WeatherForecastService>(); services.AddSingleton <NotifierService>(); services.AddRazorPages(); services.AddServerSideBlazor(); services.AddMvc(options => { // 添加全局异常 options.Filters.Add <HttpResponseExceptionFilter>(); });//.SetCompatibilityVersion(CompatibilityVersion.Version_3_0); ; //禁用默认行为 services.Configure <ApiBehaviorOptions>(options => { //options.SuppressModelStateInvalidFilter = true; options.InvalidModelStateResponseFactory = (context) => { var error = context.ModelState; try { var errmsgs = new List <string>(); foreach (var item in error.Values) { errmsgs.Add(item.Errors.First().ErrorMessage); } int allCount = 0; var ErrorDic = new List <ErrorInfo>(); foreach (var item in error.Keys) { var itemSplit = item.Split('.'); string key = item; if (itemSplit.Length > 1) { key = itemSplit[1]; } ErrorDic.Add(new ErrorInfo() { Name = key, Message = errmsgs[allCount] }); allCount++; } var result = new ResponseObject <object>() { errcode = -1, errinfo = $"参数验证不通过", errbody = ErrorDic }; return(new JsonResult(result)); } catch (Exception) { var result = new ResponseObject <object>() { errcode = -1, errinfo = $"参数验证不通过", errbody = error }; return(new JsonResult(result)); } }; }); }
private RequestQueue(UrlGroup?urlGroup, string?requestQueueName, RequestQueueMode mode, ILogger logger, bool receiver) { _mode = mode; UrlGroup = urlGroup; _logger = logger; var flags = HttpApiTypes.HTTP_CREATE_REQUEST_QUEUE_FLAG.None; Created = true; if (_mode == RequestQueueMode.Attach) { flags = HttpApiTypes.HTTP_CREATE_REQUEST_QUEUE_FLAG.OpenExisting; Created = false; if (receiver) { flags |= HttpApiTypes.HTTP_CREATE_REQUEST_QUEUE_FLAG.Delegation; } } var statusCode = HttpApi.HttpCreateRequestQueue( HttpApi.Version, requestQueueName, null, flags, out var requestQueueHandle); if (_mode == RequestQueueMode.CreateOrAttach && statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_ALREADY_EXISTS) { // Tried to create, but it already exists so attach to it instead. Created = false; flags = HttpApiTypes.HTTP_CREATE_REQUEST_QUEUE_FLAG.OpenExisting; statusCode = HttpApi.HttpCreateRequestQueue( HttpApi.Version, requestQueueName, null, flags, out requestQueueHandle); } if (flags.HasFlag(HttpApiTypes.HTTP_CREATE_REQUEST_QUEUE_FLAG.OpenExisting) && statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_FILE_NOT_FOUND) { throw new HttpSysException((int)statusCode, $"Failed to attach to the given request queue '{requestQueueName}', the queue could not be found."); } else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_INVALID_NAME) { throw new HttpSysException((int)statusCode, $"The given request queue name '{requestQueueName}' is invalid."); } else if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { throw new HttpSysException((int)statusCode); } // Disabling callbacks when IO operation completes synchronously (returns ErrorCodes.ERROR_SUCCESS) if (HttpSysListener.SkipIOCPCallbackOnSuccess && !UnsafeNclNativeMethods.SetFileCompletionNotificationModes( requestQueueHandle, UnsafeNclNativeMethods.FileCompletionNotificationModes.SkipCompletionPortOnSuccess | UnsafeNclNativeMethods.FileCompletionNotificationModes.SkipSetEventOnHandle)) { requestQueueHandle.Dispose(); throw new HttpSysException(Marshal.GetLastWin32Error()); } Handle = requestQueueHandle; BoundHandle = ThreadPoolBoundHandle.BindHandle(Handle); if (!Created) { Log.AttachedToQueue(_logger, requestQueueName); } }
public MainForm() { nsManager = new HttpApi(); InitializeComponent(); }
public SkyscannerApi(HttpApi httpApi, ILocationHandler locationHandler) : base(httpApi) { this.locationHandler = locationHandler; }
/// <summary> /// 为接口配置HttpApiOptions /// </summary> /// <param name="services"></param> /// <param name="httpApiType">接口类型</param> /// <returns></returns> private static OptionsBuilder <HttpApiOptions> AddHttpApiOptions(this IServiceCollection services, Type httpApiType) { var name = HttpApi.GetName(httpApiType); return(services.AddOptions <HttpApiOptions>(name)); }
// Simpler than Flush because it will never be called at the end of the request from Dispose. private unsafe Task FlushInternalAsync(ArraySegment <byte> data, CancellationToken cancellationToken) { if (_skipWrites) { return(Task.CompletedTask); } var started = _requestContext.Response.HasStarted; if (data.Count == 0 && started) { // No data to send and we've already sent the headers return(Task.CompletedTask); } if (cancellationToken.IsCancellationRequested) { Abort(ThrowWriteExceptions); return(Task.FromCanceled <int>(cancellationToken)); } // Make sure all validation is performed before this computes the headers var flags = ComputeLeftToWrite(data.Count); uint statusCode; var chunked = _requestContext.Response.BoundaryType == BoundaryType.Chunked; var asyncResult = new ResponseStreamAsyncResult(this, data, chunked, cancellationToken); uint bytesSent = 0; try { if (!started) { statusCode = _requestContext.Response.SendHeaders(null, asyncResult, flags, false); bytesSent = asyncResult.BytesSent; } else { statusCode = HttpApi.HttpSendResponseEntityBody( RequestQueueHandle, RequestId, (uint)flags, asyncResult.DataChunkCount, asyncResult.DataChunks, &bytesSent, IntPtr.Zero, 0, asyncResult.NativeOverlapped !, IntPtr.Zero); } } catch (Exception e) { Log.ErrorWhenFlushAsync(Logger, e); asyncResult.Dispose(); Abort(); throw; } if (statusCode != ErrorCodes.ERROR_SUCCESS && statusCode != ErrorCodes.ERROR_IO_PENDING) { if (cancellationToken.IsCancellationRequested) { Log.WriteFlushCancelled(Logger, statusCode); asyncResult.Cancel(ThrowWriteExceptions); } else if (ThrowWriteExceptions) { asyncResult.Dispose(); Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode)); Log.ErrorWhenFlushAsync(Logger, exception); Abort(); throw exception; } else { // Abort the request but do not close the stream, let future writes complete silently Log.WriteErrorIgnored(Logger, statusCode); asyncResult.FailSilently(); } } if (statusCode == ErrorCodes.ERROR_SUCCESS && HttpSysListener.SkipIOCPCallbackOnSuccess) { // IO operation completed synchronously - callback won't be called to signal completion. asyncResult.IOCompleted(statusCode, bytesSent); } // Last write, cache it for special cancellation handling. if ((flags & HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA) == 0) { _lastWrite = asyncResult; } return(asyncResult.Task); }
public async void ParameterLevelTypeConverter() { var api = new HttpApi<IParameterLevelTypeConverter>(); var endpoint = api.Endpoints.Single().Value; var httpHandler = new MockHttpHandler(); await endpoint.Call(httpHandler, "http://localhost", new Dictionary<string, object> { ["number"] = 5 }); Assert.AreEqual("http://localhost/foo", httpHandler.Request.Url.ToString()); }
static async Task <Tuple <long, string> > GetPullRequestBaselineRunSetId(Product product, string pullRequestURL, compare.Repository repository, Config config) { var gitHubClient = GitHubInterface.GitHubClient; var match = Regex.Match(pullRequestURL, product.PullRequestRegexp); if (match == null) { Console.Error.WriteLine("Error: Cannot parse pull request URL."); Environment.Exit(1); } var pullRequestNumber = Int32.Parse(match.Groups [1].Value); Console.WriteLine("pull request {0}", pullRequestNumber); var pullRequest = await gitHubClient.PullRequest.Get("mono", "mono", pullRequestNumber); var prRepo = pullRequest.Head.Repository.CloneUrl; var prBranch = pullRequest.Head.Ref; var prSha = repository.Fetch(prRepo, prBranch); if (prSha == null) { Console.Error.WriteLine("Error: Could not fetch pull request branch {0} from repo {1}", prBranch, prRepo); Environment.Exit(1); } var masterSha = repository.Fetch(product.GitRepositoryUrl, "master"); if (masterSha == null) { Console.Error.WriteLine("Error: Could not fetch master."); Environment.Exit(1); } var baseSha = repository.MergeBase(prSha, masterSha); if (baseSha == null) { Console.Error.WriteLine("Error: Could not determine merge base of pull request."); Environment.Exit(1); } Console.WriteLine("Merge base sha is {0}", baseSha); var revList = repository.RevList(baseSha); if (revList == null) { Console.Error.WriteLine("Error: Could not get rev-list for merge base {0}.", baseSha); Environment.Exit(1); } Console.WriteLine("{0} commits in rev-list", revList.Length); // FIXME: also support `--machine` var hostarch = compare.Utils.LocalHostnameAndArch(); var machine = new Machine { Name = hostarch.Item1, Architecture = hostarch.Item2 }; JArray runsets = await HttpApi.GetRunsets(machine.Name, config.Name); if (runsets == null) { Console.Error.WriteLine("Error: Could not get run sets."); Environment.Exit(1); } var runSetIdsByCommits = new Dictionary <string, long> (); foreach (var rs in runsets) { var id = rs ["ID"].ToObject <long> (); var commit = rs ["MainProduct"] ["Commit"].ToObject <string> (); runSetIdsByCommits [commit] = id; } Console.WriteLine("{0} run sets", runSetIdsByCommits.Count); foreach (var sha in revList) { if (runSetIdsByCommits.ContainsKey(sha)) { Console.WriteLine("tested base commit is {0}", sha); return(Tuple.Create(runSetIdsByCommits [sha], baseSha)); } } return(null); }
public async Task DirectJsonBody() { var api = new HttpApi<IDirectJsonBody>(); var endpoint = api.Endpoints.Single().Value; var httpHandler = new MockHttpHandler(); await endpoint.Call(httpHandler, "http://localhost", new Dictionary<string, object> { ["number"] = 5 }); var body = (JsonHttpBody)httpHandler.Request.Body; var value = (JValue)body.Json; Assert.AreEqual(5, (int)value); }
public static HttpConfigSsl GetHttpSslConfig() { return(HttpApi.GetHttpSslConfig()); }
public async void JsonResponse() { var api = new HttpApi<IJsonResponse>(); var endpoint = api.Endpoints.Single().Value; var httpHandler = new MockHttpHandler(new HttpApiResponse(body: new JsonHttpBody("foo"))); var result = (string)await endpoint.Call(httpHandler, "http://localhost", new Dictionary<string, object>()); Assert.AreEqual("foo", result); }
public async void MultipelIdsCommaSeparated() { var api = new HttpApi<IMultipleIdsCommaSeparated>(); var endpoint = api.Endpoints.Single().Value; var httpHandler = new MockHttpHandler(); await endpoint.Call(httpHandler, "http://localhost", new Dictionary<string, object> { ["ids"] = new[] { 1, 3 } }); Assert.AreEqual("http://localhost?ids=1,3", httpHandler.Request.Url.ToString()); }
private static async Task DisableApiAccessForUserAsync(ApiUserDTO userDto, int id) { userDto.HasApiAccess = false; await HttpApi.PatchOdataUserAsync(userDto, id); }
public async void ReturnTypeConverter() { var api = new HttpApi<IReturnTypeConverter>(); var endpoint = api.Endpoints.Single().Value; var httpHandler = new MockHttpHandler(); var result = await endpoint.Call(httpHandler, "http://localhost", new Dictionary<string, object> { ["number"] = 5 }); Assert.AreEqual("foo", result); }
static ExchangeRates() { HttpApi.Register <IExchangeRate>(); HttpApi.Register <ICmbcCreditRate>(); HttpApi.Register <ICibRate>(); }
public async Task ComposedJsonBody() { var api = new HttpApi<IComposedJsonBody>(); var endpoint = api.Endpoints.Single().Value; var httpHandler = new MockHttpHandler(); await endpoint.Call(httpHandler, "http://localhost", new Dictionary<string, object> { ["value1"] = 5, ["value2"] = "foo" }); var body = (JsonHttpBody)httpHandler.Request.Body; var jsonObject = (JObject)body.Json; Assert.AreEqual(5, (int)jsonObject["value1"]); Assert.AreEqual("foo", (string)jsonObject["value2"]); }
internal unsafe void SendError(ulong requestId, int httpStatusCode, IList <string>?authChallenges = null) { HttpApiTypes.HTTP_RESPONSE_V2 httpResponse = new HttpApiTypes.HTTP_RESPONSE_V2(); httpResponse.Response_V1.Version = new HttpApiTypes.HTTP_VERSION(); httpResponse.Response_V1.Version.MajorVersion = (ushort)1; httpResponse.Response_V1.Version.MinorVersion = (ushort)1; List <GCHandle>?pinnedHeaders = null; GCHandle gcHandle; try { // Copied from the multi-value headers section of SerializeHeaders if (authChallenges != null && authChallenges.Count > 0) { pinnedHeaders = new List <GCHandle>(authChallenges.Count + 3); HttpApiTypes.HTTP_RESPONSE_INFO[] knownHeaderInfo = new HttpApiTypes.HTTP_RESPONSE_INFO[1]; gcHandle = GCHandle.Alloc(knownHeaderInfo, GCHandleType.Pinned); pinnedHeaders.Add(gcHandle); httpResponse.pResponseInfo = (HttpApiTypes.HTTP_RESPONSE_INFO *)gcHandle.AddrOfPinnedObject(); knownHeaderInfo[httpResponse.ResponseInfoCount].Type = HttpApiTypes.HTTP_RESPONSE_INFO_TYPE.HttpResponseInfoTypeMultipleKnownHeaders; knownHeaderInfo[httpResponse.ResponseInfoCount].Length = (uint)Marshal.SizeOf <HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS>(); HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS header = new HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS(); header.HeaderId = HttpApiTypes.HTTP_RESPONSE_HEADER_ID.Enum.HttpHeaderWwwAuthenticate; header.Flags = HttpApiTypes.HTTP_RESPONSE_INFO_FLAGS.PreserveOrder; // The docs say this is for www-auth only. HttpApiTypes.HTTP_KNOWN_HEADER[] nativeHeaderValues = new HttpApiTypes.HTTP_KNOWN_HEADER[authChallenges.Count]; gcHandle = GCHandle.Alloc(nativeHeaderValues, GCHandleType.Pinned); pinnedHeaders.Add(gcHandle); header.KnownHeaders = (HttpApiTypes.HTTP_KNOWN_HEADER *)gcHandle.AddrOfPinnedObject(); for (int headerValueIndex = 0; headerValueIndex < authChallenges.Count; headerValueIndex++) { // Add Value string headerValue = authChallenges[headerValueIndex]; byte[] bytes = HeaderEncoding.GetBytes(headerValue); nativeHeaderValues[header.KnownHeaderCount].RawValueLength = (ushort)bytes.Length; gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); pinnedHeaders.Add(gcHandle); nativeHeaderValues[header.KnownHeaderCount].pRawValue = (byte *)gcHandle.AddrOfPinnedObject(); header.KnownHeaderCount++; } // This type is a struct, not an object, so pinning it causes a boxed copy to be created. We can't do that until after all the fields are set. gcHandle = GCHandle.Alloc(header, GCHandleType.Pinned); pinnedHeaders.Add(gcHandle); knownHeaderInfo[0].pInfo = (HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS *)gcHandle.AddrOfPinnedObject(); httpResponse.ResponseInfoCount = 1; } httpResponse.Response_V1.StatusCode = (ushort)httpStatusCode; string?statusDescription = HttpReasonPhrase.Get(httpStatusCode); uint dataWritten = 0; uint statusCode; byte[] byteReason = statusDescription != null?HeaderEncoding.GetBytes(statusDescription) : Array.Empty <byte>(); fixed(byte *pReason = byteReason) { httpResponse.Response_V1.pReason = (byte *)pReason; httpResponse.Response_V1.ReasonLength = (ushort)byteReason.Length; byte[] byteContentLength = new byte[] { (byte)'0' }; fixed(byte *pContentLength = byteContentLength) { (&httpResponse.Response_V1.Headers.KnownHeaders)[(int)HttpSysResponseHeader.ContentLength].pRawValue = (byte *)pContentLength; (&httpResponse.Response_V1.Headers.KnownHeaders)[(int)HttpSysResponseHeader.ContentLength].RawValueLength = (ushort)byteContentLength.Length; httpResponse.Response_V1.Headers.UnknownHeaderCount = 0; statusCode = HttpApi.HttpSendHttpResponse( _requestQueue.Handle, requestId, 0, &httpResponse, null, &dataWritten, IntPtr.Zero, 0, SafeNativeOverlapped.Zero, IntPtr.Zero); } } if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { // if we fail to send a 401 something's seriously wrong, abort the request HttpApi.HttpCancelHttpRequest(_requestQueue.Handle, requestId, IntPtr.Zero); } } finally { if (pinnedHeaders != null) { foreach (GCHandle handle in pinnedHeaders) { if (handle.IsAllocated) { handle.Free(); } } } } }
public async void Header() { var api = new HttpApi<IHeaderApi>(); var endpoint = api.Endpoints.Single().Value; var httpHandler = new MockHttpHandler(); await endpoint.Call(httpHandler, "http://localhost", new Dictionary<string, object>()); var header = httpHandler.Request.Headers.Single(x => x.Name == "User-Agent"); Assert.AreEqual("TestUserAgent", header.Values.Single()); }
public async Task Bind_To_TestRouteWithInvalidReturnType() { var sz = new JsonSerialiser(); using (var api = new HttpApi(sz, 9211)) { api.Bind("/factorial/{x}").To(new { x = 1 }, a => Task.FromResult(Functions.Factorial(a.x))); var url = new Uri(api.BaseEndpoint, "/factorial/10"); try { await api.TestRoute<double>(url); } catch (Exception ex) { Assert.That(ex, Is.InstanceOf<HttpException>()); } } }
public void Post() { var api = new HttpApi<IPost>(); Assert.AreEqual(HttpMethod.Post, api.Endpoints.Single().Value.Method); }
private static unsafe void IOCompleted(ClientCertLoader asyncResult, uint errorCode, uint numBytes) { RequestContext requestContext = asyncResult.RequestContext; try { if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA) { // There is a bug that has existed in http.sys since w2k3. Bytesreceived will only // return the size of the initial cert structure. To get the full size, // we need to add the certificate encoding size as well. HttpApiTypes.HTTP_SSL_CLIENT_CERT_INFO *pClientCertInfo = asyncResult.RequestBlob; asyncResult.Reset(numBytes + pClientCertInfo->CertEncodedSize); uint bytesReceived = 0; errorCode = HttpApi.HttpReceiveClientCertificate( requestContext.Server.RequestQueue.Handle, requestContext.Request.UConnectionId, (uint)HttpApiTypes.HTTP_FLAGS.NONE, asyncResult._memoryBlob, asyncResult._size, &bytesReceived, asyncResult._overlapped !); if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING || (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && !HttpSysListener.SkipIOCPCallbackOnSuccess)) { return; } } if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_NOT_FOUND) { // The client did not send a cert. asyncResult.Complete(0, null); } else if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { asyncResult.Fail(new HttpSysException((int)errorCode)); } else { HttpApiTypes.HTTP_SSL_CLIENT_CERT_INFO *pClientCertInfo = asyncResult._memoryBlob; if (pClientCertInfo == null) { asyncResult.Complete(0, null); } else { if (pClientCertInfo->pCertEncoded != null) { try { byte[] certEncoded = new byte[pClientCertInfo->CertEncodedSize]; Marshal.Copy((IntPtr)pClientCertInfo->pCertEncoded, certEncoded, 0, certEncoded.Length); asyncResult.Complete((int)pClientCertInfo->CertFlags, new X509Certificate2(certEncoded)); } catch (CryptographicException exception) { // TODO: Log asyncResult.Fail(exception); } catch (SecurityException exception) { // TODO: Log asyncResult.Fail(exception); } } } } } catch (Exception exception) { asyncResult.Fail(exception); } }
public async void QueryWithSubstitution() { var api = new HttpApi<IQueryWithSubstitution>(); var endpoint = api.Endpoints.Single().Value; var httpHandler = new MockHttpHandler(); await endpoint.Call(httpHandler, "http://localhost", new Dictionary<string, object> { ["key"] = "bar" }); Assert.AreEqual("http://localhost/path?foo=bar", httpHandler.Request.Url.ToString()); }
internal static unsafe ChannelBinding?GetChannelBindingFromTls(RequestQueue requestQueue, ulong connectionId, ILogger logger) { // +128 since a CBT is usually <128 thus we need to call HRCC just once. If the CBT // is >128 we will get ERROR_MORE_DATA and call again int size = RequestChannelBindStatusSize + 128; Debug.Assert(size >= 0); byte[]? blob = null; SafeLocalFreeChannelBinding?token = null; uint bytesReceived = 0;; uint statusCode; do { blob = new byte[size]; fixed(byte *blobPtr = blob) { // Http.sys team: ServiceName will always be null if // HTTP_RECEIVE_SECURE_CHANNEL_TOKEN flag is set. statusCode = HttpApi.HttpReceiveClientCertificate( requestQueue.Handle, connectionId, (uint)HttpApiTypes.HTTP_FLAGS.HTTP_RECEIVE_SECURE_CHANNEL_TOKEN, blobPtr, (uint)size, &bytesReceived, SafeNativeOverlapped.Zero); if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { int tokenOffset = GetTokenOffsetFromBlob((IntPtr)blobPtr); int tokenSize = GetTokenSizeFromBlob((IntPtr)blobPtr); Debug.Assert(tokenSize < Int32.MaxValue); token = SafeLocalFreeChannelBinding.LocalAlloc(tokenSize); Marshal.Copy(blob, tokenOffset, token.DangerousGetHandle(), tokenSize); } else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA) { int tokenSize = GetTokenSizeFromBlob((IntPtr)blobPtr); Debug.Assert(tokenSize < Int32.MaxValue); size = RequestChannelBindStatusSize + tokenSize; } else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_INVALID_PARAMETER) { Log.ChannelBindingUnsupported(logger); return(null); // old schannel library which doesn't support CBT } else { // It's up to the consumer to fail if the missing ChannelBinding matters to them. Log.ChannelBindingMissing(logger, new HttpSysException((int)statusCode)); break; } } }while (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS); return(token); }
public CurrencyApi(HttpApi httpApi) : base(httpApi) { }
/// <summary> /// /// </summary> private void GetLoginQRCode() { contact_all.Clear(); _contact_all.Clear(); picQRCode.Image = null; picQRCode.SizeMode = PictureBoxSizeMode.Zoom; ((Action)(delegate() { //异步加载二维码 LoginService ls = new LoginService(); Image qrcode = ls.GetQRCode(); if (qrcode != null) { this.BeginInvoke((Action) delegate() { picQRCode.Image = qrcode; }); object login_result = null; while (true) //循环判断手机扫面二维码结果 { login_result = ls.LoginCheck(); if (login_result is Image) //已扫描 未登录 { this.BeginInvoke((Action) delegate() { picQRCode.SizeMode = PictureBoxSizeMode.CenterImage; //显示头像 picQRCode.Image = login_result as Image; }); } if (login_result is string) //已完成登录 { //访问登录跳转URL ls.GetSidUid(login_result as string); //初始化API HttpApi api = new HttpApi(); api.InitApi(login_result.ToString()); //获取好友和并绑定 UserServices userServices = new UserServices(); WXServices wxServices = new WXServices(); JObject initResult = wxServices.WxInit(); if (initResult != null) { _me = new WXUser(); _me.UserName = initResult["User"]["UserName"].ToString(); _me.City = ""; _me.HeadImgUrl = initResult["User"]["HeadImgUrl"].ToString(); _me.NickName = initResult["User"]["NickName"].ToString(); _me.Province = ""; _me.PYQuanPin = initResult["User"]["PYQuanPin"].ToString(); _me.RemarkName = initResult["User"]["RemarkName"].ToString(); _me.RemarkPYQuanPin = initResult["User"]["RemarkPYQuanPin"].ToString(); _me.Sex = initResult["User"]["Sex"].ToString(); _me.Signature = initResult["User"]["Signature"].ToString(); } JObject contact_result = userServices.GetContact(); //通讯录 if (contact_result != null) { foreach (JObject contact in contact_result["MemberList"]) //完整好友名单 { WXUser user = new WXUser(); user.UserName = contact["UserName"].ToString(); user.City = contact["City"].ToString(); user.HeadImgUrl = contact["HeadImgUrl"].ToString(); user.NickName = contact["NickName"].ToString(); user.Province = contact["Province"].ToString(); user.PYQuanPin = contact["PYQuanPin"].ToString(); user.RemarkName = contact["RemarkName"].ToString(); user.RemarkPYQuanPin = contact["RemarkPYQuanPin"].ToString(); user.Sex = contact["Sex"].ToString(); user.Signature = contact["Signature"].ToString(); user.ContactFlag = contact["ContactFlag"].ToString(); user.VerifyFlag = contact["VerifyFlag"].ToString(); contact_all.Add(user); } } IOrderedEnumerable <WXUser> list_all = contact_all.OrderBy(e => (e as WXUser).ShowPinYin); WXUser wx; string start_char; foreach (object o in list_all) { wx = o as WXUser; start_char = wx.ShowPinYin == "" ? "" : wx.ShowPinYin.Substring(0, 1); if (!_contact_all.Contains(start_char.ToUpper())) { _contact_all.Add(start_char.ToUpper()); } _contact_all.Add(o); } SendMessageInit(); return; } } } })).BeginInvoke(null, null); }
// We never expect endOfRequest and data at the same time private unsafe void FlushInternal(bool endOfRequest, ArraySegment <byte> data = new ArraySegment <byte>()) { Debug.Assert(!(endOfRequest && data.Count > 0), "Data is not supported at the end of the request."); if (_skipWrites) { return; } var started = _requestContext.Response.HasStarted; if (data.Count == 0 && started && !endOfRequest) { // No data to send and we've already sent the headers return; } // Make sure all validation is performed before this computes the headers var flags = ComputeLeftToWrite(data.Count, endOfRequest); if (endOfRequest && _leftToWrite > 0) { if (!RequestContext.DisconnectToken.IsCancellationRequested) { // This is logged rather than thrown because it is too late for an exception to be visible in user code. Log.FewerBytesThanExpected(Logger); } _requestContext.Abort(); return; } uint statusCode = 0; HttpApiTypes.HTTP_DATA_CHUNK[] dataChunks; var pinnedBuffers = PinDataBuffers(endOfRequest, data, out dataChunks); try { if (!started) { statusCode = _requestContext.Response.SendHeaders(dataChunks, null, flags, false); } else { fixed(HttpApiTypes.HTTP_DATA_CHUNK *pDataChunks = dataChunks) { statusCode = HttpApi.HttpSendResponseEntityBody( RequestQueueHandle, RequestId, (uint)flags, (ushort)dataChunks.Length, pDataChunks, null, IntPtr.Zero, 0, SafeNativeOverlapped.Zero, IntPtr.Zero); } } } finally { FreeDataBuffers(pinnedBuffers); } if (statusCode != ErrorCodes.ERROR_SUCCESS && statusCode != ErrorCodes.ERROR_HANDLE_EOF // Don't throw for disconnects, we were already finished with the response. && (!endOfRequest || (statusCode != ErrorCodes.ERROR_CONNECTION_INVALID && statusCode != ErrorCodes.ERROR_INVALID_PARAMETER))) { if (ThrowWriteExceptions) { var exception = new IOException(string.Empty, new HttpSysException((int)statusCode)); Log.WriteError(Logger, exception); Abort(); throw exception; } else { // Abort the request but do not close the stream, let future writes complete silently Log.WriteErrorIgnored(Logger, statusCode); Abort(dispose: false); } } }
internal static extern unsafe uint HttpCreateRequestQueue(HttpApi.HTTPAPI_VERSION version, string pName, Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES pSecurityAttributes, uint flags, out HttpRequestQueueV2Handle pReqQueueHandle);
internal unsafe Task SendFileAsyncCore(string fileName, long offset, long?count, CancellationToken cancellationToken) { if (_skipWrites) { return(Task.CompletedTask); } var started = _requestContext.Response.HasStarted; if (count == 0 && started) { // No data to send and we've already sent the headers return(Task.CompletedTask); } if (cancellationToken.IsCancellationRequested) { Abort(ThrowWriteExceptions); return(Task.FromCanceled <int>(cancellationToken)); } // We are setting buffer size to 1 to prevent FileStream from allocating it's internal buffer // It's too expensive to validate anything before opening the file. Open the file and then check the lengths. var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, bufferSize: 1, options: FileOptions.Asynchronous | FileOptions.SequentialScan); // Extremely expensive. try { var length = fileStream.Length; // Expensive, only do it once if (!count.HasValue) { count = length - offset; } if (offset < 0 || offset > length) { throw new ArgumentOutOfRangeException(nameof(offset), offset, string.Empty); } if (count < 0 || count > length - offset) { throw new ArgumentOutOfRangeException(nameof(count), count, string.Empty); } CheckWriteCount(count); } catch { fileStream.Dispose(); throw; } // Make sure all validation is performed before this computes the headers var flags = ComputeLeftToWrite(count.Value); uint statusCode; uint bytesSent = 0; var chunked = _requestContext.Response.BoundaryType == BoundaryType.Chunked; var asyncResult = new ResponseStreamAsyncResult(this, fileStream, offset, count.Value, chunked, cancellationToken); try { if (!started) { statusCode = _requestContext.Response.SendHeaders(null, asyncResult, flags, false); bytesSent = asyncResult.BytesSent; } else { // TODO: If opaque then include the buffer data flag. statusCode = HttpApi.HttpSendResponseEntityBody( RequestQueueHandle, RequestId, (uint)flags, asyncResult.DataChunkCount, asyncResult.DataChunks, &bytesSent, IntPtr.Zero, 0, asyncResult.NativeOverlapped !, IntPtr.Zero); } } catch (Exception e) { Log.FileSendAsyncError(Logger, e); asyncResult.Dispose(); Abort(); throw; } if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING) { if (cancellationToken.IsCancellationRequested) { Log.FileSendAsyncCancelled(Logger, statusCode); asyncResult.Cancel(ThrowWriteExceptions); } else if (ThrowWriteExceptions) { asyncResult.Dispose(); var exception = new IOException(string.Empty, new HttpSysException((int)statusCode)); Log.FileSendAsyncError(Logger, exception); Abort(); throw exception; } else { // Abort the request but do not close the stream, let future writes complete Log.FileSendAsyncErrorIgnored(Logger, statusCode); asyncResult.FailSilently(); } } if (statusCode == ErrorCodes.ERROR_SUCCESS && HttpSysListener.SkipIOCPCallbackOnSuccess) { // IO operation completed synchronously - callback won't be called to signal completion. asyncResult.IOCompleted(statusCode, bytesSent); } // Last write, cache it for special cancellation handling. if ((flags & HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA) == 0) { _lastWrite = asyncResult; } return(asyncResult.Task); }
public async Task Bind_To_AnonymousMethod_AndTestRoute() { var sz = new JsonSerialiser(); using (var api = new HttpApi(sz, 9211)) { api.Bind("/abc/{param}").To(new { param = 123 }, a => Task.FromResult(new { x = a.param * 5 })); var url = new Uri(api.BaseEndpoint, "/abc/44"); var result = await api.TestRoute(url, new { x = 123 }); Assert.That(result.x, Is.EqualTo(220)); } }