Example usage for io.netty.handler.codec.http HttpMethod HEAD

List of usage examples for io.netty.handler.codec.http HttpMethod HEAD

Introduction

In this page you can find the example usage for io.netty.handler.codec.http HttpMethod HEAD.

Prototype

HttpMethod HEAD

To view the source code for io.netty.handler.codec.http HttpMethod HEAD.

Click Source Link

Document

The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response.

Usage

From source file:com.chiorichan.http.HttpResponseWrapper.java

License:Mozilla Public License

public void sendMultipart(byte[] bytesToWrite) throws IOException {
    if (request.method() == HttpMethod.HEAD)
        throw new IllegalStateException("You can't start MULTIPART mode on a HEAD Request.");

    if (stage != HttpResponseStage.MULTIPART) {
        stage = HttpResponseStage.MULTIPART;
        HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);

        HttpHeaders h = response.headers();
        try {//from   w ww .j ava2 s.  c o  m
            request.getSession().save();
        } catch (SessionException e) {
            e.printStackTrace();
        }

        for (HttpCookie c : request.getCookies())
            if (c.needsUpdating())
                h.add("Set-Cookie", c.toHeaderValue());

        if (h.get("Server") == null)
            h.add("Server", Versioning.getProduct() + " Version " + Versioning.getVersion());

        h.add("Access-Control-Allow-Origin",
                request.getLocation().getConfig().getString("site.web-allowed-origin", "*"));
        h.add("Connection", "close");
        h.add("Cache-Control", "no-cache");
        h.add("Cache-Control", "private");
        h.add("Pragma", "no-cache");
        h.set("Content-Type", "multipart/x-mixed-replace; boundary=--cwsframe");

        // if ( isKeepAlive( request ) )
        {
            // response.headers().set( CONNECTION, HttpHeaders.Values.KEEP_ALIVE );
        }

        request.getChannel().write(response);
    } else {
        StringBuilder sb = new StringBuilder();

        sb.append("--cwsframe\r\n");
        sb.append("Content-Type: " + httpContentType + "\r\n");
        sb.append("Content-Length: " + bytesToWrite.length + "\r\n\r\n");

        ByteArrayOutputStream ba = new ByteArrayOutputStream();

        ba.write(sb.toString().getBytes(encoding));
        ba.write(bytesToWrite);
        ba.flush();

        ChannelFuture sendFuture = request.getChannel().write(
                new ChunkedStream(new ByteArrayInputStream(ba.toByteArray())),
                request.getChannel().newProgressivePromise());

        ba.close();

        sendFuture.addListener(new ChannelProgressiveFutureListener() {
            @Override
            public void operationComplete(ChannelProgressiveFuture future) throws Exception {
                NetworkManager.getLogger().info("Transfer complete.");
            }

            @Override
            public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) {
                if (total < 0)
                    NetworkManager.getLogger().info("Transfer progress: " + progress);
                else
                    NetworkManager.getLogger().info("Transfer progress: " + progress + " / " + total);
            }
        });
    }
}

From source file:com.couchbase.client.core.endpoint.view.ViewHandler.java

License:Apache License

