From 623594749c76f65bf964a5dc517128f207d25b42 Mon Sep 17 00:00:00 2001 From: Bryan Duxbury Date: Thu, 24 Jun 2010 20:34:34 +0000 Subject: [PATCH] THRIFT-160. csharp: Created THttpTransport for the C# library based on WebHttpRequest This patch adds a new THttpTransport to the C# library and adds some related changes to the Makefile and csproj. Patch: Michael Greene and Todd Gardner git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@957708 13f79535-47bb-0310-9956-ffa450edef68 --- lib/csharp/Makefile.am | 1 + lib/csharp/src/Thrift.csproj | 1 + lib/csharp/src/Transport/THttpClient.cs | 182 ++++++++++++++++++++++++ test/csharp/ThriftTest/TestClient.cs | 18 ++- 4 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 lib/csharp/src/Transport/THttpClient.cs diff --git a/lib/csharp/Makefile.am b/lib/csharp/Makefile.am index 039db744..d8a007be 100644 --- a/lib/csharp/Makefile.am +++ b/lib/csharp/Makefile.am @@ -46,6 +46,7 @@ THRIFTCODE= \ src/Transport/TServerTransport.cs \ src/Transport/TServerSocket.cs \ src/Transport/TTransportFactory.cs \ + src/Transport/THttpClient.cs \ src/TProcessor.cs \ src/TApplicationException.cs diff --git a/lib/csharp/src/Thrift.csproj b/lib/csharp/src/Thrift.csproj index b7e21088..7cc13584 100644 --- a/lib/csharp/src/Thrift.csproj +++ b/lib/csharp/src/Thrift.csproj @@ -59,6 +59,7 @@ + diff --git a/lib/csharp/src/Transport/THttpClient.cs b/lib/csharp/src/Transport/THttpClient.cs new file mode 100644 index 00000000..d5d4abc2 --- /dev/null +++ b/lib/csharp/src/Transport/THttpClient.cs @@ -0,0 +1,182 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; + +namespace Thrift.Transport +{ + public class THttpClient : TTransport + { + private readonly Uri uri; + private Stream inputStream; + private MemoryStream outputStream = new MemoryStream(); + private int connectTimeout = 0; + private int readTimeout = 0; + private IDictionary customHeaders = new Dictionary(); + + public THttpClient(Uri u) + { + uri = u; + } + + public int ConnectTimeout + { + set + { + connectTimeout = value; + } + } + + public int ReadTimeout + { + set + { + readTimeout = value; + } + } + + public IDictionary CustomHeaders + { + get + { + return customHeaders; + } + } + + public override bool IsOpen + { + get + { + return true; + } + } + + public override void Open() + { + } + + public override void Close() + { + if (inputStream != null) + { + inputStream.Close(); + inputStream = null; + } + if (outputStream != null) + { + outputStream.Close(); + outputStream = null; + } + } + + public override int Read(byte[] buf, int off, int len) + { + if (inputStream == null) + { + throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No request has been sent"); + } + + try + { + int ret = inputStream.Read(buf, off, len); + + if (ret == -1) + { + throw new TTransportException(TTransportException.ExceptionType.EndOfFile, "No more data available"); + } + + return ret; + } + catch (IOException iox) + { + throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString()); + } + } + + public override void Write(byte[] buf, int off, int len) + { + outputStream.Write(buf, off, len); + } + + public override void Flush() + { + SendRequest(); + outputStream = new MemoryStream(); + } + + private void SendRequest() + { + try + { + HttpWebRequest connection = CreateRequest(); + + byte[] data = outputStream.ToArray(); + connection.ContentLength = data.Length; + + Stream requestStream = connection.GetRequestStream(); + requestStream.Write(data, 0, data.Length); + inputStream = connection.GetResponse().GetResponseStream(); + } + catch (IOException iox) + { + throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString()); + } + catch (WebException wx) + { + throw new TTransportException(TTransportException.ExceptionType.Unknown, "Couldn't connect to server: " + wx); + } + } + + private HttpWebRequest CreateRequest() + { + HttpWebRequest connection = (HttpWebRequest)WebRequest.Create(uri); + + if (connectTimeout > 0) + { + connection.Timeout = connectTimeout; + } + if (readTimeout > 0) + { + connection.ReadWriteTimeout = readTimeout; + } + + // Make the request + connection.ContentType = "application/x-thrift"; + connection.Accept = "application/x-thrift"; + connection.UserAgent = "C#/THttpClient"; + connection.Method = "POST"; + connection.ProtocolVersion = HttpVersion.Version10; + + //add custom headers here + foreach (KeyValuePair item in customHeaders) + { + connection.Headers.Add(item.Key, item.Value); + } + + connection.Proxy = null; + + return connection; + } + } +} diff --git a/test/csharp/ThriftTest/TestClient.cs b/test/csharp/ThriftTest/TestClient.cs index 2d278b7f..1d7c75ea 100644 --- a/test/csharp/ThriftTest/TestClient.cs +++ b/test/csharp/ThriftTest/TestClient.cs @@ -87,15 +87,23 @@ namespace Test { Thread t = new Thread(new ParameterizedThreadStart(ClientThread)); threads[test] = t; - TSocket socket = new TSocket(host, port); - if (buffered) + if (url == null) { - TBufferedTransport buffer = new TBufferedTransport(socket); - t.Start(buffer); + TSocket socket = new TSocket(host, port); + if (buffered) + { + TBufferedTransport buffer = new TBufferedTransport(socket); + t.Start(buffer); + } + else + { + t.Start(socket); + } } else { - t.Start(socket); + THttpClient http = new THttpClient(new Uri(url)); + t.Start(http); } } -- 2.17.1