How to make local test with okhttp - android

I am learning okhttp and I want to make a test with local json file in my computer or android device. But I don't know how to access local file as url string to call the function.
Like this:
File sdcard = Environment.getExternalStorageDirectory();
File testJson = new File(sdcard, "test.json");
HttpUtils.HttpGet(testJson., mCallback);
public class HttpUtils {
private static final String TAG = "HttpUtils";
private static final OkHttpClient mClient = new OkHttpClient();
public static void HttpGet(String url, Callback callback) {
//创建一个Request
final Request request = new Request.Builder()
.url(url)
.build();
//创建一个Call
Call call = mClient.newCall(request);
//请求加入调度
call.enqueue(callback);
}
}

You can use MockWebServer to serve content you load from a file.
https://github.com/square/okhttp/tree/master/mockwebserver
MockWebServer server = new MockWebServer();
// Schedule some responses.
server.enqueue(new MockResponse().setBody("hello, world!"));
server.enqueue(new MockResponse().setBody("sup, bra?"));
server.enqueue(new MockResponse().setBody("yo dog"));
// Start the server.
server.start();
// Ask the server for its URL. You'll need this to make HTTP requests.
HttpUrl baseUrl = server.url("/v1/chat/");

Well, you have to abstract your http client by some interface and create two implementation - one using OkHTTP and another - simply reading file.

Related

How to get references of variables in APK?

I'm doing the static analysis on Android APK file. Given the following source code:
protected void OkHttpClientCheck() throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.vogella.com/index.html")
.build();
Response response = client.newCall(request).execute();
}
So I can extract this source code uses OkHttpClient to open a connection and the target URL by using pattern matching (likes grep with regex). My question is, how do we map the OkHttpClient API with the corresponding url? In other words, I would like to output: "https://www.vogella.com/index.html" is called by OkHttpClient.
Can androguard do it or I need to perform static analysis with Soot or Flowdroid?
I have tried androguard but it could not extract the detail inside a method. Is it true or did I miss something?

How to pass files to WEB API from Android

I have Web API service and Android Client to consume that service. Data parsing is working as expected. But now I have to transfer some documents/files to the web API. I have tried to pass in query parameter as string (after converting document to base64 string), which is working fine only for document having length of 2-3KB. But for large files (1-4MB) I get Socket timeout exception at android side I have tried with increasing the socket timeout for both android (okhttp client) and the web API from the C# code in controller.
please you can suggest me any other way that make it better. I know this is not the right way to pass files. I have max file size of 4-5 MB.
I am adding the code snippet of both Android and Web API. thanks in advance
C#:
[System.Web.Http.HttpPost]
public JsonResultModel SaveClaimDocument(string cd)
{
HttpContext.Current.Server.ScriptTimeout = 300;
.....
}
Android Code:
new Thread() {
#Override
public void run() {
super.run();
OkHttpClient client = SingleConnectionManager.getInstance().getConnectionWithHighTimeOut();
String url = "http://" + Constants.IP + "/api/ClaimDocuments/SaveClaimDocument?cd=" + file_base;
try {
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("test", cd)
.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
//Set Before New Connection Request
System.setProperty("http.keepAlive", "false");
client.newCall(request).enqueue(new Callback() {
Edit:
Android Exception

OkHttp MockWebServer with dynamic URLs using Retrofit

My app uses dynamic URLs to make web-service calls (on Android). baseUrl is set as empty and we pass Retrofit2 #Url parameters in the service interface:
public interface UserService {
#GET
public Call<ResponseBody> profilePicture(#Url String url);
}
We don't know the host/domain in advance, so MockWebServer is not able to intercept the requests. The call to fetch the initial list of dynamic URLs is made in different screens. One idea is to create a new flavor providing a local data source for URLs to be used, which is my fallback plan.
I am curious if MockWebServer has any other methods to help test such cases and can be limited to test code.
You could use an OkHttp interceptor to rewrite the hostname and port?
I was also facing the same kind of issue. When I use MockWebserver in testing I have to change base URL to target mock web server localhost and port. I tried this it is working fine.
private static final Interceptor mRequestInterceptor = new Interceptor() {
#Override
public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
final InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(), 8080);
HttpUrl httpUrl = request.url().newBuilder().scheme("http://").host(address.getHostName()).port(8080)
.build();
request = request.newBuilder()
.url(httpUrl)
.build();
return chain.proceed(request);
}
};
After this base url changes to "http://localhost:8080/"

Is there a way to get passed in post request parameters during building process in Retrofit2.1.0?

I am trying to compute a checksum from HTTP arguments dynamically. And then I would like to add this checksum as an HTTP argument.
I need to get the fields that are passed in as parameters first, but it looks like retrofit can only access url query parameters.
#Gordak shows the way to get query parameter, but what I want to achive, if any possible, to get post parameters in the request chain.
Okay, here we go.
First, build your OkHTTP client and retrofit object.
OkHttpClient client = httpBuilder
.addNetworkInterceptor(INTERCEPTOR_REQUEST_ADD_CHECKSUM)
.build();
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.baseUrl("https://my.domain.com")
.build();
Then, you need to define your interceptor :
private static final Interceptor INTERCEPTOR_REQUEST_ADD_CHECKSUM = new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
HttpUrl url = chain.request().url();
String param1 = url.queryParameter("param1");
String param2 = url.queryParameter("param2");
String chk = aMethodToComputeChecksum(param1,param2);
url = url.newBuilder().addQueryParameter("checksum", chk).build();
Request request = chain.request().newBuilder().url(url).build();
return chain.proceed(request);
}
Maybe it will help - try to compute this parameter once and write it in RequestInterceptor

How to use disk cache to cache ParseFile

I'm using Parse and Picasso to load images onto ParseImageViews. Is there anything I'm missing to cache the parse files? My listview seems to be fetching the file from server every time and using the disk cache that comes with Picasso.
I don't see cache-control: max-age parameter in the http responses of downloads of parse files(from amazon s3 where parse stores them)
I have the following code,
final ParseImageView pic = viewHolder.img;
pic.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
ParseFile f = parseObject.getParseFile("image");
Picasso.with(mContext).load(f.getUrl()).into(pic);
Any help would be appreciated. Thanks.
Use OkHttp client as http transport for Picasso and specify disk and memory cache size:
OkHttpClient okHttp = new OkHttpClient();
Cache cache = new Cache(ctx.getCacheDir(), cacheSize);
okHttp.setCache(cache);
// Use OkHttp as downloader
Downloader downloader = new OkHttpDownloader(okHttp);
mPicasso = new Picasso.Builder(getApplicationContext())
.downloader(downloader)).memoryCache(new LruCache(size)).build();
Setup request interceptor (example) for OkHttp client:
// Add Cache-Control to origin response (force cache)
client.networkInterceptors().add(new Interceptor() {
private com.squareup.okhttp.Request request;
private Response response;
private String requestUrl;
#Override
public Response intercept(Chain c) throws IOException {
request = c.request();
response = c.proceed(request);
if (!request.cacheControl().noStore()
&& !response.cacheControl().noStore()) {
requestUrl = request.urlString();
// Do not cache keys or playlists
response = response
.newBuilder()
.header("Cache-Control","public, max-age=42000").build();
}
return response;
}
});

Categories

Resources