Modify URLSession incoming traffic?

I need the URLSession to be able to interpret non-compliant HTTP-like responses. The response may contain a non-standard status-line HTTP version (SOURCETABLE, instead of HTTP/1.1), may be missing a CRLF to separate the status-line and message body and may contain custom headers.

My thought is to intercept and modify the textual traffic to make it HTTP-compliant. How would I intercept and modify the traffic in Swift?

I'm considering intercepting and modifying the request to be optimal, since it requires the least amount of rewriting (reinventing the wheel with URLSession HTTP support). Alternatively, I've considered using a custom URLProtocol. However, this appears to require writing a lot of the HTTP parsing code.

Answered by DTS Engineer in 725787022

The response may contain a non-standard status-line HTTP version … may be missing a CRLF to separate the status-line and message body and may contain custom headers.

Custom headers shouldn’t be a problem, assuming they follow the basic HTTP layout. The other two, however, are serious problems. I don’t see how you can get around this without “writing a lot of the HTTP parsing code”.

Imagine you could get at the byte stream underlying the session’s connection. How would you fix this? Well, to fix the CR LF problem you need to write your own parser to find where the header-to-body break is and insert it. Doing that correctly is implementing an HTTP parser (well, not HTTP, obviously, but a protocol that’s just as complicated).

This will be much worse if the origin server supports HTTP persistent connections, and worse again if you have to deal with the chunked transfer encoding.

If you want to go down that path you could implement an HTTP proxy and tell your URLSession to use that via the connectionProxyDictionary property. However, I suspect that’s needless complexity, and it’s likely you’d be better implementing this protocol directly on top Network framework.

If you need help with the specifics of parsing an HTTP message, you can use CFHTTPMessage for that. It’s ugly, but it’s quite helpful in situations like this.


Oh, there is another way forward here: Find the person who implementing this HTTP Just Kidding™ protocol and beat them with a rubber hose yell at them until they decide that it was a bad idea and fix their server (-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

The response may contain a non-standard status-line HTTP version … may be missing a CRLF to separate the status-line and message body and may contain custom headers.

Custom headers shouldn’t be a problem, assuming they follow the basic HTTP layout. The other two, however, are serious problems. I don’t see how you can get around this without “writing a lot of the HTTP parsing code”.

Imagine you could get at the byte stream underlying the session’s connection. How would you fix this? Well, to fix the CR LF problem you need to write your own parser to find where the header-to-body break is and insert it. Doing that correctly is implementing an HTTP parser (well, not HTTP, obviously, but a protocol that’s just as complicated).

This will be much worse if the origin server supports HTTP persistent connections, and worse again if you have to deal with the chunked transfer encoding.

If you want to go down that path you could implement an HTTP proxy and tell your URLSession to use that via the connectionProxyDictionary property. However, I suspect that’s needless complexity, and it’s likely you’d be better implementing this protocol directly on top Network framework.

If you need help with the specifics of parsing an HTTP message, you can use CFHTTPMessage for that. It’s ugly, but it’s quite helpful in situations like this.


Oh, there is another way forward here: Find the person who implementing this HTTP Just Kidding™ protocol and beat them with a rubber hose yell at them until they decide that it was a bad idea and fix their server (-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Modify URLSession incoming traffic?
 
 
Q