1//
2//  ========================================================================
3//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4//  ------------------------------------------------------------------------
5//  All rights reserved. This program and the accompanying materials
6//  are made available under the terms of the Eclipse Public License v1.0
7//  and Apache License v2.0 which accompanies this distribution.
8//
9//      The Eclipse Public License is available at
10//      http://www.eclipse.org/legal/epl-v10.html
11//
12//      The Apache License v2.0 is available at
13//      http://www.opensource.org/licenses/apache2.0.php
14//
15//  You may elect to redistribute this code under either of these licenses.
16//  ========================================================================
17//
18
19package org.eclipse.jetty.client;
20
21import java.io.ByteArrayOutputStream;
22import java.io.File;
23import java.io.FileInputStream;
24import java.io.IOException;
25import java.io.InputStream;
26import java.io.UnsupportedEncodingException;
27
28import org.eclipse.jetty.http.HttpHeaders;
29import org.eclipse.jetty.io.Buffer;
30import org.eclipse.jetty.io.BufferUtil;
31import org.eclipse.jetty.util.StringUtil;
32
33/**
34 * A exchange that retains response content for later use.
35 */
36public class ContentExchange extends CachedExchange
37{
38    private int _bufferSize = 4096;
39    private String _encoding = "utf-8";
40    private ByteArrayOutputStream _responseContent;
41    private File _fileForUpload;
42
43    public ContentExchange()
44    {
45        super(false);
46    }
47
48    public ContentExchange(boolean cacheFields)
49    {
50        super(cacheFields);
51    }
52
53    public synchronized String getResponseContent() throws UnsupportedEncodingException
54    {
55        if (_responseContent != null)
56            return _responseContent.toString(_encoding);
57        return null;
58    }
59
60    public synchronized byte[] getResponseContentBytes()
61    {
62        if (_responseContent != null)
63            return _responseContent.toByteArray();
64        return null;
65    }
66
67    @Override
68    protected synchronized void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
69    {
70        if (_responseContent!=null)
71            _responseContent.reset();
72        super.onResponseStatus(version,status,reason);
73    }
74
75    @Override
76    protected synchronized void onResponseHeader(Buffer name, Buffer value) throws IOException
77    {
78        super.onResponseHeader(name, value);
79        int header = HttpHeaders.CACHE.getOrdinal(name);
80        switch (header)
81        {
82            case HttpHeaders.CONTENT_LENGTH_ORDINAL:
83                _bufferSize = BufferUtil.toInt(value);
84                break;
85            case HttpHeaders.CONTENT_TYPE_ORDINAL:
86                String mime = StringUtil.asciiToLowerCase(value.toString());
87                int i = mime.indexOf("charset=");
88                if (i > 0)
89                {
90                    _encoding = mime.substring(i + 8);
91                    i = _encoding.indexOf(';');
92                    if (i > 0)
93                        _encoding = _encoding.substring(0, i);
94                }
95                break;
96        }
97    }
98
99    @Override
100    protected synchronized void onResponseContent(Buffer content) throws IOException
101    {
102        super.onResponseContent(content);
103        if (_responseContent == null)
104            _responseContent = new ByteArrayOutputStream(_bufferSize);
105        content.writeTo(_responseContent);
106    }
107
108    @Override
109    protected synchronized void onRetry() throws IOException
110    {
111        if (_fileForUpload != null)
112        {
113            setRequestContent(null);
114            setRequestContentSource(getInputStream());
115        }
116        else
117            super.onRetry();
118    }
119
120    private synchronized InputStream getInputStream() throws IOException
121    {
122        return new FileInputStream(_fileForUpload);
123    }
124
125    public synchronized File getFileForUpload()
126    {
127        return _fileForUpload;
128    }
129
130    public synchronized void setFileForUpload(File fileForUpload) throws IOException
131    {
132        this._fileForUpload = fileForUpload;
133        setRequestContentSource(getInputStream());
134    }
135}
136