1*90c8c64dSAndroid Build Coastguard Worker#!/usr/bin/env python 2*90c8c64dSAndroid Build Coastguard Worker 3*90c8c64dSAndroid Build Coastguard Worker# 4*90c8c64dSAndroid Build Coastguard Worker# Copyright 2007, The Android Open Source Project 5*90c8c64dSAndroid Build Coastguard Worker# 6*90c8c64dSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 7*90c8c64dSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 8*90c8c64dSAndroid Build Coastguard Worker# You may obtain a copy of the License at 9*90c8c64dSAndroid Build Coastguard Worker# 10*90c8c64dSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 11*90c8c64dSAndroid Build Coastguard Worker# 12*90c8c64dSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 13*90c8c64dSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 14*90c8c64dSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15*90c8c64dSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 16*90c8c64dSAndroid Build Coastguard Worker# limitations under the License. 17*90c8c64dSAndroid Build Coastguard Worker# 18*90c8c64dSAndroid Build Coastguard Worker 19*90c8c64dSAndroid Build Coastguard Worker""" 20*90c8c64dSAndroid Build Coastguard Worker axl.py: HTTP Client torture tester 21*90c8c64dSAndroid Build Coastguard Worker 22*90c8c64dSAndroid Build Coastguard Worker""" 23*90c8c64dSAndroid Build Coastguard Worker 24*90c8c64dSAndroid Build Coastguard Workerimport sys, time 25*90c8c64dSAndroid Build Coastguard Worker 26*90c8c64dSAndroid Build Coastguard Workerfrom twisted.internet import protocol, reactor, defer 27*90c8c64dSAndroid Build Coastguard Workerfrom twisted.internet.protocol import ServerFactory, Protocol 28*90c8c64dSAndroid Build Coastguard Worker 29*90c8c64dSAndroid Build Coastguard Workerimport singletonmixin, log 30*90c8c64dSAndroid Build Coastguard Worker 31*90c8c64dSAndroid Build Coastguard Workerclass BaseProtocol(Protocol): 32*90c8c64dSAndroid Build Coastguard Worker def __init__(self): 33*90c8c64dSAndroid Build Coastguard Worker self.log = log.Log.getInstance() 34*90c8c64dSAndroid Build Coastguard Worker 35*90c8c64dSAndroid Build Coastguard Worker def write(self, data): 36*90c8c64dSAndroid Build Coastguard Worker self.log("BaseProtocol.write()", len(data), data) 37*90c8c64dSAndroid Build Coastguard Worker return self.transport.write(data) 38*90c8c64dSAndroid Build Coastguard Worker 39*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 40*90c8c64dSAndroid Build Coastguard Worker self.log("BaseProtocol.dataReceived()", len(data), data) 41*90c8c64dSAndroid Build Coastguard Worker 42*90c8c64dSAndroid Build Coastguard Worker def connectionMade(self): 43*90c8c64dSAndroid Build Coastguard Worker self.log("BaseProtocol.connectionMade()") 44*90c8c64dSAndroid Build Coastguard Worker self.transport.setTcpNoDelay(1) # send immediately 45*90c8c64dSAndroid Build Coastguard Worker 46*90c8c64dSAndroid Build Coastguard Worker def connectionLost(self, reason): 47*90c8c64dSAndroid Build Coastguard Worker self.log("BaseProtocol.connectionLost():", reason) 48*90c8c64dSAndroid Build Coastguard Worker 49*90c8c64dSAndroid Build Coastguard Worker def sendResponse(self, response): 50*90c8c64dSAndroid Build Coastguard Worker self.write("HTTP/1.1 200 OK\r\n") 51*90c8c64dSAndroid Build Coastguard Worker self.write("Content-Length: %d\r\n\r\n" % len(response)) 52*90c8c64dSAndroid Build Coastguard Worker if len(response) > 0: 53*90c8c64dSAndroid Build Coastguard Worker self.write(response) 54*90c8c64dSAndroid Build Coastguard Worker 55*90c8c64dSAndroid Build Coastguard Worker 56*90c8c64dSAndroid Build Coastguard Worker# Tests 57*90c8c64dSAndroid Build Coastguard Worker# 8000: test driven by resource request 58*90c8c64dSAndroid Build Coastguard Worker 59*90c8c64dSAndroid Build Coastguard Workerclass Drop(BaseProtocol): 60*90c8c64dSAndroid Build Coastguard Worker """Drops connection immediately after connect""" 61*90c8c64dSAndroid Build Coastguard Worker PORT = 8001 62*90c8c64dSAndroid Build Coastguard Worker def connectionMade(self): 63*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.connectionMade(self) 64*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 65*90c8c64dSAndroid Build Coastguard Worker 66*90c8c64dSAndroid Build Coastguard Workerclass ReadAndDrop(BaseProtocol): 67*90c8c64dSAndroid Build Coastguard Worker """Read 1st line of request, then drop connection""" 68*90c8c64dSAndroid Build Coastguard Worker PORT = 8002 69*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 70*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 71*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 72*90c8c64dSAndroid Build Coastguard Worker 73*90c8c64dSAndroid Build Coastguard Workerclass GarbageStatus(BaseProtocol): 74*90c8c64dSAndroid Build Coastguard Worker """Send garbage statusline""" 75*90c8c64dSAndroid Build Coastguard Worker PORT = 8003 76*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 77*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 78*90c8c64dSAndroid Build Coastguard Worker self.write("welcome to the jungle baby\r\n") 79*90c8c64dSAndroid Build Coastguard Worker 80*90c8c64dSAndroid Build Coastguard Workerclass BadHeader(BaseProtocol): 81*90c8c64dSAndroid Build Coastguard Worker """Drop connection after a header is half-sent""" 82*90c8c64dSAndroid Build Coastguard Worker PORT = 8004 83*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 84*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 85*90c8c64dSAndroid Build Coastguard Worker self.write("HTTP/1.1 200 OK\r\n") 86*90c8c64dSAndroid Build Coastguard Worker self.write("Cache-Contr") 87*90c8c64dSAndroid Build Coastguard Worker time.sleep(1) 88*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 89*90c8c64dSAndroid Build Coastguard Worker 90*90c8c64dSAndroid Build Coastguard Workerclass PauseHeader(BaseProtocol): 91*90c8c64dSAndroid Build Coastguard Worker """Pause for a second in middle of a header""" 92*90c8c64dSAndroid Build Coastguard Worker PORT = 8005 93*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 94*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 95*90c8c64dSAndroid Build Coastguard Worker self.write("HTTP/1.1 200 OK\r\n") 96*90c8c64dSAndroid Build Coastguard Worker self.write("Cache-Contr") 97*90c8c64dSAndroid Build Coastguard Worker time.sleep(1) 98*90c8c64dSAndroid Build Coastguard Worker self.write("ol: private\r\n\r\nwe've got fun and games") 99*90c8c64dSAndroid Build Coastguard Worker time.sleep(1) 100*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 101*90c8c64dSAndroid Build Coastguard Worker 102*90c8c64dSAndroid Build Coastguard Workerclass Redirect(BaseProtocol): 103*90c8c64dSAndroid Build Coastguard Worker PORT = 8006 104*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 105*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 106*90c8c64dSAndroid Build Coastguard Worker self.write("HTTP/1.1 302 Moved Temporarily\r\n") 107*90c8c64dSAndroid Build Coastguard Worker self.write("Content-Length: 0\r\n") 108*90c8c64dSAndroid Build Coastguard Worker self.write("Location: http://shopping.yahoo.com/p:Canon PowerShot SD630 Digital Camera:1993588104;_ylc=X3oDMTFhZXNmcjFjBF9TAzI3MTYxNDkEc2VjA2ZwLXB1bHNlBHNsawNyc3NfcHVsc2U0LmluYw--\r\n\r\n") 109*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 110*90c8c64dSAndroid Build Coastguard Worker 111*90c8c64dSAndroid Build Coastguard Workerclass DataDrop(BaseProtocol): 112*90c8c64dSAndroid Build Coastguard Worker """Drop connection in body""" 113*90c8c64dSAndroid Build Coastguard Worker PORT = 8007 114*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 115*90c8c64dSAndroid Build Coastguard Worker if data.find("favico") >= 0: 116*90c8c64dSAndroid Build Coastguard Worker self.write("HTTP/1.1 404 Not Found\r\n\r\n") 117*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 118*90c8c64dSAndroid Build Coastguard Worker return 119*90c8c64dSAndroid Build Coastguard Worker 120*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 121*90c8c64dSAndroid Build Coastguard Worker self.write("HTTP/1.1 200 OK\r\n") 122*90c8c64dSAndroid Build Coastguard Worker# self.write("Content-Length: 100\r\n\r\n") 123*90c8c64dSAndroid Build Coastguard Worker self.write("\r\n") 124*90c8c64dSAndroid Build Coastguard Worker# self.write("Data cuts off < 100 here!") 125*90c8c64dSAndroid Build Coastguard Worker# time.sleep(4) 126*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 127*90c8c64dSAndroid Build Coastguard Worker 128*90c8c64dSAndroid Build Coastguard Workerclass DropOnce(BaseProtocol): 129*90c8c64dSAndroid Build Coastguard Worker """Drop every other connection""" 130*90c8c64dSAndroid Build Coastguard Worker PORT = 8008 131*90c8c64dSAndroid Build Coastguard Worker COUNT = 0 132*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 133*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 134*90c8c64dSAndroid Build Coastguard Worker self.write("HTTP/1.1 200 OK\r\n") 135*90c8c64dSAndroid Build Coastguard Worker self.write("Content-Length: 5\r\n\r\n") 136*90c8c64dSAndroid Build Coastguard Worker 137*90c8c64dSAndroid Build Coastguard Worker if (not(DropOnce.COUNT & 1)): 138*90c8c64dSAndroid Build Coastguard Worker self.write("HE") 139*90c8c64dSAndroid Build Coastguard Worker else: 140*90c8c64dSAndroid Build Coastguard Worker self.write("HELLO") 141*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 142*90c8c64dSAndroid Build Coastguard Worker 143*90c8c64dSAndroid Build Coastguard Worker DropOnce.COUNT += 1 144*90c8c64dSAndroid Build Coastguard Worker 145*90c8c64dSAndroid Build Coastguard Workerclass NoCR(BaseProtocol): 146*90c8c64dSAndroid Build Coastguard Worker """Send headers without carriage returns""" 147*90c8c64dSAndroid Build Coastguard Worker PORT = 8009 148*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 149*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 150*90c8c64dSAndroid Build Coastguard Worker self.write("HTTP/1.1 200 OK\n") 151*90c8c64dSAndroid Build Coastguard Worker self.write("Content-Length: 5\n\n") 152*90c8c64dSAndroid Build Coastguard Worker 153*90c8c64dSAndroid Build Coastguard Worker self.write("HELLO") 154*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 155*90c8c64dSAndroid Build Coastguard Worker 156*90c8c64dSAndroid Build Coastguard Workerclass PipeDrop(BaseProtocol): 157*90c8c64dSAndroid Build Coastguard Worker PORT = 8010 158*90c8c64dSAndroid Build Coastguard Worker COUNT = 0 159*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 160*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 161*90c8c64dSAndroid Build Coastguard Worker if not PipeDrop.COUNT % 3: 162*90c8c64dSAndroid Build Coastguard Worker self.write("HTTP/1.1 200 OK\n") 163*90c8c64dSAndroid Build Coastguard Worker self.write("Content-Length: 943\n\n") 164*90c8c64dSAndroid Build Coastguard Worker 165*90c8c64dSAndroid Build Coastguard Worker self.write(open("./stfu.jpg").read()) 166*90c8c64dSAndroid Build Coastguard Worker PipeDrop.COUNT += 1 167*90c8c64dSAndroid Build Coastguard Worker 168*90c8c64dSAndroid Build Coastguard Worker else: 169*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 170*90c8c64dSAndroid Build Coastguard Worker PipeDrop.COUNT += 1 171*90c8c64dSAndroid Build Coastguard Worker 172*90c8c64dSAndroid Build Coastguard Workerclass RedirectLoop(BaseProtocol): 173*90c8c64dSAndroid Build Coastguard Worker """Redirect back to same resource""" 174*90c8c64dSAndroid Build Coastguard Worker PORT = 8011 175*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 176*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 177*90c8c64dSAndroid Build Coastguard Worker self.write("HTTP/1.1 302 Moved Temporarily\r\n") 178*90c8c64dSAndroid Build Coastguard Worker self.write("Content-Length: 0\r\n") 179*90c8c64dSAndroid Build Coastguard Worker self.write("Location: http://localhost:8011/\r\n") 180*90c8c64dSAndroid Build Coastguard Worker self.write("\r\n") 181*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 182*90c8c64dSAndroid Build Coastguard Worker 183*90c8c64dSAndroid Build Coastguard Workerclass ReadAll(BaseProtocol): 184*90c8c64dSAndroid Build Coastguard Worker """Read entire request""" 185*90c8c64dSAndroid Build Coastguard Worker PORT = 8012 186*90c8c64dSAndroid Build Coastguard Worker 187*90c8c64dSAndroid Build Coastguard Worker def connectionMade(self): 188*90c8c64dSAndroid Build Coastguard Worker self.count = 0 189*90c8c64dSAndroid Build Coastguard Worker 190*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 191*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 192*90c8c64dSAndroid Build Coastguard Worker self.count += len(data) 193*90c8c64dSAndroid Build Coastguard Worker if self.count == 190890: 194*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 195*90c8c64dSAndroid Build Coastguard Worker 196*90c8c64dSAndroid Build Coastguard Workerclass Timeout(BaseProtocol): 197*90c8c64dSAndroid Build Coastguard Worker """Timout sending body""" 198*90c8c64dSAndroid Build Coastguard Worker PORT = 8013 199*90c8c64dSAndroid Build Coastguard Worker 200*90c8c64dSAndroid Build Coastguard Worker def connectionMade(self): 201*90c8c64dSAndroid Build Coastguard Worker self.count = 0 202*90c8c64dSAndroid Build Coastguard Worker 203*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 204*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 205*90c8c64dSAndroid Build Coastguard Worker if self.count == 0: self.write("HTTP/1.1 200 OK\r\n\r\n") 206*90c8c64dSAndroid Build Coastguard Worker self.count += 1 207*90c8c64dSAndroid Build Coastguard Worker 208*90c8c64dSAndroid Build Coastguard Workerclass SlowResponse(BaseProtocol): 209*90c8c64dSAndroid Build Coastguard Worker """Ensure client does not time out on slow writes""" 210*90c8c64dSAndroid Build Coastguard Worker PORT = 8014 211*90c8c64dSAndroid Build Coastguard Worker 212*90c8c64dSAndroid Build Coastguard Worker def connectionMade(self): 213*90c8c64dSAndroid Build Coastguard Worker self.count = 0 214*90c8c64dSAndroid Build Coastguard Worker 215*90c8c64dSAndroid Build Coastguard Worker def dataReceived(self, data): 216*90c8c64dSAndroid Build Coastguard Worker BaseProtocol.dataReceived(self, data) 217*90c8c64dSAndroid Build Coastguard Worker if self.count == 0: self.write("HTTP/1.1 200 OK\r\n\r\n") 218*90c8c64dSAndroid Build Coastguard Worker self.sendPack(0) 219*90c8c64dSAndroid Build Coastguard Worker 220*90c8c64dSAndroid Build Coastguard Worker def sendPack(self, count): 221*90c8c64dSAndroid Build Coastguard Worker if count > 10: 222*90c8c64dSAndroid Build Coastguard Worker self.transport.loseConnection() 223*90c8c64dSAndroid Build Coastguard Worker 224*90c8c64dSAndroid Build Coastguard Worker self.write("all work and no play makes jack a dull boy %s\n" % count) 225*90c8c64dSAndroid Build Coastguard Worker d = defer.Deferred() 226*90c8c64dSAndroid Build Coastguard Worker d.addCallback(self.sendPack) 227*90c8c64dSAndroid Build Coastguard Worker reactor.callLater(15, d.callback, count + 1) 228*90c8c64dSAndroid Build Coastguard Worker 229*90c8c64dSAndroid Build Coastguard Worker 230*90c8c64dSAndroid Build Coastguard Worker# HTTP/1.1 200 OK 231*90c8c64dSAndroid Build Coastguard Worker# Cache-Control: private 232*90c8c64dSAndroid Build Coastguard Worker# Content-Type: text/html 233*90c8c64dSAndroid Build Coastguard Worker# Set-Cookie: PREF=ID=10644de62c423aa5:TM=1155044293:LM=1155044293:S=0lHtymefQRs2j7nD; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com 234*90c8c64dSAndroid Build Coastguard Worker# Server: GWS/2.1 235*90c8c64dSAndroid Build Coastguard Worker# Transfer-Encoding: chunked 236*90c8c64dSAndroid Build Coastguard Worker# Date: Tue, 08 Aug 2006 13:38:13 GMT 237*90c8c64dSAndroid Build Coastguard Worker 238*90c8c64dSAndroid Build Coastguard Workerdef main(): 239*90c8c64dSAndroid Build Coastguard Worker # Initialize log 240*90c8c64dSAndroid Build Coastguard Worker log.Log.getInstance(sys.stdout) 241*90c8c64dSAndroid Build Coastguard Worker 242*90c8c64dSAndroid Build Coastguard Worker for protocol in Drop, ReadAndDrop, GarbageStatus, BadHeader, PauseHeader, \ 243*90c8c64dSAndroid Build Coastguard Worker Redirect, DataDrop, DropOnce, NoCR, PipeDrop, RedirectLoop, ReadAll, \ 244*90c8c64dSAndroid Build Coastguard Worker Timeout, SlowResponse: 245*90c8c64dSAndroid Build Coastguard Worker factory = ServerFactory() 246*90c8c64dSAndroid Build Coastguard Worker factory.protocol = protocol 247*90c8c64dSAndroid Build Coastguard Worker reactor.listenTCP(protocol.PORT, factory) 248*90c8c64dSAndroid Build Coastguard Worker 249*90c8c64dSAndroid Build Coastguard Worker 250*90c8c64dSAndroid Build Coastguard Worker reactor.run() 251*90c8c64dSAndroid Build Coastguard Worker 252*90c8c64dSAndroid Build Coastguard Workerif __name__ == '__main__': 253*90c8c64dSAndroid Build Coastguard Worker main() 254