]> git.mxchange.org Git - simgear.git/blob - simgear/io/httpget.cxx
Unit test for SGBinObj, and fix a bug in large-indice handling the test revealed.
[simgear.git] / simgear / io / httpget.cxx
1
2 #include <cstdio>
3 #include <cstring>
4 #include <signal.h>
5
6 #include <iostream>
7 #include <boost/foreach.hpp>
8
9
10 #include <simgear/io/sg_file.hxx>
11 #include <simgear/io/HTTPClient.hxx>
12 #include <simgear/io/HTTPRequest.hxx>
13 #include <simgear/io/sg_netChannel.hxx>
14 #include <simgear/misc/strutils.hxx>
15 #include <simgear/misc/sg_sleep.hxx>
16
17 using namespace simgear;
18 using std::cout;
19 using std::endl;
20 using std::cerr;
21 using std::string;
22
23 class ARequest : public HTTP::Request
24 {
25 public:
26     ARequest(string& url) :
27         Request(url),
28         _complete(false),
29         _file(NULL)
30     {
31         
32     }
33     
34     void setFile(SGFile* f)
35     {
36         _file = f;
37     }
38     
39     bool complete() const
40         { return _complete; }
41         
42     void addHeader(const string& h)
43     {
44         int colonPos = h.find(':');
45         if (colonPos < 0) {
46             cerr << "malformed header: " << h << endl;
47             return;
48         }
49         
50         string key = h.substr(0, colonPos);
51         _headers[key] = h.substr(colonPos + 1);
52     }
53     
54     virtual string_list requestHeaders() const
55     {
56         string_list r;
57         std::map<string, string>::const_iterator it;
58         for (it = _headers.begin(); it != _headers.end(); ++it) {
59             r.push_back(it->first);
60         }
61         
62         return r;
63     }
64     
65     virtual string header(const string& name) const
66     {
67         std::map<string, string>::const_iterator it = _headers.find(name);
68         if (it == _headers.end()) {
69             return string();
70         }
71         
72         return it->second;
73     }
74 protected:
75     virtual void responseHeadersComplete()
76     {
77     }
78
79     virtual void responseComplete()
80     {
81         _complete = true;
82     }  
83
84     virtual void gotBodyData(const char* s, int n)
85     {
86         _file->write(s, n);
87     }
88 private:    
89     bool _complete;
90     SGFile* _file;
91     std::map<string, string> _headers;
92 };
93
94 int main(int argc, char* argv[])
95 {
96     HTTP::Client cl;
97     SGFile* outFile;
98     string proxy, proxyAuth;
99     string_list headers;
100     string url;
101     
102     for (int a=0; a<argc;++a) {
103         if (argv[a][0] == '-') {
104             if (!strcmp(argv[a], "--user-agent")) {
105                 cl.setUserAgent(argv[++a]);
106             } else if (!strcmp(argv[a], "--proxy")) {
107                 proxy = argv[++a];
108             } else if (!strcmp(argv[a], "--auth")) {
109                 proxyAuth = argv[++a];
110             } else if (!strcmp(argv[a], "-f") || !strcmp(argv[a], "--file")) {
111                 outFile = new SGFile(argv[++a]);
112                 if (!outFile->open(SG_IO_OUT)) {
113                     cerr << "failed to open output for writing:" << outFile->get_file_name() << endl;
114                     return EXIT_FAILURE;
115                 }
116             } else if (!strcmp(argv[a], "--header")) {
117                 headers.push_back(argv[++a]);
118             }
119         } else { // of argument starts with a hyphen
120             url = argv[a];
121         }
122     } // of arguments iteration
123
124     if (!proxy.empty()) {
125         int colonPos = proxy.find(':');
126         string proxyHost = proxy;
127         int proxyPort = 8800;
128         if (colonPos >= 0) {
129             proxyHost = proxy.substr(0, colonPos);
130             proxyPort = strutils::to_int(proxy.substr(colonPos + 1));
131         }
132         
133         cl.setProxy(proxyHost, proxyPort, proxyAuth);
134     }
135
136 #ifndef WIN32
137     signal(SIGPIPE, SIG_IGN);
138 #endif
139
140     if (!outFile) {
141         outFile = new SGFile(fileno(stdout));
142     }
143
144     if (url.empty()) {
145         cerr << "no URL argument specificed" << endl;
146         return EXIT_FAILURE;
147     }
148
149     ARequest* req = new ARequest(url);
150     BOOST_FOREACH(string h, headers) {
151         req->addHeader(h);
152     }
153     
154     req->setFile(outFile);
155     cl.makeRequest(req);
156     
157     while (!req->complete()) {
158         cl.update();
159         sleepForMSec(100);
160     }
161         
162     if (req->responseCode() != 200) {
163         cerr << "got response:" << req->responseCode() << endl;
164         cerr << "\treason:" << req->responseReason() << endl;
165         return EXIT_FAILURE;
166     }
167     
168     return EXIT_SUCCESS;
169 }