From 1475d2a0b643d0dde5256ef1568277fcc6fc97d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Thu, 15 Nov 2018 01:10:43 +0000 Subject: [PATCH] Revert "Merge for Release v1.0.2 (#4)" This reverts commit 91135c57ee6829e94db70f95617eeb886e7a3051. --- .github_changelog_generator | 14 - CHANGELOG.md | 13 - CODE_OF_CONDUCT.md | 3 - CONTRIBUTING.md | 3 - README.md | 4 +- appveyor-discord.ps1 | 82 - appveyor.yml | 164 -- commit-assemblyinfo-changes.ps1 | 20 - generate-change-log.ps1 | 36 - install-vsix-appveyor.ps1 | 9 - source/NuGet.Config | 6 - source/key.snk | Bin 596 -> 0 bytes source/nanoFramework.System.Net.Http.nuspec | 32 - source/nanoFramework.System.Net.Http.sln | 26 - .../Http/System.Net.AuthenticationType.cs | 26 - .../Http/System.Net.HttpListener.cs | 675 ------ .../Http/System.Net.HttpListenerContext.cs | 191 -- .../Http/System.Net.HttpListenerRequest.cs | 438 ---- .../Http/System.Net.HttpListenerResponse.cs | 539 ----- .../Http/System.Net.HttpStatusCode.cs | 300 --- .../Http/System.Net.HttpVersion.cs | 33 - .../Http/System.Net.HttpWebRequest.cs | 1957 ----------------- .../Http/System.Net.HttpWebResponse.cs | 330 --- .../Http/System.Net.IWebRequestCreate.cs | 33 - .../Http/System.Net.Internal.cs | 328 --- .../Http/System.Net.NetworkCredential.cs | 99 - .../System.Net.ProtocolViolationException.cs | 42 - .../Http/System.Net.WebException.cs | 145 -- .../Http/System.Net.WebHeaders.cs | 725 ------ .../Http/System.Net.WebRequest.cs | 394 ---- .../Http/System.Net.WebResponse.cs | 138 -- .../Http/System.Net.WebStatus.cs | 65 - .../Http/System.Net._HeaderInfo.cs | 39 - .../Http/System.Net._HeaderInfoTable.cs | 171 -- .../Http/System.Net._HttpDateParse.cs | 494 ----- .../System.Net._InputNetworkStreamWrapper.cs | 761 ------- .../System.Net._OutputNetworkStreamWrapper.cs | 220 -- .../Http/System.Net._ValidationHelper.cs | 136 -- .../Http/System.Net.iwebproxy.cs | 38 - .../Http/System.Net.webproxy.cs | 237 -- .../Http/System.Uri.cs | 1060 --------- .../Properties/AssemblyInfo.cs | 17 - .../System.Net.Http.nfproj | 85 - .../packages.config | 7 - source/version.json | 26 - template.vssettings | 74 - 46 files changed, 2 insertions(+), 10233 deletions(-) delete mode 100644 .github_changelog_generator delete mode 100644 CHANGELOG.md delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 CONTRIBUTING.md delete mode 100644 appveyor-discord.ps1 delete mode 100644 appveyor.yml delete mode 100644 commit-assemblyinfo-changes.ps1 delete mode 100644 generate-change-log.ps1 delete mode 100644 install-vsix-appveyor.ps1 delete mode 100644 source/NuGet.Config delete mode 100644 source/key.snk delete mode 100644 source/nanoFramework.System.Net.Http.nuspec delete mode 100644 source/nanoFramework.System.Net.Http.sln delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.AuthenticationType.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.HttpListener.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerContext.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerRequest.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerResponse.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.HttpStatusCode.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.HttpVersion.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.HttpWebRequest.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.HttpWebResponse.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.IWebRequestCreate.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.Internal.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.NetworkCredential.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.ProtocolViolationException.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.WebException.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.WebHeaders.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.WebRequest.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.WebResponse.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.WebStatus.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net._HeaderInfo.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net._HeaderInfoTable.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net._HttpDateParse.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net._InputNetworkStreamWrapper.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net._OutputNetworkStreamWrapper.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net._ValidationHelper.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.iwebproxy.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Net.webproxy.cs delete mode 100644 source/nanoFramework.System.Net.Http/Http/System.Uri.cs delete mode 100644 source/nanoFramework.System.Net.Http/Properties/AssemblyInfo.cs delete mode 100644 source/nanoFramework.System.Net.Http/System.Net.Http.nfproj delete mode 100644 source/nanoFramework.System.Net.Http/packages.config delete mode 100644 source/version.json delete mode 100644 template.vssettings diff --git a/.github_changelog_generator b/.github_changelog_generator deleted file mode 100644 index 6e1fac72..00000000 --- a/.github_changelog_generator +++ /dev/null @@ -1,14 +0,0 @@ -user=nanoframework -project=lib-nanoFramework.System.Net.Http -issues=true -add_issues_wo_labels=false -add_pr_wo_labels=false -add_issues_wo_labels=false -filter_issues_by_milestone=false -exclude_labels=Area: Config-and-Build,Area: Infrastructure-and-Organization,reverted -enhancement_labels=Type: enhancement -bug_labels=Type: bug -merge_prefix=**Documentation and other chores:** -unreleased_label=**Changes available only in 'Preview' NuGet packages:** -issue_line_labels=Breaking-Change,documentation -author=false diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 872823be..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,13 +0,0 @@ -# Change Log - -## [**Changes available only in 'Preview' NuGet packages:**](https://github.com/nanoframework/lib-nanoFramework.System.Net.Http/tree/HEAD) - -**Documentation and other chores:** - -- Bumps nanoFramework.System.Net from 1.0.0 to 1.0.2-preview-004 [\#3](https://github.com/nanoframework/lib-nanoFramework.System.Net.Http/pull/3) -- Stop internal exception on close of output stream [\#2](https://github.com/nanoframework/lib-nanoFramework.System.Net.Http/pull/2) -- Work on CD/CI [\#1](https://github.com/nanoframework/lib-nanoFramework.System.Net.Http/pull/1) - - - -\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 7feff0a1..00000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contributor Code of Conduct - -Please refer to the contributor Code of Conduct at the Home repository [here](https://github.com/nanoframework/Home/blob/master/CODE_OF_CONDUCT.md. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 5a6a6c10..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contributing to **nanoFramework** - -Please refer to the contribution guidelines at the Home repository [here](https://github.com/nanoframework/Home/blob/master/CONTRIBUTING.md). diff --git a/README.md b/README.md index 7389d785..1e2fb3ae 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ | Component | Build Status | NuGet Package | |:-|---|---| -| System.Net.Http | [![Build status](https://ci.appveyor.com/api/projects/status/48swank708qq217f/branch/master?svg=true)](https://ci.appveyor.com/project/nfbot/lib-nanoframework-system-net-http/branch/master) | [![NuGet](https://img.shields.io/nuget/v/nanoFramework.System.Net.Http.svg)](https://www.nuget.org/packages/nanoFramework.System.Net.Http/) | -| System.Net.Http (preview) | [![Build status](https://ci.appveyor.com/api/projects/status/48swank708qq217f/branch/develop?svg=true)](https://ci.appveyor.com/project/nfbot/lib-nanoframework-system-net-http/branch/develop) | [![MyGet Pre Release](https://img.shields.io/myget/nanoframework-dev/vpre/nanoFramework.System.Net.Http.svg)](https://www.myget.org/feed/nanoframework-dev/package/nuget/nanoFramework.System.Net.Http) | +| System.Net.Http | [![Build status](https://ci.appveyor.com/api/projects/status/jw18rw9nibb41led/branch/master?svg=true)](https://ci.appveyor.com/project/nfbot/lib-system-net/branch/master) | [![NuGet](https://img.shields.io/nuget/vpre/nanoFramework.System.Net.Http.svg)](https://www.nuget.org/packages/nanoFramework.System.Net.Http/) | +| System.Net.Http (preview) | [![Build status](https://ci.appveyor.com/api/projects/status/jw18rw9nibb41led/branch/develop?svg=true)](https://ci.appveyor.com/project/nfbot/lib-system-net/branch/develop) | [![MyGet Pre Release](https://img.shields.io/myget/nanoframework-dev/vpre/nanoFramework.System.Net.Http.svg)](https://www.myget.org/feed/nanoframework-dev/package/nuget/nanoFramework.System.Net) | ## Feedback and documentation diff --git a/appveyor-discord.ps1 b/appveyor-discord.ps1 deleted file mode 100644 index a1ce8b91..00000000 --- a/appveyor-discord.ps1 +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright (c) 2017 The nanoFramework project contributors -# Portions Copyright (c) Sankarsan Kampa (a.k.a. k3rn31p4nic). All rights reserved. -# See LICENSE file in the project root for full license information. - -$STATUS=$args[0] -$WEBHOOK_URL=$args[1] - -Write-Output "[Webhook]: Sending webhook to Discord..." - -Switch ($STATUS) { - "success" { - $EMBED_COLOR=3066993 - $STATUS_MESSAGE="Passed" - Break - } - "failure" { - $EMBED_COLOR=15158332 - $STATUS_MESSAGE="Failed" - Break - } - default { - Write-Output "Default!" - Break - } -} - -if (!$env:APPVEYOR_REPO_COMMIT) { - $env:APPVEYOR_REPO_COMMIT="$(git log -1 --pretty="%H")" -} - -$AUTHOR_NAME="$(git log -1 "$env:APPVEYOR_REPO_COMMIT" --pretty="%aN")" -$COMMITTER_NAME="$(git log -1 "$env:APPVEYOR_REPO_COMMIT" --pretty="%cN")" -$COMMIT_SUBJECT="$(git log -1 "$env:APPVEYOR_REPO_COMMIT" --pretty="%s")" -$COMMIT_MESSAGE="$(git log -1 "$env:APPVEYOR_REPO_COMMIT" --pretty="%b")" - -if ($AUTHOR_NAME -eq $COMMITTER_NAME) { - $CREDITS = "$AUTHOR_NAME authored & committed" -} -else { - $CREDITS = "$AUTHOR_NAME authored & $COMMITTER_NAME committed" -} - -if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { - $URL="https://github.com/$env:APPVEYOR_REPO_NAME/pull/$env:APPVEYOR_PULL_REQUEST_NUMBER" -} -else { - $URL="" -} - -$BUILD_VERSION = [uri]::EscapeDataString($env:APPVEYOR_BUILD_VERSION) - -$WEBHOOK_DATA="{ - ""embeds"": [ { - ""color"": $EMBED_COLOR, - ""author"": { - ""name"": ""Job #$env:APPVEYOR_JOB_NUMBER (Build #$env:APPVEYOR_BUILD_NUMBER) $STATUS_MESSAGE - $env:APPVEYOR_REPO_NAME"", - ""url"": ""https://ci.appveyor.com/project/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/build/$BUILD_VERSION"", - ""icon_url"": ""$AVATAR"" - }, - ""title"": ""$COMMIT_SUBJECT"", - ""url"": ""$URL"", - ""description"": ""$COMMIT_MESSAGE $CREDITS"", - ""fields"": [ - { - ""name"": ""Commit"", - ""value"": ""[``$($env:APPVEYOR_REPO_COMMIT.substring(0, 7))``](https://github.com/$env:APPVEYOR_REPO_NAME/commit/$env:APPVEYOR_REPO_COMMIT)"", - ""inline"": true - }, - { - ""name"": ""Branch/Tag"", - ""value"": ""[``$env:APPVEYOR_REPO_BRANCH``](https://github.com/$env:APPVEYOR_REPO_NAME/tree/$env:APPVEYOR_REPO_BRANCH)"", - ""inline"": true - } - ] - } ], - ""content"" : """", - ""file"": """" -}" - -Invoke-RestMethod -Uri $WEBHOOK_URL -Method POST -UserAgent AppVeyor-Webhook -ContentType 'application/json' -Body $WEBHOOK_DATA - -Write-Output "[Webhook]: Successfully sent the webhook." diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 1dd4e1e0..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,164 +0,0 @@ -# configuration for all branches - -image: Visual Studio 2017 - -skip_tags: false - -skip_branch_with_pr: true - -test: off - -# Skipping commits affecting specific files -skip_commits: - files: - - '**\AssemblyInfo.*' - - '**/*.md' - - 'LICENSE' - - dir/* - - '.gitignore' - - 'azure-pipelines.yml' - -build: - verbosity: minimal - -environment: - APPVEYOR_IGNORE_COMMIT_FILTERING_ON_TAG: true - APPVEYOR_SAVE_CACHE_ON_ERROR: true - matrix: - - RUBY_VERSION: 24 - GitHubUserName: - secure: 7OBtVAMTodMWK20wg6pGnQ== - GitHubUserEmail: - secure: /NpmL1KqwHyHFnF0GlUovA586wDIt8Hg/Q8Dro6kUpk= - GitHubToken: - secure: i/2hGsqVMwzdM5yIS4rxOIeG3ftx7su7klWYN80s/fHvgk7A5H2fF3oUTNLcyTbw - GitRestAuth: - secure: E3bCMe4LtDdAhHSYRcLp0N6DixJe1m8TNxhYeJW/GnqM3WXdRqsgkHSbwootPjJQtOQJrps4twmzTVzofLSVgPgbzU8PxU0AkJV7zwkyVOE= - -init: -- git config --global core.autocrlf true -- git config --global credential.helper store -- ps: Add-Content "$env:USERPROFILE\.git-credentials" "https://$($env:GitHubToken):x-oauth-basic@github.com`n" -- git config --global user.email "%GitHubUserEmail%" -- git config --global user.name "%GitHubUserName%" - -install: -- set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH% -- bundle config --local path vendor/bundle -- gem install bundler --quiet --no-ri --no-rdoc -- gem install github_changelog_generator --quiet --no-ri --no-rdoc -- dotnet tool install --tool-path . nbgv -- ps: .\install-vsix-appveyor.ps1 - -before_build: -- ps: >- - - nuget sources add -name MyGet -Source https://www.myget.org/F/nanoframework-dev - - nuget restore source\nanoFramework.System.Net.Http.sln - - .\nbgv cloud -p source -a -c - -build_script: -- ps: msbuild source\nanoFramework.System.Net.Http.sln /p:PublicRelease=true /p:Configuration=Release /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" - -before_deploy: - - ps: >- - .\nbgv cloud --version=$env:NBGV_SemVer1 - - $env:MyNuGetVersion = $env:NBGV_NuGetPackageVersion -replace "\-g$env:NBGV_GitCommitIdShort", "" - - .\generate-change-log.ps1 - - - nuget pack source\nanoFramework.System.Net.Http.nuspec -Version %MyNuGetVersion% - - ps: >- - .\commit-assemblyinfo-changes.ps1 - - .\generate-change-log.ps1 - - Push-AppveyorArtifact $env:APPVEYOR_BUILD_FOLDER\nanoFramework.System.Net.Http.$env:MyNuGetVersion.nupkg - -after_deploy: -# for this environment variable to work here it has to be set in AppVeyor UI -- nuget push nanoFramework.System.Net.Http.%MyNuGetVersion%.nupkg %MyGetToken% -Source https://www.myget.org/F/nanoframework-dev/api/v2/package - -# requires APPVEYOR_DISCORD_WEBHOOK_URL enviroment variable set with Discord webhook URL -on_failure: - - ps: | - - & $env:APPVEYOR_BUILD_FOLDER\appveyor-discord.ps1 failure $env:APPVEYOR_DISCORD_WEBHOOK_URL - -cache: - - source\packages -> **source\packages.config - -################################################ -# override configuration for specific branches -for: - -- - branches: - only: - - master - - /v\d.*/ - - deploy: - - provider: NuGet - api_key: $(NuGetToken) - skip_symbols: true - on: - appveyor_repo_tag: true - - provider: GitHub - tag: v$(MyNuGetVersion) - release: nanoFramework System.Net.Http Library v$(MyNuGetVersion) - description: 'Check the [changelog](https://github.com/nanoframework/lib-nanoFramework.System.Net.Http/blob/$(appveyor_repo_branch)/CHANGELOG.md)\n\n## Install from NuGet\n\nThe following NuGet packages are available for download from this release\n\n:package: [.NET](https://www.nuget.org/packages/nanoFramework.System.Net.Http/$(MyNuGetVersion)) v$(MyNuGetVersion)' - auth_token: - secure: DNixoFFE+pGlwyhj7McfZoln42vOmj0iY1iNV9zXEr3y0NpXlOIgL8k5ehzlFM1S - artifact: - draft: true - prerelease: false - force_update: true - on: - appveyor_repo_tag: false - -- - branches: - only: - - /dev(elop)?$/ - - deploy: - - provider: GitHub - tag: v$(MyNuGetVersion) - release: nanoFramework System.Net.Http Library v$(MyNuGetVersion) - description: 'Check the [changelog](https://github.com/nanoframework/lib-nanoFramework.System.Net.Http/blob/$(appveyor_repo_branch)/CHANGELOG.md)\n\n## Install from nanoFramework MyGet development feed\n\nThe following NuGet packages are available for download from this release\n\n:package: [.NET](https://www.myget.org/feed/nanoframework-dev/package/nuget/nanoFramework.System.Net.Http/$(MyNuGetVersion)) v$(MyNuGetVersion)' - auth_token: - secure: DNixoFFE+pGlwyhj7McfZoln42vOmj0iY1iNV9zXEr3y0NpXlOIgL8k5ehzlFM1S - artifact: - draft: true - prerelease: true - force_update: true - on: - appveyor_repo_tag: false - -- - branches: - only: - - /release.*/ - - deploy: - - provider: NuGet - api_key: $(NuGetToken) - skip_symbols: true - on: - appveyor_repo_tag: true - - provider: GitHub - tag: v$(MyNuGetVersion) - release: nanoFramework System.Net.Http Library v$(MyNuGetVersion) - description: 'Check the [changelog](https://github.com/nanoframework/lib-nanoFramework.System.Net.Http/blob/$(appveyor_repo_branch)/CHANGELOG.md)\n\n## Install from NuGet\n\nThe following NuGet packages are available for download from this release\n\n:package: [.NET](https://www.nuget.org/packages/nanoFramework.System.Net.Http/$(MyNuGetVersion)) v$(MyNuGetVersion)' - auth_token: - secure: DNixoFFE+pGlwyhj7McfZoln42vOmj0iY1iNV9zXEr3y0NpXlOIgL8k5ehzlFM1S - artifact: - draft: true - prerelease: true - force_update: true - on: - appveyor_repo_tag: false diff --git a/commit-assemblyinfo-changes.ps1 b/commit-assemblyinfo-changes.ps1 deleted file mode 100644 index 9cf46a8c..00000000 --- a/commit-assemblyinfo-changes.ps1 +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2018 The nanoFramework project contributors -# See LICENSE file in the project root for full license information. - -# skip updating assembly info changes if build is a pull-request or not a tag (can't commit when repo is in a tag) -if ($env:appveyor_pull_request_number -or $env:APPVEYOR_REPO_TAG -eq "true") -{ - 'Skip committing assembly info changes...' | Write-Host -ForegroundColor White -} -else -{ - # updated assembly info files - git add "source\nanoFramework.System.Net.Http\Properties\AssemblyInfo.cs" - git commit -m "Update assembly info file for v$env:MyNuGetVersion" -m"[version update]" - git push origin --porcelain -q > $null - - 'Updated assembly info...' | Write-Host -ForegroundColor White -NoNewline - 'OK' | Write-Host -ForegroundColor Green - - # this assembly does not have native implementation, no updates requried in that repo -} diff --git a/generate-change-log.ps1 b/generate-change-log.ps1 deleted file mode 100644 index 7385c270..00000000 --- a/generate-change-log.ps1 +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) 2018 The nanoFramework project contributors -# See LICENSE file in the project root for full license information. - -# skip generating the change log when build is a pull-request or not a tag (can't commit when repo is in a tag) -if ($env:appveyor_pull_request_number -or $env:APPVEYOR_REPO_TAG -eq "true") -{ - 'Skip change log processing...' | Write-Host -ForegroundColor White -} -else -{ - # need this to keep ruby happy - md c:\tmp > $null - - if ($env:APPVEYOR_REPO_BRANCH -eq "master" -or $env:APPVEYOR_REPO_BRANCH -match "^release*") - { - # generate change log including future version - bundle exec github_changelog_generator --token $env:GitHubToken --future-release "v$env:NBGV_Version" - } - else - { - # generate change log - # version includes commits - bundle exec github_changelog_generator --token $env:GitHubToken - } - - # updated changelog, if there are any differences - $logDif = git diff CHANGELOG.md - - if($logDif -ne $null) - { - git add CHANGELOG.md - git commit -m "Update CHANGELOG for v$env:MyNuGetVersion" - # need to wrap the git command bellow so it doesn't throw an error because of redirecting the output to stderr - git push origin "HEAD:$env:APPVEYOR_REPO_BRANCH" --porcelain | Write-Host - } -} diff --git a/install-vsix-appveyor.ps1 b/install-vsix-appveyor.ps1 deleted file mode 100644 index 127c876d..00000000 --- a/install-vsix-appveyor.ps1 +++ /dev/null @@ -1,9 +0,0 @@ -$vsixPath = "$($env:USERPROFILE)\nanoFramework.Tools.VS2017.Extension.vsix" -(New-Object Net.WebClient).DownloadFile('https://marketplace.visualstudio.com/_apis/public/gallery/publishers/vs-publisher-1470366/vsextensions/nanoFrameworkVS2017Extension/0/vspackage', $vsixPath) -"`"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VSIXInstaller.exe`" /q /a $vsixPath" | out-file ".\install-vsix.cmd" -Encoding ASCII - -'Installing nanoFramework VS extension ...' | Write-Host -ForegroundColor White -NoNewline - -& .\install-vsix.cmd > $null - -'OK' | Write-Host -ForegroundColor Green diff --git a/source/NuGet.Config b/source/NuGet.Config deleted file mode 100644 index efc7d1b5..00000000 --- a/source/NuGet.Config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/source/key.snk b/source/key.snk deleted file mode 100644 index 67c9bb0ad77fd9cfb31a5fe1f8e4f6537f8883f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096IAgVrqn?0oVUK<}}z@wqRV>QE=V9G(P zv&4>n;N)r`28$iZ}__~(k83t)%SuJd!((DT{8XK)X~rK64E`*F3l z_5^K&AM;wi;^44^3SyC?622Htvk|)gU+)k0iCdaqB2%u@FR*KYku>(Zol_KusD7d= zA40qu=-~L94PXsGJ#eO@FlCr&O~0PO!6o-*GQq`zy7)g4B)IFgLhI0vfH=+L6i;`a zn(iWy{`8{{oj}vGf9S9M=48~NC!$coEAg@m^H3NXd_JrnT}HOd0AR%m^g zLg4+2jC7g-iYgo9N=!v@nv=I99O}eXu|AyULz5*Z*LDuQt4pP~UX|Zf`1Y#v4}kU8;^ac8l5!?oeMbz%wA_dHw*Ud81*FK}w1r zw3t~`4#bY+anQY5XU!i9#lc>IiLAxX~!c5@{0(|Buf%3XVh2FE%G?X~1 z7e5uWO?|rx0b=vcr3gpq3{-d$I8fk&Qrx<8j#tO3HOsxjGMJn4IT0*|11Oqu{gBd3 z&+6?KA|)R~alAn@8a!Y9Eq$TwFM@mu$U=dJ?PzCQY8jWLBlv^YEFIb8Fvhr*vMTOc zG+a5pRFEs9BT_>6MCF{WdN&DTsp^F!N=e1<>cRNkafH_Fr3`v9f%5G2(}LQ$j`vCM iwz?1qR;-^j3D_^H<{zl%^r6ivhR`zlIvhi1+jkY8izavg diff --git a/source/nanoFramework.System.Net.Http.nuspec b/source/nanoFramework.System.Net.Http.nuspec deleted file mode 100644 index 41c13469..00000000 --- a/source/nanoFramework.System.Net.Http.nuspec +++ /dev/null @@ -1,32 +0,0 @@ - - - - nanoFramework.System.Net.Http - $version$ - nanoFramework.System.Net.Http - nanoFramework project contributors - nanoFramework project contributors - false - - - false - https://github.com/nanoframework - https://secure.gravatar.com/avatar/97d0e092247f0716db6d4b47b7d1d1ad - Copyright (c) 2018 The nanoFramework project contributors - This package includes the nanoFramework.System.Net.Http assembly for nanoFramework C# projects. - nanoFramework.System.Net.Http assembly for nanoFramework C# projects - nanoFramework C# csharp netmf netnf nanoFramework.System.Net.Http - - - - - - - - - - - - - - \ No newline at end of file diff --git a/source/nanoFramework.System.Net.Http.sln b/source/nanoFramework.System.Net.Http.sln deleted file mode 100644 index 6385703a..00000000 --- a/source/nanoFramework.System.Net.Http.sln +++ /dev/null @@ -1,26 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28010.2041 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "System.Net.Http", "nanoFramework.System.Net.Http\System.Net.Http.nfproj", "{C3ABA656-9831-4006-A3B3-EA842A3C508E}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C3ABA656-9831-4006-A3B3-EA842A3C508E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C3ABA656-9831-4006-A3B3-EA842A3C508E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C3ABA656-9831-4006-A3B3-EA842A3C508E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C3ABA656-9831-4006-A3B3-EA842A3C508E}.Release|Any CPU.Build.0 = Release|Any CPU - {C3ABA656-9831-4006-A3B3-EA842A3C508E}.Release|Any CPU.Deploy.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {8D8B822C-5CC2-428E-A49B-E1D0E25B7A11} - EndGlobalSection -EndGlobal diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.AuthenticationType.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.AuthenticationType.cs deleted file mode 100644 index 1fd0d749..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.AuthenticationType.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - /// - /// Network authentication type. - /// Currently supports: - /// Basic Authentication - /// Microsoft Live Id Delegate Authentication - /// - public enum AuthenticationType - { - /// - /// - /// - Basic, - /// - /// - /// - WindowsLive - }; -} diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListener.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListener.cs deleted file mode 100644 index 76fc4697..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListener.cs +++ /dev/null @@ -1,675 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System.Collections; - using System.Net.Security; - using System.Net.Sockets; - using System.Security.Cryptography.X509Certificates; - using System.Threading; - - /// - /// Provides a simple, programmatically controlled HTTP protocol listener. - /// This class cannot be inherited. - /// - /// - /// This class enables using a socket to receive data that uses the HTTP - /// protocol. - /// - public class HttpListener - { - /// - /// Indicates whether the listener is waiting on an http or https - /// connection. - /// - bool m_IsHttpsConnection; - - /// - /// The certificate to send during https authentication. - /// - X509Certificate m_httpsCert; - - /// - /// This value is the number of connections that can be ready but are - /// not retrieved through the Accept call. - /// - /// - /// This value is passed to the Listen method of the socket. - /// - private const int MaxCountOfPendingConnections = 10; - - /// - /// The time we keep connection idle with HTTP 1.1 - /// This is one minute. - /// - internal const int DefaultKeepAliveMilliseconds = 60000; - - /// - /// Server socket for incoming connections. - /// - private Socket m_listener; - - /// - /// The MAXIMUM length, in kilobytes (1024 bytes), of the request - /// headers. - /// - internal int m_maxResponseHeadersLen; - - /// - /// Event that indicates arrival of new event from client. - /// - private AutoResetEvent m_RequestArrived; - - /// - /// The queue of connected networks streams with pending client data. - /// - Queue m_InputStreamsQueue; - - /// - /// Port number for the server socket. - /// - private int m_Port; - - /// - /// Indicates whether the listener is started and is currently accepting - /// connections. - /// - private bool m_ServiceRunning; - - /// - /// Indicates whether the listener has been closed - /// - private bool m_Closed; - - /// - /// Array of connected client sockets. - /// - private ArrayList m_ClientStreams; - - /// - /// Http Thread for accepting new connections. - /// - private Thread m_thAccept; - - /// - /// Creates an HTTP or HTTPS listener on the standard ports. - /// - /// Prefix ( http or https ) to start listen - /// In the desktop version of .NET, the constructor for this - /// class has no arguments. - public HttpListener(string prefix) - { - InitListener(prefix, -1); - } - - /// - /// Creates an HTTP or HTTPS listener on the specified port. - /// - /// The prefix for the service, either "http" or - /// "https". - /// The port to start listening on. If -1, the - /// default port is used (port 80 for http, or port 443 for https). - /// - /// In the desktop version of .NET, the constructor for this - /// class has no arguments. - public HttpListener(string prefix, int port) - { - InitListener(prefix, port); - } - - /// - /// Initializes the listener. - /// - /// The prefix for the service, either "http" or - /// "https". - /// The port to start listening on. If -1, the - /// default port is used (port 80 for http, or port 443 for https). - /// - private void InitListener(string prefix, int port) - { - switch (prefix.ToLower()) - { - case "http": - { - m_IsHttpsConnection = false; - m_Port = Uri.HttpDefaultPort; - break; - } - case "https": - { - m_IsHttpsConnection = true; - m_Port = Uri.HttpsDefaultPort; - break; - } - default: throw new ArgumentException("Prefix should be http or https"); - } - - if (port != -1) - { - m_Port = port; - } - - // Default members initialization - m_maxResponseHeadersLen = 4; - m_RequestArrived = new AutoResetEvent(false); - m_InputStreamsQueue = new Queue(); - m_ClientStreams = new ArrayList(); - } - - /// - /// Adds a new output stream to the list of connected streams. - /// - /// This is an internal function, not visible to the user. - /// - /// The stream to add. - internal void AddClientStream(OutputNetworkStreamWrapper clientStream) - { - lock(m_ClientStreams) - { - m_ClientStreams.Add(clientStream); - } - } - - /// - /// Removes the specified output stream from the list of connected - /// streams. - /// - /// The stream to remove. - internal void RemoveClientStream(OutputNetworkStreamWrapper clientStream) - { - lock(m_ClientStreams) - { - for (int i = 0; i < m_ClientStreams.Count; i++) - { - if (clientStream == m_ClientStreams[i]) - { - m_ClientStreams.RemoveAt(i); - break; - } - } - } - } - - /// - /// Packages together an HttpListener and a socket. - /// - /// This class is used to package together an HttpListener and a socket. - /// We need to start new thread and pass 2 parameters - instance of listener and socket. - /// For that purpose we create class that keeps references to both listerner and socket and - /// start thread using member function of this class as delegate. - /// Internal class not visible to user. - private class HttpListernerAndStream - { - internal HttpListernerAndStream(HttpListener listener, OutputNetworkStreamWrapper outputStream) - { - m_listener = listener; - m_outStream = outputStream; - } - - internal HttpListener m_listener; - internal OutputNetworkStreamWrapper m_outStream; - - // Forwards to waiting function of the listener. - internal void AddToWaitingConnections() - { - m_listener.WaitingConnectionThreadFunc(m_outStream); - } - } - - internal void AddToWaitingConnections(OutputNetworkStreamWrapper outputStream) - { - // Create a thread that blocks onsocket.Poll - basically waits for new data from client. - HttpListernerAndStream listAndSock = new HttpListernerAndStream(this, outputStream); - - // Creates new thread to wait on data - Thread thWaitData = new Thread(listAndSock.AddToWaitingConnections); - thWaitData.Start(); - } - - private void WaitingConnectionThreadFunc2() - { - try - { - Console.WriteLine("test"); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - } - /// - /// Waits for new data from the client. - /// - private void WaitingConnectionThreadFunc(OutputNetworkStreamWrapper outputStream) - { - try - { - // This is a blocking call waiting for more data. - outputStream.m_Socket.Poll(DefaultKeepAliveMilliseconds * 1000, SelectMode.SelectRead); - - if (outputStream.m_Socket.Available > 0) - { - - // Add this connected stream to the list. - lock (m_InputStreamsQueue) - { - m_InputStreamsQueue.Enqueue(outputStream); - } - - // Set event that client stream or exception is added to the queue. - m_RequestArrived.Set(); - } - else // If no data available - means connection was close on other side or timed out. - { - outputStream.Dispose(); - } - } - catch(Exception ex) - { - Console.WriteLine(ex.Message); - } - } - - /// - /// Shuts down the HttpListener object immediately, - /// discarding all currently queued requests. - /// - /// This method disposes of all resources held by this - /// listener. Any pending requests are unable to complete. To shut - /// down the HttpListener object after processing - /// currently queued requests, use the - /// method. - /// - /// After calling this method, you will receive an - /// if you attempt to use this - /// HttpListener. - /// - /// - public void Abort() - { - lock (this) - { - // First we shut down the service. - Close(); - - // Now we need to go through list of all client sockets and close all of them. - // This will cause exceptions on read/write operations on these sockets. - foreach (OutputNetworkStreamWrapper netStream in m_ClientStreams) - { - netStream.Close(); - } - m_ClientStreams.Clear(); - } - - if (m_thAccept != null) - { - m_thAccept.Join(); - } - } - - /// - /// Waits for new connections from the client. - /// - /// On new connections, this method enques the new input - /// network stream and sets an event that a new connection is available. - /// - private void AcceptThreadFunc() - { - Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; - // If there was no exception up to this point, means we succeded to start listening. - m_ServiceRunning = true; - int retry = 0; - - // The Start function is waiting on this event. We set it to indicate that - // thread that waits for connections is already started. - m_RequestArrived.Set(); - - // The value of m_serviceStarted normally is changed from other thread by calling Stop. - while (m_ServiceRunning) - { - Socket clientSock; - // Need to create NetworkStream or SSL stream depending on protocol used. - NetworkStream netStream = null; - - try - { - // It is important that multithread access to m_listener.Accept(); is not locked. - // If it was locked - then Close or Stop would be blocked potnetially for ever while waiting for connection. - // This is a blocking call waiting for connection. - clientSock = m_listener.Accept(); - - retry = 0; - try - { - // set NoDelay to increase HTTP(s) response times - clientSock.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); - } - catch - { - - } - } - catch (SocketException) - { - if (retry > 5) - { - // If request to stop listener flag is set or locking call is interupted return - // On exception we stop the service and record the exception. - if (m_ServiceRunning && !m_Closed) - { - Stop(); - } - - // Set event to unblock thread waiting for accept. - m_RequestArrived.Set(); - - break; - } - - retry++; - continue; - } - catch - { - // If request to stop listener flag is set or locking call is interupted return - // On exception we stop the service and record the exception. - if (m_ServiceRunning && !m_Closed) - { - Stop(); - } - - // Set event to unblock thread waiting for accept. - m_RequestArrived.Set(); - - break; - } - - try - { - if (!m_IsHttpsConnection) - { - // This is case of normal HTTP. Create network stream. - netStream = new NetworkStream(clientSock, true); - } - else - { - // This is the case of https. - // Once connection estiblished need to create secure stream and authenticate server. - netStream = new SslStream(clientSock); - - SslProtocols[] sslProtocols = new SslProtocols[] { SslProtocols.Default }; - - // Throws exception if fails. - ((SslStream)netStream).AuthenticateAsServer(m_httpsCert, SslVerification.NoVerification, sslProtocols); - - netStream.ReadTimeout = 10000; - } - } - catch(SocketException) - { - if (netStream != null) - { - netStream.Dispose(); - } - else - { - clientSock.Close(); - } - - m_RequestArrived.Set(); - - // try again - continue; - } - - // Add this connected stream to the list. - lock (m_InputStreamsQueue) - { - m_InputStreamsQueue.Enqueue(new OutputNetworkStreamWrapper(clientSock, netStream)); - } - - // Set event that client stream or exception is added to the queue. - m_RequestArrived.Set(); - } - } - - /// - /// Allows this instance to receive incoming requests. - /// - /// This method must be called before you call the - /// method. If - /// the service was already started, the call has no effect. After you - /// have started an HttpListener object, you can use - /// the method to stop it. - /// - public void Start() - { - lock (this) - { - if (m_Closed) throw new ObjectDisposedException(); - - // If service was already started, the call has no effect. - if (m_ServiceRunning) - { - return; - } - - m_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - try - { - // set NoDelay to increase HTTP(s) response times - m_listener.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); - } - catch {} - - try - { - // Start server socket to accept incoming connections. - m_listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - } - catch {} - - IPAddress addr; - - // FIXME - /// if(System.Hardware.SystemInfo.IsEmulator) - // { - // addr = IPAddress.Any; - // } - // else - { - // addr = IPAddress.GetDefaultLocalAddress(); - addr = IPAddress.Any; - } - - IPEndPoint endPoint = new IPEndPoint(addr, m_Port); - m_listener.Bind(endPoint); - - // Starts to listen to maximum of 10 connections. - m_listener.Listen(MaxCountOfPendingConnections); - - // Create a thread that blocks on m_listener.Accept() - basically waits for connection from client. - m_thAccept = new Thread(AcceptThreadFunc); - m_thAccept.Start(); - - // Waits for thread that calls Accept to start. - m_RequestArrived.WaitOne(); - } - } - - /// - /// Shuts down the HttpListener after processing all - /// currently queued requests. - /// - /// After calling this method, you can no longer use the - /// HttpListener object. To temporarily pause an - /// HttpListener object, use the - /// method. - public void Close() - { - lock(this) - { - // close does not throw - try - { - Stop(); - } - catch - { - } - - m_Closed = true; - } - } - - /// - /// Causes this instance to stop receiving incoming requests. - /// - /// If this instance is already stopped, calling this method - /// has no effect. - /// - /// After you have stopped an HttpListener object, - /// you can use the method - /// to restart it. - /// - /// - public void Stop() - { - // Need to lock access to object, because Stop can be called from a - // different thread. - lock (this) - { - if (m_Closed) throw new ObjectDisposedException(); - - m_ServiceRunning = false; - - // We close the server socket that listen for incoming connection. - // Connections that already accepted are processed. - // Connections that has been in queue for server socket, but not accepted, are lost. - if(m_listener != null) - { - m_listener.Close(); - m_listener = null; - - m_RequestArrived.Set(); - } - } - } - - /// - /// Waits for an incoming request and returns when one is received. - /// - /// - /// An object that - /// represents a client request. - /// - /// A socket call failed. Check the - /// exception's ErrorCode property to determine the cause of the exception. - /// This object has not been started or is - /// currently stopped or The HttpListener does not have any Uniform Resource Identifier - /// (URI) prefixes to respond to. - /// This object is closed. - /// This example shows how to call the - /// GetContext method. - /// - /// HttpListener myListener = new HttpListener("http", -1); - /// myListener.Start(); - /// while (true) - /// { - /// HttpListenerResponse response = null; - /// try - /// { - /// Debug.Print("Waiting for requests"); - /// HttpListenerContext context = myListener.GetContext(); - /// - /// - public HttpListenerContext GetContext() - { - // Protects access for simulteneous call for GetContext and Close or Stop. - lock (this) - { - if (m_Closed) throw new ObjectDisposedException(); - - if (!m_ServiceRunning) throw new InvalidOperationException(); - } - - // Try to get context until service is running. - while (m_ServiceRunning) - { - // Before waiting for event we need to look for pending connections. - lock (m_InputStreamsQueue) - { - if (m_InputStreamsQueue.Count > 0) - { - OutputNetworkStreamWrapper outputStreamWrap = m_InputStreamsQueue.Dequeue() as OutputNetworkStreamWrapper; - if (outputStreamWrap != null) - { - return new HttpListenerContext(outputStreamWrap, this); - } - } - } - - // Waits for new connection to arrive on new or existing socket. - m_RequestArrived.WaitOne(); - } - - return null; - } - - /// - /// Gets whether the HttpListener service was started - /// and is waiting for client connections. - /// - /// true if the - /// HttpListener was started; otherwise, - /// false. - public bool IsListening - { - get { return m_ServiceRunning; } - } - - /// - /// Gets or sets the maximum allowed length of the response headers, in - /// KB. - /// - /// The length, in kilobytes (1024 bytes), of the response - /// headers. - /// - /// The length of the response header includes the response status line - /// and any extra control characters that are received as part of the - /// HTTP protocol. A value of -1 means no limit is imposed on the - /// response headers; a value of 0 means that all requests fail. If - /// this property is not explicitly set, it defaults to 4 (KB). - /// - public int MaximumResponseHeadersLength - { - get { return m_maxResponseHeadersLen; } - set - { - if (value <= 0 && value != -1) - { - throw new ArgumentOutOfRangeException(); - } - - m_maxResponseHeadersLen = value; - } - } - - /// - /// The certificate used if HttpListener implements an https - /// server. - /// - public X509Certificate HttpsCert - { - get { return m_httpsCert; } - set { m_httpsCert = value; } - } - } -} - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerContext.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerContext.cs deleted file mode 100644 index 0b15a3dc..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerContext.cs +++ /dev/null @@ -1,191 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System.Net.Sockets; - - /// - /// Provides access to the request and response objects used by the - /// HttpListener class. This class cannot be inherited. - /// - public class HttpListenerContext - { - /// - /// A flag that indicates whether an HTTP request was parsed. - /// - /// - /// The HTTP request is parsed upon the first access to the Request to - /// Response property. Access to that property might be done from a - /// different thread than the thread that is used for construction of - /// the HttpListenerContext. - /// - bool m_IsHTTPRequestParsed; - - /// - /// Member with network stream connected to client. - /// This stream is used for writing data. - /// This stream owns the socket. - /// - private OutputNetworkStreamWrapper m_clientOutputStream; - - /// - /// Member with network stream connected to client. - /// This stream is used for Reading data. - /// This stream does not own the socket. - /// - private InputNetworkStreamWrapper m_clientInputStream; - - /// - /// Instance of the request from client. - /// it is a server side representation of HttpWebRequest. - /// It is the same data, but instead of composing request we parse it. - /// - private HttpListenerRequest m_ClientRequest; - - /// - /// Instance of the response to client. - /// - /// - private HttpListenerResponse m_ResponseToClient; - - /// - /// Internal constructor, used each time client connects. - /// - /// The stream that is connected to the client. A stream is needed, to - /// provide information about the connected client. - /// See also the class. - /// - /// TBD - internal HttpListenerContext(OutputNetworkStreamWrapper clientStream, HttpListener httpListener) - { - // Saves the stream. - m_clientOutputStream = clientStream; - - // Input stream does not own socket. - m_clientInputStream = new InputNetworkStreamWrapper(clientStream.m_Stream, clientStream.m_Socket, false, null); - - // Constructs request and response classes. - m_ClientRequest = new HttpListenerRequest(m_clientInputStream, httpListener.m_maxResponseHeadersLen); - - // Closing reponse to client causes removal from clientSocketsList. - // Thus we need to pass clientSocketsList to client response. - m_ResponseToClient = new HttpListenerResponse(m_clientOutputStream, httpListener); - - // There is incoming connection HTTP connection. Add new Socket to the list of connected sockets - // The socket is removed from this array after correponding HttpListenerResponse is closed. - httpListener.AddClientStream(m_clientOutputStream); - - // Set flag that HTTP request was not parsed yet. - // It will be parsed on first access to m_ClientRequest or m_ResponseToClient - m_IsHTTPRequestParsed = false; - } - - public void Reset() - { - m_IsHTTPRequestParsed = false; - m_ClientRequest.Reset(); - } - - /// - /// Gets the HttpListenerRequest that represents a - /// client's request for a resource. - /// - /// An HttpListenerRequest object that - /// represents the client request. - public HttpListenerRequest Request - { - get - { - if (!m_IsHTTPRequestParsed) - { - m_ClientRequest.ParseHTTPRequest(); - // After request parsed check for "transfer-ecoding" header. If it is chunked, change stream property. - // If m_EnableChunkedDecoding is set to true, then readig from stream automatically processing chunks. - string chunkedVal = m_ClientRequest.Headers[HttpKnownHeaderNames.TransferEncoding]; - if (chunkedVal != null && chunkedVal.ToLower() == "chunked") - { - m_clientInputStream.m_EnableChunkedDecoding = true; - } - - m_IsHTTPRequestParsed = true; - } - - return m_ClientRequest; - } - } - - /// - /// Gets the HttpListenerResponse object that will be - /// sent to the client in response to the client's request. - /// - /// An HttpListenerResponse object used to - /// send a response back to the client. - public HttpListenerResponse Response - { - get - { - if (!m_IsHTTPRequestParsed) - { - m_ClientRequest.ParseHTTPRequest(); - m_IsHTTPRequestParsed = true; - } - - return m_ResponseToClient; - } - } - - public void Close() - { - Close(-2); - } - - /// - /// Closes the stream attached to this listener context. - /// - public void Close(int lingerValue) - { - try - { - if (m_clientOutputStream != null) - { - try - { - if (m_clientOutputStream.m_Socket != null) - { - m_clientOutputStream.m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lingerValue); - } - } - catch { } - } - - if (m_ResponseToClient != null) - { - m_ResponseToClient.Close(); - m_ResponseToClient = null; - } - - // Close the underlying stream - if (m_clientOutputStream != null) - { - m_clientOutputStream.Dispose(); - m_clientOutputStream = null; - } - - if (m_clientInputStream != null) - { - m_clientInputStream.Dispose(); - m_clientInputStream = null; - } - } - catch - { - } - } - } -} - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerRequest.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerRequest.cs deleted file mode 100644 index ac42a630..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerRequest.cs +++ /dev/null @@ -1,438 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System; - using System.IO; - - /// - /// Describes an incoming HTTP request to an - /// object. - /// - /// - /// When a client makes a request to a Uniform Resource Identifier (URI) - /// handled by an HttpListener object, the - /// HttpListener provides an - /// object that contains - /// information about the sender, the request, and the response that is sent - /// to the client. The - /// property returns the HttpListenerRequest object that - /// describes the request. - /// - /// The HttpListenerRequest object contains information - /// about the request, such as the request - /// string, - /// string, and - /// request body data (see the - /// - /// property). - /// - /// To reply to the request, you must get the associated response using the - /// property. - /// - public class HttpListenerRequest - { - /// - /// The original string with the request. For example, - /// "GET /Index.htm HTTP/1.1". - /// - private string m_RequestString; - - /// - /// The maximum length of the request headers, in KB (1024 bytes). - /// - private int m_maxResponseHeadersLen; - - /// - /// The verb of the request parsed from m_RequestString. - /// - private string m_requestVerb; - - /// - /// URL of request parsed from m_RequestString. - /// - private string m_rawURL; - - /// - /// HTTP version from m_RequestString. - /// - private Version m_requestHttpVer; - - /// - /// Indicates whether the client requests a persistent connection. - /// If client did not specify "Connection" header - default is false. - /// - private bool m_KeepAlive = false; - - /// - /// The request Headers From HTTP client. - /// - private WebHeaderCollection m_httpRequestHeaders = new WebHeaderCollection(true); - - /// - /// Member with network stream connected to client. - /// - /// - private InputNetworkStreamWrapper m_clientStream; - - /// - /// The length of the content in the body of the request, if a body is - /// present. - /// - long m_contentLength; - - /// - /// Keep NetworkCredential if user have send user name and password. - /// - private NetworkCredential m_NetworkCredentials; - - /// - /// Constructs a HttpListenerRequest is created by HttpListenerContext. - /// - /// Network stream to the client. - /// TBD - internal HttpListenerRequest(InputNetworkStreamWrapper clientStream, int maxHeaderLen) - { - m_clientStream = clientStream; - - // maxHeaderLen is in kilobytes (Desktop designer decided so). If -1 just maximum integer value - m_maxResponseHeadersLen = maxHeaderLen == -1 ? 0x7FFFFFFF : maxHeaderLen * 1024; - // If not set, default for content length is -1 - m_contentLength = -1; - } - - public void Reset() - { - m_httpRequestHeaders = new WebHeaderCollection(true); - m_contentLength = -1; - } - - /// - /// Parses request from client. - /// Fills - /// - HTTP Verb. - /// - HTTP version. - /// - Content Length. - /// - Fills generic value name pair in WEB header collection. - /// - internal void ParseHTTPRequest() - { - // This is the request line. - m_RequestString = m_clientStream.Read_HTTP_Line(HttpWebRequest.maxHTTPLineLength).Trim(); - - // Split request line into 3 strings - VERB, URL and HTTP version. - char[] delimiter = { ' ' }; - string[] requestStr = m_RequestString.Split(delimiter); - // requestStr should consist of 3 parts. - if (requestStr.Length < 3) - { - throw new ProtocolViolationException("Invalid HTTP request String: " + m_RequestString); - } - - // We have at least 3 strings. Fills the proper fields - m_requestVerb = requestStr[0]; - m_rawURL = requestStr[1]; - - // Process third string. It should be either http/1.1 or http/1.0 - string httpVerLowerCase = requestStr[2].ToLower(); - if (httpVerLowerCase.Equals("http/1.1")) - { - m_requestHttpVer = HttpVersion.Version11; - } - else if (httpVerLowerCase.Equals("http/1.0")) - { - m_requestHttpVer = HttpVersion.Version10; - } - else - { - throw new ProtocolViolationException("Unsupported HTTP version: " + requestStr[2]); - } - - // Now it is list of HTTP headers: - string line; - int headersLen = m_maxResponseHeadersLen; - while ((line = m_clientStream.Read_HTTP_Header(HttpWebRequest.maxHTTPLineLength)).Length > 0) - { - // line.Length is used for the header. Substruct it. - headersLen -= line.Length; - // If total length used for header is exceeded, we break - - if (headersLen < 0) - { - throw new ProtocolViolationException("Http Headers exceeding: " + m_maxResponseHeadersLen); - } - - int sepIdx = line.IndexOf(':'); - if (sepIdx == -1) - { - throw new ProtocolViolationException("Invalid HTTP Header: " + line); - } - - string headerName = line.Substring(0, sepIdx).Trim(); - string headerValue = line.Substring(sepIdx + 1).Trim(); - string matchableHeaderName = headerName.ToLower(); - // Adds new header to collection. - m_httpRequestHeaders.AddInternal(headerName, headerValue); - - // Now we check the value - name pair. For some of them we need to initilize member variables. - headerName = headerName.ToLower(); - // If it is connection header - if (headerName == "connection") - { - // If value is "Keep-Alive" ( lower case now ), set m_KeepAlive to true; - headerValue = headerValue.ToLower(); - m_KeepAlive = headerValue == "keep-alive"; - } - - // If user supplied user name and password - parse it and store in m_NetworkCredentials - if (headerName == "authorization") - { - int sepSpace = headerValue.IndexOf(' '); - string authType = headerValue.Substring(0, sepSpace); - if (authType.ToLower() == "basic") - { - string authInfo = headerValue.Substring(sepSpace + 1); - // authInfo is base64 encoded username and password. - byte[] authInfoDecoded = Convert.FromBase64String(authInfo); - char[] authInfoDecChar = System.Text.Encoding.UTF8.GetChars(authInfoDecoded); - string strAuthInfo = new string(authInfoDecChar); - // The strAuthInfo comes in format username:password. Parse it. - int sepColon = strAuthInfo.IndexOf(':'); - if (sepColon != -1) - { - m_NetworkCredentials = new NetworkCredential(strAuthInfo.Substring(0, sepColon), strAuthInfo.Substring(sepColon + 1)); - } - } - } - } - - // Http headers were processed. Now we search for content length. - string strContentLen = m_httpRequestHeaders[HttpKnownHeaderNames.ContentLength]; - if (strContentLen != null) - { - try - { - m_contentLength = Convert.ToInt32(strContentLen); - } - catch (Exception) - { - throw new ProtocolViolationException("Invalid content length in request: " + strContentLen); - } - } - } - - /// - /// Gets the HTTP method specified by the client. - /// - /// A String that contains the method used in - /// the request. - public string HttpMethod - { - get { return m_requestVerb; } - } - - /// - /// Gets the URL information (without the host and port) requested by - /// the client. - /// - /// A String that contains the raw URL for - /// this request. - /// - /// This URL information is the URL requested in the first request line. - /// - public string RawUrl - { - get { return m_rawURL; } - } - - /// - /// Gets the MIME types accepted by the client. - /// - /// A String array that contains the type - /// names specified in the request's Accept header, or a null reference - /// if the client request did not include an Accept header. - public string[] AcceptTypes - { - get { return m_httpRequestHeaders.GetValues(HttpKnownHeaderNames.Accept); } - } - - /// - /// Gets the length of the body data included in the request. - /// - /// - /// The Content-Length header expresses the length, in bytes, of the - /// body data that accompanies the request. - /// enumeration. - /// - /// The value from the request's Content-Length header. This - /// value is -1 if the content length is not known. - public long ContentLength64 - { - get { return m_contentLength; } - } - - /// - /// Gets the MIME type of the body data included in the request. - /// - /// A String that contains the text of the - /// request's Content-Type header. - public string ContentType - { - get { return m_httpRequestHeaders[HttpKnownHeaderNames.ContentType]; } - } - - /// - /// Gets the collection of header name/value pairs sent in the request. - /// - /// A WebHeaderCollection that contains the - /// HTTP headers included in the request. - public WebHeaderCollection Headers - { - get { return m_httpRequestHeaders; } - } - - /// - /// Gets a stream that contains the body data sent by the client. - /// - /// A readable Stream object that contains the - /// bytes sent by the client in the body of the request. This property - /// returns Null if no data is sent with the request. - /// - public Stream InputStream - { - get { return m_clientStream; } - } - - /// - /// Gets a Boolean value that indicates whether the client sending this - /// request is authenticated. - /// - /// - /// Because authentication is not supported, returns - /// false. - /// - /// Because authentication is not supported, returns - /// false. - public bool IsAuthenticated - { - get { return false; } - } - - /// - /// Gets a value that indicates whether the - /// client requests a persistent connection. - /// - /// - /// This property is set during parsing of HTTP header. - /// - /// true if the connection should be kept - /// open; otherwise, false. - public bool KeepAlive - { - get { return m_KeepAlive; } - } - - /// - /// Gets the server IP address and port number to which the request is - /// directed. Not currently supported. - /// - /// An IPEndPoint that represents the IP - /// address that the request is sent to. - /// - public IPEndPoint LocalEndPoint - { - get { return (IPEndPoint)m_clientStream.m_Socket.LocalEndPoint; } - } - - /// - /// Gets the HTTP version used by the requesting client. - /// - /// - /// The capabilities of different HTTP versions are specified in the - /// documents available at http://www.rfc-editor.org. - /// - /// A Version that identifies the client's - /// version of HTTP. - public Version ProtocolVersion - { - get { return m_requestHttpVer; } - } - - /// - /// Gets the client IP address and port number from which the request - /// originated. - /// - /// An IPEndPoint that represents the IP - /// address and port number from which the request originated. - public IPEndPoint RemoteEndPoint - { - get { return (IPEndPoint)m_clientStream.m_Socket.RemoteEndPoint; } - } - - /// - /// Gets the Uri object requested by the client. Not currently - /// supported. - /// - public Uri Url { get { return new Uri(m_rawURL, UriKind.Relative); } } - - /// - /// Gets the user agent presented by the client. - /// - /// A String object that contains the text of - /// the request's User-Agent header. - /// - /// - public string UserAgent - { - get { return m_httpRequestHeaders[HttpKnownHeaderNames.UserAgent]; } - } - - /// - /// Gets the server IP address and port number to which the request is - /// directed. - /// - /// A String that contains the host address - /// information. - public string UserHostAddress - { - get { return ((IPEndPoint)m_clientStream.m_Socket.LocalEndPoint).Address.ToString(); } - } - - /// - /// Gets the DNS name and, if provided, the port number specified by the - /// client. - /// - /// A String value that contains the text of the request's Host header. - public string UserHostName - { - get { return m_httpRequestHeaders[HttpKnownHeaderNames.UserAgent]; } - } - - /// - /// Return NetworkCredential if user have send user name and password. - /// - public NetworkCredential Credentials - { - get { return m_NetworkCredentials; } - } - - /// - /// Gets the natural languages that are preferred for the response. - /// - /// A String array that contains the languages - /// specified in the request's AcceptLanguage header, - /// or null if the client request did not include an - /// AcceptLanguage header. - public string[] UserLanguages - { - get { return m_httpRequestHeaders.GetValues(HttpKnownHeaderNames.AcceptLanguage); } - } - - } -} - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerResponse.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerResponse.cs deleted file mode 100644 index ecfb2ec4..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpListenerResponse.cs +++ /dev/null @@ -1,539 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System; - using System.IO; - using System.Text; - - /// - /// Represents a response to a request being handled by an - /// object. - /// - public sealed class HttpListenerResponse : IDisposable - { - /// - /// A flag that indicates whether the response was already sent. - /// - private bool m_WasResponseSent = false; - - /// - /// A flag that indicates that the response was closed. - /// Writing to client is not allowed after response is closed. - /// - private bool m_IsResponseClosed = false; - - /// - /// The length of the content of the response. - /// - long m_ContentLength = -1; - - /// - /// The response headers from the HTTP client. - /// - private WebHeaderCollection m_httpResponseHeaders = new WebHeaderCollection(true); - - /// - /// The HTTP version for the response. - /// - private Version m_version = new Version(1, 1); - - /// - /// Indicates whether the server requests a persistent connection. - /// Persistent connection is used if KeepAlive is true - /// in both the request and the response. - /// - private bool m_KeepAlive = false; - - /// - /// Encoding for this response's OutputStream. - /// - private Encoding m_Encoding = Encoding.UTF8; - - /// - /// Keeps content type for the response, set by user application. - /// - private string m_contentType; - - /// - /// Response status code. - /// - private int m_ResponseStatusCode = (int)HttpStatusCode.OK; - - /// - /// Array of connected client streams - /// - private HttpListener m_Listener; - - /// - /// Member with network stream connected to client. - /// After call to Close() the stream is closed, no further writing allowed. - /// - private OutputNetworkStreamWrapper m_clientStream; - - /// - /// The value of the HTTP Location header in this response. - /// - private string m_redirectLocation; - - /// - /// Response uses chunked transfer encoding. - /// - private bool m_sendChunked = false; - - /// - /// text description of the HTTP status code returned to the client. - /// - private string m_statusDescription; - - /// - /// Throws InvalidOperationException is HTTP response was sent. - /// Called before setting of properties. - /// - private void ThrowIfResponseSent() - { - if (m_WasResponseSent) - { - throw new InvalidOperationException(); - } - } - - /// - /// HttpListenerResponse is created by HttpListenerContext - /// - /// Network stream to the client - /// TBD - internal HttpListenerResponse(OutputNetworkStreamWrapper clientStream, HttpListener httpListener) - { - // Sets the delegate, so SendHeaders will be called on first write. - clientStream.HeadersDelegate = new OutputNetworkStreamWrapper.SendHeadersDelegate(SendHeaders); - // Saves network stream as member. - m_clientStream = clientStream; - // Saves list of client streams. m_clientStream is removed from clientStreamsList during Close(). - m_Listener = httpListener; - } - - /// - /// Updates the HTTP WEB header collection to prepare it for request. - /// For each property set it adds member to m_httpResponseHeaders. - /// m_httpResponseHeaders is serializes to string and sent to client. - /// - private void PrepareHeaders() - { - // Adds content length if it was present. - if (m_ContentLength != -1) - { - m_httpResponseHeaders.ChangeInternal(HttpKnownHeaderNames.ContentLength, m_ContentLength.ToString()); - } - - // Since we do not support persistent connection, send close always. - string connection = m_KeepAlive ? "Keep-Alive" : "Close"; - m_httpResponseHeaders.ChangeInternal(HttpKnownHeaderNames.Connection, connection); - - // Adds content type if user set it: - if (m_contentType != null) - { - m_httpResponseHeaders.AddWithoutValidate(HttpKnownHeaderNames.ContentType, m_contentType); - } - - if (m_redirectLocation != null) - { - m_httpResponseHeaders.AddWithoutValidate(HttpKnownHeaderNames.Location, m_redirectLocation); - m_ResponseStatusCode = (int)HttpStatusCode.Redirect; - } - } - - /// - /// Composes HTTP response line based on - /// - /// - private string ComposeHTTPResponse() - { - // Starts with HTTP - string resp = "HTTP/"; - // Adds version of HTTP - resp += m_version.ToString(); - // Add status code. - resp += " " + m_ResponseStatusCode; - // Adds description - if (m_statusDescription == null) - { - resp += " " + GetStatusDescription(m_ResponseStatusCode); - } - else // User provided description is present. - { - resp += " " + m_statusDescription; - } - - // Add line termindation. - resp += "\r\n"; - return resp; - } - - /// - /// Sends HTTP status and headers to client. - /// - private void SendHeaders() - { - // As first step we disable the callback to SendHeaders, so m_clientStream.Write would not call - // SendHeaders() again. - m_clientStream.HeadersDelegate = null; - - // Creates encoder, generates headers and sends the data. - Encoding encoder = Encoding.UTF8; - - byte[] statusLine = encoder.GetBytes(ComposeHTTPResponse()); - m_clientStream.Write(statusLine, 0, statusLine.Length); - - // Prepares/Updates WEB header collection. - PrepareHeaders(); - - // Serialise WEB header collection to byte array. - byte[] pHeaders = m_httpResponseHeaders.ToByteArray(); - - // Sends the headers - m_clientStream.Write(pHeaders, 0, pHeaders.Length); - - m_WasResponseSent = true; - } - - /// - /// Gets or sets the HTTP status code to be returned to the client. - /// - /// An Int32 value that specifies the - /// for the requested resource. - /// The default is OK, indicating that the server - /// successfully processed the client's request and included the - /// requested resource in the response body. - public int StatusCode - { - get { return m_ResponseStatusCode; } - set - { - ThrowIfResponseSent(); - m_ResponseStatusCode = value; - } - } - - /// - /// Gets or sets the number of bytes in the body data included in the - /// response. - /// - /// The value of the response's Content-Length - /// header. - public long ContentLength64 - { - get { return m_ContentLength; } - - set - { - ThrowIfResponseSent(); - m_ContentLength = value; - } - } - - /// - /// Gets or sets the collection of header name/value pairs that is - /// returned by the server. - /// - /// A WebHeaderCollection instance that - /// contains all the explicitly set HTTP headers to be included in the - /// response. - public WebHeaderCollection Headers - { - get { return m_httpResponseHeaders; } - set - { - ThrowIfResponseSent(); - m_httpResponseHeaders = value; - } - } - - /// - /// Gets or sets whether the server requests a persistent connection. - /// - /// true if the server requests a persistent - /// connection; otherwise, false. The default is - /// true. - public bool KeepAlive - { - get { return m_KeepAlive; } - - set { m_KeepAlive = value; } - } - - /// - /// Gets a Stream object to which a response can be - /// written. - /// - /// A Stream object to which a response can be - /// written. - /// - /// The first write to the output stream sends a response to the client. - /// - public Stream OutputStream - { - get - { - if (m_IsResponseClosed) - { - throw new ObjectDisposedException("Response has been sent"); - } - - return m_clientStream; - } - } - - /// - /// Gets or sets the HTTP version that is used for the response. - /// - /// A Version object indicating the version of - /// HTTP used when responding to the client. This property is obsolete. - /// - public Version ProtocolVersion - { - get { return m_version; } - set - { - ThrowIfResponseSent(); - m_version = value; - } - } - - /// - /// Gets or sets the value of the HTTP Location - /// header in this response. - /// - /// A String that contains the absolute URL to - /// be sent to the client in the Location header. - /// - public string RedirectLocation - { - get { return m_redirectLocation; } - set - { - ThrowIfResponseSent(); - m_redirectLocation = value; - } - } - - /// - /// Gets or sets whether the response uses chunked transfer encoding. - /// - /// true if the response is set to use chunked - /// transfer encoding; otherwise, false. The default - /// is false. - public bool SendChunked - { - get { return m_sendChunked; } - set - { - ThrowIfResponseSent(); - m_sendChunked = value; - } - } - - /// - /// Gets or sets the encoding for this response's - /// OutputStream. - /// - /// An Encoding object suitable for use with - /// the data in the - /// property, - /// or null reference if no encoding is specified. - /// - /// - /// Only UTF8 encoding is supported. - /// - public Encoding ContentEncoding - { - get { return m_Encoding; } - set - { - ThrowIfResponseSent(); - m_Encoding = value; - } - } - - /// - /// Gets or sets the MIME type of the returned content. - /// - /// A String instance that contains the text - /// of the response's Content-Type header. - public string ContentType - { - get { return m_contentType; } - set - { - ThrowIfResponseSent(); - m_contentType = value; - } - } - - /// - /// Gets or sets a text description of the HTTP status code that is - /// returned to the client. - /// - /// The text description of the HTTP status code returned to the - /// client. - public string StatusDescription - { - get { return m_statusDescription; } - set - { - ThrowIfResponseSent(); - m_statusDescription = value; - } - } - - public void Detach() - { - if (!m_IsResponseClosed) - { - if (!m_WasResponseSent) - { - SendHeaders(); - } - - m_IsResponseClosed = true; - } - } - - /// - /// Sends the response to the client and releases the resources held by - /// this HttpListenerResponse instance. - /// - /// - /// This method flushes data to the client and closes the network - /// connection. - /// - public void Close() - { - if (!m_IsResponseClosed) - { - try - { - if (!m_WasResponseSent) - { - SendHeaders(); - } - } - finally - { - // Removes from the list of streams and closes the socket. - ((IDisposable)this).Dispose(); - } - } - } - - /// - /// Closes the socket and sends the response if it was not done earlier - /// and the socket is present. - /// - void IDisposable.Dispose() - { - if (!m_IsResponseClosed) - { - try - { - // Iterates over list of client connections and remove its stream from it. - m_Listener.RemoveClientStream(m_clientStream); - - m_clientStream.Flush(); - - // If KeepAlive is true, - if (m_KeepAlive) - { // Then socket is tramsferred to the list of waiting for new data. - m_Listener.AddToWaitingConnections(m_clientStream); - } - else // If not KeepAlive then close - { - m_clientStream.Dispose(); - } - } - catch { } - - m_IsResponseClosed = true; - } - - GC.SuppressFinalize(this); - } - - /// - /// Called to close the socket if necessary. - /// - ~HttpListenerResponse() - { - ((IDisposable)this).Dispose(); - } - - /// - /// Return default Description based in response status code. - /// - /// HTTP status code - /// - /// Default string with description. - /// - internal static string GetStatusDescription(int code) - { - switch (code) - { - case 100: return "Continue"; - case 101: return "Switching Protocols"; - case 102: return "Processing"; - case 200: return "OK"; - case 201: return "Created"; - case 202: return "Accepted"; - case 203: return "Non-Authoritative Information"; - case 204: return "No Content"; - case 205: return "Reset Content"; - case 206: return "Partial Content"; - case 207: return "Multi-Status"; - case 300: return "Multiple Choices"; - case 301: return "Moved Permanently"; - case 302: return "Found"; - case 303: return "See Other"; - case 304: return "Not Modified"; - case 305: return "Use Proxy"; - case 307: return "Temporary Redirect"; - case 400: return "Bad Request"; - case 401: return "Unauthorized"; - case 402: return "Payment Required"; - case 403: return "Forbidden"; - case 404: return "Not Found"; - case 405: return "Method Not Allowed"; - case 406: return "Not Acceptable"; - case 407: return "Proxy Authentication Required"; - case 408: return "Request Timeout"; - case 409: return "Conflict"; - case 410: return "Gone"; - case 411: return "Length Required"; - case 412: return "Precondition Failed"; - case 413: return "Request Entity Too Large"; - case 414: return "Request-Uri Too Long"; - case 415: return "Unsupported Media Type"; - case 416: return "Requested Range Not Satisfiable"; - case 417: return "Expectation Failed"; - case 422: return "Unprocessable Entity"; - case 423: return "Locked"; - case 424: return "Failed Dependency"; - case 500: return "Internal Server Error"; - case 501: return "Not Implemented"; - case 502: return "Bad Gateway"; - case 503: return "Service Unavailable"; - case 504: return "Gateway Timeout"; - case 505: return "Http Version Not Supported"; - case 507: return "Insufficient Storage"; - } - - return ""; - } - - } -} - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpStatusCode.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.HttpStatusCode.cs deleted file mode 100644 index f353f9ee..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpStatusCode.cs +++ /dev/null @@ -1,300 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - - -namespace System.Net -{ - - // Any int can be cast to a HttpStatusCode to allow checking for non http1.1 - // codes. - - /// - /// Contains the values of status codes defined for HTTP. - /// - /// - ///

