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