Пример #1
0
  @Override
  public void setCharacterEncoding(String encoding) {
    if (isIncluding()) return;

    if (_outputType == OutputType.NONE && !isCommitted()) {
      if (encoding == null) {
        // Clear any encoding.
        if (_characterEncoding != null) {
          _characterEncoding = null;
          if (_contentType != null) {
            _contentType = MimeTypes.getContentTypeWithoutCharset(_contentType);
            HttpField field = HttpField.CONTENT_TYPE.get(_contentType);
            if (field != null) _fields.put(field);
            else _fields.put(HttpHeader.CONTENT_TYPE, _contentType);
          }
        }
      } else {
        // No, so just add this one to the mimetype
        _characterEncoding = StringUtil.normalizeCharset(encoding);
        if (_contentType != null) {
          _contentType =
              MimeTypes.getContentTypeWithoutCharset(_contentType)
                  + ";charset="
                  + _characterEncoding;
          HttpField field = HttpField.CONTENT_TYPE.get(_contentType);
          if (field != null) _fields.put(field);
          else _fields.put(HttpHeader.CONTENT_TYPE, _contentType);
        }
      }
    }
  }
Пример #2
0
  /* ------------------------------------------------------------ */
  private HttpContent load(String pathInContext, Resource resource) throws IOException {
    Content content = null;

    if (resource == null || !resource.exists()) return null;

    // Will it fit in the cache?
    if (!resource.isDirectory() && isCacheable(resource)) {
      // Create the Content (to increment the cache sizes before adding the content
      content = new Content(pathInContext, resource);

      // reduce the cache to an acceptable size.
      shrinkCache();

      // Add it to the cache.
      Content added = _cache.putIfAbsent(pathInContext, content);
      if (added != null) {
        content.invalidate();
        content = added;
      }

      return content;
    }

    return new HttpContent.ResourceAsHttpContent(
        resource,
        _mimeTypes.getMimeByExtension(resource.toString()),
        getMaxCachedFileSize(),
        _etags);
  }
Пример #3
0
  @Override
  public PrintWriter getWriter() throws IOException {
    if (_outputType == OutputType.STREAM) throw new IllegalStateException("STREAM");

    if (_outputType == OutputType.NONE) {
      /* get encoding from Content-Type header */
      String encoding = _characterEncoding;
      if (encoding == null) {
        encoding = MimeTypes.inferCharsetFromContentType(_contentType);
        if (encoding == null) encoding = StringUtil.__ISO_8859_1;
        setCharacterEncoding(encoding);
      }

      if (_writer != null && _writer.isFor(encoding)) _writer.reopen();
      else {
        if (StringUtil.__ISO_8859_1.equalsIgnoreCase(encoding))
          _writer = new ResponseWriter(new Iso88591HttpWriter(_out), encoding);
        else if (StringUtil.__UTF8.equalsIgnoreCase(encoding))
          _writer = new ResponseWriter(new Utf8HttpWriter(_out), encoding);
        else _writer = new ResponseWriter(new EncodingHttpWriter(_out, encoding), encoding);
      }

      // Set the output type at the end, because setCharacterEncoding() checks for it
      _outputType = OutputType.WRITER;
    }
    return _writer;
  }
Пример #4
0
  @Override
  public boolean parsedHeader(HttpField field) {
    HttpHeader header = field.getHeader();
    String value = field.getValue();
    if (value == null) value = "";
    if (header != null) {
      switch (header) {
        case EXPECT:
          if (_version.getVersion() >= HttpVersion.HTTP_1_1.getVersion()) {
            HttpHeaderValue expect = HttpHeaderValue.CACHE.get(value);
            switch (expect == null ? HttpHeaderValue.UNKNOWN : expect) {
              case CONTINUE:
                _expect100Continue = true;
                break;

              case PROCESSING:
                _expect102Processing = true;
                break;

              default:
                String[] values = value.split(",");
                for (int i = 0; values != null && i < values.length; i++) {
                  expect = HttpHeaderValue.CACHE.get(values[i].trim());
                  if (expect == null) _expect = true;
                  else {
                    switch (expect) {
                      case CONTINUE:
                        _expect100Continue = true;
                        break;
                      case PROCESSING:
                        _expect102Processing = true;
                        break;
                      default:
                        _expect = true;
                    }
                  }
                }
            }
          }
          break;

        case CONTENT_TYPE:
          MimeTypes.Type mime = MimeTypes.CACHE.get(value);
          String charset =
              (mime == null || mime.getCharset() == null)
                  ? MimeTypes.getCharsetFromContentType(value)
                  : mime.getCharset().toString();
          if (charset != null) _request.setCharacterEncodingUnchecked(charset);
          break;
        default:
      }
    }

    if (field.getName() != null) _request.getHttpFields().add(field);
    return false;
  }
