mirror of
https://github.com/ntex-rs/ntex-extras.git
synced 2025-04-04 13:27:41 +03:00
migrate multipart
This commit is contained in:
parent
8d2e70094e
commit
09598fa723
9 changed files with 154 additions and 80 deletions
25
LICENSE
25
LICENSE
|
@ -1,25 +0,0 @@
|
||||||
Copyright (c) 2020 Nikolay Kim
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any
|
|
||||||
person obtaining a copy of this software and associated
|
|
||||||
documentation files (the "Software"), to deal in the
|
|
||||||
Software without restriction, including without
|
|
||||||
limitation the rights to use, copy, modify, merge,
|
|
||||||
publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software
|
|
||||||
is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice
|
|
||||||
shall be included in all copies or substantial portions
|
|
||||||
of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
||||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
||||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
|
||||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
|
@ -1 +0,0 @@
|
||||||
../LICENSE
|
|
25
ntex-cors/LICENSE
Normal file
25
ntex-cors/LICENSE
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
Copyright (c) 2020 Nikolay Kim
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any
|
||||||
|
person obtaining a copy of this software and associated
|
||||||
|
documentation files (the "Software"), to deal in the
|
||||||
|
Software without restriction, including without
|
||||||
|
limitation the rights to use, copy, modify, merge,
|
||||||
|
publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software
|
||||||
|
is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice
|
||||||
|
shall be included in all copies or substantial portions
|
||||||
|
of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||||
|
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||||
|
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||||
|
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
|
@ -1 +0,0 @@
|
||||||
../LICENSE
|
|
25
ntex-files/LICENSE
Normal file
25
ntex-files/LICENSE
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
Copyright (c) 2020 Nikolay Kim
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any
|
||||||
|
person obtaining a copy of this software and associated
|
||||||
|
documentation files (the "Software"), to deal in the
|
||||||
|
Software without restriction, including without
|
||||||
|
limitation the rights to use, copy, modify, merge,
|
||||||
|
publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software
|
||||||
|
is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice
|
||||||
|
shall be included in all copies or substantial portions
|
||||||
|
of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||||
|
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||||
|
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||||
|
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
|
@ -1 +0,0 @@
|
||||||
../LICENSE
|
|
25
ntex-identity/LICENSE
Normal file
25
ntex-identity/LICENSE
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
Copyright (c) 2020 Nikolay Kim
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any
|
||||||
|
person obtaining a copy of this software and associated
|
||||||
|
documentation files (the "Software"), to deal in the
|
||||||
|
Software without restriction, including without
|
||||||
|
limitation the rights to use, copy, modify, merge,
|
||||||
|
publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software
|
||||||
|
is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice
|
||||||
|
shall be included in all copies or substantial portions
|
||||||
|
of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||||
|
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||||
|
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||||
|
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
|
@ -1 +0,0 @@
|
||||||
/Users/fafhrd91/actix/ntex-extras/ntex-files/LICENSE
|
|
25
ntex-multipart/LICENSE
Normal file
25
ntex-multipart/LICENSE
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
Copyright (c) 2020 Nikolay Kim
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any
|
||||||
|
person obtaining a copy of this software and associated
|
||||||
|
documentation files (the "Software"), to deal in the
|
||||||
|
Software without restriction, including without
|
||||||
|
limitation the rights to use, copy, modify, merge,
|
||||||
|
publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software
|
||||||
|
is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice
|
||||||
|
shall be included in all copies or substantial portions
|
||||||
|
of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||||
|
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||||
|
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||||
|
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
|
@ -1,8 +1,8 @@
|
||||||
//! Error and Result module
|
//! Error and Result module
|
||||||
use actix_web::error::{ParseError, PayloadError};
|
|
||||||
use actix_web::http::StatusCode;
|
|
||||||
use actix_web::ResponseError;
|
|
||||||
use derive_more::{Display, From};
|
use derive_more::{Display, From};
|
||||||
|
use ntex::http::error::{ParseError, PayloadError};
|
||||||
|
use ntex::http::StatusCode;
|
||||||
|
use ntex::web::error::{DefaultError, WebResponseError};
|
||||||
|
|
||||||
/// A set of errors that can occur during parsing multipart streams
|
/// A set of errors that can occur during parsing multipart streams
|
||||||
#[derive(Debug, Display, From)]
|
#[derive(Debug, Display, From)]
|
||||||
|
@ -36,7 +36,7 @@ pub enum MultipartError {
|
||||||
impl std::error::Error for MultipartError {}
|
impl std::error::Error for MultipartError {}
|
||||||
|
|
||||||
/// Return `BadRequest` for `MultipartError`
|
/// Return `BadRequest` for `MultipartError`
|
||||||
impl ResponseError for MultipartError {
|
impl WebResponseError<DefaultError> for MultipartError {
|
||||||
fn status_code(&self) -> StatusCode {
|
fn status_code(&self) -> StatusCode {
|
||||||
StatusCode::BAD_REQUEST
|
StatusCode::BAD_REQUEST
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ impl ResponseError for MultipartError {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use actix_web::HttpResponse;
|
use ntex::web::HttpResponse;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_multipart_error() {
|
fn test_multipart_error() {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
//! Multipart payload support
|
//! Multipart payload support
|
||||||
use actix_web::{dev::Payload, Error, FromRequest, HttpRequest};
|
use std::convert::Infallible;
|
||||||
|
|
||||||
use futures::future::{ok, Ready};
|
use futures::future::{ok, Ready};
|
||||||
|
use ntex::http::Payload;
|
||||||
|
use ntex::web::{FromRequest, HttpRequest};
|
||||||
|
|
||||||
use crate::server::Multipart;
|
use crate::server::Multipart;
|
||||||
|
|
||||||
|
@ -12,8 +15,8 @@ use crate::server::Multipart;
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use futures::{Stream, StreamExt};
|
/// use futures::{Stream, StreamExt};
|
||||||
/// use actix_web::{web, HttpResponse, Error};
|
/// use ntex::web::{self, HttpResponse, Error};
|
||||||
/// use actix_multipart as mp;
|
/// use ntex_multipart as mp;
|
||||||
///
|
///
|
||||||
/// async fn index(mut payload: mp::Multipart) -> Result<HttpResponse, Error> {
|
/// async fn index(mut payload: mp::Multipart) -> Result<HttpResponse, Error> {
|
||||||
/// // iterate over multipart stream
|
/// // iterate over multipart stream
|
||||||
|
@ -29,10 +32,9 @@ use crate::server::Multipart;
|
||||||
/// }
|
/// }
|
||||||
/// # fn main() {}
|
/// # fn main() {}
|
||||||
/// ```
|
/// ```
|
||||||
impl FromRequest for Multipart {
|
impl<Err> FromRequest<Err> for Multipart {
|
||||||
type Error = Error;
|
type Error = Infallible;
|
||||||
type Future = Ready<Result<Multipart, Error>>;
|
type Future = Ready<Result<Multipart, Infallible>>;
|
||||||
type Config = ();
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
||||||
|
|
|
@ -12,11 +12,9 @@ use futures::stream::{LocalBoxStream, Stream, StreamExt};
|
||||||
use httparse;
|
use httparse;
|
||||||
use mime;
|
use mime;
|
||||||
|
|
||||||
use actix_utils::task::LocalWaker;
|
use ntex::http::error::{ParseError, PayloadError};
|
||||||
use actix_web::error::{ParseError, PayloadError};
|
use ntex::http::header::{self, HeaderMap, HeaderName, HeaderValue};
|
||||||
use actix_web::http::header::{
|
use ntex::task::LocalWaker;
|
||||||
self, ContentDisposition, HeaderMap, HeaderName, HeaderValue,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::error::MultipartError;
|
use crate::error::MultipartError;
|
||||||
|
|
||||||
|
@ -401,18 +399,6 @@ impl Field {
|
||||||
pub fn content_type(&self) -> &mime::Mime {
|
pub fn content_type(&self) -> &mime::Mime {
|
||||||
&self.ct
|
&self.ct
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the content disposition of the field, if it exists
|
|
||||||
pub fn content_disposition(&self) -> Option<ContentDisposition> {
|
|
||||||
// RFC 7578: 'Each part MUST contain a Content-Disposition header field
|
|
||||||
// where the disposition type is "form-data".'
|
|
||||||
if let Some(content_disposition) = self.headers.get(&header::CONTENT_DISPOSITION)
|
|
||||||
{
|
|
||||||
ContentDisposition::from_raw(content_disposition).ok()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stream for Field {
|
impl Stream for Field {
|
||||||
|
@ -810,13 +796,12 @@ impl PayloadBuffer {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use actix_http::h1::Payload;
|
|
||||||
use actix_utils::mpsc;
|
|
||||||
use actix_web::http::header::{DispositionParam, DispositionType};
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::future::lazy;
|
use futures::future::lazy;
|
||||||
|
use ntex::channel::mpsc;
|
||||||
|
use ntex::http::h1::Payload;
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[ntex::test]
|
||||||
async fn test_boundary() {
|
async fn test_boundary() {
|
||||||
let headers = HeaderMap::new();
|
let headers = HeaderMap::new();
|
||||||
match Multipart::boundary(&headers) {
|
match Multipart::boundary(&headers) {
|
||||||
|
@ -929,7 +914,7 @@ mod tests {
|
||||||
(bytes, headers)
|
(bytes, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[ntex::test]
|
||||||
async fn test_multipart_no_end_crlf() {
|
async fn test_multipart_no_end_crlf() {
|
||||||
let (sender, payload) = create_stream();
|
let (sender, payload) = create_stream();
|
||||||
let (mut bytes, headers) = create_simple_request_with_header();
|
let (mut bytes, headers) = create_simple_request_with_header();
|
||||||
|
@ -956,7 +941,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[ntex::test]
|
||||||
async fn test_multipart() {
|
async fn test_multipart() {
|
||||||
let (sender, payload) = create_stream();
|
let (sender, payload) = create_stream();
|
||||||
let (bytes, headers) = create_simple_request_with_header();
|
let (bytes, headers) = create_simple_request_with_header();
|
||||||
|
@ -966,10 +951,6 @@ mod tests {
|
||||||
let mut multipart = Multipart::new(&headers, payload);
|
let mut multipart = Multipart::new(&headers, payload);
|
||||||
match multipart.next().await {
|
match multipart.next().await {
|
||||||
Some(Ok(mut field)) => {
|
Some(Ok(mut field)) => {
|
||||||
let cd = field.content_disposition().unwrap();
|
|
||||||
assert_eq!(cd.disposition, DispositionType::FormData);
|
|
||||||
assert_eq!(cd.parameters[0], DispositionParam::Name("file".into()));
|
|
||||||
|
|
||||||
assert_eq!(field.content_type().type_(), mime::TEXT);
|
assert_eq!(field.content_type().type_(), mime::TEXT);
|
||||||
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
||||||
|
|
||||||
|
@ -1020,7 +1001,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[ntex::test]
|
||||||
async fn test_stream() {
|
async fn test_stream() {
|
||||||
let (bytes, headers) = create_simple_request_with_header();
|
let (bytes, headers) = create_simple_request_with_header();
|
||||||
let payload = SlowStream::new(bytes);
|
let payload = SlowStream::new(bytes);
|
||||||
|
@ -1028,10 +1009,6 @@ mod tests {
|
||||||
let mut multipart = Multipart::new(&headers, payload);
|
let mut multipart = Multipart::new(&headers, payload);
|
||||||
match multipart.next().await.unwrap() {
|
match multipart.next().await.unwrap() {
|
||||||
Ok(mut field) => {
|
Ok(mut field) => {
|
||||||
let cd = field.content_disposition().unwrap();
|
|
||||||
assert_eq!(cd.disposition, DispositionType::FormData);
|
|
||||||
assert_eq!(cd.parameters[0], DispositionParam::Name("file".into()));
|
|
||||||
|
|
||||||
assert_eq!(field.content_type().type_(), mime::TEXT);
|
assert_eq!(field.content_type().type_(), mime::TEXT);
|
||||||
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
||||||
|
|
||||||
|
@ -1056,7 +1033,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[ntex::test]
|
||||||
async fn test_basic() {
|
async fn test_basic() {
|
||||||
let (_, payload) = Payload::create(false);
|
let (_, payload) = Payload::create(false);
|
||||||
let mut payload = PayloadBuffer::new(payload);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
|
@ -1066,7 +1043,7 @@ mod tests {
|
||||||
assert_eq!(None, payload.read_max(1).unwrap());
|
assert_eq!(None, payload.read_max(1).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[ntex::test]
|
||||||
async fn test_eof() {
|
async fn test_eof() {
|
||||||
let (mut sender, payload) = Payload::create(false);
|
let (mut sender, payload) = Payload::create(false);
|
||||||
let mut payload = PayloadBuffer::new(payload);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
|
@ -1082,7 +1059,7 @@ mod tests {
|
||||||
assert!(payload.eof);
|
assert!(payload.eof);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[ntex::test]
|
||||||
async fn test_err() {
|
async fn test_err() {
|
||||||
let (mut sender, payload) = Payload::create(false);
|
let (mut sender, payload) = Payload::create(false);
|
||||||
let mut payload = PayloadBuffer::new(payload);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
|
@ -1091,7 +1068,7 @@ mod tests {
|
||||||
lazy(|cx| payload.poll_stream(cx)).await.err().unwrap();
|
lazy(|cx| payload.poll_stream(cx)).await.err().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[ntex::test]
|
||||||
async fn test_readmax() {
|
async fn test_readmax() {
|
||||||
let (mut sender, payload) = Payload::create(false);
|
let (mut sender, payload) = Payload::create(false);
|
||||||
let mut payload = PayloadBuffer::new(payload);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
|
@ -1108,7 +1085,7 @@ mod tests {
|
||||||
assert_eq!(payload.buf.len(), 0);
|
assert_eq!(payload.buf.len(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[ntex::test]
|
||||||
async fn test_readexactly() {
|
async fn test_readexactly() {
|
||||||
let (mut sender, payload) = Payload::create(false);
|
let (mut sender, payload) = Payload::create(false);
|
||||||
let mut payload = PayloadBuffer::new(payload);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
|
@ -1126,7 +1103,7 @@ mod tests {
|
||||||
assert_eq!(payload.buf.len(), 4);
|
assert_eq!(payload.buf.len(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[ntex::test]
|
||||||
async fn test_readuntil() {
|
async fn test_readuntil() {
|
||||||
let (mut sender, payload) = Payload::create(false);
|
let (mut sender, payload) = Payload::create(false);
|
||||||
let mut payload = PayloadBuffer::new(payload);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
/Users/fafhrd91/actix/ntex-extras/ntex-files/LICENSE
|
|
25
ntex-session/LICENSE
Normal file
25
ntex-session/LICENSE
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
Copyright (c) 2020 Nikolay Kim
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any
|
||||||
|
person obtaining a copy of this software and associated
|
||||||
|
documentation files (the "Software"), to deal in the
|
||||||
|
Software without restriction, including without
|
||||||
|
limitation the rights to use, copy, modify, merge,
|
||||||
|
publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software
|
||||||
|
is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice
|
||||||
|
shall be included in all copies or substantial portions
|
||||||
|
of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||||
|
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||||
|
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||||
|
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
Loading…
Add table
Add a link
Reference in a new issue