@Override
protected HttpRequest encodeRequest(final ChannelHandlerContext ctx, final ViewRequest msg) throws Exception {
    if (msg instanceof KeepAliveRequest) {
        FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.HEAD, "/",
                Unpooled.EMPTY_BUFFER);/*from  www.j ava2 s.  c  o m*/
        request.headers().set(HttpHeaders.Names.USER_AGENT, env().userAgent());
        request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, 0);
        return request;
    }

    StringBuilder path = new StringBuilder();

    HttpMethod method = HttpMethod.GET;
    ByteBuf content = null;
    if (msg instanceof ViewQueryRequest) {
        ViewQueryRequest queryMsg = (ViewQueryRequest) msg;
        path.append("/").append(msg.bucket()).append("/_design/");
        path.append(queryMsg.development() ? "dev_" + queryMsg.design() : queryMsg.design());
        if (queryMsg.spatial()) {
            path.append("/_spatial/");
        } else {
            path.append("/_view/");
        }
        path.append(queryMsg.view());

        int queryLength = queryMsg.query() == null ? 0 : queryMsg.query().length();
        int keysLength = queryMsg.keys() == null ? 0 : queryMsg.keys().length();
        boolean hasQuery = queryLength > 0;
        boolean hasKeys = keysLength > 0;

        if (hasQuery || hasKeys) {
            if (queryLength + keysLength < MAX_GET_LENGTH) {
                //the query is short enough for GET
                //it has query, query+keys or keys only
                if (hasQuery) {
                    path.append("?").append(queryMsg.query());
                    if (hasKeys) {
                        path.append("&keys=").append(encodeKeysGet(queryMsg.keys()));
                    }
                } else {
                    //it surely has keys if not query
                    path.append("?keys=").append(encodeKeysGet(queryMsg.keys()));
                }
            } else {
                //the query is too long for GET, use the keys as JSON body
                if (hasQuery) {
                    path.append("?").append(queryMsg.query());
                }
                String keysContent = encodeKeysPost(queryMsg.keys());

                //switch to POST
                method = HttpMethod.POST;
                //body is "keys" but in JSON
                content = ctx.alloc().buffer(keysContent.length());
                content.writeBytes(keysContent.getBytes(CHARSET));
            }
        }
    } else if (msg instanceof GetDesignDocumentRequest) {
        GetDesignDocumentRequest queryMsg = (GetDesignDocumentRequest) msg;
        path.append("/").append(msg.bucket()).append("/_design/");
        path.append(queryMsg.development() ? "dev_" + queryMsg.name() : queryMsg.name());
    } else if (msg instanceof UpsertDesignDocumentRequest) {
        method = HttpMethod.PUT;
        UpsertDesignDocumentRequest queryMsg = (UpsertDesignDocumentRequest) msg;
        path.append("/").append(msg.bucket()).append("/_design/");
        path.append(queryMsg.development() ? "dev_" + queryMsg.name() : queryMsg.name());
        content = Unpooled.copiedBuffer(queryMsg.body(), CHARSET);
    } else if (msg instanceof RemoveDesignDocumentRequest) {
        method = HttpMethod.DELETE;
        RemoveDesignDocumentRequest queryMsg = (RemoveDesignDocumentRequest) msg;
        path.append("/").append(msg.bucket()).append("/_design/");
        path.append(queryMsg.development() ? "dev_" + queryMsg.name() : queryMsg.name());
    } else {
        throw new IllegalArgumentException("Unknown incoming ViewRequest type " + msg.getClass());
    }

    if (content == null) {
        content = Unpooled.buffer(0);
    }
    FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, method, path.toString(),
            content);
    request.headers().set(HttpHeaders.Names.USER_AGENT, env().userAgent());
    request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, content.readableBytes());
    request.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/json");
    request.headers().set(HttpHeaders.Names.HOST, remoteHttpHost(ctx));
    addHttpBasicAuth(ctx, request, msg.bucket(), msg.password());

    return request;
}

From source file:com.github.ambry.admin.AdminIntegrationTest.java

License:Open Source License

/**
 * Gets the headers of the blob with blob ID {@code blobId} and verifies them against what is expected.
 * @param blobId the blob ID of the blob to HEAD.
 * @param expectedHeaders the expected headers in the response.
 * @throws ExecutionException//w w w.j  a v  a  2 s  . c  o m
 * @throws InterruptedException
 */
