summaryrefslogtreecommitdiffstats
path: root/test/cgi/test_cgi_session.rb
blob: 50e0f4af4d069d362455fb88117742d1487104cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
require 'test/unit'
require 'cgi'
require 'cgi/session'
require 'cgi/session/pstore'
require 'stringio'
require 'tmpdir'

class CGISessionTest < Test::Unit::TestCase
  def setup
    @session_dir = File.join(File.dirname(__FILE__), 'session_dir')
    FileUtils.mkdir_p @session_dir
  end

  def teardown
    @environ.each do |key, val| ENV.delete(key) end
    $stdout = STDOUT
    FileUtils.rm_rf(@session_dir)
  end

  def test_cgi_session_filestore
    @environ = {
      'REQUEST_METHOD'  => 'GET',
  #    'QUERY_STRING'    => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
  #    'HTTP_COOKIE'     => '_session_id=12345; name1=val1&val2;',
      'SERVER_SOFTWARE' => 'Apache 2.2.0',
      'SERVER_PROTOCOL' => 'HTTP/1.1',
    }
    value1="value1"
    value2="\x8F\xBC\x8D]"
    value2.force_encoding("SJIS") if RUBY_VERSION>="1.9"
    ENV.update(@environ)
    cgi = CGI.new
    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
    session["key1"]=value1
    session["key2"]=value2
    assert_equal(value1,session["key1"])
    assert_equal(value2,session["key2"])
    session.close
    $stdout = StringIO.new
    cgi.out{""}

    @environ = {
      'REQUEST_METHOD'  => 'GET',
      # 'HTTP_COOKIE'     => "_session_id=#{session_id}",
      'QUERY_STRING'    => "_session_id=#{session.session_id}",
      'SERVER_SOFTWARE' => 'Apache 2.2.0',
      'SERVER_PROTOCOL' => 'HTTP/1.1',
    }
    ENV.update(@environ)
    cgi = CGI.new
    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
    $stdout = StringIO.new
    assert_equal(value1,session["key1"])
    assert_equal(value2,session["key2"])
    session.close

  end
  def test_cgi_session_pstore
    @environ = {
      'REQUEST_METHOD'  => 'GET',
  #    'QUERY_STRING'    => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
  #    'HTTP_COOKIE'     => '_session_id=12345; name1=val1&val2;',
      'SERVER_SOFTWARE' => 'Apache 2.2.0',
      'SERVER_PROTOCOL' => 'HTTP/1.1',
    }
    value1="value1"
    value2="\x8F\xBC\x8D]"
    value2.force_encoding("SJIS") if RUBY_VERSION>="1.9"
    ENV.update(@environ)
    cgi = CGI.new
    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"database_manager"=>CGI::Session::PStore)
    session["key1"]=value1
    session["key2"]=value2
    assert_equal(value1,session["key1"])
    assert_equal(value2,session["key2"])
    session.close
    $stdout = StringIO.new
    cgi.out{""}

    @environ = {
      'REQUEST_METHOD'  => 'GET',
      # 'HTTP_COOKIE'     => "_session_id=#{session_id}",
      'QUERY_STRING'    => "_session_id=#{session.session_id}",
      'SERVER_SOFTWARE' => 'Apache 2.2.0',
      'SERVER_PROTOCOL' => 'HTTP/1.1',
    }
    ENV.update(@environ)
    cgi = CGI.new
    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"database_manager"=>CGI::Session::PStore)
    $stdout = StringIO.new
    assert_equal(value1,session["key1"])
    assert_equal(value2,session["key2"])
    session.close
  end
  def test_cgi_session_specify_session_id
    @environ = {
      'REQUEST_METHOD'  => 'GET',
  #    'QUERY_STRING'    => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
  #    'HTTP_COOKIE'     => '_session_id=12345; name1=val1&val2;',
      'SERVER_SOFTWARE' => 'Apache 2.2.0',
      'SERVER_PROTOCOL' => 'HTTP/1.1',
    }
    value1="value1"
    value2="\x8F\xBC\x8D]"
    value2.force_encoding("SJIS") if RUBY_VERSION>="1.9"
    ENV.update(@environ)
    cgi = CGI.new
    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"session_id"=>"foo")
    session["key1"]=value1
    session["key2"]=value2
    assert_equal(value1,session["key1"])
    assert_equal(value2,session["key2"])
    assert_equal("foo",session.session_id)
    session_id=session.session_id
    session.close
    $stdout = StringIO.new
    cgi.out{""}

    @environ = {
      'REQUEST_METHOD'  => 'GET',
      # 'HTTP_COOKIE'     => "_session_id=#{session_id}",
      'QUERY_STRING'    => "_session_id=#{session.session_id}",
      'SERVER_SOFTWARE' => 'Apache 2.2.0',
      'SERVER_PROTOCOL' => 'HTTP/1.1',
    }
    ENV.update(@environ)
    cgi = CGI.new
    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
    $stdout = StringIO.new
    assert_equal(value1,session["key1"])
    assert_equal(value2,session["key2"])
    assert_equal("foo",session.session_id)
    session.close
  end
  def test_cgi_session_specify_session_key
    @environ = {
      'REQUEST_METHOD'  => 'GET',
  #    'QUERY_STRING'    => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
  #    'HTTP_COOKIE'     => '_session_id=12345; name1=val1&val2;',
      'SERVER_SOFTWARE' => 'Apache 2.2.0',
      'SERVER_PROTOCOL' => 'HTTP/1.1',
    }
    value1="value1"
    value2="\x8F\xBC\x8D]"
    value2.force_encoding("SJIS") if RUBY_VERSION>="1.9"
    ENV.update(@environ)
    cgi = CGI.new
    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"session_key"=>"bar")
    session["key1"]=value1
    session["key2"]=value2
    assert_equal(value1,session["key1"])
    assert_equal(value2,session["key2"])
    session_id=session.session_id
    session.close
    $stdout = StringIO.new
    cgi.out{""}

    @environ = {
      'REQUEST_METHOD'  => 'GET',
      'HTTP_COOKIE'     => "bar=#{session_id}",
      # 'QUERY_STRING'    => "bar=#{session.session_id}",
      'SERVER_SOFTWARE' => 'Apache 2.2.0',
      'SERVER_PROTOCOL' => 'HTTP/1.1',
    }
    ENV.update(@environ)
    cgi = CGI.new
    session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"session_key"=>"bar")
    $stdout = StringIO.new
    assert_equal(value1,session["key1"])
    assert_equal(value2,session["key2"])
    session.close
  end