Status codes indicate categories, as follows:

- ///

1xx -- Informational.

- ///

2xx -- Successful.

- ///

3xx -- Redirection.

- ///

4xx -- Client Error.

- ///

5xx -- Server Error.

- ///
- public enum HttpStatusCode - { - - /// Informational -- 1xx. - /// Equivalent to HTTP status 100. Indicates that the client can continue with its - /// request. - Continue = 100, - /// Equivalent to HTTP status 101. Indicates that the protocol version or protocol - /// is being changed. - SwitchingProtocols = 101, - - /// Successful -- 2xx. - /// Equivalent to HTTP status 200. Indicates that the request succeeded and that - /// the requested information is in the response. This is the most common status code to - /// receive. - OK = 200, - /// Equivalent to HTTP status 201. Indicates that the request resulted in a new - /// resource created before the response was sent. - Created = 201, - /// Equivalent to HTTP status 202. Indicates that the request has been accepted for - /// further processing. - Accepted = 202, - /// Equivalent to HTTP status 203. Indicates that the returned metainformation is - /// from a cached copy instead of the origin server and therefore may be incorrect. - NonAuthoritativeInformation = 203, - /// Equivalent to HTTP status 204. Indicates that the request has been successfully - /// processed and that the response is intentionally blank. - NoContent = 204, - /// Equivalent to HTTP status 205. Indicates that the client should reset (not - /// reload) the current resource. - ResetContent = 205, - /// Equivalent to HTTP status 206. Indicates that the response is a - /// partial response as requested by a GET request that includes a byte range. - PartialContent = 206, - - /// Redirection -- 3xx. - /// Equivalent to HTTP status 300. Indicates that the requested information has - /// multiple representations. The default action is to treat this status as a redirect and - /// follow the contents of the Location header associated with this response. - /// If the property is - /// false, MultipleChoices will cause an exception to - /// be thrown. - /// MultipleChoices is a synonym for Ambiguous. - MultipleChoices = 300, - /// Equivalent to HTTP status 300. Indicates that the requested - /// information has multiple representations. The default action is to treat this status as - /// a redirect and follow the contents of the Location header associated with this response. - /// If the property is - /// false, Ambiguous will cause an exception to be - /// thrown. - /// Ambiguous is a synonym for MultipleChoices. - Ambiguous = 300, - /// Equivalent to HTTP status 301. Indicates that the requested information has - /// been moved to the URI specified in the Location header. The default action when this - /// status is received is to follow the Location header associated with the response. - /// MovedPermanently is a synonym for Moved. - MovedPermanently = 301, - /// Equivalent to HTTP status 301. Indicates that the requested information - /// has been moved to the URI specified in the Location header. The default action when this - /// status is received is to follow the Location header associated with the response. When - /// the original request method was POST, the redirected request will use the GET method. - /// Moved is a synonym for MovedPermanently. - Moved = 301, - /// Equivalent to HTTP status 302. Indicates that the requested information is - /// located at the URI specified in the Location header. The default action when this status - /// is received is to follow the Location header associated with the response. When the - /// original request method was POST, the redirected request will use the GET method. - /// If the property is - /// false, Found will cause an exception to be thrown. - /// Found is a synonym for Redirect. - Found = 302, - /// Equivalent to HTTP status 302. Indicates that the requested information is - /// located at the URI specified in the Location header. The default action when this status - /// is received is to follow the Location header associated with the response. When the - /// original request method was POST, the redirected request will use the GET method. - /// If the property is - /// false, Redirect will cause an exception to be - /// thrown. - /// Redirect is a synonym for Found. - Redirect = 302, - /// Equivalent to HTTP status 303. Automatically redirects the client to - /// the URI specified in the Location header as the result of a POST. The request to the - /// resource specified by the Location header will be made with a GET. - /// If the property is - /// false, SeeOther will cause an exception to be - /// thrown. - /// SeeOther is a synonym for RedirectMethod. - SeeOther = 303, - /// Equivalent to HTTP status 303. Automatically redirects the - /// client to the URI specified in the Location header as the result of a POST. The request - /// to the resource specified by the Location header will be made with a GET. - /// If the property is - /// false, RedirectMethod will cause an exception to - /// be thrown. - /// RedirectMethod is a synonym for SeeOther. - RedirectMethod = 303, - /// Equivalent to HTTP status 304. Indicates that the client's cached copy is - /// up-to-date. The contents of the resource are not transferred. - NotModified = 304, - /// Equivalent to HTTP status 305. Indicates that the request should use the proxy - /// server at the URI specified in the Location header. - UseProxy = 305, - /// Equivalent to HTTP status 306. This value is a proposed extension to the HTTP/1.1 - /// specification that is not fully specified. - Unused = 306, - /// Equivalent to HTTP status 307. Indicates that the request information is - /// located at the URI specified in the Location header. The default action when this status - /// is received is to follow the Location header associated with the response. When the - /// original request method was POST, the redirected request will also use the POST method. - /// If the property is - /// false, TemporaryRedirect will cause an exception - /// to be thrown. - /// TemporaryRedirect is a synonym for RedirectKeepVerb. - TemporaryRedirect = 307, - /// Equivalent to HTTP status 307. Indicates that the request - /// information is located at the URI specified in the Location header. The default action - /// when this status is received is to follow the Location header associated with the - /// response. When the original request method was POST, the redirected request will also - /// use the POST method. - /// If the property is - /// false, RedirectKeepVerb will cause an exception to - /// be thrown. - /// RedirectKeepVerb is a synonym for TemporaryRedirect. - RedirectKeepVerb = 307, - - /// Client Error -- 4xx. - /// Equivalent to HTTP status 400. Indicates that the request could not be - /// understood by the server. BadRequest is sent when no other error is - /// applicable, or if the exact error is unknown or does not have its own error code. - BadRequest = 400, - /// Equivalent to HTTP status 401. Indicates that the requested - /// resource requires authentication. The WWW-Authenticate header contains the details of - /// how to perform the authentication. - Unauthorized = 401, - /// Equivalent to HTTP status 402. Reserved for future use. - PaymentRequired = 402, - /// Equivalent to HTTP status 403. Indicates that the server refuses to - /// fulfill the request. - Forbidden = 403, - /// Equivalent to HTTP status 404. Indicates that the requested resource - /// does not exist on the server. - NotFound = 404, - /// Equivalent to HTTP status 405. Indicates that the request - /// method (POST or GET) is not allowed on the requested resource. - MethodNotAllowed = 405, - /// Equivalent to HTTP status 406. Indicates that the client has - /// indicated with Accept headers that it will not accept any of the available - /// representations of the resource. - NotAcceptable = 406, - /// Equivalent to HTTP status 407. Indicates that the - /// requested proxy requires authentication. The Proxy-authenticate header contains the - /// details of how to perform the authentication. - ProxyAuthenticationRequired = 407, - /// Equivalent to HTTP status 408. Indicates that the client did not - /// send a request within the time the server was expecting the request. - RequestTimeout = 408, - /// Equivalent to HTTP status 409. Indicates that the request could not be - /// carried out because of a conflict on the server. - Conflict = 409, - /// Equivalent to HTTP status 410. Indicates that the requested resource is no - /// longer available. - Gone = 410, - /// Equivalent to HTTP status 411. Indicates that the required - /// Content-length header is missing. - LengthRequired = 411, - /// Equivalent to HTTP status 412. Indicates that a condition - /// set for this request failed, and the request cannot be carried out. Conditions are set - /// with conditional request headers like If-Match, If-None-Match, or If-Unmodified-Since. - PreconditionFailed = 412, - /// Equivalent to HTTP status 413. Indicates that the request - /// is too large for the server to process. - RequestEntityTooLarge = 413, - /// Equivalent to HTTP status 414. Indicates that the URI is too - /// long. - RequestUriTooLong = 414, - /// Equivalent to HTTP status 415. Indicates that the request - /// is an unsupported type. - UnsupportedMediaType = 415, - /// Equivalent to HTTP status 416. Indicates that the - /// range of data requested from the resource cannot be returned, either because the - /// beginning of the range is before the beginning of the resource, or the end of the range - /// is after the end of the resource. - RequestedRangeNotSatisfiable = 416, - /// Equivalent to HTTP status 417. Indicates that an expectation - /// given in an Expect header could not be met by the server. - ExpectationFailed = 417, - - /// Server Error -- 5xx. - /// Equivalent to HTTP status 500. Indicates that a generic - /// error has occurred on the server. - InternalServerError = 500, - /// Equivalent to HTTP status 501. Indicates that the server does - /// not support the requested function. - NotImplemented = 501, - /// Equivalent to HTTP status 502. Indicates that an intermediate proxy - /// server received a bad response from another proxy or the origin server. - BadGateway = 502, - /// Equivalent to HTTP status 503. Indicates that the server is - /// temporarily unavailable, usually due to high load or maintenance. - ServiceUnavailable = 503, - /// Equivalent to HTTP status 504. Indicates that an intermediate - /// proxy server timed out while waiting for a response from another proxy or the origin - /// server. - GatewayTimeout = 504, - /// Equivalent to HTTP status 505. Indicates that the - /// requested HTTP version is not supported by the server. - HttpVersionNotSupported = 505, - - }; // enum HttpStatusCode - - /// - /// Range for the HTTP status codes. - /// - internal enum HttpStatusRange - { - /// TBD - MaxOkStatus = 299, - /// TBD - MaxRedirectionStatus = 399 - }; // enum HttpStatusRange - - /* - Fielding, et al. Standards Track [Page 3] - - RFC 2616 HTTP/1.1 June 1999 - - 10.1 Informational 1xx ...........................................57 - 10.1.1 100 Continue .............................................58 - 10.1.2 101 Switching Protocols ..................................58 - 10.2 Successful 2xx ..............................................58 - 10.2.1 200 OK ...................................................58 - 10.2.2 201 Created ..............................................59 - 10.2.3 202 Accepted .............................................59 - 10.2.4 203 Non-Authoritative Information ........................59 - 10.2.5 204 No Content ...........................................60 - 10.2.6 205 Reset Content ........................................60 - 10.2.7 206 Partial Content ......................................60 - 10.3 Redirection 3xx .............................................61 - 10.3.1 300 Multiple Choices .....................................61 - 10.3.2 301 Moved Permanently ....................................62 - 10.3.3 302 Found ................................................62 - 10.3.4 303 See Other ............................................63 - 10.3.5 304 Not Modified .........................................63 - 10.3.6 305 Use Proxy ............................................64 - 10.3.7 306 (Unused) .............................................64 - 10.3.8 307 Temporary Redirect ...................................65 - 10.4 Client Error 4xx ............................................65 - 10.4.1 400 Bad Request .........................................65 - 10.4.2 401 Unauthorized ........................................66 - 10.4.3 402 Payment Required ....................................66 - 10.4.4 403 Forbidden ...........................................66 - 10.4.5 404 Not Found ...........................................66 - 10.4.6 405 Method Not Allowed ..................................66 - 10.4.7 406 Not Acceptable ......................................67 - 10.4.8 407 Proxy Authentication Required .......................67 - 10.4.9 408 Request Timeout .....................................67 - 10.4.10 409 Conflict ............................................67 - 10.4.11 410 Gone ................................................68 - 10.4.12 411 Length Required .....................................68 - 10.4.13 412 Precondition Failed .................................68 - 10.4.14 413 Request Entity Too Large ............................69 - 10.4.15 414 Request-URI Too Long ................................69 - 10.4.16 415 Unsupported Media Type ..............................69 - 10.4.17 416 Requested Range Not Satisfiable .....................69 - 10.4.18 417 Expectation Failed ..................................70 - 10.5 Server Error 5xx ............................................70 - 10.5.1 500 Internal Server Error ................................70 - 10.5.2 501 Not Implemented ......................................70 - 10.5.3 502 Bad Gateway ..........................................70 - 10.5.4 503 Service Unavailable ..................................70 - 10.5.5 504 Gateway Timeout ......................................71 - 10.5.6 505 HTTP Version Not Supported ...........................71 - */ -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpVersion.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.HttpVersion.cs deleted file mode 100644 index 72dacbec..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpVersion.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - - -namespace System.Net -{ - - /// - /// Defines the HTTP version numbers that are supported by the - /// and - /// classes. - /// - public class HttpVersion - { - - /// - /// Defines a instance for HTTP 1.0. - /// - public static readonly Version Version10 = new Version(1, 0); - - /// - /// Defines a instance for HTTP 1.1. - /// - public static readonly Version Version11 = new Version(1, 1); - - } // class HttpVersion - -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpWebRequest.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.HttpWebRequest.cs deleted file mode 100644 index 414638dc..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpWebRequest.cs +++ /dev/null @@ -1,1957 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System; - using System.Collections; - using System.IO; - using System.Net.Security; - using System.Net.Sockets; - using System.Security.Cryptography.X509Certificates; - using System.Text; - using System.Threading; - - /// - /// This is the class that we use to create HTTP and requests. - /// Used to register prefix "http" with WEB Request class. - /// - internal class HttpRequestCreator : IWebRequestCreate - { - internal HttpRequestCreator() - { - } - - /// - /// Creates an HttpWebRequest. We register - /// for HTTP and HTTPS URLs, and this method is called when a request - /// needs to be created for one of those. - /// - /// Url for request being created. - /// The newly created HttpWebRequest. - public WebRequest Create(Uri Url) - { - - return new HttpWebRequest(Url); - } - - } // class HttpRequestCreator - - /// - /// Provides an HTTP-specific implementation of the class. - /// - /// This class does the main work of the request: it collects the header information - /// from the user, exposes the Stream for outgoing entity data, and processes the incoming - /// request. - public class HttpWebRequest : WebRequest - { - - /// - /// Array list of connected streams. - /// This is static list, keeps all "stay live" sockets. - /// - internal static ArrayList m_ConnectedStreams; - - /// - /// Timer that checks on open connections and closes them if they are - /// idle for a long time. - /// - static Timer m_DropOldConnectionsTimer; - - /// - /// If a response was created then Dispose on the Request will not dispose the underlying stream. - /// - private bool m_responseCreated; - - /// - /// Timer callback. Called periodically and closes all connections that - /// are idle for long time. - /// - /// Unused - static private void CheckPersistentConnections(object unused) - { - int count = m_ConnectedStreams.Count; - // The fastest way to exit out - if there are no sockets in the list - exit out. - if (count > 0) - { - DateTime curTime = DateTime.UtcNow; - lock (m_ConnectedStreams) - { - count = m_ConnectedStreams.Count; - - for (int i = count-1; i >= 0; i--) - { - InputNetworkStreamWrapper streamWrapper = (InputNetworkStreamWrapper)m_ConnectedStreams[i]; - - TimeSpan timePassed = streamWrapper.m_lastUsed - curTime; - - // If the socket is old, then close and remove from the list. - if (timePassed.Milliseconds > HttpListener.DefaultKeepAliveMilliseconds) - { - m_ConnectedStreams.RemoveAt(i); - - // Closes the socket to release resources. - streamWrapper.Dispose(); - } - } - - // turn off the timer if there are no active streams - if(m_ConnectedStreams.Count > 0) - { - m_DropOldConnectionsTimer.Change( HttpListener.DefaultKeepAliveMilliseconds, System.Threading.Timeout.Infinite ); - } - } - } - } - - /// - /// Registers HttpRequestCreator as the creator for the "http" prefix. - /// - static HttpWebRequest() - { - // Creates instance of HttpRequestCreator. HttpRequestCreator creates HttpWebRequest - HttpRequestCreator Creator = new HttpRequestCreator(); - // Register prefix. HttpWebRequest handles both http and https - RegisterPrefix("http:", Creator); - RegisterPrefix("https:", Creator); - if (m_ConnectedStreams == null) - { - // Creates new list for connected sockets. - m_ConnectedStreams = new ArrayList(); - m_DropOldConnectionsTimer = new Timer(CheckPersistentConnections, null, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); - } - } - - /// - /// Closes a response stream, if present. - /// - /// Not used. - protected override void Dispose(bool disposing) - { - if(m_requestStream != null) - { - if(!m_responseCreated) - { - RemoveStreamFromPool(m_requestStream); - - m_requestStream.Dispose(); - } - } - - base.Dispose(disposing); - } - - - /// - /// The length in KB of the default maximum for response headers - /// received. - /// - /// - /// The default configuration file sets this value to 4 kilobytes. - /// - static int defaultMaxResponseHeadersLen = 4; - - /// - /// Default delay on the Stream.Read and Stream.Write operations - /// - private const int DefaultReadWriteTimeout = 5 * 60 * 1000; // 5 minutes - - /// - /// maximum length of the line in reponse line - /// - internal const int maxHTTPLineLength = 4000; - - /// - /// Delegate that can be called on Continue Response - /// - private HttpContinueDelegate m_continueDelegate; - - /// - /// HTTP verb. - /// - private string m_method; - - /// - /// The Headers for the HTTP request. - /// - private WebHeaderCollection m_httpRequestHeaders; - - /// - /// Controls how writes are handled. - /// - private HttpWriteMode m_httpWriteMode; - - /// - /// The URI that we do the request for. - /// - private Uri m_originalUrl; - - /// - /// Content length of the request message on POST. - /// - private long m_contentLength; - - /// - /// The HTTP version for this request. - /// - private Version m_version; - - /// - /// Timeout for Read And Write on the Stream that we return through - /// GetResponse().GetResponseStream() and GetRequestStream() - /// - private int m_readWriteTimeout; - - /// - /// Proxy to use for connection. - /// - private IWebProxy m_proxy; - - /// - /// Whether to use persistent connections. - /// - private bool m_keepAlive; - - /// - /// An array of certificates used to verify servers that support https. - /// - /// - /// The client application sets these certificates to the - /// HttpWebRequest. When the server certificate is received, it - /// is validated with certificates in this array. - /// - X509Certificate[] m_caCerts; - - /// - /// The number of people using the connection. Must reference-count this - /// stuff. Except reference counting is apparently insufficient. I'm going to flag each section - /// that uses the parser with a constant, and twiddle the flags for - /// adding and removing connections. - /// - internal const int k_noConnection = 0x0; - private const int k_parserFlag = 0x1; - private const int k_writeStreamFlag = 0x2; - private const int k_readStreamFlag = 0x4; - private const int k_abortFlag = 0x8; - internal int m_connectionUsers = 0; - - /// - /// Static instance of decoder to convert received bytes from network - /// stream into text of the response line and WEB headers. - /// - static private Decoder UTF8decoder = System.Text.Encoding.UTF8.GetDecoder(); - - /// - /// Invalid characters that cannot be found in a valid method-verb. - /// - private static readonly char[] k_invalidMethodChars = - new char[]{' ', - '\r', - '\t', - '\n'}; - - /// - /// The maximum length, in kilobytes (1024 bytes), of the response - /// headers. - /// - private int m_maxResponseHeadersLen = defaultMaxResponseHeadersLen; - - /// - /// The response from the server. - /// - private HttpStatusCode m_responseStatus = (HttpStatusCode)0; - - /// - /// true if we have a response, or a transport error while constructing the response - /// - private bool m_responseComplete = false; - - /// - /// This is non-null if there was an error. If this is true, then there is no valid HttpWebResponse. - /// - private WebException m_errorResponse = null; - - /// - /// Buffer size for reading from the server - /// - private const int k_readBlockLength = 2048; - - /// - /// This is the maximum amount of data which can be buffered at any time - /// and have a failed match. In other words, if we receive this much - /// data, and can't parse it in any useful way, assume an error. - /// - private const int k_maximumBufferSize = 8192; - - /// - /// True if the request has been started, false otherwise. Disables - /// setting of many header properties. - /// - private bool m_requestSent; - - /// - /// This is the request stream, if it has been created. - /// - private InputNetworkStreamWrapper m_requestStream; - - /// - /// Whether or not data should be buffered when sent. - /// Data is always buffered though (given redirects and stuff). - /// - private bool m_allowWriteStreamBuffering; - - /// - /// The timeout value for this request. - /// - private int m_timeout; - - /// - /// Keep NetworkCredential if user have send user name and password. - /// - private NetworkCredential m_NetworkCredentials; - - /// - /// Gets or sets the timeout value in milliseconds for the - /// and - /// methods. - /// - /// The number of milliseconds to wait before the request times - /// out. The default is 100,000 milliseconds (100 seconds). - /// - /// Overrides the property - /// of WebRequest. - public override int Timeout - { - get - { - return m_timeout; - } - - set - { - if (value < 0 && value != System.Threading.Timeout.Infinite) - { - throw new ArgumentOutOfRangeException("value"); - } - - m_timeout = value; - } - } - - /// - /// Set or Get NetworkCredential if user have send user name and password. - /// - public NetworkCredential Credentials - { - get { return m_NetworkCredentials; } - set { m_NetworkCredentials = value; } - } - - /// - /// Gets or sets the array of certificates used to authenticate https - /// servers. These certificates are used only for https connections; - /// http connections do not require them. - /// - public X509Certificate[] HttpsAuthentCerts - { - get { return m_caCerts; } - set { m_caCerts = value; } - } - - /// - /// Gets or sets a timeout in milliseconds when writing to or reading - /// from a stream. - /// - /// The number of milliseconds before the writing or reading - /// times out. The default value is 300,000 milliseconds (5 minutes). - /// - /// This property is used to control the timeout when calling - /// and . - /// This property affects Streams returned from - /// GetResponse().() - /// and - /// GetResponse().(). - /// - public int ReadWriteTimeout - { - get - { - return m_readWriteTimeout; - } - - set - { - // we can't change timeouts after the request has been sent - if (m_requestSent) - throw new InvalidOperationException("Cannot change timeout after request submitted "); - if (value <= 0 && value != System.Threading.Timeout.Infinite) - { - throw new ArgumentOutOfRangeException("value"); - } - - m_readWriteTimeout = value; - } - } - - /// - /// The HTTP status code returned by the server. - /// - internal HttpStatusCode ResponseStatusCode - { - get - { - return m_responseStatus; - } - } - - /// - /// Return if error is present in response. - /// - /// true if error happened, false otherwise - internal bool hasError() - { - return m_errorResponse != null; - } - - /// - /// Gets the original Uniform Resource Identifier (URI) of the request. - /// - /// - /// The URI object was created by the constructor and is always - /// non-null. The URI object will always be the base URI, because - /// automatic re-directs aren't supported. - /// - /// A Uri that contains the URI of the Internet resource passed - /// to the WebRequest. method. - /// - public override Uri RequestUri - { - get - { - return m_originalUrl; - } - } - - /// - /// Gets the URI for this request. - /// - /// A Uri that identifies the Internet - /// resource that actually responds to the request. The default is the - /// URI used by the - /// WebRequest. method to - /// initialize the request. - /// - /// - /// This value is always the same as the - /// - /// property, because automatic re-direction isn't supported. - /// - public Uri Address - { - get - { - return m_originalUrl; - } - } - - /// - /// Gets or sets a value that indicates whether to buffer the data sent - /// to the Internet resource. - /// - /// true to enable buffering of the data sent - /// to the Internet resource; false to disable buffering. The - /// default is true. - public bool AllowWriteStreamBuffering - { - - get - { - return m_allowWriteStreamBuffering; - } - - set - { - m_allowWriteStreamBuffering = value; - } - } - - /// - /// Gets or sets the Content-Length of the request entity body. - /// - /// The number of bytes of data to send to the Internet resource. - /// The default is -1, which indicates the property has not been set and - /// that there is no request data to send. - /// - /// Getting this property returns the last value set, or -1 if no value - /// has been set. Setting it sets the content length, and the - /// application must write that much data to the stream. This property - /// interacts with - /// HttpWebRequest.. - /// - public override long ContentLength - { - get - { - return m_contentLength; - } - - set - { - //no race. Don't need interlocked - if (true == m_requestSent) - throw new InvalidOperationException(); - - if (value < 0) - throw new ArgumentOutOfRangeException("Content length cannot be negative: " + value); - - m_contentLength = value; - //if a content length is set, then we cannot send chunked data. - m_httpWriteMode = HttpWriteMode.Write; - } - } - - /// - /// Gets or sets the delegate used to signal on Continue callback. - /// - /// A delegate that implements the callback method that executes - /// when an HTTP Continue response is returned from the Internet - /// resource. The default value is null. - /// - /// This property gets or sets the delegate method called when an HTTP - /// 100-continue response is received from the Internet resource. - /// - public HttpContinueDelegate ContinueDelegate - { - get { return m_continueDelegate; } - set { m_continueDelegate = value; } - } - - /// - /// Gets a value that indicates whether the request should follow - /// redirection responses. This value is always - /// false, because Autodirect isn't supported. - /// - /// This value is always false, because - /// Autodirect isn't supported. - public bool AllowAutoRedirect - { - get - { - return false; - } - } - - /// - /// Gets the maximum number of automatic redirections. This value is - /// always zero, because auto-redirection isn't supported. - /// - /// This value is always zero, because auto-redirection isn't - /// supported. - public int MaximumAutomaticRedirections - { - get - { - return 0; - } - } - - /// - /// Gets or sets the HTTP method of this request. - /// - /// The request method to use to contact the Internet resource. - /// The default value is GET. - /// - /// This method represents the initial origin verb, which is unchanged - /// and unaffected by redirects. - /// - public override string Method - { - get - { - return m_method; - } - - set - { - if (ValidationHelper.IsBlankString(value)) - { - throw new ArgumentException("Blank Method Set: " + value); - } - - if (value.IndexOfAny(k_invalidMethodChars) != -1) - { - throw new ArgumentException("Invalid Method Set: " + value); - } - - m_method = value; - } - } - - /// - /// Gets or sets whether to use a persistent connection, if available. - /// - /// true if the request to the Internet resource should - /// contain a Connection HTTP header with the value Keep-alive; - /// otherwise, false. The default is true. - public bool KeepAlive - { - get - { - return m_keepAlive; - } - - set - { - m_keepAlive = value; - } - } - - /// - /// Gets or sets the maximum allowed length of the response headers. - /// - /// The length, in kilobytes (1024 bytes), of the response - /// headers. - /// - /// The length of the response header includes the response status line - /// and any extra control characters that are received as part of HTTP - /// protocol. A value of -1 means no limit is imposed on the response - /// headers; a value of 0 means that all requests fail. If this - /// property is not explicitly set, it defaults to the value of the - /// - /// property. - /// - public int MaximumResponseHeadersLength - { - get { return m_maxResponseHeadersLen; } - set - { - if (value <= 0 && value != -1) - { - throw new ArgumentOutOfRangeException(); - } - - m_maxResponseHeadersLen = value; - } - } - - /// - /// Gets or sets the default maximum allowed length of the response - /// headers. - /// - /// The default maximum allowed length of the response headers. - /// - /// - /// On creation of an HttpWebRequest instance, this - /// value is used for the - /// - /// property. - /// - public static int DefaultMaximumResponseHeadersLength - { - get { return defaultMaxResponseHeadersLen; } - set - { - if (value <= 0 && value != -1) - { - throw new ArgumentOutOfRangeException(); - } - defaultMaxResponseHeadersLen = value; - } - } - - /// - /// A collection of HTTP headers stored as name/value pairs. - /// - /// A WebHeaderCollection that contains the name/value - /// pairs that make up the headers for the HTTP request. - /// - /// The following header values are set through properties on the - /// HttpWebRequest class: Accept, Connection, - /// Content-Length, Content-Type, Expect, Range, Referer, - /// Transfer-Encoding, and User-Agent. Trying to set these header - /// values by using - /// WebHeaderCollection.() - /// will raise an exception. Date and Host are set internally. - /// - public override WebHeaderCollection Headers - { - get - { - return m_httpRequestHeaders; - } - - set - { - // we can't change headers after they've already been sent - if (m_requestSent) - throw new InvalidOperationException("Cannot change headers after request submitted"); - - WebHeaderCollection webHeaders = value; - WebHeaderCollection newWebHeaders = - new WebHeaderCollection(true); - - // Copy And Validate - - // Handle the case where their object tries to change - // name, value pairs after they call set, so therefore, - // we need to clone their headers. - for (int i = 0; i < webHeaders.AllKeys.Length; i++) - { - newWebHeaders.Add(webHeaders.AllKeys[i], webHeaders[webHeaders.AllKeys[i]]); - } - - m_httpRequestHeaders = newWebHeaders; - } - } - - /// - /// Gets or sets the proxy for the request. - /// - /// The object to use to proxy - /// the request. null indicates that no proxy will be used. - public override IWebProxy Proxy - { - get { return m_proxy; } - set - { - if (m_requestSent) - throw new InvalidOperationException("Cannot change proxy after request submitted"); - if (value == null) - throw new ArgumentNullException(); - - m_proxy = value; - } - } - - /// - /// Gets or sets the state of chunk transfer send mode. - /// - /// true to send data to the Internet resource in - /// segments; otherwise, false. The default value is - /// false. - /// - /// If true, bits are uploaded and written using the - /// Chunked property of HttpWriteMode. - /// - public bool SendChunked - { - get { return m_httpWriteMode == HttpWriteMode.Chunked; } - set - { - //no race. Don't need interlocked - if (true == m_requestSent) - { - throw new InvalidOperationException("Cannot set \"chunked\" after request submitted"); - } - - if (value) - { - m_httpWriteMode = HttpWriteMode.Chunked; - } - else - { - if (m_contentLength >= 0) - { - m_httpWriteMode = HttpWriteMode.Write; - } - else - { - m_httpWriteMode = HttpWriteMode.None; - } - } - } - } - - /// - /// Gets or sets the HTTP protocol version for this request. - /// - /// The HTTP version to use for the request. The default is - /// . - public Version ProtocolVersion - { - get - { - return m_version; - } - - set - { - if (!value.Equals(HttpVersion.Version10) && - !value.Equals(HttpVersion.Version11)) - { - throw new ArgumentException("Invalid HTTP Verion: " + value); - } - - m_version = new Version(value.Major, value.Minor); - } - } - - /// - /// Private method for removing duplicate code which removes and adds - /// headers that are marked private. - /// - /// The name of the HTTP header. - /// The value of the HTTP header. - private void SetSpecialHeaders(String HeaderName, String value) - { - value = WebHeaderCollection.CheckBadChars(value, true); - - m_httpRequestHeaders.RemoveInternal(HeaderName); - if (value != null && value.Length != 0) - { - m_httpRequestHeaders.AddInternal(HeaderName, value); - } - } - - /// - /// Gets or sets the type of the entity body (the value of the content - /// type). - /// - /// The value of the Content-type HTTP header. The - /// default value is null. - /// - /// Setting to null clears the content-type. - /// - public override String ContentType - { - get - { - return m_httpRequestHeaders[HttpKnownHeaderNames.ContentType]; - } - - set - { - SetSpecialHeaders(HttpKnownHeaderNames.ContentType, value); - } - } - - /// - /// Gets or sets the TransferEncoding HTTP header. - /// - /// The value of the Transfer-encoding HTTP header. The - /// default value is null. - /// - /// null clears the transfer encoding except for the - /// Chunked setting. - /// - public String TransferEncoding - { - get - { - return m_httpRequestHeaders[HttpKnownHeaderNames.TransferEncoding]; - } - - set - { - bool fChunked; - - // on blank string, remove current header - if (ValidationHelper.IsBlankString(value)) - { - // if the value is blank, then remove the header - m_httpRequestHeaders.RemoveInternal(HttpKnownHeaderNames.TransferEncoding); - - return; - } - - // if not, check if the user is trying to set chunked: - string newValue = value.ToLower(); - - fChunked = (newValue.IndexOf("chunked") != -1); - - // prevent them from adding chunked, or from adding an Encoding - // without turing on chunked, the reason is due to the HTTP - // Spec which prevents additional encoding types from being - // used without chunked - if (fChunked) - { - throw new ArgumentException("Cannot add \"Encoding\" and set \"chunked\""); - } - else if (m_httpWriteMode != HttpWriteMode.Chunked) - { - throw new InvalidOperationException("Need HttpWriteMode.Chunked to be current mode"); - } - else - { - m_httpRequestHeaders.CheckUpdate(HttpKnownHeaderNames.TransferEncoding, value); - } - } - - } - - /// - /// Gets or sets the value of the Accept HTTP header. - /// - /// The value of the Accept HTTP header. The default - /// value is null. - public String Accept - { - get { return m_httpRequestHeaders[HttpKnownHeaderNames.Accept]; } - set { SetSpecialHeaders(HttpKnownHeaderNames.Accept, value); } - } - - /// - /// Gets or sets the value of the Referer HTTP header. - /// - /// The value of the Referer HTTP header. The default - /// value is null. - /// This header value is misspelled intentionally. - public String Referer - { - get { return m_httpRequestHeaders[HttpKnownHeaderNames.Referer]; } - set - { - SetSpecialHeaders(HttpKnownHeaderNames.Referer, value); - } - } - - /// - /// Gets or sets the value of the User-Agent HTTP header. - /// - /// The value of the User-agent HTTP header. The default - /// value is null. - public String UserAgent - { - get { return m_httpRequestHeaders[HttpKnownHeaderNames.UserAgent]; } - set - { - SetSpecialHeaders(HttpKnownHeaderNames.UserAgent, value); - } - } - - /// - /// Gets or sets the value of the Expect HTTP header. - /// - /// The contents of the Expect HTTP header. The default - /// value is null. - /// When setting this property, null clears the - /// Expect (except for the 100-continue value). - public String Expect - { - get { return m_httpRequestHeaders[HttpKnownHeaderNames.Expect]; } - set - { - // on blank string, remove current header - if (ValidationHelper.IsBlankString(value)) - { - m_httpRequestHeaders.RemoveInternal(HttpKnownHeaderNames.Expect); - return; - } - - m_httpRequestHeaders.CheckUpdate(HttpKnownHeaderNames.Expect, value); - } - } - - /// - /// Gets the IfModifiedSince value of - /// HttpKnownHeaderNames. - /// - /// A that contains the contents of - /// the If-Modified-Since HTTP header. The default value is the - /// current date and time. - /// - /// The setter for this property isn't supported, because a function - /// that formats the time isn't implemented. - /// - /// null clears the - /// IfModifiedSince header. - /// - public DateTime IfModifiedSince - { - get - { - string ifmodHeaderValue = m_httpRequestHeaders[HttpKnownHeaderNames.IfModifiedSince]; - - if (ifmodHeaderValue == null) - { - return DateTime.UtcNow; - } - - return HttpProtocolUtils.string2date(ifmodHeaderValue); - } - - // Set is not supported at this moment. It is needed for server. - //set - //{ - // SetSpecialHeaders(HttpKnownHeaderNames.IfModifiedSince, - // HttpProtocolUtils.date2string(value)); - //} - } - - /// - /// Constructs an instance of the HTTP Protocol class and initalizes it - /// to the basic header state. - /// - /// The Url object for which we're creating. - internal HttpWebRequest(Uri Url) - { - m_requestSent = false; - m_originalUrl = Url; - SendChunked = false; - m_keepAlive = true; - m_httpRequestHeaders = new WebHeaderCollection(true); - m_httpWriteMode = HttpWriteMode.None; - - m_contentLength = -1; - m_version = HttpVersion.Version11; - - m_allowWriteStreamBuffering = false; - - Method = "GET"; - - m_timeout = WebRequest.DefaultTimeout; - m_readWriteTimeout = DefaultReadWriteTimeout; - - // set the default proxy initially (this can be overriden by the Proxy property) - m_proxy = WebRequest.DefaultWebProxy; - - m_responseCreated = false; - } - - /// - /// Reset - /// - public void Reset() - { - m_requestSent = false; - m_responseCreated = false; - m_contentLength = -1; - m_httpWriteMode = HttpWriteMode.None; - m_httpRequestHeaders = new WebHeaderCollection(true); - } - - /// - /// Gets whether a response has been received from an Internet resource. - /// - /// true if a response has been received; otherwise, - /// false. - public bool HaveResponse - { - get { return (m_responseComplete); } - } - - /// - /// Adds a byte range header to the request for a specified range. - /// - /// The start of the range. - /// The end of the range. - public void AddRange(int from, int to) - { - AddRange("bytes", from, to); - } - - /// - /// Adds a range header to a request for a specific range from the - /// beginning or end of the requested data. - /// - /// Start of the range. The end of the range is the - /// end of the existing data. - public void AddRange(int range) - { - AddRange("bytes", range); - } - - /// - /// Adds a range header to a request for a specified range. - /// - /// The description of the range, such as - /// "bytes". - /// The start of the range. - /// The end of the range. - /// - /// would normally be - /// specified as "bytes", since this is the only range specifier - /// recognized by most HTTP servers. Setting - /// to some other string allows - /// support for custom range specifiers other than bytes. The - /// byte-range specifier is defined in RFC 2616 by the IETF. - public void AddRange(string rangeSpecifier, int from, int to) - { - - // Do some range checking before assembling the header - if ((from < 0) || (to < 0) || (from > to)) - { - throw new ArgumentOutOfRangeException(); - } - - // Add it - if (!AddRange(rangeSpecifier, from.ToString(), to.ToString())) - { - throw new InvalidOperationException(); - } - } - - /// - /// Adds a range header to a request for a specific range from the - /// beginning or end of the requested data. - /// - /// The description of the range, such as - /// "bytes". - /// The range value. - public void AddRange(string rangeSpecifier, int range) - { - if (!AddRange(rangeSpecifier, range.ToString(), (range >= 0) ? "" : null)) - { - throw new InvalidOperationException(); - } - } - - /// - /// Adds or extends a range header. - /// - /// Range specifier - /// Start of range - /// End of range - /// TBD - /// - /// Various range types can be specified via - /// , but only one type of Range - /// request will be made; for example, a byte-range request, or a - /// row-range request. Range types cannot be mixed. - /// - private bool AddRange(string rangeSpecifier, string from, string to) - { - // Checks for NULL rangeSpecifier - if (rangeSpecifier == null) - { - throw new ArgumentNullException(); - } - - // Checks for Valid characters in rangeSpecifier - if (!WebHeaderCollection.IsValidToken(rangeSpecifier)) - { - throw new ArgumentException(); - } - - // Add range specifier or appends to existing one - string curRange = m_httpRequestHeaders[HttpKnownHeaderNames.Range]; - - if ((curRange == null) || (curRange.Length == 0)) - { - curRange = rangeSpecifier + "="; - } - else - { - if (String.Compare(curRange.Substring(0, curRange.IndexOf('=')), rangeSpecifier) != 0) - { - return false; - } - - curRange = string.Empty; - } - - curRange += from.ToString(); - if (to != null) - { - curRange += "-" + to; - } - - m_httpRequestHeaders.SetAddVerified(HttpKnownHeaderNames.Range, curRange); - return true; - } - - /// - /// This function is called first in GetRequestStream() and throws exception - /// if conditions are not correct. - /// - private void ValidateGetRequestStream() - { - // TransferEncoding is set to a value and SendChunked is false. - if (TransferEncoding != null && SendChunked == false) - { - throw new InvalidOperationException(); - } - - // ProtocolViolationException The Method property is GET or HEAD. - if (m_method == "GET" || m_method == "HEAD") - { - throw new ProtocolViolationException("HTTP Method is incorrect: " + Method); - } - - // Condition for exception - KeepAlive is true, AllowWriteStreamBuffering is false, - // ContentLength is -1, SendChunked is false. - if (m_method == "PUT" || m_method == "POST") - { - if (ContentLength == -1 && SendChunked == false) - { - throw new ProtocolViolationException("Content lenght must be present for this request"); - } - } - } - - /// - /// Updates the HTTP WEB header collection to prepare it for request. - /// - private void PrepareHeaders() - { - // Depending on protocol version we update HTTP headers collection. - if (!(m_version.Equals(HttpVersion.Version10))) - { - if (m_httpWriteMode == HttpWriteMode.Write) - { - m_httpRequestHeaders.ChangeInternal(HttpKnownHeaderNames.ContentLength, m_contentLength.ToString()); - } - else if (m_httpWriteMode == HttpWriteMode.Chunked) - { - m_httpRequestHeaders.AddInternal(HttpKnownHeaderNames.TransferEncoding, "chunked"); - } - - // Set keepAlive header, we always send it, do not rely in defaults. - // Basically we send "Connection:Close" or "Connection:Keep-Alive" - string connectionValue; - if (m_keepAlive) - { - connectionValue = "Keep-Alive"; - } - else - { - connectionValue = "Close"; - } - - m_httpRequestHeaders.ChangeInternal(HttpKnownHeaderNames.Connection, connectionValue); - } - - //1.0 path - else - { - //1.0 doesn't support chunking - SendChunked = false; - - //1.0 doesn't support keep alive - m_keepAlive = false; - - if (m_httpWriteMode == HttpWriteMode.Write) - { - m_httpRequestHeaders.ChangeInternal(HttpKnownHeaderNames.ContentLength, m_contentLength.ToString()); - } - } - - m_httpRequestHeaders.ChangeInternal(HttpKnownHeaderNames.Host, ConnectHostAndPort()); - // Adds user name and password for basic Http authentication. - if (m_NetworkCredentials != null && m_NetworkCredentials.AuthenticationType == AuthenticationType.Basic) - { // If credentials are supplied, we need to add header like "Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" - // where QWxhZGRpbjpvcGVuIHNlc2FtZQ== is b64 encoded user name and password orginating as username:password. - string userInfo = ""; - if (m_NetworkCredentials.UserName != null) - { - userInfo += m_NetworkCredentials.UserName; - } - - userInfo += ":"; - if (m_NetworkCredentials.Password != null) - { - userInfo += m_NetworkCredentials.Password; - } - - // Encode user info. - byte[] buffer = Encoding.UTF8.GetBytes(userInfo); - string userNameAndPassEncoded = buffer != null ? Convert.ToBase64String(buffer) : ""; - string authValue = "Basic " + userNameAndPassEncoded; - m_httpRequestHeaders.ChangeInternal(HttpKnownHeaderNames.Authorization, authValue); - } - - m_requestSent = true; - } - - /// - /// Return string with remote Host and Port if port is not default. - /// Need update for HTTPS. - /// - /// String with host Url and port corresponding to target Uri. - internal string ConnectHostAndPort() - { - string retStr = m_originalUrl.Host; - if (m_originalUrl.Port != 80) - { - retStr += ":" + m_originalUrl.Port; - } - - return retStr; - } - - /// - /// Removes the given stream from the connection pool - /// - internal static void RemoveStreamFromPool(InputNetworkStreamWrapper stream) - { - lock (m_ConnectedStreams) - { - if (m_ConnectedStreams.Contains(stream)) - { - m_ConnectedStreams.Remove(stream); - } - } - } - - /// - /// Returns network stream connected to server. It could be a proxy or a - /// real server Uri. - /// - /// Uri that describes the proxy server. - /// Uri that describes the target (real) server. - /// Nerwork stream connected to server. - private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targetServer) - { - InputNetworkStreamWrapper retStream = null; - - // Create a socket and set reuse true. - // But before creating new socket we look in the list of existing sockets. If socket for this host already - // exist - use it. No need to create new socket. - string remoteServer = targetServer.Host + ":" + targetServer.Port; - lock (m_ConnectedStreams) - { - ArrayList removeStreamList = new ArrayList(); - - for (int i = 0; i < m_ConnectedStreams.Count; i++) - { - InputNetworkStreamWrapper inputStream = (InputNetworkStreamWrapper)m_ConnectedStreams[i]; - - if (inputStream.m_rmAddrAndPort == remoteServer && !inputStream.m_InUse) - { - // Re-use the connected socket. - // But first we need to know that socket is not closed. - try - { - // If socket is closed ( from this or other side ) the call throws exception. - if (inputStream.m_Socket.Poll(1, SelectMode.SelectWrite)) - { - // No exception, good we can condtinue and re-use connected stream. - - // Control flow returning here means persistent connection actually works. - inputStream.m_InUse = true; - inputStream.m_lastUsed = DateTime.UtcNow; - - retStream = inputStream; - break; - } - else - { - removeStreamList.Add(inputStream); - } - - } - catch (Exception) - { - removeStreamList.Add(inputStream); - } - - } - } - - for (int i = 0; i < removeStreamList.Count; i++) - { - InputNetworkStreamWrapper removeStream = (InputNetworkStreamWrapper)removeStreamList[i]; - - // Means socket was closed. Remove it from the list. - m_ConnectedStreams.Remove(removeStream); - - removeStream.Dispose(); - } - } - - if (retStream == null) - { - // Existing connection did not worked. Need to establish new one. - IPAddress address = null; - UriHostNameType hostNameType = proxyServer.HostNameType; - if (hostNameType == UriHostNameType.IPv4) - { - address = IPAddress.Parse(proxyServer.Host); - } - else if (hostNameType == UriHostNameType.Dns) - { - IPHostEntry hostEntry = null; - - try - { - hostEntry = Dns.GetHostEntry(proxyServer.Host); - } - catch(SocketException se) - { - throw new WebException("host not available", se, WebExceptionStatus.ConnectFailure, null); - } - - int addressListSize = hostEntry.AddressList.Length; - for (int i = 0; i < addressListSize; i++) - { - if ((address = hostEntry.AddressList[i]) != null) - { - break; - } - } - - if (address == null) - { - throw new WebException("Unable to resolve Dns entry to valid IPv4 Address", WebExceptionStatus.NameResolutionFailure); - } - } - else - { - throw new WebException("Only IPv4 or Dns host names allowed."); - } - - // If socket was not found in waiting connections, then we create new one. - Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - try - { - socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - } - catch{} - try - { - socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); - } - catch{} - - // Connect to remote endpoint - try - { - IPEndPoint remoteEP = new IPEndPoint(address, proxyServer.Port); - socket.Connect((EndPoint)remoteEP); - } - catch (SocketException e) - { - throw new WebException("connection failed", e, WebExceptionStatus.ConnectFailure, null); - } - - bool isHttps = m_originalUrl.Scheme == "https"; - - // We have connected socket. Create request stream - retStream = new InputNetworkStreamWrapper(new NetworkStream(socket), socket, !isHttps, proxyServer.Host + ":" + proxyServer.Port); - - // For https proxy works differenly from http. - if (isHttps) - { - // If proxy is set, then for https we need to send "CONNECT" command to proxy. - // Once this command is send, the socket from proxy works as if it is the socket to the destination server. - if (proxyServer != targetServer) - { - String request = "CONNECT " + remoteServer + " HTTP/" + ProtocolVersion + "\r\n\r\n"; - Byte[] bytesToSend = Encoding.UTF8.GetBytes(request); - retStream.Write(bytesToSend, 0, bytesToSend.Length); - - // Now proxy should respond with the connected status. If it is successul, then we are good to go. - CoreResponseData respData = ParseHTTPResponse(retStream, m_keepAlive); - if (respData.m_statusCode != (int)HttpStatusCode.OK) - { - throw new WebException("Proxy returned " + respData.m_statusCode, WebExceptionStatus.ConnectFailure); - } - } - - // Once connection estiblished need to create secure stream and authenticate server. - SslStream sslStream = new SslStream(retStream.m_Socket); - - // Throws exception is fails. - sslStream.AuthenticateAsClient(m_originalUrl.Host, null, m_caCerts, SslVerification.CertificateRequired, SslProtocols.Default); - - // Changes the stream to SSL stream. - retStream.m_Stream = sslStream; - - // Changes the address. Originally socket was connected to proxy, now as if it connected to m_originalUrl.Host on m_originalUrl.Port - retStream.m_rmAddrAndPort = m_originalUrl.Host + ":" + m_originalUrl.Port; - } - - lock (m_ConnectedStreams) - { - m_ConnectedStreams.Add(retStream); - - // if the current stream list is empty then start the timer that drops unused connections. - if (m_ConnectedStreams.Count == 1) - { - m_DropOldConnectionsTimer.Change(HttpListener.DefaultKeepAliveMilliseconds, System.Threading.Timeout.Infinite); - } - } - } - - return retStream; - } - - /// - /// Submits request to the WEB server. - /// - private void SubmitRequest() - { - // We have connected socket. Create request stream - // If proxy is set - connect to proxy server. - - if(m_requestStream == null) - { - if (m_proxy == null) - { // Direct connection to target server. - m_requestStream = EstablishConnection(m_originalUrl, m_originalUrl); - } - else // Connection through proxy. We create network stream connected to proxy - { - Uri proxyUri = m_proxy.GetProxy(m_originalUrl); - - if (m_originalUrl.Scheme == "https") - { - // For HTTPs we still need to know the target name to decide on persistent connection. - m_requestStream = EstablishConnection(proxyUri, m_originalUrl); - } - else - { - // For normal HTTP all requests go to proxy - m_requestStream = EstablishConnection(proxyUri, proxyUri); - } - } - } - - // We have connected stream. Set the timeout from HttpWebRequest - m_requestStream.WriteTimeout = m_readWriteTimeout; - m_requestStream.ReadTimeout = m_readWriteTimeout; - - // Now we need to write headers. First we update headers. - PrepareHeaders(); - - // Now send request string and headers. - byte[] dataToSend = GetHTTPRequestData(); - -#if DEBUG // In debug mode print the request. It helps a lot to troubleshoot the issues. - int byteUsed, charUsed; - bool completed = false; - char[] charBuf = new char[dataToSend.Length]; - UTF8decoder.Convert(dataToSend, 0, dataToSend.Length, charBuf, 0, charBuf.Length, true, out byteUsed, out charUsed, out completed); - string strSend = new string(charBuf); - Console.WriteLine(strSend); -#endif - // Writes this data to the network stream. - m_requestStream.Write(dataToSend, 0, dataToSend.Length); - m_requestSent = true; - } - - - /// - /// Reads and parses HTTP response from server. - /// After return of function HTTP response is read. - /// - /// Network stream connected to server. - /// TBD - /// CoreResponseData that describes server response. - private CoreResponseData ParseHTTPResponse(InputNetworkStreamWrapper inStream, bool defaultKeepAlive) - { - // CoreResponseData keeps all the information of the response. - CoreResponseData ret = new CoreResponseData(); - // maximumHeadersLength is maximum total length of http header. Basically this is amount - // of memory used for headers. - int headersLength = m_maxResponseHeadersLen == -1 ? 0x7FFFFFFF : m_maxResponseHeadersLen * 1024; - - ret.m_shouldClose = !defaultKeepAlive; - // Parse the request line. - string line = inStream.Read_HTTP_Line(maxHTTPLineLength).Trim(); - - // Cutoff white spaces - int currentOffset = 0; - for (; currentOffset < line.Length && ' ' != line[currentOffset]; ++currentOffset) ; - - // find HTTP version, read http/1.x - string httpVersionString = line.Substring(0, currentOffset).ToLower(); - if (httpVersionString.Equals("http/1.1")) - { - ret.m_version = HttpVersion.Version11; - } - else if (httpVersionString.Equals("http/1.0")) - { - ret.m_version = HttpVersion.Version10; - } - else - { - ret.m_status = WebExceptionStatus.ServerProtocolViolation; - ret.m_exceptionMessage = "Unknown http version: " + httpVersionString; - return ret; - } - - //advance to the status code - for (; currentOffset < line.Length && ' ' == line[currentOffset]; ++currentOffset) ; - - // Read the status code - int codeStart = currentOffset; - for (; currentOffset < line.Length && ' ' != line[currentOffset]; ++currentOffset) ; - int statusCode = -1; - try - { - string statusCodeStr = - line.Substring(codeStart, - currentOffset - codeStart); - statusCode = Convert.ToInt32(statusCodeStr); - } - catch (Exception e) - { - ret.m_status = WebExceptionStatus.ServerProtocolViolation; - ret.m_exceptionMessage = "Missing status code in HTTP reply"; - ret.m_innerException = e; - return ret; - } - - // If we get here - status code should be read. - ret.m_statusCode = statusCode; - - // Advance to the status message. The message is optional - for (; currentOffset < line.Length && ' ' != line[currentOffset]; ++currentOffset) ; - ret.m_statusDescription = line.Substring(currentOffset); - - ret.m_headers = new WebHeaderCollection(true); - ret.m_chunked = false; - ret.m_contentLength = -1; - - while ((line = inStream.Read_HTTP_Header(maxHTTPLineLength)).Length > 0) - { - // line.Length is used for the header. Substruct it. - headersLength -= line.Length; - // If total length used for header is exceeded, we break - if (headersLength < 0) - { - ret.m_status = WebExceptionStatus.ServerProtocolViolation; - ret.m_exceptionMessage = "Headers size exceed limit"; - return ret; - } - - // Now parse the header. - int sepIdx = line.IndexOf(':'); - if (sepIdx == -1) - { - ret.m_status = WebExceptionStatus.ServerProtocolViolation; - ret.m_exceptionMessage = "Illegal header format: " + line; - return ret; - } - - string headerName = line.Substring(0, sepIdx); - string headerValue = line.Substring(sepIdx + 1).TrimStart(null); - string matchableHeaderName = headerName.ToLower(); - - ret.m_headers.AddInternal(headerName, headerValue); - if (matchableHeaderName.Equals("content-length")) - { - try - { - ret.m_contentLength = Convert.ToInt32(headerValue); - - // set the response stream length for the input stream, so that an EOF will be read - // if the caller tries to read base the response content length - inStream.m_BytesLeftInResponse = ret.m_contentLength; - } - catch (Exception e) - { - ret.m_status = - WebExceptionStatus.ServerProtocolViolation; - ret.m_exceptionMessage = "Content length NAN: " + headerValue; - ret.m_innerException = e; - return ret; - } - } - else if (matchableHeaderName.Equals("transfer-encoding")) - { - if (headerValue.ToLower().IndexOf("chunked") != -1) - { - ret.m_chunked = true; - } - } - else if (matchableHeaderName.Equals("connection")) - { - if (headerValue.ToLower().IndexOf(HttpKnownHeaderValues.close) != -1) - { - ret.m_shouldClose = true; - } - } - } - - return ret; - } - - /// - /// Event handler for the web request timeout. This handler will be invoked if the response takes longer than the value - /// indicated by the property Timeout. - /// - /// - private void OnRequestTimeout(object arg) - { - if(m_requestStream != null && m_requestStream.m_Socket != null) - { - try - { - // Close the socket to kill the operation - m_requestStream.m_Socket.Close(); - } - catch - { - } - finally - { - m_requestStream.m_InUse = false; - } - } - } - - /// - /// Returns a response from an Internet resource. Overrides the - /// WebRequest. - /// method. - /// - /// The response from the Internet resource. - public override WebResponse GetResponse() - { - HttpWebResponse response = null; - - try - { - // If response was not sent, Submit the request. - if (!m_requestSent) - { - SubmitRequest(); - } - - CoreResponseData respData = null; - - // reset the total response bytes for the new request. - m_requestStream.m_BytesLeftInResponse = -1; - - // create the request timeout timer. This will kill the operation if it takes longer than specified by the Timeout property. - // The underlying socket will be closed to end the web request - using (Timer tmr = new Timer(new TimerCallback(OnRequestTimeout), null, m_timeout, System.Threading.Timeout.Infinite)) - { - // Processes response from server. Request stream should already be there. - - respData = ParseHTTPResponse(m_requestStream, m_keepAlive); - - if (respData.m_statusCode == (int)HttpStatusCode.Continue) - { - if (m_continueDelegate != null) - { - m_continueDelegate(respData.m_statusCode, respData.m_headers); - } - else - { - respData = ParseHTTPResponse(m_requestStream, m_keepAlive); - } - } - } - - response = new HttpWebResponse(m_method, m_originalUrl, respData, this); - - // Now we look if response has chunked encoding. If it is chunked, we need to set flag in m_requestStream we return. - if (respData.m_chunked) - { - m_requestStream.m_EnableChunkedDecoding = true; - } - - // Currently the request and response are the same network streams, but we optimize later. - response.SetResponseStream(m_requestStream); - - m_responseStatus = response.StatusCode; - - m_responseCreated = true; - } - catch(SocketException se) - { - if (m_requestStream != null) - { - m_requestStream.m_InUse = false; - - if (m_requestStream.m_Socket != null) - { - this.m_requestStream.m_Socket.Close(); - } - } - - throw new WebException("", se); - } - catch(Exception e) - { - throw new WebException("", e); - } - - - return response; - } - - /// - /// Submits a request with HTTP headers to the server, and returns a - /// Stream object to use to write request data. - /// - /// A Stream to use to write request data. - /// Used for POST of PUT requests. - public override Stream GetRequestStream() - { - // Validates the call to GetRequestStream. Throws exception on errors. - ValidateGetRequestStream(); - - // Submits the request. - try - { - SubmitRequest(); - } - catch - { - if(m_requestStream != null) - { - RemoveStreamFromPool(m_requestStream); - m_requestStream.Dispose(); - } - throw; - } - - // Return the stream - return m_requestStream.CloneStream(); - } - - /// - /// Constucts WEB exception if error is detected during parsing. - /// - /// Inner exception network exception - /// Partially constructed HttpWebResponse - /// WebException instance - private static WebException protocolError(Exception inner, - HttpWebResponse resp) - { - HttpStatusCode statusCode = resp.StatusCode; - int sr = (int)statusCode; - string message = "(" + ((int)statusCode) + ")"; - string description; - description = resp.StatusDescription; - if (description != null && description.Length > 0) - message += " " + description; - message = "Server returned error" + message; - return new WebException(message, inner, - WebExceptionStatus.ProtocolError, resp); - } - - internal bool m_sentHeaders = false; - - private bool hasEntityData() - { - if (m_httpWriteMode != HttpWriteMode.None) - return true; - else - return false; - } - - private bool canWrite() - { - return !KnownVerbs.GetHttpVerbType(Method).m_ContentBodyNotAllowed; - } - - /// - /// Retrieves HTTP request as bytes array. Used to create a request - /// message. - /// - /// Byte array with HTTP request. This data is sent through network. - private byte[] GetHTTPRequestData() - { - //step 1 - compute the length of the headers. - - string statusLine; - - // Connect verbs require CONNECT host:port - if (Method.ToUpper().Equals("CONNECT")) - { - statusLine = "CONNECT " + Address.Host + ":" + Address.Port + " HTTP/" + ProtocolVersion + "\r\n"; - } - else if (m_proxy != null && m_originalUrl.Scheme != "https") - { - statusLine = Method + " " + Address.AbsoluteUri + " HTTP/" + ProtocolVersion + "\r\n"; - } - else - { - statusLine = Method + " " + Address.AbsolutePath + " HTTP/" + ProtocolVersion + "\r\n"; // .PathAndQuery - } - - //most intrinsic headers are stored in the webheaders class - //content length is not. - int headersLength = statusLine.Length; - - //extra header lengths. Includes extension headers. - headersLength += Headers.byteLength(); - - byte[] headerBytes = new byte[headersLength]; - - int currentOffset = 0; - //store the request line - currentOffset += copyString(statusLine, headerBytes, - currentOffset); - - //now for the general headers - currentOffset += Headers.copyTo(headerBytes, currentOffset); - - return headerBytes; - } - - /// - /// Converts array to string by casting bytes to chars. - /// - /// Array with byte data. - /// Offset to start convertion. - /// Count of bytes to convert to string. - /// String converted from byte array. - private static string toEAscii(byte[] data, int offset, int count) - { - char[] output = new char[count]; - for (int i = 0; i < count; ++i) - { - output[i] = (char)data[offset + i]; - } - - return new string(output, 0, count); - } - - /// - /// Convert string to array of bytes - /// - /// string to convert - /// array of bytes converted from string - internal static byte[] fromEAscii(string data) - { - byte[] ret = new byte[data.Length]; - for (int i = 0; i < data.Length; ++i) - { - ret[i] = (byte)data[i]; - } - - return ret; - } - - /// - /// This function returns true if the response code from the server - /// (i.e. 304) MUST NOT have any entity data. I will artificially set - /// the content length in the stream to zero, so that reading... - /// - /// HTTP response code - /// true if the specified response code is one of the - /// defined values; otherwise, false. - private bool setContentLengthToZero(HttpStatusCode responseCode) - { - switch (responseCode) - { - case HttpStatusCode.SwitchingProtocols: - case HttpStatusCode.ResetContent: - case HttpStatusCode.NotModified: - case HttpStatusCode.NoContent: - case HttpStatusCode.UseProxy: - return true; - default: - return false; - } - } - - /// - /// Copies a string into an array of bytes. - /// - /// A String to copy. - /// Output array. - /// Offset to start placing data in array. - /// Count of bytes copied - private static int copyString(String src, byte[] bytes, int offset) - { - int i; - for (i = 0; i < src.Length; ++i) - bytes[offset + i] = (byte)src[i]; - return i; - } - - }; // class HttpWebRequest - -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpWebResponse.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.HttpWebResponse.cs deleted file mode 100644 index 1b466da8..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.HttpWebResponse.cs +++ /dev/null @@ -1,330 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System; - using System.IO; - - /// - /// Handles retrieval of HTTP Response headers, and handles data reads. - /// - /// This class should never be created directly, but rather should - /// be created by the - /// HttpWebRequest. - /// method. - /// - public class HttpWebResponse : WebResponse - { - - /// - /// The Web request object that was used for this response. - /// We need it to access KeepAlive property. - /// - private HttpWebRequest m_httpWebRequest; - - /// - /// Response URI generated by the request. - /// - private Uri m_url; - - /// - /// response Method gernated by the request - /// - private string m_method; - - /// - /// ConnectStream - for reading actual data - /// - private InputNetworkStreamWrapper m_responseStream; - - /// - /// Collection of HTTP headers returned by server - /// - private WebHeaderCollection m_httpResponseHeaders; - - /// - /// Content Length needed for semantics, -1 if chunked - /// - private long m_contentLength = -1; - - /// - /// The HTTP version for the response. - /// - private Version m_version; - - /// - /// The status code from the response. - /// - private int m_statusCode; - - /// - /// the description of the status returned by the server. - /// - private String m_statusDescription; - - /// - /// Retrieves a response header object. - /// - /// A WebHeaderCollection that contains the header - /// information returned with the response. - public override WebHeaderCollection Headers - { - get - { - return m_httpResponseHeaders; - } - } - - /// - /// Gets the length of the content returned by the request. - /// - /// - /// This property contains the value of the Content-Length header - /// that is returned with the response. If the Content-Length - /// header is not set in the response, this property is set to -1. - /// - /// The number of bytes returned by the request. Content length - /// does not include header information. - public override long ContentLength - { get { return m_contentLength; } } - - /// - /// TBD - /// - /// TBD - internal long InternalContentLength - { set { m_contentLength = value; } } - - /// - /// Gets the method that is used to encode the body of the response. - /// - /// - /// This property contains the value of the Content-Encoding - /// header returned with the response; that is, the encoding used for - /// the response. - /// - /// A string that describes the method that is used to encode the - /// body of the response. - public String ContentEncoding - { - get - { - return GetResponseHeader(HttpKnownHeaderNames.ContentEncoding); - } - } - - /// - /// Gets the content type of the response. - /// - /// A string that contains the content type of the response. - /// - /// - /// This property contains the value of the Content-Type header - /// returned with the response. - /// - public override string ContentType - { - get - { - return GetResponseHeader(HttpKnownHeaderNames.ContentType); - } - } - - /// - /// Gets the name of the server that sent the response. - /// - /// A string that contains the name of the server that sent the - /// response. - public string Server - { - get - { - return GetResponseHeader(HttpKnownHeaderNames.Server); - } - } - - /// - /// Gets the value of the Last-Modified header, which indicates the last - /// time the document was modified. - /// - /// A that contains the date and - /// time that the contents of the response were modified. - public DateTime LastModified - { - get - { - - string lastmodHeaderValue = - m_httpResponseHeaders[HttpKnownHeaderNames.LastModified]; - if (lastmodHeaderValue == null) - { - return DateTime.UtcNow; - } - - return HttpProtocolUtils.string2date(lastmodHeaderValue); - } - } - - /// - /// Gets the status of the HTTP response, as a number. - /// - /// - /// For status code values, see . - /// - /// One of the HttpStatusCode values. - public HttpStatusCode StatusCode - { - get { return (HttpStatusCode)m_statusCode; } - } - - /// - /// Gets the status description returned with the response. - /// - /// A string that describes the status of the response. - public string StatusDescription - { - get - { - return m_statusDescription; - } - } - - /// - /// Gets the version of the HTTP protocol that is used in the response. - /// - /// A Version that contains the HTTP protocol version of - /// the response. - public Version ProtocolVersion - { - get { return m_version; } -#if DEBUG - set { m_version = value; } -#endif - } - - /// - /// Gets the stream used for reading the body of the response from the - /// server. - /// - /// A network stream to read body of the message. - public override Stream GetResponseStream() - { - Stream retVal = m_responseStream.CloneStream(); - - m_responseStream.m_dataStart = m_responseStream.m_dataEnd = 0; - - return retVal; - } - - /// - /// Sets the response stream. - /// - /// - /// - /// Used internally during creation of HttpWebResponse. - /// - internal void SetResponseStream(InputNetworkStreamWrapper stream) - { - m_responseStream = stream; - } - - /// - /// Creates WEB response based on information known just after parsing the status line. - /// - /// Http Verb - /// TBD - /// Response data - /// TBD - internal HttpWebResponse(string method, Uri responseUrl, - CoreResponseData data, HttpWebRequest httpWebReq) - { - m_httpWebRequest = httpWebReq; - m_method = method; - m_url = responseUrl; - m_version = data.m_version; - m_statusCode = data.m_statusCode; - m_statusDescription = data.m_statusDescription; - - m_httpResponseHeaders = data.m_headers; - - m_contentLength = data.m_contentLength; - } - - /// - /// Gets the contents of a header that was returned with the response. - /// - /// HTTP header to search for matching header on. - /// The matched entry, if found. - /// - public string GetResponseHeader(string headerName) - { - string headerValue = m_httpResponseHeaders[headerName]; - return ((headerValue == null) ? String.Empty : headerValue); - } - - /// - /// Gets the final Response URI, that includes any - /// changes that may have transpired from the orginal Request. - /// - /// A Uri that contains the URI of the Internet resource - /// that responded to the request. - public override Uri ResponseUri { get { return m_url; } } - - /// - /// Gets the method that is used to return the response. - /// - /// A string that contains the HTTP method that is used to return - /// the response. - public string Method { get { return m_method; } } - - /// - /// Closes a response stream, if present. - /// - /// Not used. - protected override void Dispose(bool disposing) - { - if (m_responseStream != null) - { - bool closeConnection = true; - if (m_httpWebRequest.KeepAlive) - { - string connValue = null; - - // Check if server have sent use "Connection:Close" - if (m_httpResponseHeaders != null) connValue = m_httpResponseHeaders[HttpKnownHeaderNames.Connection]; - - // If server had not send this header or value is not "close", then we keep connection. - closeConnection = connValue == null || connValue.ToLower() == HttpKnownHeaderValues.close; - } - - // If it is not in the list - Add it - if (closeConnection) - { - // Add new socket and port used to connect to the list of sockets. - // Save connected socket and Destination IP End Point, so it can be used next time. - // But first we need to validate that this socket is already not in the list. We do not want same socket to be twice in the list. - - HttpWebRequest.RemoveStreamFromPool(m_responseStream); - - // Closing connection socket. - m_responseStream.Dispose(); - } - else - { - m_responseStream.ReleaseStream(); - } - - // Set flag that we already completed work on this stream. - m_responseStream = null; - } - - base.Dispose(disposing); - } - } // class HttpWebResponse -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.IWebRequestCreate.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.IWebRequestCreate.cs deleted file mode 100644 index c59ccdfd..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.IWebRequestCreate.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - - -namespace System.Net -{ - - /// - /// The interface for creating class - /// objects. - /// - public interface IWebRequestCreate - { - /// - /// Creates an instance of a class derived from - /// WebRequest. - /// - /// The URI for initialization of the class that is - /// derived from WebRequest. - /// - /// An instance of the class that is derived from - /// WebRequest. - /// - WebRequest Create(Uri uri); - - } // interface IWebRequestCreate - -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.Internal.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.Internal.cs deleted file mode 100644 index bfefa76c..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.Internal.cs +++ /dev/null @@ -1,328 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - internal class WebRequestPrefixElement - { - public string Prefix; - public IWebRequestCreate Creator; - - public WebRequestPrefixElement(string P, IWebRequestCreate C) - { - Prefix = P; - Creator = C; - } - - } // class PrefixListElement - - /// - /// Used during parsing to capture all the information contained in the http - /// status line and headers. - /// - internal class CoreResponseData - { - // Basic response information. - internal int m_statusCode; - internal string m_statusDescription; - internal WebHeaderCollection m_headers; - internal Version m_version; - - // Variables for the end of entity mark. - internal bool m_chunked; - internal long m_contentLength; - internal bool m_shouldClose; - - // The web status. - internal WebExceptionStatus m_status; - //here is the error message string associated with the status code. - //Its used for an exception message. - internal string m_exceptionMessage; - //here's the inner exception from the parse (for the WebException) - internal Exception m_innerException; - } - - /// - /// Contains known HTTP header names. - /// - public class HttpKnownHeaderNames - { - /// The Cache-Control HTTP header. - public const string CacheControl = "Cache-Control"; - /// The Connection HTTP header. - public const string Connection = "Connection"; - /// The Date HTTP header. - public const string Date = "Date"; - /// The Keep-Alive HTTP header. - public const string KeepAlive = "Keep-Alive"; - /// The Pragma HTTP header. - public const string Pragma = "Pragma"; - /// The Proxy-Connection HTTP header. - public const string ProxyConnection = "Proxy-Connection"; - /// The Trailer HTTP header. - public const string Trailer = "Trailer"; - /// The Transfer-Encoding HTTP header. - public const string TransferEncoding = "Transfer-Encoding"; - /// The Upgrade HTTP header. - public const string Upgrade = "Upgrade"; - /// The Via HTTP header. - public const string Via = "Via"; - /// The Warning HTTP header. - public const string Warning = "Warning"; - /// The Content-Length HTTP header. - public const string ContentLength = "Content-Length"; - /// The Content-Type HTTP header. - public const string ContentType = "Content-Type"; - /// The Content-ID HTTP header. - public const string ContentID = "Content-ID"; - /// The Content-Encoding HTTP header. - public const string ContentEncoding = "Content-Encoding"; - /// The Content-Transfer-Encoding HTTP header. - public const string ContentTransferEncoding = "Content-Transfer-Encoding"; - /// The Content-Language HTTP header. - public const string ContentLanguage = "Content-Language"; - /// The Content-Location HTTP header. - public const string ContentLocation = "Content-Location"; - /// The Content-Range HTTP header. - public const string ContentRange = "Content-Range"; - /// The Expires HTTP header. - public const string Expires = "Expires"; - /// The Last-Modified HTTP header. - public const string LastModified = "Last-Modified"; - /// The Age HTTP header. - public const string Age = "Age"; - /// The Location HTTP header. - public const string Location = "Location"; - /// The Proxy-Authenticate HTTP header. - public const string ProxyAuthenticate = "Proxy-Authenticate"; - /// The Retry-After HTTP header. - public const string RetryAfter = "Retry-After"; - /// The Server HTTP header. - public const string Server = "Server"; - /// The Set-Cookie HTTP header. - public const string SetCookie = "Set-Cookie"; - /// The Set-Cookie2 HTTP header. - public const string SetCookie2 = "Set-Cookie2"; - /// The Vary HTTP header. - public const string Vary = "Vary"; - /// The WWW-Authenticate HTTP header. - public const string WWWAuthenticate = "WWW-Authenticate"; - /// The Accept HTTP header. - public const string Accept = "Accept"; - /// The Accept-Charset HTTP header. - public const string AcceptCharset = "Accept-Charset"; - /// The Accept-Encoding HTTP header. - public const string AcceptEncoding = "Accept-Encoding"; - /// The Accept-Language HTTP header. - public const string AcceptLanguage = "Accept-Language"; - /// The Authorization HTTP header. - public const string Authorization = "Authorization"; - /// The Cookie HTTP header. - public const string Cookie = "Cookie"; - /// The Cookie2 HTTP header. - public const string Cookie2 = "Cookie2"; - /// The Expect HTTP header. - public const string Expect = "Expect"; - /// The From HTTP header. - public const string From = "From"; - /// The Host HTTP header. - public const string Host = "Host"; - /// The If-Match HTTP header. - public const string IfMatch = "If-Match"; - /// The If-Modified-Since HTTP header. - public const string IfModifiedSince = "If-Modified-Since"; - /// The If-None-Match HTTP header. - public const string IfNoneMatch = "If-None-Match"; - /// The If-Range HTTP header. - public const string IfRange = "If-Range"; - /// The If-Unmodified-Since HTTP header. - public const string IfUnmodifiedSince = "If-Unmodified-Since"; - /// The Max-Forwards HTTP header. - public const string MaxForwards = "Max-Forwards"; - /// The Proxy-Authorization HTTP header. - public const string ProxyAuthorization = "Proxy-Authorization"; - /// The Referer HTTP header. - public const string Referer = "Referer"; - /// The Range HTTP header. - public const string Range = "Range"; - /// The User-Agent HTTP header. - public const string UserAgent = "User-Agent"; - /// The Content-MD5 HTTP header. - public const string ContentMD5 = "Content-MD5"; - /// The ETag HTTP header. - public const string ETag = "ETag"; - /// The TE HTTP header. - public const string TE = "TE"; - /// The Allow HTTP header. - public const string Allow = "Allow"; - /// The Accept-Ranges HTTP header. - public const string AcceptRanges = "Accept-Ranges"; - /// The MIME-Version HTTP header. - public const string MimeVersion = "MIME-Version"; - } - - /// - /// TBD - /// - internal class HttpKnownHeaderValues - { - /// TBD - public const string close = "close"; - } - - /* - File: httpreq.cs - - Summary: Basic HTTP Protocol support for HttpWeb request Class. - Contains the implimention of various HTTP primitives. - - Classes: HttpWebReques - - Functions: - - ---------------------------------------------------------------------------- - This file is part of the Microsoft COM+ Netclasses. - - Copyright (C) 1998-1999 Microsoft Corporation. All rights reserved. - ==========================================================================+*/ - - // - seperate HTTP header names/header data - // - improve/check var/func naming - // - stress parsering cases - // - Chunked transfer needs a better algorithm, to prevent over copying - // - keep-alive - - /// - /// Represents the method that notifies callers when a continue response is - /// received by the client. - /// - /// The numeric value of the HTTP status from the - /// server. - /// The headers returned with the 100-continue - /// response from the server. - public delegate void HttpContinueDelegate(int StatusCode, WebHeaderCollection httpHeaders); - - /// - /// Controls the way an entity body is posted. - /// - internal enum HttpWriteMode - { - Chunked = 1, - Write = 2, - None = 0, - Prebuffer = 3 - } - - /// - /// Known Verbs are verbs that require special handling. - /// - internal class KnownVerbs - { - - // This is a placeholder for Verb properties. The following two bools can most likely be - // combined into a single Enum type. And the Verb can be incorporated. - - internal struct HttpVerb - { - // require content body to be sent - internal bool m_RequireContentBody; - // not allowed to send content body - internal bool m_ContentBodyNotAllowed; - // special semantics for a connect request - internal bool m_ConnectRequest; - // response will not have content body - internal bool m_ExpectNoContentResponse; - - /* - * XXX - * * Wed 10/10/2001 - * This should only be used by KnownVerbs - * */ - internal string m_name; - internal HttpVerb(string name, bool RequireContentBody, bool ContentBodyNotAllowed, bool ConnectRequest, bool ExpectNoContentResponse) - { - - m_name = name; - m_RequireContentBody = RequireContentBody; - m_ContentBodyNotAllowed = ContentBodyNotAllowed; - m_ConnectRequest = ConnectRequest; - m_ExpectNoContentResponse = ExpectNoContentResponse; - } - } - - // Force an an init, before we use them - private static HttpVerb[] m_knownVerbs; - static KnownVerbs() - { - m_knownVerbs = new HttpVerb[5]; - m_knownVerbs[0] = new HttpVerb("GET", false, true, false, false); - m_knownVerbs[1] = new HttpVerb("POST", true, false, false, false); - m_knownVerbs[2] = new HttpVerb("HEAD", false, true, false, true); - m_knownVerbs[3] = new HttpVerb("PUT", true, false, false, false); - /* - * XXX - * * Mon 02/25/2002 - * I've changed this from the desktop. There is no entity response - * in a connect request. It won't be there, and don't close it. - * */ - m_knownVerbs[4] = new HttpVerb("CONNECT", false, true, true, true); - - // default Verb - DefaultVerb = new HttpVerb("", false, false, false, false); - } - - // default verb, contains default properties for an unidentifable verb. - private static HttpVerb DefaultVerb; - - internal static HttpVerb GetHttpVerbType(String name) - { - for (int i = 0; i < m_knownVerbs.Length; ++i) - { - HttpVerb v = m_knownVerbs[i]; - if (0 == string.Compare(v.m_name, name)) - return v; - } - - return DefaultVerb; - } - } - - /// - /// A collection of utility functions for HTTP usage. - /// - internal class HttpProtocolUtils - { - private HttpProtocolUtils() - { - } - - /// - /// Parse String to DateTime format. - /// - /// String with date. - /// DateTime object that represent the same value as in input string. - internal static DateTime - string2date(String S) - { - DateTime dtOut; - - if (HttpDateParse.ParseHttpDate( - S, - out dtOut)) - { - return dtOut; - } - else - { - throw new Exception("Invalid Date in HTTP header"); - } - - } - } - -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.NetworkCredential.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.NetworkCredential.cs deleted file mode 100644 index 031f2804..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.NetworkCredential.cs +++ /dev/null @@ -1,99 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - - /// - /// Class that keeps user name and password. - /// - public class NetworkCredential - { - - private string m_userName; - private string m_password; - private AuthenticationType m_authenticationType; - - /// - /// Construct class with empty user name and password - /// - public NetworkCredential() - { - } - - /// - /// Constructs credientials and initializes them by provided user name and pssword - /// - /// - /// - public NetworkCredential(string userName, string password) - : this(userName, password, AuthenticationType.Basic) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the user. - /// The password. - /// Type of the authentication. - public NetworkCredential(string userName, string password, AuthenticationType authenticationType) - { - UserName = userName; - Password = password; - AuthenticationType = authenticationType; - } - - /// - /// Set or get user name. - /// - public string UserName - { - get - { - return m_userName; - } - set - { - m_userName = value; - } - } - - /// - /// Set or get password. - /// - public string Password - { - get - { - return m_password; - } - set - { - m_password = value; - } - } - - /// - /// Gets or sets the type of the authentication. - /// - /// The type of the authentication. - public AuthenticationType AuthenticationType - { - get - { - return m_authenticationType; - } - set - { - m_authenticationType = value; - } - } - - } // class NetworkCredential -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.ProtocolViolationException.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.ProtocolViolationException.cs deleted file mode 100644 index 91d7635b..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.ProtocolViolationException.cs +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - - -namespace System.Net -{ - - /// - /// The exception that is thrown when an error is made while using a network - /// protocol. - /// - public class ProtocolViolationException : InvalidOperationException - { - - // constructors - /// - /// Initializes a new instance of the - /// ProtocolViolationException class. - /// - public ProtocolViolationException() - { - } - - /// - /// Initializes a new instance of the - /// ProtocolViolationException class with the - /// specified message. - /// - /// The error message string. - public ProtocolViolationException(string message) - : base(message) - { - } - - } // class ProtocolViolationException - -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.WebException.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.WebException.cs deleted file mode 100644 index e11b7d37..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.WebException.cs +++ /dev/null @@ -1,145 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System; - - /*++ - Copyright (c) 2000 Microsoft Corporation - - Abstract: - Contains the defintion for the WebException object. This is a subclass of - Exception that contains a WebExceptionStatus and possible a reference to a - WebResponse. - - Original Author: - Henry Sanders (henrysa) 03-Feb-2000 - - Environment: - COM+ Managed Code - - Revision History: - 03-Feb-2000 henrysa - Created - - * Feb 2009 - Updated for Micro Framework. - --*/ - - /// - /// Defines the exception that is thrown by - /// instances when an error occurs. - /// - /// - /// This class is a subclass of InvalidOperationException - /// that contains a WebExceptionStatus and possibly a - /// reference to a WebResponse. The - /// WebResponse is only present if there is a response - /// from the remote server. - /// - public class WebException : InvalidOperationException - { - - private WebExceptionStatus m_Status; - private WebResponse m_Response; - - /// - /// The default constructor. - /// - public WebException() - { - - } - - /// - /// Constructs a WebException based on the specified - /// message string. - /// - /// The message string for the exception. - public WebException(string message) - : base(message) - { - } - - /// - /// Constructs a WebException based on the specified - /// message string and inner exception. - /// - /// The message string for the exception. - /// The exception that caused this - /// exception. - public WebException(string message, Exception innerException) : - base(message, innerException) - { - - } - - /// - /// Constructs a WebException based on the specified - /// message string and WebExceptionStatus. - /// - /// The message string for the exception. - /// The network status of the exception. - public WebException(string message, WebExceptionStatus status) - : base(message) - { - m_Status = status; - } - - /// - /// Constructs a WebException based on the specified - /// message string, inner exception, - /// , and - /// . - /// - /// Message string for exception. - /// The exception that caused this exception. - /// - /// The network status of the exception. - /// The WebResponse we have. - /// - public WebException(string message, - Exception inner, - WebExceptionStatus status, - WebResponse response) - : base(message, inner) - { - m_Status = status; - m_Response = response; - } - - /// - /// Gets the WebExceptionStatus code. - /// - /// One of the WebExceptionStatus values. - public WebExceptionStatus Status - { - get - { - return m_Status; - } - } - - /// - /// Gets the response that the remote host returned. - /// - /// If a response is available from the Internet resource, a - /// WebResponse instance that contains the error - /// response from an Internet resource; otherwise, - /// null. - public WebResponse Response - { - get - { - return m_Response; - } - } - - }; // class WebException - -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.WebHeaders.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.WebHeaders.cs deleted file mode 100644 index d64fed54..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.WebHeaders.cs +++ /dev/null @@ -1,725 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - - using System.Collections; - using System.Text; - - /// - /// Contains a name/value pair that is used in an HTTP header. - /// - internal class HeaderValuePair - { - public HeaderValuePair(string hd, string val) - { - headerAsKey = hd; - value = val; - } - - // Pair of value and header. - public string headerAsKey; - public string value; - } - - /// - /// Keeps an array of name/value pairs that are in HTTP headers. - /// - internal class HeaderValueCollection : ArrayList - { - /// - /// Searches in the collection for the header with the same name. - /// - /// The header to seach for. - /// The name/value pair if found; otherwise, null. - /// - /// Header comparison is case-insensitive. - /// - /// In the desktop and Compact Framework versions of .NET, the array is - /// represented by a hash table. - /// - /// - public HeaderValuePair GetValuePair(string header) - { - string lowerHeader = header.ToLower(); - for (int i = 0; i < this.Count; i++) - { - if (((HeaderValuePair)this[i]).headerAsKey.ToLower() == lowerHeader) - { - return (HeaderValuePair)this[i]; - } - } - - return null; - } - - /// - /// Adds a header and a value for the header into the collection. - /// - /// String for header - /// String for value - /// - /// If the specified header is already present, the value is appended to - /// that header. - /// - public void Add(string header, string value) - { - // Checks is we already have the header. - HeaderValuePair pair = GetValuePair(header); - // If found, adds valus to existing valies. - if (pair != null) - { - pair.value += "," + value; - } - else // if not found - then we add it. - { - base.Add(new HeaderValuePair(header, value)); - } - } - - /// - /// Replaces the previous values for the header with the new value. - /// - /// Header name - /// New value - public void Set(string header, string value) - { - // Remove previous header. - RemoveHeader(header); - - // Add new value(s) - base.Add(new HeaderValuePair(header, value)); - } - - /// - /// Removes the header that has the specified name. - /// - /// - /// - public bool RemoveHeader(string header) - { - int totalElemCount = Count; - string lowerHeader = header.ToLower(); - for (int i = 0; i < totalElemCount; i++) - { // If name matches - remove this header. - if (((HeaderValuePair)this[i]).headerAsKey.ToLower() == lowerHeader) - { - RemoveAt(i); - return true; - } - } - - return false; - } - - } - - /// - /// Contains protocol headers associated with a request or response. - /// Manages name-value pairs for HTTP headers. - /// - /// - /// This class includes additional methods, including HTTP parsing of a - /// collection into a buffer that can be sent. - /// - /// Headers are validated when attempting to add them. - /// - /// - public class WebHeaderCollection - { - /// - /// Data and constants. - /// - private const int ApproxAveHeaderLineSize = 30; - private static readonly HeaderInfoTable HInfo = new HeaderInfoTable(); - - /// - /// Array list of headers and values - /// - private HeaderValueCollection head_val_coll = new HeaderValueCollection(); - - /// - /// true if this object is created for internal use, in this case - /// we turn on checking when adding special headers. - /// - private bool m_IsHttpWebHeaderObject = false; - - /// - /// Adds header name/value pair to collection. Does not check if - /// multiple values are allowed. - /// - /// Name in header - /// Value in header - internal void AddWithoutValidate(string headerName, string headerValue) - { - headerName = CheckBadChars(headerName, false); - headerValue = CheckBadChars(headerValue, true); - - head_val_coll.Add(headerName, headerValue); - } - - /// - /// Adds header name/value pair to collection. - /// If multi value allowed for this header name - adds new one - /// If multi value is not allowed, replace the old value with new one - /// - /// Name in header - /// Value in header - internal void SetAddVerified(string name, string value) - { - if (HInfo[name].AllowMultiValues) - { - head_val_coll.Add(name, value); - } - else - { - head_val_coll.Set(name, value); - } - } - - // The below 3 methods are for fast headers manipulation, bypassing all - // the checks. - - /// - /// Just internal fast add. - /// - /// - /// - internal void AddInternal(string headerName, string headerValue) - { - head_val_coll.Add(headerName, headerValue); - } - - /// - /// Internal fast channge - /// - /// - /// - internal void ChangeInternal(string name, string value) - { - head_val_coll.Set(name, value); - } - - /// - /// Internal remove of header. - /// - /// - internal void RemoveInternal(string name) - { - head_val_coll.RemoveHeader(name); - } - - /// - /// Changes to new value. Check for illegal characters first. - /// - /// - /// - internal void CheckUpdate(string name, string value) - { - value = CheckBadChars(value, true); - ChangeInternal(name, value); - } - - /// - /// Throws an error if invalid chars are found in the header name or - /// value. - /// - /// The header name or header value string to - /// check. - /// Whether the name parameter is a header - /// name or a header value. - /// - internal static string CheckBadChars(string name, bool isHeaderValue) - { - - if (name == null || name.Length == 0) - { - // empty name is invlaid - if (!isHeaderValue) - { - throw new ArgumentException(); - } - - // empty value is OK - return string.Empty; - } - - if (isHeaderValue) - { - // VALUE check - // Trim spaces from both ends - name = name.Trim(); - - // First, check for correctly formed multi-line value - // Second, check for absence of CTL characters - bool crlf = false; - for (int i = 0; i < name.Length; ++i) - { - char c = name[i]; - if (c == 127 || (c < ' ' && !(c == '\t' || c == '\r' || c == '\n'))) - { - throw new ArgumentException(); - } - - if (crlf) - { - if (!(c == ' ' || c == '\t')) - { - throw new ArgumentException(); - } - - crlf = false; - } - else - { - if (c == '\n') - { - crlf = true; - } - } - } - } - else - { - // NAME check - // First, check for absence of separators and spaces - if (name.IndexOfAny(ValidationHelper.InvalidParamChars) != -1) - { - throw new ArgumentException(); - } - - // Second, check for non CTL ASCII-7 characters (32-126) - if (ContainsNonAsciiChars(name)) - { - throw new ArgumentException(); - } - } - - return name; - } - - internal static bool IsValidToken(string token) - { - return (token.Length > 0) - && (token.IndexOfAny(ValidationHelper.InvalidParamChars) == -1) - && !ContainsNonAsciiChars(token); - } - - internal static bool ContainsNonAsciiChars(string token) - { - for (int i = 0; i < token.Length; ++i) - { - if ((token[i] < 0x20) || (token[i] > 0x7e)) - { - return true; - } - } - - return false; - } - - /// - /// Throws an exception if the user passed in a reserved string as the - /// header name. - /// - /// - internal void ThrowOnRestrictedHeader(string headerName) - { - if (m_IsHttpWebHeaderObject && HInfo[headerName].IsRestricted) - { - throw new ArgumentException("Cannot update restricted header: " + headerName); - } - } - - // Our Public METHOD set, most are inherited from NameValueCollection, - // not all methods from NameValueCollection are listed, even though - // usable. - // - // This includes: - // Add(name, value) - // Add(header) - // this[name] {set, get} - // Remove(name), returns bool - // Remove(name), returns void - // Set(name, value) - // ToString() - // - // SplitValue(name, value) - // ToByteArray() - // ParseHeaders(char [], ...) - // ParseHeaders(byte [], ...) - - /// - /// Inserts a header with the specified name and value into the - /// collection. - /// - /// The name of the header that is being added to the - /// collection. - /// The content of the header that is being added - /// (its header-value). If a header with the specified name already - /// exists, this value is concatenated onto the existing header. - /// - /// If a header with the specified name already exists, the header that - /// is being added is concatenated onto the existing header. - /// - /// Throws an exception if the specified header name is the name of a - /// special header. - /// - /// - public void Add(string name, string value) - { - // Special headers are listed in the RestrictedHeaders object. - - name = CheckBadChars(name, false); - ThrowOnRestrictedHeader(name); - value = CheckBadChars(value, true); - - head_val_coll.Add(name, value); - } - - /// - /// Inserts a new header into the collection. - /// - /// A header name/value pair, in the format - /// "myHeaderName:myValue". - /// - /// This method expects a string with the format "myName:myValue", and - /// parses the two parts out. - /// - /// If a header with the specified name already exists, the header that - /// is being added is concatenated onto the existing header. - /// - /// - /// Throws an exception if the specified header name is the name of a - /// special header. - /// - /// - public void Add(string header) - { - // Special headers are listed in the RestrictedHeaders object. - - if (ValidationHelper.IsBlankString(header)) - { - throw new ArgumentNullException(); - } - - int colpos = header.IndexOf(':'); - - // check for badly formed header passed in - if (colpos < 0) - { - throw new ArgumentException(); - } - - string name = header.Substring(0, colpos); - string value = header.Substring(colpos + 1); - - name = CheckBadChars(name, false); - ThrowOnRestrictedHeader(name); - value = CheckBadChars(value, true); - - head_val_coll.Add(name, value); - } - - /// - /// Sets the specified header to the specified value. - /// - /// The header to set. - /// The content of the header to set. - /// - /// Includes validation. - /// Throws an exception if the specified header name is the name of a - /// special header. - /// - public void Set(String name, String value) - { - // Special headers are listed in the RestrictedHeaders object. - - if (ValidationHelper.IsBlankString(name)) - { - throw new ArgumentNullException("name"); - } - - name = CheckBadChars(name, false); - ThrowOnRestrictedHeader(name); - value = CheckBadChars(value, true); - - head_val_coll.Set(name, value); - } - - /// - /// Removes the specified header from the collection. - /// - /// The name of the header to remove. - /// - /// Throws an exception if the specified header name is the name of a - /// special header. - /// - public void Remove(string name) - { - // Special headers are listed in the RestrictedHeaders object. - - if (ValidationHelper.IsBlankString(name)) - { - throw new ArgumentNullException("name"); // netcf.20937 - } - - ThrowOnRestrictedHeader(name); - name = CheckBadChars(name, false); - - head_val_coll.RemoveHeader(name); - } - - /// - /// Returns the values for the specified header name. - /// - /// The name of the header. - /// An array of parsed string objects. - /// - /// Takes a header name and returns a string array representing - /// the individual values for that header. For example, if the headers - /// contain the following line: - /// - /// Accept: text/plain, text/html - /// - /// then GetValues("Accept") returns an array of - /// two strings: "text/plain" and "text/html". - /// - public string[] GetValues(string header) - { - // Get the value pair for the header. - HeaderInfo Info = HInfo[header]; - HeaderValuePair pair = head_val_coll.GetValuePair(header); - - // If header not present or value string not present or empty - - // return null. - if (pair == null || pair.value == null || pair.value.Length == 0) - { - return null; - } - - // Header present. Parse the value string. There is non-empty value - // string. - if (Info == null || !Info.AllowMultiValues) - { - string[] retVal = new string[1]; - retVal[0] = pair.value; - return retVal; - } - - // Multivalue header - return Info.Parser(pair.value); - } - - /// - /// Generates a string representation of the headers, that is ready to - /// be sent except for it being in String format. - /// - /// A string representation of the headers. - /// - /// The format looks like the following: - /// - /// Header-Name: Header-Value\r\n - /// Header-Name2: Header-Value2\r\n - /// ... - /// Header-NameN: Header-ValueN\r\n - /// \r\n - /// - /// - public override string ToString() - { - // Iterates on all headers and add them line by line in form: - // header: value - string retString = ""; - for (int i = 0; i < head_val_coll.Count; i++) - { - // Try to be most efficient by calling Concat. - // There is no Concat with 5 arguments. - retString = String.Concat(retString, ((HeaderValuePair)head_val_coll[i]).headerAsKey, ": ", ((HeaderValuePair)head_val_coll[i]).value); - retString = String.Concat(retString, "\r\n"); - } - - // Adds extra line return at the end of headers. - retString = String.Concat(retString, "\r\n"); - - // Return concatinated headers and - return retString; - } - - /// - /// Generates a byte array representation of the headers, that is ready - /// to be sent. - /// - /// An array of bytes. - /// - /// This method serializes the headers into a byte array that can be - /// sent over the network. The format looks like: - /// - /// Header-Name1: Header-Value1\r\n - /// Header-Name2: Header-Value2\r\n - /// ... - /// Header-NameN: Header-ValueN\r\n - /// \r\n - /// - /// - public byte[] ToByteArray() - { - // Performance Note: We aren't doing a single copy/covert run, - // because (according to Demitry), it's cheaper to copy the headers - // twice than to call the UNICODE-to-ANSI conversion code many - // times. (The code before used to know the size of the output.) - - // Make sure the buffer is big enough. - - string tempStr = ToString(); - - // Use the String of headers, convert to Char Array, then convert to - // Bytes, serializing finally into the buffer, along the way. - byte[] buffer = Encoding.UTF8.GetBytes(tempStr); - - return buffer; - } - - /// - /// Tests whether the specified HTTP header can be set. - /// - /// Name for the header. - /// - /// - /// Throws an exception if the header name is blank, contains illegal - /// characters, or contains characters that are reserved by the HTTP - /// protocol. - /// - public static bool IsRestricted(string headerName) - { - if (ValidationHelper.IsBlankString(headerName)) - { - throw new ArgumentNullException("headerName"); - } - - return HInfo[CheckBadChars(headerName, false)].IsRestricted; - } - - /// - /// Creates an empty collection of WEB headers. - /// - public WebHeaderCollection() - { - } - - /// - /// Private constructor, called internally. - /// - /// Whether this is an HTTP headers - /// object. - internal WebHeaderCollection(bool internalCreate) - { - m_IsHttpWebHeaderObject = internalCreate; - } - - /// - /// Calculates the number of bytes needed to store the headers. - /// - /// - internal int byteLength() - { - int ret = 0; - // Runs for all collection and adds length of header and value - // strings - for (int i = 0; i < head_val_coll.Count; i++) - { - ret += ((HeaderValuePair)head_val_coll[i]).headerAsKey.Length; - ret += 2; //for the ": " - ret += ((HeaderValuePair)head_val_coll[i]).value.Length; - ret += 2; //for the "\r\n" - } - - ret += 2; //for the final "\r\n" - - return ret; - } - - /// - /// Returns the string value for the header. - /// - /// The name of the header. - /// A string containing the value. If no value is present, - /// returns null. - public string this[string header] - { - get - { - HeaderValuePair pair = head_val_coll.GetValuePair(header); - // If header is not present, then pair is null. Return null - // string - if (pair == null) - { - return null; - } - - // Pair was found. Return the value string of it - return pair.value; - } - } - - /// - /// Gets the number of headers in the collection. - /// - /// An Int32 indicating the number of headers in a - /// request. - public int Count - { - get - { - return head_val_coll.Count; - } - } - - /// - /// Gets all header names (keys) in the collection. - /// - /// An array of type String containing all header names in - /// a Web request. - public string[] AllKeys - { - get - { - ArrayList tempCollection = new ArrayList(); - for (int i = 0; i < head_val_coll.Count; i++) - { - tempCollection.Add(((HeaderValuePair)head_val_coll[i]).headerAsKey); - } - - string[] stringArray = new string[tempCollection.Count]; - return (string[])tempCollection.ToArray(typeof(string)); - } - } - - /// - /// Copies the headers into the byte array starting at bytes[offset]. - /// If the byte array is too small to hold the data, an - /// ArgumentException is thrown. - /// - /// The array to copy. - /// The offset to the beginning of the data to be - /// copied into the WEB Headers collection. - /// How many bytes were copied. - internal int copyTo(byte[] bytes, int offset) - { - // Create array representing the headers - byte[] headersBytes = ToByteArray(); - // Copy to destination - headersBytes.CopyTo(bytes, offset); - // Return count of bytes copied. - return headersBytes.Length; - } - - }; // class WebHeaderCollection - -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.WebRequest.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.WebRequest.cs deleted file mode 100644 index f4f72fab..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.WebRequest.cs +++ /dev/null @@ -1,394 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System; - using System.Collections; - using System.IO; - - /// - /// Makes a request to a Uniform Resource Identifier (URI). This is an - /// abstract class. - /// - /// - /// This is the base class of all Web resource/protocol objects. This class - /// provides common methods, data and proprties for making the top-level - /// request. - /// - public abstract class WebRequest : MarshalByRefObject, IDisposable - { - internal const int DefaultTimeout = 100000; // default timeout is 100 seconds - // (ASP .NET is 90 seconds) - - // Lock to syncronize update of s_PrefixList - private static object g_listLock = new object(); - // List of WebRequestPrefixElement that keeps prefix ( string ) and - // IWebRequestCreate - private static ArrayList s_PrefixList = new ArrayList(); - - private static IWebProxy s_defaultProxy = null; - - /// - /// Initializes a new instance of the - /// class. - /// - protected WebRequest() - { - - } - - ~WebRequest() - { - Dispose(false); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - } - - - /// - /// When overridden in a descendant class, gets or sets the protocol - /// method to use in this request. - /// - /// - /// This property gets or sets the verb to this request, such as GET or - /// POST for HTTP. - /// - /// The protocol method to use in this request. - public virtual string Method - { - get - { - throw new NotSupportedException(); - } - - set - { - throw new NotSupportedException(); - } - } - - /// - /// When overridden in a descendant class, gets the URI of the Internet - /// resource associated with the request. - /// - /// - /// This property is read-only, since the Uri can be specified only on - /// creation. - /// - /// A Uri representing the resource associated - /// with the request. - /// - public virtual Uri RequestUri - { // read-only - get - { - throw new NotSupportedException(); - } - } - - /// - /// When overridden in a descendant class, gets or sets the name of the - /// connection group for the request. - /// - /// - /// This property serves as a way of grouping connections. - /// - /// The name of the connection group for the request. - public virtual string ConnectionGroupName - { - get - { - throw new NotSupportedException(); - } - - set - { - throw new NotSupportedException(); - } - } - - /// - /// When overridden in a descendant class, gets or sets the collection - /// of header name/value pairs associated with the request. - /// - /// A WebHeaderCollection containing the - /// header name/value pairs associated with this request. - public virtual WebHeaderCollection Headers - { - // read-only - get - { - throw new NotSupportedException(); - } - - set - { - throw new NotSupportedException(); - } - } - - /// - /// When overridden in a descendant class, gets or sets the content - /// length of the request data being sent. - /// - /// - /// The content length is the length of the message with the verb. - /// It is useful only with verbs that actually support a message, such - /// as POST; it is not used for the GET verb. - /// - /// The number of bytes of request data being sent. - public virtual long ContentLength - { - get - { - throw new NotSupportedException(); - } - - set - { - throw new NotSupportedException(); - } - } - - /// - /// When overridden in a descendant class, gets or sets the content type - /// of the request data being sent. - /// - /// - /// The content length is the length of the message with the verb. - /// It is useful only with verbs that actually support a message, such - /// as POST; it is not used for the GET verb. - /// - /// The content type of the request data. - public virtual string ContentType - { - get - { - throw new NotSupportedException(); - } - - set - { - throw new NotSupportedException(); - } - } - - /// - /// Gets or sets the length of time, in milliseconds, before the request - /// times out. - /// - /// The length of time, in milliseconds, until the request times - /// out, or the value Timeout.Infinite to indicate that the request does - /// not time out. The default value is defined by the descendant - /// class. - public virtual int Timeout - { - get - { - throw new NotSupportedException(); - } - - set - { - throw new NotSupportedException(); - } - } - - /// - /// Gets or sets the global HTTP proxy. - /// The DefaultWebProxy property determines the default proxy that all WebRequest instances use if the request - /// supports proxies and no proxy is set explicitly using the Proxy property. Proxies are currently supported - /// by HttpWebRequest. - /// - public static IWebProxy DefaultWebProxy - { - get - { - return s_defaultProxy; - } - - set - { - s_defaultProxy = value; - } - } - - /// - /// When overridden in a descendant class, gets or sets the network - /// proxy to use to access this Internet resource. - /// - /// The IWebProxy to use to access the - /// Internet resource. - public virtual IWebProxy Proxy - { - get - { - throw new NotSupportedException(); - } - - set - { - throw new NotSupportedException(); - } - } - - /// - /// When overridden in a descendant class, returns a - /// Stream for writing data to the Internet resource. - /// - /// A Stream for writing data to the - /// Internet resource. - public virtual Stream GetRequestStream() - { - // DataStream may need to be extended to URLDataStream or somesuch. - // We might need to be able to get the data available. This should - // be a method of the stream, not of the net classes. Also, we need - // to know whether the stream is seekable. Only streams via cache - // and via socket with Content-Length are seekable. - - throw new NotSupportedException(); - } - - /// - /// When overridden in a descendant class, returns a response to an - /// Internet request. - /// - /// A WebResponse containing the response to - /// the Internet request. - public virtual WebResponse GetResponse() - { - throw new NotSupportedException(); - } - - /// - /// Initializes a new WebRequest instance for the - /// specified URI scheme, such as http://, https://, or file://. - /// - /// The URI that identifies the Internet - /// resource. - /// Newly created WebRequest. - /// A WebRequest descendant for the specific URI scheme. - /// - /// - /// This is the main creation routine. The specified Uri is looked up - /// in the prefix match table, and the appropriate handler is invoked to - /// create the object. - /// - public static WebRequest Create(string requestUriString) - { - return CreateInternal(new Uri(requestUriString)); - } - - /// - /// Creates a WebRequest. - /// - /// A containing the - /// URI of the requested resource. - /// A WebRequest descendant for the specified - /// URI scheme. - /// - /// This is the main creation routine. The specified Uri is looked up - /// in the prefix match table, and the appropriate handler is invoked to - /// create the object. - /// - public static WebRequest Create(Uri requestUri) - { - return CreateInternal(requestUri); - } - - /// - /// Registers a WebRequest descendant for the - /// specified URI. - /// - /// The complete URI or URI prefix that the - /// WebRequest descendant services. - /// The create method that the - /// WebRequest calls to create the - /// WebRequest descendant. - /// true. - public static bool RegisterPrefix(string prefix, - IWebRequestCreate creator) - { - if (prefix == null || creator == null) { throw new ArgumentNullException(); } - - // Changes prefix to lower becuase it is case insensitive. - prefix = prefix.ToLower(); - lock (g_listLock) - { - // Iterate over list of prefixes and checks if this one is - // already present. - for (int i = 0; i < s_PrefixList.Count; i++) - { - if (((WebRequestPrefixElement)s_PrefixList[i]).Prefix == prefix) - { - return false; - } - } - - // This is a new prefix, add it. - s_PrefixList.Add(new WebRequestPrefixElement(prefix, creator)); - } - - return true; - } - - private static int ComparePrefixString(string Url, string prefix, int prefixLen) - { - for (int i = 0; i < prefixLen; i++) - { - if (Url[i] != prefix[i]) - { - return Url[i] < prefix[i] ? -1 : 1; - } - } - - // Actually the URL starts by prefix. - return 0; - } - - private static WebRequest CreateInternal(Uri requestUri) - { - if (requestUri == null) { throw new ArgumentNullException(); } - - // Makes LookupUri lowercase since we need case-insensitive compare - // with prefix - string lookupUri = requestUri.AbsoluteUri.ToLower(); - int lookupUriLent = lookupUri.Length; - - // Walk down the list of prefixes. - int prefixListCount = s_PrefixList.Count; - for (int i = 0; i < prefixListCount; i++) - { - WebRequestPrefixElement Current = (WebRequestPrefixElement)s_PrefixList[i]; - - // See if this prefix is short enough. - int prefixLen = Current.Prefix.Length; - if (lookupUriLent >= prefixLen) - { - // It is. See if these match. - if (ComparePrefixString(lookupUri, Current.Prefix, prefixLen) == 0) - { - return Current.Creator.Create(requestUri); - } - } - } - - throw new NotSupportedException(); - } - } // class WebRequest - -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.WebResponse.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.WebResponse.cs deleted file mode 100644 index d3e125ae..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.WebResponse.cs +++ /dev/null @@ -1,138 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System; - using System.IO; - - /// - /// Provides a response from a Uniform Resource Identifier (URI). This is - /// an abstract class. - /// - /// - /// This is the abstract base class for all WebResponse - /// objects. - /// - public abstract class WebResponse : MarshalByRefObject, IDisposable - { - /// - /// Initializes a new instance of the WebResponse - /// class. - /// - protected WebResponse() - { - } - - /// - /// When overridden in a descendant class, gets or sets the content - /// length of data being received. - /// - /// The number of bytes returned from the Internet - /// resource. - public virtual long ContentLength - { - get - { - throw new NotSupportedException(); - } - - set - { - throw new NotSupportedException(); - } - } - - /// - /// When overridden in a derived class, gets or sets the content type of - /// the data being received. - /// - /// A string that contains the content type of the - /// response. - public virtual string ContentType - { - get - { - throw new NotSupportedException(); - } - - set - { - throw new NotSupportedException(); - } - } - - /// - /// When overridden in a descendant class, returns the data stream from - /// the Internet resource. - /// - /// An instance of the class for - /// reading data from the Internet resource. - public virtual Stream GetResponseStream() - { - throw new NotSupportedException(); - } - - /// - /// When overridden in a derived class, gets the URI of the Internet - /// resource that actually responded to the request. - /// - /// An instance of the class that - /// contains the URI of the Internet resource that actually responded to - /// the request. - /// - /// This property gets the final Response URI, that includes any changes - /// that may have transpired from the orginal request. - /// - public virtual Uri ResponseUri - { // read-only - get - { - throw new NotSupportedException(); - } - } - - /// - /// When overridden in a derived class, gets a collection of header - /// name-value pairs associated with this request. - /// - /// An instance of the - /// class that contains - /// header values associated with this response. - public virtual WebHeaderCollection Headers - { - get - { - throw new NotSupportedException(); - } - } - - ~WebResponse() - { - Dispose(false); - } - - /// - /// When overridden by a descendant class, closes the response stream. - /// - public virtual void Close() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public void Dispose() - { - Close(); - } - - protected virtual void Dispose(bool disposing) - { - } - } // class WebResponse -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.WebStatus.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.WebStatus.cs deleted file mode 100644 index 8490d1bd..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.WebStatus.cs +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - /// - /// Defines status codes for the - /// class. - /// - public enum WebExceptionStatus - { - /// No error was encountered. - Success = 0, - /// The name resolver service could not resolve the host name. - /// - NameResolutionFailure = 1, - /// The remote service point could not be contacted at the - /// transport level. - ConnectFailure = 2, - /// A complete response was not received from the remote - /// server. - ReceiveFailure = 3, - /// A complete request could not be sent to the remote - /// server. - SendFailure = 4, - /// The request was a piplined request and the connection was - /// closed before the response was received. - PipelineFailure = 5, - /// The request was canceled or an unclassifiable error - /// occurred. This is the default value for - /// . - RequestCanceled = 6, - /// The response received from the server was complete but - /// indicated a protocol-level error. For example, an HTTP protocol - /// error such as 401 Access Denied would use this status. - ProtocolError = 7, - /// The connection was prematurely closed. - ConnectionClosed = 8, - /// A server certificate could not be validated. - TrustFailure = 9, - /// An error occurred while establishing a connection using - /// SSL. - SecureChannelFailure = 10, - /// The server response was not a valid HTTP - /// response. - ServerProtocolViolation = 11, - /// The connection for a request that specifies the Keep-alive - /// header was closed unexpectedly. - KeepAliveFailure = 12, - /// An internal asynchronous request is pending. - Pending = 13, - /// No response was received during the time-out period for a - /// request. - Timeout = 14, - /// The name resolver service could not resolve the proxy host - /// name. - ProxyNameResolutionFailure = 15 - } // enum WebStatus - -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net._HeaderInfo.cs b/source/nanoFramework.System.Net.Http/Http/System.Net._HeaderInfo.cs deleted file mode 100644 index 323fb45e..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net._HeaderInfo.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - - internal delegate string[] HeaderParser(string value); - - /// - /// Internal supporting class for validation of HTTP Web Headers. - /// - internal class HeaderInfo - { - - internal bool IsRestricted; - internal HeaderParser Parser; - - /// - /// Note that the HeaderName field is not always valid, and should not - /// be used after initialization. In particular, the HeaderInfo returned - /// for an unknown header will not have the correct header name. - /// - internal string HeaderName; - internal bool AllowMultiValues; - - internal HeaderInfo(string name, bool restricted, bool multi, HeaderParser p) - { - HeaderName = name; - IsRestricted = restricted; - Parser = p; - AllowMultiValues = multi; - } - } -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net._HeaderInfoTable.cs b/source/nanoFramework.System.Net.Http/Http/System.Net._HeaderInfoTable.cs deleted file mode 100644 index 3f82bccc..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net._HeaderInfoTable.cs +++ /dev/null @@ -1,171 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - - using System.Collections; - - /// - /// Internal class with utilities to validate HTTP headers. - /// - internal class HeaderInfoTable - { - - private static HeaderInfo[] HeaderTable; - - private static HeaderParser SingleParser = new HeaderParser(ParseSingleValue); - private static HeaderParser MultiParser = new HeaderParser(ParseMultiValue); - - private static string[] ParseSingleValue(string value) - { - return new string[1] { value }; - } - - /// - /// Parses single HTTP header and separates values delimited by comma. - /// Like "Content-Type: text, HTML". The value string "text, HTML" will se parsed into 2 strings. - /// - /// Value string with possible multivalue - /// Array of strings with single value in each. - private static string[] ParseMultiValue(string value) - { - ArrayList tempCollection = new ArrayList(); - - bool inquote = false; - int chIndex = 0; - char[] vp = new char[value.Length]; - string singleValue; - - for (int i = 0; i < value.Length; i++) - { - if (value[i] == '\"') - { - inquote = !inquote; - } - else if ((value[i] == ',') && !inquote) - { - singleValue = new String(vp, 0, chIndex); - tempCollection.Add(singleValue.Trim()); - chIndex = 0; - continue; - } - - vp[chIndex++] = value[i]; - } - - // - // Now add the last of the header values to the stringtable. - // - - if (chIndex != 0) - { - singleValue = new String(vp, 0, chIndex); - tempCollection.Add(singleValue.Trim()); - } - - return (string[])tempCollection.ToArray(typeof(string)); - } - - /// - /// Header info for non-standard headers. - /// - private static HeaderInfo UnknownHeaderInfo = - new HeaderInfo(String.Empty, false, false, SingleParser); - - private static bool m_Initialized = Initialize(); - - /// - /// Initialize table with infomation for HTTP WEB headers. - /// - /// - private static bool Initialize() - { - - HeaderTable = new HeaderInfo[] { - new HeaderInfo(HttpKnownHeaderNames.Age, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.Allow, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.Accept, true, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.Authorization, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.AcceptRanges, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.AcceptCharset, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.AcceptEncoding, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.AcceptLanguage, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.Cookie, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.Connection, true, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.ContentMD5, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.ContentType, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.CacheControl, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.ContentRange, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.ContentLength, true, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.ContentEncoding, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.ContentLanguage, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.ContentLocation, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.Date, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.ETag, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.Expect, true, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.Expires, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.From, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.Host, true, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.IfMatch, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.IfRange, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.IfNoneMatch, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.IfModifiedSince, true, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.IfUnmodifiedSince, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.Location, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.LastModified, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.MaxForwards, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.Pragma, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.ProxyAuthenticate, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.ProxyAuthorization, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.ProxyConnection, true, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.Range, true, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.Referer, true, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.RetryAfter, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.Server, false, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.SetCookie, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.SetCookie2, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.TE, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.Trailer, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.TransferEncoding, true , true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.Upgrade, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.UserAgent, true, false, SingleParser), - new HeaderInfo(HttpKnownHeaderNames.Via, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.Vary, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.Warning, false, true, MultiParser), - new HeaderInfo(HttpKnownHeaderNames.WWWAuthenticate, false, true, SingleParser) - }; - - return true; - } - - /// - /// Return HTTP header information from specified name of HTTP header. - /// - /// Name for HTTP header - /// HTTP header information - internal HeaderInfo this[string name] - { - get - { // Return headerInfo with the same name - string lowerCaseName = name.ToLower(); - for (int i = 0; i < HeaderTable.Length; i++) - { - if (HeaderTable[i].HeaderName.ToLower() == lowerCaseName) - { - return HeaderTable[i]; - } - } - - // Return unknownInfo, instead of NULL - return UnknownHeaderInfo; - } - } - - } // class HeaderInfoTable -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net._HttpDateParse.cs b/source/nanoFramework.System.Net.Http/Http/System.Net._HttpDateParse.cs deleted file mode 100644 index 63454c79..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net._HttpDateParse.cs +++ /dev/null @@ -1,494 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - - -namespace System.Net -{ - - /// - /// Internal class that parses the string with date in HTTP headers to DateTime object. - /// - internal class HttpDateParse - { - - /// - /// Bse for decimal numbers - /// - private const int BASE_DEC = 10; - - /// - /// Date indicies used to figure out what each entry is. - /// - private const int DATE_INDEX_DAY_OF_WEEK = 0; - - private const int DATE_1123_INDEX_DAY = 1; - private const int DATE_1123_INDEX_MONTH = 2; - private const int DATE_1123_INDEX_YEAR = 3; - private const int DATE_1123_INDEX_HRS = 4; - private const int DATE_1123_INDEX_MINS = 5; - private const int DATE_1123_INDEX_SECS = 6; - - private const int DATE_ANSI_INDEX_MONTH = 1; - private const int DATE_ANSI_INDEX_DAY = 2; - private const int DATE_ANSI_INDEX_HRS = 3; - private const int DATE_ANSI_INDEX_MINS = 4; - private const int DATE_ANSI_INDEX_SECS = 5; - private const int DATE_ANSI_INDEX_YEAR = 6; - - private const int DATE_INDEX_TZ = 7; - - private const int DATE_INDEX_LAST = DATE_INDEX_TZ; - private const int MAX_FIELD_DATE_ENTRIES = (DATE_INDEX_LAST + 1); - - // - // DATE_TOKEN's DWORD values used to determine what day/month we're on - // - - private const int DATE_TOKEN_JANUARY = 1; - private const int DATE_TOKEN_FEBRUARY = 2; - private const int DATE_TOKEN_MARCH = 3; - private const int DATE_TOKEN_APRIL = 4; - private const int DATE_TOKEN_MAY = 5; - private const int DATE_TOKEN_JUNE = 6; - private const int DATE_TOKEN_JULY = 7; - private const int DATE_TOKEN_AUGUST = 8; - private const int DATE_TOKEN_SEPTEMBER = 9; - private const int DATE_TOKEN_OCTOBER = 10; - private const int DATE_TOKEN_NOVEMBER = 11; - private const int DATE_TOKEN_DECEMBER = 12; - - private const int DATE_TOKEN_LAST_MONTH = (DATE_TOKEN_DECEMBER + 1); - - private const int DATE_TOKEN_SUNDAY = 0; - private const int DATE_TOKEN_MONDAY = 1; - private const int DATE_TOKEN_TUESDAY = 2; - private const int DATE_TOKEN_WEDNESDAY = 3; - private const int DATE_TOKEN_THURSDAY = 4; - private const int DATE_TOKEN_FRIDAY = 5; - private const int DATE_TOKEN_SATURDAY = 6; - - private const int DATE_TOKEN_LAST_DAY = (DATE_TOKEN_SATURDAY + 1); - - private const int DATE_TOKEN_GMT = -1000; - - private const int DATE_TOKEN_LAST = DATE_TOKEN_GMT; - - private const int DATE_TOKEN_ERROR = (DATE_TOKEN_LAST + 1); - - // - // MAKE_UPPER - takes an assumed lower character and bit manipulates into a upper. - // (make sure the character is Lower case alpha char to begin, - // otherwise it corrupts) - // - - private - static - char - MAKE_UPPER(char c) - { - - if (c >= 'a' && c <= 'z') - { - c -= (char)('a' - 'A'); - } - - return c; - } - - /*++ - - Routine Description: - - Arguments: - - lpszDay - - - Return Value: - - DWORD - Success - The Correct date token, 0-6 for day of the week, 1-14 for month, etc - - Failure - DATE_TOKEN_ERROR - - --*/ - /// - /// Looks at the first three bytes of string to determine if we're looking - /// at a Day of the Week, or Month, or "GMT" string. Is inlined so that - /// the compiler can optimize this code into the caller FInternalParseHttpDate. - /// - /// Array of characters respresenting of the string in question. - /// Staring index to for the time date in the string - /// - private - static - int - MapDayMonthToDword( - char[] lpszDay, - int index - ) - { - switch (MAKE_UPPER(lpszDay[index])) - { // make uppercase - case 'A': - switch (MAKE_UPPER(lpszDay[index + 1])) - { - case 'P': - return DATE_TOKEN_APRIL; - case 'U': - return DATE_TOKEN_AUGUST; - - } - - return DATE_TOKEN_ERROR; - - case 'D': - return DATE_TOKEN_DECEMBER; - - case 'F': - switch (MAKE_UPPER(lpszDay[index + 1])) - { - case 'R': - return DATE_TOKEN_FRIDAY; - case 'E': - return DATE_TOKEN_FEBRUARY; - } - - return DATE_TOKEN_ERROR; - - case 'G': - return DATE_TOKEN_GMT; - - case 'M': - - switch (MAKE_UPPER(lpszDay[index + 1])) - { - case 'O': - return DATE_TOKEN_MONDAY; - case 'A': - switch (MAKE_UPPER(lpszDay[index + 2])) - { - case 'R': - return DATE_TOKEN_MARCH; - case 'Y': - return DATE_TOKEN_MAY; - } - - // fall through to error - break; - } - - return DATE_TOKEN_ERROR; - - case 'N': - return DATE_TOKEN_NOVEMBER; - - case 'J': - - switch (MAKE_UPPER(lpszDay[index + 1])) - { - case 'A': - return DATE_TOKEN_JANUARY; - - case 'U': - switch (MAKE_UPPER(lpszDay[index + 2])) - { - case 'N': - return DATE_TOKEN_JUNE; - case 'L': - return DATE_TOKEN_JULY; - } - - // fall through to error - break; - } - - return DATE_TOKEN_ERROR; - - case 'O': - return DATE_TOKEN_OCTOBER; - - case 'S': - - switch (MAKE_UPPER(lpszDay[index + 1])) - { - case 'A': - return DATE_TOKEN_SATURDAY; - case 'U': - return DATE_TOKEN_SUNDAY; - case 'E': - return DATE_TOKEN_SEPTEMBER; - } - - return DATE_TOKEN_ERROR; - - case 'T': - switch (MAKE_UPPER(lpszDay[index + 1])) - { - case 'U': - return DATE_TOKEN_TUESDAY; - case 'H': - return DATE_TOKEN_THURSDAY; - } - - return DATE_TOKEN_ERROR; - - case 'U': - return DATE_TOKEN_GMT; - - case 'W': - return DATE_TOKEN_WEDNESDAY; - - } - - return DATE_TOKEN_ERROR; - } - - /// - /// Parses through a ANSI, RFC850, or RFC1123 date format and covents it into - /// a FILETIME/SYSTEMTIME time format. - /// - /// Important this a time-critical function and should only be changed - /// with the intention of optimizing or a critical need work item. - /// - /// - /// String with the date time information - /// - /// Out DateTime object. Used to return Systime if needed. - /// Success - TRUE, Failure - FALSE - public - static - bool - ParseHttpDate( - String DateString, - out DateTime dtOut - ) - { - int index = 0; - int i = 0, iLastLettered = -1; - bool fIsANSIDateFormat = false; - int[] rgdwDateParseResults = new int[MAX_FIELD_DATE_ENTRIES]; - bool fRet = true; - char[] lpInputBuffer = DateString.ToCharArray(); - - dtOut = new DateTime(0); - - // - // Date Parsing v2 (1 more to go), and here is how it works... - // We take a date string and churn through it once, converting - // integers to integers, Month,Day, and GMT strings into integers, - // and all is then placed IN order in a temp array. - // - // At the completetion of the parse stage, we simple look at - // the data, and then map the results into the correct - // places in the SYSTIME structure. Simple, No allocations, and - // No dirting the data. - // - // The end of the function does something munging and pretting - // up of the results to handle the year 2000, and TZ offsets - // Note: do we need to fully handle TZs anymore? - // - - while (index < DateString.Length && i < MAX_FIELD_DATE_ENTRIES) - { - if (lpInputBuffer[index] >= '0' && lpInputBuffer[index] <= '9') - { - // - // we have a numerical entry, scan through it and convent to DWORD - // - - rgdwDateParseResults[i] = 0; - - do - { - rgdwDateParseResults[i] *= BASE_DEC; - rgdwDateParseResults[i] += (lpInputBuffer[index] - '0'); - index++; - } while (index < DateString.Length && - lpInputBuffer[index] >= '0' && - lpInputBuffer[index] <= '9'); - - i++; // next token - } - else if ((lpInputBuffer[index] >= 'A' && lpInputBuffer[index] <= 'Z') || - (lpInputBuffer[index] >= 'a' && lpInputBuffer[index] <= 'z')) - { - // - // we have a string, should be a day, month, or GMT - // lets skim to the end of the string - // - - rgdwDateParseResults[i] = - MapDayMonthToDword(lpInputBuffer, index); - - iLastLettered = i; - - // We want to ignore the possibility of a time zone such as PST or EST in a non-standard - // date format such as "Thu Dec 17 16:01:28 PST 1998" (Notice that the year is _after_ the time zone - if ((rgdwDateParseResults[i] == DATE_TOKEN_ERROR) - && - !(fIsANSIDateFormat && (i == DATE_ANSI_INDEX_YEAR))) - { - fRet = false; - goto quit; - } - - // - // At this point if we have a vaild string - // at this index, we know for sure that we're - // looking at a ANSI type DATE format. - // - - if (i == DATE_ANSI_INDEX_MONTH) - { - fIsANSIDateFormat = true; - } - - // - // Read past the end of the current set of alpha characters, - // as MapDayMonthToDword only peeks at a few characters - // - - do - { - index++; - } while (index < DateString.Length && - ((lpInputBuffer[index] >= 'A' && lpInputBuffer[index] <= 'Z') || - (lpInputBuffer[index] >= 'a' && lpInputBuffer[index] <= 'z'))); - - i++; // next token - } - else - { - // - // For the generic case its either a space, comma, semi-colon, etc. - // the point is we really don't care, nor do we need to waste time - // worring about it (the orginal code did). The point is we - // care about the actual date information, So we just advance to the - // next lexume. - // - - index++; - } - } - - // - // We're finished parsing the string, now take the parsed tokens - // and turn them to the actual structured information we care about. - // So we build lpSysTime from the Array, using a local if none is passed in. - // - - int year; - int month; - int day; - int hour; - int minute; - int second; - int millisecond; - - millisecond = 0; - - if (fIsANSIDateFormat) - { - day = rgdwDateParseResults[DATE_ANSI_INDEX_DAY]; - month = rgdwDateParseResults[DATE_ANSI_INDEX_MONTH]; - hour = rgdwDateParseResults[DATE_ANSI_INDEX_HRS]; - minute = rgdwDateParseResults[DATE_ANSI_INDEX_MINS]; - second = rgdwDateParseResults[DATE_ANSI_INDEX_SECS]; - if (iLastLettered != DATE_ANSI_INDEX_YEAR) - { - year = rgdwDateParseResults[DATE_ANSI_INDEX_YEAR]; - } - else - { - // Warning! This is a hack to get around the toString/toGMTstring fiasco (where the timezone is - // appended at the end. (See above) - year = rgdwDateParseResults[DATE_INDEX_TZ]; - } - } - else - { - day = rgdwDateParseResults[DATE_1123_INDEX_DAY]; - month = rgdwDateParseResults[DATE_1123_INDEX_MONTH]; - year = rgdwDateParseResults[DATE_1123_INDEX_YEAR]; - hour = rgdwDateParseResults[DATE_1123_INDEX_HRS]; - minute = rgdwDateParseResults[DATE_1123_INDEX_MINS]; - second = rgdwDateParseResults[DATE_1123_INDEX_SECS]; - } - - // - // Normalize the year, 90 == 1990, handle the year 2000, 02 == 2002 - // This is Year 2000 handling folks!!! We get this wrong and - // we all look bad. - // - - if (year < 100) - { - year += ((year < 80) ? 2000 : 1900); - } - - // - // if we got misformed time, then plug in the current time - // !lpszHrs || !lpszMins || !lpszSec - // - - if ((i < 4) - || (day > 31) - || (hour > 23) - || (minute > 59) - || (second > 59)) - { - fRet = false; - goto quit; - } - - // - // Now do the DateTime conversion - // - - dtOut = new DateTime(year, month, day, hour, minute, second, millisecond); - - // - // Hack: we want the system time to be accurate. This is _suhlow_ - // The time passed in is in the local time zone; we have to convert this into GMT. - // - - if (iLastLettered == DATE_ANSI_INDEX_YEAR) - { - // this should be an unusual case. - // FIXME dtOut = dtOut.ToUniversalTime(); - } - - // - // If we have an Offset to another Time Zone - // then convert to appropriate GMT time - // - - if ((i > DATE_INDEX_TZ && - rgdwDateParseResults[DATE_INDEX_TZ] != DATE_TOKEN_GMT)) - { - - // - // if we received +/-nnnn as offset (hhmm), modify the output FILETIME - // - double offset; - - offset = (double)rgdwDateParseResults[DATE_INDEX_TZ]; - - dtOut.AddHours(offset); - } - - // In the end, we leave it all in LocalTime - - // FIXME dtOut = dtOut.ToLocalTime(); - - quit: - - return fRet; - } - } -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net._InputNetworkStreamWrapper.cs b/source/nanoFramework.System.Net.Http/Http/System.Net._InputNetworkStreamWrapper.cs deleted file mode 100644 index 411d17e5..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net._InputNetworkStreamWrapper.cs +++ /dev/null @@ -1,761 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System.IO; - using System.Net.Sockets; - using System.Runtime.CompilerServices; - using System.Threading; - - /// - /// The InputNetworkStreamWrapper is used to re-implement calls to NetworkStream.Read - /// It has internal buffer and during initial read operation it places available data from socket into buffer. - /// Later it releases data to Stream.Read calls. - /// It also provides direct access to bufferet data for internal code. - /// It provides possibility to "unread" or probe data - meaning user can read byte of data and then return it back to stream. - /// - internal class InputNetworkStreamWrapper : Stream - { - static private Text.Decoder UTF8decoder = System.Text.Encoding.UTF8.GetDecoder(); - static private Text.Encoding UTF8Encoding = System.Text.Encoding.UTF8; - - /// - /// Actual network or SSL stream connected to the server. - /// It could be SSL stream, so NetworkStream is not exact type, m_Stream would be derived from NetworkStream - /// - internal NetworkStream m_Stream; - - /// - /// Last time this stream was used ( used to timeout idle connections ). - /// - internal DateTime m_lastUsed; - - /// - /// This is a socket connected to client. - /// InputNetworkStreamWrapper owns the socket, not NetworkStream. - /// If connection is persistent, then the m_Socket is transferred to the list of - /// - internal Socket m_Socket; - - /// - /// Determines is the NetworkStream owns the socket - /// - internal bool m_OwnsSocket; - - /// - /// Address and port used for connection of the socket. It is in form of Address:Port ( like www.microsoft.com:80 ) - /// - internal string m_rmAddrAndPort; - - /// - /// Determines if the stream is currently in use or not. - /// - internal bool m_InUse; - - /// - /// Buffer for one line of HTTP header. - /// - private byte[] m_lineBuf; - - /// - /// Internal buffer size for read caching - /// - private const int read_buffer_size = 256; - - /// - /// Internal buffer for read caching - /// - internal byte[] m_readBuffer; - - /// - /// End of valid data in internal buffer. - /// - internal int m_dataEnd; - - /// - /// Start of valid data in internal buffer. - /// - internal int m_dataStart; - - /// - /// Indicates that the stream has chunking encoding. - /// We remove chunk markers and stop reading after end of last chunk. - /// - internal bool m_EnableChunkedDecoding; - - /// - /// Chunk data that we are currently decoding. - /// - private Chunk m_chunk; - - /// - /// Inidcates the stream wrapper object is a clone and they underlying stream should not be disposed - /// - private bool m_isClone; - - /// - /// Http web responses can contain the Content-Length of the response. In these cases, we would like the stream to return an EOF indication - /// if the caller tries to read past the content length. - /// - internal long m_BytesLeftInResponse; - - /// - /// Refills internal buffer from network. - /// - [MethodImpl(MethodImplOptions.Synchronized)] - private int RefillInternalBuffer() - { -#if DEBUG - if (m_dataStart != m_dataEnd) - { - Console.WriteLine("Internal ERROR in InputNetworkStreamWrapper"); - m_dataStart = m_dataEnd = 0; - } -#endif - // m_dataStart should be equal to m_dataEnd. Purge buffered data. - m_dataStart = m_dataEnd = 0; - // Read up to read_buffer_size, but less data can be read. - // This function does not try to block, so it reads available data or 1 byte at least. - int readCount = (int)m_Stream.Length; - if ( readCount > read_buffer_size ) - { - readCount = read_buffer_size; - } - else if (readCount == 0) - { - readCount = 1; - } - - m_dataEnd = m_Stream.Read(m_readBuffer, 0, readCount); - - return m_dataEnd; - } - - /// - /// Resets position in internal buffers to zeroes. - /// - internal void ResetState() - { - m_dataStart = m_dataEnd = 0; - m_EnableChunkedDecoding = false; - m_chunk = null; - } - - /// - /// Passes socket parameter to the base. - /// Base Network stream never owns the stream. - /// Socket is directly closed by class that contains InputNetworkStreamWrapper or transferred to - /// list of idle sockets. - /// - /// TBD - /// TBD - /// TBD - /// TBD - internal InputNetworkStreamWrapper( NetworkStream stream, Socket socket, bool ownsSocket, string rmAddrAndPort) - { - m_Stream = stream; - m_Socket = socket; - m_OwnsSocket = ownsSocket; - m_rmAddrAndPort = rmAddrAndPort; - m_InUse = true; - // negative value indicates no length is set, in which case we will continue to read upon the callers request - m_BytesLeftInResponse = -1; - - // Start with 80 (0x50) byte buffer for string. If string longer, we double it each time. - m_lineBuf = new byte[0x50]; - m_readBuffer = new byte[read_buffer_size]; - } - - /// - /// Re-implements reading of data to network stream. - /// - /// Buffer with data to write to HTTP client - /// Offset at which to use data from buffer - /// Count of bytes to write. - public override int Read(byte[] buffer, int offset, int size) - { - // If chunking decoding is not needed - perform normal read. - if (!m_EnableChunkedDecoding) - { - return ReadInternal(buffer, offset, size); - } - - // With chunking decoding there are 4 cases: - // 1. We are at the beginning of chunk. Then we read chunk header and fill m_chunk. - // 2. We are in the middle of chunk. Then it is kind of normal read, but no more than chunk length. - // 3. We are close to the end of chunk. Then we read maximum of data in the chunk and set m_chunk to null. - // 4. We already read last chunk of zero size. Return with zero bytes read. - if (m_chunk == null) - { - // We are in the beginnig of the chunk. Create new chunk and continue. This is case 1. - m_chunk = GetChunk(); - } - - // First validate that chunk is more than zero in size. The last chunk is zero size and it indicates end of data. - if (m_chunk.m_Size == 0) - { - // Nothing to read and actually it is the end of the message body. It is "case 4". - return 0; - } - - // Check if request to read is larger than remaining data in the chunk. - if (size > m_chunk.m_Size - m_chunk.m_OffsetIntoChunk) - { - // We set size to the maximum data remaining the the chunk. This is the case 3. - size = (int)(m_chunk.m_Size - m_chunk.m_OffsetIntoChunk); - } - - // Ok, we know that we are in process of reading chunk data. This is case 2. - // size is already adjusted to the maximum data remaining in the chunk. - int retVal = ReadInternal(buffer, offset, size); - - // Adjust offset into chunk by amount of data read. retVal could be less than size. - m_chunk.m_OffsetIntoChunk += (uint)retVal; - - // If we reached end of chunk, then set m_chunk to null. This indicates that chunk was completed. - if (m_chunk.m_OffsetIntoChunk == m_chunk.m_Size) - { - m_chunk = null; - } - - return retVal; - } - - /// - /// Clears the read buffer and reads from the underlying stream until no more data is available. - /// - public void FlushReadBuffer() - { - byte[] buffer = new byte[1024]; - - int waitTimeUs = m_BytesLeftInResponse == 0 ? 500000 : 1000000; - - try - { - while (m_Socket.Poll(waitTimeUs, SelectMode.SelectRead)) - { - int avail = m_Socket.Available; - - if(avail == 0) break; - - while (avail > 0) - { - int bytes = m_Stream.Read(buffer, 0, avail > buffer.Length ? buffer.Length : avail); - - if (bytes <= 0) break; - - avail -= bytes; - - if (m_BytesLeftInResponse > 0) m_BytesLeftInResponse -= bytes; - } - } - } - catch - { - } - - m_dataEnd = m_dataStart = 0; - m_BytesLeftInResponse = -1; - } - - private void ReleaseThread() - { - FlushReadBuffer(); - - m_lastUsed = DateTime.UtcNow; - ResetState(); - - m_InUse = false; - } - - /// - /// Flushes the read buffer and resets the streams parameters. When in used in conjunction with the HttpWebRequest class - /// this method enables this stream to be re-used. - /// - public void ReleaseStream() - { - Thread th = new Thread(new ThreadStart(ReleaseThread)); - th.Start(); - } - - /// - /// Re-implements reading of data to network stream. - /// - /// Buffer with data to write to HTTP client - /// Offset at which to use data from buffer - /// Count of bytes to write. - public int ReadInternal(byte[] buffer, int offset, int size) - { - // Need to init return value to zero explicitly, otherwise warning generated. - int retVal = 0; - - // As first step we copy the buffered data if present - int dataBuffered = m_dataEnd - m_dataStart; - if (dataBuffered > 0) - { - int dataToCopy = size < dataBuffered ? size : dataBuffered; - for (int i = 0; i < dataToCopy; i++) - { - buffer[offset + i] = m_readBuffer[m_dataStart + i]; - } - m_dataStart += dataToCopy; - offset += dataToCopy; - size -= dataToCopy; - retVal += dataToCopy; - } - - // - // Now we check if more data is needed. - // if m_BytesLeftInResponse == -1 , then we don't known the content length of the response - // if m_BytesLeftInResponse is > retVal, then the data in the internal buffer (above) was less than the - // the total content length of the response stream - // In either case, we need to read more data to fullfill the read request - // - if (size > 0 && (m_BytesLeftInResponse == -1 || m_BytesLeftInResponse > retVal)) - { - // If buffering desired and requested data is less than internal buffer size - // then we read into internal buffer. - if (size < read_buffer_size) - { - if(0 == RefillInternalBuffer()) return 0; - - dataBuffered = m_dataEnd - m_dataStart; - if (dataBuffered > 0) - { - int dataToCopy = size < dataBuffered ? size : dataBuffered; - for (int i = 0; i < dataToCopy; i++) - { - buffer[offset + i] = m_readBuffer[m_dataStart + i]; - } - m_dataStart += dataToCopy; - offset += dataToCopy; - size -= dataToCopy; - retVal += dataToCopy; - } - } - else // Do not replentish internal buffer. Read rest of data directly - { - retVal += m_Stream.Read(buffer, offset, size); - } - } - - // update the bytes left in response - if(m_BytesLeftInResponse > 0) - { - m_BytesLeftInResponse -= retVal; - - // in case there were more bytes in the buffer than we expected make sure the next call returns 0 - if(m_BytesLeftInResponse < 0) m_BytesLeftInResponse = 0; - } - - return retVal; - } - - /// - /// Impletments Write for the stream. - /// Since we do not have write buffering, all we do is delegate to the m_Stream. - /// - /// Buffer to write - /// Start offset to write data - /// Count of bytes to write - public override void Write(byte[] buffer, int offset, int count) - { - m_Stream.Write(buffer, offset, count); - } - - /// - /// Since we do not have write buffering, all we do is delegate to the m_Stream. - /// - public override void Flush() - { - m_Stream.Flush(); - } - - /// - /// Return true if stream support reading. - /// - public override bool CanRead { get { return m_Stream.CanRead; } } - - /// - /// Return true if stream supports seeking - /// - public override bool CanSeek { get { return m_Stream.CanSeek; } } - - /// - /// Return true if timeout is applicable to the stream - /// - public override bool CanTimeout { get { return m_Stream.CanTimeout; } } - - /// - /// Return true if stream support writing. - /// - public override bool CanWrite { get { return m_Stream.CanWrite; } } - - /// - /// Gets the length of the data available on the stream. - /// - /// The length of the data available on the stream. - /// Add data cached in the stream buffer to available on socket - public override long Length { get { return m_EnableChunkedDecoding && m_chunk != null ? m_chunk.m_Size : m_Stream.Length + m_dataEnd - m_dataStart; } } - - /// - /// Position is not supported for NetworkStream - /// - public override long Position - { - get - { - throw new NotSupportedException(); - } - set - { - throw new NotSupportedException(); - } - } - - /// - /// Seekking is not suported on network streams - /// - /// Offset to seek - /// Relative origin of the seek - /// - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException(); - } - - /// - /// Setting of length is not supported - /// - /// Length to set - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - /// - /// Timeout for read operations. - /// - public override int ReadTimeout - { - get { return m_Stream.ReadTimeout; } - set { m_Stream.ReadTimeout = value; } - } - - /// - /// Timeout for write operations. - /// - public override int WriteTimeout - { - get { return m_Stream.WriteTimeout; } - set { m_Stream.WriteTimeout = value; } - } - - public Stream CloneStream() - { - InputNetworkStreamWrapper clone = this.MemberwiseClone() as InputNetworkStreamWrapper; - clone.m_isClone = true; - - return clone; - } - - /// - /// Overrides the Dispose Behavior - /// - protected override void Dispose(bool disposing) - { - m_InUse = false; - - if (!m_isClone) - { - m_Stream.Close(); - - if(m_OwnsSocket) - { - m_Socket.Close(); - } - } - - base.Dispose(disposing); - } - - /// - /// Reads one line from steam, terminated by \r\n or by \n. - /// - /// Maxinun length of the line. If line is longer than maxLineLength exception is thrown - /// String that represents the line, not including \r\n or by \n - internal string Read_HTTP_Line( int maxLineLength ) - { - int curPos = 0; - bool readLineComplete = false; - - while (!readLineComplete) - { - // We need to read character by character. For efficiency we need stream that implements internal bufferting. - // We cannot read more than one character at a time, since this one could be the last. - int maxCurSize = m_lineBuf.Length - 1; - maxCurSize = maxCurSize < maxLineLength ? maxCurSize : maxLineLength; - while (curPos < maxCurSize) - { - // If data available, Reads one byte of data. - if (m_dataEnd - m_dataStart > 0) - { // Very special code for reading of one character. - m_lineBuf[curPos] = m_readBuffer[m_dataStart]; ++curPos; ++m_dataStart; - } - else - { // Refill internal buffer and read one character. - if(0 == RefillInternalBuffer()) - { - readLineComplete = true; - break; - } - m_lineBuf[curPos] = m_readBuffer[m_dataStart]; ++curPos; ++m_dataStart; - } - - // Accoring to HTTP spec HTTP headers lines should be separated by "\r\n" - // Still spec requires for testing of "\n" only. So we test both - if (m_lineBuf[curPos - 1] == '\r' || m_lineBuf[curPos - 1] == '\n') - { - // Next character should be '\n' if previous was '\r' - if (m_lineBuf[curPos - 1] == '\r') - { - // If data available, Reads one byte of data. - if (m_dataEnd - m_dataStart > 0) - { // Very special code for reading of one character. - m_lineBuf[curPos] = m_readBuffer[m_dataStart]; ++curPos; ++m_dataStart; - } - else - { // Refill internal buffer and read one character. - if(0 == RefillInternalBuffer()) - { - readLineComplete = true; - break; - } - m_lineBuf[curPos] = m_readBuffer[m_dataStart]; ++curPos; ++m_dataStart; - } - } - readLineComplete = true; - break; - } - } - - // If we reached limit of the line size, just throw protocol violation exception. - if (curPos == maxLineLength) - { - throw new WebException("Line too long", WebExceptionStatus.ServerProtocolViolation); - } - - // There was no place in the m_lineBuf or end of line reached. - if (!readLineComplete) - { - // Need to allocate larger m_lineBuf and copy existing line there. - byte[] newLineBuf = new byte[m_lineBuf.Length * 2]; - // Copy data to new array - m_lineBuf.CopyTo(newLineBuf, 0); - // Re-assign. Now m_lineBuf is twice as long and keeps the same data. - m_lineBuf = newLineBuf; - } - } - // Now we need to convert from byte array to string. - if (curPos - 2 > 0) - { - int byteUsed, charUsed; - bool completed = false; - char[] charBuf = new char[curPos - 2]; - UTF8decoder.Convert(m_lineBuf, 0, curPos - 2, charBuf, 0, charBuf.Length, true, out byteUsed, out charUsed, out completed); - return new string(charBuf); - } - else if(curPos == 0) - { - throw new SocketException(SocketError.ConnectionAborted); - } - - return ""; - } - - /// - /// Preview the byte in the input stream without removing it. - /// - /// Next byte in the stream. - private byte PeekByte() - { - // Refills internal buffer if there is no more data - if (m_dataEnd == m_dataStart) - { - if(0 == RefillInternalBuffer()) throw new SocketException(SocketError.ConnectionAborted); - } - return m_readBuffer[m_dataStart]; - } - - /// - /// Returns the byte in the input stream and removes it. - /// - /// Next byte in the stream. - public override int ReadByte() - { - // Refills internal buffer if there is no more data - if (m_dataEnd == m_dataStart) - { - if(0 == RefillInternalBuffer()) throw new SocketException(SocketError.ConnectionAborted); - } - // Very similar to Peek, but moves current position to next byte. - return m_readBuffer[m_dataStart++]; - } - - /// - /// Writes single byte to stream - /// - /// - public override void WriteByte(byte value) - { - m_Stream.WriteByte(value); - } - - /// - /// Reads HTTP header from input stream. - /// HTTP header can be wrapped on multiple lines. - /// If next line starts by white space or tab - means it is continuing current header. - /// Thus we need to use PeekByte() to check next byte without removing it from stream. - /// - /// Maximum length of the header - /// - internal string Read_HTTP_Header(int maxLineLength) - { - string strHeader = Read_HTTP_Line(maxLineLength); - int headLineLen = strHeader.Length; - - // If line is empty - means the last one. Just return it. - if (headLineLen == 0) - { - return strHeader; - } - - maxLineLength -= headLineLen; - // Check next byte in the stream. If it is ' ' or '\t' - next line is continuation of existing header. - while (maxLineLength > 0 ) - { - byte nextByte = PeekByte(); - // If next byte is not white space or tab, then we are done. - if (!(nextByte == ' ' || nextByte == '\t')) - { - return strHeader; - } - // If we got here - means next line starts by white space or tab. Need to read it and append it. - string strLine = Read_HTTP_Line(maxLineLength); - // Decrease by amount of data read - maxLineLength -= strLine.Length; - // Adds it to the header. - strHeader += strLine; - } - // If we come here - means HTTP header exceedes maximum length. - throw new WebException("HTTP header too long", WebExceptionStatus.ServerProtocolViolation); - } - - /// - /// Retrieve information of the chunk. - /// - /// - private Chunk GetChunk() - { - Chunk nextChunk = new Chunk(); - bool parsing = true; - ChunkState state = ChunkState.InitialLF; - byte[] buffer = new byte[1024]; - byte[] data; - int dataByte = 0; - - while (parsing) - { - int readByte = ReadByte(); - switch (readByte) - { - case 13: //CR - if (state == ChunkState.InitialLF) - break; - - data = new byte[dataByte]; - Array.Copy(buffer, data, dataByte); - switch (state) - { - case ChunkState.Size: - nextChunk.m_Size = (uint)Convert.ToInt32(new string(UTF8Encoding.GetChars(data)), 16); - dataByte = 0; - break; - case ChunkState.Value: - dataByte = 0; - break; - default: - throw new ProtocolViolationException("Wrong state for CR"); - } - state = ChunkState.LF; - break; - case 10: //LF - switch (state) - { - - case ChunkState.LF: - parsing = false; - break; - case ChunkState.InitialLF: - state = ChunkState.Size; - break; - default: - throw new ProtocolViolationException("Incorrectly formated Chunk - Unexpected Line Feed"); - } - break; - case 59: // ; - if (state == ChunkState.Size) - { - data = new byte[dataByte]; - Array.Copy(buffer, data, dataByte); - nextChunk.m_Size = (uint)Convert.ToInt32(new string(UTF8Encoding.GetChars(data)),16); - dataByte = 0; - } - else - throw new ProtocolViolationException("Incorrectly formated Chunk"); - state = ChunkState.Name; - break; - case 61: // = - if (state == ChunkState.Name) - { - dataByte = 0; - } - else - throw new ProtocolViolationException("Incorrectly formated Chunk"); - state = ChunkState.Value; - break; - default: - if (state == ChunkState.InitialLF) - state = ChunkState.Size; - buffer[dataByte] = (byte)readByte; - dataByte++; - if (state == ChunkState.LF) - throw new ProtocolViolationException("Unexpected data after Line Feed"); - break; - } - } - - return nextChunk; - } - - private enum ChunkState - { - Size, - Name, - Value, - LF, - InitialLF - } - - private class Chunk - { - public uint m_Size; - public uint m_OffsetIntoChunk; - } - - } -} diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net._OutputNetworkStreamWrapper.cs b/source/nanoFramework.System.Net.Http/Http/System.Net._OutputNetworkStreamWrapper.cs deleted file mode 100644 index 908fa776..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net._OutputNetworkStreamWrapper.cs +++ /dev/null @@ -1,220 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System.IO; - using System.Net.Sockets; - - /// - /// The OutputNetworkStreamWrapper is used to re-implement calls to NetworkStream.Write - /// On first write HttpListenerResponse needs to send HTTP headers to client. - /// - internal class OutputNetworkStreamWrapper : Stream - { - - /// - /// This is a socket connected to client. - /// OutputNetworkStreamWrapper owns the socket, not NetworkStream. - /// If connection is persistent, then the m_Socket is transferred to the list of - /// - internal Socket m_Socket; - - /// - /// Actual network or SSL stream connected to the client. - /// It could be SSL stream, so NetworkStream is not exact type, m_Stream would be derived from NetworkStream - /// - internal NetworkStream m_Stream; - - /// - /// Type definition of delegate for sending of HTTP headers. - /// - internal delegate void SendHeadersDelegate(); - - /// - /// If not null - indicates whether we have sent headers or not. - /// Calling of delegete sends HTTP headers to client - HttpListenerResponse.SendHeaders() - /// - private SendHeadersDelegate m_headersSend; - - /// - /// Just passes parameters to the base. - /// Socket is not owned by base NetworkStream - /// - /// - /// - public OutputNetworkStreamWrapper(Socket socket, NetworkStream stream) - { - m_Socket = socket; - m_Stream = stream; - } - - /// - /// Sets the delegate for sending of headers. - /// - internal SendHeadersDelegate HeadersDelegate { set { m_headersSend = value; } } - - /// - /// Return true if stream support reading. - /// - public override bool CanRead { get { return false; } } - - /// - /// Return true if stream supports seeking - /// - public override bool CanSeek { get { return false; } } - - /// - /// Return true if timeout is applicable to the stream - /// - public override bool CanTimeout { get { return m_Stream.CanTimeout; } } - - /// - /// Return true if stream support writing. It should be true, as this is output stream. - /// - public override bool CanWrite { get { return true; } } - - /// - /// Gets the length of the data available on the stream. - /// Since this is output stream reading is not allowed and length does not have meaning. - /// - /// The length of the data available on the stream. - public override long Length { get { throw new NotSupportedException(); } } - - /// - /// Position is not supported for NetworkStream - /// - public override long Position - { - get - { - throw new NotSupportedException(); - } - - set - { - throw new NotSupportedException(); - } - } - - /// - /// Timeout for read operations. - /// - public override int ReadTimeout - { - get { return m_Stream.ReadTimeout; } - set { m_Stream.ReadTimeout = value; } - } - - /// - /// Timeout for write operations. - /// - public override int WriteTimeout - { - get { return m_Stream.WriteTimeout; } - set { m_Stream.WriteTimeout = value; } - } - - /// - /// Closes the stream. Verifies that HTTP response is sent before closing. - /// - public override void Close() - { - if (m_headersSend != null) - { - // Calls HttpListenerResponse.SendHeaders. HttpListenerResponse.SendHeaders sets m_headersSend to null. - m_headersSend(); - } - - if (m_Stream != null) m_Stream.Close(); - m_Stream = null; - m_Socket = null; - } - - /// - /// Flushes the stream. Verifies that HTTP response is sent before flushing. - /// - public override void Flush() - { - if (m_headersSend != null) - { - // Calls HttpListenerResponse.SendHeaders. HttpListenerResponse.SendHeaders sets m_headersSend to null. - m_headersSend(); - } - - m_Stream.Flush(); - } - - /// - /// This putput stream, so read is not supported. - /// - /// - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - - /// - /// This putput stream, so read is not supported. - /// - /// - public override int ReadByte() - { - throw new NotSupportedException(); - } - - /// - /// Seeking is not suported on network streams - /// - /// Offset to seek - /// Relative origin of the seek - /// - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException(); - } - - /// - /// Setting length is not suported on network streams - /// - /// Length to set - /// - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - /// - /// Writes single byte to the stream. - /// - /// Byte value to write. - public override void WriteByte(byte value) - { - m_Stream.WriteByte(value); - } - - /// - /// Re-implements writing of data to network stream. - /// The only functionality - on first write it sends HTTP headers. - /// Then calls base - /// - /// Buffer with data to write to HTTP client - /// Offset at which to use data from buffer - /// Count of bytes to write. - public override void Write(byte[] buffer, int offset, int size) - { - if (m_headersSend != null) - { - // Calls HttpListenerResponse.SendHeaders. HttpListenerResponse.SendHeaders sets m_headersSend to null. - m_headersSend(); - } - - m_Stream.Write(buffer, offset, size); - } - } -} - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net._ValidationHelper.cs b/source/nanoFramework.System.Net.Http/Http/System.Net._ValidationHelper.cs deleted file mode 100644 index 449033f4..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net._ValidationHelper.cs +++ /dev/null @@ -1,136 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System; - - /// - /// Internal support class for Validation related stuff. - /// - internal class ValidationHelper - { - - public static string[] EmptyArray = new string[0]; - - public static string[] MakeEmptyArrayNull(string[] stringArray) - { - if (stringArray == null || stringArray.Length == 0) - { - return null; - } - else - { - return stringArray; - } - } - - public static string MakeStringNull(string stringValue) - { - if (stringValue == null || stringValue.Length == 0) - { - return null; - } - else - { - return stringValue; - } - } - - public static string MakeStringEmpty(string stringValue) - { - if (stringValue == null || stringValue.Length == 0) - { - return String.Empty; - } - else - { - return stringValue; - } - } - - public static bool IsBlankString(string stringValue) - { - if (stringValue == null || stringValue.Length == 0) - { - return true; - } - else - { - return false; - } - } - - public static short ValidatePort(int port) - { - - if ((port < IPEndPoint.MinPort) || - (port > IPEndPoint.MaxPort)) - { // If upper 16b is not zero... - throw new ArgumentOutOfRangeException("port"); // Then this is not valid port - } - - return (short)port; - } - - public static bool ValidateTcpPort(int port) - { - // on false, API should throw new ArgumentOutOfRangeException("port"); - return port >= IPEndPoint.MinPort && port <= IPEndPoint.MaxPort; - } - - public static void ValidateRange(int actual, int fromAllowed, int toAllowed) - { - if (actual > toAllowed || actual < fromAllowed) - { - throw new ArgumentOutOfRangeException("value"); - } - } - - public static string ExceptionMessage(Exception exception) - { - if (exception == null) - { - return string.Empty; - } - - if (exception.InnerException == null) - { - return exception.Message; - } - - return exception.Message + " (" + ExceptionMessage(exception.InnerException) + ")"; - } - - internal static readonly char[] InvalidParamChars = - new char[]{ - '(', - ')', - '<', - '>', - '@', - ',', - ';', - ':', - '\\', - '"', - '\'', - '/', - '[', - ']', - '?', - '=', - '{', - '}', - ' ', - '\t', - '\r', - '\n'}; - - } -} - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.iwebproxy.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.iwebproxy.cs deleted file mode 100644 index 50d42238..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.iwebproxy.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System.Net -{ - using System; - - /// - /// Provides the base interface for implementing proxy access for the - /// class. - /// - public interface IWebProxy - { - - /// - /// Returns the URI of a proxy. - /// - /// The destination URI. - /// A Uri instance that contains the URI of the proxy - /// used to contact . - Uri GetProxy(Uri destination); - - /// - /// Indicates whether the proxy should not be used for the specified - /// host. - /// - /// The host to check, to determine whether the proxy - /// is needed to access it. - /// Whether the proxy should not be used for the specified - /// host. - bool IsBypassed(Uri host); - } -} - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Net.webproxy.cs b/source/nanoFramework.System.Net.Http/Http/System.Net.webproxy.cs deleted file mode 100644 index 87ae9dd4..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Net.webproxy.cs +++ /dev/null @@ -1,237 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - - -namespace System.Net -{ - - /// - /// Contains HTTP proxy settings for the - /// class. - /// - public class WebProxy : IWebProxy - { - - // true means DO NOT use proxy on local connections. - // false means use proxy for local network connections. - - private bool _BypassOnLocal; - private Uri _ProxyAddress; // Uri of proxy itself - - /// - /// Initializes an empty instance of the WebProxy class. - /// - /// - /// The URI of the proxy can be set later, using the - /// property. - /// - public WebProxy() - : this((Uri)null, false) - { - } - - /// - /// Initializes a new instance of the WebProxy class - /// from the specified instance. - /// - /// A Uri instance that - /// contains the address of the proxy server. - public WebProxy(Uri Address) - : this(Address, false) - { - } - - /// - /// Initializes a new instance of the WebProxy class - /// with the specified instance and bypass - /// setting. - /// - /// A Uri instance that - /// contains the address of the proxy server. - /// Indicates whether to bypass the WebProxy - /// on local network addresses. - public WebProxy(Uri Address, bool BypassOnLocal) - { - _ProxyAddress = Address; - _BypassOnLocal = BypassOnLocal; - } - - /// - /// Initializes a new instance of the WebProxy class - /// with the specified host and port number. - /// - /// The name of the proxy host, such as: contoso - /// The port number on the host to use, such as: - /// 80 - /// - /// The WebProxy instance is initialized with the - /// property set - /// to a instance of the form: http://Host:Port - /// - public WebProxy(string Host, int Port) - : this(new Uri("http://" + Host + ":" + Port.ToString()), false) { } - - /// - /// Initializes a new instance of the WebProxy class - /// with the specified URI. - /// - /// The URI address of the proxy server. - /// - /// The WebProxy instance is initialized with the - /// property set to a - /// instance containing the - /// Address string. - /// - /// For the new instance of the WebProxy class, - /// "Bypass on local addresses" is set to false. - /// - /// - public WebProxy(string Address) - : this(CreateProxyUri(Address), false) { } - - /// - /// Initializes a new instance of the WebProxy class - /// with the specified URI and bypass setting. - /// - /// The URI of the proxy server. - /// Indicates whether to bypass the proxy - /// when accessing local addresses. - public WebProxy(string Address, bool BypassOnLocal) - : this(CreateProxyUri(Address), BypassOnLocal) { } - - /// - /// Gets or sets the address of the proxy server. - /// - /// A instance that contains the address - /// of the proxy server. - public Uri Address - { - get - { - return _ProxyAddress; - } - - set - { - _ProxyAddress = value; - } - } - - /// - /// Gets or sets whether to bypass the proxy server for local - /// addresses. - /// true to bypass the proxy server for local - /// addresses; otherwise, false. - public bool BypassProxyOnLocal - { - get - { - return _BypassOnLocal; - } - - set - { - _BypassOnLocal = value; - } - } - - /// - /// Returns the proxied URI for a request. - /// - /// The Uri instance of the - /// requested Internet resource. - /// The Uri instance of the Internet - /// resource, if the resource is on the bypass list; otherwise, the - /// Uri instance of the proxy. - /// - public Uri GetProxy(Uri destination) - { - if (IsBypassed(destination)) - { - return destination; - } - - Uri proxy = _ProxyAddress; - if (proxy != null) - { - return proxy; - } - - return destination; - } - - /// - /// Maps a string to a Uri. - /// - /// The Url for creation of the Uri. - /// The new Uri corresponding to the Url. - private static Uri CreateProxyUri(string Address) - { - if (Address == null) - { - return null; - } - - // Original code was IndexOf("://", StringComparison.Ordinal), - // changed to IndexOf("://") we only support ASCII in .NET MF. - if (Address.IndexOf("://") == -1) - { - Address = "http://" + Address; - } - - return new Uri(Address); - } - - /// - /// Checks whether the supplied Uri represents a local address. - /// - /// The Uri to check. - /// trueif the address is local; otherwise, - /// false. - private bool IsLocal(Uri host) - { - string hostString = host.Host; - int dot = hostString.IndexOf('.'); - - if (dot == -1) - { - return true; - } - - return false; - } - - /// - /// Indicates whether to use the proxy server for the specified host. - /// - /// The Uri instance of the host - /// to check for proxy use. - /// true if the proxy server should not be - /// used for the host; otherwise, false. - public bool IsBypassed(Uri host) - { - - if (host.IsLoopback) - { - return true; // bypass localhost from using a proxy. - } - - if ((_ProxyAddress == null) || - (_BypassOnLocal && IsLocal(host))) - { - return true; // bypass when non .'s and no proxy on local - } - else - { - return false; - } - } - - }; // class WebProxy - -} // namespace System.Net - - diff --git a/source/nanoFramework.System.Net.Http/Http/System.Uri.cs b/source/nanoFramework.System.Net.Http/Http/System.Uri.cs deleted file mode 100644 index 75a0c7f3..00000000 --- a/source/nanoFramework.System.Net.Http/Http/System.Uri.cs +++ /dev/null @@ -1,1060 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -namespace System -{ - /// - /// Defines the kinds of s for the - /// method and several - /// methods. - /// - public enum UriKind - { - /// - /// The kind of the Uri is indeterminate. - /// - RelativeOrAbsolute = 0, - - /// - /// The Uri is an absolute Uri. - /// - Absolute = 1, - - /// - /// The Uri is a relative Uri. - /// - Relative = 2, - } - - /// - /// Defines host name types for the http and https protocols. - /// method. - /// - public enum UriHostNameType - { - /// - /// The type of the host name is not supplied. - /// - Unknown = 0, - - /// - /// The host is set, but the type cannot be determined. - /// - Basic = 1, - - /// - /// The host name is a domain name system (DNS) style host name. - /// - Dns = 2, - - /// - /// The host name is an Internet Protocol (IP) version 4 host address. - /// - IPv4 = 3, - - /// - /// The host name is an Internet Protocol (IP) version 6 host address. - /// - IPv6 = 4, - } - - /// - /// Provides an object representation of a uniform resource identifier (URI) - /// and easy access to the parts of the URI. - /// - public class Uri - { - private int DefaultPort(string scheme) - { - switch (scheme) - { - case "http": return 80; - case "https": return 443; - case "ftp": return 21; - case "gopher": return 70; - case "nntp": return 119; - case "telnet": return 23; - case "ldap": return 389; - case "mailto": return 25; - case "net.tcp": return 808; - case "ws": return 80; - default: return UnknownPort; - } - } - - /// - /// Defines flags kept in m_Flags variable. - /// - protected enum Flags - { - /// - /// Flag value for loopback host - /// - LoopbackHost = 0x00400000 - } - - /// - /// Default port for http protocol - 80 - /// - public const int HttpDefaultPort = 80; - - /// - /// Default port for https protocol - 443 - /// - public const int HttpsDefaultPort = 443; - - /// - /// Constant to indicate that port for this protocol is unknown - /// - protected const int UnknownPort = -1; - - /// - /// Type of the host. - /// - protected UriHostNameType m_hostNameType; - - /// - /// Member variable that keeps port used by this uri. - /// - protected int m_port = UnknownPort; - - /// - /// Member variable that keeps internal flags/ - /// - protected int m_Flags = 0; - - /// - /// Member varialbe that keeps absolute path. - /// - protected string m_AbsolutePath = null; - - /// - /// Member varialbe that keeps original string passed to Uri constructor. - /// - protected string m_OriginalUriString = null; - - /// - /// Member varialbe that keeps scheme of Uri. - /// - protected string m_scheme = null; - - /// - /// Member varialbe that keeps host name ( http and https ). - /// - protected string m_host = ""; - - /// - /// Member varialbe that keeps boolean if Uri is absolute. - /// - protected bool m_isAbsoluteUri = false; - - /// - /// Member varialbe that tells if path is UNC ( Universal Naming Convention ) - /// In this class it is always false, but can be changed in derived classes. - /// - protected bool m_isUnc = false; - - /// - /// Member variable that keeps absolute uri (generated in method ParseUriString) - /// - protected string m_absoluteUri = null; - - /// - /// Initializes a new instance of the class - /// with the specified URI. - /// - /// - /// This constructor parses the URI string, therefore it can be used to - /// validate a URI. - /// - /// A URI. - /// - /// The is null. - /// - /// - ///

The is empty.

- ///

-or-

The scheme specified in - /// is not correctly formed.

- ///

-or-

contains too many - /// slashes.

- ///

-or-

The password specified in - /// is not valid.

- ///

-or-

The host name specified in - /// is not valid.

- ///

-or-

The file name specified in - /// is not valid.

- ///

-or-

The user name specified in - /// is not valid.

- ///

-or-

The host or authority name specified in - /// cannot be terminated by backslashes. - ///

- ///

-or-

The port number specified in - /// is not valid or cannot be parsed.

- ///

-or-

The length of exceeds - /// 65534 characters.

- ///

-or-

The length of the scheme specified in - /// exceeds 1023 characters.

- ///

-or-

There is an invalid character sequence in - /// .

- ///

-or-

The MS-DOS path specified in - /// must start with c:\\.

- ///
- public Uri(string uriString) - { - ConstructAbsoluteUri(uriString); - } - - /// - /// Constructs an absolute Uri from a URI string. - /// - /// A URI. - /// - /// See . - /// - protected void ConstructAbsoluteUri(string uriString) - { - // ParseUriString provides full validation including testing for - // null. - ParseUriString(uriString); - m_OriginalUriString = uriString; - } - - /// - /// Constructs Uri from string and enumeration that tell what is the type of Uri. - /// - /// String to construct Uri from - /// Type of Uri to construct - public Uri(string uriString, UriKind kind) - { - // ParseUriString provides full validation including testing for null. - switch (kind) - { - case UriKind.Absolute: { ConstructAbsoluteUri(uriString); break; } - // Do not support unknown type of Uri. User should decide what he wants. - case UriKind.RelativeOrAbsolute: { throw new ArgumentException(); } - // Relative Uri. Store in original string. - case UriKind.Relative: - { - // Validates the relative Uri. - ValidateUriPart(uriString, 0); - m_OriginalUriString = uriString; - break; - } - } - - m_OriginalUriString = uriString; - } - - /// - /// Validates that part of Uri after sheme is valid for unknown Uri scheme - /// - /// Uri string - /// Index in the string where Uri part ( after scheme ) starts - protected void ValidateUriPart(string uriString, int startIndex) - { - // Check for valid alpha numeric characters - int pathLength = uriString.Length - startIndex; - - // This is unknown scheme. We do validate following rules: - // 1. All character values are less than 128. For characters it means they are more than zero. - // 2. All charaters are >= 32. Lower values are control characters. - // 3. If there is %, then there should be 2 hex digits which are 0-10 and A-F or a-f. - - for (int i = startIndex; i < pathLength; ++i) - { - //if (!(IsAlphaNumeric(uriString[i]) || uriString[i] == '+' || uriString[i] == '-' || uriString[i] == '.')) - // If character is upper ( in signed more than 127, then value is negative ). - char value = uriString[i]; - if (value < 32) - { - throw new ArgumentException("Invalid char: " + value); - } - - // If it is percent, then there should be 2 hex digits after. - if (value == '%') - { - if (pathLength - i < 3) - { - throw new ArgumentException("No data after %"); - } - - // There are at least 2 characters. Check their values - for (int j = 1; j < 3; j++) - { - char nextVal = uriString[i + j]; - if (!((nextVal >= '0' && nextVal <= '9') || - (nextVal >= 'A' && nextVal <= 'F') || - (nextVal >= 'a' && nextVal <= 'f') - ) - ) - { - throw new ArgumentException("Invalid char after %: " + value); - } - } - - // Moves i by 2 up to bypass verified characters. - i += 2; - } - } - } - - /// - /// Internal method parses a URI string into Uri variables - /// - /// A Uri. - /// - /// The is null. - /// - /// - /// See constructor description. - /// - protected void ParseUriString(string uriString) - { - int startIndex = 0; - int endIndex = 0; - - // Check for null or empty string. - if (uriString == null || uriString.Length == 0) - { - throw new ArgumentNullException(); - } - uriString = uriString.Trim(); - - // Check for presence of ':'. Colon always should be present in URI. - if (uriString.IndexOf(':') == -1) - { - throw new ArgumentException(); - } - - string uriStringLower = uriString.ToLower(); - - // If this is a urn parse and return - if (uriStringLower.IndexOf("urn:", startIndex) == 0) - { - ValidateUrn(uriString); - return; - } - - // If the uri is a relative path parse and return - if (uriString[0] == '/') - { - ValidateRelativePath(uriString); - return; - } - - // Validate Scheme - endIndex = uriString.IndexOf(':'); - m_scheme = uriString.Substring(0, endIndex); - if (!IsAlpha(m_scheme[0])) - { - throw new ArgumentException(); - } - - for (int i = 1; i < m_scheme.Length; ++i) - { - if (!(IsAlphaNumeric(m_scheme[i]) || m_scheme[i] == '+' || m_scheme[i] == '-' || m_scheme[i] == '.')) - { - throw new ArgumentException(); - } - } - - // Get past the colon - startIndex = endIndex + 1; - if (startIndex >= uriString.Length) - { - throw new ArgumentException(); - } - - // Get host, port and absolute path - bool bRooted = ParseSchemeSpecificPart(uriString, startIndex); - - if ((m_scheme == "file" || m_scheme == "mailto") && m_host.Length == 0) - { - m_hostNameType = UriHostNameType.Basic; - } - else if (m_host.Length == 0) - { - m_hostNameType = UriHostNameType.Unknown; - } - else if (m_host[0] == '[') - { - if (!IsIPv6(m_host)) - { - throw new ArgumentException(); - } - - m_hostNameType = UriHostNameType.IPv6; - } - else if (IsIPv4(m_host)) - { - m_hostNameType = UriHostNameType.IPv4; - } - else - { - m_hostNameType = UriHostNameType.Dns; - } - - if (m_host != null) - { - if (m_host == "localhost" || - m_host == "loopback" || - (m_scheme == "file" || m_scheme == "mailto") && m_host.Length == 0) - { - m_Flags |= m_Flags | (int)Flags.LoopbackHost; - } - } - - m_absoluteUri = m_scheme + ":" + - (bRooted ? "//" : string.Empty) + - m_host + - ((DefaultPort(m_scheme) == m_port) ? string.Empty : ":" + m_port.ToString()) + - (m_scheme == "file" && m_AbsolutePath.Length >= 2 && IsAlpha(m_AbsolutePath[0]) && m_AbsolutePath[1] == ':' ? "/" : string.Empty) + - m_AbsolutePath; - - m_isAbsoluteUri = true; - m_isUnc = m_scheme == "file" && m_host.Length > 0; - } - - /// - /// Parse Scheme-specific part of uri for host, port and absolute path - /// Briefed syntax abstracted from .NET FX: - /// Group 1 - http, https, ftp, file, gopher, nntp, telnet, ldap, net.tcp and net.pipe - /// Must be rooted. The 1st segment is authority. Empty path should be replace as '/' - /// - /// Group 2 - file - /// Reminder: Treat all '\' as '/' - /// If it starts with only one '/', host should be empty - /// Otherwise, all leading '/' should be ignored before searching for 1st segment. The 1st segment is host - /// - /// Group 3 - news and uuid - /// Authority always be empty. Everything goes to path. - /// - /// Group 4 - mailto and all other shemes - /// The 1st segment is authority iff it was not rooted. - /// - /// Group 5 - all other schemes - /// The 1st segment is authority iff it was rooted. Empty path should be replace as '/' - /// - /// Scheme-specific part of uri - /// - protected bool ParseSchemeSpecificPart(string sUri, int iStart) - { - bool bRooted = sUri.Length >= iStart + 2 && sUri.Substring(iStart, 2) == "//"; - bool bAbsoluteUriRooted; - - string sAuthority; - switch (m_scheme) - { - case "http": - case "https": - case "ftp": - case "gopher": - case "nntp": - case "telnet": - case "ldap": - case "net.tcp": - case "net.pipe": - if (!bRooted) - { - throw new ArgumentException(); - } - - bAbsoluteUriRooted = bRooted; - Split(sUri, iStart + 2, out sAuthority, out m_AbsolutePath, true); - break; - - case "file": - if (!bRooted) - { - throw new ArgumentException(); - } - - sUri = sUri.Substring(iStart + 2); - if (sUri.Length > 0) - { - var array = sUri.ToCharArray(); - for (int i = 0; i < array.Length; i++) - { - if (array[i] == '\\') - { - array[i] = '/'; - } - } - sUri = new string(array); - } - - string sTrimmed = sUri.TrimStart('/'); - - if (sTrimmed.Length >= 2 && IsAlpha(sTrimmed[0]) && sTrimmed[1] == ':') - { - //Windows style path - if (sTrimmed.Length < 3 || sTrimmed[2] != '/') - { - throw new ArgumentException(); - } - - sAuthority = string.Empty; - m_AbsolutePath = sTrimmed; - } - else - { - //Unix style path - if (sUri.Length - sTrimmed.Length == 1 || sTrimmed.Length == 0) - { - sAuthority = string.Empty; - m_AbsolutePath = sUri.Length > 0 ? sUri : "/"; - } - else - { - Split(sTrimmed, 0, out sAuthority, out m_AbsolutePath, true); - } - } - - bAbsoluteUriRooted = bRooted; - break; - - case "news": - case "uuid": - sAuthority = string.Empty; - m_AbsolutePath = sUri.Substring(iStart); - bAbsoluteUriRooted = false; - break; - - case "mailto": - if (bRooted) - { - sAuthority = string.Empty; - m_AbsolutePath = sUri.Substring(iStart); - } - else - { - Split(sUri, iStart, out sAuthority, out m_AbsolutePath, false); - } - bAbsoluteUriRooted = false; - break; - - default: - if (bRooted) - { - Split(sUri, iStart + 2, out sAuthority, out m_AbsolutePath, true); - } - else - { - sAuthority = string.Empty; - m_AbsolutePath = sUri.Substring(iStart); - } - bAbsoluteUriRooted = bRooted; - break; - } - - int iPortSplitter = sAuthority.LastIndexOf(':'); - if (iPortSplitter < 0 || sAuthority.LastIndexOf(']') > iPortSplitter) - { - m_host = sAuthority; - m_port = DefaultPort(m_scheme); - } - else - { - m_host = sAuthority.Substring(0, iPortSplitter); - m_port = Convert.ToInt32(sAuthority.Substring(iPortSplitter + 1)); - } - - return bAbsoluteUriRooted; - } - - protected void Split(string sUri, int iStart, out string sAuthority, out string sPath, bool bReplaceEmptyPath) - { - int iSplitter = sUri.IndexOf('/', iStart); - if (iSplitter < 0) - { - sAuthority = sUri.Substring(iStart); - sPath = string.Empty; - } - else - { - sAuthority = sUri.Substring(iStart, iSplitter - iStart); - sPath = sUri.Substring(iSplitter); - } - - if (bReplaceEmptyPath && sPath.Length == 0) - { - sPath = "/"; - } - } - - /// - /// Returns if host name is IP adress 4 bytes. Like 192.1.1.1 - /// - /// string with host name - /// True if name is string with IPv4 address - protected bool IsIPv4(String host) - { - int dots = 0; - int number = 0; - bool haveNumber = false; - int length = host.Length; - - for (int i = 0; i < length; i++) - { - char ch = host[i]; - - if (ch <= '9' && ch >= '0') - { - haveNumber = true; - number = number * 10 + (host[i] - '0'); - if (number > 255) - { - return false; - } - } - else if (ch == '.') - { - if (!haveNumber) - { - return false; - } - - ++dots; - haveNumber = false; - number = 0; - } - else - { - return false; - } - } - - return (dots == 3) && haveNumber; - } - - protected bool IsIPv6(string host) - { - return host[0] == '[' && host[host.Length - 1] == ']'; - } - - /// - /// Parses urn string into Uri variables. - /// Parsing is restricted to basic urn:NamespaceID, urn:uuid formats only. - /// - /// A Uri. - /// - /// The is null. - /// - /// - /// See the constructor description. - /// - protected void ValidateUrn(string uri) - { - bool invalidUrn = false; - - // If this is a urn:uuid validate the uuid - if (uri.ToLower().IndexOf("urn:uuid:", 0) == 0) - { - char[] tempUUID = uri.Substring(9).ToLower().ToCharArray(); - int length = tempUUID.Length; - int uuidSegmentCount = 0; - int[] delimiterIndexes = { 8, 13, 18, 23 }; - for (int i = 0; i < length; ++i) - { - // Make sure these are valid hex numbers numbers - if (!IsHex(tempUUID[i]) && tempUUID[i] != '-') - { - invalidUrn = true; - break; - } - else - { - // Check each segment length - if (tempUUID[i] == '-') - { - if (uuidSegmentCount > 3) - { - invalidUrn = true; - break; - } - - if (i != delimiterIndexes[uuidSegmentCount]) - { - invalidUrn = true; - break; - } - - ++uuidSegmentCount; - } - } - } - - m_AbsolutePath = uri.Substring(4); - } - - // Else validate against RFC2141 - else - { - string lowerUrn = uri.Substring(4).ToLower(); - char[] tempUrn = lowerUrn.ToCharArray(); - - // Validate the NamespaceID (NID) - int index = lowerUrn.IndexOf(':'); - if (index == -1) - throw new ArgumentException(); - int i = 0; - for (i = 0; i < index; ++i) - { - // Make sure these are valid hex numbers numbers - if (!IsAlphaNumeric(tempUrn[i]) && tempUrn[i] != '-') - { - invalidUrn = true; - break; - } - } - - // Validate the Namespace String - tempUrn = lowerUrn.Substring(index + 1).ToCharArray(); - int urnLength = tempUrn.Length; - if (!invalidUrn && urnLength != 0) - { - string otherChars = "()+,-.:=@;$_!*'"; - for (i = 0; i < urnLength; ++i) - { - if (!IsAlphaNumeric(tempUrn[i]) && !IsHex(tempUrn[i]) && tempUrn[i] != '%' && otherChars.IndexOf(tempUrn[i]) == -1) - { - invalidUrn = true; - break; - } - } - - m_AbsolutePath = uri.Substring(4); - } - } - - if (invalidUrn) - throw new ArgumentNullException(); - - // Set Uri properties - m_host = ""; - m_isAbsoluteUri = true; - m_isUnc = false; - m_hostNameType = UriHostNameType.Unknown; - m_port = UnknownPort; - m_scheme = "urn"; - m_absoluteUri = uri; - - return; - } - - /// - /// Parses relative Uri into variables. - /// - /// A Uri. - /// - /// The is null. - /// - /// - /// See constructor description. - /// - protected void ValidateRelativePath(string uri) - { - // Check for null - if (uri == null || uri.Length == 0) - throw new ArgumentNullException(); - // Check for "//" - if (uri[1] == '/') - throw new ArgumentException(); - - // Check for alphnumeric and special characters - for (int i = 1; i < uri.Length; ++i) - if (!IsAlphaNumeric(uri[i]) && ("()+,-.:=@;$_!*'").IndexOf(uri[i]) == -1) - throw new ArgumentException(); - - m_AbsolutePath = uri.Substring(1); - m_host = ""; - m_isAbsoluteUri = false; - m_isUnc = false; - m_hostNameType = UriHostNameType.Unknown; - m_port = UnknownPort; - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals(object o) - { - return this == (Uri)o; - } - - public static bool operator ==(Uri lhs, Uri rhs) - { - object l = lhs, r = rhs; - - if (l == null) - { - return (r == null); - } - else if (r == null) - { - return false; - } - else - { - if (lhs.m_isAbsoluteUri && rhs.m_isAbsoluteUri) - { - return lhs.m_AbsolutePath.ToLower() == rhs.m_AbsolutePath.ToLower(); - } - else - { - return lhs.m_OriginalUriString.ToLower() == rhs.m_OriginalUriString.ToLower(); - } - } - } - - public static bool operator !=(Uri lhs, Uri rhs) - { - object l = lhs, r = rhs; - - if (l == null) - { - return (r != null); - } - else if (r == null) - { - return true; - } - else - { - if (lhs.m_isAbsoluteUri && rhs.m_isAbsoluteUri) - { - return lhs.m_AbsolutePath.ToLower() != rhs.m_AbsolutePath.ToLower(); - } - else - { - return lhs.m_OriginalUriString.ToLower() != rhs.m_OriginalUriString.ToLower(); - } - } - } - - /// - /// Checks to see if the character value is an alpha character. - /// - /// The character to evaluate. - /// true if the character is Alpha; - /// otherwise, false. - protected bool IsAlpha(char testChar) - { - return (testChar >= 'A' && testChar <= 'Z') || (testChar >= 'a' && testChar <= 'z'); - } - - /// - /// Checks to see if the character value is an alpha or numeric. - /// - /// The character to evaluate. - /// true if the character is Alpha or - /// numeric; otherwise, false. - protected bool IsAlphaNumeric(char testChar) - { - return (testChar >= 'A' && testChar <= 'Z') || (testChar >= 'a' && testChar <= 'z') || (testChar >= '0' && testChar <= '9'); - } - - /// - /// Checks to see if the character value is Hex. - /// - /// The character to evaluate. - /// true if the character is a valid Hex - /// character; otherwise, false. - protected bool IsHex(char testChar) - { - return (testChar >= 'A' && testChar <= 'F') || (testChar >= 'a' && testChar <= 'f') || (testChar >= '0' && testChar <= '9'); - } - - /// - /// Gets the type of the host name specified in the URI. - /// - /// A member of the - /// enumeration. - public UriHostNameType HostNameType { get { return m_hostNameType; } } - - /// - /// Gets the port number of this URI. - /// - /// An Int32 value containing the port number - /// for this URI. - /// - /// This instance represents a relative URI, and this property is valid - /// only for absolute URIs. - /// - public int Port - { - get - { - if (m_isAbsoluteUri == false) - throw new InvalidOperationException(); - return m_port; - } - } - - /// - /// Gets whether the instance is absolute. - /// - /// true if the Uri - /// instance is absolute; otherwise, false. - public bool IsAbsoluteUri { get { return m_isAbsoluteUri; } } - - /// - /// Gets whether the specified is a universal - /// naming convention (UNC) path. - /// - /// true if the is a - /// UNC path; otherwise, false. - /// - /// This instance represents a relative URI, and this property is valid - /// only for absolute URIs. - /// - public bool IsUnc - { - get - { - if (m_isAbsoluteUri == false) - throw new InvalidOperationException(); - return m_isUnc; - } - } - - /// - /// Gets a local operating-system representation of a file name. - /// - /// A String containing the local - /// operating-system representation of a file name. - /// - /// This instance represents a relative URI, and this property is valid - /// only for absolute URIs. - /// - public string AbsolutePath - { - get - { - if (m_isAbsoluteUri == false) - throw new InvalidOperationException(); - return m_AbsolutePath; - } - } - - /// - /// Gets the original URI string that was passed to the Uri constructor. - /// - public string OriginalString - { - get - { - // The original string was saved in m_OriginalUriString. - return m_OriginalUriString; - } - } - - /// - /// Gets a string containing the absolute uri or entire uri of this instance. - /// - /// A String containing the entire URI. - /// - public string AbsoluteUri - { - get - { - if (m_isAbsoluteUri == false) - throw new InvalidOperationException(); - return m_absoluteUri; - } - } - - /// - /// Gets the scheme name for this URI. - /// - /// A String containing the scheme for this - /// URI, converted to lowercase. - /// - /// This instance represents a relative URI, and this property is valid only - /// for absolute URIs. - /// - public string Scheme - { - get - { - if (m_isAbsoluteUri == false) - throw new InvalidOperationException(); - return m_scheme; - } - } - - /// - /// Gets the host component of this instance. - /// - /// A String containing the host name. This - /// is usually the DNS host name or IP address of the server. - public string Host { get { return m_host; } } - - /// - /// Gets whether the specified refers to the - /// local host. - /// - /// true if the host specified in the Uri is - /// the local computer; otherwise, false. - public bool IsLoopback - { - get - { - return (m_Flags & (int)Flags.LoopbackHost) != 0; - } - } - - /// - /// Indicates whether the string is well-formed by attempting to - /// construct a URI with the string. - /// - /// A URI. - /// The type of the URI in - /// . - /// - /// true if the string was well-formed in accordance - /// with RFC 2396 and RFC 2732; otherwise false. - /// - public static bool IsWellFormedUriString(string uriString, UriKind uriKind) - { - try - { // If absolute Uri was passed - create Uri object. - switch (uriKind) - { - case UriKind.Absolute: - { - Uri testUri = new Uri(uriString); - - if (testUri.IsAbsoluteUri) - { - return true; - } - - return false; - } - - case UriKind.Relative: - { - Uri testUri = new Uri(uriString, UriKind.Relative); - if (!testUri.IsAbsoluteUri) - { - return true; - } - - return false; - } - default: return false; - } - } - catch - { - return false; - } - } - } -} diff --git a/source/nanoFramework.System.Net.Http/Properties/AssemblyInfo.cs b/source/nanoFramework.System.Net.Http/Properties/AssemblyInfo.cs deleted file mode 100644 index b592de42..00000000 --- a/source/nanoFramework.System.Net.Http/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("System.Net.Http")] -[assembly: AssemblyCompany("nanoFramework Contributors")] -[assembly: AssemblyProduct("System.Net.Http")] -[assembly: AssemblyCopyright("Copyright © nanoFramework Contributors 2018")] - - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] diff --git a/source/nanoFramework.System.Net.Http/System.Net.Http.nfproj b/source/nanoFramework.System.Net.Http/System.Net.Http.nfproj deleted file mode 100644 index ca92b444..00000000 --- a/source/nanoFramework.System.Net.Http/System.Net.Http.nfproj +++ /dev/null @@ -1,85 +0,0 @@ - - - - $(MSBuildToolsPath)..\..\..\nanoFramework\v1.0\ - - - - Debug - AnyCPU - {11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - c3aba656-9831-4006-a3b3-ea842a3c508e - Library - Properties - 512 - System.Net.Http - System.Net.Http - v1.0 - bin\$(Configuration)\System.Net.Http.xml - - - true - - - ..\key.snk - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ..\packages\nanoFramework.CoreLibrary.1.0.6-preview-001\lib\mscorlib.dll - True - - - ..\packages\nanoFramework.Runtime.Events.1.0.2-preview-004\lib\nanoFramework.Runtime.Events.dll - True - - - ..\packages\nanoFramework.System.Net.1.0.2-preview-004\lib\System.Net.dll - True - - - - - - - - - - diff --git a/source/nanoFramework.System.Net.Http/packages.config b/source/nanoFramework.System.Net.Http/packages.config deleted file mode 100644 index 99ee713d..00000000 --- a/source/nanoFramework.System.Net.Http/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/source/version.json b/source/version.json deleted file mode 100644 index aa621e0f..00000000 --- a/source/version.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.0.2-preview.{height}", - "assemblyVersion": { - "precision": "revision" - }, - "semVer1NumericIdentifierPadding": 3, - "nugetPackageVersion": { - "semVer": 1 - }, - "publicReleaseRefSpec": [ - "^refs/heads/master$", - "^refs/heads/v\\d+(?:\\.\\d+)?$" - ], - "cloudBuild": { - "setVersionVariables": true, - "setAllVariables": true, - "buildNumber": { - "enabled": true, - "includeCommitId": { - "when": "nonPublicReleaseOnly", - "where": "buildMetadata" - } - } - } -} \ No newline at end of file diff --git a/template.vssettings b/template.vssettings deleted file mode 100644 index 04850706..00000000 --- a/template.vssettings +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - 4 - false - 4 - true - - - 1 - 0 - 1 - 1 - 1 - 1 - 1 - 2 - 1 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 1 - 0 - 1 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 1 - 0 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 1 - 0 - 1 - 1 - 0 - 0 - 0 - 1 - 1 - 1 - 1 - - - -