{"id":16534404,"url":"https://github.com/cristipufu/swiftclient-net","last_synced_at":"2025-03-21T09:32:08.287Z","repository":{"id":26588928,"uuid":"45693870","full_name":"cristipufu/swiftclient-net","owner":"cristipufu","description":".NET Core async HTTP client for OpenStack Swift","archived":false,"fork":false,"pushed_at":"2022-12-07T20:05:00.000Z","size":4692,"stargazers_count":39,"open_issues_count":12,"forks_count":19,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-09-04T08:14:36.052Z","etag":null,"topics":["blob-storage","openstack","openstack-swift"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cristipufu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-06T16:38:53.000Z","updated_at":"2024-07-10T03:29:40.000Z","dependencies_parsed_at":"2022-09-20T16:52:10.782Z","dependency_job_id":null,"html_url":"https://github.com/cristipufu/swiftclient-net","commit_stats":null,"previous_names":["vtfuture/swiftclient","cristipufu/swiftclient"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristipufu%2Fswiftclient-net","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristipufu%2Fswiftclient-net/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristipufu%2Fswiftclient-net/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristipufu%2Fswiftclient-net/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cristipufu","download_url":"https://codeload.github.com/cristipufu/swiftclient-net/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244772425,"owners_count":20507982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blob-storage","openstack","openstack-swift"],"created_at":"2024-10-11T18:24:04.267Z","updated_at":"2025-03-21T09:32:07.555Z","avatar_url":"https://github.com/cristipufu.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OpenStack Swift client for .NET\n\n[![Build status](https://ci.appveyor.com/api/projects/status/77ts9n1a6w5xnrjw?svg=true)](https://ci.appveyor.com/project/stefanprodan/swiftclient)\n[![NuGet version](https://img.shields.io/nuget/vpre/SwiftClient.svg)](https://www.nuget.org/packages/SwiftClient/)\n\n***SwiftClient*** is an async HTTP wrapper over OpenStack Swift REST API and follows the [Object Storage API Reference](http://developer.openstack.org/api-ref-objectstorage-v1.html). \nIt can be installed via NuGet from [nuget.org/packages/SwiftClient](https://www.nuget.org/packages/SwiftClient/) and it's compatible with .NET Framework 4.5 and .NET Core 1.0.\n\n***SwiftClient.AspNetCore*** is a SwiftClient implementation for ASP.NET Core MVC that comes with utilities for buffered upload/download and video streaming. \nIt can be installed via NuGet from [nuget.org/packages/SwiftClient.AspNetCore](https://www.nuget.org/packages/SwiftClient.AspNetCore/).\n\n### SwiftClient usage for .NET 4.5 or .NET Core\n\nInstall NuGet package:\n```\nInstall-Package SwiftClient\n```\n\nConfiguration:\n\n```cs\nvar swiftClient = new SwiftClient.Client()\n.WithCredentials(new SwiftCredentials\n{\n     Username = \"test:tester\",\n     Password = \"testing\",\n     Endpoints = new List\u003cstring\u003e { \n\t\t\"http://192.168.3.31:8080\",\n\t\t\"http://192.168.3.32:8080\"\n\t\t}\n})\n.SetRetryCount(6)\n.SetRetryPerEndpointCount(2)\n.SetLogger(new SwiftLogger());\n```\n\nThe client implements a configurable retry mechanism, so you don't have to worry about the token expiration date or a temporary request failure. \nIt also supports multiple endpoints (Swift proxy address), it will iterate through each endpoint till it finds one that's available, if the maximum retry count is reached an exception will be thrown.\nIf you want to log failure events, just pass the client your implementation of the `ISwiftLogger` interface. In the CLI project there is a [stdout log example](https://github.com/vtfuture/SwiftClient/blob/master/samples/SwiftClient.Cli/SwiftConsoleLog.cs).\n\nYou have to supply your own implementation of `ISwiftAuthManager` class and provide a caching mechanism for the ***authentication token*** so that each Swift request is not being preceded by an authentication request. It is recommended to use a dedicated cache storage like Redis so multiple instances of your app can reuse the authentication token. In the AspNetCore project there is a `ISwiftAuthManager` [implementation](https://github.com/vtfuture/SwiftClient/blob/master/src/SwiftClient.AspNetCore/SwiftAuthManagerMemoryCache.cs) that uses ASP.NET Core in memory cache.\n\n###  SwiftClient.AspNetCore usage for ASP.NET Core MVC\n\nInstall NuGet package:\n\n```\nInstall-Package SwiftClient.AspNetCore\n```\n\nYou can load Swift credentials from an json file in ASP.NET Core projects. Add an [`appsettings.json`](https://github.com/vtfuture/SwiftClient/blob/master/samples/SwiftClient.AspNetCore.Demo/appsettings.json) file in the root your project and load the settings in [`Startup.cs`](https://github.com/vtfuture/SwiftClient/blob/master/samples/SwiftClient.AspNetCore.Demo/Startup.cs).\n\nConfigure Swift in appsettings.json:\n\n```json\n  \"SwiftCluster\": {\n    \"Username\": \"test:tester\",\n    \"Password\": \"testing\",\n    \"Endpoints\": [\n      \"http://localhost:8080\",\n      \"http://localhost:8081\"\n    ],\n    \"RetryCount\": 1,\n    \"RetryPerEndpointCount\": 2\n  }\n```\n\nConfigure SwiftClient service in Startup.cs:\n\n```cs\npublic void ConfigureServices(IServiceCollection services)\n{\n\tservices.AddOptions();\n\tservices.AddMemoryCache();\n\n\tservices.AddMvc();\n\n\tservices.Configure\u003cSwiftServiceOptions\u003e(Configuration.GetSection(\"SwiftCluster\"));\n\tservices.AddSwift();\n}\n```\n\nUse the `SwiftService` in your controller:\n\n```cs\nprivate readonly ISwiftClient _swiftService;\n\npublic HomeController(ISwiftClient swiftService)\n{\n\t_swiftService = swiftService;\n}\n```\n\nSimple upload/download example for small files:\n\n```cs\npublic async Task\u003cIActionResult\u003e UploadFile(IFormFile file)\n{ \n    using (var fileStream = file.OpenReadStream())\n    {\n        using (var memoryStream = new MemoryStream())\n        {\n            await fileStream.CopyToAsync(memoryStream);\n\n            var resp = await _swiftService.PutObject(containerId, fileId, memoryStream);\n\n            return new JsonResult(new\n            {\n                Success = resp.IsSuccess\n            });\n        }\n    }\n}\n\npublic async Task\u003cIActionResult\u003e DownloadFile(string fileId)\n{\n    var rsp = await _swiftService.GetObject(\"containerId\", fileId);\n\n    if (rsp.IsSuccess)\n    {\n        return new FileStreamResult(rsp.Stream, \"application/octet-stream\");\n    }\n\n    return new NotFoundResult();\n}\n```\n\nChunked upload example for large files:\n\n```cs\npublic async Task\u003cIActionResult\u003e UploadChunk(int segment)\n{\n\tif (Request.Form.Files != null \u0026\u0026 Request.Form.Files.Count \u003e 0)\n\t{\n\t\tvar file = Request.Form.Files[0];\n\t\t\n\t\tusing (var fileStream = file.OpenReadStream())\n\t\t{\n\t\t\tusing (var memoryStream = new MemoryStream())\n\t\t\t{\n\t\t\t\tvar fileName = file.GetFileName();\n\n\t\t\t\tawait fileStream.CopyToAsync(memoryStream);\n\n\t\t\t\t// upload file chunk\n\t\t\t\tawait _swiftService.PutChunkedObject(containerTempId, fileName, memoryStream.ToArray(), segment);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn new JsonResult(new\n\t{\n\t\tSuccess = false\n\t});\n}\n\npublic async Task\u003cIActionResult\u003e UploadDone(string fileName, string contentType)\n{\n\t// use manifest to merge chunks\n        await _swiftService.PutManifest(containerTempId, fileName);\n\n        // copy chunks to new file and set some meta data info about the file (filename, contentype)\n        await _swiftService.CopyObject(containerTempId, fileName, containerDemoId, fileName, new Dictionary\u003cstring, string\u003e\n        {\n            { $\"X-Object-Meta-{metaFileName}\", fileName },\n            { $\"X-Object-Meta-{metaContentType}\", contentType }\n        });\n\n        // cleanup temp\n        await _swiftService.DeleteContainerContents(containerTempId);\n}\n```\n\nBuffered download example using `BufferedHTTPStream`:\n\n```cs\npublic async Task\u003cIActionResult\u003e DownloadFile(string fileId)\n{\n\tvar headObject = await _swiftService.HeadObject(containerId, fileId);\n\n\tif (headObject.IsSuccess \u0026\u0026 headObject.ContentLength \u003e 0)\n\t{\n\t\tvar fileName = headObject.GetMeta(\"Filename\");\n\t\tvar contentType = headObject.GetMeta(\"Contenttype\");\n\n\t\tResponse.Headers.Add(\"Content-Disposition\", $\"attachment; filename={fileName}\");\n\n\t\tvar stream = new BufferedHTTPStream((start, end) =\u003e\n\t\t{\n\t\t\tusing (var response = _swiftService.GetObjectRange(containerId, objectId, start, end).Result)\n           {\n\t                var ms = new MemoryStream();\n\t\n\t                response.Stream.CopyTo(ms);\n\t\n\t                return ms;\n           }\n\n\t\t}, () =\u003e headObject.ContentLength);\n\n\t\treturn new FileStreamResult(stream, contentType);\n\t}\n\n\treturn new NotFoundResult();\n}\n```\n\nMP4 streaming that works with any HTML5 player:\n\n```cs\npublic async Task\u003cIActionResult\u003e PlayVideo(string containerId, string objectId)\n{\n\tvar headObject = await _swiftService.HeadObject(containerId, objectId);\n\n\tif (headObject.IsSuccess)\n\t{\n\t\tvar fileName = headObject.GetMeta(metaFileName);\n\t\tvar contentType = headObject.GetMeta(metaContentType);\n\n\t\tvar stream = new BufferedHTTPStream((start, end) =\u003e\n\t\t{\n\t\t\tusing (var response = _swiftService.GetObjectRange(containerId, objectId, start, end).Result)\n\t\t\t{\n\t\t\t\tvar ms = new MemoryStream();\n\n\t\t\t\tresponse.Stream.CopyTo(ms);\n\n\t\t\t\treturn ms;\n\t\t\t}\n\n\t\t}, () =\u003e headObject.ContentLength);\n\n\t\tResponse.Headers.Add(\"Content-Disposition\", $\"attachment; filename={fileName}\");\n\n\t\treturn new VideoStreamResult(stream, \"video/mp4\");\n\t}\n\n\treturn new NotFoundResult();\n}\n```\n\n### Running the ASP.NET Core MVC demo\n\nThe [SwiftClient.AspNetCore.Demo](https://github.com/vtfuture/SwiftClient/tree/master/samples/SwiftClient.AspNetCore.Demo) project is an example of how to authenticate against Swift, do chunked upload for a large file and download it and also video streaming. \n\nYou will need at least one Ubuntu 14.04 box to host OpenStack Swift proxy and storage. For dev/test environments we provide a docker image with a single Swift proxy and storage, follow the setup instruction from [docker-swift](https://github.com/vtfuture/SwiftClient/tree/master/tools/docker-swift) to build and run the Swift container. After you've started the Swift all-in-one container, put your Ubuntu box IP in the `appsettings.json` from the demo project and your good to go. You can also use Docker for Windows to host the Swift dev container.\n\nIf you want to setup Swift for production on a Ubuntu cluster check out the [documentation](https://github.com/vtfuture/SwiftClient/wiki) from our wiki.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcristipufu%2Fswiftclient-net","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcristipufu%2Fswiftclient-net","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcristipufu%2Fswiftclient-net/lists"}