private void getHeadAndVerify(String blobId, HttpHeaders expectedHeaders)
        throws ExecutionException, InterruptedException {
    FullHttpRequest httpRequest = buildRequest(HttpMethod.HEAD, blobId, null, null);
    Queue<HttpObject> responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    HttpResponse response = (HttpResponse) responseParts.poll();
    discardContent(responseParts, 1);
    assertEquals("Unexpected response status", HttpResponseStatus.OK, response.getStatus());
    checkCommonGetHeadHeaders(response.headers(), expectedHeaders);
    assertEquals("Content-Length does not match blob size",
            Long.parseLong(expectedHeaders.get(RestUtils.Headers.BLOB_SIZE)),
            HttpHeaders.getContentLength(response));
    assertEquals("Blob size does not match", expectedHeaders.get(RestUtils.Headers.BLOB_SIZE),
            HttpHeaders.getHeader(response, RestUtils.Headers.BLOB_SIZE));
    assertEquals(RestUtils.Headers.SERVICE_ID + " does not match",
            expectedHeaders.get(RestUtils.Headers.SERVICE_ID),
            HttpHeaders.getHeader(response, RestUtils.Headers.SERVICE_ID));
    assertEquals(RestUtils.Headers.PRIVATE + " does not match", expectedHeaders.get(RestUtils.Headers.PRIVATE),
            HttpHeaders.getHeader(response, RestUtils.Headers.PRIVATE));
    assertEquals(RestUtils.Headers.AMBRY_CONTENT_TYPE + " does not match",
            expectedHeaders.get(RestUtils.Headers.AMBRY_CONTENT_TYPE),
            HttpHeaders.getHeader(response, RestUtils.Headers.AMBRY_CONTENT_TYPE));
    assertTrue("No " + RestUtils.Headers.CREATION_TIME,
            HttpHeaders.getHeader(response, RestUtils.Headers.CREATION_TIME, null) != null);
    if (Long.parseLong(expectedHeaders.get(RestUtils.Headers.TTL)) != Utils.Infinite_Time) {
        assertEquals(RestUtils.Headers.TTL + " does not match", expectedHeaders.get(RestUtils.Headers.TTL),
                HttpHeaders.getHeader(response, RestUtils.Headers.TTL));
    }
    if (expectedHeaders.contains(RestUtils.Headers.OWNER_ID)) {
        assertEquals(RestUtils.Headers.OWNER_ID + " does not match",
                expectedHeaders.get(RestUtils.Headers.OWNER_ID),
                HttpHeaders.getHeader(response, RestUtils.Headers.OWNER_ID));
    }
}

From source file:com.github.ambry.admin.AdminIntegrationTest.java

License:Open Source License

/**
 * Verifies that the right response code is returned for GET, HEAD and DELETE once a blob is deleted.
 * @param blobId the ID of the blob that was deleted.
 * @throws ExecutionException//www.  j a  v a 2s.  co m
 * @throws InterruptedException
 */
private void verifyOperationsAfterDelete(String blobId) throws ExecutionException, InterruptedException {
    FullHttpRequest httpRequest = buildRequest(HttpMethod.GET, blobId, null, null);
    verifyDeleted(httpRequest, HttpResponseStatus.GONE);

    httpRequest = buildRequest(HttpMethod.HEAD, blobId, null, null);
    verifyDeleted(httpRequest, HttpResponseStatus.GONE);

    httpRequest = buildRequest(HttpMethod.DELETE, blobId, null, null);
    verifyDeleted(httpRequest, HttpResponseStatus.ACCEPTED);
}

From source file:com.github.ambry.frontend.FrontendIntegrationTest.java

License:Open Source License

/**
 * Gets the headers of the blob with blob ID {@code blobId} and verifies them against what is expected.
 * @param blobId the blob ID of the blob to HEAD.
 * @param expectedHeaders the expected headers in the response.
 * @throws ExecutionException//w  w  w  .j ava2s. c  o  m
 * @throws InterruptedException
 */
private void getHeadAndVerify(String blobId, HttpHeaders expectedHeaders)
        throws ExecutionException, InterruptedException {
    FullHttpRequest httpRequest = buildRequest(HttpMethod.HEAD, blobId, null, null);
    Queue<HttpObject> responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    HttpResponse response = (HttpResponse) responseParts.poll();
    assertEquals("Unexpected response status", HttpResponseStatus.OK, response.getStatus());
    checkCommonGetHeadHeaders(response.headers());
    assertEquals(RestUtils.Headers.CONTENT_LENGTH + " does not match " + RestUtils.Headers.BLOB_SIZE,
            Long.parseLong(expectedHeaders.get(RestUtils.Headers.BLOB_SIZE)),
            HttpHeaders.getContentLength(response));
    assertEquals(RestUtils.Headers.CONTENT_TYPE + " does not match " + RestUtils.Headers.AMBRY_CONTENT_TYPE,
            expectedHeaders.get(RestUtils.Headers.AMBRY_CONTENT_TYPE),
            HttpHeaders.getHeader(response, HttpHeaders.Names.CONTENT_TYPE));
    verifyBlobProperties(expectedHeaders, response);
    discardContent(responseParts, 1);
    assertTrue("Channel should be active", HttpHeaders.isKeepAlive(response));
}

