Home | History | Annotate | Download | only in okhttp
      1 /*
      2  * Copyright (C) 2013 Square, Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.squareup.okhttp;
     17 
     18 import com.squareup.okhttp.internal.Util;
     19 import java.io.File;
     20 import java.io.FileWriter;
     21 import java.io.IOException;
     22 import java.net.URI;
     23 import java.net.URL;
     24 import java.util.Arrays;
     25 import java.util.Collections;
     26 import okio.Buffer;
     27 import org.junit.Test;
     28 
     29 import static org.junit.Assert.assertEquals;
     30 import static org.junit.Assert.assertNull;
     31 import static org.junit.Assert.fail;
     32 
     33 public final class RequestTest {
     34   @Test public void string() throws Exception {
     35     MediaType contentType = MediaType.parse("text/plain; charset=utf-8");
     36     RequestBody body = RequestBody.create(contentType, "abc".getBytes(Util.UTF_8));
     37     assertEquals(contentType, body.contentType());
     38     assertEquals(3, body.contentLength());
     39     assertEquals("616263", bodyToHex(body));
     40     assertEquals("Retransmit body", "616263", bodyToHex(body));
     41   }
     42 
     43   @Test public void stringWithDefaultCharsetAdded() throws Exception {
     44     MediaType contentType = MediaType.parse("text/plain");
     45     RequestBody body = RequestBody.create(contentType, "\u0800");
     46     assertEquals(MediaType.parse("text/plain; charset=utf-8"), body.contentType());
     47     assertEquals(3, body.contentLength());
     48     assertEquals("e0a080", bodyToHex(body));
     49   }
     50 
     51   @Test public void stringWithNonDefaultCharsetSpecified() throws Exception {
     52     MediaType contentType = MediaType.parse("text/plain; charset=utf-16be");
     53     RequestBody body = RequestBody.create(contentType, "\u0800");
     54     assertEquals(contentType, body.contentType());
     55     assertEquals(2, body.contentLength());
     56     assertEquals("0800", bodyToHex(body));
     57   }
     58 
     59   @Test public void byteArray() throws Exception {
     60     MediaType contentType = MediaType.parse("text/plain");
     61     RequestBody body = RequestBody.create(contentType, "abc".getBytes(Util.UTF_8));
     62     assertEquals(contentType, body.contentType());
     63     assertEquals(3, body.contentLength());
     64     assertEquals("616263", bodyToHex(body));
     65     assertEquals("Retransmit body", "616263", bodyToHex(body));
     66   }
     67 
     68   @Test public void byteArrayRange() throws Exception {
     69     MediaType contentType = MediaType.parse("text/plain");
     70     RequestBody body = RequestBody.create(contentType, ".abcd".getBytes(Util.UTF_8), 1, 3);
     71     assertEquals(contentType, body.contentType());
     72     assertEquals(3, body.contentLength());
     73     assertEquals("616263", bodyToHex(body));
     74     assertEquals("Retransmit body", "616263", bodyToHex(body));
     75   }
     76 
     77   @Test public void file() throws Exception {
     78     File file = File.createTempFile("RequestTest", "tmp");
     79     FileWriter writer = new FileWriter(file);
     80     writer.write("abc");
     81     writer.close();
     82 
     83     MediaType contentType = MediaType.parse("text/plain");
     84     RequestBody body = RequestBody.create(contentType, file);
     85     assertEquals(contentType, body.contentType());
     86     assertEquals(3, body.contentLength());
     87     assertEquals("616263", bodyToHex(body));
     88     assertEquals("Retransmit body", "616263", bodyToHex(body));
     89   }
     90 
     91   /** Common verbs used for apis such as GitHub, AWS, and Google Cloud. */
     92   @Test public void crudVerbs() throws IOException {
     93     MediaType contentType = MediaType.parse("application/json");
     94     RequestBody body = RequestBody.create(contentType, "{}");
     95 
     96     Request get = new Request.Builder().url("http://localhost/api").get().build();
     97     assertEquals("GET", get.method());
     98     assertNull(get.body());
     99 
    100     Request head = new Request.Builder().url("http://localhost/api").head().build();
    101     assertEquals("HEAD", head.method());
    102     assertNull(head.body());
    103 
    104     Request delete = new Request.Builder().url("http://localhost/api").delete().build();
    105     assertEquals("DELETE", delete.method());
    106     assertEquals(0L, delete.body().contentLength());
    107 
    108     Request post = new Request.Builder().url("http://localhost/api").post(body).build();
    109     assertEquals("POST", post.method());
    110     assertEquals(body, post.body());
    111 
    112     Request put = new Request.Builder().url("http://localhost/api").put(body).build();
    113     assertEquals("PUT", put.method());
    114     assertEquals(body, put.body());
    115 
    116     Request patch = new Request.Builder().url("http://localhost/api").patch(body).build();
    117     assertEquals("PATCH", patch.method());
    118     assertEquals(body, patch.body());
    119   }
    120 
    121   @Test public void uninitializedURI() throws Exception {
    122     Request request = new Request.Builder().url("http://localhost/api").build();
    123     assertEquals(new URI("http://localhost/api"), request.uri());
    124     assertEquals(new URL("http://localhost/api"), request.url());
    125   }
    126 
    127   @Test public void newBuilderUrlResetsUrl() throws Exception {
    128     Request requestWithoutCache = new Request.Builder().url("http://localhost/api").build();
    129     Request builtRequestWithoutCache = requestWithoutCache.newBuilder().url("http://localhost/api/foo").build();
    130     assertEquals(new URL("http://localhost/api/foo"), builtRequestWithoutCache.url());
    131 
    132     Request requestWithCache = new Request.Builder().url("http://localhost/api").build();
    133     // cache url object
    134     requestWithCache.url();
    135     Request builtRequestWithCache = requestWithCache.newBuilder().url(
    136         "http://localhost/api/foo").build();
    137     assertEquals(new URL("http://localhost/api/foo"), builtRequestWithCache.url());
    138   }
    139 
    140   @Test public void cacheControl() throws Exception {
    141     Request request = new Request.Builder()
    142         .cacheControl(new CacheControl.Builder().noCache().build())
    143         .url("https://square.com")
    144         .build();
    145     assertEquals(Arrays.asList("no-cache"), request.headers("Cache-Control"));
    146   }
    147 
    148   @Test public void emptyCacheControlClearsAllCacheControlHeaders() throws Exception {
    149     Request request = new Request.Builder()
    150         .header("Cache-Control", "foo")
    151         .cacheControl(new CacheControl.Builder().build())
    152         .url("https://square.com")
    153         .build();
    154     assertEquals(Collections.<String>emptyList(), request.headers("Cache-Control"));
    155   }
    156 
    157   @Test public void headerAcceptsPermittedCharacters() throws Exception {
    158     Request.Builder builder = new Request.Builder();
    159     builder.header("AZab09 ~", "AZab09 ~");
    160     builder.addHeader("AZab09 ~", "AZab09 ~");
    161   }
    162 
    163   @Test public void emptyNameForbidden() throws Exception {
    164     Request.Builder builder = new Request.Builder();
    165     try {
    166       builder.header("", "Value");
    167       fail();
    168     } catch (IllegalArgumentException expected) {
    169     }
    170     try {
    171       builder.addHeader("", "Value");
    172       fail();
    173     } catch (IllegalArgumentException expected) {
    174     }
    175   }
    176 
    177   @Test public void headerAllowsTabOnlyInValues() throws Exception {
    178     Request.Builder builder = new Request.Builder();
    179     builder.header("key", "sample\tvalue");
    180     try {
    181       builder.header("sample\tkey", "value");
    182       fail();
    183     } catch (IllegalArgumentException expected) {
    184     }
    185   }
    186 
    187   @Test public void headerForbidsControlCharacters() throws Exception {
    188     assertForbiddenHeader(null);
    189     assertForbiddenHeader("\u0000");
    190     // Workaround for http://b/26422335 , http://b/26889631
    191     // assertForbiddenHeader("\n");
    192     assertForbiddenHeader("a\nb");
    193     assertForbiddenHeader("\nb");
    194     // assertForbiddenHeader("\r");
    195     assertForbiddenHeader("a\rb");
    196     assertForbiddenHeader("\rb");
    197     // End of Android modification.
    198     assertForbiddenHeader("\u001f");
    199     assertForbiddenHeader("\u007f");
    200 
    201     // ANDROID-BEGIN Workaround for http://b/28867041
    202     // assertForbiddenHeader("\u0080");
    203     // assertForbiddenHeader("\ud83c\udf69");
    204     // ANDROID-END
    205   }
    206 
    207   private void assertForbiddenHeader(String s) {
    208     Request.Builder builder = new Request.Builder();
    209     try {
    210       builder.header(s, "Value");
    211       fail();
    212     } catch (IllegalArgumentException expected) {
    213     }
    214     try {
    215       builder.addHeader(s, "Value");
    216       fail();
    217     } catch (IllegalArgumentException expected) {
    218     }
    219     try {
    220       builder.header("Name", s);
    221       fail();
    222     } catch (IllegalArgumentException expected) {
    223     }
    224     try {
    225       builder.addHeader("Name", s);
    226       fail();
    227     } catch (IllegalArgumentException expected) {
    228     }
    229   }
    230 
    231   private String bodyToHex(RequestBody body) throws IOException {
    232     Buffer buffer = new Buffer();
    233     body.writeTo(buffer);
    234     return buffer.readByteString().hex();
    235   }
    236 }
    237