summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2006-11-02 08:49:42 +0000
committerMike Buland <eichlan@xagasoft.com>2006-11-02 08:49:42 +0000
commit54ef2750aef0c64df56daff50af7719f85017c33 (patch)
tree698355d5d8522671c66d40164695ed8f9fa4691f /src
parentd1e486136db52b466b788c1d81a5c88b6f24acd9 (diff)
downloadlibbu++-54ef2750aef0c64df56daff50af7719f85017c33.tar.gz
libbu++-54ef2750aef0c64df56daff50af7719f85017c33.tar.bz2
libbu++-54ef2750aef0c64df56daff50af7719f85017c33.tar.xz
libbu++-54ef2750aef0c64df56daff50af7719f85017c33.zip
Moved HttpGet in from eubit. It's pretty cool, just give it a url, and it gives
you a Stream contianing the web server's response. Right now it doesn't parse any headers or anything.
Diffstat (limited to 'src')
-rw-r--r--src/httpget.cpp181
-rw-r--r--src/httpget.h44
2 files changed, 225 insertions, 0 deletions
diff --git a/src/httpget.cpp b/src/httpget.cpp
new file mode 100644
index 0000000..6317403
--- /dev/null
+++ b/src/httpget.cpp
@@ -0,0 +1,181 @@
1#include "httpget.h"
2#include "exceptionbase.h"
3#include "connection.h"
4#include <stdio.h>
5
6char HttpGet::hexcode[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
7
8HttpGet::HttpGet() :
9 nPort( 80 ),
10 sUserAgent("libbu++; HttpGet")
11{
12}
13
14HttpGet::HttpGet( const std::string &url ) :
15 nPort( 80 )
16{
17 setURL( url );
18}
19
20HttpGet::~HttpGet()
21{
22}
23
24void HttpGet::setURL( const std::string &url )
25{
26 int len = url.size();
27 printf("Full URL: %s\n", url.c_str() );
28 int pos = url.find("://");
29 sProto.assign( url, 0, pos );
30 printf("Protocol: %s\n", sProto.c_str() );
31
32 int pos2 = url.find("/", pos+3 );
33 if( pos2 >= 0 )
34 {
35 sHost.assign( url, pos+3, pos2-pos-3 );
36 }
37 else
38 {
39 sHost.assign( url, pos+3, std::string::npos );
40 }
41
42 int pos3 = sHost.find(":");
43 if( pos3 >= 0 )
44 {
45 nPort = strtol( sHost.c_str()+pos3+1, NULL, 10 );
46 sHost.erase( pos3 );
47 }
48 printf("Hostname: %s\n", sHost.c_str() );
49 printf("Port: %d\n", nPort );
50
51 pos3 = url.find("?", pos2+1 );
52 if( pos3 >= 0 )
53 {
54 sPath.assign( url, pos2, pos3-pos2 );
55 printf("Path: %s\n", sPath.c_str() );
56 for(;;)
57 {
58 int end = pos3+1;
59 for(; url[end] != '=' && url[end] != '&' && end < len; end++ );
60 std::string sKey, sValue;
61 sKey.assign( url, pos3+1, end-pos3-1 );
62 if( url[end] == '=' )
63 {
64 pos3 = end;
65 for( end++; url[end] != '&' && end < len; end++ );
66 sValue.assign( url, pos3+1, end-pos3-1 );
67 pos3 = end;
68 }
69 else
70 {
71 }
72 lParams.push_back( StringPair( sKey, sValue ) );
73 printf("Param: %s = %s\n", sKey.c_str(), sValue.c_str() );
74 if( end+1 >= len ) break;
75 }
76 }
77 else
78 {
79 sPath.assign( url, pos2, std::string::npos );
80 printf("Path: %s\n", sPath.c_str() );
81 }
82
83 printf("\n");
84}
85
86void HttpGet::addParam( const std::string &key, const std::string &value )
87{
88 lParams.push_back( StringPair( key, value ) );
89}
90
91std::string HttpGet::escape( const std::string &src )
92{
93 std::string escaped("");
94 for( std::string::const_iterator i = src.begin(); i != src.end(); i++ )
95 {
96 unsigned char j = *i;
97 if( (j >= '0' && j <= '9') ||
98 (j >= 'a' && j <= 'z') ||
99 (j >= 'A' && j <= 'Z') ||
100 j == '$' ||
101 j == '-' ||
102 j == '_' ||
103 j == '.' ||
104 j == '+' ||
105 j == '!' ||
106 j == '*' ||
107 j == '\'' ||
108 j == '(' ||
109 j == ')' )
110 {
111 escaped += j;
112 }
113 else
114 {
115 escaped += "%";
116 escaped += hexcode[j>>4];
117 escaped += hexcode[j&0x0F];
118 }
119 }
120
121 return escaped;
122}
123
124SBuffer *HttpGet::get()
125{
126 std::string sData;
127 sData = "GET " + sPath;
128 if( !lParams.empty() )
129 {
130 sData += "?";
131 for( std::list<StringPair>::iterator i = lParams.begin();
132 i != lParams.end(); i++ )
133 {
134 if( i != lParams.begin() )
135 sData += "&";
136
137 if( (*i).second == "" )
138 {
139 sData += escape( (*i).first );
140 }
141 else
142 {
143 sData += escape( (*i).first );
144 sData += "=";
145 sData += escape( (*i).second );
146 }
147 }
148 }
149
150 sData += " HTTP/1.1\r\n"
151 "User-Agent: " + sUserAgent + "\r\n"
152 "Connection: close\r\n"
153 "Host: " + sHost + "\r\n"
154 "Content-type: application/x-www-form-urlencoded\r\n\r\n";
155
156 printf("Connection content:\n\n%s\n\n", sData.c_str() );
157
158 Connection con;
159 con.open( "127.0.0.1", nPort );
160 con.appendOutput( sData.c_str(), sData.size() );
161 con.writeOutput();
162 while( con.readInput() );
163
164 int total = con.getInputAmnt();
165 const char *dat = con.getInput();
166 for( int i = 0; i < total; i++ )
167 {
168 if( !memcmp( dat+i, "\r\n\r\n", 4 ) )
169 {
170 SBuffer *buf = new SBuffer;
171 buf->write( dat+i+4, total-i-4 );
172 buf->setPos( 0 );
173 con.close();
174 return buf;
175 }
176 }
177 con.close();
178
179 throw ExceptionBase("Something went wrong, incomplete response? fix this.\n");
180}
181
diff --git a/src/httpget.h b/src/httpget.h
new file mode 100644
index 0000000..afa1ec5
--- /dev/null
+++ b/src/httpget.h
@@ -0,0 +1,44 @@
1#ifndef HTTP_GET_H
2#define HTTP_GET_H
3
4#include <stdint.h>
5#include <string>
6#include <list>
7#include <utility>
8
9#include "sbuffer.h"
10
11class HttpGet
12{
13public:
14 HttpGet();
15 HttpGet( const std::string &url );
16 virtual ~HttpGet();
17
18 void setURL( const std::string &url );
19 void addParam( const std::string &key, const std::string &value );
20 void setUserAgent( const std::string &sUserAgent )
21 {
22 this->sUserAgent = sUserAgent;
23 }
24 void setHost( const std::string &sHost )
25 {
26 this->sHost = sHost;
27 }
28
29 std::string escape( const std::string &src );
30 SBuffer *get();
31
32private:
33 std::string sProto;
34 std::string sHost;
35 std::string sPath;
36 std::string sUserAgent;
37 typedef std::pair<std::string,std::string> StringPair;
38 std::list<StringPair> lParams;
39 int nPort;
40 static char hexcode[];
41
42};
43
44#endif