Пример #5
0
  @Override
  public void setContentType(String contentType) {
    if (isCommitted() || isIncluding()) return;

    if (contentType == null) {
      if (isWriting() && _characterEncoding != null) throw new IllegalSelectorException();

      if (_locale == null) _characterEncoding = null;
      _mimeType = null;
      _contentType = null;
      _fields.remove(HttpHeader.CONTENT_TYPE);
    } else {
      _contentType = contentType;
      _mimeType = MimeTypes.CACHE.get(contentType);
      String charset;
      if (_mimeType != null && _mimeType.getCharset() != null)
        charset = _mimeType.getCharset().toString();
      else charset = MimeTypes.getCharsetFromContentType(contentType);

      if (charset == null) {
        if (_characterEncoding != null) {
          _contentType = contentType + ";charset=" + _characterEncoding;
          _mimeType = null;
        }
      } else if (isWriting() && !charset.equals(_characterEncoding)) {
        // too late to change the character encoding;
        _mimeType = null;
        _contentType = MimeTypes.getContentTypeWithoutCharset(_contentType);
        if (_characterEncoding != null)
          _contentType = _contentType + ";charset=" + _characterEncoding;
      } else {
        _characterEncoding = charset;
      }

      HttpField field = HttpField.CONTENT_TYPE.get(_contentType);
      if (field != null) _fields.put(field);
      else _fields.put(HttpHeader.CONTENT_TYPE, _contentType);
    }
  }
    /* ------------------------------------------------------------ */
    CachedHttpContent(String pathInContext, Resource resource, CachedHttpContent gzipped) {
      _key = pathInContext;
      _resource = resource;

      String contentType = _mimeTypes.getMimeByExtension(_resource.toString());
      _contentType =
          contentType == null
              ? null
              : new PreEncodedHttpField(HttpHeader.CONTENT_TYPE, contentType);
      _characterEncoding =
          _contentType == null ? null : MimeTypes.getCharsetFromContentType(contentType);
      _mimeType =
          _contentType == null
              ? null
              : MimeTypes.CACHE.get(MimeTypes.getContentTypeWithoutCharset(contentType));

      boolean exists = resource.exists();
      _lastModifiedValue = exists ? resource.lastModified() : -1L;
      _lastModified =
          _lastModifiedValue == -1
              ? null
              : new PreEncodedHttpField(
                  HttpHeader.LAST_MODIFIED, DateGenerator.formatDate(_lastModifiedValue));

      _contentLengthValue = exists ? (int) resource.length() : 0;
      _contentLength =
          new PreEncodedHttpField(HttpHeader.CONTENT_LENGTH, Long.toString(_contentLengthValue));

      if (_cachedFiles.incrementAndGet() > _maxCachedFiles) shrinkCache();

      _lastAccessed = System.currentTimeMillis();

      _etag =
          ResourceCache.this._etags
              ? new PreEncodedHttpField(HttpHeader.ETAG, resource.getWeakETag())
              : null;

      _gzipped = gzipped == null ? null : new CachedGzipHttpContent(this, gzipped);
    }
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String fileName = request.getServletPath();
    byte[] dataBytes = loadContentFileBytes(fileName);

    response.setContentLength(dataBytes.length);
    if (fileName.endsWith(".js")) {
      // intentionally long-form content type to test ";" splitting in code
      response.setContentType("text/javascript; charset=utf-8");
    } else {
      String mime = mimeTypes.getMimeByExtension(fileName);
      if (mime != null) response.setContentType(mime);
    }
    ServletOutputStream out = response.getOutputStream();
    out.write(dataBytes);
  }
