blob: d5d4abc28306924e6286ae7f08fcb81969a6ee19 [file] [log] [blame]
Bryan Duxbury62359472010-06-24 20:34:34 +00001/**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *
19 *
20 */
21
22using System;
23using System.Collections.Generic;
24using System.IO;
25using System.Net;
26
27namespace Thrift.Transport
28{
29 public class THttpClient : TTransport
30 {
31 private readonly Uri uri;
32 private Stream inputStream;
33 private MemoryStream outputStream = new MemoryStream();
34 private int connectTimeout = 0;
35 private int readTimeout = 0;
36 private IDictionary<String, String> customHeaders = new Dictionary<string, string>();
37
38 public THttpClient(Uri u)
39 {
40 uri = u;
41 }
42
43 public int ConnectTimeout
44 {
45 set
46 {
47 connectTimeout = value;
48 }
49 }
50
51 public int ReadTimeout
52 {
53 set
54 {
55 readTimeout = value;
56 }
57 }
58
59 public IDictionary<String, String> CustomHeaders
60 {
61 get
62 {
63 return customHeaders;
64 }
65 }
66
67 public override bool IsOpen
68 {
69 get
70 {
71 return true;
72 }
73 }
74
75 public override void Open()
76 {
77 }
78
79 public override void Close()
80 {
81 if (inputStream != null)
82 {
83 inputStream.Close();
84 inputStream = null;
85 }
86 if (outputStream != null)
87 {
88 outputStream.Close();
89 outputStream = null;
90 }
91 }
92
93 public override int Read(byte[] buf, int off, int len)
94 {
95 if (inputStream == null)
96 {
97 throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No request has been sent");
98 }
99
100 try
101 {
102 int ret = inputStream.Read(buf, off, len);
103
104 if (ret == -1)
105 {
106 throw new TTransportException(TTransportException.ExceptionType.EndOfFile, "No more data available");
107 }
108
109 return ret;
110 }
111 catch (IOException iox)
112 {
113 throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString());
114 }
115 }
116
117 public override void Write(byte[] buf, int off, int len)
118 {
119 outputStream.Write(buf, off, len);
120 }
121
122 public override void Flush()
123 {
124 SendRequest();
125 outputStream = new MemoryStream();
126 }
127
128 private void SendRequest()
129 {
130 try
131 {
132 HttpWebRequest connection = CreateRequest();
133
134 byte[] data = outputStream.ToArray();
135 connection.ContentLength = data.Length;
136
137 Stream requestStream = connection.GetRequestStream();
138 requestStream.Write(data, 0, data.Length);
139 inputStream = connection.GetResponse().GetResponseStream();
140 }
141 catch (IOException iox)
142 {
143 throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString());
144 }
145 catch (WebException wx)
146 {
147 throw new TTransportException(TTransportException.ExceptionType.Unknown, "Couldn't connect to server: " + wx);
148 }
149 }
150
151 private HttpWebRequest CreateRequest()
152 {
153 HttpWebRequest connection = (HttpWebRequest)WebRequest.Create(uri);
154
155 if (connectTimeout > 0)
156 {
157 connection.Timeout = connectTimeout;
158 }
159 if (readTimeout > 0)
160 {
161 connection.ReadWriteTimeout = readTimeout;
162 }
163
164 // Make the request
165 connection.ContentType = "application/x-thrift";
166 connection.Accept = "application/x-thrift";
167 connection.UserAgent = "C#/THttpClient";
168 connection.Method = "POST";
169 connection.ProtocolVersion = HttpVersion.Version10;
170
171 //add custom headers here
172 foreach (KeyValuePair<string, string> item in customHeaders)
173 {
174 connection.Headers.Add(item.Key, item.Value);
175 }
176
177 connection.Proxy = null;
178
179 return connection;
180 }
181 }
182}