Skip to content

Commit 4ebfd7a

Browse files
committed
1 parent c5e2871 commit 4ebfd7a

9 files changed

Lines changed: 86 additions & 32 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# ActFramework Change Log
22

33
**1.6.0 TBD**
4+
* css resource `Content-Type` not set in prod mode #430
45
* ParamLoader: POJO instance not intialized if no field is set #429
56
* Support loading `AdaptiveRecord` from form post data #428
67
* java.lang.ClassCastException when ACT startup with session.ttl configuration #427

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
<okhttp.version>3.8.1</okhttp.version>
8181
<osgl-tool.version>1.4.4</osgl-tool.version>
8282
<osgl-genie.version>1.2.1-BETA-2</osgl-genie.version>
83+
<osgl-http.version>1.1.4-SNAPSHOT</osgl-http.version>
8384
<osgl-mvc.version>1.3.0</osgl-mvc.version>
8485
<osgl-storage.version>1.4.1</osgl-storage.version>
8586
<osgl-tool-ext.version>1.0.1</osgl-tool-ext.version>
@@ -418,6 +419,12 @@
418419
<version>${osgl-mvc.version}</version>
419420
</dependency>
420421

422+
<dependency>
423+
<groupId>org.osgl</groupId>
424+
<artifactId>osgl-http</artifactId>
425+
<version>${osgl-http.version}</version>
426+
</dependency>
427+
421428
<dependency>
422429
<groupId>org.osgl</groupId>
423430
<artifactId>osgl-storage</artifactId>

