1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20package thrift 21 22import ( 23 "context" 24 "encoding/base64" 25 "fmt" 26) 27 28const ( 29 THRIFT_JSON_PROTOCOL_VERSION = 1 30) 31 32// for references to _ParseContext see tsimplejson_protocol.go 33 34// JSON protocol implementation for thrift. 35// Utilizes Simple JSON protocol 36// 37type TJSONProtocol struct { 38 *TSimpleJSONProtocol 39} 40 41// Constructor 42func NewTJSONProtocol(t TTransport) *TJSONProtocol { 43 v := &TJSONProtocol{TSimpleJSONProtocol: NewTSimpleJSONProtocol(t)} 44 v.parseContextStack = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL)) 45 v.dumpContext = append(v.dumpContext, int(_CONTEXT_IN_TOPLEVEL)) 46 return v 47} 48 49// Factory 50type TJSONProtocolFactory struct{} 51 52func (p *TJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol { 53 return NewTJSONProtocol(trans) 54} 55 56func NewTJSONProtocolFactory() *TJSONProtocolFactory { 57 return &TJSONProtocolFactory{} 58} 59 60func (p *TJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error { 61 p.resetContextStack() // THRIFT-3735 62 if e := p.OutputListBegin(); e != nil { 63 return e 64 } 65 if e := p.WriteI32(THRIFT_JSON_PROTOCOL_VERSION); e != nil { 66 return e 67 } 68 if e := p.WriteString(name); e != nil { 69 return e 70 } 71 if e := p.WriteByte(int8(typeId)); e != nil { 72 return e 73 } 74 if e := p.WriteI32(seqId); e != nil { 75 return e 76 } 77 return nil 78} 79 80func (p *TJSONProtocol) WriteMessageEnd() error { 81 return p.OutputListEnd() 82} 83 84func (p *TJSONProtocol) WriteStructBegin(name string) error { 85 if e := p.OutputObjectBegin(); e != nil { 86 return e 87 } 88 return nil 89} 90 91func (p *TJSONProtocol) WriteStructEnd() error { 92 return p.OutputObjectEnd() 93} 94 95func (p *TJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error { 96 if e := p.WriteI16(id); e != nil { 97 return e 98 } 99 if e := p.OutputObjectBegin(); e != nil { 100 return e 101 } 102 s, e1 := p.TypeIdToString(typeId) 103 if e1 != nil { 104 return e1 105 } 106 if e := p.WriteString(s); e != nil { 107 return e 108 } 109 return nil 110} 111 112func (p *TJSONProtocol) WriteFieldEnd() error { 113 return p.OutputObjectEnd() 114} 115 116func (p *TJSONProtocol) WriteFieldStop() error { return nil } 117 118func (p *TJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error { 119 if e := p.OutputListBegin(); e != nil { 120 return e 121 } 122 s, e1 := p.TypeIdToString(keyType) 123 if e1 != nil { 124 return e1 125 } 126 if e := p.WriteString(s); e != nil { 127 return e 128 } 129 s, e1 = p.TypeIdToString(valueType) 130 if e1 != nil { 131 return e1 132 } 133 if e := p.WriteString(s); e != nil { 134 return e 135 } 136 if e := p.WriteI64(int64(size)); e != nil { 137 return e 138 } 139 return p.OutputObjectBegin() 140} 141 142func (p *TJSONProtocol) WriteMapEnd() error { 143 if e := p.OutputObjectEnd(); e != nil { 144 return e 145 } 146 return p.OutputListEnd() 147} 148 149func (p *TJSONProtocol) WriteListBegin(elemType TType, size int) error { 150 return p.OutputElemListBegin(elemType, size) 151} 152 153func (p *TJSONProtocol) WriteListEnd() error { 154 return p.OutputListEnd() 155} 156 157func (p *TJSONProtocol) WriteSetBegin(elemType TType, size int) error { 158 return p.OutputElemListBegin(elemType, size) 159} 160 161func (p *TJSONProtocol) WriteSetEnd() error { 162 return p.OutputListEnd() 163} 164 165func (p *TJSONProtocol) WriteBool(b bool) error { 166 if b { 167 return p.WriteI32(1) 168 } 169 return p.WriteI32(0) 170} 171 172func (p *TJSONProtocol) WriteByte(b int8) error { 173 return p.WriteI32(int32(b)) 174} 175 176func (p *TJSONProtocol) WriteI16(v int16) error { 177 return p.WriteI32(int32(v)) 178} 179 180func (p *TJSONProtocol) WriteI32(v int32) error { 181 return p.OutputI64(int64(v)) 182} 183 184func (p *TJSONProtocol) WriteI64(v int64) error { 185 return p.OutputI64(int64(v)) 186} 187 188func (p *TJSONProtocol) WriteDouble(v float64) error { 189 return p.OutputF64(v) 190} 191 192func (p *TJSONProtocol) WriteString(v string) error { 193 return p.OutputString(v) 194} 195 196func (p *TJSONProtocol) WriteBinary(v []byte) error { 197 // JSON library only takes in a string, 198 // not an arbitrary byte array, to ensure bytes are transmitted 199 // efficiently we must convert this into a valid JSON string 200 // therefore we use base64 encoding to avoid excessive escaping/quoting 201 if e := p.OutputPreValue(); e != nil { 202 return e 203 } 204 if _, e := p.write(JSON_QUOTE_BYTES); e != nil { 205 return NewTProtocolException(e) 206 } 207 writer := base64.NewEncoder(base64.StdEncoding, p.writer) 208 if _, e := writer.Write(v); e != nil { 209 p.writer.Reset(p.trans) // THRIFT-3735 210 return NewTProtocolException(e) 211 } 212 if e := writer.Close(); e != nil { 213 return NewTProtocolException(e) 214 } 215 if _, e := p.write(JSON_QUOTE_BYTES); e != nil { 216 return NewTProtocolException(e) 217 } 218 return p.OutputPostValue() 219} 220 221// Reading methods. 222func (p *TJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) { 223 p.resetContextStack() // THRIFT-3735 224 if isNull, err := p.ParseListBegin(); isNull || err != nil { 225 return name, typeId, seqId, err 226 } 227 version, err := p.ReadI32() 228 if err != nil { 229 return name, typeId, seqId, err 230 } 231 if version != THRIFT_JSON_PROTOCOL_VERSION { 232 e := fmt.Errorf("Unknown Protocol version %d, expected version %d", version, THRIFT_JSON_PROTOCOL_VERSION) 233 return name, typeId, seqId, NewTProtocolExceptionWithType(INVALID_DATA, e) 234 235 } 236 if name, err = p.ReadString(); err != nil { 237 return name, typeId, seqId, err 238 } 239 bTypeId, err := p.ReadByte() 240 typeId = TMessageType(bTypeId) 241 if err != nil { 242 return name, typeId, seqId, err 243 } 244 if seqId, err = p.ReadI32(); err != nil { 245 return name, typeId, seqId, err 246 } 247 return name, typeId, seqId, nil 248} 249 250func (p *TJSONProtocol) ReadMessageEnd() error { 251 err := p.ParseListEnd() 252 return err 253} 254 255func (p *TJSONProtocol) ReadStructBegin() (name string, err error) { 256 _, err = p.ParseObjectStart() 257 return "", err 258} 259 260func (p *TJSONProtocol) ReadStructEnd() error { 261 return p.ParseObjectEnd() 262} 263 264func (p *TJSONProtocol) ReadFieldBegin() (string, TType, int16, error) { 265 b, _ := p.reader.Peek(1) 266 if len(b) < 1 || b[0] == JSON_RBRACE[0] || b[0] == JSON_RBRACKET[0] { 267 return "", STOP, -1, nil 268 } 269 fieldId, err := p.ReadI16() 270 if err != nil { 271 return "", STOP, fieldId, err 272 } 273 if _, err = p.ParseObjectStart(); err != nil { 274 return "", STOP, fieldId, err 275 } 276 sType, err := p.ReadString() 277 if err != nil { 278 return "", STOP, fieldId, err 279 } 280 fType, err := p.StringToTypeId(sType) 281 return "", fType, fieldId, err 282} 283 284func (p *TJSONProtocol) ReadFieldEnd() error { 285 return p.ParseObjectEnd() 286} 287 288func (p *TJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) { 289 if isNull, e := p.ParseListBegin(); isNull || e != nil { 290 return VOID, VOID, 0, e 291 } 292 293 // read keyType 294 sKeyType, e := p.ReadString() 295 if e != nil { 296 return keyType, valueType, size, e 297 } 298 keyType, e = p.StringToTypeId(sKeyType) 299 if e != nil { 300 return keyType, valueType, size, e 301 } 302 303 // read valueType 304 sValueType, e := p.ReadString() 305 if e != nil { 306 return keyType, valueType, size, e 307 } 308 valueType, e = p.StringToTypeId(sValueType) 309 if e != nil { 310 return keyType, valueType, size, e 311 } 312 313 // read size 314 iSize, e := p.ReadI64() 315 if e != nil { 316 return keyType, valueType, size, e 317 } 318 size = int(iSize) 319 320 _, e = p.ParseObjectStart() 321 return keyType, valueType, size, e 322} 323 324func (p *TJSONProtocol) ReadMapEnd() error { 325 e := p.ParseObjectEnd() 326 if e != nil { 327 return e 328 } 329 return p.ParseListEnd() 330} 331 332func (p *TJSONProtocol) ReadListBegin() (elemType TType, size int, e error) { 333 return p.ParseElemListBegin() 334} 335 336func (p *TJSONProtocol) ReadListEnd() error { 337 return p.ParseListEnd() 338} 339 340func (p *TJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) { 341 return p.ParseElemListBegin() 342} 343 344func (p *TJSONProtocol) ReadSetEnd() error { 345 return p.ParseListEnd() 346} 347 348func (p *TJSONProtocol) ReadBool() (bool, error) { 349 value, err := p.ReadI32() 350 return (value != 0), err 351} 352 353func (p *TJSONProtocol) ReadByte() (int8, error) { 354 v, err := p.ReadI64() 355 return int8(v), err 356} 357 358func (p *TJSONProtocol) ReadI16() (int16, error) { 359 v, err := p.ReadI64() 360 return int16(v), err 361} 362 363func (p *TJSONProtocol) ReadI32() (int32, error) { 364 v, err := p.ReadI64() 365 return int32(v), err 366} 367 368func (p *TJSONProtocol) ReadI64() (int64, error) { 369 v, _, err := p.ParseI64() 370 return v, err 371} 372 373func (p *TJSONProtocol) ReadDouble() (float64, error) { 374 v, _, err := p.ParseF64() 375 return v, err 376} 377 378func (p *TJSONProtocol) ReadString() (string, error) { 379 var v string 380 if err := p.ParsePreValue(); err != nil { 381 return v, err 382 } 383 f, _ := p.reader.Peek(1) 384 if len(f) > 0 && f[0] == JSON_QUOTE { 385 p.reader.ReadByte() 386 value, err := p.ParseStringBody() 387 v = value 388 if err != nil { 389 return v, err 390 } 391 } else if len(f) > 0 && f[0] == JSON_NULL[0] { 392 b := make([]byte, len(JSON_NULL)) 393 _, err := p.reader.Read(b) 394 if err != nil { 395 return v, NewTProtocolException(err) 396 } 397 if string(b) != string(JSON_NULL) { 398 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) 399 return v, NewTProtocolExceptionWithType(INVALID_DATA, e) 400 } 401 } else { 402 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) 403 return v, NewTProtocolExceptionWithType(INVALID_DATA, e) 404 } 405 return v, p.ParsePostValue() 406} 407 408func (p *TJSONProtocol) ReadBinary() ([]byte, error) { 409 var v []byte 410 if err := p.ParsePreValue(); err != nil { 411 return nil, err 412 } 413 f, _ := p.reader.Peek(1) 414 if len(f) > 0 && f[0] == JSON_QUOTE { 415 p.reader.ReadByte() 416 value, err := p.ParseBase64EncodedBody() 417 v = value 418 if err != nil { 419 return v, err 420 } 421 } else if len(f) > 0 && f[0] == JSON_NULL[0] { 422 b := make([]byte, len(JSON_NULL)) 423 _, err := p.reader.Read(b) 424 if err != nil { 425 return v, NewTProtocolException(err) 426 } 427 if string(b) != string(JSON_NULL) { 428 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) 429 return v, NewTProtocolExceptionWithType(INVALID_DATA, e) 430 } 431 } else { 432 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) 433 return v, NewTProtocolExceptionWithType(INVALID_DATA, e) 434 } 435 436 return v, p.ParsePostValue() 437} 438 439func (p *TJSONProtocol) Flush(ctx context.Context) (err error) { 440 err = p.writer.Flush() 441 if err == nil { 442 err = p.trans.Flush(ctx) 443 } 444 return NewTProtocolException(err) 445} 446 447func (p *TJSONProtocol) Skip(fieldType TType) (err error) { 448 return SkipDefaultDepth(p, fieldType) 449} 450 451func (p *TJSONProtocol) Transport() TTransport { 452 return p.trans 453} 454 455func (p *TJSONProtocol) OutputElemListBegin(elemType TType, size int) error { 456 if e := p.OutputListBegin(); e != nil { 457 return e 458 } 459 s, e1 := p.TypeIdToString(elemType) 460 if e1 != nil { 461 return e1 462 } 463 if e := p.WriteString(s); e != nil { 464 return e 465 } 466 if e := p.WriteI64(int64(size)); e != nil { 467 return e 468 } 469 return nil 470} 471 472func (p *TJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) { 473 if isNull, e := p.ParseListBegin(); isNull || e != nil { 474 return VOID, 0, e 475 } 476 sElemType, err := p.ReadString() 477 if err != nil { 478 return VOID, size, err 479 } 480 elemType, err = p.StringToTypeId(sElemType) 481 if err != nil { 482 return elemType, size, err 483 } 484 nSize, err2 := p.ReadI64() 485 size = int(nSize) 486 return elemType, size, err2 487} 488 489func (p *TJSONProtocol) readElemListBegin() (elemType TType, size int, e error) { 490 if isNull, e := p.ParseListBegin(); isNull || e != nil { 491 return VOID, 0, e 492 } 493 sElemType, err := p.ReadString() 494 if err != nil { 495 return VOID, size, err 496 } 497 elemType, err = p.StringToTypeId(sElemType) 498 if err != nil { 499 return elemType, size, err 500 } 501 nSize, err2 := p.ReadI64() 502 size = int(nSize) 503 return elemType, size, err2 504} 505 506func (p *TJSONProtocol) writeElemListBegin(elemType TType, size int) error { 507 if e := p.OutputListBegin(); e != nil { 508 return e 509 } 510 s, e1 := p.TypeIdToString(elemType) 511 if e1 != nil { 512 return e1 513 } 514 if e := p.OutputString(s); e != nil { 515 return e 516 } 517 if e := p.OutputI64(int64(size)); e != nil { 518 return e 519 } 520 return nil 521} 522 523func (p *TJSONProtocol) TypeIdToString(fieldType TType) (string, error) { 524 switch byte(fieldType) { 525 case BOOL: 526 return "tf", nil 527 case BYTE: 528 return "i8", nil 529 case I16: 530 return "i16", nil 531 case I32: 532 return "i32", nil 533 case I64: 534 return "i64", nil 535 case DOUBLE: 536 return "dbl", nil 537 case STRING: 538 return "str", nil 539 case STRUCT: 540 return "rec", nil 541 case MAP: 542 return "map", nil 543 case SET: 544 return "set", nil 545 case LIST: 546 return "lst", nil 547 } 548 549 e := fmt.Errorf("Unknown fieldType: %d", int(fieldType)) 550 return "", NewTProtocolExceptionWithType(INVALID_DATA, e) 551} 552 553func (p *TJSONProtocol) StringToTypeId(fieldType string) (TType, error) { 554 switch fieldType { 555 case "tf": 556 return TType(BOOL), nil 557 case "i8": 558 return TType(BYTE), nil 559 case "i16": 560 return TType(I16), nil 561 case "i32": 562 return TType(I32), nil 563 case "i64": 564 return TType(I64), nil 565 case "dbl": 566 return TType(DOUBLE), nil 567 case "str": 568 return TType(STRING), nil 569 case "rec": 570 return TType(STRUCT), nil 571 case "map": 572 return TType(MAP), nil 573 case "set": 574 return TType(SET), nil 575 case "lst": 576 return TType(LIST), nil 577 } 578 579 e := fmt.Errorf("Unknown type identifier: %s", fieldType) 580 return TType(STOP), NewTProtocolExceptionWithType(INVALID_DATA, e) 581} 582