From source file:com.github.ambry.rest.NettyMessageProcessorTest.java

License:Open Source License

/**
 * Tests for the common case request handling flow.
 * @throws IOException/*w  w w .  j  a  v  a2s.c o  m*/
 */
@Test
public void requestHandleWithGoodInputTest() throws IOException {
    doRequestHandleWithoutKeepAlive(HttpMethod.GET, RestMethod.GET);
    doRequestHandleWithoutKeepAlive(HttpMethod.DELETE, RestMethod.DELETE);
    doRequestHandleWithoutKeepAlive(HttpMethod.HEAD, RestMethod.HEAD);

    EmbeddedChannel channel = createChannel();
    doRequestHandleWithKeepAlive(channel, HttpMethod.GET, RestMethod.GET);
    doRequestHandleWithKeepAlive(channel, HttpMethod.DELETE, RestMethod.DELETE);
    doRequestHandleWithKeepAlive(channel, HttpMethod.HEAD, RestMethod.HEAD);
}

From source file:com.github.ambry.rest.NettyMultipartRequestTest.java

License:Open Source License

/**
 * Tests instantiation of {@link NettyMultipartRequest} with different {@link HttpMethod} types.
 * </p>/*from ww w  . j  a  v a 2  s. c om*/
 * Only {@link HttpMethod#POST} should succeed.
 * @throws RestServiceException
 */
@Test
public void instantiationTest() throws RestServiceException {
    // POST will succeed.
    HttpRequest httpRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/");
    closeRequestAndValidate(new NettyMultipartRequest(httpRequest, nettyMetrics));

    // Methods that will fail. Can include other methods, but these should be enough.
    HttpMethod[] methods = { HttpMethod.GET, HttpMethod.DELETE, HttpMethod.HEAD };
    for (HttpMethod method : methods) {
        httpRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, method, "/");
        try {
            new NettyMultipartRequest(httpRequest, nettyMetrics);
            fail("Creation of NettyMultipartRequest should have failed for " + method);
        } catch (IllegalArgumentException e) {
            // expected. Nothing to do.
        }
    }
}

From source file:com.github.ambry.rest.NettyRequest.java

License:Open Source License

