WPILibC++  2018.4.1-20180729124724-1140-gcbb62fb
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
HttpUtil.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #ifndef WPIUTIL_WPI_HTTPUTIL_H_
9 #define WPIUTIL_WPI_HTTPUTIL_H_
10 
11 #include <memory>
12 #include <string>
13 #include <utility>
14 #include <vector>
15 
16 #include "wpi/ArrayRef.h"
17 #include "wpi/NetworkStream.h"
18 #include "wpi/SmallString.h"
19 #include "wpi/SmallVector.h"
20 #include "wpi/StringMap.h"
21 #include "wpi/StringRef.h"
22 #include "wpi/Twine.h"
23 #include "wpi/raw_istream.h"
24 #include "wpi/raw_socket_istream.h"
25 #include "wpi/raw_socket_ostream.h"
26 
27 namespace wpi {
28 
29 // Unescape a %xx-encoded URI.
30 // @param buf Buffer for output
31 // @param error Set to true if an error occurred
32 // @return Escaped string
33 StringRef UnescapeURI(const Twine& str, SmallVectorImpl<char>& buf,
34  bool* error);
35 
36 // Escape a string with %xx-encoding.
37 // @param buf Buffer for output
38 // @param spacePlus If true, encodes spaces to '+' rather than "%20"
39 // @return Escaped string
40 StringRef EscapeURI(const Twine& str, SmallVectorImpl<char>& buf,
41  bool spacePlus = true);
42 
43 // Parse a set of HTTP headers. Saves just the Content-Type and Content-Length
44 // fields.
45 // @param is Input stream
46 // @param contentType If not null, Content-Type contents are saved here.
47 // @param contentLength If not null, Content-Length contents are saved here.
48 // @return False if error occurred in input stream
49 bool ParseHttpHeaders(raw_istream& is, SmallVectorImpl<char>* contentType,
50  SmallVectorImpl<char>* contentLength);
51 
52 // Look for a MIME multi-part boundary. On return, the input stream will
53 // be located at the character following the boundary (usually "\r\n").
54 // @param is Input stream
55 // @param boundary Boundary string to scan for (not including "--" prefix)
56 // @param saveBuf If not null, all scanned characters up to but not including
57 // the boundary are saved to this string
58 // @return False if error occurred on input stream, true if boundary found.
59 bool FindMultipartBoundary(wpi::raw_istream& is, StringRef boundary,
60  std::string* saveBuf);
61 
62 class HttpLocation {
63  public:
64  HttpLocation() = default;
65  HttpLocation(const Twine& url_, bool* error, std::string* errorMsg);
66 
67  std::string url; // retain copy
68  std::string user; // unescaped
69  std::string password; // unescaped
70  std::string host;
71  int port;
72  std::string path; // escaped, not including leading '/'
73  std::vector<std::pair<std::string, std::string>> params; // unescaped
74  std::string fragment;
75 };
76 
77 class HttpRequest {
78  public:
79  HttpRequest() = default;
80 
81  explicit HttpRequest(const HttpLocation& loc)
82  : host{loc.host}, port{loc.port} {
83  SetPath(loc.path, loc.params);
84  SetAuth(loc);
85  }
86 
87  template <typename T>
88  HttpRequest(const HttpLocation& loc, const T& extraParams);
89 
90  HttpRequest(const HttpLocation& loc, StringRef path_)
91  : host{loc.host}, port{loc.port}, path{path_} {
92  SetAuth(loc);
93  }
94 
95  template <typename T>
96  HttpRequest(const HttpLocation& loc, StringRef path_, const T& params)
97  : host{loc.host}, port{loc.port} {
98  SetPath(path_, params);
99  SetAuth(loc);
100  }
101 
102  SmallString<128> host;
103  int port;
104  std::string auth;
105  SmallString<128> path;
106 
107  private:
108  void SetAuth(const HttpLocation& loc);
109  template <typename T>
110  void SetPath(StringRef path_, const T& params);
111 
112  template <typename T>
113  static StringRef GetFirst(const T& elem) {
114  return elem.first;
115  }
116  template <typename T>
117  static StringRef GetFirst(const StringMapEntry<T>& elem) {
118  return elem.getKey();
119  }
120  template <typename T>
121  static StringRef GetSecond(const T& elem) {
122  return elem.second;
123  }
124 };
125 
127  public:
128  HttpConnection(std::unique_ptr<wpi::NetworkStream> stream_, int timeout)
129  : stream{std::move(stream_)}, is{*stream, timeout}, os{*stream, true} {}
130 
131  bool Handshake(const HttpRequest& request, std::string* warnMsg);
132 
133  std::unique_ptr<wpi::NetworkStream> stream;
136 
137  // Valid after Handshake() is successful
138  SmallString<64> contentType;
139  SmallString<64> contentLength;
140 
141  explicit operator bool() const { return stream && !is.has_error(); }
142 };
143 
144 } // namespace wpi
145 
146 #include "HttpUtil.inl"
147 
148 #endif // WPIUTIL_WPI_HTTPUTIL_H_
Definition: HttpUtil.h:77
Definition: raw_socket_istream.h:17
namespace to hold default to_json function
Definition: SmallString.h:21
Definition: HttpUtil.h:62
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
Definition: StringMap.h:38
Definition: raw_istream.h:26
Definition: HttpUtil.h:126
Definition: raw_socket_ostream.h:17
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79