]> git.saurik.com Git - wxWidgets.git/blob - src/common/http.cpp
SetFont() the second
[wxWidgets.git] / src / common / http.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: http.cpp
3 // Purpose: HTTP protocol
4 // Author: Guilhem Lavaux
5 // Modified by:
6 // Created: August 1997
7 // RCS-ID: $Id$
8 // Copyright: (c) 1997, 1998 Guilhem Lavaux
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "http.h"
14 #endif
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include "wx/string.h"
19 #include "wx/tokenzr.h"
20 #include "wx/socket.h"
21 #include "wx/protocol/protocol.h"
22 #include "wx/protocol/http.h"
23 #include "wx/sckstrm.h"
24
25 #ifdef __BORLANDC__
26 #pragma hdrstop
27 #endif
28
29 #if !USE_SHARED_LIBRARY
30 IMPLEMENT_DYNAMIC_CLASS(wxHTTP, wxProtocol)
31 IMPLEMENT_PROTOCOL(wxHTTP, "http", "80", TRUE)
32 #endif
33
34 #define HTTP_BSIZE 2048
35
36 wxHTTP::wxHTTP()
37 : wxProtocol(),
38 m_headers(wxKEY_STRING)
39 {
40 m_addr = NULL;
41 m_read = FALSE;
42
43 SetNotify(REQ_LOST);
44 }
45
46 wxHTTP::~wxHTTP()
47 {
48 // wxString isn't a wxObject
49 wxNode *node = m_headers.First();
50 wxString *string;
51
52 while (node) {
53 string = (wxString *)node->Data();
54 delete string;
55 node = node->Next();
56 }
57 }
58
59 wxString wxHTTP::GetContentType()
60 {
61 return GetHeader("Content-Type");
62 }
63
64 void wxHTTP::SetHeader(const wxString& header, const wxString& h_data)
65 {
66 if (m_read) {
67 m_headers.Clear();
68 m_read = FALSE;
69 }
70
71 wxNode *node = m_headers.Find(header);
72
73 if (!node)
74 m_headers.Append(header, (wxObject *)(new wxString(h_data)));
75 else {
76 wxString *str = (wxString *)node->Data();
77 (*str) = h_data;
78 }
79 }
80
81 wxString wxHTTP::GetHeader(const wxString& header)
82 {
83 wxNode *node = m_headers.Find(header);
84 if (!node)
85 return (char *)NULL;
86
87 return *((wxString *)node->Data());
88 }
89
90 void wxHTTP::SendHeaders()
91 {
92 wxNode *head = m_headers.First();
93
94 while (head) {
95 wxString *str = (wxString *)head->Data();
96 char buf[100];
97
98 sprintf(buf, "%s: %s\n\r", head->key.string, str->GetData());
99 Write(buf, strlen(buf));
100
101 head = head->Next();
102 }
103 }
104
105 bool wxHTTP::ParseHeaders()
106 {
107 wxString line;
108
109 m_headers.Clear();
110 m_read = TRUE;
111
112 while (1) {
113 m_error = GetLine(this, line);
114 if (m_error != wxPROTO_NOERR)
115 return FALSE;
116
117 if (line.Length() == 0)
118 break;
119
120 int pos = line.Find(':');
121 if (pos == -1)
122 return FALSE;
123
124 wxString left_str = line(0, pos);
125 wxString right_str = line(pos+1, line.Length());
126
127 right_str = right_str.Strip(wxString::leading);
128
129 wxString *str = new wxString(right_str);
130
131 m_headers.Append(left_str, (wxObject *) str);
132 }
133 return TRUE;
134 }
135
136 bool wxHTTP::Connect(const wxString& host)
137 {
138 wxIPV4address *addr;
139
140 if (m_connected) {
141 delete m_addr;
142 m_addr = NULL;
143 Close();
144 }
145
146 m_addr = addr = new wxIPV4address();
147
148 if (!addr->Hostname(host)) {
149 delete m_addr;
150 m_addr = NULL;
151 m_error = wxPROTO_NETERR;
152 return FALSE;
153 }
154
155 if (!addr->Service("http"))
156 addr->Service(80);
157
158 return TRUE;
159 }
160
161 bool wxHTTP::Connect(wxSockAddress& addr)
162 {
163 struct sockaddr *raw_addr;
164 size_t len;
165
166 m_addr = (wxSockAddress *)(addr.GetClassInfo()->CreateObject());
167
168 addr.Build(raw_addr, len);
169 m_addr->Disassemble(raw_addr, len);
170
171 return TRUE;
172 }
173
174 bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req)
175 {
176 char *tmp_buf;
177 char buf[HTTP_BSIZE];
178
179 switch (req) {
180 case wxHTTP_GET:
181 tmp_buf = "GET";
182 break;
183 default:
184 return FALSE;
185 }
186
187 sprintf(buf, "%s %s HTTP/1.0\n\r", tmp_buf, (const char *)path);
188 Write(buf, strlen(buf));
189 SendHeaders();
190 sprintf(buf, "\n\r");
191 Write(buf, strlen(buf));
192
193 wxString tmp_str;
194
195 m_error = GetLine(this, tmp_str);
196 if (m_error != wxPROTO_NOERR)
197 return FALSE;
198
199 if (!tmp_str.Contains("HTTP/")) {
200 // TODO: support HTTP v0.9 which can have no header.
201 SetHeader("Content-Length", "-1");
202 SetHeader("Content-Type", "none/none");
203 return TRUE;
204 }
205
206 wxStringTokenizer token(tmp_str,' ');
207 wxString tmp_str2;
208
209 token.NextToken();
210 tmp_str2 = token.NextToken();
211
212 switch (atoi(tmp_str2)) {
213 case 200:
214 break;
215 default:
216 m_error = wxPROTO_NOFILE;
217 return FALSE;
218 }
219
220 return ParseHeaders();
221 }
222
223 class wxHTTPStream : public wxSocketInputStream {
224 public:
225 wxHTTP *m_http;
226 wxHTTPStream(wxHTTP *http) : wxSocketInputStream(*http), m_http(http) {}
227 virtual ~wxHTTPStream(void) { m_http->Abort(); }
228 };
229
230 bool wxHTTP::Abort(void)
231 {
232 return wxSocketClient::Close();
233 }
234
235 wxInputStream *wxHTTP::GetInputStream(const wxString& path)
236 {
237 wxHTTPStream *inp_stream = new wxHTTPStream(this);
238
239 if (!m_addr || m_connected) {
240 m_error = wxPROTO_CONNERR;
241 return NULL;
242 }
243
244 if (!wxProtocol::Connect(*m_addr))
245 return NULL;
246
247 if (!BuildRequest(path, wxHTTP_GET))
248 return NULL;
249
250 return inp_stream;
251 }