blob: e6ddf0f47f799edd19d9beaad00edcdfc77f575d [file] [log] [blame]
/**
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <iostream>
#include "tscpp/api/GlobalPlugin.h"
#include "tscpp/api/PluginInit.h"
#include "tscpp/api/utils.h"
using namespace atscppapi;
using std::cout;
using std::endl;
using std::list;
using std::string;
namespace
{
GlobalPlugin *plugin;
}
class ServerResponsePlugin : public GlobalPlugin
{
public:
ServerResponsePlugin()
{
registerHook(HOOK_SEND_REQUEST_HEADERS);
registerHook(HOOK_READ_RESPONSE_HEADERS);
registerHook(HOOK_SEND_RESPONSE_HEADERS);
}
void
handleSendRequestHeaders(Transaction &transaction) override
{
// Here we can decide to abort the request to the origin (we can do this earlier too)
// and just send the user an error page.
if (transaction.getClientRequest().getUrl().getQuery().find("error=1") != string::npos) {
// Give this user an error page and don't make a request to an origin.
cout << "Sending this request an error page" << endl;
transaction.error("This is the error response, but the response code is 500."
"In this example no request was made to the origin.");
// HTTP/1.1 500 INKApi Error
} else {
transaction.resume();
}
cout << "Server request headers are" << endl;
cout << transaction.getServerRequest().getHeaders() << endl;
}
void
handleReadResponseHeaders(Transaction &transaction) override
{
cout << "Hello from handleReadResponseHeaders!" << endl;
cout << "Server response headers are" << endl;
Response &server_response = transaction.getServerResponse();
cout << "Reason phrase is " << server_response.getReasonPhrase() << endl;
cout << transaction.getServerRequest().getHeaders() << endl;
transaction.resume();
}
void
handleSendResponseHeaders(Transaction &transaction) override
{
cout << "Hello from handleSendResponseHeaders!" << endl;
cout << "Client response headers are" << endl;
transaction.getClientResponse().getHeaders()["X-Foo-Header"] = "1";
printHeadersManual(transaction.getClientResponse().getHeaders());
//
// If the url contains a query parameter redirect=1 we will send the
// user to somewhere else. Obviously this is a silly example
// since we should technically detect this long before the origin
// request and prevent the origin request in the first place.
//
if (transaction.getClientRequest().getUrl().getQuery().find("redirect=1") != string::npos) {
cout << "Sending this guy to google." << endl;
transaction.getClientResponse().getHeaders().append("Location", "http://www.google.com");
transaction.getClientResponse().setStatusCode(HTTP_STATUS_MOVED_TEMPORARILY);
transaction.getClientResponse().setReasonPhrase("Come Back Later");
// HTTP/1.1 302 Come Back Later
}
transaction.resume();
}
private:
void
printHeadersManual(Headers &headers)
{
for (auto &&header : headers) {
cout << "Header " << header.name() << ": " << endl;
for (auto &&value_iter : header) {
cout << "\t" << value_iter << endl;
}
}
cout << endl;
}
};
void
TSPluginInit(int argc ATSCPPAPI_UNUSED, const char *argv[] ATSCPPAPI_UNUSED)
{
if (!RegisterGlobalPlugin("CPP_Example_ServerResponse", "apache", "dev@trafficserver.apache.org")) {
return;
}
plugin = new ServerResponsePlugin();
}