简体   繁体   中英

Parsing curl response with Java

Before writing something like "why don't you use Java HTTP client such as apache, etc" , I need you to know that the reason is SSL. I wish I could, they are very convenient, but I can't.

None of the available HTTP clients support GOST cipher suite, and I get handshake exception all the time. The ones which do support the suite, doesn't support SNI (they are also proprietary) - I'm returned with a wrong cert and get handshake exception over and over again.

The only solution was to configure openssl (with gost engine) and curl and finally execute the command with Java.

Having said that, I wrote a simple snippet for executing a command and getting input stream response:

public static InputStream executeCurlCommand(String finalCurlCommand) throws IOException 
{
    return Runtime.getRuntime().exec(finalCurlCommand).getInputStream();
}

Additionally, I can convert the returned IS to a string like that:

public static String convertResponseToString(InputStream isToConvertToString) throws IOException 
{
    StringWriter writer = new StringWriter();
    IOUtils.copy(isToConvertToString, writer, "UTF-8");
    return writer.toString();
}

However, I can't see a pattern according to which I could get a good response or a desired response header:

Here's what I mean

After executing a command (with -i flag), there might be lots and lots of information like in the screen below: 在此处输入图片说明

At first, I thought that I could just split it with '\\n' , but the thing is that a required response's header or a response itself may not satisfy the criteria (prettified JSON or long redirect URL break the rule).

Also, the static line GOST engine already loaded is a bit annoying (but I hope that I'll be able to get rid of it and nothing unrelated info like that will emerge)

I do believe that there's a pattern which I can use.

For now I can only do that:

public static String getLocationRedirectHeaderValue(String curlResponse) 
{
    String locationHeaderValue = curlResponse.substring(curlResponse.indexOf("Location: "));
    locationHeaderValue = locationHeaderValue.substring(0, locationHeaderValue.indexOf("\n")).replace("Location: ", "");
    return locationHeaderValue;
}

Which is not nice, obviosuly

Thanks in advance.

Instead of reading the whole result as a single string you might want to consider reading it line by line using a scanner .

Then keep a few status variables around. The main task would be to separate header from body. In the body you might have a payload you want to treat differently (eg use GSON to make a JSON object).

The nice thing: Header and Body are separated by an empty line. So your code would be along these lines:

boolean inHeader = true;
StringBuilder b = new StringBuilder;
String lastLine = "";
// Technically you would need Multimap
Map<String,String> headers = new HashMap<>();
Scanner scanner = new Scanner(yourInputStream);
while scanner.hasNextLine() {
   String line = scanner.nextLine();
   if (line.length() == 0) {
      inHeader = false;
   } else {
      if (inHeader) {
        // if line starts with space it is 
        // continuation of previous header
        treatHeader(line, lastLine);
      } else {
        b.append(line);
        b.appen(System.lineSeparator());
      }
   }
}
String body = b.toString();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM