TensorFlow Serving C++ API Documentation
evhttp_request.h
1 /* Copyright 2018 Google Inc. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7  http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 // libevent based request implementation
17 
18 #ifndef TENSORFLOW_SERVING_UTIL_NET_HTTP_SERVER_INTERNAL_EVHTTP_REQUEST_H_
19 #define TENSORFLOW_SERVING_UTIL_NET_HTTP_SERVER_INTERNAL_EVHTTP_REQUEST_H_
20 
21 #include <cstdint>
22 #include <memory>
23 #include <string>
24 
25 #include "tensorflow_serving/util/net_http/server/internal/server_support.h"
26 #include "tensorflow_serving/util/net_http/server/public/httpserver_interface.h"
27 #include "tensorflow_serving/util/net_http/server/public/server_request_interface.h"
28 
29 struct evbuffer;
30 struct evhttp_request;
31 struct evhttp_uri;
32 struct evkeyvalq;
33 
34 namespace tensorflow {
35 namespace serving {
36 namespace net_http {
37 
38 // Headers only
40  public:
41  // Doesn't take the ownership
42  explicit ParsedEvRequest(evhttp_request* request_in);
43  ~ParsedEvRequest();
44 
45  // Decode and cache the result; or return false if any parsing error
46  bool decode();
47 
48  evhttp_request* request; // raw request
49 
50  const char* method; // from enum
51 
52  const char* uri = nullptr; // from raw request
53  evhttp_uri* decoded_uri = nullptr; // owned by this
54 
55  // TODO(wenboz): do we need escaped path for dispatching requests?
56  // evhttp_uridecode(path)
57  const char* path = nullptr; // owned by uri
58  std::string path_and_query;
59 
60  evkeyvalq* headers = nullptr; // owned by raw request
61 };
62 
63 // Thread-compatible. See ServerRequestInterface on the exact contract
64 // between the server runtime and application handlers.
65 class EvHTTPRequest final : public ServerRequestInterface {
66  public:
67  virtual ~EvHTTPRequest();
68 
69  EvHTTPRequest(const EvHTTPRequest& other) = delete;
70  EvHTTPRequest& operator=(const EvHTTPRequest& other) = delete;
71 
72  // Doesn't own the server
73  EvHTTPRequest(std::unique_ptr<ParsedEvRequest> request,
74  ServerSupport* server);
75 
76  absl::string_view uri_path() const override;
77 
78  absl::string_view http_method() const override;
79 
80  void WriteResponseBytes(const char* data, int64_t size) override;
81 
82  void WriteResponseString(absl::string_view data) override;
83 
84  std::unique_ptr<char[], ServerRequestInterface::BlockDeleter>
85  ReadRequestBytes(int64_t* size) override;
86 
87  absl::string_view GetRequestHeader(absl::string_view header) const override;
88 
89  std::vector<absl::string_view> request_headers() const override;
90 
91  void OverwriteResponseHeader(absl::string_view header,
92  absl::string_view value) override;
93  void AppendResponseHeader(absl::string_view header,
94  absl::string_view value) override;
95 
96  void PartialReplyWithStatus(HTTPStatusCode status) override;
97  void PartialReply() override;
98 
99  CallbackStatus PartialReplyWithFlushCallback(
100  std::function<void()> callback) override;
101 
102  void ReplyWithStatus(HTTPStatusCode status) override;
103  void Reply() override;
104 
105  void Abort() override;
106 
107  // Initializes the resource and returns false if any error.
108  bool Initialize();
109 
110  // Keeps a reference to the registered RequestHandlerOptions
111  void SetHandlerOptions(const RequestHandlerOptions& handler_options) {
112  this->handler_options_ = &handler_options;
113  }
114 
115  private:
116  void EvSendReply(HTTPStatusCode status);
117 
118  // Returns true if the data needs be uncompressed
119  bool NeedUncompressGzipContent();
120 
121  // Must set uncompressed_input to nullptr if uncompression is failed
122  void UncompressGzipBody(void* input, size_t input_size,
123  void** uncompressed_input,
124  size_t* uncompressed_input_size);
125 
126  std::unique_ptr<char[], ServerRequestInterface::BlockDeleter>
127  ReadRequestGzipBytes(evbuffer* input_buf, int64_t* size);
128 
129  ServerSupport* server_;
130 
131  const RequestHandlerOptions* handler_options_;
132 
133  std::unique_ptr<ParsedEvRequest> parsed_request_;
134 
135  evbuffer* output_buf; // owned by this
136 };
137 
138 } // namespace net_http
139 } // namespace serving
140 } // namespace tensorflow
141 
142 #endif // TENSORFLOW_SERVING_UTIL_NET_HTTP_SERVER_INTERNAL_EVHTTP_REQUEST_H_