/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package io.milton.restlet; import io.milton.http.AbstractRequest; import io.milton.http.Auth; import io.milton.http.Cookie; import io.milton.http.Request.Header; import io.milton.http.Request.Method; import io.milton.http.RequestParseException; import org.apache.commons.fileupload.FileItem; import org.restlet.data.Form; import org.restlet.data.MediaType; import org.restlet.engine.adapter.HttpRequest; import org.restlet.util.Series; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; public class RequestAdapter extends AbstractRequest { final protected HttpRequest target; protected Auth auth; RequestAdapter(HttpRequest target) { this.target = target; } public HttpRequest getTarget() { return target; } protected Series<org.restlet.engine.header.Header> getRawHeaders() { return getTarget().getHttpCall().getRequestHeaders(); } @Override public String getRequestHeader(Header header) { return getRawHeaders().getValues(header.code); } @Override public Map<String, String> getHeaders() { return getRawHeaders().getValuesMap(); } @Override public String getFromAddress() { return getTarget().getClientInfo().getAddress(); } @Override public String getRemoteAddr() { return getTarget().getClientInfo().getAddress(); } @Override public Method getMethod() { return Method.valueOf(getTarget().getMethod().getName()); } @Override public Auth getAuthorization() { if (auth != null) { return auth; } String enc = getRequestHeader(Header.AUTHORIZATION); if (enc == null) { return null; } if (enc.length() == 0) { return null; } auth = new Auth(enc); return auth; } @Override public void setAuthorization(Auth auth) { this.auth = auth; } @Override public String getAbsoluteUrl() { return getTarget().getOriginalRef().toString(); } @Override public InputStream getInputStream() throws IOException { // Milton doesn't check for null InputStream, but there are some places where it checks for -1 // Don't call target.isEntityAvailable(), doesn't work for PUT, see its source... if (getTarget().getEntity() != null && getTarget().getEntity().isAvailable()) { InputStream stream = getTarget().getEntity().getStream(); if (stream != null) return stream; } return new InputStream() { @Override public int read() throws IOException { return -1; } }; } @Override public void parseRequestParameters(Map<String, String> params, Map<String, io.milton.http.FileItem> files) throws RequestParseException { // GET params if (getTarget().getOriginalRef().hasQuery()) { params.putAll( getTarget().getOriginalRef().getQueryAsForm(true).getValuesMap() ); } // Again, don't use Request#isEntityAvailable(), it restricts methods if (getTarget().getEntity() != null && getTarget().getEntity().isAvailable()) { if (MediaType.APPLICATION_WWW_FORM.equals(getTarget().getEntity().getMediaType(), true)) { params.putAll( new Form(getTarget().getEntity(), true).getValuesMap() ); } else if (MediaType.MULTIPART_FORM_DATA.equals(getTarget().getEntity().getMediaType(), true)) { throw new UnsupportedOperationException("Multipart file uploading not implemented"); /* TODO: Two reasons why this is not done: 1. it doesn't seem to work, but because we have no tests, we don't know 2. someone has to clean up the temp files, so we have to use background threads or something try { RestletFileUpload fileUpload = new RestletFileUpload(new DiskFileItemFactory()); List<FileItem> fileItems = fileUpload.parseRepresentation(getTarget().getEntity()); for (FileItem fileItem : fileItems) { if (fileItem.isFormField()) { params.put(fileItem.getFieldName(), fileItem.getString()); } else { files.put(fileItem.getFieldName(), new FileItemWrapper(fileItem)); } } } catch (FileUploadException ex) { throw new RequestParseException("FileUploadException", ex); } catch (Throwable ex) { throw new RequestParseException(ex.getMessage(), ex); } */ } } } @Override public Cookie getCookie(String name) { if (getTarget().getCookies().size() > 0) { for (org.restlet.data.Cookie cookie : getTarget().getCookies()) { if (cookie.getName().equals(name)) { return new CookieAdapter(cookie); } } } return null; } @Override public List<Cookie> getCookies() { List<Cookie> cookies = new ArrayList<Cookie>(); for (org.restlet.data.Cookie cookie : getTarget().getCookies()) { cookies.add(new CookieAdapter(cookie)); } return cookies; } // Copied from milton-servlet.. public static class FileItemWrapper implements io.milton.http.FileItem { final FileItem wrapped; final String name; /** * strip path information provided by IE * * @param s * @return */ public static String fixIEFileName(String s) { if (s.contains("\\")) { int pos = s.lastIndexOf('\\'); s = s.substring(pos + 1); } return s; } public FileItemWrapper(FileItem wrapped) { this.wrapped = wrapped; name = fixIEFileName(wrapped.getName()); } public String getContentType() { return wrapped.getContentType(); } public String getFieldName() { return wrapped.getFieldName(); } public InputStream getInputStream() { try { return wrapped.getInputStream(); } catch (IOException ex) { throw new RuntimeException(ex); } } public OutputStream getOutputStream() { try { return wrapped.getOutputStream(); } catch (IOException ex) { throw new RuntimeException(ex); } } public String getName() { return name; } public long getSize() { return wrapped.getSize(); } } }