src/main/java/act/ActResponse.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public abstract class ActResponse<T extends ActResponse> extends H.Response<T> {
3838
protected String charset;
3939
protected Locale locale;
4040
protected String contentType;
41+
protected H.Format fmt;
4142
private boolean charsetSet;
4243

4344
protected ActResponse() {}
@@ -74,6 +75,16 @@ public T sendRedirect(String location) {
7475
throw new Redirect(location);
7576
}
7677

78+
public T contentType(H.Format fmt) {
79+
contentType(fmt.contentType());
80+
this.fmt = fmt;
81+
return me();
82+
}
83+
84+
public H.Format lastContentType() {
85+
return fmt;
86+
}
87+
7788
/**
7889
* Mark the framework is ready to write to the response.
7990
*/

src/main/java/act/app/ActionContext.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,12 @@ public ActionContext applyContentType(Result result) {
574574
}
575575

576576
public ActionContext applyContentType() {
577+
ActResponse resp = resp();
578+
H.Format lastContentType = resp.lastContentType();
579+
if (null != lastContentType && $.ne(H.Format.UNKNOWN, lastContentType)) {
580+
resp.commitContentType();
581+
return this;
582+
}
577583
H.Request req = req();
578584
H.Format fmt = req.accept();
579585
if (H.Format.UNKNOWN == fmt) {

src/main/java/act/controller/ResponseCache.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ public H.Response contentType(String type) {
129129
return this;
130130
}
131131

132+
@Override
133+
public ActResponse contentType(H.Format fmt) {
134+
contentType = fmt.contentType();
135+
return super.contentType(fmt);
136+
}
137+
132138
@Override
133139
public H.Response initContentType(String type) {
134140
realResponse.initContentType(type);

src/main/java/act/handler/builtin/AlwaysNotModified.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class AlwaysNotModified extends FastRequestHandler implements ExpressHand
3131

3232
@Override
3333
public void handle(ActionContext context) {
34+
context.applyContentType();
3435
NotModified.get().apply(context.req(), context.prepareRespForWrite());
3536
}
3637

src/main/java/act/handler/builtin/FileGetter.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* #L%
2121
*/
2222

23+
import act.ActResponse;
2324
import act.app.ActionContext;
2425
import act.app.App;
2526
import act.controller.ParamNames;
@@ -83,9 +84,9 @@ public void handle(ActionContext context) {
8384
return;
8485
}
8586
}
86-
H.Response resp = context.prepareRespForWrite();
87+
ActResponse resp = context.prepareRespForWrite();
8788
fmt = contentType(file.getPath());
88-
resp.contentType(fmt.contentType());
89+
resp.contentType(fmt);
8990
context.applyCorsSpec().applyContentType();
9091
InputStream is = new BufferedInputStream(IO.is(file));
9192
IO.copy(is, resp.outputStream());

src/main/java/act/handler/builtin/ResourceGetter.java

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
*/
2222

2323
import act.Act;
24+
import act.ActResponse;
2425
import act.app.ActionContext;
2526
import act.controller.ParamNames;
2627
import act.handler.builtin.controller.FastRequestHandler;
@@ -38,6 +39,7 @@
3839
import java.util.*;
3940

4041
import static org.osgl.http.H.Format.*;
42+
import static org.osgl.http.H.Header.Names.CACHE_CONTROL;
4143

4244
/**
4345
* Unlike a {@link FileGetter}, the
@@ -54,15 +56,15 @@ public class ResourceGetter extends FastRequestHandler {
5456
private int preloadSizeLimit;
5557
private boolean isFolder;
5658
private ByteBuffer buffer;
57-
private H.Format contentType;
59+
private H.Format preloadedContentType;
5860
private boolean preloadFailure;
5961
private boolean preloaded;
6062
private String etag;
6163

6264
private Set<URL> folders = new HashSet<>();
6365
private Map<String, String> etags = new HashMap<>();
6466
private Map<String, ByteBuffer> cachedBuffers = new HashMap<>();
65-
private Map<String, String> cachedContentType = new HashMap<>();
67+
private Map<String, H.Format> cachedContentType = new HashMap<>();
6668
private Map<String, Boolean> cachedFailures = new HashMap<>();
6769

6870
public ResourceGetter(String base) {
@@ -114,43 +116,58 @@ public void handle(ActionContext context) {
114116
protected void handle(String path, ActionContext context) {
115117
H.Request req = context.req();
116118
if (Act.isProd()) {
119+
ActResponse resp = context.prepareRespForWrite();
117120
if (preloaded) {
118121
// this is a reloaded file resource
119122
if (preloadFailure) {
120123
AlwaysNotFound.INSTANCE.handle(context);
121124
} else {
125+
resp.contentType(preloadedContentType);
122126
if (req.etagMatches(etag)) {
123127
AlwaysNotModified.INSTANCE.handle(context);
124128
} else {
125-
H.Response resp = context.prepareRespForWrite();
126-
resp.contentType(contentType.contentType())
129+
H.Format contentType = cachedContentType.get(path);
130+
if (null == contentType) {
131+
contentType = req.contentType();
132+
}
133+
resp
134+
.contentType(contentType)
135+
.header(CACHE_CONTROL, "public, max-age=7200")
127136
.etag(this.etag)
128137
.writeContent(buffer.duplicate());
129138
}
130139
}
131140
return;
132141
}
142+
133143
if (cachedFailures.containsKey(path)) {
134144
AlwaysNotFound.INSTANCE.handle(context);
135145
return;
136146
}
137147

138148
if (null != req.etag() && req.etagMatches(etags.get(path))) {
149+
H.Format contentType = cachedContentType.get(path);
150+
if (null == contentType) {
151+
contentType = req.contentType();
152+
}
153+
resp.contentType(contentType);
139154
AlwaysNotModified.INSTANCE.handle(context);
140155
return;
141156
}
142157
}
143158
ByteBuffer buffer = cachedBuffers.get(path);
144159
if (null != buffer) {
145-
context.prepareRespForWrite()
160+
context.resp()
146161
.contentType(cachedContentType.get(path))
162+
.header(CACHE_CONTROL, "public, max-age=7200");
163+
context.applyContentType();
164+
context.prepareRespForWrite()
147165
.etag(etags.get(path))
148166
.writeContent(buffer.duplicate());
149167
return;
150168
}
151169
try {
152170
URL target;
153-
H.Format fmt;
154171
String loadPath;
155172
if (S.blank(path)) {
156173
target = baseUrl;
@@ -165,9 +182,12 @@ protected void handle(String path, ActionContext context) {
165182
if (preventFolderAccess(target, loadPath, context)) {
166183
return;
167184
}
168-
fmt = FileGetter.contentType(target.getPath());
169-
H.Response resp = context.prepareRespForWrite();
170-
resp.contentType(fmt.contentType());
185+
H.Format contentType = FileGetter.contentType(target.getPath());
186+
ActResponse resp = context.prepareRespForWrite();
187+
resp.contentType(contentType);
188+
if (Act.isProd()) {
189+
resp.header(CACHE_CONTROL, "public, max-age=7200");
190+
}
171191
context.applyCorsSpec().applyContentType();
172192
try {
173193
int n = IO.copy(target.openStream(), resp.outputStream());
@@ -180,7 +200,7 @@ protected void handle(String path, ActionContext context) {
180200
cachedFailures.put(path, true);
181201
} else {
182202
cachedBuffers.put(path, buffer);
183-
cachedContentType.put(path, fmt.contentType());
203+
cachedContentType.put(path, contentType);
184204
}
185205
}
186206
}
@@ -227,7 +247,7 @@ private void preloadCache() {
227247
if (Act.isDev()) {
228248
return;
229249
}
230-
contentType = FileGetter.contentType(baseUrl.getPath());
250+
H.Format contentType = FileGetter.contentType(baseUrl.getPath());
231251
if (HTML == contentType || CSS == contentType || JAVASCRIPT == contentType
232252
|| TXT == contentType || CSV == contentType
233253
|| JSON == contentType || XML == contentType
@@ -239,6 +259,7 @@ private void preloadCache() {
239259
} else {
240260
this.etag = etagBag.get();
241261
}
262+
preloadedContentType = contentType;
242263
preloaded = true;
243264
}
244265
}

src/main/java/act/inject/param/AdaptiveRecordLoader.java

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
package act.inject.param;
22

3-
/*-
4-
* #%L
5-
* ACT Framework
6-
* %%
7-
* Copyright (C) 2014 - 2017 ActFramework
8-
* %%
9-
* Licensed under the Apache License, Version 2.0 (the "License");
10-
* you may not use this file except in compliance with the License.
11-
* You may obtain a copy of the License at
12-
*
13-
* http://www.apache.org/licenses/LICENSE-2.0
14-
*
15-
* Unless required by applicable law or agreed to in writing, software
16-
* distributed under the License is distributed on an "AS IS" BASIS,
17-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18-
* See the License for the specific language governing permissions and
19-
* limitations under the License.
20-
* #L%
21-
*/
3+
/*-
4+
* #%L
5+
* ACT Framework
6+
* %%
7+
* Copyright (C) 2014 - 2017 ActFramework
8+
* %%
9+
* Licensed under the Apache License, Version 2.0 (the "License");
10+
* you may not use this file except in compliance with the License.
11+
* You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS,
17+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* See the License for the specific language governing permissions and
19+
* limitations under the License.
20+
* #L%
21+
*/
2222

2323
import act.db.AdaptiveRecord;
2424
import act.util.ActContext;

0 commit comments

Comments
 (0)