Пример #8
0
    /*
     * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#parsedHeaderValue(org.eclipse.io.Buffer)
     */
    @Override
    public void parsedHeader(Buffer name, Buffer value) {
      int ho = HttpHeaders.CACHE.getOrdinal(name);
      switch (ho) {
        case HttpHeaders.HOST_ORDINAL:
          // TODO check if host matched a host in the URI.
          _host = true;
          break;

        case HttpHeaders.EXPECT_ORDINAL:
          value = HttpHeaderValues.CACHE.lookup(value);
          switch (HttpHeaderValues.CACHE.getOrdinal(value)) {
            case HttpHeaderValues.CONTINUE_ORDINAL:
              _expect100Continue = _generator instanceof HttpGenerator;
              break;

            case HttpHeaderValues.PROCESSING_ORDINAL:
              _expect102Processing = _generator instanceof HttpGenerator;
              break;

            default:
              String[] values = value.toString().split(",");
              for (int i = 0; values != null && i < values.length; i++) {
                CachedBuffer cb = HttpHeaderValues.CACHE.get(values[i].trim());
                if (cb == null) _expect = true;
                else {
                  switch (cb.getOrdinal()) {
                    case HttpHeaderValues.CONTINUE_ORDINAL:
                      _expect100Continue = _generator instanceof HttpGenerator;
                      break;
                    case HttpHeaderValues.PROCESSING_ORDINAL:
                      _expect102Processing = _generator instanceof HttpGenerator;
                      break;
                    default:
                      _expect = true;
                  }
                }
              }
          }
          break;

        case HttpHeaders.ACCEPT_ENCODING_ORDINAL:
        case HttpHeaders.USER_AGENT_ORDINAL:
          value = HttpHeaderValues.CACHE.lookup(value);
          break;

        case HttpHeaders.CONTENT_TYPE_ORDINAL:
          value = MimeTypes.CACHE.lookup(value);
          _charset = MimeTypes.getCharsetFromContentType(value);
          break;

        case HttpHeaders.CONNECTION_ORDINAL:
          // looks rather clumsy, but the idea is to optimize for a single valued header
          switch (HttpHeaderValues.CACHE.getOrdinal(value)) {
            case -1:
              {
                String[] values = value.toString().split(",");
                for (int i = 0; values != null && i < values.length; i++) {
                  CachedBuffer cb = HttpHeaderValues.CACHE.get(values[i].trim());

                  if (cb != null) {
                    switch (cb.getOrdinal()) {
                      case HttpHeaderValues.CLOSE_ORDINAL:
                        _responseFields.add(
                            HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
                        _generator.setPersistent(false);
                        break;

                      case HttpHeaderValues.KEEP_ALIVE_ORDINAL:
                        if (_version == HttpVersions.HTTP_1_0_ORDINAL)
                          _responseFields.add(
                              HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.KEEP_ALIVE_BUFFER);
                        break;
                    }
                  }
                }
                break;
              }
            case HttpHeaderValues.CLOSE_ORDINAL:
              _responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
              _generator.setPersistent(false);
              break;

            case HttpHeaderValues.KEEP_ALIVE_ORDINAL:
              if (_version == HttpVersions.HTTP_1_0_ORDINAL)
                _responseFields.put(
                    HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.KEEP_ALIVE_BUFFER);
              break;
          }
      }

      _requestFields.add(name, value);
    }
  protected void commit(ByteBuffer content, boolean complete, Callback callback) {
    // Are we excluding because of status?
    Response response = _channel.getResponse();
    int sc = response.getStatus();
    if (sc > 0 && (sc < 200 || sc == 204 || sc == 205 || sc >= 300)) {
      LOG.debug("{} exclude by status {}", this, sc);
      noCompression();

      if (sc == 304) {
        String request_etags =
            (String) _channel.getRequest().getAttribute("o.e.j.s.h.gzip.GzipHandler.etag");
        String response_etag = response.getHttpFields().get(HttpHeader.ETAG);
        if (request_etags != null && response_etag != null) {
          String response_etag_gzip = etagGzip(response_etag);
          if (request_etags.contains(response_etag_gzip))
            response.getHttpFields().put(HttpHeader.ETAG, response_etag_gzip);
        }
      }

      _interceptor.write(content, complete, callback);
      return;
    }

    // Are we excluding because of mime-type?
    String ct = response.getContentType();
    if (ct != null) {
      ct = MimeTypes.getContentTypeWithoutCharset(ct);
      if (!_factory.isMimeTypeGzipable(StringUtil.asciiToLowerCase(ct))) {
        LOG.debug("{} exclude by mimeType {}", this, ct);
        noCompression();
        _interceptor.write(content, complete, callback);
        return;
      }
    }

    // Has the Content-Encoding header already been set?
    HttpFields fields = response.getHttpFields();
    String ce = fields.get(HttpHeader.CONTENT_ENCODING);
    if (ce != null) {
      LOG.debug("{} exclude by content-encoding {}", this, ce);
      noCompression();
      _interceptor.write(content, complete, callback);
      return;
    }

    // Are we the thread that commits?
    if (_state.compareAndSet(GZState.MIGHT_COMPRESS, GZState.COMMITTING)) {
      // We are varying the response due to accept encoding header.
      if (_vary != null) {
        if (fields.contains(HttpHeader.VARY)) fields.addCSV(HttpHeader.VARY, _vary.getValues());
        else fields.add(_vary);
      }

      long content_length = response.getContentLength();
      if (content_length < 0 && complete) content_length = content.remaining();

      _deflater = _factory.getDeflater(_channel.getRequest(), content_length);

      if (_deflater == null) {
        LOG.debug("{} exclude no deflater", this);
        _state.set(GZState.NOT_COMPRESSING);
        _interceptor.write(content, complete, callback);
        return;
      }

      fields.put(GZIP._contentEncoding);
      _crc.reset();
      _buffer = _channel.getByteBufferPool().acquire(_bufferSize, false);
      BufferUtil.fill(_buffer, GZIP_HEADER, 0, GZIP_HEADER.length);

      // Adjust headers
      response.setContentLength(-1);
      String etag = fields.get(HttpHeader.ETAG);
      if (etag != null) fields.put(HttpHeader.ETAG, etagGzip(etag));

      LOG.debug("{} compressing {}", this, _deflater);
      _state.set(GZState.COMPRESSING);

      gzip(content, complete, callback);
    } else callback.failed(new WritePendingException());
  }
  /* ------------------------------------------------------------ */
  private HttpContent load(String pathInContext, Resource resource, int maxBufferSize)
      throws IOException {
    if (resource == null || !resource.exists()) return null;

    if (resource.isDirectory())
      return new ResourceHttpContent(
          resource, _mimeTypes.getMimeByExtension(resource.toString()), getMaxCachedFileSize());

    // Will it fit in the cache?
    if (isCacheable(resource)) {
      CachedHttpContent content = null;

      // Look for a gzip resource
      if (_gzip) {
        String pathInContextGz = pathInContext + ".gz";
        CachedHttpContent contentGz = _cache.get(pathInContextGz);
        if (contentGz == null || !contentGz.isValid()) {
          contentGz = null;
          Resource resourceGz = _factory.getResource(pathInContextGz);
          if (resourceGz.exists()
              && resourceGz.lastModified() >= resource.lastModified()
              && resourceGz.length() < resource.length()) {
            contentGz = new CachedHttpContent(pathInContextGz, resourceGz, null);
            CachedHttpContent added = _cache.putIfAbsent(pathInContextGz, contentGz);
            if (added != null) {
              contentGz.invalidate();
              contentGz = added;
            }
          }
        }
        content = new CachedHttpContent(pathInContext, resource, contentGz);
      } else content = new CachedHttpContent(pathInContext, resource, null);

      // Add it to the cache.
      CachedHttpContent added = _cache.putIfAbsent(pathInContext, content);
      if (added != null) {
        content.invalidate();
        content = added;
      }

      return content;
    }

    // Look for non Cacheable gzip resource or content
    String mt = _mimeTypes.getMimeByExtension(pathInContext);
    if (_gzip) {
      // Is the gzip content cached?
      String pathInContextGz = pathInContext + ".gz";
      CachedHttpContent contentGz = _cache.get(pathInContextGz);
      if (contentGz != null
          && contentGz.isValid()
          && contentGz.getResource().lastModified() >= resource.lastModified())
        return new ResourceHttpContent(resource, mt, maxBufferSize, contentGz);

      // Is there a gzip resource?
      Resource resourceGz = _factory.getResource(pathInContextGz);
      if (resourceGz.exists()
          && resourceGz.lastModified() >= resource.lastModified()
          && resourceGz.length() < resource.length())
        return new ResourceHttpContent(
            resource,
            mt,
            maxBufferSize,
            new ResourceHttpContent(
                resourceGz, _mimeTypes.getMimeByExtension(pathInContextGz), maxBufferSize));
    }

    return new ResourceHttpContent(resource, mt, maxBufferSize);
  }