blob: 2ec4b28e7c0a510d642d45d6a65f3e19407101db [file] [log] [blame]
Christian Lavoieafc6d8f2011-02-20 02:39:19 +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
20package thrift
21
22import (
23 "bytes"
24 "http"
25 "os"
Bryan Duxburyb7bd5622011-07-13 17:58:05 +000026 "strconv"
Jake Farrell7e3b8662011-09-19 23:38:39 +000027 "url"
Christian Lavoieafc6d8f2011-02-20 02:39:19 +000028)
29
30
31type THttpClient struct {
32 response *http.Response
Jake Farrell7e3b8662011-09-19 23:38:39 +000033 url *url.URL
Christian Lavoieafc6d8f2011-02-20 02:39:19 +000034 requestBuffer *bytes.Buffer
35 nsecConnectTimeout int64
36 nsecReadTimeout int64
37}
38
39type THttpClientTransportFactory struct {
40 url string
41 isPost bool
42}
43
44func (p *THttpClientTransportFactory) GetTransport(trans TTransport) TTransport {
45 if trans != nil {
46 t, ok := trans.(*THttpClient)
47 if ok && t.url != nil {
48 if t.requestBuffer != nil {
49 t2, _ := NewTHttpPostClient(t.url.String())
50 return t2
51 }
52 t2, _ := NewTHttpClient(t.url.String())
53 return t2
54 }
55 }
56 if p.isPost {
57 s, _ := NewTHttpPostClient(p.url)
58 return s
59 }
60 s, _ := NewTHttpClient(p.url)
61 return s
62}
63
64func NewTHttpClientTransportFactory(url string) *THttpClientTransportFactory {
65 return &THttpClientTransportFactory{url: url, isPost: false}
66}
67
68func NewTHttpPostClientTransportFactory(url string) *THttpClientTransportFactory {
69 return &THttpClientTransportFactory{url: url, isPost: true}
70}
71
72
Jake Farrell7e3b8662011-09-19 23:38:39 +000073func NewTHttpClient(urlstr string) (TTransport, os.Error) {
74 parsedURL, err := url.Parse(urlstr)
Christian Lavoieafc6d8f2011-02-20 02:39:19 +000075 if err != nil {
76 return nil, err
77 }
Jake Farrell7e3b8662011-09-19 23:38:39 +000078 response, err := http.Get(urlstr)
Christian Lavoieafc6d8f2011-02-20 02:39:19 +000079 if err != nil {
80 return nil, err
81 }
82 return &THttpClient{response: response, url: parsedURL}, nil
83}
84
Jake Farrell7e3b8662011-09-19 23:38:39 +000085func NewTHttpPostClient(urlstr string) (TTransport, os.Error) {
86 parsedURL, err := url.Parse(urlstr)
Christian Lavoieafc6d8f2011-02-20 02:39:19 +000087 if err != nil {
88 return nil, err
89 }
90 buf := make([]byte, 0, 1024)
91 return &THttpClient{url: parsedURL, requestBuffer: bytes.NewBuffer(buf)}, nil
92}
93
94func (p *THttpClient) Open() os.Error {
95 // do nothing
96 return nil
97}
98
99func (p *THttpClient) IsOpen() bool {
100 return p.response != nil || p.requestBuffer != nil
101}
102
103func (p *THttpClient) Peek() bool {
104 return p.IsOpen()
105}
106
107func (p *THttpClient) Close() os.Error {
108 if p.response != nil && p.response.Body != nil {
109 err := p.response.Body.Close()
110 p.response = nil
111 return err
112 }
113 if p.requestBuffer != nil {
114 p.requestBuffer.Reset()
115 p.requestBuffer = nil
116 }
117 return nil
118}
119
120func (p *THttpClient) Read(buf []byte) (int, os.Error) {
121 if p.response == nil {
122 return 0, NewTTransportException(NOT_OPEN, "Response buffer is empty, no request.")
123 }
124 n, err := p.response.Body.Read(buf)
125 return n, NewTTransportExceptionFromOsError(err)
126}
127
128func (p *THttpClient) ReadAll(buf []byte) (int, os.Error) {
129 return ReadAllTransport(p, buf)
130}
131
132func (p *THttpClient) Write(buf []byte) (int, os.Error) {
133 n, err := p.requestBuffer.Write(buf)
134 return n, err
135}
136
137func (p *THttpClient) Flush() os.Error {
138 response, err := http.Post(p.url.String(), "application/x-thrift", p.requestBuffer)
139 if err != nil {
140 return NewTTransportExceptionFromOsError(err)
141 }
142 if response.StatusCode != http.StatusOK {
143 // TODO(pomack) log bad response
Bryan Duxburyb7bd5622011-07-13 17:58:05 +0000144 return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "HTTP Response code: "+ strconv.Itoa(response.StatusCode))
Christian Lavoieafc6d8f2011-02-20 02:39:19 +0000145 }
146 p.response = response
147 return nil
148}