end
0x04, RxBufEmpty=0x01, }; /* Interrupt register bits, using my own meaningful names. */ enum IntrStatusBits { PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000, RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10, TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01, }; enum TxStatusBits { TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000, TxOutOfWindow=0x20000000, TxAborted=0x40000000, TxCarrierLost=0x80000000, }; enum RxStatusBits { RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000, RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004, RxBadAlign=0x0002, RxStatusOK=0x0001, }; enum MediaStatusBits { MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08, MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01, }; enum MIIBMCRBits { BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000, BMCRRestartNWay=0x0200, BMCRDuplex=0x0100, }; enum CSCRBits { CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800, CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0, CSCR_LinkDownCmd=0x0f3c0, }; /* Bits in RxConfig. */ enum rx_mode_bits { RxCfgWrap=0x80, AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08, AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01, }; static int ioaddr; static unsigned int cur_rx,cur_tx; /* The RTL8139 can only transmit from a contiguous, aligned memory block. */ static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4))); static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4))); static int rtl8139_probe(struct eth_device *dev, bd_t *bis); static int read_eeprom(int location, int addr_len); static void rtl_reset(struct eth_device *dev); static int rtl_transmit(struct eth_device *dev, volatile void *packet, int length); static int rtl_poll(struct eth_device *dev); static void rtl_disable(struct eth_device *dev); #ifdef CONFIG_MCAST_TFTP/* This driver already accepts all b/mcast */ static int rtl_bcast_addr (struct eth_device *dev, u8 bcast_mac, u8 set) { return (0); } #endif static struct pci_device_id supported[] = { {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139}, {PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139}, {} }; int rtl8139_initialize(bd_t *bis) { pci_dev_t devno; int card_number = 0; struct eth_device *dev; u32 iobase; int idx=0; while(1){ /* Find RTL8139 */ if ((devno = pci_find_devices(supported, idx++)) < 0) break; pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); iobase &= ~0xf; debug ("rtl8139: REALTEK RTL8139 @0x%x\n", iobase); dev = (struct eth_device *)malloc(sizeof *dev); sprintf (dev->name, "RTL8139#%d", card_number); dev->priv = (void *) devno; dev->iobase = (int)bus_to_phys(iobase); dev->init = rtl8139_probe; dev->halt = rtl_disable; dev->send = rtl_transmit; dev->recv = rtl_poll; #ifdef CONFIG_MCAST_TFTP dev->mcast = rtl_bcast_addr; #endif eth_register (dev); card_number++; pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20); udelay (10 * 1000); } return card_number; } static int rtl8139_probe(struct eth_device *dev, bd_t *bis) { int i; int speed10, fullduplex; int addr_len; unsigned short *ap = (unsigned short *)dev->enetaddr; ioaddr = dev->iobase; /* Bring the chip out of low-power mode. */ outb(0x00, ioaddr + Config1); addr_len = read_eeprom(0,8) == 0x8129 ? 8 : 6; for (i = 0; i < 3; i++) *ap++ = le16_to_cpu (read_eeprom(i + 7, addr_len)); speed10 = inb(ioaddr + MediaStatus) & MSRSpeed10; fullduplex = inw(ioaddr + MII_BMCR) & BMCRDuplex; rtl_reset(dev); if (inb(ioaddr + MediaStatus) & MSRLinkFail) { printf("Cable not connected or other link failure\n"); return -1 ; } return 0; } /* Serial EEPROM section. */ /* EEPROM_Ctrl bits. */ #define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */ #define EE_CS 0x08 /* EEPROM chip select. */ #define EE_DATA_WRITE 0x02 /* EEPROM chip data in. */ #define EE_WRITE_0 0x00 #define EE_WRITE_1 0x02 #define EE_DATA_READ 0x01 /* EEPROM chip data out. */ #define EE_ENB (0x80 | EE_CS) /* Delay between EEPROM clock transitions. No extra delay is needed with 33MHz PCI, but 66MHz may change this. */ #define eeprom_delay() inl(ee_addr) /* The EEPROM commands include the alway-set leading bit. */ #define EE_WRITE_CMD (5) #define EE_READ_CMD (6) #define EE_ERASE_CMD (7) static int read_eeprom(int location, int addr_len) { int i; unsigned int retval = 0; long ee_addr = ioaddr + Cfg9346; int read_cmd = location | (EE_READ_CMD << addr_len); outb(EE_ENB & ~EE_CS, ee_addr); outb(EE_ENB, ee_addr); eeprom_delay(); /* Shift the read command bits out. */ for (i = 4 + addr_len; i >= 0; i--) { int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; outb(EE_ENB | dataval, ee_addr); eeprom_delay(); outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); eeprom_delay(); } outb(EE_ENB, ee_addr); eeprom_delay(); for (i = 16; i > 0; i--) { outb(EE_ENB | EE_SHIFT_CLK, ee_addr); eeprom_delay(); retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0); outb(EE_ENB, ee_addr); eeprom_delay(); } /* Terminate the EEPROM access. */ outb(~EE_CS, ee_addr); eeprom_delay(); return retval; } static const unsigned int rtl8139_rx_config = (RX_BUF_LEN_IDX << 11) | (RX_FIFO_THRESH << 13) | (RX_DMA_BURST << 8); static void set_rx_mode(struct eth_device *dev) { unsigned int mc_filter[2]; int rx_mode; /* !IFF_PROMISC */ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; mc_filter[1] = mc_filter[0] = 0xffffffff; outl(rtl8139_rx_config | rx_mode, ioaddr + RxConfig); outl(mc_filter[0], ioaddr + MAR0 + 0); outl(mc_filter[1], ioaddr + MAR0 + 4); } static void rtl_reset(struct eth_device *dev) { int i; outb(CmdReset, ioaddr + ChipCmd); cur_rx = 0; cur_tx = 0; /* Give the chip 10ms to finish the reset. */ for (i=0; i<100; ++i){ if ((inb(ioaddr + ChipCmd) & CmdReset) == 0) break; udelay (100); /* wait 100us */ } for (i = 0; i < ETH_ALEN; i++) outb(dev->enetaddr[i], ioaddr + MAC0 + i); /* Must enable Tx/Rx before setting transfer thresholds! */ outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd); outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8), ioaddr + RxConfig); /* accept no frames yet! */ outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig); /* The Linux driver changes Config1 here to use a different LED pattern * for half duplex or full/autodetect duplex (for full/autodetect, the * outputs are TX/RX, Link10/100, FULL, while for half duplex it uses * TX/RX, Link100, Link10). This is messy, because it doesn't match * the inscription on the mounting bracket. It should not be changed * from the configuration EEPROM default, because the card manufacturer * should have set that to match the card. */ #ifdef DEBUG_RX printf("rx ring address is %X\n",(unsigned long)rx_ring); #endif flush_cache((unsigned long)rx_ring, RX_BUF_LEN); outl(phys_to_bus((int)rx_ring), ioaddr + RxBuf); /* If we add multicast support, the MAR0 register would have to be * initialized to 0xffffffffffffffff (two 32 bit accesses). Etherboot * only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast. */ outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd); outl(rtl8139_rx_config, ioaddr + RxConfig); /* Start the chip's Tx and Rx process. */ outl(0, ioaddr + RxMissed); /* set_rx_mode */ set_rx_mode(dev); /* Disable all known interrupts by setting the interrupt mask. */ outw(0, ioaddr + IntrMask); } static int rtl_transmit(struct eth_device *dev, volatile void *packet, int length) { unsigned int status; unsigned long txstatus; unsigned int len = length; int i = 0; ioaddr = dev->iobase; memcpy((char *)tx_buffer, (char *)packet, (int)length); #ifdef DEBUG_TX printf("sending %d bytes\n", len); #endif /* Note: RTL8139 doesn't auto-pad, send minimum payload (another 4 * bytes are sent automatically for the FCS, totalling to 64 bytes). */ while (len < ETH_ZLEN) { tx_buffer[len++] = '\0'; } flush_cache((unsigned long)tx_buffer, length); outl(phys_to_bus((int)tx_buffer), ioaddr + TxAddr0 + cur_tx*4); outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len, ioaddr + TxStatus0 + cur_tx*4); do { status = inw(ioaddr + IntrStatus); /* Only acknlowledge interrupt sources we can properly handle * here - the RxOverflow/RxFIFOOver MUST be handled in the * rtl_poll() function. */ outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus); if ((status & (TxOK | TxErr | PCIErr)) != 0) break; udelay(10); } while (i++ < RTL_TIMEOUT); txstatus = inl(ioaddr + TxStatus0 + cur_tx*4); if (status & TxOK) { cur_tx = (cur_tx + 1) % NUM_TX_DESC; #ifdef DEBUG_TX printf("tx done (%d ticks), status %hX txstatus %X\n", to-currticks(), status, txstatus); #endif return length; } else { #ifdef DEBUG_TX printf("tx timeout/error (%d usecs), status %hX txstatus %X\n", 10*i, status, txstatus); #endif rtl_reset(dev); return 0; } } static int rtl_poll(struct eth_device *dev) { unsigned int status; unsigned int ring_offs; unsigned int rx_size, rx_status; int length=0; ioaddr = dev->iobase; if (inb(ioaddr + ChipCmd) & RxBufEmpty) { return 0; } status = inw(ioaddr + IntrStatus); /* See below for the rest of the interrupt acknowledges. */ outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus); #ifdef DEBUG_RX printf("rtl_poll: int %hX ", status); #endif ring_offs = cur_rx % RX_BUF_LEN; /* ring_offs is guaranteed being 4-byte aligned */ rx_status = le32_to_cpu(*(unsigned int *)(rx_ring + ring_offs)); rx_size = rx_status >> 16; rx_status &= 0xffff; if ((rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) || (rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) { printf("rx error %hX\n", rx_status); rtl_reset(dev); /* this clears all interrupts still pending */ return 0; } /* Received a good packet */ length = rx_size - 4; /* no one cares about the FCS */ if (ring_offs+4+rx_size-4 > RX_BUF_LEN) { int semi_count = RX_BUF_LEN - ring_offs - 4; unsigned char rxdata[RX_BUF_LEN]; memcpy(rxdata, rx_ring + ring_offs + 4, semi_count); memcpy(&(rxdata[semi_count]), rx_ring, rx_size-4-semi_count); NetReceive(rxdata, length); #ifdef DEBUG_RX printf("rx packet %d+%d bytes", semi_count,rx_size-4-semi_count); #endif } else { NetReceive(rx_ring + ring_offs + 4, length); #ifdef DEBUG_RX printf("rx packet %d bytes", rx_size-4); #endif } flush_cache((unsigned long)rx_ring, RX_BUF_LEN); cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; outw(cur_rx - 16, ioaddr + RxBufPtr); /* See RTL8139 Programming Guide V0.1 for the official handling of * Rx overflow situations. The document itself contains basically no * usable information, except for a few exception handling rules. */