Fix URL parsing of HTTP inputs with no port.
[cubemap] / input.cpp
1 #include <stddef.h>
2 #include <string>
3
4 #include "httpinput.h"
5 #include "input.h"
6 #include "state.pb.h"
7 #include "udpinput.h"
8
9 using namespace std;
10
11 // Extremely rudimentary URL parsing.
12 bool parse_url(const string &url, string *protocol, string *host, string *port, string *path)
13 {
14         size_t split = url.find("://");
15         if (split == string::npos) {
16                 return false;
17         }
18         *protocol = string(url.begin(), url.begin() + split);
19
20         string rest = string(url.begin() + split + 3, url.end());
21         split = rest.find_first_of(":/");
22         if (split == string::npos) {
23                 // http://foo
24                 *host = rest;
25                 *port = *protocol;
26                 *path = "/";
27                 return true;
28         }
29
30         *host = string(rest.begin(), rest.begin() + split);
31         char ch = rest[split];  // Colon or slash.
32         rest = string(rest.begin() + split + 1, rest.end());
33
34         if (ch == ':') {
35                 // Parse the port.
36                 split = rest.find_first_of('/');
37                 if (split == string::npos) {
38                         // http://foo:1234
39                         *port = rest;
40                         *path = "/";
41                         return true;
42                 } else {
43                         // http://foo:1234/bar
44                         *port = string(rest.begin(), rest.begin() + split);
45                         *path = string(rest.begin() + split, rest.end());
46                         return true;
47                 }
48         }
49
50         // http://foo/bar
51         *port = *protocol;
52         *path = "/" + rest;
53         return true;
54 }
55
56 Input *create_input(const std::string &url)
57 {
58         string protocol, host, port, path;
59         if (!parse_url(url, &protocol, &host, &port, &path)) {
60                 return NULL;
61         }
62         if (protocol == "http") {
63                 return new HTTPInput(url);
64         }
65         if (protocol == "udp") {
66                 return new UDPInput(url);
67         }
68         return NULL;
69 }
70
71 Input *create_input(const InputProto &serialized)
72 {
73         string protocol, host, port, path;
74         if (!parse_url(serialized.url(), &protocol, &host, &port, &path)) {
75                 return NULL;
76         }
77         if (protocol == "http") {
78                 return new HTTPInput(serialized);
79         }
80         if (protocol == "udp") {
81                 return new UDPInput(serialized);
82         }
83         return NULL;
84 }
85
86 Input::~Input() {}
87