mirror of https://github.com/rwf2/Rocket.git
parent
73fed03ef4
commit
a6c4d053ad
|
@ -22,5 +22,5 @@ log = "^0.3"
|
||||||
compiletest_rs = "^0.2"
|
compiletest_rs = "^0.2"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
ansi_term = "0.9"
|
yansi = "0.2"
|
||||||
version_check = "0.1"
|
version_check = "0.1"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//! This tiny build script ensures that rocket_codegen is not compiled with an
|
//! This tiny build script ensures that rocket_codegen is not compiled with an
|
||||||
//! incompatible version of rust.
|
//! incompatible version of rust.
|
||||||
|
|
||||||
extern crate ansi_term;
|
extern crate yansi;
|
||||||
extern crate version_check;
|
extern crate version_check;
|
||||||
|
|
||||||
use ansi_term::Color::{Red, Yellow, Blue, White};
|
use yansi::Color::{Red, Yellow, Blue, White};
|
||||||
use version_check::{is_nightly, is_min_version, is_min_date};
|
use version_check::{is_nightly, is_min_version, is_min_date};
|
||||||
|
|
||||||
// Specifies the minimum nightly version needed to compile Rocket's codegen.
|
// Specifies the minimum nightly version needed to compile Rocket's codegen.
|
||||||
|
@ -37,7 +37,7 @@ fn main() {
|
||||||
(Some(is_nightly), Some((ok_version, version)), Some((ok_date, date))) => {
|
(Some(is_nightly), Some((ok_version, version)), Some((ok_date, date))) => {
|
||||||
if !is_nightly {
|
if !is_nightly {
|
||||||
printerr!("{} {}",
|
printerr!("{} {}",
|
||||||
Red.bold().paint("Error:"),
|
Red.paint("Error:").bold(),
|
||||||
White.paint("Rocket requires a nightly version of Rust."));
|
White.paint("Rocket requires a nightly version of Rust."));
|
||||||
print_version_err(&*version, &*date);
|
print_version_err(&*version, &*date);
|
||||||
printerr!("{}{}{}",
|
printerr!("{}{}{}",
|
||||||
|
@ -49,7 +49,7 @@ fn main() {
|
||||||
|
|
||||||
if !ok_version || !ok_date {
|
if !ok_version || !ok_date {
|
||||||
printerr!("{} {}",
|
printerr!("{} {}",
|
||||||
Red.bold().paint("Error:"),
|
Red.paint("Error:").bold(),
|
||||||
White.paint("Rocket codegen requires a more recent version of rustc."));
|
White.paint("Rocket codegen requires a more recent version of rustc."));
|
||||||
printerr!("{}{}{}",
|
printerr!("{}{}{}",
|
||||||
Blue.paint("Use `"),
|
Blue.paint("Use `"),
|
||||||
|
|
|
@ -18,7 +18,7 @@ categories = ["web-programming::http-server"]
|
||||||
tls = ["rustls", "hyper-rustls"]
|
tls = ["rustls", "hyper-rustls"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
term-painter = "0.2"
|
yansi = "0.2"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
url = "1"
|
url = "1"
|
||||||
toml = { version = "0.2", default-features = false }
|
toml = { version = "0.2", default-features = false }
|
||||||
|
@ -47,5 +47,5 @@ lazy_static = "0.2"
|
||||||
rocket_codegen = { version = "0.2.8", path = "../codegen" }
|
rocket_codegen = { version = "0.2.8", path = "../codegen" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
ansi_term = "0.9"
|
yansi = "0.2"
|
||||||
version_check = "^0.1"
|
version_check = "^0.1"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//! This tiny build script ensures that rocket is not compiled with an
|
//! This tiny build script ensures that rocket is not compiled with an
|
||||||
//! incompatible version of rust.
|
//! incompatible version of rust.
|
||||||
|
|
||||||
extern crate ansi_term;
|
extern crate yansi;
|
||||||
extern crate version_check;
|
extern crate version_check;
|
||||||
|
|
||||||
use ansi_term::Color::{Red, Yellow, Blue, White};
|
use yansi::Color::{Red, Yellow, Blue, White};
|
||||||
use version_check::{is_nightly, is_min_version};
|
use version_check::{is_nightly, is_min_version};
|
||||||
|
|
||||||
// Specifies the minimum nightly version needed to compile Rocket.
|
// Specifies the minimum nightly version needed to compile Rocket.
|
||||||
|
@ -32,7 +32,7 @@ fn main() {
|
||||||
if let (Some(is_nightly), Some((ok_version, version))) = (ok_nightly, ok_version) {
|
if let (Some(is_nightly), Some((ok_version, version))) = (ok_nightly, ok_version) {
|
||||||
if !is_nightly {
|
if !is_nightly {
|
||||||
printerr!("{} {}",
|
printerr!("{} {}",
|
||||||
Red.bold().paint("Error:"),
|
Red.paint("Error:").bold(),
|
||||||
White.paint("Rocket requires a nightly version of Rust."));
|
White.paint("Rocket requires a nightly version of Rust."));
|
||||||
print_version_err(&*version);
|
print_version_err(&*version);
|
||||||
printerr!("{}{}{}",
|
printerr!("{}{}{}",
|
||||||
|
@ -44,7 +44,7 @@ fn main() {
|
||||||
|
|
||||||
if !ok_version {
|
if !ok_version {
|
||||||
printerr!("{} {}",
|
printerr!("{} {}",
|
||||||
Red.bold().paint("Error:"),
|
Red.paint("Error:").bold(),
|
||||||
White.paint("Rocket requires a newer version of rustc."));
|
White.paint("Rocket requires a newer version of rustc."));
|
||||||
printerr!("{}{}{}",
|
printerr!("{}{}{}",
|
||||||
Blue.paint("Use `"),
|
Blue.paint("Use `"),
|
||||||
|
|
|
@ -5,8 +5,7 @@ use error::Error;
|
||||||
use request::Request;
|
use request::Request;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use term_painter::ToStyle;
|
use yansi::Color::*;
|
||||||
use term_painter::Color::*;
|
|
||||||
|
|
||||||
/// An error catching route.
|
/// An error catching route.
|
||||||
///
|
///
|
||||||
|
|
|
@ -5,8 +5,7 @@ use std::fmt;
|
||||||
use super::Environment;
|
use super::Environment;
|
||||||
use self::ConfigError::*;
|
use self::ConfigError::*;
|
||||||
|
|
||||||
use term_painter::Color::White;
|
use yansi::Color::White;
|
||||||
use term_painter::ToStyle;
|
|
||||||
|
|
||||||
/// The type of a configuration parsing error.
|
/// The type of a configuration parsing error.
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
|
|
@ -82,8 +82,7 @@ impl Fairings {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pretty_print_counts(&self) {
|
pub fn pretty_print_counts(&self) {
|
||||||
use term_painter::ToStyle;
|
use yansi::Paint;
|
||||||
use term_painter::Color::{White, Magenta};
|
|
||||||
|
|
||||||
if self.all_fairings.is_empty() {
|
if self.all_fairings.is_empty() {
|
||||||
return
|
return
|
||||||
|
@ -92,12 +91,12 @@ impl Fairings {
|
||||||
fn info_if_nonempty(kind: &str, fairings: &[&Fairing]) {
|
fn info_if_nonempty(kind: &str, fairings: &[&Fairing]) {
|
||||||
let names: Vec<&str> = fairings.iter().map(|f| f.info().name).collect();
|
let names: Vec<&str> = fairings.iter().map(|f| f.info().name).collect();
|
||||||
info_!("{} {}: {}",
|
info_!("{} {}: {}",
|
||||||
White.paint(fairings.len()),
|
Paint::white(fairings.len()),
|
||||||
kind,
|
kind,
|
||||||
White.paint(names.join(", ")));
|
Paint::white(names.join(", ")));
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("📡 {}:", Magenta.paint("Fairings"));
|
info!("📡 {}:", Paint::purple("Fairings"));
|
||||||
info_if_nonempty("launch", &self.launch);
|
info_if_nonempty("launch", &self.launch);
|
||||||
info_if_nonempty("request", &self.request);
|
info_if_nonempty("request", &self.request);
|
||||||
info_if_nonempty("response", &self.response);
|
info_if_nonempty("response", &self.response);
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
#[macro_use] extern crate pear;
|
#[macro_use] extern crate pear;
|
||||||
#[cfg(feature = "tls")] extern crate rustls;
|
#[cfg(feature = "tls")] extern crate rustls;
|
||||||
#[cfg(feature = "tls")] extern crate hyper_rustls;
|
#[cfg(feature = "tls")] extern crate hyper_rustls;
|
||||||
extern crate term_painter;
|
extern crate yansi;
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
extern crate toml;
|
extern crate toml;
|
||||||
|
|
|
@ -4,8 +4,7 @@ use std::str::FromStr;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use log::{self, Log, LogLevel, LogRecord, LogMetadata};
|
use log::{self, Log, LogLevel, LogRecord, LogMetadata};
|
||||||
use term_painter::Color::*;
|
use yansi::Color::*;
|
||||||
use term_painter::ToStyle;
|
|
||||||
|
|
||||||
struct RocketLogger(LoggingLevel);
|
struct RocketLogger(LoggingLevel);
|
||||||
|
|
||||||
|
@ -119,20 +118,20 @@ impl Log for RocketLogger {
|
||||||
use log::LogLevel::*;
|
use log::LogLevel::*;
|
||||||
match level {
|
match level {
|
||||||
Info => println!("{}", Blue.paint(record.args())),
|
Info => println!("{}", Blue.paint(record.args())),
|
||||||
Trace => println!("{}", Magenta.paint(record.args())),
|
Trace => println!("{}", Purple.paint(record.args())),
|
||||||
Error => {
|
Error => {
|
||||||
println!("{} {}",
|
println!("{} {}",
|
||||||
Red.bold().paint("Error:"),
|
Red.paint("Error:").bold(),
|
||||||
Red.paint(record.args()))
|
Red.paint(record.args()))
|
||||||
}
|
}
|
||||||
Warn => {
|
Warn => {
|
||||||
println!("{} {}",
|
println!("{} {}",
|
||||||
Yellow.bold().paint("Warning:"),
|
Yellow.paint("Warning:").bold(),
|
||||||
Yellow.paint(record.args()))
|
Yellow.paint(record.args()))
|
||||||
}
|
}
|
||||||
Debug => {
|
Debug => {
|
||||||
let loc = record.location();
|
let loc = record.location();
|
||||||
print!("\n{} ", Blue.bold().paint("-->"));
|
print!("\n{} ", Blue.paint("-->").bold());
|
||||||
println!("{}:{}", Blue.paint(loc.file()), Blue.paint(loc.line()));
|
println!("{}:{}", Blue.paint(loc.file()), Blue.paint(loc.line()));
|
||||||
println!("{}", record.args());
|
println!("{}", record.args());
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,7 @@
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use term_painter::Color::*;
|
use yansi::{Paint, Color};
|
||||||
use term_painter::Color;
|
|
||||||
use term_painter::ToStyle;
|
|
||||||
|
|
||||||
use self::Outcome::*;
|
use self::Outcome::*;
|
||||||
|
|
||||||
|
@ -422,9 +420,9 @@ impl<S, E, F> Outcome<S, E, F> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn formatting(&self) -> (Color, &'static str) {
|
fn formatting(&self) -> (Color, &'static str) {
|
||||||
match *self {
|
match *self {
|
||||||
Success(..) => (Green, "Success"),
|
Success(..) => (Color::Green, "Success"),
|
||||||
Failure(..) => (Red, "Failure"),
|
Failure(..) => (Color::Red, "Failure"),
|
||||||
Forward(..) => (Yellow, "Forward"),
|
Forward(..) => (Color::Yellow, "Forward"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -438,6 +436,6 @@ impl<S, E, F> fmt::Debug for Outcome<S, E, F> {
|
||||||
impl<S, E, F> fmt::Display for Outcome<S, E, F> {
|
impl<S, E, F> fmt::Display for Outcome<S, E, F> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let (color, string) = self.formatting();
|
let (color, string) = self.formatting();
|
||||||
write!(f, "{}", color.paint(string))
|
write!(f, "{}", Paint::new(string).fg(color))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,7 @@ use std::net::SocketAddr;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use term_painter::Color::*;
|
use yansi::Paint;
|
||||||
use term_painter::ToStyle;
|
|
||||||
|
|
||||||
use state::{Container, Storage};
|
use state::{Container, Storage};
|
||||||
|
|
||||||
|
@ -580,10 +579,10 @@ impl<'r> fmt::Display for Request<'r> {
|
||||||
/// Pretty prints a Request. This is primarily used by Rocket's logging
|
/// Pretty prints a Request. This is primarily used by Rocket's logging
|
||||||
/// infrastructure.
|
/// infrastructure.
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{} {}", Green.paint(&self.method), Blue.paint(&self.uri))?;
|
write!(f, "{} {}", Paint::green(&self.method), Paint::blue(&self.uri))?;
|
||||||
if let Some(content_type) = self.content_type() {
|
if let Some(content_type) = self.content_type() {
|
||||||
if self.method.supports_payload() {
|
if self.method.supports_payload() {
|
||||||
write!(f, " {}", Yellow.paint(content_type))?;
|
write!(f, " {}", Paint::yellow(content_type))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,7 @@ use std::net::SocketAddr;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use term_painter::Color::*;
|
use yansi::Paint;
|
||||||
use term_painter::ToStyle;
|
|
||||||
use state::Container;
|
use state::Container;
|
||||||
|
|
||||||
#[cfg(feature = "tls")] use hyper_rustls::TlsServer;
|
#[cfg(feature = "tls")] use hyper_rustls::TlsServer;
|
||||||
|
@ -111,7 +110,7 @@ impl Rocket {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn issue_response(&self, response: Response, hyp_res: hyper::FreshResponse) {
|
fn issue_response(&self, response: Response, hyp_res: hyper::FreshResponse) {
|
||||||
match self.write_response(response, hyp_res) {
|
match self.write_response(response, hyp_res) {
|
||||||
Ok(_) => info_!("{}", Green.paint("Response succeeded.")),
|
Ok(_) => info_!("{}", Paint::green("Response succeeded.")),
|
||||||
Err(e) => error_!("Failed to write response: {:?}.", e)
|
Err(e) => error_!("Failed to write response: {:?}.", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,7 +250,7 @@ impl Rocket {
|
||||||
|
|
||||||
// There was no matching route.
|
// There was no matching route.
|
||||||
if request.method() == Method::Head {
|
if request.method() == Method::Head {
|
||||||
info_!("Autohandling {} request.", White.paint("HEAD"));
|
info_!("Autohandling {} request.", Paint::white("HEAD"));
|
||||||
request.set_method(Method::Get);
|
request.set_method(Method::Get);
|
||||||
let mut response = self.dispatch(request, data);
|
let mut response = self.dispatch(request, data);
|
||||||
response.strip_body();
|
response.strip_body();
|
||||||
|
@ -298,7 +297,7 @@ impl Rocket {
|
||||||
|
|
||||||
// Check if the request processing completed or if the request needs
|
// Check if the request processing completed or if the request needs
|
||||||
// to be forwarded. If it does, continue the loop to try again.
|
// to be forwarded. If it does, continue the loop to try again.
|
||||||
info_!("{} {}", White.paint("Outcome:"), outcome);
|
info_!("{} {}", Paint::white("Outcome:"), outcome);
|
||||||
match outcome {
|
match outcome {
|
||||||
o@Outcome::Success(_) | o @Outcome::Failure(_) => return o,
|
o@Outcome::Success(_) | o @Outcome::Failure(_) => return o,
|
||||||
Outcome::Forward(unused_data) => data = unused_data,
|
Outcome::Forward(unused_data) => data = unused_data,
|
||||||
|
@ -315,7 +314,7 @@ impl Rocket {
|
||||||
// 500 catcher is executed. if there is no registered catcher for `status`,
|
// 500 catcher is executed. if there is no registered catcher for `status`,
|
||||||
// the default catcher is used.
|
// the default catcher is used.
|
||||||
fn handle_error<'r>(&self, status: Status, req: &'r Request) -> Response<'r> {
|
fn handle_error<'r>(&self, status: Status, req: &'r Request) -> Response<'r> {
|
||||||
warn_!("Responding with {} catcher.", Red.paint(&status));
|
warn_!("Responding with {} catcher.", Paint::red(&status));
|
||||||
|
|
||||||
// Try to get the active catcher but fallback to user's 500 catcher.
|
// Try to get the active catcher but fallback to user's 500 catcher.
|
||||||
let catcher = self.catchers.get(&status.code).unwrap_or_else(|| {
|
let catcher = self.catchers.get(&status.code).unwrap_or_else(|| {
|
||||||
|
@ -396,28 +395,28 @@ impl Rocket {
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("🔧 Configured for {}.", config.environment);
|
info!("🔧 Configured for {}.", config.environment);
|
||||||
info_!("address: {}", White.paint(&config.address));
|
info_!("address: {}", Paint::white(&config.address));
|
||||||
info_!("port: {}", White.paint(&config.port));
|
info_!("port: {}", Paint::white(&config.port));
|
||||||
info_!("log: {}", White.paint(config.log_level));
|
info_!("log: {}", Paint::white(config.log_level));
|
||||||
info_!("workers: {}", White.paint(config.workers));
|
info_!("workers: {}", Paint::white(config.workers));
|
||||||
info_!("secret key: {}", White.paint(config.secret_key.kind()));
|
info_!("secret key: {}", Paint::white(config.secret_key.kind()));
|
||||||
info_!("limits: {}", White.paint(&config.limits));
|
info_!("limits: {}", Paint::white(&config.limits));
|
||||||
|
|
||||||
let tls_configured = config.tls.is_some();
|
let tls_configured = config.tls.is_some();
|
||||||
if tls_configured && cfg!(feature = "tls") {
|
if tls_configured && cfg!(feature = "tls") {
|
||||||
info_!("tls: {}", White.paint("enabled"));
|
info_!("tls: {}", Paint::white("enabled"));
|
||||||
} else {
|
} else {
|
||||||
if tls_configured {
|
if tls_configured {
|
||||||
error_!("tls: {}", White.paint("disabled"));
|
error_!("tls: {}", Paint::white("disabled"));
|
||||||
error_!("tls is configured, but the tls feature is disabled");
|
error_!("tls is configured, but the tls feature is disabled");
|
||||||
} else {
|
} else {
|
||||||
info_!("tls: {}", White.paint("disabled"));
|
info_!("tls: {}", Paint::white("disabled"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name, value) in config.extras() {
|
for (name, value) in config.extras() {
|
||||||
info_!("{} {}: {}",
|
info_!("{} {}: {}",
|
||||||
Yellow.paint("[extra]"), name, White.paint(LoggedValue(value)));
|
Paint::yellow("[extra]"), name, Paint::white(LoggedValue(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Rocket {
|
Rocket {
|
||||||
|
@ -483,7 +482,7 @@ impl Rocket {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mount(mut self, base: &str, routes: Vec<Route>) -> Self {
|
pub fn mount(mut self, base: &str, routes: Vec<Route>) -> Self {
|
||||||
info!("🛰 {} '{}':", Magenta.paint("Mounting"), base);
|
info!("🛰 {} '{}':", Paint::purple("Mounting"), base);
|
||||||
|
|
||||||
if base.contains('<') {
|
if base.contains('<') {
|
||||||
error_!("Bad mount point: '{}'.", base);
|
error_!("Bad mount point: '{}'.", base);
|
||||||
|
@ -534,11 +533,11 @@ impl Rocket {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn catch(mut self, catchers: Vec<Catcher>) -> Self {
|
pub fn catch(mut self, catchers: Vec<Catcher>) -> Self {
|
||||||
info!("👾 {}:", Magenta.paint("Catchers"));
|
info!("👾 {}:", Paint::purple("Catchers"));
|
||||||
for c in catchers {
|
for c in catchers {
|
||||||
if self.catchers.get(&c.code).map_or(false, |e| !e.is_default()) {
|
if self.catchers.get(&c.code).map_or(false, |e| !e.is_default()) {
|
||||||
let msg = "(warning: duplicate catcher!)";
|
let msg = "(warning: duplicate catcher!)";
|
||||||
info_!("{} {}", c, Yellow.paint(msg));
|
info_!("{} {}", c, Paint::yellow(msg));
|
||||||
} else {
|
} else {
|
||||||
info_!("{}", c);
|
info_!("{}", c);
|
||||||
}
|
}
|
||||||
|
@ -685,9 +684,9 @@ impl Rocket {
|
||||||
|
|
||||||
let full_addr = format!("{}:{}", self.config.address, self.config.port);
|
let full_addr = format!("{}:{}", self.config.address, self.config.port);
|
||||||
launch_info!("🚀 {} {}{}",
|
launch_info!("🚀 {} {}{}",
|
||||||
White.paint("Rocket has launched from"),
|
Paint::white("Rocket has launched from"),
|
||||||
White.bold().paint(proto),
|
Paint::white(proto).bold(),
|
||||||
White.bold().paint(&full_addr));
|
Paint::white(&full_addr).bold());
|
||||||
|
|
||||||
let threads = self.config.workers as usize;
|
let threads = self.config.workers as usize;
|
||||||
if let Err(e) = server.handle_threads(self, threads) {
|
if let Err(e) = server.handle_threads(self, threads) {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
|
||||||
use term_painter::ToStyle;
|
use yansi::Color::*;
|
||||||
use term_painter::Color::*;
|
|
||||||
|
|
||||||
use codegen::StaticRouteInfo;
|
use codegen::StaticRouteInfo;
|
||||||
use handler::Handler;
|
use handler::Handler;
|
||||||
|
|
Loading…
Reference in New Issue