1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
//! A *Pastebin* server library. //! //! This library implements a very simple *pastebin* service, which is basically a web-interface //! between a user and a database (be it MongoDB, or hash table, or MariaDB, or anything else). //! The library is database-agnostic, which means a database wrapper has to be implemented for a //! desired DB kind my implementing a quite simple interface `DbInterface`. //! //! [Iron](https://github.com/iron/iron) is used as a web-backend, so all its features could be //! utilized (at least theoretically). The actual code is in the [web](web/index.html) module, //! useful examples are also there. extern crate base64; extern crate chrono; #[macro_use] extern crate iron; #[macro_use] extern crate lazy_static; #[macro_use] extern crate log; extern crate mime_guess; #[macro_use] extern crate quick_error; extern crate rand; extern crate serde; #[macro_use] extern crate serde_json; extern crate tera; extern crate tree_magic; pub mod web; mod error; mod id; mod mime; mod pastebin; mod read; mod request; #[cfg(test)] mod test; #[cfg(test)] extern crate reqwest; use chrono::{DateTime, Utc}; pub use error::Error; use iron::error::HttpResult; /// A paste representation. As simple as that. #[derive(Debug, Clone)] pub struct PasteEntry { /// Raw paste data. pub data: Vec<u8>, /// File name associated with the pate, if any. pub file_name: Option<String>, /// Mime type of the paste. pub mime_type: String, /// Expiration date, if any. pub best_before: Option<DateTime<Utc>>, } /// Interface to a database. /// /// To store and retrieve pastes from a database we only need several functions. And we can /// describe them to be abstract enough to be easily used with just any kind of database, be it /// SQL, NoSQL or just a hash table or whatever. /// /// # Thread safety /// /// This trait is required to be thread safe (`Send + Sync`) since it will be used from multiple /// threads. /// /// # Errors handling /// /// An implementation must provide an `Error` type, which must be thread safe as well and also /// have a `'static` lifetime. /// /// Should some method return an error it will be logged by the web server, but will not be send to /// an http client, it will just receive an internal server error: /// [500](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500). pub trait DbInterface: Send + Sync { type Error: Send + Sync + std::error::Error + 'static; /// Stores the data into the database and returns a unique ID that should be used later to /// access the data. /// /// # Return value /// /// The function is expected to return a unique ID. fn store_data(&self, data: Vec<u8>, file_name: Option<String>, mime_type: String, best_before: Option<DateTime<Utc>>) -> Result<u64, Self::Error>; /// Loads data from the database. /// /// Returns corresponding data if found, `None` otherwise. fn load_data(&self, id: u64) -> Result<Option<PasteEntry>, Self::Error>; /// Gets a file name of a paste (if any). fn get_file_name(&self, id: u64) -> Result<Option<String>, Self::Error>; /// Removes data from the database. /// /// Normally we don't care whether an object exists in the database or not, so an /// implementation doesn't have to check that fact, and usually databases are okay with /// attempts to remove something that doesn't exist. fn remove_data(&self, id: u64) -> Result<(), Self::Error>; /// Returns the maximum data size that could be handled. /// /// This is useful, for example, for MongoDB which has a limit on a BSON document size. fn max_data_size(&self) -> usize; }