Skip to content

Commit f72cdb4

Browse files
committed
http: add minimal HEAD support in the mover
some clients do send HEAD after redirect Acked-by: Gerd Behrmann Target: master Require-book: no Require-notes: no (cherry picked from commit 8040e1e) Signed-off-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
1 parent 256034d commit f72cdb4

File tree

3 files changed

+69
-8
lines changed

3 files changed

+69
-8
lines changed

modules/dcache/src/main/java/org/dcache/http/HttpPoolRequestHandler.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ private static ChannelFuture sendGetResponse(ChannelHandlerContext context,
197197
FsPath path = new FsPath(file.getProtocolInfo().getPath());
198198

199199
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
200+
response.headers().add(ACCEPT_RANGES, BYTES);
200201
response.setHeader(CONTENT_LENGTH, file.size());
201202
String digest = buildDigest(file);
202203
if(!digest.isEmpty()) {
@@ -211,6 +212,27 @@ private static ChannelFuture sendGetResponse(ChannelHandlerContext context,
211212
return context.getChannel().write(response);
212213
}
213214

215+
private static ChannelFuture sendHeadResponse(ChannelHandlerContext context,
216+
MoverChannel<HttpProtocolInfo> file)
217+
throws IOException {
218+
FsPath path = new FsPath(file.getProtocolInfo().getPath());
219+
220+
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
221+
response.headers().add(ACCEPT_RANGES, BYTES);
222+
response.headers().add(CONTENT_LENGTH, file.size());
223+
String digest = buildDigest(file);
224+
if (!digest.isEmpty()) {
225+
response.headers().add(DIGEST, digest);
226+
}
227+
response.headers().add("Content-Disposition", contentDisposition(path
228+
.getName()));
229+
if (file.getProtocolInfo().getLocation() != null) {
230+
response.headers().add(CONTENT_LOCATION, file.getProtocolInfo().getLocation());
231+
}
232+
233+
return context.getChannel().write(response);
234+
}
235+
214236
private static String contentDisposition(String filename)
215237
{
216238
StringBuilder sb = new StringBuilder();
@@ -581,6 +603,32 @@ protected void doOnChunk(ChannelHandlerContext context, MessageEvent event,
581603
}
582604
}
583605

606+
@Override
607+
protected void doOnHead(ChannelHandlerContext context,
608+
MessageEvent event,
609+
HttpRequest request) {
610+
ChannelFuture future = null;
611+
MoverChannel<HttpProtocolInfo> file;
612+
613+
try {
614+
file = open(request, false);
615+
future = sendHeadResponse(context, file);
616+
} catch (IOException | IllegalArgumentException e) {
617+
future = conditionalSendError(context, request.getMethod(),
618+
future, BAD_REQUEST, e.getMessage());
619+
} catch (URISyntaxException e) {
620+
future = conditionalSendError(context, request.getMethod(),
621+
future, BAD_REQUEST, "URI not valid: " + e.getMessage());
622+
} catch (RuntimeException e) {
623+
future = conditionalSendError(context, request.getMethod(),
624+
future, INTERNAL_SERVER_ERROR, e.getMessage());
625+
} finally {
626+
if (future != null && !isKeepAlive()) {
627+
future.addListener(ChannelFutureListener.CLOSE);
628+
}
629+
}
630+
}
631+
584632
/**
585633
* Get the mover channel for a certain HTTP request. The mover
586634
* channel is identified by UUID generated upon mover start and

modules/dcache/src/main/java/org/dcache/http/HttpRequestHandler.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public void messageReceived(ChannelHandlerContext ctx, MessageEvent event) {
5656
doOnPost(ctx, event, request);
5757
} else if (request.getMethod() == HttpMethod.DELETE) {
5858
doOnDelete(ctx, event, request);
59+
} else if (request.getMethod() == HttpMethod.HEAD) {
60+
doOnHead(ctx, event, request);
5961
} else {
6062
unsupported(ctx, event);
6163
}
@@ -94,6 +96,12 @@ protected void doOnChunk(ChannelHandlerContext context, MessageEvent event,
9496
unsupported(context, event);
9597
}
9698

99+
protected void doOnHead(ChannelHandlerContext context, MessageEvent event,
100+
HttpRequest request) {
101+
_logger.info("Received a HEAD request, writing default response.");
102+
unsupported(context, event);
103+
}
104+
97105
/**
98106
* Send an HTTP error with the given status code and message.
99107
*

modules/dcache/src/test/java/org/dcache/http/HttpPoolRequestHandlerTests.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import static com.google.common.base.Preconditions.checkState;
5252
import static org.hamcrest.Matchers.*;
5353
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
54+
import static org.jboss.netty.handler.codec.http.HttpHeaders.Values.*;
5455
import static org.jboss.netty.handler.codec.http.HttpMethod.*;
5556
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
5657
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
@@ -146,7 +147,7 @@ public void shouldDeliverCompleteFileIfReceivesRequestForWholeFile()
146147
assertThat(_response, hasHeader(CONTENT_DISPOSITION,
147148
"attachment;filename=file"));
148149
assertThat(_response, not(hasHeader(DIGEST)));
149-
assertThat(_response, not(hasHeader(ACCEPT_RANGES)));
150+
assertThat(_response, hasHeader(ACCEPT_RANGES, BYTES));
150151
assertThat(_response, not(hasHeader(CONTENT_RANGE)));
151152

152153
assertThat(_additionalWrites, hasSize(1));
@@ -169,7 +170,7 @@ public void shouldDeliverCompleteFileWithChecksumIfReceivesRequestForWholeFileWi
169170
assertThat(_response, hasHeader(CONTENT_DISPOSITION,
170171
"attachment;filename=file"));
171172
assertThat(_response, hasHeader(DIGEST, "adler32=03da0195"));
172-
assertThat(_response, not(hasHeader(ACCEPT_RANGES)));
173+
assertThat(_response, hasHeader(ACCEPT_RANGES, BYTES));
173174
assertThat(_response, not(hasHeader(CONTENT_RANGE)));
174175

175176
assertThat(_additionalWrites, hasSize(1));
@@ -192,7 +193,7 @@ public void shouldDeliverCompleteFileIfReceivesRequestForWholeFileWithQuestionMa
192193
assertThat(_response, hasHeader(CONTENT_DISPOSITION,
193194
"attachment;filename=\"file?here\""));
194195
assertThat(_response, not(hasHeader(DIGEST)));
195-
assertThat(_response, not(hasHeader(ACCEPT_RANGES)));
196+
assertThat(_response, hasHeader(ACCEPT_RANGES, BYTES));
196197
assertThat(_response, not(hasHeader(CONTENT_RANGE)));
197198

198199
assertThat(_additionalWrites, hasSize(1));
@@ -216,7 +217,7 @@ public void shouldDeliverCompleteFileIfReceivesRequestForWholeFileWithBackslashQ
216217
assertThat(_response, hasHeader(CONTENT_DISPOSITION,
217218
"attachment;filename=\"file\\\\\\\"here\""));
218219
assertThat(_response, not(hasHeader(DIGEST)));
219-
assertThat(_response, not(hasHeader(ACCEPT_RANGES)));
220+
assertThat(_response, hasHeader(ACCEPT_RANGES, BYTES));
220221
assertThat(_response, not(hasHeader(CONTENT_RANGE)));
221222

222223
assertThat(_additionalWrites, hasSize(1));
@@ -245,7 +246,7 @@ public void shouldDeliverCompleteFileIfReceivesRequestForWholeFileWithNonAsciiNa
245246
assertThat(_response, hasHeader(CONTENT_DISPOSITION,
246247
"attachment;filename*=UTF-8''%E1%9A%A0%E1%9B%87%E1%9A%BB"));
247248
assertThat(_response, not(hasHeader(DIGEST)));
248-
assertThat(_response, not(hasHeader(ACCEPT_RANGES)));
249+
assertThat(_response, hasHeader(ACCEPT_RANGES, BYTES));
249250
assertThat(_response, not(hasHeader(CONTENT_RANGE)));
250251

251252
assertThat(_additionalWrites, hasSize(1));
@@ -380,12 +381,16 @@ public void shouldRejectConnectRequests()
380381
}
381382

382383
@Test
383-
public void shouldRejectHeadRequests()
384+
public void shouldAcceptHeadRequests() throws URISyntaxException
384385
{
385-
whenClientMakes(a(HEAD).forUri("/path/to/file"));
386+
givenPoolHas(file("/path/to/file").withSize(1024));
387+
givenDoorHasOrganisedReadOf(file("/path/to/file").with(SOME_UUID));
388+
whenClientMakes(a(HEAD)
389+
.forUri("/path/to/file?dcache-http-uuid=" + SOME_UUID));
386390

387-
assertThat(_response.getStatus(), is(NOT_IMPLEMENTED));
391+
assertThat(_response.getStatus(), is(OK));
388392
assertThat(_response, hasHeader(CONTENT_LENGTH));
393+
assertThat(_response, hasHeader(ACCEPT_RANGES, BYTES));
389394
}
390395

391396
@Test

0 commit comments

Comments
 (0)