]> git.mxchange.org Git - simgear.git/blob - simgear/io/httpget.cxx
Revert "Support non-blocking address lookups, and switch to getaddrinfo over gethostb...
[simgear.git] / simgear / io / httpget.cxx
1
2 #include <cstdio>
3 #include <cstring>
4
5 #include <unistd.h> // for STDOUT_FILENO
6 #include <iostream>
7 #include <boost/foreach.hpp>
8 #include <signal.h>
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     signal(SIGPIPE, SIG_IGN);
137
138     if (!outFile) {
139         outFile = new SGFile(STDOUT_FILENO);
140     }
141
142     if (url.empty()) {
143         cerr << "no URL argument specificed" << endl;
144         return EXIT_FAILURE;
145     }
146
147     ARequest* req = new ARequest(url);
148     BOOST_FOREACH(string h, headers) {
149         req->addHeader(h);
150     }
151     
152     req->setFile(outFile);
153     cl.makeRequest(req);
154     
155     while (!req->complete()) {
156         cl.update();
157         sleepForMSec(100);
158     }
159         
160     if (req->responseCode() != 200) {
161         cerr << "got response:" << req->responseCode() << endl;
162         cerr << "\treason:" << req->responseReason() << endl;
163         return EXIT_FAILURE;
164     }
165     
166     return EXIT_SUCCESS;
167 }