Skip to content

Commit

Permalink
Request/Response improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
snej committed Nov 20, 2024
1 parent 29d3b3f commit 96cda1a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 42 deletions.
4 changes: 2 additions & 2 deletions REST/Request.cc
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ namespace litecore::REST {
json.writeKey("error"_sl);
json.writeString(defaultMessage);
}
if ( message && defaultMessage && 0 != strcasecmp(message, defaultMessage) ) {
if ( message && *message && defaultMessage && 0 != strcasecmp(message, defaultMessage) ) {
json.writeKey("reason"_sl);
json.writeString(message);
}
Expand Down Expand Up @@ -223,7 +223,7 @@ namespace litecore::REST {
void RequestResponse::respondWithError(C4Error err) {
Assert(err.code != 0);
alloc_slice message = c4error_getMessage(err);
respondWithStatus(errorToStatus(err), (message ? message.asString().c_str() : nullptr));
respondWithStatus(errorToStatus(err), message.asString());
}

HTTPStatus RequestResponse::errorToStatus(C4Error err) {
Expand Down
41 changes: 23 additions & 18 deletions REST/Request.hh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace litecore::REST {
public:
using Method = net::Method;

explicit Request(fleece::slice httpData);
explicit Request(slice httpData);

bool isValid() const { return _method != Method::None; }

Expand Down Expand Up @@ -62,10 +62,10 @@ namespace litecore::REST {
bool keepAlive() const;

protected:
Request(Method, std::string path, std::string queries, websocket::Headers headers, fleece::alloc_slice body);
Request(Method, std::string path, std::string queries, websocket::Headers headers, alloc_slice body);
Request() = default;

bool readFromHTTP(fleece::slice httpData); // data must extend at least to CRLF
bool readFromHTTP(slice httpData); // data must extend at least to CRLF

Method _method{Method::None};
std::string _path;
Expand All @@ -84,6 +84,11 @@ namespace litecore::REST {
// Response status:

void respondWithStatus(HTTPStatus, const char* message = nullptr);

void respondWithStatus(HTTPStatus status, std::string const& message) {
respondWithStatus(status, message.c_str());
}

void respondWithError(C4Error);

void setStatus(HTTPStatus status, const char* message);
Expand All @@ -94,9 +99,9 @@ namespace litecore::REST {

// Response headers:

void setHeader(fleece::slice header, fleece::slice value);
void setHeader(slice header, slice value);

void setHeader(fleece::slice header, int64_t value) { setHeader(header, std::to_string(value)); }
void setHeader(slice header, int64_t value) { setHeader(header, std::to_string(value)); }

void addHeaders(const std::map<std::string, std::string>&);

Expand All @@ -112,13 +117,13 @@ namespace litecore::REST {
void setContentLength(uint64_t length);
void uncacheable();

void write(fleece::slice);
void write(slice);

void write(const char* content) { write(fleece::slice(content)); }
void write(const char* content) { write(slice(content)); }

void printf(const char* format, ...) __printflike(2, 3);

fleece::JSONEncoder& jsonEncoder();
JSONEncoder& jsonEncoder();

void writeStatusJSON(HTTPStatus status, const char* message = nullptr);
void writeErrorJSON(C4Error);
Expand Down Expand Up @@ -153,28 +158,28 @@ namespace litecore::REST {
protected:
void sendStatus();
void sendHeaders();
void writeToSocket(fleece::slice);
void writeToSocket(slice);
void _flush();
void handleSocketError();

private:
std::unique_ptr<net::ResponderSocket> _socket;
C4Error _error{};
std::vector<fleece::alloc_slice> _requestBody;
std::vector<alloc_slice> _requestBody;
HTTPStatus _status{HTTPStatus::OK}; // Response status code
std::string _statusMessage; // Response custom status message
bool _sentStatus{false}; // Sent the response line yet?
fleece::Writer _responseHeaderWriter;
Writer _responseHeaderWriter;
websocket::Headers _responseHeaders;
bool _sentHeaders{false}; // True after headers are ended
int64_t _contentLength{-1}; // Content-Length, once it's set
bool _streaming{false}; // If true, content is being streamed, no Content-Length header
bool _chunked{false}; // True if using chunked transfer encoding
fleece::Writer _responseWriter; // Output stream for response body
std::unique_ptr<fleece::JSONEncoder> _jsonEncoder; // Used for writing JSON to response
fleece::alloc_slice _responseBody; // Finished response body
fleece::slice _unsentBody; // Unsent portion of _responseBody
bool _finished{false}; // Finished configuring the response?
bool _streaming{false}; // If true, content is being streamed, no Content-Length header
bool _chunked{false}; // True if using chunked transfer encoding
Writer _responseWriter; // Output stream for response body
std::unique_ptr<JSONEncoder> _jsonEncoder; // Used for writing JSON to response
alloc_slice _responseBody; // Finished response body
slice _unsentBody; // Unsent portion of _responseBody
bool _finished{false}; // Finished configuring the response?
};

} // namespace litecore::REST
Expand Down
43 changes: 21 additions & 22 deletions REST/Response.hh
Original file line number Diff line number Diff line change
Expand Up @@ -37,31 +37,30 @@ namespace litecore::REST {
public:
using HTTPStatus = net::HTTPStatus;

fleece::slice header(const char* name) const { return _headers[fleece::slice(name)]; }
slice header(const char* name) const { return _headers[slice(name)]; }

fleece::slice operator[](const char* name) const { return header(name); }
slice operator[](const char* name) const { return header(name); }

std::optional<MIMEType> contentType() const;

bool hasContentType(fleece::slice hasType) const;
fleece::alloc_slice body() const;
fleece::Value bodyAsJSON() const;
bool hasContentType(slice hasType) const;
alloc_slice body() const;
Value bodyAsJSON() const;

protected:
Body() = default;

Body(websocket::Headers headers, fleece::alloc_slice body)
: _headers(std::move(headers)), _body(std::move(body)) {}
Body(websocket::Headers headers, alloc_slice body) : _headers(std::move(headers)), _body(std::move(body)) {}

void setHeaders(const websocket::Headers& h) { _headers = h; }

void setBody(fleece::alloc_slice body) { _body = std::move(body); }
void setBody(alloc_slice body) { _body = std::move(body); }

websocket::Headers _headers;
mutable std::optional<MIMEType> _contentType;
fleece::alloc_slice _body;
alloc_slice _body;
mutable bool _gotBodyFleece{false};
mutable fleece::Doc _bodyFleece;
mutable Doc _bodyFleece;
};

/** An HTTP response from a server, created by specifying a request to send.
Expand All @@ -78,11 +77,11 @@ namespace litecore::REST {

~Response();

Response& setHeaders(const fleece::Doc& headers);
Response& setHeaders(const Doc& headers);
Response& setHeaders(const websocket::Headers& headers);

Response& setAuthHeader(fleece::slice authHeader);
Response& setBody(fleece::slice body);
Response& setAuthHeader(slice authHeader);
Response& setBody(slice body);
Response& setTLSContext(net::TLSContext*);
Response& setProxy(const net::ProxySpec&);

Expand All @@ -93,8 +92,8 @@ namespace litecore::REST {
return *this;
}

Response& allowOnlyCert(fleece::slice certData);
Response& setRootCerts(fleece::slice certsData);
Response& allowOnlyCert(slice certData);
Response& setRootCerts(slice certsData);
#ifdef COUCHBASE_ENTERPRISE
Response& allowOnlyCert(C4Cert*);
Response& setRootCerts(C4Cert*);
Expand Down Expand Up @@ -131,13 +130,13 @@ namespace litecore::REST {
}

private:
double _timeout{0};
std::unique_ptr<net::HTTPLogic> _logic;
fleece::Retained<net::TLSContext> _tlsContext;
fleece::alloc_slice _requestBody;
HTTPStatus _status{HTTPStatus::undefined};
std::string _statusMessage;
C4Error _error{};
double _timeout{0};
std::unique_ptr<net::HTTPLogic> _logic;
Retained<net::TLSContext> _tlsContext;
alloc_slice _requestBody;
HTTPStatus _status{HTTPStatus::undefined};
std::string _statusMessage;
C4Error _error{};
};

} // namespace litecore::REST

0 comments on commit 96cda1a

Please sign in to comment.