/**
 * Wraps the {@code request} in an implementation of {@link RestRequest} so that other layers can understand the
 * request./*from  ww w  .j  a  v a 2s.  co m*/
 * <p/>
 * Note on content size: The content size is deduced in the following order:-
 * 1. From the {@link RestUtils.Headers#BLOB_SIZE} header.
 * 2. If 1 fails, from the {@link HttpHeaders.Names#CONTENT_LENGTH} header.
 * 3. If 2 fails, it is set to -1 which means that the content size is unknown.
 * If content size is set in the header (i.e. not -1), the actual content size should match that value. Otherwise, an
 * exception will be thrown.
 * @param request the {@link HttpRequest} that needs to be wrapped.
 * @param nettyMetrics the {@link NettyMetrics} instance to use.
 * @throws IllegalArgumentException if {@code request} is null.
 * @throws RestServiceException if the {@link HttpMethod} defined in {@code request} is not recognized as a
 *                                {@link RestMethod}.
 */
public NettyRequest(HttpRequest request, NettyMetrics nettyMetrics) throws RestServiceException {
    if (request == null) {
        throw new IllegalArgumentException("Received null HttpRequest");
    }
    restRequestMetricsTracker.nioMetricsTracker.markRequestReceived();
    HttpMethod httpMethod = request.getMethod();
    if (httpMethod == HttpMethod.GET) {
        restMethod = RestMethod.GET;
    } else if (httpMethod == HttpMethod.POST) {
        restMethod = RestMethod.POST;
    } else if (httpMethod == HttpMethod.DELETE) {
        restMethod = RestMethod.DELETE;
    } else if (httpMethod == HttpMethod.HEAD) {
        restMethod = RestMethod.HEAD;
    } else {
        nettyMetrics.unsupportedHttpMethodError.inc();
        throw new RestServiceException("http method not supported: " + httpMethod,
                RestServiceErrorCode.UnsupportedHttpMethod);
    }
    this.request = request;
    this.query = new QueryStringDecoder(request.getUri());
    this.nettyMetrics = nettyMetrics;

    if (HttpHeaders.getHeader(request, RestUtils.Headers.BLOB_SIZE, null) != null) {
        size = Long.parseLong(HttpHeaders.getHeader(request, RestUtils.Headers.BLOB_SIZE));
    } else {
        size = HttpHeaders.getContentLength(request, -1);
    }

    // query params.
    for (Map.Entry<String, List<String>> e : query.parameters().entrySet()) {
        StringBuilder value = null;
        if (e.getValue() != null) {
            StringBuilder combinedValues = combineVals(new StringBuilder(), e.getValue());
            if (combinedValues.length() > 0) {
                value = combinedValues;
            }
        }
        allArgs.put(e.getKey(), value);
    }

    Set<io.netty.handler.codec.http.Cookie> nettyCookies = null;
    // headers.
    for (Map.Entry<String, String> e : request.headers()) {
        StringBuilder sb;
        if (e.getKey().equals(HttpHeaders.Names.COOKIE)) {
            String value = e.getValue();
            if (value != null) {
                nettyCookies = CookieDecoder.decode(value);
            }
        } else {
            boolean valueNull = request.headers().get(e.getKey()) == null;
            if (!valueNull && allArgs.get(e.getKey()) == null) {
                sb = new StringBuilder(e.getValue());
                allArgs.put(e.getKey(), sb);
            } else if (!valueNull) {
                sb = (StringBuilder) allArgs.get(e.getKey());
                sb.append(MULTIPLE_HEADER_VALUE_DELIMITER).append(e.getValue());
            } else if (!allArgs.containsKey(e.getKey())) {
                allArgs.put(e.getKey(), null);
            }
        }
    }

    // turn all StringBuilders into String
    for (Map.Entry<String, Object> e : allArgs.entrySet()) {
        if (allArgs.get(e.getKey()) != null) {
            allArgs.put(e.getKey(), (e.getValue()).toString());
        }
    }
    // add cookies to the args as java cookies
    if (nettyCookies != null) {
        Set<javax.servlet.http.Cookie> cookies = convertHttpToJavaCookies(nettyCookies);
        allArgs.put(RestUtils.Headers.COOKIE, cookies);
    }
    allArgsReadOnly = Collections.unmodifiableMap(allArgs);
}

From source file:com.github.ambry.rest.NettyRequestTest.java

License:Open Source License

/**
 * Tests conversion of {@link HttpRequest} to {@link NettyRequest} given good input.
 * @throws RestServiceException//from  w ww  .j av  a 2  s  .c o m
 */
@Test
public void conversionWithGoodInputTest() throws RestServiceException {
    // headers
    HttpHeaders headers = new DefaultHttpHeaders(false);
    headers.add(HttpHeaders.Names.CONTENT_LENGTH, new Random().nextInt(Integer.MAX_VALUE));
    headers.add("headerKey", "headerValue1");
    headers.add("headerKey", "headerValue2");
    headers.add("overLoadedKey", "headerOverloadedValue");
    headers.add("paramNoValueInUriButValueInHeader", "paramValueInHeader");
    headers.add("headerNoValue", (Object) null);
    headers.add("headerNoValueButValueInUri", (Object) null);

    // params
    Map<String, List<String>> params = new HashMap<String, List<String>>();
    List<String> values = new ArrayList<String>(2);
    values.add("paramValue1");
    values.add("paramValue2");
    params.put("paramKey", values);
    values = new ArrayList<String>(1);
    values.add("paramOverloadedValue");
    params.put("overLoadedKey", values);
    values = new ArrayList<String>(1);
    values.add("headerValueInUri");
    params.put("headerNoValueButValueInUri", values);
    params.put("paramNoValue", null);
    params.put("paramNoValueInUriButValueInHeader", null);

    StringBuilder uriAttachmentBuilder = new StringBuilder("?");
    for (Map.Entry<String, List<String>> param : params.entrySet()) {
        if (param.getValue() != null) {
            for (String value : param.getValue()) {
                uriAttachmentBuilder.append(param.getKey()).append("=").append(value).append("&");
            }
        } else {
            uriAttachmentBuilder.append(param.getKey()).append("&");
        }
    }
    uriAttachmentBuilder.deleteCharAt(uriAttachmentBuilder.length() - 1);
    String uriAttachment = uriAttachmentBuilder.toString();

    NettyRequest nettyRequest;
    String uri;
    Set<Cookie> cookies = new HashSet<Cookie>();
    Cookie httpCookie = new DefaultCookie("CookieKey1", "CookieValue1");
    cookies.add(httpCookie);
    httpCookie = new DefaultCookie("CookieKey2", "CookieValue2");
    cookies.add(httpCookie);
    headers.add(RestUtils.Headers.COOKIE, getCookiesHeaderValue(cookies));

    uri = "/GET" + uriAttachment;
    nettyRequest = createNettyRequest(HttpMethod.GET, uri, headers);
    validateRequest(nettyRequest, RestMethod.GET, uri, headers, params, cookies);
    closeRequestAndValidate(nettyRequest);

    uri = "/POST" + uriAttachment;
    nettyRequest = createNettyRequest(HttpMethod.POST, uri, headers);
    validateRequest(nettyRequest, RestMethod.POST, uri, headers, params, cookies);
    closeRequestAndValidate(nettyRequest);

    uri = "/DELETE" + uriAttachment;
    nettyRequest = createNettyRequest(HttpMethod.DELETE, uri, headers);
    validateRequest(nettyRequest, RestMethod.DELETE, uri, headers, params, cookies);
    closeRequestAndValidate(nettyRequest);

    uri = "/HEAD" + uriAttachment;
    nettyRequest = createNettyRequest(HttpMethod.HEAD, uri, headers);
    validateRequest(nettyRequest, RestMethod.HEAD, uri, headers, params, cookies);
    closeRequestAndValidate(nettyRequest);
}

From source file:com.github.ambry.rest.NettyResponseChannelTest.java

License:Open Source License

/**
 * Tests that HEAD returns no body in error responses.
 *//*  w  ww.  ja v  a  2 s .c  om*/
@Test
public void noBodyForHeadTest() {
    EmbeddedChannel channel = createEmbeddedChannel();
    for (Map.Entry<RestServiceErrorCode, HttpResponseStatus> entry : REST_ERROR_CODE_TO_HTTP_STATUS
            .entrySet()) {
        HttpHeaders httpHeaders = new DefaultHttpHeaders();
        httpHeaders.set(MockNettyMessageProcessor.REST_SERVICE_ERROR_CODE_HEADER_NAME, entry.getKey());
        channel.writeInbound(RestTestUtils.createRequest(HttpMethod.HEAD,
                TestingUri.OnResponseCompleteWithRestException.toString(), httpHeaders));
        HttpResponse response = (HttpResponse) channel.readOutbound();
        assertEquals("Unexpected response status", entry.getValue(), response.getStatus());
        if (response instanceof FullHttpResponse) {
            // assert that there is no content
            assertEquals("The response should not contain content", 0,
                    ((FullHttpResponse) response).content().readableBytes());
        } else {
            HttpContent content = (HttpContent) channel.readOutbound();
            assertTrue("End marker should be received", content instanceof LastHttpContent);
        }
        assertNull("There should be no more data in the channel", channel.readOutbound());
        boolean shouldBeAlive = !NettyResponseChannel.CLOSE_CONNECTION_ERROR_STATUSES
                .contains(entry.getValue());
        assertEquals("Channel state (open/close) not as expected", shouldBeAlive, channel.isActive());
        assertEquals("Connection header should be consistent with channel state", shouldBeAlive,
                HttpHeaders.isKeepAlive(response));
        if (!shouldBeAlive) {
            channel = createEmbeddedChannel();
        }
    }
    channel.close();
}