├── src
└── CodeScales.Http
│ ├── CodeScales.Http.Tests
│ ├── resources
│ │ ├── small-text.txt
│ │ ├── logo.png
│ │ ├── ResourceManager.cs
│ │ └── big-text.txt
│ ├── NameValueColl.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Constants.cs
│ ├── CodeScales.Http.Tests.csproj
│ ├── MessageData.cs
│ ├── HttpRedirectTests.cs
│ ├── HttpGetTests.cs
│ └── HttpPostTests.cs
│ ├── CodeScales.Http.Tests.Server
│ ├── HttpGet200.aspx
│ ├── HttpGet302.aspx
│ ├── HttpPost200.aspx
│ ├── HttpRedirectTarget1.aspx
│ ├── HttpMultipartPost200.aspx
│ ├── HttpGet200WithSetCookies.aspx
│ ├── SendPostRequest.htm
│ ├── SendMultipartPostRequest.htm
│ ├── AspNetUpload.aspx
│ ├── HttpGet200.aspx.designer.cs
│ ├── HttpGet302.aspx.designer.cs
│ ├── HttpPost200.aspx.designer.cs
│ ├── HttpMultipartPost200.aspx.designer.cs
│ ├── HttpRedirectTarget1.aspx.designer.cs
│ ├── HttpGet200WithSetCookies.aspx.designer.cs
│ ├── AspNetUpload.aspx.cs
│ ├── HttpGet302.aspx.cs
│ ├── Web.config
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── AspNetUpload.aspx.designer.cs
│ ├── HttpRedirectTarget1.aspx.cs
│ ├── HttpPost200.aspx.cs
│ ├── HttpGet200WithSetCookies.aspx.cs
│ ├── HttpGet200.aspx.cs
│ ├── HttpMultipartPost200.aspx.cs
│ └── CodeScales.Http.Tests.Server.csproj
│ ├── CodeScales.Http.Examples
│ ├── Program.cs
│ ├── HttpPostExamples.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── CodeScales.Http.Examples.csproj
│ └── HttpGetExample.cs
│ ├── CodeScales.Http
│ ├── Entity
│ │ ├── BasicHttpEntity.cs
│ │ ├── HttpEntityEnclosingRequest.cs
│ │ ├── HttpEntity.cs
│ │ ├── Mime
│ │ │ ├── Body.cs
│ │ │ ├── InputStreamBody.cs
│ │ │ ├── StringBody.cs
│ │ │ └── FileBody.cs
│ │ ├── AbstractHttpEntity.cs
│ │ ├── EntityUtils.cs
│ │ ├── UrlEncodedFormEntity.cs
│ │ └── MultipartEntity.cs
│ ├── Network
│ │ ├── HttpNetworkException.cs
│ │ ├── HttpConnectionFactory.cs
│ │ ├── HttpProtocol.cs
│ │ └── HttpConnection.cs
│ ├── Methods
│ │ ├── HttpRequest.cs
│ │ ├── HttpMessageBase.cs
│ │ ├── HttpResponse.cs
│ │ ├── HttpGet.cs
│ │ └── HttpPost.cs
│ ├── Common
│ │ └── NameValuePair.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Cookies
│ │ ├── HttpCookie.cs
│ │ ├── HttpCookieCollection.cs
│ │ └── HttpCookieStore.cs
│ ├── Protocol
│ │ └── HTTP.cs
│ ├── CodeScales.Http.csproj
│ ├── HttpBehavior.cs
│ └── HttpClient.cs
│ └── CodeScales.Http.sln
└── README.md
/src/CodeScales.Http/CodeScales.Http.Tests/resources/small-text.txt:
--------------------------------------------------------------------------------
1 | this is a test
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests/resources/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yaroncon/c-sharp-http-client/HEAD/src/CodeScales.Http/CodeScales.Http.Tests/resources/logo.png
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpGet200.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HttpGet200.aspx.cs" Inherits="CodeScales.Http.Tests.Server.HttpGet200" %>
2 |
3 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpGet302.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HttpGet302.aspx.cs" Inherits="CodeScales.Http.Tests.Server.HttpGet302" %>
2 |
3 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpPost200.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HttpPost200.aspx.cs" Inherits="CodeScales.Http.Tests.Server.HttpPost200" %>
2 |
3 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpRedirectTarget1.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HttpRedirectTarget1.aspx.cs" Inherits="CodeScales.Http.Tests.Server.HttpRedirectTarget1" %>
2 |
3 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpMultipartPost200.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HttpMultipartPost200.aspx.cs" Inherits="CodeScales.Http.Tests.Server.HttpMultipartPost200" %>
2 |
3 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpGet200WithSetCookies.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HttpGet200WithSetCookies.aspx.cs" Inherits="CodeScales.Http.Tests.Server.HttpGet200WithSetCookies" %>
2 |
3 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Examples/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace CodeScales.Http.Examples
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 | HttpPostExamples.DoPost();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/SendPostRequest.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Untitled Page
5 |
6 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/SendMultipartPostRequest.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Untitled Page
5 |
6 |
7 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/AspNetUpload.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AspNetUpload.aspx.cs" Inherits="CodeScales.Http.Tests.Server.AspNetUpload" %>
2 |
3 |
4 |
5 |
6 |
7 | Untitled Page
8 |
9 |
10 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpGet200.aspx.designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:2.0.50727.1873
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace CodeScales.Http.Tests.Server {
12 |
13 |
14 | ///
15 | /// HttpGet200 class.
16 | ///
17 | ///
18 | /// Auto-generated class.
19 | ///
20 | public partial class HttpGet200 {
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpGet302.aspx.designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:2.0.50727.1873
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace CodeScales.Http.Tests.Server {
12 |
13 |
14 | ///
15 | /// HttpGet302 class.
16 | ///
17 | ///
18 | /// Auto-generated class.
19 | ///
20 | public partial class HttpGet302 {
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpPost200.aspx.designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:2.0.50727.3603
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace CodeScales.Http.Tests.Server {
12 |
13 |
14 | ///
15 | /// HttpPost200 class.
16 | ///
17 | ///
18 | /// Auto-generated class.
19 | ///
20 | public partial class HttpPost200 {
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpMultipartPost200.aspx.designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:2.0.50727.4927
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace CodeScales.Http.Tests.Server {
12 |
13 |
14 | ///
15 | /// HttpMultipartPost200 class.
16 | ///
17 | ///
18 | /// Auto-generated class.
19 | ///
20 | public partial class HttpMultipartPost200 {
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpRedirectTarget1.aspx.designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:2.0.50727.1873
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace CodeScales.Http.Tests.Server {
12 |
13 |
14 | ///
15 | /// HttpRedirectTarget1 class.
16 | ///
17 | ///
18 | /// Auto-generated class.
19 | ///
20 | public partial class HttpRedirectTarget1 {
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpGet200WithSetCookies.aspx.designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:2.0.50727.3603
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace CodeScales.Http.Tests.Server {
12 |
13 |
14 | ///
15 | /// HttpGet200WithSetCookies class.
16 | ///
17 | ///
18 | /// Auto-generated class.
19 | ///
20 | public partial class HttpGet200WithSetCookies {
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Entity/BasicHttpEntity.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | namespace CodeScales.Http.Entity
21 | {
22 | public class BasicHttpEntity : AbstractHttpEntity
23 | {
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests/NameValueColl.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | using CodeScales.Http.Common;
21 |
22 | namespace CodeScales.Http.Tests
23 | {
24 | [Serializable]
25 | public class NameValueColl : List
26 | {
27 |
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Entity/HttpEntityEnclosingRequest.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | namespace CodeScales.Http.Entity
21 | {
22 | public interface HttpEntityEnclosingRequest
23 | {
24 | HttpEntity Entity { get; set;}
25 | bool ExpectContinue { get; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Entity/HttpEntity.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 |
18 | namespace CodeScales.Http.Entity
19 | {
20 | public interface HttpEntity
21 | {
22 | byte[] Content { get; set; }
23 | string ContentEncoding { get; set; }
24 | long ContentLength { get; set; }
25 | string ContentType { get; set; }
26 | bool IsChunked { get; set; }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Examples/HttpPostExamples.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | using CodeScales.Http;
6 | using CodeScales.Http.Methods;
7 | using CodeScales.Http.Entity;
8 | using CodeScales.Http.Common;
9 |
10 | namespace CodeScales.Http.Examples
11 | {
12 | public class HttpPostExamples
13 | {
14 | public static void DoPost()
15 | {
16 | HttpClient client = new HttpClient();
17 | HttpPost postMethod = new HttpPost(new Uri("http://www.w3schools.com/asp/demo_simpleform.asp"));
18 |
19 | List nameValuePairList = new List();
20 | nameValuePairList.Add(new NameValuePair("fname", "brian"));
21 |
22 | UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, Encoding.UTF8);
23 | postMethod.Entity = formEntity;
24 |
25 | HttpResponse response = client.Execute(postMethod);
26 |
27 | Console.WriteLine("Response Code: " + response.ResponseCode);
28 | Console.WriteLine("Response Content: " + EntityUtils.ToString(response.Entity));
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Network/HttpNetworkException.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | namespace CodeScales.Http.Network
21 | {
22 | public class HttpNetworkException : Exception
23 | {
24 |
25 | public HttpNetworkException(string message)
26 | : base(message)
27 | {
28 |
29 | }
30 |
31 | public HttpNetworkException(string message, Exception innerException) : base(message, innerException)
32 | {
33 |
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Entity/Mime/Body.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | /*
17 | * ====================================================================
18 | *
19 | * This class is inspired by org.apache.http.entity.mime.content.AbstractContentBody
20 | *
21 | * ====================================================================
22 | *
23 | */
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Text;
28 |
29 | namespace CodeScales.Http.Entity.Mime
30 | {
31 | public interface Body
32 | {
33 | byte[] GetContent(string boundry);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Methods/HttpRequest.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.Net;
20 |
21 | namespace CodeScales.Http.Methods
22 | {
23 | public abstract class HttpRequest : HttpMessageBase
24 | {
25 | private Uri m_uri = null;
26 |
27 | public abstract string Method { get; }
28 | public abstract string GetRequestLine(bool useProxy);
29 |
30 | public Uri Uri
31 | {
32 | get { return m_uri; }
33 | set { m_uri = value; }
34 | }
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/AspNetUpload.aspx.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Data;
18 | using System.Configuration;
19 | using System.Collections;
20 | using System.Web;
21 | using System.Web.Security;
22 | using System.Web.UI;
23 | using System.Web.UI.WebControls;
24 | using System.Web.UI.WebControls.WebParts;
25 | using System.Web.UI.HtmlControls;
26 |
27 | namespace CodeScales.Http.Tests.Server
28 | {
29 | public partial class AspNetUpload : System.Web.UI.Page
30 | {
31 | protected void Page_Load(object sender, EventArgs e)
32 | {
33 |
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Entity/Mime/InputStreamBody.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | /*
17 | * ====================================================================
18 | *
19 | * This class is inspired by org.apache.http.entity.mime.content.InputStreamBody
20 | *
21 | * ====================================================================
22 | *
23 | */
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Text;
28 |
29 | namespace CodeScales.Http.Entity.Mime
30 | {
31 | public class InputStreamBody : Body
32 | {
33 | public byte[] GetContent(string boundry)
34 | {
35 | return null;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpGet302.aspx.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Data;
18 | using System.Configuration;
19 | using System.Collections;
20 | using System.Collections.Specialized;
21 | using System.Web;
22 | using System.Web.Security;
23 | using System.Web.UI;
24 | using System.Web.UI.WebControls;
25 | using System.Web.UI.WebControls.WebParts;
26 | using System.Web.UI.HtmlControls;
27 |
28 | namespace CodeScales.Http.Tests.Server
29 | {
30 | public partial class HttpGet302 : System.Web.UI.Page
31 | {
32 | protected void Page_Load(object sender, EventArgs e)
33 | {
34 | Response.Redirect("HttpRedirectTarget1.aspx");
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Examples/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CodeScales.Http.Examples")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("CodeScales.Http.Examples")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("78e8ebd8-eefb-4d09-9875-fadd73c59f55")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | [assembly: AssemblyVersion("1.0.0.0")]
33 | [assembly: AssemblyFileVersion("1.0.0.0")]
34 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
16 |
21 |
22 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Common/NameValuePair.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | namespace CodeScales.Http.Common
21 | {
22 | [Serializable]
23 | public class NameValuePair
24 | {
25 | private string m_name;
26 | private string m_value;
27 |
28 | public NameValuePair()
29 | {
30 | }
31 |
32 | public NameValuePair(string name, string value)
33 | {
34 | this.m_name = name;
35 | this.m_value = value;
36 | }
37 |
38 | public string Name
39 | {
40 | get { return m_name; }
41 | set { m_name = value; }
42 | }
43 |
44 | public string Value
45 | {
46 | get { return this.m_value; }
47 | set { this.m_value = value; }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CodeScales.Http")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("CodeScales.com")]
12 | [assembly: AssemblyProduct("CodeScales.Http")]
13 | [assembly: AssemblyCopyright("Copyright © CodeScales.com 2010")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("7a0a7b45-63ff-4937-9ccf-ba4bdf340054")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # c-sharp-http-client
2 | Automatically exported from code.google.com/p/c-sharp-http-client
3 |
4 | CSharp HttpClient by CodeScales.com
5 |
6 | An HTTP client library with a very simple API, written in CSharp (.Net 2.0) for sending HTTP requests and receiving HTTP responses.
7 | This library is much simpler to use than the HttpWebRequest provided with the .Net library.
8 | This library was inspired by the JAVA HttpClient library, and has a very similar API.
9 | See codescales.com for more details
10 | You are encouraged to visit the project's web site at http://www.codescales.com for code examples and documentation.
11 |
12 | What can you do with it?
13 |
14 | Send GET requests.
15 | Send POST requests with parameters, using Url-Encoded Entity.
16 | upload Files to an HTTP server, using a Multipart Entity.
17 | Send Post request with parameters, using Multipart Entity (which is actually the same as #3).
18 | Control the redirect behavior of the client, using HttpBehavior.
19 | Use as many parallel connections (sockets) as you need, using the default HttpConnectionFactory.
20 | Use a proxy server that does not need a password.
21 | Current Status
22 |
23 | This is a preliminary version. Some basic functionality is missing. See the limitations section for details. It is still work in progress, and you are welcome to write me if you want to help at yaron@codescales.com.
24 |
25 | Limitations
26 |
27 | This is a list of things that are NOT supported yet:
28 |
29 | Transfer-Encoding: gzip
30 | Requests with keep-alive header.
31 | Expiration of cookies.
32 | Using proxies that need password.
33 | HTTPS and SSL.
34 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CodeScales.Http.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("CodeScales.com")]
12 | [assembly: AssemblyProduct("CodeScales.Http.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © CodeScales.com 2010")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("5c6afe3c-2ca9-4dac-bd8d-09c51bd78883")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CodeScales.Http.Tests.Server")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("CodeScales.com")]
12 | [assembly: AssemblyProduct("CodeScales.Http.Tests.Server")]
13 | [assembly: AssemblyCopyright("Copyright © CodeScales.com 2010")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("3d5900ae-111a-45be-96b3-d9e4606ca793")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Methods/HttpMessageBase.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.Net;
20 |
21 | namespace CodeScales.Http.Methods
22 | {
23 | public abstract class HttpMessageBase
24 | {
25 | private WebHeaderCollection m_headers = new WebHeaderCollection();
26 | private Dictionary m_parameters = new Dictionary();
27 |
28 | public virtual WebHeaderCollection Headers
29 | {
30 | get
31 | {
32 | return m_headers;
33 | }
34 | set
35 | {
36 | this.m_headers = value;
37 | }
38 | }
39 |
40 | public Dictionary Parameters
41 | {
42 | get
43 | {
44 | return m_parameters;
45 | }
46 | set
47 | {
48 | this.m_parameters = value;
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests/Constants.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | namespace CodeScales.Http.Tests
21 | {
22 | public class Constants
23 | {
24 | public const string HTTP_GET_200 = "http://localhost/CodeScales/HttpGet200.aspx";
25 | public const string HTTP_GET_200_CODESCALES_COM = "http://www.codescales.com/";
26 | public const string HTTP_GET_200_WITH_SET_COOKIES = "http://localhost/CodeScales/HttpGet200WithSetCookies.aspx";
27 | public const string HTTP_GET_302 = "http://localhost/CodeScales/HttpGet302.aspx";
28 | public const string HTTP_POST_200 = "http://localhost/CodeScales/HttpPost200.aspx";
29 | public const string HTTP_POST_W3SCHOOLS = "http://www.w3schools.com/asp/demo_simpleform.asp";
30 | public const string HTTP_MULTIPART_POST_200 = "http://localhost/CodeScales/HttpMultipartPost200.aspx";
31 | public const string HTTP_REDIRECT_TARGET_1 = "http://localhost/CodeScales/HttpRedirectTarget1.aspx";
32 | public const string FIDDLER_DEFAULT_ADDRESS = "http://localhost:8888/";
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Entity/Mime/StringBody.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | /*
17 | * ====================================================================
18 | *
19 | * This class is inspired by org.apache.http.entity.mime.content.StringBody
20 | *
21 | * ====================================================================
22 | *
23 | */
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Text;
28 |
29 | using CodeScales.Http.Network;
30 |
31 | namespace CodeScales.Http.Entity.Mime
32 | {
33 | public class StringBody : Body
34 | {
35 | private Encoding m_encoding;
36 | private string m_name;
37 | private string m_value;
38 |
39 | public StringBody(Encoding encoding, string name, string value)
40 | {
41 | this.m_encoding = encoding;
42 | this.m_name = name;
43 | this.m_value = value;
44 | }
45 |
46 | public byte[] GetContent(string boundry)
47 | {
48 | return this.m_encoding.GetBytes(HTTPProtocol.GetPostParameter(this.m_name, this.m_value, boundry));
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Cookies/HttpCookie.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | namespace CodeScales.Http.Cookies
21 | {
22 | public class HttpCookie
23 | {
24 | private string m_name;
25 | private string m_value;
26 | private string m_path;
27 | private DateTime m_expiration;
28 |
29 | public HttpCookie(string name, string value)
30 | {
31 | this.m_name = name;
32 | this.m_value = value;
33 | }
34 |
35 | public string Name
36 | {
37 | get { return m_name; }
38 | set { m_name = value; }
39 | }
40 |
41 | public string Value
42 | {
43 | get { return m_value; }
44 | set { m_value = value; }
45 | }
46 |
47 | public string Path
48 | {
49 | get { return m_path; }
50 | set { m_path = value; }
51 | }
52 |
53 | public DateTime Expiration
54 | {
55 | get { return m_expiration; }
56 | set { m_expiration = value; }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/AspNetUpload.aspx.designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:2.0.50727.4927
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace CodeScales.Http.Tests.Server {
12 |
13 |
14 | ///
15 | /// AspNetUpload class.
16 | ///
17 | ///
18 | /// Auto-generated class.
19 | ///
20 | public partial class AspNetUpload {
21 |
22 | ///
23 | /// form1 control.
24 | ///
25 | ///
26 | /// Auto-generated field.
27 | /// To modify move field declaration from designer file to code-behind file.
28 | ///
29 | protected global::System.Web.UI.HtmlControls.HtmlForm form1;
30 |
31 | ///
32 | /// FileUpload1 control.
33 | ///
34 | ///
35 | /// Auto-generated field.
36 | /// To modify move field declaration from designer file to code-behind file.
37 | ///
38 | protected global::System.Web.UI.WebControls.FileUpload FileUpload1;
39 |
40 | ///
41 | /// Submit1 control.
42 | ///
43 | ///
44 | /// Auto-generated field.
45 | /// To modify move field declaration from designer file to code-behind file.
46 | ///
47 | protected global::System.Web.UI.WebControls.Button Submit1;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests/resources/ResourceManager.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.IO;
20 | using System.Reflection;
21 |
22 | namespace CodeScales.Http.Tests.resources
23 | {
24 | public class ResourceManager
25 | {
26 | private const string RESOURCE_FOLDER = "resources";
27 |
28 | public static FileInfo GetResourceFileInfo(string fileName)
29 | {
30 | string filePath = Assembly.GetAssembly(typeof(ResourceManager)).Location;
31 | filePath = filePath.Substring(0, filePath.LastIndexOf('\\')) + "\\";
32 | byte[] fileBytes = GetResourceBinary(fileName);
33 | File.WriteAllBytes(filePath + fileName, fileBytes);
34 | return new FileInfo(filePath + fileName);
35 | }
36 |
37 | public static byte[] GetResourceBinary(string fileName)
38 | {
39 | Stream stream = Assembly.GetAssembly(typeof(ResourceManager)).GetManifestResourceStream("CodeScales.Http.Tests.resources." + fileName);
40 | BinaryReader reader = new BinaryReader(stream);
41 | return reader.ReadBytes((int)reader.BaseStream.Length);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Network/HttpConnectionFactory.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | namespace CodeScales.Http.Network
21 | {
22 | internal class HttpConnectionFactory
23 | {
24 | public HttpConnection GetConnnection(Uri uri, Uri proxy)
25 | {
26 | return GetConnectionPrivate(uri, proxy);
27 | }
28 |
29 | // make sure the connection is still open and from the same host
30 | public HttpConnection GetConnnection(Uri uri, Uri proxy, HttpConnection liveConnection)
31 | {
32 | if (liveConnection != null
33 | && liveConnection.IsConnected()
34 | && liveConnection.Uri.Host.ToLower() == uri.Host.ToLower())
35 | {
36 | return liveConnection;
37 | }
38 | else
39 | {
40 | liveConnection.Close();
41 | return GetConnectionPrivate(uri, proxy);
42 | }
43 | }
44 |
45 | private HttpConnection GetConnectionPrivate(Uri uri, Uri proxy)
46 | {
47 | HttpConnection conn = new HttpConnection(this, uri, proxy);
48 | conn.SetBusy(true);
49 | conn.Connect();
50 | return conn;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Cookies/HttpCookieCollection.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | namespace CodeScales.Http.Cookies
21 | {
22 | public class HttpCookieCollection
23 | {
24 |
25 | private Dictionary m_cookies = new Dictionary();
26 |
27 | public Dictionary.KeyCollection Keys
28 | {
29 | get
30 | {
31 | return this.m_cookies.Keys;
32 | }
33 | }
34 |
35 | public int Count
36 | {
37 | get
38 | {
39 | return this.m_cookies.Count;
40 | }
41 | }
42 |
43 | public HttpCookie GetCookie(string key)
44 | {
45 | return this.m_cookies[key];
46 | }
47 |
48 | public void Add(string key, HttpCookie cookie)
49 | {
50 | if (cookie.Value != null && cookie.Value != string.Empty)
51 | {
52 | if (this.m_cookies.ContainsKey(key))
53 | {
54 | this.m_cookies[key].Value = cookie.Value;
55 | }
56 | else
57 | this.m_cookies.Add(key, cookie);
58 |
59 |
60 | }
61 | }
62 |
63 |
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Protocol/HTTP.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | namespace CodeScales.Http.Protocol
21 | {
22 | public class HTTP
23 | {
24 | /** HTTP header definitions */
25 | public const string TRANSFER_ENCODING = "Transfer-Encoding";
26 | public const string CONTENT_LEN = "Content-Length";
27 | public const string CONTENT_TYPE = "Content-Type";
28 | public const string CONTENT_ENCODING = "Content-Encoding";
29 | public const string EXPECT_DIRECTIVE = "Expect";
30 | public const string CONN_DIRECTIVE = "Connection";
31 | public const string PROXY_CONN_DIRECTIVE = "Proxy-Connection";
32 | public const string TARGET_HOST = "Host";
33 | public const string USER_AGENT = "User-Agent";
34 | public const string DATE_HEADER = "Date";
35 | public const string SERVER_HEADER = "Server";
36 |
37 | /** HTTP expectations */
38 | public const string EXPECT_CONTINUE = "100-Continue";
39 |
40 | /** HTTP connection control */
41 | public const string CONN_CLOSE = "Close";
42 | public const string CONN_KEEP_ALIVE = "Keep-Alive";
43 |
44 | /** Transfer encoding definitions */
45 | public const string CHUNK_CODING = "chunked";
46 | public const string IDENTITY_CODING = "identity";
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpRedirectTarget1.aspx.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Data;
18 | using System.Configuration;
19 | using System.Collections;
20 | using System.Web;
21 | using System.Web.Security;
22 | using System.Web.UI;
23 | using System.Web.UI.WebControls;
24 | using System.Web.UI.WebControls.WebParts;
25 | using System.Web.UI.HtmlControls;
26 |
27 | using CodeScales.Http.Common;
28 |
29 | namespace CodeScales.Http.Tests.Server
30 | {
31 | public partial class HttpRedirectTarget1 : System.Web.UI.Page
32 | {
33 | protected void Page_Load(object sender, EventArgs e)
34 | {
35 | MessageData msgData = new MessageData();
36 | if (Request.QueryString != null
37 | && Request.QueryString.Count > 0)
38 | {
39 | foreach (string s in Request.QueryString.AllKeys)
40 | {
41 | msgData.QueryParameters.Add(new NameValuePair(s, Request.QueryString[s]));
42 | }
43 | }
44 |
45 | if (Request.Cookies != null
46 | && Request.Cookies.Count > 0)
47 | {
48 | foreach (string s in Request.Cookies.AllKeys)
49 | {
50 | msgData.Cookies.Add(new NameValuePair(s, Request.Cookies[s].Value));
51 | }
52 | }
53 | Response.Write(msgData.ToString());
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpPost200.aspx.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Data;
18 | using System.Configuration;
19 | using System.Collections;
20 | using System.Collections.Specialized;
21 | using System.Web;
22 | using System.Web.Security;
23 | using System.Web.UI;
24 | using System.Web.UI.WebControls;
25 | using System.Web.UI.WebControls.WebParts;
26 | using System.Web.UI.HtmlControls;
27 |
28 | using CodeScales.Http.Common;
29 |
30 | namespace CodeScales.Http.Tests.Server
31 | {
32 | public partial class HttpPost200 : System.Web.UI.Page
33 | {
34 | protected void Page_Load(object sender, EventArgs e)
35 | {
36 | MessageData msgData = new MessageData();
37 | if (Request.Form != null
38 | && Request.Form.Count > 0)
39 | {
40 | foreach (string s in Request.Form.AllKeys)
41 | {
42 | msgData.PostParameters.Add(new NameValuePair(s, Request.Form[s]));
43 | }
44 | }
45 |
46 | if (Request.Cookies != null
47 | && Request.Cookies.Count > 0)
48 | {
49 | foreach (string s in Request.Cookies.AllKeys)
50 | {
51 | msgData.Cookies.Add(new NameValuePair(s, Request.Cookies[s].Value));
52 | }
53 | }
54 | Response.Write(msgData.ToString());
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpGet200WithSetCookies.aspx.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Data;
18 | using System.Configuration;
19 | using System.Collections;
20 | using System.Collections.Specialized;
21 | using System.Web;
22 | using System.Web.Security;
23 | using System.Web.UI;
24 | using System.Web.UI.WebControls;
25 | using System.Web.UI.WebControls.WebParts;
26 | using System.Web.UI.HtmlControls;
27 |
28 | using CodeScales.Http.Common;
29 |
30 | namespace CodeScales.Http.Tests.Server
31 | {
32 | public partial class HttpGet200WithSetCookies : System.Web.UI.Page
33 | {
34 | protected void Page_Load(object sender, EventArgs e)
35 | {
36 | MessageData msgData = new MessageData();
37 | if (Request.QueryString != null
38 | && Request.QueryString.Count > 0)
39 | {
40 | foreach (string s in Request.QueryString.AllKeys)
41 | {
42 | msgData.QueryParameters.Add(new NameValuePair(s, Request.QueryString[s]));
43 | }
44 | }
45 | if (Request.QueryString != null
46 | && Request.QueryString.Count > 0)
47 | {
48 | foreach (string s in Request.QueryString.AllKeys)
49 | {
50 | Response.Cookies.Add(new HttpCookie(s, Request.QueryString[s]));
51 | }
52 | }
53 | Response.Write(msgData.ToString());
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpGet200.aspx.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Data;
18 | using System.Configuration;
19 | using System.Collections;
20 | using System.Collections.Specialized;
21 | using System.Web;
22 | using System.Web.Security;
23 | using System.Web.UI;
24 | using System.Web.UI.WebControls;
25 | using System.Web.UI.WebControls.WebParts;
26 | using System.Web.UI.HtmlControls;
27 |
28 |
29 | using CodeScales.Http.Common;
30 |
31 | namespace CodeScales.Http.Tests.Server
32 | {
33 | public partial class HttpGet200 : System.Web.UI.Page
34 | {
35 | protected void Page_Load(object sender, EventArgs e)
36 | {
37 | MessageData msgData = new MessageData();
38 | if (Request.QueryString != null
39 | && Request.QueryString.Count > 0)
40 | {
41 | foreach (string s in Request.QueryString.AllKeys)
42 | {
43 | msgData.QueryParameters.Add(new NameValuePair(s, Request.QueryString[s]));
44 | }
45 | }
46 |
47 | if (Request.Cookies != null
48 | && Request.Cookies.Count > 0)
49 | {
50 | foreach (string s in Request.Cookies.AllKeys)
51 | {
52 | msgData.Cookies.Add(new NameValuePair(s, Request.Cookies[s].Value));
53 | }
54 | }
55 | Response.Write(msgData.ToString());
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Methods/HttpResponse.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.Net;
20 |
21 | using CodeScales.Http.Network;
22 | using CodeScales.Http.Entity;
23 |
24 | namespace CodeScales.Http.Methods
25 | {
26 | public class HttpResponse : HttpMessageBase
27 | {
28 | private int m_responseCode = 0;
29 | private Uri m_requestUri = null;
30 | private HttpEntity m_entity = null;
31 |
32 | public HttpResponse()
33 | {
34 |
35 | }
36 |
37 | public int ResponseCode
38 | {
39 | get { return m_responseCode; }
40 | set { m_responseCode = value; }
41 | }
42 |
43 | public Uri RequestUri
44 | {
45 | get { return m_requestUri; }
46 | set { m_requestUri = value; }
47 | }
48 |
49 | public HttpEntity Entity
50 | {
51 | get { return m_entity; }
52 | set { m_entity = value; }
53 | }
54 |
55 | public string Location
56 | {
57 | get
58 | {
59 | if (this.Headers != null &&
60 | this.Headers["Location"] != null)
61 | {
62 | try { return new Uri(this.Headers["Location"]).AbsoluteUri; }
63 | catch { return new Uri(this.m_requestUri, this.Headers["Location"]).AbsoluteUri; }
64 | }
65 | else
66 | return string.Empty;
67 | }
68 | }
69 |
70 |
71 |
72 |
73 | }
74 | }
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Examples/CodeScales.Http.Examples.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Debug
4 | AnyCPU
5 | 8.0.50727
6 | 2.0
7 | {7479716F-061C-4751-8895-B405E8B6B4EE}
8 | Exe
9 | Properties
10 | CodeScales.Http.Examples
11 | CodeScales.Http.Examples
12 |
13 |
14 | true
15 | full
16 | false
17 | bin\Debug\
18 | DEBUG;TRACE
19 | prompt
20 | 4
21 |
22 |
23 | pdbonly
24 | true
25 | bin\Release\
26 | TRACE
27 | prompt
28 | 4
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | {FC262E96-6275-4798-8181-D9001FB50541}
44 | CodeScales.Http
45 |
46 |
47 |
48 |
55 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/HttpMultipartPost200.aspx.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Data;
18 | using System.Configuration;
19 | using System.Collections;
20 | using System.Collections.Specialized;
21 | using System.Web;
22 | using System.Web.Security;
23 | using System.Web.UI;
24 | using System.Web.UI.WebControls;
25 | using System.Web.UI.WebControls.WebParts;
26 | using System.Web.UI.HtmlControls;
27 |
28 | using CodeScales.Http.Common;
29 |
30 | namespace CodeScales.Http.Tests.Server
31 | {
32 | public partial class HttpMultipartPost200 : System.Web.UI.Page
33 | {
34 | protected void Page_Load(object sender, EventArgs e)
35 | {
36 | MessageData msgData = new MessageData();
37 | if (Request.Form != null
38 | && Request.Form.Count > 0)
39 | {
40 | foreach (string s in Request.Form.AllKeys)
41 | {
42 | msgData.PostParameters.Add(new NameValuePair(s, Request.Form[s]));
43 | }
44 | }
45 |
46 | if (Request.Cookies != null
47 | && Request.Cookies.Count > 0)
48 | {
49 | foreach (string s in Request.Cookies.AllKeys)
50 | {
51 | msgData.Cookies.Add(new NameValuePair(s, Request.Cookies[s].Value));
52 | }
53 | }
54 |
55 | if (Request.Files != null
56 | && Request.Files.Count > 0)
57 | {
58 | foreach (string key in Request.Files.AllKeys)
59 | {
60 | msgData.Files.Add(new NameValuePair(Request.Files[key].FileName, Request.Files[key].ContentLength.ToString()));
61 | }
62 | }
63 | Response.Write(msgData.ToString());
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Entity/AbstractHttpEntity.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | /*
17 | * ====================================================================
18 | *
19 | * This class is inspired by org.apache.http.entity.AbstractHttpEntity
20 | *
21 | * ====================================================================
22 | *
23 | */
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Text;
28 |
29 | namespace CodeScales.Http.Entity
30 | {
31 | public abstract class AbstractHttpEntity : HttpEntity
32 | {
33 | // void WriteTo(OutputStream);
34 | private byte[] m_content;
35 | private string m_contentEncoding;
36 | private long m_contentLength = -1;
37 | private string m_contentType;
38 | private bool m_isChunked;
39 |
40 | // Replaces the getContent and writeTo methods in java
41 | public byte[] Content
42 | {
43 | get { return m_content; }
44 | set { m_content = value; }
45 | }
46 |
47 | // this is not the .net Encoding relevant header
48 | public string ContentEncoding
49 | {
50 | get { return m_contentEncoding; }
51 | set { m_contentEncoding = value; }
52 | }
53 |
54 | public long ContentLength
55 | {
56 | get { return m_contentLength; }
57 | set { m_contentLength = value; }
58 | }
59 |
60 | // this is the .net Encoding relevant header
61 | public string ContentType
62 | {
63 | get { return m_contentType; }
64 | set { m_contentType = value; }
65 | }
66 |
67 | // for future reference. this method is not used.
68 | public bool IsChunked
69 | {
70 | get { return m_isChunked; }
71 | set { m_isChunked = value; }
72 | }
73 |
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Entity/EntityUtils.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.Net;
20 |
21 | using CodeScales.Http.Network;
22 | using CodeScales.Http.Protocol;
23 |
24 | namespace CodeScales.Http.Entity
25 | {
26 | public class EntityUtils
27 | {
28 | public static string ToString(HttpEntity entity)
29 | {
30 | if (entity != null
31 | && entity.Content != null)
32 | {
33 | return HTTPProtocol.GetEncoding(entity.ContentType).GetString(entity.Content);
34 | }
35 | else
36 | return string.Empty;
37 | }
38 |
39 | public static string GetContentType(WebHeaderCollection headers)
40 | {
41 |
42 | if (headers != null &&
43 | headers[HTTP.CONTENT_TYPE] != null)
44 | return headers[HTTP.CONTENT_TYPE];
45 | else
46 | return null;
47 |
48 | }
49 |
50 | public static int GetContentLength(WebHeaderCollection headers)
51 | {
52 | if (headers != null &&
53 | headers[HTTP.CONTENT_LEN] != null)
54 | {
55 | return int.Parse(headers[HTTP.CONTENT_LEN]);
56 | }
57 | return 0;
58 | }
59 |
60 | public static string GetTransferEncoding(WebHeaderCollection headers)
61 | {
62 | if (headers != null &&
63 | headers[HTTP.TRANSFER_ENCODING] != null)
64 | return headers[HTTP.TRANSFER_ENCODING];
65 | else
66 | return null;
67 | }
68 |
69 | public static int ConvertHexToInt(string hexValue)
70 | {
71 | try
72 | {
73 | return int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);
74 | }
75 | catch
76 | {
77 | return 0;
78 | }
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Cookies/HttpCookieStore.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | using CodeScales.Http.Methods;
21 | using CodeScales.Http.Cookies;
22 | using CodeScales.Http.Network;
23 |
24 | namespace CodeScales.Http.Cookies
25 | {
26 | public class HttpCookieStore
27 | {
28 | private Dictionary m_cookieStore = new Dictionary();
29 |
30 | internal void WriteCookiesToRequest(HttpRequest request)
31 | {
32 | string host = request.Uri.Host;
33 | if (this.m_cookieStore.ContainsKey(host))
34 | {
35 | HttpCookieCollection cookieColl = this.m_cookieStore[request.Uri.Host];
36 | if (cookieColl != null)
37 | {
38 | request.Headers.Add("Cookie", HTTPProtocol.GetCookiesHeader(cookieColl));
39 | }
40 | }
41 | }
42 |
43 | internal void ReadCookiesFromResponse(HttpResponse response)
44 | {
45 | lock (this)
46 | {
47 | Uri responseUri = response.RequestUri;
48 | HttpCookieCollection cookieColl = null;
49 | if (this.m_cookieStore.ContainsKey(responseUri.Host))
50 | {
51 | cookieColl = this.m_cookieStore[responseUri.Host];
52 | }
53 | else
54 | {
55 | cookieColl = new HttpCookieCollection();
56 | this.m_cookieStore.Add(responseUri.Host, cookieColl);
57 | }
58 |
59 | string [] cookieHeaders = response.Headers.GetValues("Set-Cookie");
60 | if (cookieHeaders != null)
61 | {
62 |
63 | foreach (string header in cookieHeaders)
64 | {
65 | HTTPProtocol.AddHttpCookie(header, cookieColl);
66 | }
67 | }
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Examples/HttpGetExample.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | using CodeScales.Http;
6 | using CodeScales.Http.Entity;
7 | using CodeScales.Http.Methods;
8 |
9 | namespace CodeScales.Http.Examples
10 | {
11 | public class HttpGetExample
12 | {
13 | public static void DoGet()
14 | {
15 | HttpClient httpClient = new HttpClient();
16 | HttpGet httpGet = new HttpGet(new Uri("http://www.codescales.com"));
17 | HttpResponse httpResponse = httpClient.Execute(httpGet);
18 |
19 | Console.WriteLine("Response Code: " + httpResponse.ResponseCode);
20 | Console.WriteLine("Response Content: " + EntityUtils.ToString(httpResponse.Entity));
21 | }
22 |
23 | public static void DoGetWithRedirects()
24 | {
25 | HttpClient httpClient = new HttpClient();
26 | httpClient.MaxRedirects = 0;
27 | HttpGet httpGet = new HttpGet(new Uri("http://www.codescales.com/home"));
28 | HttpResponse httpResponse = httpClient.Execute(httpGet);
29 |
30 | Console.WriteLine("Response Code: " + httpResponse.ResponseCode);
31 | Console.WriteLine("Response Code: " + httpResponse.Location);
32 | Console.WriteLine("Response Content: " + EntityUtils.ToString(httpResponse.Entity));
33 | }
34 |
35 | public static void DoGetWithRedirects2()
36 | {
37 | HttpClient httpClient = new HttpClient();
38 | HttpGet httpGet = new HttpGet(new Uri("http://www.codescales.com/home"));
39 |
40 | HttpBehavior httpBehavior = new HttpBehavior();
41 | httpBehavior.AddStep(301, "http://www.codescales.com");
42 | httpBehavior.AddStep(200);
43 |
44 | HttpResponse httpResponse = httpClient.Execute(httpGet, httpBehavior);
45 |
46 | Console.WriteLine("Response Code: " + httpResponse.ResponseCode);
47 | Console.WriteLine("Response Code: " + httpResponse.Location);
48 | Console.WriteLine("Response Content: " + EntityUtils.ToString(httpResponse.Entity));
49 | }
50 |
51 | public static void DoGetWithProxy()
52 | {
53 | HttpClient httpClient = new HttpClient();
54 | httpClient.Proxy = new Uri("http://localhost:8888/"); // default address of fiddler
55 | HttpGet httpGet = new HttpGet(new Uri("http://www.codescales.com"));
56 | HttpResponse httpResponse = httpClient.Execute(httpGet);
57 |
58 | Console.WriteLine("Response Code: " + httpResponse.ResponseCode);
59 | Console.WriteLine("Response Content: " + EntityUtils.ToString(httpResponse.Entity));
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Entity/UrlEncodedFormEntity.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | /*
17 | * ====================================================================
18 | *
19 | * This class is inspired by org.apache.http.client.entity.UrlEncodedFormEntity
20 | *
21 | * ====================================================================
22 | *
23 | */
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Text;
28 | using System.Web;
29 |
30 | using CodeScales.Http.Common;
31 | using CodeScales.Http.Network;
32 |
33 | namespace CodeScales.Http.Entity
34 | {
35 | public class UrlEncodedFormEntity : HttpEntity
36 | {
37 | private Encoding m_encoding;
38 | private List m_parameters;
39 | private byte[] m_content;
40 |
41 | public UrlEncodedFormEntity(List parameters, Encoding encoding)
42 | {
43 | this.m_parameters = parameters;
44 | this.m_encoding = encoding;
45 |
46 | StringBuilder stringBuilder = new StringBuilder();
47 | HTTPProtocol.AddPostParameters(this.m_parameters, stringBuilder);
48 | m_content = this.m_encoding.GetBytes(stringBuilder.ToString());
49 | }
50 |
51 | public string ContentEncoding
52 | {
53 | get { return null; }
54 | set {}
55 | }
56 |
57 | public string ContentType
58 | {
59 | get { return "application/x-www-form-urlencoded"; }
60 | set {}
61 | }
62 |
63 | public byte[] Content
64 | {
65 | get
66 | {
67 | return this.m_content;
68 | }
69 | set {}
70 | }
71 |
72 | public long ContentLength
73 | {
74 | get
75 | {
76 | if (this.m_content != null)
77 | {
78 | return this.m_content.GetLongLength(0);
79 | }
80 | else
81 | return 0;
82 | }
83 | set {}
84 | }
85 |
86 | public bool IsChunked
87 | {
88 | get
89 | {
90 | return false;
91 | }
92 | set {}
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Entity/Mime/FileBody.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | /*
17 | * ====================================================================
18 | *
19 | * This class is inspired by org.apache.http.entity.mime.content.FileBody
20 | *
21 | * ====================================================================
22 | *
23 | */
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Text;
28 | using System.IO;
29 |
30 | using CodeScales.Http.Network;
31 |
32 | namespace CodeScales.Http.Entity.Mime
33 | {
34 | public class FileBody : Body
35 | {
36 | private string m_name;
37 | private string m_fileName;
38 | private byte[] m_content;
39 | private string m_mimeType;
40 |
41 | public FileBody(string name, string fileName, FileInfo fileInfo, string mimeType)
42 | : this(name, fileName, fileInfo)
43 | {
44 | this.m_mimeType = mimeType;
45 | }
46 |
47 | public FileBody(string name, string fileName, FileInfo fileInfo)
48 | {
49 | this.m_name = name;
50 | this.m_fileName = fileName;
51 | this.m_content = null;
52 |
53 | if (fileInfo == null)
54 | {
55 | this.m_content = new byte[0];
56 | }
57 | else
58 | {
59 | using (BinaryReader reader = new BinaryReader(fileInfo.OpenRead()))
60 | {
61 | this.m_content = reader.ReadBytes((int)reader.BaseStream.Length);
62 | }
63 | }
64 | }
65 |
66 | public byte[] GetContent(string boundry)
67 | {
68 | List bytes = new List();
69 | if (this.m_content.Length == 0 || this.m_mimeType == null || this.m_mimeType.Equals(string.Empty))
70 | {
71 | bytes.AddRange(Encoding.ASCII.GetBytes(HTTPProtocol.AddPostParametersFile(this.m_name, this.m_fileName, boundry, "application/octet-stream")));
72 | }
73 | else
74 | {
75 | bytes.AddRange(Encoding.ASCII.GetBytes(HTTPProtocol.AddPostParametersFile(this.m_name, this.m_fileName, boundry, this.m_mimeType)));
76 | }
77 | bytes.AddRange(this.m_content);
78 | bytes.AddRange(Encoding.ASCII.GetBytes("\r\n"));
79 | return bytes.ToArray();
80 | }
81 |
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests/CodeScales.Http.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Debug
4 | AnyCPU
5 | 8.0.50727
6 | 2.0
7 | {AADEA75C-2370-4C6E-A704-FEA3E11A8EAB}
8 | Library
9 | Properties
10 | CodeScales.Http.Tests
11 | CodeScales.Http.Tests
12 |
13 |
14 | true
15 | full
16 | false
17 | bin\Debug\
18 | DEBUG;TRACE
19 | prompt
20 | 4
21 |
22 |
23 | pdbonly
24 | true
25 | bin\Release\
26 | TRACE
27 | prompt
28 | 4
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | {FC262E96-6275-4798-8181-D9001FB50541}
50 | CodeScales.Http
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
66 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Methods/HttpGet.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.Net;
20 | using System.Web;
21 |
22 | namespace CodeScales.Http.Methods
23 | {
24 | public class HttpGet : HttpRequest
25 | {
26 | private static string METHOD = "GET";
27 |
28 | public HttpGet()
29 | {
30 | this.Headers.Add("UserAgent", @"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)");
31 | }
32 |
33 | public HttpGet(Uri uri) : this()
34 | {
35 | this.Uri = uri;
36 | }
37 |
38 | public override string Method
39 | {
40 | get
41 | {
42 | return METHOD;
43 | }
44 | }
45 |
46 | public override string GetRequestLine(bool useProxy)
47 | {
48 | Uri url = AddParametersToPath(this.Uri);
49 |
50 | string requestUri = null;
51 | if (useProxy)
52 | {
53 | requestUri = url.AbsoluteUri;
54 | }
55 | else
56 | {
57 | requestUri = url.PathAndQuery;
58 | }
59 |
60 | return Method + " " + requestUri + " HTTP/1.1";
61 | }
62 |
63 | private Uri AddParametersToPath(Uri url)
64 | {
65 | if (this.Parameters.Count > 0)
66 | {
67 | string absoluteUri = url.AbsoluteUri;
68 | StringBuilder newQuery = new StringBuilder();
69 | newQuery.Append(absoluteUri);
70 | if (absoluteUri.IndexOf('?') < 0)
71 | {
72 | newQuery.Append('?');
73 | }
74 | else
75 | {
76 | newQuery.Append('&');
77 | }
78 | int counter = 1;
79 | foreach (string key in this.Parameters.Keys)
80 | {
81 | newQuery.Append(key + '=' + HttpUtility.UrlEncode(this.Parameters[key]));
82 | if (counter < this.Parameters.Count)
83 | {
84 | newQuery.Append('&');
85 | }
86 | counter++;
87 | }
88 | return new Uri(newQuery.ToString());
89 | }
90 | else
91 | return url;
92 | }
93 |
94 |
95 |
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 9.00
3 | # Visual Studio 2005
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeScales.Http.Tests.Server", "CodeScales.Http.Tests.Server\CodeScales.Http.Tests.Server.csproj", "{064A9560-7590-42A9-9E33-1FC1689760B3}"
5 | ProjectSection(WebsiteProperties) = preProject
6 | Debug.AspNetCompiler.Debug = "True"
7 | Release.AspNetCompiler.Debug = "False"
8 | EndProjectSection
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeScales.Http", "CodeScales.Http\CodeScales.Http.csproj", "{FC262E96-6275-4798-8181-D9001FB50541}"
11 | ProjectSection(WebsiteProperties) = preProject
12 | Debug.AspNetCompiler.Debug = "True"
13 | Release.AspNetCompiler.Debug = "False"
14 | EndProjectSection
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeScales.Http.Tests", "CodeScales.Http.Tests\CodeScales.Http.Tests.csproj", "{AADEA75C-2370-4C6E-A704-FEA3E11A8EAB}"
17 | ProjectSection(WebsiteProperties) = preProject
18 | Debug.AspNetCompiler.Debug = "True"
19 | Release.AspNetCompiler.Debug = "False"
20 | EndProjectSection
21 | EndProject
22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeScales.Http.Examples", "CodeScales.Http.Examples\CodeScales.Http.Examples.csproj", "{7479716F-061C-4751-8895-B405E8B6B4EE}"
23 | ProjectSection(WebsiteProperties) = preProject
24 | Debug.AspNetCompiler.Debug = "True"
25 | Release.AspNetCompiler.Debug = "False"
26 | EndProjectSection
27 | EndProject
28 | Global
29 | GlobalSection(SubversionScc) = preSolution
30 | Svn-Managed = True
31 | Manager = AnkhSVN - Subversion Support for Visual Studio
32 | EndGlobalSection
33 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
34 | Debug|Any CPU = Debug|Any CPU
35 | Release|Any CPU = Release|Any CPU
36 | EndGlobalSection
37 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
38 | {064A9560-7590-42A9-9E33-1FC1689760B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {064A9560-7590-42A9-9E33-1FC1689760B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {064A9560-7590-42A9-9E33-1FC1689760B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
41 | {064A9560-7590-42A9-9E33-1FC1689760B3}.Release|Any CPU.Build.0 = Release|Any CPU
42 | {FC262E96-6275-4798-8181-D9001FB50541}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43 | {FC262E96-6275-4798-8181-D9001FB50541}.Debug|Any CPU.Build.0 = Debug|Any CPU
44 | {FC262E96-6275-4798-8181-D9001FB50541}.Release|Any CPU.ActiveCfg = Release|Any CPU
45 | {FC262E96-6275-4798-8181-D9001FB50541}.Release|Any CPU.Build.0 = Release|Any CPU
46 | {AADEA75C-2370-4C6E-A704-FEA3E11A8EAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47 | {AADEA75C-2370-4C6E-A704-FEA3E11A8EAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
48 | {AADEA75C-2370-4C6E-A704-FEA3E11A8EAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
49 | {AADEA75C-2370-4C6E-A704-FEA3E11A8EAB}.Release|Any CPU.Build.0 = Release|Any CPU
50 | {7479716F-061C-4751-8895-B405E8B6B4EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
51 | {7479716F-061C-4751-8895-B405E8B6B4EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
52 | {7479716F-061C-4751-8895-B405E8B6B4EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
53 | {7479716F-061C-4751-8895-B405E8B6B4EE}.Release|Any CPU.Build.0 = Release|Any CPU
54 | EndGlobalSection
55 | GlobalSection(SolutionProperties) = preSolution
56 | HideSolutionNode = FALSE
57 | EndGlobalSection
58 | EndGlobal
59 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/CodeScales.Http.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Debug
4 | AnyCPU
5 | 8.0.50727
6 | 2.0
7 | {FC262E96-6275-4798-8181-D9001FB50541}
8 | Library
9 | Properties
10 | CodeScales.Http
11 | CodeScales.Http
12 |
13 |
14 | true
15 | full
16 | false
17 | bin\Debug\
18 | DEBUG;TRACE
19 | prompt
20 | 4
21 |
22 |
23 | pdbonly
24 | true
25 | bin\Release\
26 | TRACE
27 | prompt
28 | 4
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
74 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests/MessageData.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.Xml.Serialization;
20 | using System.IO;
21 |
22 | namespace CodeScales.Http.Tests
23 | {
24 | [Serializable]
25 | public class MessageData
26 | {
27 | private NameValueColl m_queryParameters;
28 | private NameValueColl m_postParameters;
29 | private NameValueColl m_cookies;
30 | private NameValueColl m_files;
31 |
32 | public static MessageData Empty
33 | {
34 | get
35 | {
36 | return new MessageData();
37 | }
38 | }
39 |
40 | public NameValueColl QueryParameters
41 | {
42 | get
43 | {
44 | if (m_queryParameters == null)
45 | {
46 | m_queryParameters = new NameValueColl();
47 | }
48 | return m_queryParameters;
49 | }
50 | set { m_queryParameters = value; }
51 | }
52 |
53 | public NameValueColl PostParameters
54 | {
55 | get
56 | {
57 | if (m_postParameters == null)
58 | {
59 | m_postParameters = new NameValueColl();
60 | }
61 | return m_postParameters;
62 | }
63 | set { m_postParameters = value; }
64 | }
65 |
66 | public NameValueColl Cookies
67 | {
68 | get
69 | {
70 | if (m_cookies == null)
71 | {
72 | m_cookies = new NameValueColl();
73 | }
74 | return m_cookies;
75 | }
76 | set { m_cookies = value; }
77 | }
78 |
79 | public NameValueColl Files
80 | {
81 | get
82 | {
83 | if (m_files == null)
84 | {
85 | m_files = new NameValueColl();
86 | }
87 | return m_files;
88 | }
89 | set { m_files = value; }
90 | }
91 |
92 | public override string ToString()
93 | {
94 | XmlSerializer xs = new XmlSerializer(typeof(MessageData));
95 | TextWriter writer = new StringWriter();
96 | xs.Serialize(writer, this);
97 | return writer.ToString();
98 | }
99 |
100 | public MessageData FromString(string xmlString)
101 | {
102 | XmlSerializer xs = new XmlSerializer(typeof(MessageData));
103 | TextReader reader = new StringReader(xmlString);
104 | return (MessageData)xs.Deserialize(reader);
105 | }
106 |
107 |
108 |
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Entity/MultipartEntity.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | /*
17 | * ====================================================================
18 | *
19 | * This class is inspired by org.apache.http.entity.mime.MultipartEntity
20 | *
21 | * ====================================================================
22 | *
23 | */
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Text;
28 |
29 | using CodeScales.Http.Entity.Mime;
30 | using CodeScales.Http.Network;
31 |
32 | namespace CodeScales.Http.Entity
33 | {
34 | public class MultipartEntity : HttpEntity
35 | {
36 | private List m_bodyList = new List();
37 | private string m_boundry;
38 |
39 | public MultipartEntity()
40 | {
41 | GenerateBoundry();
42 | }
43 |
44 | public void AddBody(Body body)
45 | {
46 | this.m_bodyList.Add(body);
47 | }
48 |
49 | public string ContentEncoding
50 | {
51 | get { return null; }
52 | set {}
53 | }
54 |
55 | public string ContentType
56 | {
57 | get { return "multipart/form-data; boundary=" + m_boundry; }
58 | set {}
59 | }
60 |
61 | public byte[] Content
62 | {
63 | get
64 | {
65 | List byteList = new List();
66 | foreach (Body body in this.m_bodyList)
67 | {
68 | byteList.AddRange(body.GetContent(this.m_boundry));
69 | }
70 | if (this.m_bodyList.Count > 0)
71 | {
72 | byteList.AddRange(Encoding.ASCII.GetBytes(HTTPProtocol.AddPostParametersEnd(this.m_boundry)));
73 | }
74 | return byteList.ToArray();
75 | }
76 | set {}
77 | }
78 |
79 | public long ContentLength
80 | {
81 | get
82 | {
83 | return this.Content.Length;
84 | }
85 | set {}
86 | }
87 |
88 | public bool IsChunked
89 | {
90 | get
91 | {
92 | return false;
93 | }
94 | set {}
95 | }
96 |
97 | private static string allowedCharacters = "abcdefghijklmnopqrstuvwxyz1234567890";
98 | private void GenerateBoundry()
99 | {
100 | Random random = new Random(DateTime.Now.Millisecond);
101 | StringBuilder sb = new StringBuilder();
102 | sb.Append("---------------------------");
103 | for (int i = 0; i < 14; i++)
104 | {
105 | sb.Append(allowedCharacters[random.Next(allowedCharacters.Length-1)]);
106 | }
107 | this.m_boundry = sb.ToString();
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Methods/HttpPost.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.Net;
20 |
21 | using CodeScales.Http.Entity;
22 | using CodeScales.Http.Protocol;
23 |
24 | namespace CodeScales.Http.Methods
25 | {
26 | public class HttpPost : HttpRequest, HttpEntityEnclosingRequest
27 | {
28 | private static string METHOD = "POST";
29 | private HttpEntity m_entity = null;
30 |
31 | public HttpPost()
32 | {
33 | }
34 |
35 | public HttpPost(Uri uri) : this()
36 | {
37 | this.Uri = uri;
38 | }
39 |
40 | public override string Method
41 | {
42 | get
43 | {
44 | return METHOD;
45 | }
46 | }
47 |
48 | public override string GetRequestLine(bool useProxy)
49 | {
50 | string requestUri = null;
51 | if (useProxy)
52 | {
53 | requestUri = this.Uri.AbsoluteUri;
54 | }
55 | else
56 | {
57 | requestUri = this.Uri.PathAndQuery;
58 | }
59 |
60 | return Method + " " + requestUri + " HTTP/1.1";
61 | }
62 |
63 | public HttpEntity Entity
64 | {
65 | get { return m_entity; }
66 | set { m_entity = value; }
67 | }
68 |
69 | public override WebHeaderCollection Headers
70 | {
71 | get
72 | {
73 | if (base.Headers != null && this.m_entity != null)
74 | {
75 | if (base.Headers[HTTP.CONTENT_LEN] == null
76 | || base.Headers[HTTP.CONTENT_LEN] == string.Empty)
77 | {
78 | base.Headers[HTTP.CONTENT_LEN] = this.m_entity.ContentLength.ToString();
79 | }
80 |
81 | if (base.Headers[HTTP.CONTENT_TYPE] == null
82 | || base.Headers[HTTP.CONTENT_TYPE] == string.Empty)
83 | {
84 | base.Headers[HTTP.CONTENT_TYPE] = this.m_entity.ContentType;
85 | }
86 | base.Headers.Add(HTTP.USER_AGENT, @"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)");
87 | }
88 |
89 | return base.Headers;
90 | }
91 | set
92 | {
93 | base.Headers = value;
94 | }
95 | }
96 |
97 | public bool ExpectContinue
98 | {
99 | get
100 | {
101 | if (base.Headers != null)
102 | {
103 | return (base.Headers[HTTP.EXPECT_DIRECTIVE] != null
104 | && base.Headers[HTTP.EXPECT_DIRECTIVE].Equals(HTTP.EXPECT_CONTINUE));
105 | }
106 | else return false;
107 | }
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/HttpBehavior.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | namespace CodeScales.Http
21 | {
22 | public class HttpBehavior
23 | {
24 | private Queue m_steps = new Queue();
25 |
26 | public void AddStep(int responseCode)
27 | {
28 | AddStep(responseCode, null);
29 | }
30 |
31 | public void AddStep(int responseCode, string url)
32 | {
33 | RedirectStep rs = new RedirectStep();
34 | rs.ResponseCode = responseCode;
35 | rs.Url = url;
36 | m_steps.Enqueue(rs);
37 | }
38 |
39 | public bool IsEmpty()
40 | {
41 | return m_steps.Count == 0;
42 | }
43 |
44 | public RedirectStep GetNextStep()
45 | {
46 | if (m_steps.Count > 0)
47 | {
48 | return m_steps.Dequeue();
49 | }
50 | else
51 | {
52 | // if there is no next step
53 | throw new HttpBehaviorException();
54 | }
55 | }
56 |
57 | public class RedirectStep
58 | {
59 | private int m_responseCode = 0;
60 | private string m_url = null;
61 |
62 | public int ResponseCode
63 | {
64 | get { return m_responseCode; }
65 | set { m_responseCode = value; }
66 | }
67 |
68 | public string Url
69 | {
70 | get { return m_url; }
71 | set { m_url = value; }
72 | }
73 |
74 | internal void Compare(int responseStatus, string redirectUri)
75 | {
76 | if (m_responseCode != responseStatus)
77 | {
78 | throw new HttpBehaviorException(responseStatus, redirectUri);
79 | }
80 |
81 | if (m_responseCode == 301 || m_responseCode == 302)
82 | {
83 | if (IsEmpty(redirectUri) && !IsEmpty(m_url))
84 | throw new HttpBehaviorException();
85 |
86 | if (!IsEmpty(redirectUri) && IsEmpty(m_url))
87 | throw new HttpBehaviorException();
88 |
89 | if (redirectUri.StartsWith(m_url))
90 | {
91 | return; //OK
92 | }
93 | else
94 | {
95 | throw new HttpBehaviorException();
96 | }
97 | }
98 | }
99 |
100 | private bool IsEmpty(string uri)
101 | {
102 | if (uri == null || uri.Equals(string.Empty))
103 | return true;
104 | else
105 | return false;
106 | }
107 |
108 | internal bool IsRedirect()
109 | {
110 | return (m_responseCode == 301 || m_responseCode == 302);
111 | }
112 | }
113 | }
114 |
115 | public class HttpBehaviorException : Exception
116 | {
117 | private int m_responseCode = 0;
118 | private string m_locatioon = null;
119 |
120 | public HttpBehaviorException()
121 | {
122 | }
123 |
124 | public HttpBehaviorException(int responseCode, string location)
125 | {
126 | this.m_responseCode = responseCode;
127 | this.m_locatioon = location;
128 | }
129 | }
130 |
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests/HttpRedirectTests.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | using CodeScales.Http;
21 | using CodeScales.Http.Methods;
22 | using CodeScales.Http.Entity;
23 | using NUnit.Framework;
24 |
25 | namespace CodeScales.Http.Tests
26 | {
27 | [TestFixture]
28 | public class HttpRedirectTests
29 | {
30 | [Test]
31 | public void HttpGetWithRedirect()
32 | {
33 | // with SetMaxRedirects
34 | // make sure we are not redirected
35 | HttpClient client = new HttpClient();
36 | client.MaxRedirects = 0;
37 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_302));
38 | HttpResponse response = client.Execute(getMethod);
39 |
40 | Assert.AreEqual(302, response.ResponseCode);
41 | Console.Write(EntityUtils.ToString(response.Entity));
42 |
43 | getMethod = new HttpGet(new Uri(response.Location));
44 | response = client.Execute(getMethod);
45 |
46 | Assert.AreEqual(200, response.ResponseCode);
47 | Assert.AreEqual(Constants.HTTP_REDIRECT_TARGET_1, response.RequestUri.AbsoluteUri);
48 | string responseString = EntityUtils.ToString(response.Entity);
49 | Console.Write(responseString);
50 |
51 | }
52 |
53 | [Test]
54 | public void HttpGetWithRedirect2()
55 | {
56 | // with SetMaxRedirects
57 | // make sure we were redirected
58 | HttpClient client = new HttpClient();
59 | client.MaxRedirects = 1;
60 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_302));
61 | HttpResponse response = client.Execute(getMethod);
62 |
63 | Assert.AreEqual(200, response.ResponseCode);
64 | Assert.AreEqual(Constants.HTTP_REDIRECT_TARGET_1, response.RequestUri.AbsoluteUri);
65 | string responseString = EntityUtils.ToString(response.Entity);
66 | Console.Write(responseString);
67 |
68 | }
69 |
70 | [Test]
71 | public void HttpGetWithRedirect3()
72 | {
73 | // this time with HTTPBehavior
74 | // make sure we were redirected and no exception is thrown
75 | HttpClient client = new HttpClient();
76 | HttpBehavior httpBehavior = new HttpBehavior();
77 | httpBehavior.AddStep(302, Constants.HTTP_REDIRECT_TARGET_1);
78 | httpBehavior.AddStep(200);
79 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_302));
80 | HttpResponse response = client.Execute(getMethod, httpBehavior);
81 |
82 | Assert.AreEqual(200, response.ResponseCode);
83 | Assert.AreEqual(Constants.HTTP_REDIRECT_TARGET_1, response.RequestUri.AbsoluteUri);
84 | string responseString = EntityUtils.ToString(response.Entity);
85 | Console.Write(responseString);
86 | }
87 |
88 | [Test]
89 | [ExpectedException(typeof(HttpBehaviorException))]
90 | public void HttpGetWithRedirect4()
91 | {
92 | // this time with HTTPBehavior
93 | // here both response code and location are wrong
94 | // make sure an exception is thrown
95 |
96 | HttpClient client = new HttpClient();
97 | HttpBehavior httpBehavior = new HttpBehavior();
98 | httpBehavior.AddStep(200);
99 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_302));
100 | HttpResponse response = client.Execute(getMethod, httpBehavior);
101 | }
102 |
103 | [Test]
104 | [ExpectedException(typeof(HttpBehaviorException))]
105 | public void HttpGetWithRedirect5()
106 | {
107 | // this time with HTTPBehavior
108 | // here the response code is wrong
109 | // make sure an exception is thrown
110 |
111 | HttpClient client = new HttpClient();
112 | HttpBehavior httpBehavior = new HttpBehavior();
113 | httpBehavior.AddStep(200, Constants.HTTP_GET_302);
114 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_302));
115 | HttpResponse response = client.Execute(getMethod, httpBehavior);
116 | }
117 |
118 | [Test]
119 | [ExpectedException(typeof(HttpBehaviorException))]
120 | public void HttpGetWithRedirect6()
121 | {
122 | // this time with HTTPBehavior
123 | // here the response location is wrong
124 | // make sure an exception is thrown
125 |
126 | HttpClient client = new HttpClient();
127 | HttpBehavior httpBehavior = new HttpBehavior();
128 | httpBehavior.AddStep(302, Constants.HTTP_GET_200);
129 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_302));
130 | HttpResponse response = client.Execute(getMethod, httpBehavior);
131 | }
132 |
133 | [Test]
134 | public void HttpGetWithRedirect7()
135 | {
136 | // this time with HTTPBehavior
137 | // make sure we get only the first response
138 | // and do not make the second call
139 | HttpClient client = new HttpClient();
140 | HttpBehavior httpBehavior = new HttpBehavior();
141 | httpBehavior.AddStep(302, Constants.HTTP_REDIRECT_TARGET_1);
142 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_302));
143 | HttpResponse response = client.Execute(getMethod, httpBehavior);
144 |
145 | Assert.AreEqual(302, response.ResponseCode);
146 | Assert.AreEqual(Constants.HTTP_REDIRECT_TARGET_1, response.Location);
147 | }
148 |
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests.Server/CodeScales.Http.Tests.Server.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Debug
4 | AnyCPU
5 | 8.0.50727
6 | 2.0
7 | {064A9560-7590-42A9-9E33-1FC1689760B3}
8 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
9 | Library
10 | Properties
11 | CodeScales.Http.Tests.Server
12 | CodeScales.Http.Tests.Server
13 |
14 |
15 | true
16 | full
17 | false
18 | bin\
19 | DEBUG;TRACE
20 | prompt
21 | 4
22 |
23 |
24 | pdbonly
25 | true
26 | bin\
27 | TRACE
28 | prompt
29 | 4
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | ASPXCodeBehind
57 | AspNetUpload.aspx
58 |
59 |
60 | AspNetUpload.aspx
61 |
62 |
63 | HttpMultipartPost200.aspx
64 | ASPXCodeBehind
65 |
66 |
67 | HttpMultipartPost200.aspx
68 |
69 |
70 | HttpPost200.aspx
71 | ASPXCodeBehind
72 |
73 |
74 | HttpPost200.aspx
75 |
76 |
77 | HttpGet200WithSetCookies.aspx
78 | ASPXCodeBehind
79 |
80 |
81 | HttpGet200WithSetCookies.aspx
82 |
83 |
84 | HttpGet302.aspx
85 | ASPXCodeBehind
86 |
87 |
88 | HttpGet302.aspx
89 |
90 |
91 | ASPXCodeBehind
92 | HttpGet200.aspx
93 |
94 |
95 | HttpGet200.aspx
96 |
97 |
98 | ASPXCodeBehind
99 | HttpRedirectTarget1.aspx
100 |
101 |
102 | HttpRedirectTarget1.aspx
103 |
104 |
105 |
106 |
107 |
108 | {AADEA75C-2370-4C6E-A704-FEA3E11A8EAB}
109 | CodeScales.Http.Tests
110 |
111 |
112 | {FC262E96-6275-4798-8181-D9001FB50541}
113 | CodeScales.Http
114 |
115 |
116 |
117 |
118 |
125 |
126 |
127 |
128 |
129 | False
130 | True
131 | 1508
132 | /
133 |
134 |
135 | False
136 |
137 |
138 |
139 |
140 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests/HttpGetTests.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 |
20 | using CodeScales.Http;
21 | using CodeScales.Http.Common;
22 | using CodeScales.Http.Methods;
23 | using CodeScales.Http.Entity;
24 | using NUnit.Framework;
25 |
26 | namespace CodeScales.Http.Tests
27 | {
28 | [TestFixture]
29 | public class HttpGetTests
30 | {
31 | [Test]
32 | public void HttpGet()
33 | {
34 | HttpClient client = new HttpClient();
35 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_200));
36 | HttpResponse response = client.Execute(getMethod);
37 |
38 | Assert.AreEqual(200, response.ResponseCode);
39 | string responseString = EntityUtils.ToString(response.Entity);
40 | Assert.AreEqual(MessageData.Empty.ToString(), responseString);
41 | Assert.AreEqual(Constants.HTTP_GET_200, response.RequestUri.AbsoluteUri);
42 | Console.Write(responseString);
43 |
44 | }
45 |
46 | [Test]
47 | public void HttpGetWithParameters()
48 | {
49 | HttpClient client = new HttpClient();
50 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_200));
51 | getMethod.Parameters.Add("test", "1 and text");
52 | getMethod.Parameters.Add("test2", "2 and text <> &&");
53 | HttpResponse response = client.Execute(getMethod);
54 |
55 | Assert.AreEqual(200, response.ResponseCode);
56 | Assert.AreEqual(Constants.HTTP_GET_200, response.RequestUri.AbsoluteUri);
57 | // assert the parameters
58 | MessageData md = new MessageData();
59 | md.QueryParameters.Add(new NameValuePair("test", "1 and text"));
60 | md.QueryParameters.Add(new NameValuePair("test2", "2 and text <> &&"));
61 | string responseString = EntityUtils.ToString(response.Entity);
62 | Assert.AreEqual(md.ToString(), responseString);
63 | Console.Write(responseString);
64 | }
65 |
66 | [Test]
67 | public void HttpGetWithProxy()
68 | {
69 | HttpClient client = new HttpClient();
70 | client.Proxy = new Uri(Constants.FIDDLER_DEFAULT_ADDRESS);
71 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_200));
72 | HttpResponse response = client.Execute(getMethod);
73 |
74 | Assert.AreEqual(200, response.ResponseCode);
75 | string responseString = EntityUtils.ToString(response.Entity);
76 | Assert.AreEqual(MessageData.Empty.ToString(), responseString);
77 | Assert.AreEqual(Constants.HTTP_GET_200, response.RequestUri.AbsoluteUri);
78 | Console.Write(responseString);
79 | }
80 |
81 | [Test]
82 | public void HttpGetWithCookies()
83 | {
84 | // with SetMaxRedirects
85 | // make sure we are not redirected
86 | HttpClient client = new HttpClient();
87 | client.MaxRedirects = 0;
88 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_200_WITH_SET_COOKIES));
89 | getMethod.Parameters.Add("cookie1", "value1");
90 | getMethod.Parameters.Add("cookie2", "value2");
91 | HttpResponse response = client.Execute(getMethod);
92 |
93 | Assert.AreEqual(200, response.ResponseCode);
94 | Assert.AreEqual(Constants.HTTP_GET_200_WITH_SET_COOKIES, response.RequestUri.AbsoluteUri);
95 |
96 | getMethod = new HttpGet(new Uri(Constants.HTTP_GET_200));
97 | response = client.Execute(getMethod);
98 |
99 | Assert.AreEqual(200, response.ResponseCode);
100 | Assert.AreEqual(Constants.HTTP_GET_200, response.RequestUri.AbsoluteUri);
101 |
102 | // assert the cookies
103 | MessageData md = new MessageData();
104 | md.Cookies.Add(new NameValuePair("cookie1", "value1"));
105 | md.Cookies.Add(new NameValuePair("cookie2", "value2"));
106 | string responseString = EntityUtils.ToString(response.Entity);
107 | Assert.AreEqual(md.ToString(), responseString);
108 | Console.Write(responseString);
109 | }
110 |
111 | [Test]
112 | public void HttpGetWithChunkedResponse()
113 | {
114 | // we use codescales.com that is hosted by google
115 | // the google server always uses chunked transfer-encoding
116 |
117 | HttpClient client = new HttpClient();
118 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_GET_200_CODESCALES_COM));
119 | HttpResponse response = client.Execute(getMethod);
120 |
121 | Assert.AreEqual(200, response.ResponseCode);
122 | string responseString = EntityUtils.ToString(response.Entity);
123 | Assert.AreEqual(Constants.HTTP_GET_200_CODESCALES_COM, response.RequestUri.AbsoluteUri);
124 | Console.Write(responseString);
125 | }
126 |
127 | [Test]
128 | public void HttpGetWithChunkedResponse2()
129 | {
130 | // we use codescales.com that is hosted by google
131 | // the google server always uses chunked transfer-encoding
132 |
133 | HttpClient client = new HttpClient();
134 | HttpGet getMethod = new HttpGet(new Uri("http://forums.photographyreview.com/showthread.php?t=68825"));
135 | HttpResponse response = client.Execute(getMethod);
136 |
137 | Assert.AreEqual(200, response.ResponseCode);
138 | string responseString = EntityUtils.ToString(response.Entity);
139 | Assert.AreEqual("http://forums.photographyreview.com/showthread.php?t=68825", response.RequestUri.AbsoluteUri);
140 | Console.Write(responseString);
141 | }
142 |
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/HttpClient.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.Net;
20 | using System.IO;
21 |
22 | using CodeScales.Http.Cookies;
23 | using CodeScales.Http.Methods;
24 | using CodeScales.Http.Network;
25 | using CodeScales.Http.Entity;
26 |
27 | namespace CodeScales.Http
28 | {
29 | public class HttpClient
30 | {
31 | private HttpCookieStore m_cookieStore = new HttpCookieStore();
32 | private Uri m_proxy = null;
33 | private int m_maxRedirects = 1;
34 |
35 | public Uri Proxy
36 | {
37 | set
38 | {
39 | this.m_proxy = value;
40 | }
41 | }
42 |
43 | public int MaxRedirects
44 | {
45 | set
46 | {
47 | this.m_maxRedirects = value;
48 | }
49 | get
50 | {
51 | return this.MaxRedirects;
52 | }
53 | }
54 |
55 | public HttpResponse Execute(HttpRequest request)
56 | {
57 | return Navigate(request, null);
58 | }
59 |
60 | public HttpResponse Execute(HttpRequest request, HttpBehavior httpBehavior)
61 | {
62 | return Navigate(request, httpBehavior);
63 | }
64 |
65 | private HttpResponse Navigate(HttpRequest request, HttpBehavior httpBehavior)
66 | {
67 | bool ContinueRedirect = true;
68 | HttpResponse response = null;
69 |
70 | HttpConnectionFactory connFactory = new HttpConnectionFactory();
71 | HttpConnection connection = connFactory.GetConnnection(request.Uri, this.m_proxy);
72 |
73 | HttpBehavior.RedirectStep rs = null;
74 | string redirectUri = null;
75 | int responseCode = 0;
76 | int redirectCounter = 0;
77 |
78 | try
79 | {
80 | while (ContinueRedirect)
81 | {
82 | try
83 | {
84 | response = SendRequestAndGetResponse(connection, request);
85 | redirectUri = response.Location;
86 | responseCode = response.ResponseCode;
87 |
88 | // response code 100 means that we need to wait for another response
89 | // and receive the response from the socket again on the same connection
90 | if (responseCode == 100)
91 | {
92 | response = GetResponse(connection);
93 | redirectUri = response.Location;
94 | responseCode = response.ResponseCode;
95 | }
96 |
97 | if (httpBehavior != null)
98 | {
99 | rs = httpBehavior.GetNextStep();
100 | rs.Compare(responseCode, redirectUri);
101 | ContinueRedirect = !httpBehavior.IsEmpty();
102 | }
103 | else
104 | {
105 | ContinueRedirect = (redirectCounter < this.m_maxRedirects && (responseCode == 301 || responseCode == 302));
106 | redirectCounter++;
107 | }
108 |
109 | if (ContinueRedirect)
110 | {
111 | request = new HttpGet(new Uri(redirectUri));
112 | // make sure the connection is still open and redirect url is from the same host
113 | connection = connFactory.GetConnnection(request.Uri, this.m_proxy, connection);
114 | }
115 |
116 | }
117 | catch (Exception ex)
118 | {
119 | int i = 0;
120 | throw ex;
121 | }
122 |
123 | }
124 | }
125 | finally
126 | {
127 | connection.Close();
128 | }
129 | return response;
130 |
131 | }
132 |
133 | private HttpResponse SendRequestAndGetResponse(HttpConnection connection, HttpRequest request)
134 | {
135 | m_cookieStore.WriteCookiesToRequest(request);
136 |
137 | // if we need to send a body (not only headers)
138 | if (request.GetType().GetInterface("HttpEntityEnclosingRequest") != null)
139 | {
140 | HttpEntityEnclosingRequest heer = (HttpEntityEnclosingRequest)request;
141 | connection.SendRequestHeaderAndEntity(request, heer.Entity, heer.ExpectContinue);
142 | }
143 | else
144 | {
145 | connection.SendRequestHeader(request);
146 | }
147 |
148 | return GetResponse(connection);
149 |
150 | }
151 |
152 | private HttpResponse GetResponse(HttpConnection connection)
153 | {
154 | HttpResponse response = connection.ReceiveResponseHeaders();
155 | m_cookieStore.ReadCookiesFromResponse(response);
156 | connection.ReceiveResponseEntity(response);
157 |
158 | // for response code 100 we expect another http message to arrive later
159 | if (response.ResponseCode != 100)
160 | {
161 | connection.CheckKeepAlive(response);
162 | }
163 | return response;
164 | }
165 |
166 | private string GetRedirectUri(Uri uri)
167 | {
168 | if (uri != null)
169 | return uri.AbsoluteUri;
170 | else
171 | return "";
172 | }
173 |
174 |
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Network/HttpProtocol.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.Web;
20 |
21 | using CodeScales.Http.Cookies;
22 | using CodeScales.Http.Common;
23 |
24 | namespace CodeScales.Http.Network
25 | {
26 | internal class HTTPProtocol
27 | {
28 | private const string VIEWSTATEStart = " ExtractUrlParameters(string url)
31 | {
32 | if (url.IndexOf('?') < 0)
33 | return null;
34 | string query = url.Substring(url.IndexOf('?') + 1);
35 | if (query == null)
36 | return null;
37 | string[] parameters = query.Split('&');
38 | if (parameters.Length <= 0)
39 | return null;
40 | Dictionary dic = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
41 | foreach (string param in parameters)
42 | {
43 | string[] namevalue = param.Split('=');
44 | if (namevalue != null && namevalue.Length == 2)
45 | {
46 | dic.Add(namevalue[0], namevalue[1]);
47 | }
48 | }
49 | return dic;
50 | }
51 |
52 | public static string GetViewState(string html)
53 | {
54 | string viewState = "";
55 | if (html.IndexOf("__VIEWSTATE") > 0)
56 | {
57 | int start = html.IndexOf(VIEWSTATEStart) + VIEWSTATEStart.Length;
58 | int end = html.IndexOf("\"", start);
59 | viewState = html.Substring(start, end - start);
60 | }
61 | return viewState;
62 | }
63 |
64 | internal static void AddPostParameters(List parameters, StringBuilder builder)
65 | {
66 | int counter = 0;
67 | foreach (NameValuePair pair in parameters)
68 | {
69 | builder.Append(pair.Name + "=" + HttpUtility.UrlEncode(pair.Value));
70 | if (counter < parameters.Count - 1)
71 | {
72 | builder.Append("&");
73 | }
74 | counter++;
75 | }
76 | }
77 |
78 | internal static string GetPostParameter(string name, string value, string boundry)
79 | {
80 | StringBuilder builder = new StringBuilder();
81 | string paramBoundry = "--" + boundry + "\r\n";
82 | string stringParam = "Content-Disposition: form-data; name=\"";
83 | string paramEnd = "\"\r\n\r\n";
84 | builder.Append(paramBoundry);
85 | builder.Append(stringParam + name + paramEnd + value + "\r\n");
86 | return builder.ToString();
87 | }
88 |
89 | internal static string AddPostParametersFile(string name, string fileName, string boundry, string contentType)
90 | {
91 | if (name == null)
92 | {
93 | name = string.Empty;
94 | }
95 | if (fileName == null)
96 | {
97 | fileName = string.Empty;
98 | }
99 |
100 | StringBuilder builder = new StringBuilder();
101 | string paramBoundry = "--" + boundry + "\r\n";
102 | string stringParam = "Content-Disposition: form-data; name=\"";
103 | string paramEnd = "\"; filename=\"" + fileName + "\"\r\nContent-Type: " + contentType + "\r\n\r\n";
104 | builder.Append(paramBoundry);
105 | builder.Append(stringParam + name + paramEnd);
106 | return builder.ToString();
107 | }
108 |
109 | internal static string AddPostParametersEnd(string boundry)
110 | {
111 | return "--" + boundry + "--\r\n\r\n";
112 | }
113 |
114 | public static Encoding GetEncoding(string contentType)
115 | {
116 | Encoding encoding = null;
117 | string enStr = GetCharacterSet(contentType);
118 | if (enStr != null && enStr != string.Empty)
119 | {
120 | try
121 | {
122 | encoding = Encoding.GetEncoding(enStr);
123 | }
124 | catch
125 | {
126 | encoding = Encoding.UTF8; //default
127 | }
128 | }
129 | else
130 | {
131 | encoding = Encoding.UTF8; //default
132 | }
133 | return encoding;
134 | }
135 |
136 | private static string GetCharacterSet(string s)
137 | {
138 | s = s.ToUpper();
139 | int start = s.LastIndexOf("CHARSET");
140 | if (start == -1)
141 | return "";
142 |
143 |
144 | start = s.IndexOf("=", start);
145 | if (start == -1)
146 | return "";
147 |
148 |
149 | start++;
150 | s = s.Substring(start).Trim();
151 | int end = s.Length;
152 |
153 |
154 | int i = s.IndexOf(";");
155 | if (i != -1)
156 | end = i;
157 | i = s.IndexOf("\"");
158 | if (i != -1 && i < end)
159 | end = i;
160 | i = s.IndexOf("'");
161 | if (i != -1 && i < end)
162 | end = i;
163 | i = s.IndexOf("/");
164 | if (i != -1 && i < end)
165 | end = i;
166 |
167 |
168 | return s.Substring(0, end).Trim();
169 | }
170 |
171 | public static string GetCookiesHeader(CodeScales.Http.Cookies.HttpCookieCollection cookies)
172 | {
173 | if (cookies != null && cookies.Count > 0)
174 | {
175 | int cookieCounter = 0;
176 | StringBuilder sb = new StringBuilder();
177 | // sb.Append("Cookie: ");
178 | foreach (string key in cookies.Keys)
179 | {
180 | sb.Append(key + "=" + cookies.GetCookie(key).Value);
181 | if (cookieCounter < cookies.Count - 1)
182 | {
183 | sb.Append(';');
184 | }
185 | cookieCounter++;
186 | }
187 | return sb.ToString(); // +"\r\n";
188 | }
189 | return null;
190 | }
191 |
192 | public static void AddHttpCookie(string headerPart, CodeScales.Http.Cookies.HttpCookieCollection cookies)
193 | {
194 | if (headerPart == null || headerPart == "" || cookies == null)
195 | return;
196 |
197 | string[] cookie_components = headerPart.Split(';');
198 |
199 | if (cookie_components != null && cookie_components.Length > 0)
200 | {
201 | string kv = cookie_components[0];
202 | int pos = kv.IndexOf('=');
203 | if (pos == -1)
204 | {
205 | /* XXX ugh */
206 |
207 | }
208 | else
209 | {
210 | string key = kv.Substring(0, pos).Trim();
211 | string val = kv.Substring(pos + 1).Trim();
212 |
213 | cookies.Add(key, new CodeScales.Http.Cookies.HttpCookie(key, val));
214 | }
215 | }
216 | }
217 | }
218 | }
219 |
220 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests/HttpPostTests.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.IO;
20 |
21 | using CodeScales.Http;
22 | using CodeScales.Http.Common;
23 | using CodeScales.Http.Methods;
24 | using CodeScales.Http.Entity;
25 | using CodeScales.Http.Entity.Mime;
26 | using NUnit.Framework;
27 |
28 | using CodeScales.Http.Tests.resources;
29 |
30 | namespace CodeScales.Http.Tests
31 | {
32 | [TestFixture]
33 | public class HttpPostTests
34 | {
35 | [Test]
36 | public void HttpPost()
37 | {
38 | HttpClient client = new HttpClient();
39 | HttpPost postMethod = new HttpPost(new Uri(Constants.HTTP_POST_200));
40 | List nameValuePairList = new List();
41 | nameValuePairList.Add(new NameValuePair("param1","value1"));
42 | nameValuePairList.Add(new NameValuePair("param2","!#$^&*((<>"));
43 | UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, Encoding.UTF8);
44 | postMethod.Entity = formEntity;
45 | HttpResponse response = client.Execute(postMethod);
46 |
47 | Assert.AreEqual(200, response.ResponseCode);
48 | string responseString = EntityUtils.ToString(response.Entity);
49 | MessageData md = new MessageData();
50 | md.PostParameters.Add(new NameValuePair("param1", "value1"));
51 | md.PostParameters.Add(new NameValuePair("param2", "!#$^&*((<>"));
52 | Assert.AreEqual(md.ToString(), responseString);
53 | Assert.AreEqual(Constants.HTTP_POST_200, response.RequestUri.AbsoluteUri);
54 | Console.Write(responseString);
55 |
56 | }
57 |
58 | [Test]
59 | public void HttpPostWithParameters2()
60 | {
61 | HttpClient client = new HttpClient();
62 |
63 | // first request - to get cookies
64 | HttpGet getMethod = new HttpGet(new Uri(Constants.HTTP_POST_W3SCHOOLS));
65 | HttpResponse response = client.Execute(getMethod);
66 | Assert.AreEqual(200, response.ResponseCode);
67 |
68 | // second request - to send form data
69 | HttpPost postMethod = new HttpPost(new Uri(Constants.HTTP_POST_W3SCHOOLS));
70 | List nameValuePairList = new List();
71 | nameValuePairList.Add(new NameValuePair("fname", "user 1"));
72 | UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, Encoding.UTF8);
73 | postMethod.Entity = formEntity;
74 | response = client.Execute(postMethod);
75 |
76 | Assert.AreEqual(200, response.ResponseCode);
77 | string responseString = EntityUtils.ToString(response.Entity);
78 | Assert.IsTrue(responseString.Contains("Hello user 1!"));
79 |
80 | }
81 |
82 | [Test]
83 | public void HttpPostWithFilesAndParameters()
84 | {
85 | // this method sends an empty file (or no file :)
86 | HttpClient client = new HttpClient();
87 | HttpPost postMethod = new HttpPost(new Uri(Constants.HTTP_MULTIPART_POST_200));
88 |
89 | MultipartEntity multipartEntity = new MultipartEntity();
90 | StringBody stringBody1 = new StringBody(Encoding.ASCII, "param1", "value1");
91 | multipartEntity.AddBody(stringBody1);
92 | StringBody stringBody2 = new StringBody(Encoding.ASCII, "param2", "!#$^&*((<>");
93 | multipartEntity.AddBody(stringBody2);
94 | FileBody fileBody1 = new FileBody("photo", "me.file", null);
95 | multipartEntity.AddBody(fileBody1);
96 | postMethod.Entity = multipartEntity;
97 | HttpResponse response = client.Execute(postMethod);
98 |
99 | Assert.AreEqual(200, response.ResponseCode);
100 | string responseString = EntityUtils.ToString(response.Entity);
101 | MessageData md = new MessageData();
102 | md.PostParameters.Add(new NameValuePair("param1", "value1"));
103 | md.PostParameters.Add(new NameValuePair("param2", "!#$^&*((<>"));
104 | md.Files.Add(new NameValuePair("me.file", "0"));
105 | Assert.AreEqual(md.ToString(), responseString);
106 | Assert.AreEqual(Constants.HTTP_MULTIPART_POST_200, response.RequestUri.AbsoluteUri);
107 | Console.Write(responseString);
108 | }
109 |
110 | [Test]
111 | public void HttpPostWithFilesAndParameters2()
112 | {
113 | // this method sends a file and checks for the number of bytes recieved
114 | HttpClient client = new HttpClient();
115 | HttpPost postMethod = new HttpPost(new Uri(Constants.HTTP_MULTIPART_POST_200));
116 |
117 | MultipartEntity multipartEntity = new MultipartEntity();
118 |
119 | string fileName = "big-text.txt";
120 |
121 | FileInfo fi = ResourceManager.GetResourceFileInfo(fileName);
122 | FileBody fileBody1 = new FileBody("file", fileName, fi, "text/plain");
123 |
124 | multipartEntity.AddBody(fileBody1);
125 | postMethod.Entity = multipartEntity;
126 |
127 | StringBody stringBody1 = new StringBody(Encoding.ASCII, "param1", "value1");
128 | multipartEntity.AddBody(stringBody1);
129 | StringBody stringBody2 = new StringBody(Encoding.ASCII, "param2", "!#$^&*((<>");
130 | multipartEntity.AddBody(stringBody2);
131 |
132 | HttpResponse response = client.Execute(postMethod);
133 |
134 | Assert.AreEqual(200, response.ResponseCode);
135 | string responseString = EntityUtils.ToString(response.Entity);
136 | MessageData md = new MessageData();
137 | md.PostParameters.Add(new NameValuePair("param1", "value1"));
138 | md.PostParameters.Add(new NameValuePair("param2", "!#$^&*((<>"));
139 | md.Files.Add(new NameValuePair(fileName, fi.Length.ToString()));
140 | Assert.AreEqual(md.ToString(), responseString);
141 | Assert.AreEqual(Constants.HTTP_MULTIPART_POST_200, response.RequestUri.AbsoluteUri);
142 | Console.Write(responseString);
143 | }
144 |
145 | [Test]
146 | public void HttpPostWithFilesAndParameters3()
147 | {
148 | // this method sends a file and checks for the number of bytes recieved
149 | HttpClient client = new HttpClient();
150 | string url = "http://www.fiddler2.com/sandbox/FileForm.asp";
151 | HttpPost postMethod = new HttpPost(new Uri(url));
152 |
153 | MultipartEntity multipartEntity = new MultipartEntity();
154 | postMethod.Entity = multipartEntity;
155 |
156 | string fileName = "small-text.txt";
157 |
158 | StringBody stringBody1 = new StringBody(Encoding.ASCII, "1", "1_");
159 | multipartEntity.AddBody(stringBody1);
160 |
161 | FileInfo fi = ResourceManager.GetResourceFileInfo(fileName);
162 | FileBody fileBody1 = new FileBody("fileentry", fileName, fi, "text/plain");
163 | multipartEntity.AddBody(fileBody1);
164 |
165 | StringBody stringBody2 = new StringBody(Encoding.ASCII, "_charset_", "windows-1252");
166 | multipartEntity.AddBody(stringBody2);
167 |
168 | HttpResponse response = client.Execute(postMethod);
169 |
170 | Assert.AreEqual(200, response.ResponseCode);
171 | string responseString = EntityUtils.ToString(response.Entity);
172 | Assert.AreEqual(url, response.RequestUri.AbsoluteUri);
173 | Console.Write(responseString);
174 | }
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http.Tests/resources/big-text.txt:
--------------------------------------------------------------------------------
1 | this is a test this is a test this is a test
2 | this is a test this is a test this is a test
3 | this is a test this is a test this is a test
4 | this is a test this is a test this is a test
5 | this is a test this is a test this is a test
6 | this is a test this is a test this is a test
7 | this is a test this is a test this is a test
8 | this is a test this is a test this is a test
9 | this is a test this is a test this is a test
10 | this is a test this is a test this is a test
11 | this is a test this is a test this is a test
12 | this is a test this is a test this is a test
13 | this is a test this is a test this is a test
14 | this is a test this is a test this is a test
15 | this is a test this is a test this is a test
16 | this is a test this is a test this is a test
17 | this is a test this is a test this is a test
18 | this is a test this is a test this is a test
19 | this is a test this is a test this is a test
20 | this is a test this is a test this is a test
21 | this is a test this is a test this is a test
22 | this is a test this is a test this is a test
23 | this is a test this is a test this is a test
24 | this is a test this is a test this is a test
25 | this is a test this is a test this is a test
26 | this is a test this is a test this is a test
27 | this is a test this is a test this is a test
28 | this is a test this is a test this is a test
29 | this is a test this is a test this is a test
30 | this is a test this is a test this is a test
31 | this is a test this is a test this is a test
32 | this is a test this is a test this is a test
33 | this is a test this is a test this is a test
34 | this is a test this is a test this is a test
35 | this is a test this is a test this is a test
36 | this is a test this is a test this is a test
37 | this is a test this is a test this is a test
38 | this is a test this is a test this is a test
39 | this is a test this is a test this is a test
40 | this is a test this is a test this is a test
41 | this is a test this is a test this is a test
42 | this is a test this is a test this is a test
43 | this is a test this is a test this is a test
44 | this is a test this is a test this is a test
45 | this is a test this is a test this is a test
46 | this is a test this is a test this is a test
47 | this is a test this is a test this is a test
48 | this is a test this is a test this is a test
49 | this is a test this is a test this is a test
50 | this is a test this is a test this is a test
51 | this is a test this is a test this is a test
52 | this is a test this is a test this is a test
53 | this is a test this is a test this is a test
54 | this is a test this is a test this is a test
55 | this is a test this is a test this is a test
56 | this is a test this is a test this is a test
57 | this is a test this is a test this is a test
58 | this is a test this is a test this is a test
59 | this is a test this is a test this is a test
60 | this is a test this is a test this is a test
61 | this is a test this is a test this is a test
62 | this is a test this is a test this is a test
63 | this is a test this is a test this is a test
64 | this is a test this is a test this is a test
65 | this is a test this is a test this is a test
66 | this is a test this is a test this is a test
67 | this is a test this is a test this is a test
68 | this is a test this is a test this is a test
69 | this is a test this is a test this is a test
70 | this is a test this is a test this is a test
71 | this is a test this is a test this is a test
72 | this is a test this is a test this is a test
73 | this is a test this is a test this is a test
74 | this is a test this is a test this is a test
75 | this is a test this is a test this is a test
76 | this is a test this is a test this is a test
77 | this is a test this is a test this is a test
78 | this is a test this is a test this is a test
79 | this is a test this is a test this is a test
80 | this is a test this is a test this is a test
81 | this is a test this is a test this is a test
82 | this is a test this is a test this is a test
83 | this is a test this is a test this is a test
84 | this is a test this is a test this is a test
85 | this is a test this is a test this is a test
86 | this is a test this is a test this is a test
87 | this is a test this is a test this is a test
88 | this is a test this is a test this is a test
89 | this is a test this is a test this is a test
90 | this is a test this is a test this is a test
91 | this is a test this is a test this is a test
92 | this is a test this is a test this is a test
93 | this is a test this is a test this is a test
94 | this is a test this is a test this is a test
95 | this is a test this is a test this is a test
96 | this is a test this is a test this is a test
97 | this is a test this is a test this is a test
98 | this is a test this is a test this is a test
99 | this is a test this is a test this is a test
100 | this is a test this is a test this is a test
101 | this is a test this is a test this is a test
102 | this is a test this is a test this is a test
103 | this is a test this is a test this is a test
104 | this is a test this is a test this is a test
105 | this is a test this is a test this is a test
106 | this is a test this is a test this is a test
107 | this is a test this is a test this is a test
108 | this is a test this is a test this is a test
109 | this is a test this is a test this is a test
110 | this is a test this is a test this is a test
111 | this is a test this is a test this is a test
112 | this is a test this is a test this is a test
113 | this is a test this is a test this is a test
114 | this is a test this is a test this is a test
115 | this is a test this is a test this is a test
116 | this is a test this is a test this is a test
117 | this is a test this is a test this is a test
118 | this is a test this is a test this is a test
119 | this is a test this is a test this is a test
120 | this is a test this is a test this is a test
121 | this is a test this is a test this is a test
122 | this is a test this is a test this is a test
123 | this is a test this is a test this is a test
124 | this is a test this is a test this is a test
125 | this is a test this is a test this is a test
126 | this is a test this is a test this is a test
127 | this is a test this is a test this is a test
128 | this is a test this is a test this is a test
129 | this is a test this is a test this is a test
130 | this is a test this is a test this is a test
131 | this is a test this is a test this is a test
132 | this is a test this is a test this is a test
133 | this is a test this is a test this is a test
134 | this is a test this is a test this is a test
135 | this is a test this is a test this is a test
136 | this is a test this is a test this is a test
137 | this is a test this is a test this is a test
138 | this is a test this is a test this is a test
139 | this is a test this is a test this is a test
140 | this is a test this is a test this is a test
141 | this is a test this is a test this is a test
142 | this is a test this is a test this is a test
143 | this is a test this is a test this is a test
144 | this is a test this is a test this is a test
145 | this is a test this is a test this is a test
146 | this is a test this is a test this is a test
147 | this is a test this is a test this is a test
148 | this is a test this is a test this is a test
149 | this is a test this is a test this is a test
150 | this is a test this is a test this is a test
151 | this is a test this is a test this is a test
152 | this is a test this is a test this is a test
153 | this is a test this is a test this is a test
154 | this is a test this is a test this is a test
155 | this is a test this is a test this is a test
156 | this is a test this is a test this is a test
157 | this is a test this is a test this is a test
158 | this is a test this is a test this is a test
159 | this is a test this is a test this is a test
160 | this is a test this is a test this is a test
161 | this is a test this is a test this is a test
162 | this is a test this is a test this is a test
163 | this is a test this is a test this is a test
164 | this is a test this is a test this is a test
165 | this is a test this is a test this is a test
166 | this is a test this is a test this is a test
167 | this is a test this is a test this is a test
168 | this is a test this is a test this is a test
169 | this is a test this is a test this is a test
170 | this is a test this is a test this is a test
171 | this is a test this is a test this is a test
172 | this is a test this is a test this is a test
173 | this is a test this is a test this is a test
174 | this is a test this is a test this is a test
175 | this is a test this is a test this is a test
176 | this is a test this is a test this is a test
177 | this is a test this is a test this is a test
178 | this is a test this is a test this is a test
179 | this is a test this is a test this is a test
180 | this is a test this is a test this is a test
181 | this is a test this is a test this is a test
182 | this is a test this is a test this is a test
183 | this is a test this is a test this is a test
184 | this is a test this is a test this is a test
185 | this is a test this is a test this is a test
186 | this is a test this is a test this is a test
187 | this is a test this is a test this is a test
188 | this is a test this is a test this is a test
189 | this is a test this is a test this is a test
190 | this is a test this is a test this is a test
191 | this is a test this is a test this is a test
192 | this is a test this is a test this is a test
193 | this is a test this is a test this is a test
194 | this is a test this is a test this is a test
195 | this is a test this is a test this is a test
196 | this is a test this is a test this is a test
197 | this is a test this is a test this is a test
198 | this is a test this is a test this is a test
199 | this is a test this is a test this is a test
200 | this is a test this is a test this is a test
201 | this is a test this is a test this is a test
202 | this is a test this is a test this is a test
203 | this is a test this is a test this is a test
204 | this is a test this is a test this is a test
205 | this is a test this is a test this is a test
206 | this is a test this is a test this is a test
207 | this is a test this is a test this is a test
208 | this is a test this is a test this is a test
209 | this is a test this is a test this is a test
210 | this is a test this is a test this is a test
211 | this is a test this is a test this is a test
212 | this is a test this is a test this is a test
213 | this is a test this is a test this is a test
214 | this is a test this is a test this is a test
215 | this is a test this is a test this is a test
216 | this is a test this is a test this is a test
217 | this is a test this is a test this is a test
218 | this is a test this is a test this is a test
219 | this is a test this is a test this is a test
220 | this is a test this is a test this is a test
221 | this is a test this is a test this is a test
222 | this is a test this is a test this is a test
223 | this is a test this is a test this is a test
224 | this is a test this is a test this is a test
225 | this is a test this is a test this is a test
226 | this is a test this is a test this is a test
227 | this is a test this is a test this is a test
228 | this is a test this is a test this is a test
229 | this is a test this is a test this is a test
230 | this is a test this is a test this is a test
231 | this is a test this is a test this is a test
232 | this is a test this is a test this is a test
233 | this is a test this is a test this is a test
234 | this is a test this is a test this is a test
235 | this is a test this is a test this is a test
236 | this is a test this is a test this is a test
237 | this is a test this is a test this is a test
238 | this is a test this is a test this is a test
239 | this is a test this is a test this is a test
240 | this is a test this is a test this is a test
241 | this is a test this is a test this is a test
242 | this is a test this is a test this is a test
243 | this is a test this is a test this is a test
244 | this is a test this is a test this is a test
245 | this is a test this is a test this is a test
246 | this is a test this is a test this is a test
247 | this is a test this is a test this is a test
248 | this is a test this is a test this is a test
249 | this is a test this is a test this is a test
250 | this is a test this is a test this is a test
251 | this is a test this is a test this is a test
252 | this is a test this is a test this is a test
253 | this is a test this is a test this is a test
254 | this is a test this is a test this is a test
255 | this is a test this is a test this is a test
256 | this is a test this is a test this is a test
257 | this is a test this is a test this is a test
258 | this is a test this is a test this is a test
259 | this is a test this is a test this is a test
260 | this is a test this is a test this is a test
261 | this is a test this is a test this is a test
262 | this is a test this is a test this is a test
263 | this is a test this is a test this is a test
264 | this is a test this is a test this is a test
265 | this is a test this is a test this is a test
266 | this is a test this is a test this is a test
267 | this is a test this is a test this is a test
268 |
--------------------------------------------------------------------------------
/src/CodeScales.Http/CodeScales.Http/Network/HttpConnection.cs:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2010 CodeScales.com
2 | *
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | using System;
17 | using System.Collections.Generic;
18 | using System.Text;
19 | using System.Text.RegularExpressions;
20 | using System.Net;
21 | using System.Net.Sockets;
22 | using System.Threading;
23 |
24 | using CodeScales.Http.Methods;
25 | using CodeScales.Http.Entity;
26 | using CodeScales.Http.Protocol;
27 |
28 | namespace CodeScales.Http.Network
29 | {
30 | internal class HttpConnection
31 | {
32 |
33 | private HttpConnectionFactory m_factory = null;
34 | private bool m_isBusy = false;
35 | private Socket m_socket = null;
36 | private Uri m_proxy = null;
37 | private Uri m_uri = null;
38 | private int m_timeout = 60 * 1000;
39 |
40 | internal HttpConnection(HttpConnectionFactory factory, Uri uri, Uri proxy)
41 | {
42 | this.m_factory = factory;
43 | this.m_uri = uri;
44 | this.m_proxy = proxy;
45 | }
46 |
47 | internal Uri Uri
48 | {
49 | get
50 | {
51 | return this.m_uri;
52 | }
53 | }
54 |
55 | internal Uri EndPointUri
56 | {
57 | get
58 | {
59 | if (this.m_proxy != null)
60 | {
61 | return this.m_proxy;
62 | }
63 | else
64 | {
65 | return this.m_uri;
66 | }
67 | }
68 | }
69 |
70 | internal bool IsConnected()
71 | {
72 | return (m_socket != null
73 | && m_socket.Connected);
74 | }
75 |
76 | internal void Connect()
77 | {
78 | m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
79 | IPEndPoint remoteEP = new IPEndPoint(Dns.Resolve(this.EndPointUri.Host).AddressList[0], EndPointUri.Port);
80 | m_socket.Connect(remoteEP);
81 |
82 | m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 60 * 1000);
83 | m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 60 * 1000);
84 | }
85 |
86 | public void Close()
87 | {
88 | if (m_socket != null)
89 | {
90 | m_socket.Close();
91 | }
92 | }
93 |
94 | public bool IsBusy()
95 | {
96 | return this.m_isBusy;
97 | }
98 |
99 | public void SetBusy(bool busyState)
100 | {
101 | this.m_isBusy = busyState;
102 | }
103 |
104 | public void CheckKeepAlive(HttpResponse response)
105 | {
106 | WebHeaderCollection headers = response.Headers;
107 |
108 | if ((headers[HTTP.CONN_DIRECTIVE] != null && headers[HTTP.CONN_DIRECTIVE].ToLower() == HTTP.CONN_KEEP_ALIVE) ||
109 | (headers[HTTP.PROXY_CONN_DIRECTIVE] != null && headers[HTTP.PROXY_CONN_DIRECTIVE].ToLower() == HTTP.CONN_KEEP_ALIVE))
110 | {
111 | return;
112 | }
113 | else
114 | {
115 | this.Close();
116 | }
117 | }
118 |
119 | public void SendRequestHeader(HttpRequest request)
120 | {
121 | if (!this.IsConnected())
122 | {
123 | throw new HttpNetworkException("Socket is closed or not ready");
124 | }
125 | this.m_socket.Send(Encoding.ASCII.GetBytes(GetRequestHeader(request).ToString()));
126 |
127 | int counter = 0;
128 | // wait another timeout period for the response to arrive.
129 | while (!(this.m_socket.Available > 0) && counter < (this.m_timeout / 100))
130 | {
131 | counter++;
132 | Thread.Sleep(100);
133 | }
134 | }
135 |
136 | public void SendRequestHeaderAndEntity(HttpRequest request, HttpEntity httpEntity, bool expectContinue)
137 | {
138 | if (!this.IsConnected())
139 | {
140 | throw new HttpNetworkException("Socket is closed or not ready");
141 | }
142 | byte[] header = Encoding.ASCII.GetBytes(GetRequestHeader(request).ToString());
143 | byte[] body = httpEntity.Content;
144 |
145 | // first send the headers
146 | Send(header, 0, header.Length, this.m_timeout);
147 |
148 | // then look for 100-continue response for no more than 2 seconds
149 | if (expectContinue)
150 | {
151 | // 2 seconds timeout for 100-continue
152 | WaitForDataToArriveAtSocket(2 * 1000);
153 | if (this.m_socket.Available > 0)
154 | {
155 | // now read the 100-continue response
156 | HttpResponse response = ReceiveResponseHeaders();
157 | if (response.ResponseCode != 100)
158 | {
159 | throw new HttpNetworkException("reponse returned before entity was sent, but it is not 100-continue");
160 | }
161 | }
162 | }
163 |
164 | byte[] message = body;
165 |
166 | int sendBufferSize = this.m_socket.SendBufferSize;
167 | int size = (message.Length > sendBufferSize) ? sendBufferSize : message.Length;
168 | for (int i = 0; i < message.Length; i = i + size)
169 | {
170 | int remaining = (size < (message.Length - i)) ? size : (message.Length - i);
171 | Send(message, i, remaining, this.m_timeout);
172 | }
173 |
174 | }
175 |
176 | private void WaitForDataToArriveAtSocket(int timeout)
177 | {
178 | int counter = 0;
179 | // wait another timeout period for the response to arrive.
180 | while (!(this.m_socket.Available > 0) && counter < (timeout / 100))
181 | {
182 | counter++;
183 | Thread.Sleep(100);
184 | }
185 | }
186 |
187 | private void Send(byte[] buffer, int offset, int size, int timeout)
188 | {
189 | int startTickCount = Environment.TickCount;
190 | int sent = 0; // how many bytes is already sent
191 | do
192 | {
193 | if (Environment.TickCount > startTickCount + timeout)
194 | throw new Exception("Timeout.");
195 | try
196 | {
197 | sent += this.m_socket.Send(buffer, offset + sent, size - sent, SocketFlags.None);
198 | }
199 | catch (SocketException ex)
200 | {
201 | if (ex.SocketErrorCode == SocketError.WouldBlock ||
202 | ex.SocketErrorCode == SocketError.IOPending ||
203 | ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
204 | {
205 | // socket buffer is probably full, wait and try again
206 | Thread.Sleep(30);
207 | }
208 | else
209 | throw ex; // any serious error occurr
210 | }
211 | } while (sent < size);
212 | }
213 |
214 | private StringBuilder GetRequestHeader(HttpRequest request)
215 | {
216 | StringBuilder sb = new StringBuilder();
217 | sb.AppendLine(request.GetRequestLine(this.m_proxy != null));
218 | sb.AppendLine("Host: " + this.m_uri.Host);
219 | sb.Append(request.Headers);
220 | return sb;
221 | }
222 |
223 | public HttpResponse ReceiveResponseHeaders()
224 | {
225 | if (!this.IsConnected())
226 | {
227 | throw new HttpNetworkException("Socket is closed or not ready");
228 | }
229 |
230 | WaitForDataToArriveAtSocket(this.m_timeout);
231 |
232 | HttpResponse httpResponse = new HttpResponse();
233 | httpResponse.RequestUri = this.Uri;
234 | string Header = "";
235 | WebHeaderCollection Headers = new WebHeaderCollection();
236 |
237 | byte[] bytes = new byte[10];
238 | while (this.m_socket.Receive(bytes, 0, 1, SocketFlags.None) > 0)
239 | {
240 | Header += Encoding.ASCII.GetString(bytes, 0, 1);
241 | if (bytes[0] == '\n' && Header.EndsWith("\r\n\r\n"))
242 | break;
243 | }
244 | MatchCollection matches = new Regex("[^\r\n]+").Matches(Header.TrimEnd('\r', '\n'));
245 | for (int n = 1; n < matches.Count; n++)
246 | {
247 | string[] strItem = matches[n].Value.Split(new char[] { ':' }, 2);
248 | if (strItem.Length > 1)
249 | {
250 | if (!strItem[0].Trim().ToLower().Equals("set-cookie"))
251 | {
252 | Headers.Add(strItem[0].Trim(), strItem[1].Trim());
253 | }
254 | else
255 | {
256 | Headers.Add(strItem[0].Trim(), strItem[1].Trim());
257 | // HTTPProtocol.AddHttpCookie(strItem[1].Trim(), cookieCollection);
258 | }
259 | }
260 | }
261 |
262 | httpResponse.Headers = Headers;
263 |
264 | // set the response code
265 | if (matches.Count > 0)
266 | {
267 | try
268 | {
269 | string firstLine = matches[0].Value;
270 | int index1 = firstLine.IndexOf(" ");
271 | int index2 = firstLine.IndexOf(" ", index1 + 1);
272 | httpResponse.ResponseCode = Int32.Parse(firstLine.Substring(index1 + 1, index2 - index1 - 1));
273 | }
274 | catch (Exception ex)
275 | {
276 | throw new HttpNetworkException("Response Code is missing from the response");
277 | }
278 | }
279 |
280 | return httpResponse;
281 |
282 | }
283 |
284 | public void ReceiveResponseEntity(HttpResponse response)
285 | {
286 | if (!this.IsConnected())
287 | {
288 | throw new HttpNetworkException("Socket is closed or not ready");
289 | }
290 |
291 | string chunkedHeader = EntityUtils.GetTransferEncoding(response.Headers);
292 | if (chunkedHeader != null
293 | && chunkedHeader.ToLower().Equals(HTTP.CHUNK_CODING))
294 | {
295 | List byteBuffer = new List();
296 | BasicHttpEntity httpEntity = new BasicHttpEntity();
297 | httpEntity.ContentLength = 0;
298 | httpEntity.ContentType = EntityUtils.GetContentType(response.Headers);
299 | response.Entity = httpEntity;
300 |
301 | int chunkSize = EntityUtils.ConvertHexToInt(ReceiveLine());
302 | while (chunkSize > 0)
303 | {
304 | // for each chunk...
305 | byteBuffer.AddRange(ReceiveBytes(chunkSize));
306 | httpEntity.ContentLength += chunkSize;
307 | string test = ReceiveLine();
308 | chunkSize = EntityUtils.ConvertHexToInt(ReceiveLine());
309 | }
310 |
311 | httpEntity.Content = byteBuffer.ToArray();
312 | }
313 | else
314 | {
315 | // TODO: support "Transfer-Encoding: chunked"
316 | int length = EntityUtils.GetContentLength(response.Headers);
317 | if (length > 0)
318 | {
319 | BasicHttpEntity httpEntity = new BasicHttpEntity();
320 | httpEntity.ContentLength = length;
321 | httpEntity.Content = ReceiveBytes(length).ToArray();
322 | httpEntity.ContentType = EntityUtils.GetContentType(response.Headers);
323 | response.Entity = httpEntity;
324 | }
325 | }
326 |
327 | return;
328 | }
329 |
330 | private string ReceiveLine()
331 | {
332 | WaitForDataToArriveAtSocket(this.m_timeout);
333 |
334 | string line = string.Empty;
335 | byte[] bytes = new byte[10];
336 | while (this.m_socket.Receive(bytes, 0, 1, SocketFlags.None) > 0)
337 | {
338 | line += Encoding.ASCII.GetString(bytes, 0, 1);
339 | if (bytes[0] == '\n' && line.EndsWith("\r\n"))
340 | break;
341 | }
342 | return line.Replace("\r\n","");
343 | }
344 |
345 | private List ReceiveBytes(long size)
346 | {
347 | WaitForDataToArriveAtSocket(this.m_timeout);
348 |
349 | List byteBuffer = new List();
350 | int minSize = 10240;
351 | if (size < 10240)
352 | {
353 | minSize = (int)size;
354 | }
355 | byte[] RecvBuffer = new byte[minSize];
356 | long nBytes, nTotalBytes = 0;
357 | int RecvSize = minSize;
358 |
359 | // loop to receive response buffer
360 | while ((nBytes = this.m_socket.Receive(RecvBuffer, 0, RecvSize, SocketFlags.None)) > 0)
361 | {
362 | // increment total received bytes
363 | nTotalBytes += nBytes;
364 |
365 | // add received buffer to response string
366 | if (nBytes < minSize)
367 | {
368 | byte[] smallByteArray = new byte[nBytes];
369 | for (int i = 0; i < nBytes; i++)
370 | {
371 | smallByteArray[i] = RecvBuffer[i];
372 | }
373 | byteBuffer.AddRange(smallByteArray);
374 | }
375 | else
376 | {
377 | byteBuffer.AddRange(RecvBuffer);
378 | }
379 |
380 | if (nTotalBytes >= size && size > 0)
381 | break;
382 | else
383 | {
384 | long nBytesLeft = size - nTotalBytes;
385 | if (nBytesLeft < RecvSize)
386 | {
387 | RecvSize = (int)nBytesLeft;
388 | }
389 | }
390 | }
391 | return byteBuffer;
392 | }
393 |
394 | }
395 | }
396 |
--------------------------------------------------------------------------------