Skip to content

Commit 0d12b34

Browse files
committed
Update README - v0.0.8
1 parent 049f80e commit 0d12b34

File tree

3 files changed

+115
-2
lines changed

3 files changed

+115
-2
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
**This project is currently in progress, feel free to [contribute](https://github.com/Simonwep/java-express/graphs/contributors) / [report](https://github.com/Simonwep/java-express/issues) issues! :)**
99

10-
**[0.0.7-alpha](https://github.com/Simonwep/java-express/releases/tag/0.0.7) is ready, check it out!**
10+
**[0.0.8-alpha](https://github.com/Simonwep/java-express/releases/tag/0.0.8) is ready, check it out!**
1111

1212
```java
1313
Express app = new Express();
@@ -242,6 +242,7 @@ res.setContentType(String type); // Set the content type
242242
res.isClosed(); // Check if the response is already closed
243243
res.getHeader(String key); // Get the value from an header field via key
244244
res.setHeader(String key, String val); // Add an specific response header
245+
res.sendAttachment(Path file) // Sends an file as attachment
245246
res.send(String str); // Send an string as response
246247
res.send(Path path); // Send an file as response
247248
res.send(); // Send empty response
@@ -277,6 +278,11 @@ req.getCookies(); // Returns all cookies
277278
req.getIp(); // Returns the client IP-Address
278279
req.getUserAgent(); // Returns the client user agent
279280
req.getURI(); // Returns the request URI
281+
req.isFresh(); // Returns true if the connection is fresh, false otherwise (see code inline-doc)
282+
req.isStale(); // Returns the opposite of req.fresh;
283+
req.isSecure(); // Returns true when the connection is over HTTPS, false otherwise
284+
req.isXHR(); // Returns true if the 'X-Requested-With' header field is 'XMLHttpRequest'
285+
req.getProtocol(); // Returns the connection protocol
280286
req.getAuthorization(); // Returns the request authorization
281287
req.hasAuthorization(); // Check if the request has an authorization
282288
req.pipe(OutputStream stream, int buffersize); // Pipe the request body to an outputstream

src/express/http/request/Request.java

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.sun.net.httpserver.Headers;
44
import com.sun.net.httpserver.HttpExchange;
5+
import com.sun.net.httpserver.HttpsExchange;
56
import express.Express;
67
import express.filter.Filter;
78
import express.http.Cookie;
@@ -15,6 +16,8 @@
1516
import java.net.URI;
1617
import java.nio.file.Files;
1718
import java.nio.file.Path;
19+
import java.time.Instant;
20+
import java.time.format.DateTimeFormatter;
1821
import java.util.HashMap;
1922
import java.util.List;
2023

@@ -27,9 +30,11 @@ public class Request {
2730

2831
private final Express EXPRESS;
2932

33+
private final String PROTOCOL; // Request protocoll
3034
private final URI URI; // Request URI
3135
private final InputStream BODY; // Request body
3236
private final Headers HEADERS; // Request Headers
37+
private final boolean SECURE;
3338
private final String CONTENT_TYPE; // Request content-type
3439
private final long CONTENT_LENGTH; // Request content-length
3540
private final String METHOD; // Request method
@@ -56,6 +61,9 @@ public Request(HttpExchange exchange, Express express) {
5661
this.BODY = exchange.getRequestBody();
5762
this.INET = exchange.getRemoteAddress();
5863

64+
this.PROTOCOL = exchange.getProtocol();
65+
this.SECURE = exchange instanceof HttpsExchange; // Can be suckered?
66+
5967
// Parse content length
6068
String contentLength = HEADERS.get("Content-Length") != null ? HEADERS.get("Content-Length").get(0) : null;
6169
this.CONTENT_LENGTH = contentLength != null ? Long.parseLong(contentLength) : -1;
@@ -223,6 +231,89 @@ public String getMethod() {
223231
return this.METHOD;
224232
}
225233

234+
/**
235+
* Checks if the connection is 'fresh'
236+
* It is true if the cache-control request header doesn’t have a no-cache directive, the if-modified-since request header is specified
237+
* and last-modified request header is equal to or earlier than the modified response header or if-none-match request header is *.
238+
*
239+
* @return True if the connection is fresh, false otherwise.
240+
*/
241+
public boolean isFresh() {
242+
243+
if (HEADERS.containsKey("cache-control") && HEADERS.get("cache-control").get(0) != null && HEADERS.get("cache-control").get(0).equals("no-cache"))
244+
return true;
245+
246+
if (HEADERS.containsKey("if-none-match") && HEADERS.get("if-none-match").get(0) != null && HEADERS.get("if-none-match").equals("*"))
247+
return true;
248+
249+
if (HEADERS.containsKey("if-modified-since") && HEADERS.containsKey("last-modified") && HEADERS.containsKey("modified")) {
250+
List<String> lmlist = HEADERS.get("last-modified");
251+
List<String> mlist = HEADERS.get("modified");
252+
253+
// Check lists
254+
if (lmlist.isEmpty() || mlist.isEmpty())
255+
return false;
256+
257+
String lm = lmlist.get(0);
258+
String m = mlist.get(0);
259+
260+
// Check header
261+
if (lm != null && m != null) {
262+
try {
263+
264+
// Try to convert it
265+
Instant lmi = Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(lm));
266+
Instant mi = Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(m));
267+
268+
if (lmi.isBefore(mi) || lmi.equals(mi)) {
269+
return true;
270+
}
271+
272+
} catch (Exception ignored) {
273+
}
274+
}
275+
}
276+
277+
return false;
278+
}
279+
280+
/**
281+
* Indicates whether the request is “stale,” and is the opposite of req.fresh
282+
*
283+
* @return The opposite of req.fresh;
284+
*/
285+
public boolean isStale() {
286+
return !isFresh();
287+
}
288+
289+
/**
290+
* Returns whenever the connection is over HTTPS.
291+
*
292+
* @return True when the connection is over HTTPS, false otherwise.
293+
*/
294+
public boolean isSecure() {
295+
return SECURE;
296+
}
297+
298+
/**
299+
* Returns true if the 'X-Requested-With' header field is 'XMLHttpRequest'.
300+
* Indicating that the request was made by a client library such as jQuery.
301+
*
302+
* @return True if the 'X-Requested-With' header field is 'XMLHttpRequest'.
303+
*/
304+
public boolean isXHR() {
305+
return HEADERS.containsKey("X-Requested-With") && !HEADERS.get("X-Requested-With").isEmpty() && HEADERS.get("X-Requested-With").get(0).equals("XMLHttpRequest");
306+
}
307+
308+
/**
309+
* The connection protocol HTTP/1.0, HTTP/1.1 etc.
310+
*
311+
* @return The connection protocol.
312+
*/
313+
public String getProtocol() {
314+
return PROTOCOL;
315+
}
316+
226317
/**
227318
* If there is an Authorization header, it was parsed and saved
228319
* in a Authorization Object.
@@ -321,5 +412,4 @@ public Express getApp() {
321412
return EXPRESS;
322413
}
323414

324-
325415
}

src/express/http/response/Response.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,23 @@ public void send(String s) {
184184
close();
185185
}
186186

187+
/**
188+
* Sets the 'Content-Disposition' header to 'attachment' and his
189+
* Content-Disposition "filename=" parameter to the file name.
190+
* Normally this triggers an download event client-side.
191+
*
192+
* @param file The file which will be send as attachment.
193+
*/
194+
public void sendAttachment(@NotNull Path file) {
195+
if (isClosed() || !Files.isRegularFile(file))
196+
return;
197+
198+
String dispo = "attachment; filename=\"" + file.getFileName() + "\"";
199+
setHeader("Content-Disposition", dispo);
200+
201+
send(file);
202+
}
203+
187204
/**
188205
* Send an entire file as response
189206
* The mime type will be automatically detected.

0 commit comments

Comments
 (0)