mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 15:04:10 +01:00
ircd::resource: Add permanent redirect device.
This commit is contained in:
parent
b57ef2e8fe
commit
9d0542a93a
3 changed files with 130 additions and 0 deletions
41
include/ircd/resource/redirect.h
Normal file
41
include/ircd/resource/redirect.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_RESOURCE_REDIRECT_H
|
||||
|
||||
struct ircd::resource::redirect
|
||||
{
|
||||
struct permanent; // 308
|
||||
};
|
||||
|
||||
/// This is a pseudo-resource that listens on `old_path` and responds with
|
||||
/// a 308 Permanent Redirect. The Location header replaces old_path with
|
||||
/// new_path, preserving anything in the URI after the replacement. This
|
||||
/// resource responds to all of the methods listed as instances.
|
||||
struct ircd::resource::redirect::permanent
|
||||
:resource
|
||||
{
|
||||
string_view new_path;
|
||||
method _options;
|
||||
method _trace;
|
||||
method _head;
|
||||
method _get;
|
||||
method _put;
|
||||
method _post;
|
||||
method _patch;
|
||||
method _delete;
|
||||
|
||||
response handler(client &, const request &);
|
||||
|
||||
permanent(const string_view &old_path,
|
||||
const string_view &new_path,
|
||||
struct opts);
|
||||
};
|
|
@ -28,6 +28,7 @@ struct ircd::resource
|
|||
struct method;
|
||||
struct request;
|
||||
struct response;
|
||||
struct redirect;
|
||||
|
||||
static log::log log;
|
||||
static std::map<string_view, resource *, iless> resources;
|
||||
|
@ -53,6 +54,7 @@ struct ircd::resource
|
|||
#include "method.h"
|
||||
#include "request.h"
|
||||
#include "response.h"
|
||||
#include "redirect.h"
|
||||
|
||||
enum ircd::resource::flag
|
||||
:uint
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// resource/resource.h
|
||||
//
|
||||
|
||||
decltype(ircd::resource::log)
|
||||
ircd::resource::log
|
||||
{
|
||||
|
@ -1163,3 +1168,85 @@ ircd::resource::response::response(client &client,
|
|||
|
||||
assert(written == size(head.completed()));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// resource/redirect.h
|
||||
//
|
||||
|
||||
//
|
||||
// redirect::permanent::permanent
|
||||
//
|
||||
|
||||
ircd::resource::redirect::permanent::permanent(const string_view &old_path,
|
||||
const string_view &new_path,
|
||||
struct opts opts)
|
||||
:resource
|
||||
{
|
||||
old_path, std::move(opts)
|
||||
}
|
||||
,new_path
|
||||
{
|
||||
new_path
|
||||
}
|
||||
,_options
|
||||
{
|
||||
*this, "OPTIONS", std::bind(&permanent::handler, this, ph::_1, ph::_2)
|
||||
}
|
||||
,_trace
|
||||
{
|
||||
*this, "TRACE", std::bind(&permanent::handler, this, ph::_1, ph::_2)
|
||||
}
|
||||
,_head
|
||||
{
|
||||
*this, "HEAD", std::bind(&permanent::handler, this, ph::_1, ph::_2)
|
||||
}
|
||||
,_get
|
||||
{
|
||||
*this, "GET", std::bind(&permanent::handler, this, ph::_1, ph::_2)
|
||||
}
|
||||
,_put
|
||||
{
|
||||
*this, "PUT", std::bind(&permanent::handler, this, ph::_1, ph::_2)
|
||||
}
|
||||
,_post
|
||||
{
|
||||
*this, "POST", std::bind(&permanent::handler, this, ph::_1, ph::_2)
|
||||
}
|
||||
,_patch
|
||||
{
|
||||
*this, "PATCH", std::bind(&permanent::handler, this, ph::_1, ph::_2)
|
||||
}
|
||||
,_delete
|
||||
{
|
||||
*this, "DELETE", std::bind(&permanent::handler, this, ph::_1, ph::_2)
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::resource::response
|
||||
ircd::resource::redirect::permanent::handler(client &client,
|
||||
const request &request)
|
||||
{
|
||||
thread_local char buf[response::HEAD_BUF_SZ];
|
||||
|
||||
const string_view postfix
|
||||
{
|
||||
lstrip(request.head.uri, this->path)
|
||||
};
|
||||
|
||||
const string_view location{fmt::sprintf
|
||||
{
|
||||
buf, "%s/%s",
|
||||
rstrip(this->new_path, '/'),
|
||||
lstrip(postfix, '/')
|
||||
}};
|
||||
|
||||
return response
|
||||
{
|
||||
client, {}, {}, http::MOVED_PERMANENTLY,
|
||||
{
|
||||
http::header { "Location", location }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue